{"version":3,"sources":["webpack:///./node_modules/video.js/node_modules/mux.js/lib/tools/parse-sidx.js","webpack:///./node_modules/video.js/node_modules/videojs-vtt.js/lib/vttcue.js","webpack:///./node_modules/video.js/node_modules/mux.js/lib/utils/clock.js","webpack:///./node_modules/is-function/index.js","webpack:///./node_modules/mpd-parser/dist/mpd-parser.es.js","webpack:///./node_modules/global/window.js","webpack:///./node_modules/video.js/node_modules/m3u8-parser/dist/m3u8-parser.es.js","webpack:///./node_modules/video.js/node_modules/videojs-vtt.js/lib/vtt.js","webpack:///./node_modules/video.js/node_modules/videojs-vtt.js/lib/browser-index.js","webpack:///./node_modules/video.js/node_modules/mux.js/lib/utils/numbers.js","webpack:///./node_modules/video.js/node_modules/videojs-vtt.js/lib/vttregion.js","webpack:///./node_modules/global/document.js"],"names":["getUint64","parseSidx","data","view","DataView","buffer","byteOffset","byteLength","result","version","flags","Uint8Array","subarray","references","referenceId","getUint32","timescale","i","earliestPresentationTime","firstOffset","referenceCount","getUint16","push","referenceType","referencedSize","subsegmentDuration","startsWithSap","sapType","sapDeltaTime","module","exports","autoKeyword","directionSetting","alignSetting","findDirectionSetting","value","dir","toLowerCase","findAlignSetting","align","VTTCue","startTime","endTime","text","this","hasBeenReset","_id","_pauseOnExit","_startTime","_endTime","_text","_region","_vertical","_snapToLines","_line","_lineAlign","_position","_positionAlign","_size","_align","Object","defineProperties","enumerable","get","set","TypeError","setting","SyntaxError","console","warn","Error","displayState","undefined","prototype","getCueAsHTML","WebVTT","convertCueToDOMTree","window","secondsToVideoTs","secondsToAudioTs","videoTsToSeconds","audioTsToSeconds","audioTsToVideoTs","videoTsToAudioTs","metadataTsToSeconds","ONE_SECOND_IN_TS","seconds","sampleRate","timestamp","timelineStartPts","keepOriginalTimestamps","isFunction","toString","fn","string","call","setTimeout","alert","confirm","prompt","isObject","obj","merge","objects","reduce","source","keys","forEach","key","Array","isArray","concat","values","o","map","k","range","start","end","flatten","lists","x","y","from","list","length","findIndexes","l","a","e","union","keyFunction","acc","el","errors","INVALID_NUMBER_OF_PERIOD","INVALID_NUMBER_OF_CONTENT_STEERING","DASH_EMPTY_MANIFEST","DASH_INVALID_XML","NO_BASE_URL","MISSING_SEGMENT_INFORMATION","SEGMENT_TIME_UNSPECIFIED","UNSUPPORTED_UTC_TIMING_SCHEME","urlTypeToSegment","baseUrl","indexRange","segment","uri","resolvedUri","rangeStr","ranges","split","startRange","BigInt","parseInt","endRange","Number","MAX_SAFE_INTEGER","byterange","offset","byteRangeToString","parseEndNumber","endNumber","isNaN","segmentRange","attributes","duration","sourceDuration","periodDuration","segmentDuration","NOW","clientOffset","availabilityStartTime","periodStart","minimumUpdatePeriod","timeShiftBufferDepth","Infinity","now","periodStartWC","periodEndWC","segmentCount","Math","ceil","availableStart","floor","availableEnd","max","min","toSegments","number","startNumber","timeline","time","parseByDuration","type","segments","index","sectionDuration","segmentsFromBase","initialization","presentationTime","initSegment","sourceURL","segmentTimeInfo","addSidxSegmentsToPlaylist$1","playlist","sidx","sidxByteRange","sidxEnd","mediaReferences","filter","r","endList","startIndex","mediaSequence","reference","size","endIndex","SUPPORTED_MEDIA_TYPES","TIME_FUDGE","getUniqueTimelineStarts","timelineStarts","sort","b","findPlaylistWithName","playlists","name","NAME","getMediaGroupPlaylists","manifest","mediaGroupPlaylists","properties","group","label","updateMediaSequenceForPlaylist","updateSequenceNumbers","oldPlaylists","newPlaylists","discontinuitySequence","findIndex","oldPlaylist","firstNewSegment","oldMatchingSegmentIndex","oldSegment","abs","discontinuity","discontinuityStarts","unshift","oldMatchingSegment","positionManifestOnTimeline","oldManifest","newManifest","generateSidxKey","mergeDiscontiguousPlaylists","playlistsByBaseUrl","cur","allPlaylists","playlistGroup","mergedPlaylists","id","lang","contentProtection","addSidxSegmentsToPlaylist","sidxMapping","sidxKey","sidxMatch","addSidxSegmentsToPlaylists","formatAudioPlaylist","isAudioOnly","BANDWIDTH","bandwidth","CODECS","codecs","targetDuration","serviceLocation","AUDIO","SUBTITLES","formatVttPlaylist","m3u8Attributes","vttPlaylist","organizeAudioPlaylists","mainPlaylist","formattedPlaylists","role","language","roleLabel","autoselect","default","formatted","firstLabel","organizeVttPlaylists","organizeCaptionServices","captionServices","svcObj","svc","service","channel","instreamId","hasOwnProperty","aspectRatio","easyReader","formatVideoPlaylist","RESOLUTION","width","height","frameRate","videoOnly","mimeType","contentType","audioOnly","vttOnly","addMediaSequenceValues","flattenMediaGroupPlaylists","mediaGroupObject","labelContents","toM3u8","dashPlaylists","locations","contentSteering","previousManifest","eventStream","suggestedPresentationDelay","videoPlaylists","audioPlaylists","vttPlaylists","captions","Boolean","allowCache","mediaGroups","VIDEO","organizedAudioGroup","organizedVttGroup","playlistTimelineStarts","audio","subs","cc","getLiveRValue","parseByTimeline","segmentTimeline","media","sIndex","S","d","repeat","segmentTime","t","count","nextS","indexOf","identifierPattern","identifierReplacement","match","identifier","format","join","constructTemplateUrl","url","replace","parseTemplateInfo","segmentsFromTemplate","templateValues","RepresentationID","Bandwidth","mapSegment","Time","presentationTimeOffset","SegmentURLToSegmentObject","segmentUrl","mediaRange","segmentsFromList","segmentUrls","segmentUrlMap","segmentUrlObject","generateSegments","segmentInfo","segmentAttributes","segmentsFn","template","base","segmentsInfo","toPlaylists","representations","findChildren","element","childNodes","tagName","getContent","textContent","trim","parseDivisionValue","parseFloat","prev","current","parseDuration","str","SECONDS_IN_YEAR","SECONDS_IN_MONTH","SECONDS_IN_DAY","SECONDS_IN_HOUR","SECONDS_IN_MIN","durationRegex","exec","year","month","day","hour","minute","second","slice","parseDate","dateRegex","test","Date","parse","parsers","parsedValue","parseAttributes","parseFn","DEFAULT","keySystemsMap","buildBaseUrls","baseUrlElements","baseUrlElement","initialBaseUrl","resolvedBaseUrl","finalBaseUrl","getSegmentInformation","adaptationSet","segmentTemplate","segmentList","s","tag","segmentBase","segmentTimelineParentNode","segmentInitializationParentNode","segmentInitialization","inheritBaseUrls","adaptationSetAttributes","adaptationSetBaseUrls","adaptationSetSegmentInfo","representation","repBaseUrlElements","repBaseUrls","representationSegmentInfo","generateKeySystemInformation","contentProtectionNodes","node","schemeIdUri","keySystem","psshNode","pssh","parseCaptionServiceMetadata","opts","opt","val","toEventStream","period","eventStreamAttributes","event","eventAttributes","messageData","contentEncoding","toRepresentations","periodAttributes","periodBaseUrls","periodSegmentInfo","roleAttributes","attrs","accessibility","labelVal","nodeValue","toAdaptationSets","mpdAttributes","mpdBaseUrls","adaptationSets","generateContentSteeringInformation","contentSteeringNodes","eventHandler","message","infoFromContentSteeringTag","serverURL","queryBeforeStart","getPeriodStart","priorPeriodAttributes","mpdType","inheritAttributes","mpd","options","manifestUri","periodNodes","mediaPresentationDuration","periods","priorPeriod","contentSteeringInfo","representationInfo","stringToMpdXml","manifestString","parser","xml","parseFromString","documentElement","getElementsByTagName","parseUTCTimingScheme","UTCTimingNode","method","parsedManifestInfo","parseUTCTiming","win","global","self","LineStream","super","nextNewline","trigger","substring","TAB","String","fromCharCode","parseByterange","byterangeString","attributeSeparator","keyvalue","RegExp","attr","parseResolution","resolution","ParseStream","customParsers","tagMappers","line","newLines","mapper","mappedLine","newLine","tagType","title","playlistType","allowed","URI","BYTERANGE","dateTimeString","dateTimeObject","IV","Uint32Array","PRECISE","subkey","clientAttributePattern","isHexaDecimal","isDecimalFloating","expression","customType","dataParser","mapFn","camelCase","toUpperCase","camelCaseKeys","setHoldBack","serverControl","partTargetDuration","hb","phb","minTargetDuration","minPartDuration","Parser","lineStream","parseStream","pipe","mainDefinitions","params","URL","searchParams","lastProgramDateTime","uris","currentMap","currentUri","hasParts","noop","defaultMediaGroups","widevineUuid","currentTimeline","dateRanges","iFramePlaylists","lastByterangeEnd","lastPartByterangeEnd","dateRangeTags","on","parts","preloadHints","preloadSegment","entry","mediaGroup","rendition","definitions","def","METHOD","KEYFORMAT","VALID_METHODS","KEYID","keyId","iv","isFinite","TYPE","mediaGroupType","AUTOSELECT","LANGUAGE","CHARACTERISTICS","characteristics","FORCED","forced","getTime","reduceRight","programDateTime","timeOffset","precise","cueOut","cueOutCont","cueIn","skip","warnOnMissingAttributes_","segmentIndex","part","partIndex","renditionReports","canBlockReload","canSkipDateranges","hint","isPart","otherHint","report","required","partInf","partTarget","dateRange","endDate","startDate","plannedDuration","endOnNextYes","endOnNext","class","newDateInSeconds","attribute","JSON","stringify","dateRangeWithSameId","dateRangeToFind","pop","independentSegments","iFramesOnly","requiredCompatibilityversion","addDef","n","v","QUERYPARAM","decodeURIComponent","VALUE","IMPORT","custom","currentVersion","targetVersion","missing","chunk","addParser","addTagMapper","document","_objCreate","create","F","arguments","ParsingError","errorData","code","parseTimeStamp","input","computeSeconds","h","m","f","Settings","parseOptions","callback","keyValueDelim","groupDelim","groups","kv","parseCue","cue","regionList","oInput","consumeTimeStamp","ts","Errors","BadTimeStamp","consumeCueSettings","settings","region","alt","vals","vals0","integer","percent","vertical","lineAlign","snapToLines","position","left","center","middle","right","positionAlign","skipWhitespace","substr","constructor","BadSignature","dflt","defaultKey","has","TEXTAREA_ELEMENT","createElement","TAG_NAME","c","u","ruby","rt","DEFAULT_COLOR_CLASS","white","lime","cyan","red","yellow","magenta","blue","black","TAG_ANNOTATION","NEEDS_PARENT","parseContent","nextToken","consume","unescape","innerHTML","shouldAdd","localName","annotation","rootDiv","tagStack","appendChild","createTextNode","parentNode","createProcessingInstruction","classes","cl","bgColor","colorName","propName","propValue","style","className","strongRTLRanges","isStrongRTLChar","charCode","currentRange","determineBidi","cueDiv","nodeStack","pushNodes","nextTextNode","innerText","charCodeAt","computeLinePos","track","textTrackList","mediaElement","trackList","mode","StyleBox","CueStyleBox","styleOptions","styles","color","backgroundColor","top","bottom","display","writingMode","unicodeBidi","applyStyles","div","direction","textAlign","font","whiteSpace","textPos","formatStyle","move","box","BoxPosition","lh","offsetHeight","offsetWidth","offsetTop","rects","getClientRects","getBoundingClientRect","lineHeight","moveBoxToLinePosition","styleBox","containerBox","boxPositions","findBestPosition","axis","bestPosition","specifiedPosition","percentage","overlapsOppositeAxis","within","overlapsAny","p","intersectPercentage","boxPosition","linePos","step","round","maxPosition","initialAxis","reverse","calculatedPercentage","toCSSCompatValues","prop","unit","toMove","overlaps","b2","boxes","container","intersectArea","getSimpleBoxPosition","ret","StringDecoder","decode","encodeURIComponent","cuetext","FONT_SIZE_PERCENT","FONT_STYLE","CUE_BACKGROUND_PADDING","processCues","cues","overlay","firstChild","removeChild","paddedOverlay","shouldCompute","margin","fontSize","vttjs","decoder","state","TextDecoder","reportOrThrowError","onparsingerror","collectNextLine","pos","parseRegion","xy","anchor","VTTRegion","lines","regionAnchorX","regionAnchorY","viewportAnchorX","viewportAnchorY","scroll","onregion","parseTimestampMap","ontimestampmap","parseHeader","stream","alreadyCollectedLine","hasSubstring","oncue","flush","onflush","cueShim","regionShim","nativeVTTCue","nativeVTTRegion","shim","restore","MAX_UINT32","pow","uint8","dv","getBigUint64","scrollSetting","findScrollSetting","isValidPercentValue","_width","_lines","_regionAnchorX","_regionAnchorY","_viewportAnchorX","_viewportAnchorY","_scroll","doccy","minDoc","topLevel"],"mappings":"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","file":"js/chunk-07666390.7e73ef1d.js","sourcesContent":["var getUint64 = require('../utils/numbers.js').getUint64;\n\nvar parseSidx = function(data) {\n var view = new DataView(data.buffer, data.byteOffset, data.byteLength),\n result = {\n version: data[0],\n flags: new Uint8Array(data.subarray(1, 4)),\n references: [],\n referenceId: view.getUint32(4),\n timescale: view.getUint32(8)\n },\n i = 12;\n\n if (result.version === 0) {\n result.earliestPresentationTime = view.getUint32(i);\n result.firstOffset = view.getUint32(i + 4);\n i += 8;\n } else {\n // read 64 bits\n result.earliestPresentationTime = getUint64(data.subarray(i));\n result.firstOffset = getUint64(data.subarray(i + 8));\n i += 16;\n }\n\n i += 2; // reserved\n\n var referenceCount = view.getUint16(i);\n\n i += 2; // start of references\n\n for (; referenceCount > 0; i += 12, referenceCount--) {\n result.references.push({\n referenceType: (data[i] & 0x80) >>> 7,\n referencedSize: view.getUint32(i) & 0x7FFFFFFF,\n subsegmentDuration: view.getUint32(i + 4),\n startsWithSap: !!(data[i + 8] & 0x80),\n sapType: (data[i + 8] & 0x70) >>> 4,\n sapDeltaTime: view.getUint32(i + 8) & 0x0FFFFFFF\n });\n }\n\n return result;\n};\n\n\nmodule.exports = parseSidx;\n","/**\n * Copyright 2013 vtt.js Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nvar autoKeyword = \"auto\";\nvar directionSetting = {\n \"\": 1,\n \"lr\": 1,\n \"rl\": 1\n};\nvar alignSetting = {\n \"start\": 1,\n \"center\": 1,\n \"end\": 1,\n \"left\": 1,\n \"right\": 1,\n \"auto\": 1,\n \"line-left\": 1,\n \"line-right\": 1\n};\n\nfunction findDirectionSetting(value) {\n if (typeof value !== \"string\") {\n return false;\n }\n var dir = directionSetting[value.toLowerCase()];\n return dir ? value.toLowerCase() : false;\n}\n\nfunction findAlignSetting(value) {\n if (typeof value !== \"string\") {\n return false;\n }\n var align = alignSetting[value.toLowerCase()];\n return align ? value.toLowerCase() : false;\n}\n\nfunction VTTCue(startTime, endTime, text) {\n /**\n * Shim implementation specific properties. These properties are not in\n * the spec.\n */\n\n // Lets us know when the VTTCue's data has changed in such a way that we need\n // to recompute its display state. This lets us compute its display state\n // lazily.\n this.hasBeenReset = false;\n\n /**\n * VTTCue and TextTrackCue properties\n * http://dev.w3.org/html5/webvtt/#vttcue-interface\n */\n\n var _id = \"\";\n var _pauseOnExit = false;\n var _startTime = startTime;\n var _endTime = endTime;\n var _text = text;\n var _region = null;\n var _vertical = \"\";\n var _snapToLines = true;\n var _line = \"auto\";\n var _lineAlign = \"start\";\n var _position = \"auto\";\n var _positionAlign = \"auto\";\n var _size = 100;\n var _align = \"center\";\n\n Object.defineProperties(this, {\n \"id\": {\n enumerable: true,\n get: function() {\n return _id;\n },\n set: function(value) {\n _id = \"\" + value;\n }\n },\n\n \"pauseOnExit\": {\n enumerable: true,\n get: function() {\n return _pauseOnExit;\n },\n set: function(value) {\n _pauseOnExit = !!value;\n }\n },\n\n \"startTime\": {\n enumerable: true,\n get: function() {\n return _startTime;\n },\n set: function(value) {\n if (typeof value !== \"number\") {\n throw new TypeError(\"Start time must be set to a number.\");\n }\n _startTime = value;\n this.hasBeenReset = true;\n }\n },\n\n \"endTime\": {\n enumerable: true,\n get: function() {\n return _endTime;\n },\n set: function(value) {\n if (typeof value !== \"number\") {\n throw new TypeError(\"End time must be set to a number.\");\n }\n _endTime = value;\n this.hasBeenReset = true;\n }\n },\n\n \"text\": {\n enumerable: true,\n get: function() {\n return _text;\n },\n set: function(value) {\n _text = \"\" + value;\n this.hasBeenReset = true;\n }\n },\n\n \"region\": {\n enumerable: true,\n get: function() {\n return _region;\n },\n set: function(value) {\n _region = value;\n this.hasBeenReset = true;\n }\n },\n\n \"vertical\": {\n enumerable: true,\n get: function() {\n return _vertical;\n },\n set: function(value) {\n var setting = findDirectionSetting(value);\n // Have to check for false because the setting an be an empty string.\n if (setting === false) {\n throw new SyntaxError(\"Vertical: an invalid or illegal direction string was specified.\");\n }\n _vertical = setting;\n this.hasBeenReset = true;\n }\n },\n\n \"snapToLines\": {\n enumerable: true,\n get: function() {\n return _snapToLines;\n },\n set: function(value) {\n _snapToLines = !!value;\n this.hasBeenReset = true;\n }\n },\n\n \"line\": {\n enumerable: true,\n get: function() {\n return _line;\n },\n set: function(value) {\n if (typeof value !== \"number\" && value !== autoKeyword) {\n throw new SyntaxError(\"Line: an invalid number or illegal string was specified.\");\n }\n _line = value;\n this.hasBeenReset = true;\n }\n },\n\n \"lineAlign\": {\n enumerable: true,\n get: function() {\n return _lineAlign;\n },\n set: function(value) {\n var setting = findAlignSetting(value);\n if (!setting) {\n console.warn(\"lineAlign: an invalid or illegal string was specified.\");\n } else {\n _lineAlign = setting;\n this.hasBeenReset = true;\n }\n }\n },\n\n \"position\": {\n enumerable: true,\n get: function() {\n return _position;\n },\n set: function(value) {\n if (value < 0 || value > 100) {\n throw new Error(\"Position must be between 0 and 100.\");\n }\n _position = value;\n this.hasBeenReset = true;\n }\n },\n\n \"positionAlign\": {\n enumerable: true,\n get: function() {\n return _positionAlign;\n },\n set: function(value) {\n var setting = findAlignSetting(value);\n if (!setting) {\n console.warn(\"positionAlign: an invalid or illegal string was specified.\");\n } else {\n _positionAlign = setting;\n this.hasBeenReset = true;\n }\n }\n },\n\n \"size\": {\n enumerable: true,\n get: function() {\n return _size;\n },\n set: function(value) {\n if (value < 0 || value > 100) {\n throw new Error(\"Size must be between 0 and 100.\");\n }\n _size = value;\n this.hasBeenReset = true;\n }\n },\n\n \"align\": {\n enumerable: true,\n get: function() {\n return _align;\n },\n set: function(value) {\n var setting = findAlignSetting(value);\n if (!setting) {\n throw new SyntaxError(\"align: an invalid or illegal alignment string was specified.\");\n }\n _align = setting;\n this.hasBeenReset = true;\n }\n }\n });\n\n /**\n * Other spec defined properties\n */\n\n // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state\n this.displayState = undefined;\n}\n\n/**\n * VTTCue methods\n */\n\nVTTCue.prototype.getCueAsHTML = function() {\n // Assume WebVTT.convertCueToDOMTree is on the global.\n return WebVTT.convertCueToDOMTree(window, this.text);\n};\n\nmodule.exports = VTTCue;\n","/**\n * mux.js\n *\n * Copyright (c) Brightcove\n * Licensed Apache-2.0 https://github.com/videojs/mux.js/blob/master/LICENSE\n */\nvar\n ONE_SECOND_IN_TS = 90000, // 90kHz clock\n secondsToVideoTs,\n secondsToAudioTs,\n videoTsToSeconds,\n audioTsToSeconds,\n audioTsToVideoTs,\n videoTsToAudioTs,\n metadataTsToSeconds;\n\nsecondsToVideoTs = function(seconds) {\n return seconds * ONE_SECOND_IN_TS;\n};\n\nsecondsToAudioTs = function(seconds, sampleRate) {\n return seconds * sampleRate;\n};\n\nvideoTsToSeconds = function(timestamp) {\n return timestamp / ONE_SECOND_IN_TS;\n};\n\naudioTsToSeconds = function(timestamp, sampleRate) {\n return timestamp / sampleRate;\n};\n\naudioTsToVideoTs = function(timestamp, sampleRate) {\n return secondsToVideoTs(audioTsToSeconds(timestamp, sampleRate));\n};\n\nvideoTsToAudioTs = function(timestamp, sampleRate) {\n return secondsToAudioTs(videoTsToSeconds(timestamp), sampleRate);\n};\n\n/**\n * Adjust ID3 tag or caption timing information by the timeline pts values\n * (if keepOriginalTimestamps is false) and convert to seconds\n */\nmetadataTsToSeconds = function(timestamp, timelineStartPts, keepOriginalTimestamps) {\n return videoTsToSeconds(keepOriginalTimestamps ? timestamp : timestamp - timelineStartPts);\n};\n\nmodule.exports = {\n ONE_SECOND_IN_TS: ONE_SECOND_IN_TS,\n secondsToVideoTs: secondsToVideoTs,\n secondsToAudioTs: secondsToAudioTs,\n videoTsToSeconds: videoTsToSeconds,\n audioTsToSeconds: audioTsToSeconds,\n audioTsToVideoTs: audioTsToVideoTs,\n videoTsToAudioTs: videoTsToAudioTs,\n metadataTsToSeconds: metadataTsToSeconds\n};\n","module.exports = isFunction\n\nvar toString = Object.prototype.toString\n\nfunction isFunction (fn) {\n var string = toString.call(fn)\n return string === '[object Function]' ||\n (typeof fn === 'function' && string !== '[object RegExp]') ||\n (typeof window !== 'undefined' &&\n // IE8 and below\n (fn === window.setTimeout ||\n fn === window.alert ||\n fn === window.confirm ||\n fn === window.prompt))\n};\n","/*! @name mpd-parser @version 1.3.1 @license Apache-2.0 */\nimport resolveUrl from '@videojs/vhs-utils/es/resolve-url';\nimport window from 'global/window';\nimport { forEachMediaGroup } from '@videojs/vhs-utils/es/media-groups';\nimport decodeB64ToUint8Array from '@videojs/vhs-utils/es/decode-b64-to-uint8-array';\nimport { DOMParser } from '@xmldom/xmldom';\n\nvar version = \"1.3.1\";\n\nconst isObject = obj => {\n return !!obj && typeof obj === 'object';\n};\n\nconst merge = (...objects) => {\n return objects.reduce((result, source) => {\n if (typeof source !== 'object') {\n return result;\n }\n\n Object.keys(source).forEach(key => {\n if (Array.isArray(result[key]) && Array.isArray(source[key])) {\n result[key] = result[key].concat(source[key]);\n } else if (isObject(result[key]) && isObject(source[key])) {\n result[key] = merge(result[key], source[key]);\n } else {\n result[key] = source[key];\n }\n });\n return result;\n }, {});\n};\nconst values = o => Object.keys(o).map(k => o[k]);\n\nconst range = (start, end) => {\n const result = [];\n\n for (let i = start; i < end; i++) {\n result.push(i);\n }\n\n return result;\n};\nconst flatten = lists => lists.reduce((x, y) => x.concat(y), []);\nconst from = list => {\n if (!list.length) {\n return [];\n }\n\n const result = [];\n\n for (let i = 0; i < list.length; i++) {\n result.push(list[i]);\n }\n\n return result;\n};\nconst findIndexes = (l, key) => l.reduce((a, e, i) => {\n if (e[key]) {\n a.push(i);\n }\n\n return a;\n}, []);\n/**\n * Returns a union of the included lists provided each element can be identified by a key.\n *\n * @param {Array} list - list of lists to get the union of\n * @param {Function} keyFunction - the function to use as a key for each element\n *\n * @return {Array} the union of the arrays\n */\n\nconst union = (lists, keyFunction) => {\n return values(lists.reduce((acc, list) => {\n list.forEach(el => {\n acc[keyFunction(el)] = el;\n });\n return acc;\n }, {}));\n};\n\nvar errors = {\n INVALID_NUMBER_OF_PERIOD: 'INVALID_NUMBER_OF_PERIOD',\n INVALID_NUMBER_OF_CONTENT_STEERING: 'INVALID_NUMBER_OF_CONTENT_STEERING',\n DASH_EMPTY_MANIFEST: 'DASH_EMPTY_MANIFEST',\n DASH_INVALID_XML: 'DASH_INVALID_XML',\n NO_BASE_URL: 'NO_BASE_URL',\n MISSING_SEGMENT_INFORMATION: 'MISSING_SEGMENT_INFORMATION',\n SEGMENT_TIME_UNSPECIFIED: 'SEGMENT_TIME_UNSPECIFIED',\n UNSUPPORTED_UTC_TIMING_SCHEME: 'UNSUPPORTED_UTC_TIMING_SCHEME'\n};\n\n/**\n * @typedef {Object} SingleUri\n * @property {string} uri - relative location of segment\n * @property {string} resolvedUri - resolved location of segment\n * @property {Object} byterange - Object containing information on how to make byte range\n * requests following byte-range-spec per RFC2616.\n * @property {String} byterange.length - length of range request\n * @property {String} byterange.offset - byte offset of range request\n *\n * @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.1\n */\n\n/**\n * Converts a URLType node (5.3.9.2.3 Table 13) to a segment object\n * that conforms to how m3u8-parser is structured\n *\n * @see https://github.com/videojs/m3u8-parser\n *\n * @param {string} baseUrl - baseUrl provided by nodes\n * @param {string} source - source url for segment\n * @param {string} range - optional range used for range calls,\n * follows RFC 2616, Clause 14.35.1\n * @return {SingleUri} full segment information transformed into a format similar\n * to m3u8-parser\n */\n\nconst urlTypeToSegment = ({\n baseUrl = '',\n source = '',\n range = '',\n indexRange = ''\n}) => {\n const segment = {\n uri: source,\n resolvedUri: resolveUrl(baseUrl || '', source)\n };\n\n if (range || indexRange) {\n const rangeStr = range ? range : indexRange;\n const ranges = rangeStr.split('-'); // default to parsing this as a BigInt if possible\n\n let startRange = window.BigInt ? window.BigInt(ranges[0]) : parseInt(ranges[0], 10);\n let endRange = window.BigInt ? window.BigInt(ranges[1]) : parseInt(ranges[1], 10); // convert back to a number if less than MAX_SAFE_INTEGER\n\n if (startRange < Number.MAX_SAFE_INTEGER && typeof startRange === 'bigint') {\n startRange = Number(startRange);\n }\n\n if (endRange < Number.MAX_SAFE_INTEGER && typeof endRange === 'bigint') {\n endRange = Number(endRange);\n }\n\n let length;\n\n if (typeof endRange === 'bigint' || typeof startRange === 'bigint') {\n length = window.BigInt(endRange) - window.BigInt(startRange) + window.BigInt(1);\n } else {\n length = endRange - startRange + 1;\n }\n\n if (typeof length === 'bigint' && length < Number.MAX_SAFE_INTEGER) {\n length = Number(length);\n } // byterange should be inclusive according to\n // RFC 2616, Clause 14.35.1\n\n\n segment.byterange = {\n length,\n offset: startRange\n };\n }\n\n return segment;\n};\nconst byteRangeToString = byterange => {\n // `endRange` is one less than `offset + length` because the HTTP range\n // header uses inclusive ranges\n let endRange;\n\n if (typeof byterange.offset === 'bigint' || typeof byterange.length === 'bigint') {\n endRange = window.BigInt(byterange.offset) + window.BigInt(byterange.length) - window.BigInt(1);\n } else {\n endRange = byterange.offset + byterange.length - 1;\n }\n\n return `${byterange.offset}-${endRange}`;\n};\n\n/**\n * parse the end number attribue that can be a string\n * number, or undefined.\n *\n * @param {string|number|undefined} endNumber\n * The end number attribute.\n *\n * @return {number|null}\n * The result of parsing the end number.\n */\n\nconst parseEndNumber = endNumber => {\n if (endNumber && typeof endNumber !== 'number') {\n endNumber = parseInt(endNumber, 10);\n }\n\n if (isNaN(endNumber)) {\n return null;\n }\n\n return endNumber;\n};\n/**\n * Functions for calculating the range of available segments in static and dynamic\n * manifests.\n */\n\n\nconst segmentRange = {\n /**\n * Returns the entire range of available segments for a static MPD\n *\n * @param {Object} attributes\n * Inheritied MPD attributes\n * @return {{ start: number, end: number }}\n * The start and end numbers for available segments\n */\n static(attributes) {\n const {\n duration,\n timescale = 1,\n sourceDuration,\n periodDuration\n } = attributes;\n const endNumber = parseEndNumber(attributes.endNumber);\n const segmentDuration = duration / timescale;\n\n if (typeof endNumber === 'number') {\n return {\n start: 0,\n end: endNumber\n };\n }\n\n if (typeof periodDuration === 'number') {\n return {\n start: 0,\n end: periodDuration / segmentDuration\n };\n }\n\n return {\n start: 0,\n end: sourceDuration / segmentDuration\n };\n },\n\n /**\n * Returns the current live window range of available segments for a dynamic MPD\n *\n * @param {Object} attributes\n * Inheritied MPD attributes\n * @return {{ start: number, end: number }}\n * The start and end numbers for available segments\n */\n dynamic(attributes) {\n const {\n NOW,\n clientOffset,\n availabilityStartTime,\n timescale = 1,\n duration,\n periodStart = 0,\n minimumUpdatePeriod = 0,\n timeShiftBufferDepth = Infinity\n } = attributes;\n const endNumber = parseEndNumber(attributes.endNumber); // clientOffset is passed in at the top level of mpd-parser and is an offset calculated\n // after retrieving UTC server time.\n\n const now = (NOW + clientOffset) / 1000; // WC stands for Wall Clock.\n // Convert the period start time to EPOCH.\n\n const periodStartWC = availabilityStartTime + periodStart; // Period end in EPOCH is manifest's retrieval time + time until next update.\n\n const periodEndWC = now + minimumUpdatePeriod;\n const periodDuration = periodEndWC - periodStartWC;\n const segmentCount = Math.ceil(periodDuration * timescale / duration);\n const availableStart = Math.floor((now - periodStartWC - timeShiftBufferDepth) * timescale / duration);\n const availableEnd = Math.floor((now - periodStartWC) * timescale / duration);\n return {\n start: Math.max(0, availableStart),\n end: typeof endNumber === 'number' ? endNumber : Math.min(segmentCount, availableEnd)\n };\n }\n\n};\n/**\n * Maps a range of numbers to objects with information needed to build the corresponding\n * segment list\n *\n * @name toSegmentsCallback\n * @function\n * @param {number} number\n * Number of the segment\n * @param {number} index\n * Index of the number in the range list\n * @return {{ number: Number, duration: Number, timeline: Number, time: Number }}\n * Object with segment timing and duration info\n */\n\n/**\n * Returns a callback for Array.prototype.map for mapping a range of numbers to\n * information needed to build the segment list.\n *\n * @param {Object} attributes\n * Inherited MPD attributes\n * @return {toSegmentsCallback}\n * Callback map function\n */\n\nconst toSegments = attributes => number => {\n const {\n duration,\n timescale = 1,\n periodStart,\n startNumber = 1\n } = attributes;\n return {\n number: startNumber + number,\n duration: duration / timescale,\n timeline: periodStart,\n time: number * duration\n };\n};\n/**\n * Returns a list of objects containing segment timing and duration info used for\n * building the list of segments. This uses the @duration attribute specified\n * in the MPD manifest to derive the range of segments.\n *\n * @param {Object} attributes\n * Inherited MPD attributes\n * @return {{number: number, duration: number, time: number, timeline: number}[]}\n * List of Objects with segment timing and duration info\n */\n\nconst parseByDuration = attributes => {\n const {\n type,\n duration,\n timescale = 1,\n periodDuration,\n sourceDuration\n } = attributes;\n const {\n start,\n end\n } = segmentRange[type](attributes);\n const segments = range(start, end).map(toSegments(attributes));\n\n if (type === 'static') {\n const index = segments.length - 1; // section is either a period or the full source\n\n const sectionDuration = typeof periodDuration === 'number' ? periodDuration : sourceDuration; // final segment may be less than full segment duration\n\n segments[index].duration = sectionDuration - duration / timescale * index;\n }\n\n return segments;\n};\n\n/**\n * Translates SegmentBase into a set of segments.\n * (DASH SPEC Section 5.3.9.3.2) contains a set of nodes. Each\n * node should be translated into segment.\n *\n * @param {Object} attributes\n * Object containing all inherited attributes from parent elements with attribute\n * names as keys\n * @return {Object.} list of segments\n */\n\nconst segmentsFromBase = attributes => {\n const {\n baseUrl,\n initialization = {},\n sourceDuration,\n indexRange = '',\n periodStart,\n presentationTime,\n number = 0,\n duration\n } = attributes; // base url is required for SegmentBase to work, per spec (Section 5.3.9.2.1)\n\n if (!baseUrl) {\n throw new Error(errors.NO_BASE_URL);\n }\n\n const initSegment = urlTypeToSegment({\n baseUrl,\n source: initialization.sourceURL,\n range: initialization.range\n });\n const segment = urlTypeToSegment({\n baseUrl,\n source: baseUrl,\n indexRange\n });\n segment.map = initSegment; // If there is a duration, use it, otherwise use the given duration of the source\n // (since SegmentBase is only for one total segment)\n\n if (duration) {\n const segmentTimeInfo = parseByDuration(attributes);\n\n if (segmentTimeInfo.length) {\n segment.duration = segmentTimeInfo[0].duration;\n segment.timeline = segmentTimeInfo[0].timeline;\n }\n } else if (sourceDuration) {\n segment.duration = sourceDuration;\n segment.timeline = periodStart;\n } // If presentation time is provided, these segments are being generated by SIDX\n // references, and should use the time provided. For the general case of SegmentBase,\n // there should only be one segment in the period, so its presentation time is the same\n // as its period start.\n\n\n segment.presentationTime = presentationTime || periodStart;\n segment.number = number;\n return [segment];\n};\n/**\n * Given a playlist, a sidx box, and a baseUrl, update the segment list of the playlist\n * according to the sidx information given.\n *\n * playlist.sidx has metadadata about the sidx where-as the sidx param\n * is the parsed sidx box itself.\n *\n * @param {Object} playlist the playlist to update the sidx information for\n * @param {Object} sidx the parsed sidx box\n * @return {Object} the playlist object with the updated sidx information\n */\n\nconst addSidxSegmentsToPlaylist$1 = (playlist, sidx, baseUrl) => {\n // Retain init segment information\n const initSegment = playlist.sidx.map ? playlist.sidx.map : null; // Retain source duration from initial main manifest parsing\n\n const sourceDuration = playlist.sidx.duration; // Retain source timeline\n\n const timeline = playlist.timeline || 0;\n const sidxByteRange = playlist.sidx.byterange;\n const sidxEnd = sidxByteRange.offset + sidxByteRange.length; // Retain timescale of the parsed sidx\n\n const timescale = sidx.timescale; // referenceType 1 refers to other sidx boxes\n\n const mediaReferences = sidx.references.filter(r => r.referenceType !== 1);\n const segments = [];\n const type = playlist.endList ? 'static' : 'dynamic';\n const periodStart = playlist.sidx.timeline;\n let presentationTime = periodStart;\n let number = playlist.mediaSequence || 0; // firstOffset is the offset from the end of the sidx box\n\n let startIndex; // eslint-disable-next-line\n\n if (typeof sidx.firstOffset === 'bigint') {\n startIndex = window.BigInt(sidxEnd) + sidx.firstOffset;\n } else {\n startIndex = sidxEnd + sidx.firstOffset;\n }\n\n for (let i = 0; i < mediaReferences.length; i++) {\n const reference = sidx.references[i]; // size of the referenced (sub)segment\n\n const size = reference.referencedSize; // duration of the referenced (sub)segment, in the timescale\n // this will be converted to seconds when generating segments\n\n const duration = reference.subsegmentDuration; // should be an inclusive range\n\n let endIndex; // eslint-disable-next-line\n\n if (typeof startIndex === 'bigint') {\n endIndex = startIndex + window.BigInt(size) - window.BigInt(1);\n } else {\n endIndex = startIndex + size - 1;\n }\n\n const indexRange = `${startIndex}-${endIndex}`;\n const attributes = {\n baseUrl,\n timescale,\n timeline,\n periodStart,\n presentationTime,\n number,\n duration,\n sourceDuration,\n indexRange,\n type\n };\n const segment = segmentsFromBase(attributes)[0];\n\n if (initSegment) {\n segment.map = initSegment;\n }\n\n segments.push(segment);\n\n if (typeof startIndex === 'bigint') {\n startIndex += window.BigInt(size);\n } else {\n startIndex += size;\n }\n\n presentationTime += duration / timescale;\n number++;\n }\n\n playlist.segments = segments;\n return playlist;\n};\n\nconst SUPPORTED_MEDIA_TYPES = ['AUDIO', 'SUBTITLES']; // allow one 60fps frame as leniency (arbitrarily chosen)\n\nconst TIME_FUDGE = 1 / 60;\n/**\n * Given a list of timelineStarts, combines, dedupes, and sorts them.\n *\n * @param {TimelineStart[]} timelineStarts - list of timeline starts\n *\n * @return {TimelineStart[]} the combined and deduped timeline starts\n */\n\nconst getUniqueTimelineStarts = timelineStarts => {\n return union(timelineStarts, ({\n timeline\n }) => timeline).sort((a, b) => a.timeline > b.timeline ? 1 : -1);\n};\n/**\n * Finds the playlist with the matching NAME attribute.\n *\n * @param {Array} playlists - playlists to search through\n * @param {string} name - the NAME attribute to search for\n *\n * @return {Object|null} the matching playlist object, or null\n */\n\nconst findPlaylistWithName = (playlists, name) => {\n for (let i = 0; i < playlists.length; i++) {\n if (playlists[i].attributes.NAME === name) {\n return playlists[i];\n }\n }\n\n return null;\n};\n/**\n * Gets a flattened array of media group playlists.\n *\n * @param {Object} manifest - the main manifest object\n *\n * @return {Array} the media group playlists\n */\n\nconst getMediaGroupPlaylists = manifest => {\n let mediaGroupPlaylists = [];\n forEachMediaGroup(manifest, SUPPORTED_MEDIA_TYPES, (properties, type, group, label) => {\n mediaGroupPlaylists = mediaGroupPlaylists.concat(properties.playlists || []);\n });\n return mediaGroupPlaylists;\n};\n/**\n * Updates the playlist's media sequence numbers.\n *\n * @param {Object} config - options object\n * @param {Object} config.playlist - the playlist to update\n * @param {number} config.mediaSequence - the mediaSequence number to start with\n */\n\nconst updateMediaSequenceForPlaylist = ({\n playlist,\n mediaSequence\n}) => {\n playlist.mediaSequence = mediaSequence;\n playlist.segments.forEach((segment, index) => {\n segment.number = playlist.mediaSequence + index;\n });\n};\n/**\n * Updates the media and discontinuity sequence numbers of newPlaylists given oldPlaylists\n * and a complete list of timeline starts.\n *\n * If no matching playlist is found, only the discontinuity sequence number of the playlist\n * will be updated.\n *\n * Since early available timelines are not supported, at least one segment must be present.\n *\n * @param {Object} config - options object\n * @param {Object[]} oldPlaylists - the old playlists to use as a reference\n * @param {Object[]} newPlaylists - the new playlists to update\n * @param {Object} timelineStarts - all timelineStarts seen in the stream to this point\n */\n\nconst updateSequenceNumbers = ({\n oldPlaylists,\n newPlaylists,\n timelineStarts\n}) => {\n newPlaylists.forEach(playlist => {\n playlist.discontinuitySequence = timelineStarts.findIndex(function ({\n timeline\n }) {\n return timeline === playlist.timeline;\n }); // Playlists NAMEs come from DASH Representation IDs, which are mandatory\n // (see ISO_23009-1-2012 5.3.5.2).\n //\n // If the same Representation existed in a prior Period, it will retain the same NAME.\n\n const oldPlaylist = findPlaylistWithName(oldPlaylists, playlist.attributes.NAME);\n\n if (!oldPlaylist) {\n // Since this is a new playlist, the media sequence values can start from 0 without\n // consequence.\n return;\n } // TODO better support for live SIDX\n //\n // As of this writing, mpd-parser does not support multiperiod SIDX (in live or VOD).\n // This is evident by a playlist only having a single SIDX reference. In a multiperiod\n // playlist there would need to be multiple SIDX references. In addition, live SIDX is\n // not supported when the SIDX properties change on refreshes.\n //\n // In the future, if support needs to be added, the merging logic here can be called\n // after SIDX references are resolved. For now, exit early to prevent exceptions being\n // thrown due to undefined references.\n\n\n if (playlist.sidx) {\n return;\n } // Since we don't yet support early available timelines, we don't need to support\n // playlists with no segments.\n\n\n const firstNewSegment = playlist.segments[0];\n const oldMatchingSegmentIndex = oldPlaylist.segments.findIndex(function (oldSegment) {\n return Math.abs(oldSegment.presentationTime - firstNewSegment.presentationTime) < TIME_FUDGE;\n }); // No matching segment from the old playlist means the entire playlist was refreshed.\n // In this case the media sequence should account for this update, and the new segments\n // should be marked as discontinuous from the prior content, since the last prior\n // timeline was removed.\n\n if (oldMatchingSegmentIndex === -1) {\n updateMediaSequenceForPlaylist({\n playlist,\n mediaSequence: oldPlaylist.mediaSequence + oldPlaylist.segments.length\n });\n playlist.segments[0].discontinuity = true;\n playlist.discontinuityStarts.unshift(0); // No matching segment does not necessarily mean there's missing content.\n //\n // If the new playlist's timeline is the same as the last seen segment's timeline,\n // then a discontinuity can be added to identify that there's potentially missing\n // content. If there's no missing content, the discontinuity should still be rather\n // harmless. It's possible that if segment durations are accurate enough, that the\n // existence of a gap can be determined using the presentation times and durations,\n // but if the segment timing info is off, it may introduce more problems than simply\n // adding the discontinuity.\n //\n // If the new playlist's timeline is different from the last seen segment's timeline,\n // then a discontinuity can be added to identify that this is the first seen segment\n // of a new timeline. However, the logic at the start of this function that\n // determined the disconinuity sequence by timeline index is now off by one (the\n // discontinuity of the newest timeline hasn't yet fallen off the manifest...since\n // we added it), so the disconinuity sequence must be decremented.\n //\n // A period may also have a duration of zero, so the case of no segments is handled\n // here even though we don't yet support early available periods.\n\n if (!oldPlaylist.segments.length && playlist.timeline > oldPlaylist.timeline || oldPlaylist.segments.length && playlist.timeline > oldPlaylist.segments[oldPlaylist.segments.length - 1].timeline) {\n playlist.discontinuitySequence--;\n }\n\n return;\n } // If the first segment matched with a prior segment on a discontinuity (it's matching\n // on the first segment of a period), then the discontinuitySequence shouldn't be the\n // timeline's matching one, but instead should be the one prior, and the first segment\n // of the new manifest should be marked with a discontinuity.\n //\n // The reason for this special case is that discontinuity sequence shows how many\n // discontinuities have fallen off of the playlist, and discontinuities are marked on\n // the first segment of a new \"timeline.\" Because of this, while DASH will retain that\n // Period while the \"timeline\" exists, HLS keeps track of it via the discontinuity\n // sequence, and that first segment is an indicator, but can be removed before that\n // timeline is gone.\n\n\n const oldMatchingSegment = oldPlaylist.segments[oldMatchingSegmentIndex];\n\n if (oldMatchingSegment.discontinuity && !firstNewSegment.discontinuity) {\n firstNewSegment.discontinuity = true;\n playlist.discontinuityStarts.unshift(0);\n playlist.discontinuitySequence--;\n }\n\n updateMediaSequenceForPlaylist({\n playlist,\n mediaSequence: oldPlaylist.segments[oldMatchingSegmentIndex].number\n });\n });\n};\n/**\n * Given an old parsed manifest object and a new parsed manifest object, updates the\n * sequence and timing values within the new manifest to ensure that it lines up with the\n * old.\n *\n * @param {Array} oldManifest - the old main manifest object\n * @param {Array} newManifest - the new main manifest object\n *\n * @return {Object} the updated new manifest object\n */\n\nconst positionManifestOnTimeline = ({\n oldManifest,\n newManifest\n}) => {\n // Starting from v4.1.2 of the IOP, section 4.4.3.3 states:\n //\n // \"MPD@availabilityStartTime and Period@start shall not be changed over MPD updates.\"\n //\n // This was added from https://github.com/Dash-Industry-Forum/DASH-IF-IOP/issues/160\n //\n // Because of this change, and the difficulty of supporting periods with changing start\n // times, periods with changing start times are not supported. This makes the logic much\n // simpler, since periods with the same start time can be considerred the same period\n // across refreshes.\n //\n // To give an example as to the difficulty of handling periods where the start time may\n // change, if a single period manifest is refreshed with another manifest with a single\n // period, and both the start and end times are increased, then the only way to determine\n // if it's a new period or an old one that has changed is to look through the segments of\n // each playlist and determine the presentation time bounds to find a match. In addition,\n // if the period start changed to exceed the old period end, then there would be no\n // match, and it would not be possible to determine whether the refreshed period is a new\n // one or the old one.\n const oldPlaylists = oldManifest.playlists.concat(getMediaGroupPlaylists(oldManifest));\n const newPlaylists = newManifest.playlists.concat(getMediaGroupPlaylists(newManifest)); // Save all seen timelineStarts to the new manifest. Although this potentially means that\n // there's a \"memory leak\" in that it will never stop growing, in reality, only a couple\n // of properties are saved for each seen Period. Even long running live streams won't\n // generate too many Periods, unless the stream is watched for decades. In the future,\n // this can be optimized by mapping to discontinuity sequence numbers for each timeline,\n // but it may not become an issue, and the additional info can be useful for debugging.\n\n newManifest.timelineStarts = getUniqueTimelineStarts([oldManifest.timelineStarts, newManifest.timelineStarts]);\n updateSequenceNumbers({\n oldPlaylists,\n newPlaylists,\n timelineStarts: newManifest.timelineStarts\n });\n return newManifest;\n};\n\nconst generateSidxKey = sidx => sidx && sidx.uri + '-' + byteRangeToString(sidx.byterange);\n\nconst mergeDiscontiguousPlaylists = playlists => {\n // Break out playlists into groups based on their baseUrl\n const playlistsByBaseUrl = playlists.reduce(function (acc, cur) {\n if (!acc[cur.attributes.baseUrl]) {\n acc[cur.attributes.baseUrl] = [];\n }\n\n acc[cur.attributes.baseUrl].push(cur);\n return acc;\n }, {});\n let allPlaylists = [];\n Object.values(playlistsByBaseUrl).forEach(playlistGroup => {\n const mergedPlaylists = values(playlistGroup.reduce((acc, playlist) => {\n // assuming playlist IDs are the same across periods\n // TODO: handle multiperiod where representation sets are not the same\n // across periods\n const name = playlist.attributes.id + (playlist.attributes.lang || '');\n\n if (!acc[name]) {\n // First Period\n acc[name] = playlist;\n acc[name].attributes.timelineStarts = [];\n } else {\n // Subsequent Periods\n if (playlist.segments) {\n // first segment of subsequent periods signal a discontinuity\n if (playlist.segments[0]) {\n playlist.segments[0].discontinuity = true;\n }\n\n acc[name].segments.push(...playlist.segments);\n } // bubble up contentProtection, this assumes all DRM content\n // has the same contentProtection\n\n\n if (playlist.attributes.contentProtection) {\n acc[name].attributes.contentProtection = playlist.attributes.contentProtection;\n }\n }\n\n acc[name].attributes.timelineStarts.push({\n // Although they represent the same number, it's important to have both to make it\n // compatible with HLS potentially having a similar attribute.\n start: playlist.attributes.periodStart,\n timeline: playlist.attributes.periodStart\n });\n return acc;\n }, {}));\n allPlaylists = allPlaylists.concat(mergedPlaylists);\n });\n return allPlaylists.map(playlist => {\n playlist.discontinuityStarts = findIndexes(playlist.segments || [], 'discontinuity');\n return playlist;\n });\n};\n\nconst addSidxSegmentsToPlaylist = (playlist, sidxMapping) => {\n const sidxKey = generateSidxKey(playlist.sidx);\n const sidxMatch = sidxKey && sidxMapping[sidxKey] && sidxMapping[sidxKey].sidx;\n\n if (sidxMatch) {\n addSidxSegmentsToPlaylist$1(playlist, sidxMatch, playlist.sidx.resolvedUri);\n }\n\n return playlist;\n};\nconst addSidxSegmentsToPlaylists = (playlists, sidxMapping = {}) => {\n if (!Object.keys(sidxMapping).length) {\n return playlists;\n }\n\n for (const i in playlists) {\n playlists[i] = addSidxSegmentsToPlaylist(playlists[i], sidxMapping);\n }\n\n return playlists;\n};\nconst formatAudioPlaylist = ({\n attributes,\n segments,\n sidx,\n mediaSequence,\n discontinuitySequence,\n discontinuityStarts\n}, isAudioOnly) => {\n const playlist = {\n attributes: {\n NAME: attributes.id,\n BANDWIDTH: attributes.bandwidth,\n CODECS: attributes.codecs,\n ['PROGRAM-ID']: 1\n },\n uri: '',\n endList: attributes.type === 'static',\n timeline: attributes.periodStart,\n resolvedUri: attributes.baseUrl || '',\n targetDuration: attributes.duration,\n discontinuitySequence,\n discontinuityStarts,\n timelineStarts: attributes.timelineStarts,\n mediaSequence,\n segments\n };\n\n if (attributes.contentProtection) {\n playlist.contentProtection = attributes.contentProtection;\n }\n\n if (attributes.serviceLocation) {\n playlist.attributes.serviceLocation = attributes.serviceLocation;\n }\n\n if (sidx) {\n playlist.sidx = sidx;\n }\n\n if (isAudioOnly) {\n playlist.attributes.AUDIO = 'audio';\n playlist.attributes.SUBTITLES = 'subs';\n }\n\n return playlist;\n};\nconst formatVttPlaylist = ({\n attributes,\n segments,\n mediaSequence,\n discontinuityStarts,\n discontinuitySequence\n}) => {\n if (typeof segments === 'undefined') {\n // vtt tracks may use single file in BaseURL\n segments = [{\n uri: attributes.baseUrl,\n timeline: attributes.periodStart,\n resolvedUri: attributes.baseUrl || '',\n duration: attributes.sourceDuration,\n number: 0\n }]; // targetDuration should be the same duration as the only segment\n\n attributes.duration = attributes.sourceDuration;\n }\n\n const m3u8Attributes = {\n NAME: attributes.id,\n BANDWIDTH: attributes.bandwidth,\n ['PROGRAM-ID']: 1\n };\n\n if (attributes.codecs) {\n m3u8Attributes.CODECS = attributes.codecs;\n }\n\n const vttPlaylist = {\n attributes: m3u8Attributes,\n uri: '',\n endList: attributes.type === 'static',\n timeline: attributes.periodStart,\n resolvedUri: attributes.baseUrl || '',\n targetDuration: attributes.duration,\n timelineStarts: attributes.timelineStarts,\n discontinuityStarts,\n discontinuitySequence,\n mediaSequence,\n segments\n };\n\n if (attributes.serviceLocation) {\n vttPlaylist.attributes.serviceLocation = attributes.serviceLocation;\n }\n\n return vttPlaylist;\n};\nconst organizeAudioPlaylists = (playlists, sidxMapping = {}, isAudioOnly = false) => {\n let mainPlaylist;\n const formattedPlaylists = playlists.reduce((a, playlist) => {\n const role = playlist.attributes.role && playlist.attributes.role.value || '';\n const language = playlist.attributes.lang || '';\n let label = playlist.attributes.label || 'main';\n\n if (language && !playlist.attributes.label) {\n const roleLabel = role ? ` (${role})` : '';\n label = `${playlist.attributes.lang}${roleLabel}`;\n }\n\n if (!a[label]) {\n a[label] = {\n language,\n autoselect: true,\n default: role === 'main',\n playlists: [],\n uri: ''\n };\n }\n\n const formatted = addSidxSegmentsToPlaylist(formatAudioPlaylist(playlist, isAudioOnly), sidxMapping);\n a[label].playlists.push(formatted);\n\n if (typeof mainPlaylist === 'undefined' && role === 'main') {\n mainPlaylist = playlist;\n mainPlaylist.default = true;\n }\n\n return a;\n }, {}); // if no playlists have role \"main\", mark the first as main\n\n if (!mainPlaylist) {\n const firstLabel = Object.keys(formattedPlaylists)[0];\n formattedPlaylists[firstLabel].default = true;\n }\n\n return formattedPlaylists;\n};\nconst organizeVttPlaylists = (playlists, sidxMapping = {}) => {\n return playlists.reduce((a, playlist) => {\n const label = playlist.attributes.label || playlist.attributes.lang || 'text';\n const language = playlist.attributes.lang || 'und';\n\n if (!a[label]) {\n a[label] = {\n language,\n default: false,\n autoselect: false,\n playlists: [],\n uri: ''\n };\n }\n\n a[label].playlists.push(addSidxSegmentsToPlaylist(formatVttPlaylist(playlist), sidxMapping));\n return a;\n }, {});\n};\n\nconst organizeCaptionServices = captionServices => captionServices.reduce((svcObj, svc) => {\n if (!svc) {\n return svcObj;\n }\n\n svc.forEach(service => {\n const {\n channel,\n language\n } = service;\n svcObj[language] = {\n autoselect: false,\n default: false,\n instreamId: channel,\n language\n };\n\n if (service.hasOwnProperty('aspectRatio')) {\n svcObj[language].aspectRatio = service.aspectRatio;\n }\n\n if (service.hasOwnProperty('easyReader')) {\n svcObj[language].easyReader = service.easyReader;\n }\n\n if (service.hasOwnProperty('3D')) {\n svcObj[language]['3D'] = service['3D'];\n }\n });\n return svcObj;\n}, {});\n\nconst formatVideoPlaylist = ({\n attributes,\n segments,\n sidx,\n discontinuityStarts\n}) => {\n const playlist = {\n attributes: {\n NAME: attributes.id,\n AUDIO: 'audio',\n SUBTITLES: 'subs',\n RESOLUTION: {\n width: attributes.width,\n height: attributes.height\n },\n CODECS: attributes.codecs,\n BANDWIDTH: attributes.bandwidth,\n ['PROGRAM-ID']: 1\n },\n uri: '',\n endList: attributes.type === 'static',\n timeline: attributes.periodStart,\n resolvedUri: attributes.baseUrl || '',\n targetDuration: attributes.duration,\n discontinuityStarts,\n timelineStarts: attributes.timelineStarts,\n segments\n };\n\n if (attributes.frameRate) {\n playlist.attributes['FRAME-RATE'] = attributes.frameRate;\n }\n\n if (attributes.contentProtection) {\n playlist.contentProtection = attributes.contentProtection;\n }\n\n if (attributes.serviceLocation) {\n playlist.attributes.serviceLocation = attributes.serviceLocation;\n }\n\n if (sidx) {\n playlist.sidx = sidx;\n }\n\n return playlist;\n};\n\nconst videoOnly = ({\n attributes\n}) => attributes.mimeType === 'video/mp4' || attributes.mimeType === 'video/webm' || attributes.contentType === 'video';\n\nconst audioOnly = ({\n attributes\n}) => attributes.mimeType === 'audio/mp4' || attributes.mimeType === 'audio/webm' || attributes.contentType === 'audio';\n\nconst vttOnly = ({\n attributes\n}) => attributes.mimeType === 'text/vtt' || attributes.contentType === 'text';\n/**\n * Contains start and timeline properties denoting a timeline start. For DASH, these will\n * be the same number.\n *\n * @typedef {Object} TimelineStart\n * @property {number} start - the start time of the timeline\n * @property {number} timeline - the timeline number\n */\n\n/**\n * Adds appropriate media and discontinuity sequence values to the segments and playlists.\n *\n * Throughout mpd-parser, the `number` attribute is used in relation to `startNumber`, a\n * DASH specific attribute used in constructing segment URI's from templates. However, from\n * an HLS perspective, the `number` attribute on a segment would be its `mediaSequence`\n * value, which should start at the original media sequence value (or 0) and increment by 1\n * for each segment thereafter. Since DASH's `startNumber` values are independent per\n * period, it doesn't make sense to use it for `number`. Instead, assume everything starts\n * from a 0 mediaSequence value and increment from there.\n *\n * Note that VHS currently doesn't use the `number` property, but it can be helpful for\n * debugging and making sense of the manifest.\n *\n * For live playlists, to account for values increasing in manifests when periods are\n * removed on refreshes, merging logic should be used to update the numbers to their\n * appropriate values (to ensure they're sequential and increasing).\n *\n * @param {Object[]} playlists - the playlists to update\n * @param {TimelineStart[]} timelineStarts - the timeline starts for the manifest\n */\n\n\nconst addMediaSequenceValues = (playlists, timelineStarts) => {\n // increment all segments sequentially\n playlists.forEach(playlist => {\n playlist.mediaSequence = 0;\n playlist.discontinuitySequence = timelineStarts.findIndex(function ({\n timeline\n }) {\n return timeline === playlist.timeline;\n });\n\n if (!playlist.segments) {\n return;\n }\n\n playlist.segments.forEach((segment, index) => {\n segment.number = index;\n });\n });\n};\n/**\n * Given a media group object, flattens all playlists within the media group into a single\n * array.\n *\n * @param {Object} mediaGroupObject - the media group object\n *\n * @return {Object[]}\n * The media group playlists\n */\n\nconst flattenMediaGroupPlaylists = mediaGroupObject => {\n if (!mediaGroupObject) {\n return [];\n }\n\n return Object.keys(mediaGroupObject).reduce((acc, label) => {\n const labelContents = mediaGroupObject[label];\n return acc.concat(labelContents.playlists);\n }, []);\n};\nconst toM3u8 = ({\n dashPlaylists,\n locations,\n contentSteering,\n sidxMapping = {},\n previousManifest,\n eventStream\n}) => {\n if (!dashPlaylists.length) {\n return {};\n } // grab all main manifest attributes\n\n\n const {\n sourceDuration: duration,\n type,\n suggestedPresentationDelay,\n minimumUpdatePeriod\n } = dashPlaylists[0].attributes;\n const videoPlaylists = mergeDiscontiguousPlaylists(dashPlaylists.filter(videoOnly)).map(formatVideoPlaylist);\n const audioPlaylists = mergeDiscontiguousPlaylists(dashPlaylists.filter(audioOnly));\n const vttPlaylists = mergeDiscontiguousPlaylists(dashPlaylists.filter(vttOnly));\n const captions = dashPlaylists.map(playlist => playlist.attributes.captionServices).filter(Boolean);\n const manifest = {\n allowCache: true,\n discontinuityStarts: [],\n segments: [],\n endList: true,\n mediaGroups: {\n AUDIO: {},\n VIDEO: {},\n ['CLOSED-CAPTIONS']: {},\n SUBTITLES: {}\n },\n uri: '',\n duration,\n playlists: addSidxSegmentsToPlaylists(videoPlaylists, sidxMapping)\n };\n\n if (minimumUpdatePeriod >= 0) {\n manifest.minimumUpdatePeriod = minimumUpdatePeriod * 1000;\n }\n\n if (locations) {\n manifest.locations = locations;\n }\n\n if (contentSteering) {\n manifest.contentSteering = contentSteering;\n }\n\n if (type === 'dynamic') {\n manifest.suggestedPresentationDelay = suggestedPresentationDelay;\n }\n\n if (eventStream && eventStream.length > 0) {\n manifest.eventStream = eventStream;\n }\n\n const isAudioOnly = manifest.playlists.length === 0;\n const organizedAudioGroup = audioPlaylists.length ? organizeAudioPlaylists(audioPlaylists, sidxMapping, isAudioOnly) : null;\n const organizedVttGroup = vttPlaylists.length ? organizeVttPlaylists(vttPlaylists, sidxMapping) : null;\n const formattedPlaylists = videoPlaylists.concat(flattenMediaGroupPlaylists(organizedAudioGroup), flattenMediaGroupPlaylists(organizedVttGroup));\n const playlistTimelineStarts = formattedPlaylists.map(({\n timelineStarts\n }) => timelineStarts);\n manifest.timelineStarts = getUniqueTimelineStarts(playlistTimelineStarts);\n addMediaSequenceValues(formattedPlaylists, manifest.timelineStarts);\n\n if (organizedAudioGroup) {\n manifest.mediaGroups.AUDIO.audio = organizedAudioGroup;\n }\n\n if (organizedVttGroup) {\n manifest.mediaGroups.SUBTITLES.subs = organizedVttGroup;\n }\n\n if (captions.length) {\n manifest.mediaGroups['CLOSED-CAPTIONS'].cc = organizeCaptionServices(captions);\n }\n\n if (previousManifest) {\n return positionManifestOnTimeline({\n oldManifest: previousManifest,\n newManifest: manifest\n });\n }\n\n return manifest;\n};\n\n/**\n * Calculates the R (repetition) value for a live stream (for the final segment\n * in a manifest where the r value is negative 1)\n *\n * @param {Object} attributes\n * Object containing all inherited attributes from parent elements with attribute\n * names as keys\n * @param {number} time\n * current time (typically the total time up until the final segment)\n * @param {number} duration\n * duration property for the given \n *\n * @return {number}\n * R value to reach the end of the given period\n */\nconst getLiveRValue = (attributes, time, duration) => {\n const {\n NOW,\n clientOffset,\n availabilityStartTime,\n timescale = 1,\n periodStart = 0,\n minimumUpdatePeriod = 0\n } = attributes;\n const now = (NOW + clientOffset) / 1000;\n const periodStartWC = availabilityStartTime + periodStart;\n const periodEndWC = now + minimumUpdatePeriod;\n const periodDuration = periodEndWC - periodStartWC;\n return Math.ceil((periodDuration * timescale - time) / duration);\n};\n/**\n * Uses information provided by SegmentTemplate.SegmentTimeline to determine segment\n * timing and duration\n *\n * @param {Object} attributes\n * Object containing all inherited attributes from parent elements with attribute\n * names as keys\n * @param {Object[]} segmentTimeline\n * List of objects representing the attributes of each S element contained within\n *\n * @return {{number: number, duration: number, time: number, timeline: number}[]}\n * List of Objects with segment timing and duration info\n */\n\n\nconst parseByTimeline = (attributes, segmentTimeline) => {\n const {\n type,\n minimumUpdatePeriod = 0,\n media = '',\n sourceDuration,\n timescale = 1,\n startNumber = 1,\n periodStart: timeline\n } = attributes;\n const segments = [];\n let time = -1;\n\n for (let sIndex = 0; sIndex < segmentTimeline.length; sIndex++) {\n const S = segmentTimeline[sIndex];\n const duration = S.d;\n const repeat = S.r || 0;\n const segmentTime = S.t || 0;\n\n if (time < 0) {\n // first segment\n time = segmentTime;\n }\n\n if (segmentTime && segmentTime > time) {\n // discontinuity\n // TODO: How to handle this type of discontinuity\n // timeline++ here would treat it like HLS discontuity and content would\n // get appended without gap\n // E.G.\n // \n // \n // \n // \n // would have $Time$ values of [0, 1, 2, 5]\n // should this be appened at time positions [0, 1, 2, 3],(#EXT-X-DISCONTINUITY)\n // or [0, 1, 2, gap, gap, 5]? (#EXT-X-GAP)\n // does the value of sourceDuration consider this when calculating arbitrary\n // negative @r repeat value?\n // E.G. Same elements as above with this added at the end\n // \n // with a sourceDuration of 10\n // Would the 2 gaps be included in the time duration calculations resulting in\n // 8 segments with $Time$ values of [0, 1, 2, 5, 6, 7, 8, 9] or 10 segments\n // with $Time$ values of [0, 1, 2, 5, 6, 7, 8, 9, 10, 11] ?\n time = segmentTime;\n }\n\n let count;\n\n if (repeat < 0) {\n const nextS = sIndex + 1;\n\n if (nextS === segmentTimeline.length) {\n // last segment\n if (type === 'dynamic' && minimumUpdatePeriod > 0 && media.indexOf('$Number$') > 0) {\n count = getLiveRValue(attributes, time, duration);\n } else {\n // TODO: This may be incorrect depending on conclusion of TODO above\n count = (sourceDuration * timescale - time) / duration;\n }\n } else {\n count = (segmentTimeline[nextS].t - time) / duration;\n }\n } else {\n count = repeat + 1;\n }\n\n const end = startNumber + segments.length + count;\n let number = startNumber + segments.length;\n\n while (number < end) {\n segments.push({\n number,\n duration: duration / timescale,\n time,\n timeline\n });\n time += duration;\n number++;\n }\n }\n\n return segments;\n};\n\nconst identifierPattern = /\\$([A-z]*)(?:(%0)([0-9]+)d)?\\$/g;\n/**\n * Replaces template identifiers with corresponding values. To be used as the callback\n * for String.prototype.replace\n *\n * @name replaceCallback\n * @function\n * @param {string} match\n * Entire match of identifier\n * @param {string} identifier\n * Name of matched identifier\n * @param {string} format\n * Format tag string. Its presence indicates that padding is expected\n * @param {string} width\n * Desired length of the replaced value. Values less than this width shall be left\n * zero padded\n * @return {string}\n * Replacement for the matched identifier\n */\n\n/**\n * Returns a function to be used as a callback for String.prototype.replace to replace\n * template identifiers\n *\n * @param {Obect} values\n * Object containing values that shall be used to replace known identifiers\n * @param {number} values.RepresentationID\n * Value of the Representation@id attribute\n * @param {number} values.Number\n * Number of the corresponding segment\n * @param {number} values.Bandwidth\n * Value of the Representation@bandwidth attribute.\n * @param {number} values.Time\n * Timestamp value of the corresponding segment\n * @return {replaceCallback}\n * Callback to be used with String.prototype.replace to replace identifiers\n */\n\nconst identifierReplacement = values => (match, identifier, format, width) => {\n if (match === '$$') {\n // escape sequence\n return '$';\n }\n\n if (typeof values[identifier] === 'undefined') {\n return match;\n }\n\n const value = '' + values[identifier];\n\n if (identifier === 'RepresentationID') {\n // Format tag shall not be present with RepresentationID\n return value;\n }\n\n if (!format) {\n width = 1;\n } else {\n width = parseInt(width, 10);\n }\n\n if (value.length >= width) {\n return value;\n }\n\n return `${new Array(width - value.length + 1).join('0')}${value}`;\n};\n/**\n * Constructs a segment url from a template string\n *\n * @param {string} url\n * Template string to construct url from\n * @param {Obect} values\n * Object containing values that shall be used to replace known identifiers\n * @param {number} values.RepresentationID\n * Value of the Representation@id attribute\n * @param {number} values.Number\n * Number of the corresponding segment\n * @param {number} values.Bandwidth\n * Value of the Representation@bandwidth attribute.\n * @param {number} values.Time\n * Timestamp value of the corresponding segment\n * @return {string}\n * Segment url with identifiers replaced\n */\n\nconst constructTemplateUrl = (url, values) => url.replace(identifierPattern, identifierReplacement(values));\n/**\n * Generates a list of objects containing timing and duration information about each\n * segment needed to generate segment uris and the complete segment object\n *\n * @param {Object} attributes\n * Object containing all inherited attributes from parent elements with attribute\n * names as keys\n * @param {Object[]|undefined} segmentTimeline\n * List of objects representing the attributes of each S element contained within\n * the SegmentTimeline element\n * @return {{number: number, duration: number, time: number, timeline: number}[]}\n * List of Objects with segment timing and duration info\n */\n\nconst parseTemplateInfo = (attributes, segmentTimeline) => {\n if (!attributes.duration && !segmentTimeline) {\n // if neither @duration or SegmentTimeline are present, then there shall be exactly\n // one media segment\n return [{\n number: attributes.startNumber || 1,\n duration: attributes.sourceDuration,\n time: 0,\n timeline: attributes.periodStart\n }];\n }\n\n if (attributes.duration) {\n return parseByDuration(attributes);\n }\n\n return parseByTimeline(attributes, segmentTimeline);\n};\n/**\n * Generates a list of segments using information provided by the SegmentTemplate element\n *\n * @param {Object} attributes\n * Object containing all inherited attributes from parent elements with attribute\n * names as keys\n * @param {Object[]|undefined} segmentTimeline\n * List of objects representing the attributes of each S element contained within\n * the SegmentTimeline element\n * @return {Object[]}\n * List of segment objects\n */\n\nconst segmentsFromTemplate = (attributes, segmentTimeline) => {\n const templateValues = {\n RepresentationID: attributes.id,\n Bandwidth: attributes.bandwidth || 0\n };\n const {\n initialization = {\n sourceURL: '',\n range: ''\n }\n } = attributes;\n const mapSegment = urlTypeToSegment({\n baseUrl: attributes.baseUrl,\n source: constructTemplateUrl(initialization.sourceURL, templateValues),\n range: initialization.range\n });\n const segments = parseTemplateInfo(attributes, segmentTimeline);\n return segments.map(segment => {\n templateValues.Number = segment.number;\n templateValues.Time = segment.time;\n const uri = constructTemplateUrl(attributes.media || '', templateValues); // See DASH spec section 5.3.9.2.2\n // - if timescale isn't present on any level, default to 1.\n\n const timescale = attributes.timescale || 1; // - if presentationTimeOffset isn't present on any level, default to 0\n\n const presentationTimeOffset = attributes.presentationTimeOffset || 0;\n const presentationTime = // Even if the @t attribute is not specified for the segment, segment.time is\n // calculated in mpd-parser prior to this, so it's assumed to be available.\n attributes.periodStart + (segment.time - presentationTimeOffset) / timescale;\n const map = {\n uri,\n timeline: segment.timeline,\n duration: segment.duration,\n resolvedUri: resolveUrl(attributes.baseUrl || '', uri),\n map: mapSegment,\n number: segment.number,\n presentationTime\n };\n return map;\n });\n};\n\n/**\n * Converts a (of type URLType from the DASH spec 5.3.9.2 Table 14)\n * to an object that matches the output of a segment in videojs/mpd-parser\n *\n * @param {Object} attributes\n * Object containing all inherited attributes from parent elements with attribute\n * names as keys\n * @param {Object} segmentUrl\n * node to translate into a segment object\n * @return {Object} translated segment object\n */\n\nconst SegmentURLToSegmentObject = (attributes, segmentUrl) => {\n const {\n baseUrl,\n initialization = {}\n } = attributes;\n const initSegment = urlTypeToSegment({\n baseUrl,\n source: initialization.sourceURL,\n range: initialization.range\n });\n const segment = urlTypeToSegment({\n baseUrl,\n source: segmentUrl.media,\n range: segmentUrl.mediaRange\n });\n segment.map = initSegment;\n return segment;\n};\n/**\n * Generates a list of segments using information provided by the SegmentList element\n * SegmentList (DASH SPEC Section 5.3.9.3.2) contains a set of nodes. Each\n * node should be translated into segment.\n *\n * @param {Object} attributes\n * Object containing all inherited attributes from parent elements with attribute\n * names as keys\n * @param {Object[]|undefined} segmentTimeline\n * List of objects representing the attributes of each S element contained within\n * the SegmentTimeline element\n * @return {Object.} list of segments\n */\n\n\nconst segmentsFromList = (attributes, segmentTimeline) => {\n const {\n duration,\n segmentUrls = [],\n periodStart\n } = attributes; // Per spec (5.3.9.2.1) no way to determine segment duration OR\n // if both SegmentTimeline and @duration are defined, it is outside of spec.\n\n if (!duration && !segmentTimeline || duration && segmentTimeline) {\n throw new Error(errors.SEGMENT_TIME_UNSPECIFIED);\n }\n\n const segmentUrlMap = segmentUrls.map(segmentUrlObject => SegmentURLToSegmentObject(attributes, segmentUrlObject));\n let segmentTimeInfo;\n\n if (duration) {\n segmentTimeInfo = parseByDuration(attributes);\n }\n\n if (segmentTimeline) {\n segmentTimeInfo = parseByTimeline(attributes, segmentTimeline);\n }\n\n const segments = segmentTimeInfo.map((segmentTime, index) => {\n if (segmentUrlMap[index]) {\n const segment = segmentUrlMap[index]; // See DASH spec section 5.3.9.2.2\n // - if timescale isn't present on any level, default to 1.\n\n const timescale = attributes.timescale || 1; // - if presentationTimeOffset isn't present on any level, default to 0\n\n const presentationTimeOffset = attributes.presentationTimeOffset || 0;\n segment.timeline = segmentTime.timeline;\n segment.duration = segmentTime.duration;\n segment.number = segmentTime.number;\n segment.presentationTime = periodStart + (segmentTime.time - presentationTimeOffset) / timescale;\n return segment;\n } // Since we're mapping we should get rid of any blank segments (in case\n // the given SegmentTimeline is handling for more elements than we have\n // SegmentURLs for).\n\n }).filter(segment => segment);\n return segments;\n};\n\nconst generateSegments = ({\n attributes,\n segmentInfo\n}) => {\n let segmentAttributes;\n let segmentsFn;\n\n if (segmentInfo.template) {\n segmentsFn = segmentsFromTemplate;\n segmentAttributes = merge(attributes, segmentInfo.template);\n } else if (segmentInfo.base) {\n segmentsFn = segmentsFromBase;\n segmentAttributes = merge(attributes, segmentInfo.base);\n } else if (segmentInfo.list) {\n segmentsFn = segmentsFromList;\n segmentAttributes = merge(attributes, segmentInfo.list);\n }\n\n const segmentsInfo = {\n attributes\n };\n\n if (!segmentsFn) {\n return segmentsInfo;\n }\n\n const segments = segmentsFn(segmentAttributes, segmentInfo.segmentTimeline); // The @duration attribute will be used to determin the playlist's targetDuration which\n // must be in seconds. Since we've generated the segment list, we no longer need\n // @duration to be in @timescale units, so we can convert it here.\n\n if (segmentAttributes.duration) {\n const {\n duration,\n timescale = 1\n } = segmentAttributes;\n segmentAttributes.duration = duration / timescale;\n } else if (segments.length) {\n // if there is no @duration attribute, use the largest segment duration as\n // as target duration\n segmentAttributes.duration = segments.reduce((max, segment) => {\n return Math.max(max, Math.ceil(segment.duration));\n }, 0);\n } else {\n segmentAttributes.duration = 0;\n }\n\n segmentsInfo.attributes = segmentAttributes;\n segmentsInfo.segments = segments; // This is a sidx box without actual segment information\n\n if (segmentInfo.base && segmentAttributes.indexRange) {\n segmentsInfo.sidx = segments[0];\n segmentsInfo.segments = [];\n }\n\n return segmentsInfo;\n};\nconst toPlaylists = representations => representations.map(generateSegments);\n\nconst findChildren = (element, name) => from(element.childNodes).filter(({\n tagName\n}) => tagName === name);\nconst getContent = element => element.textContent.trim();\n\n/**\n * Converts the provided string that may contain a division operation to a number.\n *\n * @param {string} value - the provided string value\n *\n * @return {number} the parsed string value\n */\nconst parseDivisionValue = value => {\n return parseFloat(value.split('/').reduce((prev, current) => prev / current));\n};\n\nconst parseDuration = str => {\n const SECONDS_IN_YEAR = 365 * 24 * 60 * 60;\n const SECONDS_IN_MONTH = 30 * 24 * 60 * 60;\n const SECONDS_IN_DAY = 24 * 60 * 60;\n const SECONDS_IN_HOUR = 60 * 60;\n const SECONDS_IN_MIN = 60; // P10Y10M10DT10H10M10.1S\n\n const durationRegex = /P(?:(\\d*)Y)?(?:(\\d*)M)?(?:(\\d*)D)?(?:T(?:(\\d*)H)?(?:(\\d*)M)?(?:([\\d.]*)S)?)?/;\n const match = durationRegex.exec(str);\n\n if (!match) {\n return 0;\n }\n\n const [year, month, day, hour, minute, second] = match.slice(1);\n 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);\n};\nconst parseDate = str => {\n // Date format without timezone according to ISO 8601\n // YYY-MM-DDThh:mm:ss.ssssss\n const dateRegex = /^\\d+-\\d+-\\d+T\\d+:\\d+:\\d+(\\.\\d+)?$/; // If the date string does not specifiy a timezone, we must specifiy UTC. This is\n // expressed by ending with 'Z'\n\n if (dateRegex.test(str)) {\n str += 'Z';\n }\n\n return Date.parse(str);\n};\n\nconst parsers = {\n /**\n * Specifies the duration of the entire Media Presentation. Format is a duration string\n * as specified in ISO 8601\n *\n * @param {string} value\n * value of attribute as a string\n * @return {number}\n * The duration in seconds\n */\n mediaPresentationDuration(value) {\n return parseDuration(value);\n },\n\n /**\n * Specifies the Segment availability start time for all Segments referred to in this\n * MPD. For a dynamic manifest, it specifies the anchor for the earliest availability\n * time. Format is a date string as specified in ISO 8601\n *\n * @param {string} value\n * value of attribute as a string\n * @return {number}\n * The date as seconds from unix epoch\n */\n availabilityStartTime(value) {\n return parseDate(value) / 1000;\n },\n\n /**\n * Specifies the smallest period between potential changes to the MPD. Format is a\n * duration string as specified in ISO 8601\n *\n * @param {string} value\n * value of attribute as a string\n * @return {number}\n * The duration in seconds\n */\n minimumUpdatePeriod(value) {\n return parseDuration(value);\n },\n\n /**\n * Specifies the suggested presentation delay. Format is a\n * duration string as specified in ISO 8601\n *\n * @param {string} value\n * value of attribute as a string\n * @return {number}\n * The duration in seconds\n */\n suggestedPresentationDelay(value) {\n return parseDuration(value);\n },\n\n /**\n * specifices the type of mpd. Can be either \"static\" or \"dynamic\"\n *\n * @param {string} value\n * value of attribute as a string\n *\n * @return {string}\n * The type as a string\n */\n type(value) {\n return value;\n },\n\n /**\n * Specifies the duration of the smallest time shifting buffer for any Representation\n * in the MPD. Format is a duration string as specified in ISO 8601\n *\n * @param {string} value\n * value of attribute as a string\n * @return {number}\n * The duration in seconds\n */\n timeShiftBufferDepth(value) {\n return parseDuration(value);\n },\n\n /**\n * Specifies the PeriodStart time of the Period relative to the availabilityStarttime.\n * Format is a duration string as specified in ISO 8601\n *\n * @param {string} value\n * value of attribute as a string\n * @return {number}\n * The duration in seconds\n */\n start(value) {\n return parseDuration(value);\n },\n\n /**\n * Specifies the width of the visual presentation\n *\n * @param {string} value\n * value of attribute as a string\n * @return {number}\n * The parsed width\n */\n width(value) {\n return parseInt(value, 10);\n },\n\n /**\n * Specifies the height of the visual presentation\n *\n * @param {string} value\n * value of attribute as a string\n * @return {number}\n * The parsed height\n */\n height(value) {\n return parseInt(value, 10);\n },\n\n /**\n * Specifies the bitrate of the representation\n *\n * @param {string} value\n * value of attribute as a string\n * @return {number}\n * The parsed bandwidth\n */\n bandwidth(value) {\n return parseInt(value, 10);\n },\n\n /**\n * Specifies the frame rate of the representation\n *\n * @param {string} value\n * value of attribute as a string\n * @return {number}\n * The parsed frame rate\n */\n frameRate(value) {\n return parseDivisionValue(value);\n },\n\n /**\n * Specifies the number of the first Media Segment in this Representation in the Period\n *\n * @param {string} value\n * value of attribute as a string\n * @return {number}\n * The parsed number\n */\n startNumber(value) {\n return parseInt(value, 10);\n },\n\n /**\n * Specifies the timescale in units per seconds\n *\n * @param {string} value\n * value of attribute as a string\n * @return {number}\n * The parsed timescale\n */\n timescale(value) {\n return parseInt(value, 10);\n },\n\n /**\n * Specifies the presentationTimeOffset.\n *\n * @param {string} value\n * value of the attribute as a string\n *\n * @return {number}\n * The parsed presentationTimeOffset\n */\n presentationTimeOffset(value) {\n return parseInt(value, 10);\n },\n\n /**\n * Specifies the constant approximate Segment duration\n * NOTE: The element also contains an @duration attribute. This duration\n * specifies the duration of the Period. This attribute is currently not\n * supported by the rest of the parser, however we still check for it to prevent\n * errors.\n *\n * @param {string} value\n * value of attribute as a string\n * @return {number}\n * The parsed duration\n */\n duration(value) {\n const parsedValue = parseInt(value, 10);\n\n if (isNaN(parsedValue)) {\n return parseDuration(value);\n }\n\n return parsedValue;\n },\n\n /**\n * Specifies the Segment duration, in units of the value of the @timescale.\n *\n * @param {string} value\n * value of attribute as a string\n * @return {number}\n * The parsed duration\n */\n d(value) {\n return parseInt(value, 10);\n },\n\n /**\n * Specifies the MPD start time, in @timescale units, the first Segment in the series\n * starts relative to the beginning of the Period\n *\n * @param {string} value\n * value of attribute as a string\n * @return {number}\n * The parsed time\n */\n t(value) {\n return parseInt(value, 10);\n },\n\n /**\n * Specifies the repeat count of the number of following contiguous Segments with the\n * same duration expressed by the value of @d\n *\n * @param {string} value\n * value of attribute as a string\n * @return {number}\n * The parsed number\n */\n r(value) {\n return parseInt(value, 10);\n },\n\n /**\n * Specifies the presentationTime.\n *\n * @param {string} value\n * value of the attribute as a string\n *\n * @return {number}\n * The parsed presentationTime\n */\n presentationTime(value) {\n return parseInt(value, 10);\n },\n\n /**\n * Default parser for all other attributes. Acts as a no-op and just returns the value\n * as a string\n *\n * @param {string} value\n * value of attribute as a string\n * @return {string}\n * Unparsed value\n */\n DEFAULT(value) {\n return value;\n }\n\n};\n/**\n * Gets all the attributes and values of the provided node, parses attributes with known\n * types, and returns an object with attribute names mapped to values.\n *\n * @param {Node} el\n * The node to parse attributes from\n * @return {Object}\n * Object with all attributes of el parsed\n */\n\nconst parseAttributes = el => {\n if (!(el && el.attributes)) {\n return {};\n }\n\n return from(el.attributes).reduce((a, e) => {\n const parseFn = parsers[e.name] || parsers.DEFAULT;\n a[e.name] = parseFn(e.value);\n return a;\n }, {});\n};\n\nconst keySystemsMap = {\n 'urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b': 'org.w3.clearkey',\n 'urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed': 'com.widevine.alpha',\n 'urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95': 'com.microsoft.playready',\n 'urn:uuid:f239e769-efa3-4850-9c16-a903c6932efb': 'com.adobe.primetime',\n // ISO_IEC 23009-1_2022 5.8.5.2.2 The mp4 Protection Scheme\n 'urn:mpeg:dash:mp4protection:2011': 'mp4protection'\n};\n/**\n * Builds a list of urls that is the product of the reference urls and BaseURL values\n *\n * @param {Object[]} references\n * List of objects containing the reference URL as well as its attributes\n * @param {Node[]} baseUrlElements\n * List of BaseURL nodes from the mpd\n * @return {Object[]}\n * List of objects with resolved urls and attributes\n */\n\nconst buildBaseUrls = (references, baseUrlElements) => {\n if (!baseUrlElements.length) {\n return references;\n }\n\n return flatten(references.map(function (reference) {\n return baseUrlElements.map(function (baseUrlElement) {\n const initialBaseUrl = getContent(baseUrlElement);\n const resolvedBaseUrl = resolveUrl(reference.baseUrl, initialBaseUrl);\n const finalBaseUrl = merge(parseAttributes(baseUrlElement), {\n baseUrl: resolvedBaseUrl\n }); // If the URL is resolved, we want to get the serviceLocation from the reference\n // assuming there is no serviceLocation on the initialBaseUrl\n\n if (resolvedBaseUrl !== initialBaseUrl && !finalBaseUrl.serviceLocation && reference.serviceLocation) {\n finalBaseUrl.serviceLocation = reference.serviceLocation;\n }\n\n return finalBaseUrl;\n });\n }));\n};\n/**\n * Contains all Segment information for its containing AdaptationSet\n *\n * @typedef {Object} SegmentInformation\n * @property {Object|undefined} template\n * Contains the attributes for the SegmentTemplate node\n * @property {Object[]|undefined} segmentTimeline\n * Contains a list of atrributes for each S node within the SegmentTimeline node\n * @property {Object|undefined} list\n * Contains the attributes for the SegmentList node\n * @property {Object|undefined} base\n * Contains the attributes for the SegmentBase node\n */\n\n/**\n * Returns all available Segment information contained within the AdaptationSet node\n *\n * @param {Node} adaptationSet\n * The AdaptationSet node to get Segment information from\n * @return {SegmentInformation}\n * The Segment information contained within the provided AdaptationSet\n */\n\nconst getSegmentInformation = adaptationSet => {\n const segmentTemplate = findChildren(adaptationSet, 'SegmentTemplate')[0];\n const segmentList = findChildren(adaptationSet, 'SegmentList')[0];\n const segmentUrls = segmentList && findChildren(segmentList, 'SegmentURL').map(s => merge({\n tag: 'SegmentURL'\n }, parseAttributes(s)));\n const segmentBase = findChildren(adaptationSet, 'SegmentBase')[0];\n const segmentTimelineParentNode = segmentList || segmentTemplate;\n const segmentTimeline = segmentTimelineParentNode && findChildren(segmentTimelineParentNode, 'SegmentTimeline')[0];\n const segmentInitializationParentNode = segmentList || segmentBase || segmentTemplate;\n const segmentInitialization = segmentInitializationParentNode && findChildren(segmentInitializationParentNode, 'Initialization')[0]; // SegmentTemplate is handled slightly differently, since it can have both\n // @initialization and an node. @initialization can be templated,\n // while the node can have a url and range specified. If the has\n // both @initialization and an subelement we opt to override with\n // the node, as this interaction is not defined in the spec.\n\n const template = segmentTemplate && parseAttributes(segmentTemplate);\n\n if (template && segmentInitialization) {\n template.initialization = segmentInitialization && parseAttributes(segmentInitialization);\n } else if (template && template.initialization) {\n // If it is @initialization we convert it to an object since this is the format that\n // later functions will rely on for the initialization segment. This is only valid\n // for \n template.initialization = {\n sourceURL: template.initialization\n };\n }\n\n const segmentInfo = {\n template,\n segmentTimeline: segmentTimeline && findChildren(segmentTimeline, 'S').map(s => parseAttributes(s)),\n list: segmentList && merge(parseAttributes(segmentList), {\n segmentUrls,\n initialization: parseAttributes(segmentInitialization)\n }),\n base: segmentBase && merge(parseAttributes(segmentBase), {\n initialization: parseAttributes(segmentInitialization)\n })\n };\n Object.keys(segmentInfo).forEach(key => {\n if (!segmentInfo[key]) {\n delete segmentInfo[key];\n }\n });\n return segmentInfo;\n};\n/**\n * Contains Segment information and attributes needed to construct a Playlist object\n * from a Representation\n *\n * @typedef {Object} RepresentationInformation\n * @property {SegmentInformation} segmentInfo\n * Segment information for this Representation\n * @property {Object} attributes\n * Inherited attributes for this Representation\n */\n\n/**\n * Maps a Representation node to an object containing Segment information and attributes\n *\n * @name inheritBaseUrlsCallback\n * @function\n * @param {Node} representation\n * Representation node from the mpd\n * @return {RepresentationInformation}\n * Representation information needed to construct a Playlist object\n */\n\n/**\n * Returns a callback for Array.prototype.map for mapping Representation nodes to\n * Segment information and attributes using inherited BaseURL nodes.\n *\n * @param {Object} adaptationSetAttributes\n * Contains attributes inherited by the AdaptationSet\n * @param {Object[]} adaptationSetBaseUrls\n * List of objects containing resolved base URLs and attributes\n * inherited by the AdaptationSet\n * @param {SegmentInformation} adaptationSetSegmentInfo\n * Contains Segment information for the AdaptationSet\n * @return {inheritBaseUrlsCallback}\n * Callback map function\n */\n\nconst inheritBaseUrls = (adaptationSetAttributes, adaptationSetBaseUrls, adaptationSetSegmentInfo) => representation => {\n const repBaseUrlElements = findChildren(representation, 'BaseURL');\n const repBaseUrls = buildBaseUrls(adaptationSetBaseUrls, repBaseUrlElements);\n const attributes = merge(adaptationSetAttributes, parseAttributes(representation));\n const representationSegmentInfo = getSegmentInformation(representation);\n return repBaseUrls.map(baseUrl => {\n return {\n segmentInfo: merge(adaptationSetSegmentInfo, representationSegmentInfo),\n attributes: merge(attributes, baseUrl)\n };\n });\n};\n/**\n * Tranforms a series of content protection nodes to\n * an object containing pssh data by key system\n *\n * @param {Node[]} contentProtectionNodes\n * Content protection nodes\n * @return {Object}\n * Object containing pssh data by key system\n */\n\nconst generateKeySystemInformation = contentProtectionNodes => {\n return contentProtectionNodes.reduce((acc, node) => {\n const attributes = parseAttributes(node); // Although it could be argued that according to the UUID RFC spec the UUID string (a-f chars) should be generated\n // as a lowercase string it also mentions it should be treated as case-insensitive on input. Since the key system\n // UUIDs in the keySystemsMap are hardcoded as lowercase in the codebase there isn't any reason not to do\n // .toLowerCase() on the input UUID string from the manifest (at least I could not think of one).\n\n if (attributes.schemeIdUri) {\n attributes.schemeIdUri = attributes.schemeIdUri.toLowerCase();\n }\n\n const keySystem = keySystemsMap[attributes.schemeIdUri];\n\n if (keySystem) {\n acc[keySystem] = {\n attributes\n };\n const psshNode = findChildren(node, 'cenc:pssh')[0];\n\n if (psshNode) {\n const pssh = getContent(psshNode);\n acc[keySystem].pssh = pssh && decodeB64ToUint8Array(pssh);\n }\n }\n\n return acc;\n }, {});\n}; // defined in ANSI_SCTE 214-1 2016\n\n\nconst parseCaptionServiceMetadata = service => {\n // 608 captions\n if (service.schemeIdUri === 'urn:scte:dash:cc:cea-608:2015') {\n const values = typeof service.value !== 'string' ? [] : service.value.split(';');\n return values.map(value => {\n let channel;\n let language; // default language to value\n\n language = value;\n\n if (/^CC\\d=/.test(value)) {\n [channel, language] = value.split('=');\n } else if (/^CC\\d$/.test(value)) {\n channel = value;\n }\n\n return {\n channel,\n language\n };\n });\n } else if (service.schemeIdUri === 'urn:scte:dash:cc:cea-708:2015') {\n const values = typeof service.value !== 'string' ? [] : service.value.split(';');\n return values.map(value => {\n const flags = {\n // service or channel number 1-63\n 'channel': undefined,\n // language is a 3ALPHA per ISO 639.2/B\n // field is required\n 'language': undefined,\n // BIT 1/0 or ?\n // default value is 1, meaning 16:9 aspect ratio, 0 is 4:3, ? is unknown\n 'aspectRatio': 1,\n // BIT 1/0\n // easy reader flag indicated the text is tailed to the needs of beginning readers\n // default 0, or off\n 'easyReader': 0,\n // BIT 1/0\n // If 3d metadata is present (CEA-708.1) then 1\n // default 0\n '3D': 0\n };\n\n if (/=/.test(value)) {\n const [channel, opts = ''] = value.split('=');\n flags.channel = channel;\n flags.language = value;\n opts.split(',').forEach(opt => {\n const [name, val] = opt.split(':');\n\n if (name === 'lang') {\n flags.language = val; // er for easyReadery\n } else if (name === 'er') {\n flags.easyReader = Number(val); // war for wide aspect ratio\n } else if (name === 'war') {\n flags.aspectRatio = Number(val);\n } else if (name === '3D') {\n flags['3D'] = Number(val);\n }\n });\n } else {\n flags.language = value;\n }\n\n if (flags.channel) {\n flags.channel = 'SERVICE' + flags.channel;\n }\n\n return flags;\n });\n }\n};\n/**\n * A map callback that will parse all event stream data for a collection of periods\n * DASH ISO_IEC_23009 5.10.2.2\n * https://dashif-documents.azurewebsites.net/Events/master/event.html#mpd-event-timing\n *\n * @param {PeriodInformation} period object containing necessary period information\n * @return a collection of parsed eventstream event objects\n */\n\nconst toEventStream = period => {\n // get and flatten all EventStreams tags and parse attributes and children\n return flatten(findChildren(period.node, 'EventStream').map(eventStream => {\n const eventStreamAttributes = parseAttributes(eventStream);\n const schemeIdUri = eventStreamAttributes.schemeIdUri; // find all Events per EventStream tag and map to return objects\n\n return findChildren(eventStream, 'Event').map(event => {\n const eventAttributes = parseAttributes(event);\n const presentationTime = eventAttributes.presentationTime || 0;\n const timescale = eventStreamAttributes.timescale || 1;\n const duration = eventAttributes.duration || 0;\n const start = presentationTime / timescale + period.attributes.start;\n return {\n schemeIdUri,\n value: eventStreamAttributes.value,\n id: eventAttributes.id,\n start,\n end: start + duration / timescale,\n messageData: getContent(event) || eventAttributes.messageData,\n contentEncoding: eventStreamAttributes.contentEncoding,\n presentationTimeOffset: eventStreamAttributes.presentationTimeOffset || 0\n };\n });\n }));\n};\n/**\n * Maps an AdaptationSet node to a list of Representation information objects\n *\n * @name toRepresentationsCallback\n * @function\n * @param {Node} adaptationSet\n * AdaptationSet node from the mpd\n * @return {RepresentationInformation[]}\n * List of objects containing Representaion information\n */\n\n/**\n * Returns a callback for Array.prototype.map for mapping AdaptationSet nodes to a list of\n * Representation information objects\n *\n * @param {Object} periodAttributes\n * Contains attributes inherited by the Period\n * @param {Object[]} periodBaseUrls\n * Contains list of objects with resolved base urls and attributes\n * inherited by the Period\n * @param {string[]} periodSegmentInfo\n * Contains Segment Information at the period level\n * @return {toRepresentationsCallback}\n * Callback map function\n */\n\nconst toRepresentations = (periodAttributes, periodBaseUrls, periodSegmentInfo) => adaptationSet => {\n const adaptationSetAttributes = parseAttributes(adaptationSet);\n const adaptationSetBaseUrls = buildBaseUrls(periodBaseUrls, findChildren(adaptationSet, 'BaseURL'));\n const role = findChildren(adaptationSet, 'Role')[0];\n const roleAttributes = {\n role: parseAttributes(role)\n };\n let attrs = merge(periodAttributes, adaptationSetAttributes, roleAttributes);\n const accessibility = findChildren(adaptationSet, 'Accessibility')[0];\n const captionServices = parseCaptionServiceMetadata(parseAttributes(accessibility));\n\n if (captionServices) {\n attrs = merge(attrs, {\n captionServices\n });\n }\n\n const label = findChildren(adaptationSet, 'Label')[0];\n\n if (label && label.childNodes.length) {\n const labelVal = label.childNodes[0].nodeValue.trim();\n attrs = merge(attrs, {\n label: labelVal\n });\n }\n\n const contentProtection = generateKeySystemInformation(findChildren(adaptationSet, 'ContentProtection'));\n\n if (Object.keys(contentProtection).length) {\n attrs = merge(attrs, {\n contentProtection\n });\n }\n\n const segmentInfo = getSegmentInformation(adaptationSet);\n const representations = findChildren(adaptationSet, 'Representation');\n const adaptationSetSegmentInfo = merge(periodSegmentInfo, segmentInfo);\n return flatten(representations.map(inheritBaseUrls(attrs, adaptationSetBaseUrls, adaptationSetSegmentInfo)));\n};\n/**\n * Contains all period information for mapping nodes onto adaptation sets.\n *\n * @typedef {Object} PeriodInformation\n * @property {Node} period.node\n * Period node from the mpd\n * @property {Object} period.attributes\n * Parsed period attributes from node plus any added\n */\n\n/**\n * Maps a PeriodInformation object to a list of Representation information objects for all\n * AdaptationSet nodes contained within the Period.\n *\n * @name toAdaptationSetsCallback\n * @function\n * @param {PeriodInformation} period\n * Period object containing necessary period information\n * @param {number} periodStart\n * Start time of the Period within the mpd\n * @return {RepresentationInformation[]}\n * List of objects containing Representaion information\n */\n\n/**\n * Returns a callback for Array.prototype.map for mapping Period nodes to a list of\n * Representation information objects\n *\n * @param {Object} mpdAttributes\n * Contains attributes inherited by the mpd\n * @param {Object[]} mpdBaseUrls\n * Contains list of objects with resolved base urls and attributes\n * inherited by the mpd\n * @return {toAdaptationSetsCallback}\n * Callback map function\n */\n\nconst toAdaptationSets = (mpdAttributes, mpdBaseUrls) => (period, index) => {\n const periodBaseUrls = buildBaseUrls(mpdBaseUrls, findChildren(period.node, 'BaseURL'));\n const periodAttributes = merge(mpdAttributes, {\n periodStart: period.attributes.start\n });\n\n if (typeof period.attributes.duration === 'number') {\n periodAttributes.periodDuration = period.attributes.duration;\n }\n\n const adaptationSets = findChildren(period.node, 'AdaptationSet');\n const periodSegmentInfo = getSegmentInformation(period.node);\n return flatten(adaptationSets.map(toRepresentations(periodAttributes, periodBaseUrls, periodSegmentInfo)));\n};\n/**\n * Tranforms an array of content steering nodes into an object\n * containing CDN content steering information from the MPD manifest.\n *\n * For more information on the DASH spec for Content Steering parsing, see:\n * https://dashif.org/docs/DASH-IF-CTS-00XX-Content-Steering-Community-Review.pdf\n *\n * @param {Node[]} contentSteeringNodes\n * Content steering nodes\n * @param {Function} eventHandler\n * The event handler passed into the parser options to handle warnings\n * @return {Object}\n * Object containing content steering data\n */\n\nconst generateContentSteeringInformation = (contentSteeringNodes, eventHandler) => {\n // If there are more than one ContentSteering tags, throw an error\n if (contentSteeringNodes.length > 1) {\n eventHandler({\n type: 'warn',\n message: 'The MPD manifest should contain no more than one ContentSteering tag'\n });\n } // Return a null value if there are no ContentSteering tags\n\n\n if (!contentSteeringNodes.length) {\n return null;\n }\n\n const infoFromContentSteeringTag = merge({\n serverURL: getContent(contentSteeringNodes[0])\n }, parseAttributes(contentSteeringNodes[0])); // Converts `queryBeforeStart` to a boolean, as well as setting the default value\n // to `false` if it doesn't exist\n\n infoFromContentSteeringTag.queryBeforeStart = infoFromContentSteeringTag.queryBeforeStart === 'true';\n return infoFromContentSteeringTag;\n};\n/**\n * Gets Period@start property for a given period.\n *\n * @param {Object} options\n * Options object\n * @param {Object} options.attributes\n * Period attributes\n * @param {Object} [options.priorPeriodAttributes]\n * Prior period attributes (if prior period is available)\n * @param {string} options.mpdType\n * The MPD@type these periods came from\n * @return {number|null}\n * The period start, or null if it's an early available period or error\n */\n\nconst getPeriodStart = ({\n attributes,\n priorPeriodAttributes,\n mpdType\n}) => {\n // Summary of period start time calculation from DASH spec section 5.3.2.1\n //\n // A period's start is the first period's start + time elapsed after playing all\n // prior periods to this one. Periods continue one after the other in time (without\n // gaps) until the end of the presentation.\n //\n // The value of Period@start should be:\n // 1. if Period@start is present: value of Period@start\n // 2. if previous period exists and it has @duration: previous Period@start +\n // previous Period@duration\n // 3. if this is first period and MPD@type is 'static': 0\n // 4. in all other cases, consider the period an \"early available period\" (note: not\n // currently supported)\n // (1)\n if (typeof attributes.start === 'number') {\n return attributes.start;\n } // (2)\n\n\n if (priorPeriodAttributes && typeof priorPeriodAttributes.start === 'number' && typeof priorPeriodAttributes.duration === 'number') {\n return priorPeriodAttributes.start + priorPeriodAttributes.duration;\n } // (3)\n\n\n if (!priorPeriodAttributes && mpdType === 'static') {\n return 0;\n } // (4)\n // There is currently no logic for calculating the Period@start value if there is\n // no Period@start or prior Period@start and Period@duration available. This is not made\n // explicit by the DASH interop guidelines or the DASH spec, however, since there's\n // nothing about any other resolution strategies, it's implied. Thus, this case should\n // be considered an early available period, or error, and null should suffice for both\n // of those cases.\n\n\n return null;\n};\n/**\n * Traverses the mpd xml tree to generate a list of Representation information objects\n * that have inherited attributes from parent nodes\n *\n * @param {Node} mpd\n * The root node of the mpd\n * @param {Object} options\n * Available options for inheritAttributes\n * @param {string} options.manifestUri\n * The uri source of the mpd\n * @param {number} options.NOW\n * Current time per DASH IOP. Default is current time in ms since epoch\n * @param {number} options.clientOffset\n * Client time difference from NOW (in milliseconds)\n * @return {RepresentationInformation[]}\n * List of objects containing Representation information\n */\n\nconst inheritAttributes = (mpd, options = {}) => {\n const {\n manifestUri = '',\n NOW = Date.now(),\n clientOffset = 0,\n // TODO: For now, we are expecting an eventHandler callback function\n // to be passed into the mpd parser as an option.\n // In the future, we should enable stream parsing by using the Stream class from vhs-utils.\n // This will support new features including a standardized event handler.\n // See the m3u8 parser for examples of how stream parsing is currently used for HLS parsing.\n // https://github.com/videojs/vhs-utils/blob/88d6e10c631e57a5af02c5a62bc7376cd456b4f5/src/stream.js#L9\n eventHandler = function () {}\n } = options;\n const periodNodes = findChildren(mpd, 'Period');\n\n if (!periodNodes.length) {\n throw new Error(errors.INVALID_NUMBER_OF_PERIOD);\n }\n\n const locations = findChildren(mpd, 'Location');\n const mpdAttributes = parseAttributes(mpd);\n const mpdBaseUrls = buildBaseUrls([{\n baseUrl: manifestUri\n }], findChildren(mpd, 'BaseURL'));\n const contentSteeringNodes = findChildren(mpd, 'ContentSteering'); // See DASH spec section 5.3.1.2, Semantics of MPD element. Default type to 'static'.\n\n mpdAttributes.type = mpdAttributes.type || 'static';\n mpdAttributes.sourceDuration = mpdAttributes.mediaPresentationDuration || 0;\n mpdAttributes.NOW = NOW;\n mpdAttributes.clientOffset = clientOffset;\n\n if (locations.length) {\n mpdAttributes.locations = locations.map(getContent);\n }\n\n const periods = []; // Since toAdaptationSets acts on individual periods right now, the simplest approach to\n // adding properties that require looking at prior periods is to parse attributes and add\n // missing ones before toAdaptationSets is called. If more such properties are added, it\n // may be better to refactor toAdaptationSets.\n\n periodNodes.forEach((node, index) => {\n const attributes = parseAttributes(node); // Use the last modified prior period, as it may contain added information necessary\n // for this period.\n\n const priorPeriod = periods[index - 1];\n attributes.start = getPeriodStart({\n attributes,\n priorPeriodAttributes: priorPeriod ? priorPeriod.attributes : null,\n mpdType: mpdAttributes.type\n });\n periods.push({\n node,\n attributes\n });\n });\n return {\n locations: mpdAttributes.locations,\n contentSteeringInfo: generateContentSteeringInformation(contentSteeringNodes, eventHandler),\n // TODO: There are occurences where this `representationInfo` array contains undesired\n // duplicates. This generally occurs when there are multiple BaseURL nodes that are\n // direct children of the MPD node. When we attempt to resolve URLs from a combination of the\n // parent BaseURL and a child BaseURL, and the value does not resolve,\n // we end up returning the child BaseURL multiple times.\n // We need to determine a way to remove these duplicates in a safe way.\n // See: https://github.com/videojs/mpd-parser/pull/17#discussion_r162750527\n representationInfo: flatten(periods.map(toAdaptationSets(mpdAttributes, mpdBaseUrls))),\n eventStream: flatten(periods.map(toEventStream))\n };\n};\n\nconst stringToMpdXml = manifestString => {\n if (manifestString === '') {\n throw new Error(errors.DASH_EMPTY_MANIFEST);\n }\n\n const parser = new DOMParser();\n let xml;\n let mpd;\n\n try {\n xml = parser.parseFromString(manifestString, 'application/xml');\n mpd = xml && xml.documentElement.tagName === 'MPD' ? xml.documentElement : null;\n } catch (e) {// ie 11 throws on invalid xml\n }\n\n if (!mpd || mpd && mpd.getElementsByTagName('parsererror').length > 0) {\n throw new Error(errors.DASH_INVALID_XML);\n }\n\n return mpd;\n};\n\n/**\n * Parses the manifest for a UTCTiming node, returning the nodes attributes if found\n *\n * @param {string} mpd\n * XML string of the MPD manifest\n * @return {Object|null}\n * Attributes of UTCTiming node specified in the manifest. Null if none found\n */\n\nconst parseUTCTimingScheme = mpd => {\n const UTCTimingNode = findChildren(mpd, 'UTCTiming')[0];\n\n if (!UTCTimingNode) {\n return null;\n }\n\n const attributes = parseAttributes(UTCTimingNode);\n\n switch (attributes.schemeIdUri) {\n case 'urn:mpeg:dash:utc:http-head:2014':\n case 'urn:mpeg:dash:utc:http-head:2012':\n attributes.method = 'HEAD';\n break;\n\n case 'urn:mpeg:dash:utc:http-xsdate:2014':\n case 'urn:mpeg:dash:utc:http-iso:2014':\n case 'urn:mpeg:dash:utc:http-xsdate:2012':\n case 'urn:mpeg:dash:utc:http-iso:2012':\n attributes.method = 'GET';\n break;\n\n case 'urn:mpeg:dash:utc:direct:2014':\n case 'urn:mpeg:dash:utc:direct:2012':\n attributes.method = 'DIRECT';\n attributes.value = Date.parse(attributes.value);\n break;\n\n case 'urn:mpeg:dash:utc:http-ntp:2014':\n case 'urn:mpeg:dash:utc:ntp:2014':\n case 'urn:mpeg:dash:utc:sntp:2014':\n default:\n throw new Error(errors.UNSUPPORTED_UTC_TIMING_SCHEME);\n }\n\n return attributes;\n};\n\nconst VERSION = version;\n/*\n * Given a DASH manifest string and options, parses the DASH manifest into an object in the\n * form outputed by m3u8-parser and accepted by videojs/http-streaming.\n *\n * For live DASH manifests, if `previousManifest` is provided in options, then the newly\n * parsed DASH manifest will have its media sequence and discontinuity sequence values\n * updated to reflect its position relative to the prior manifest.\n *\n * @param {string} manifestString - the DASH manifest as a string\n * @param {options} [options] - any options\n *\n * @return {Object} the manifest object\n */\n\nconst parse = (manifestString, options = {}) => {\n const parsedManifestInfo = inheritAttributes(stringToMpdXml(manifestString), options);\n const playlists = toPlaylists(parsedManifestInfo.representationInfo);\n return toM3u8({\n dashPlaylists: playlists,\n locations: parsedManifestInfo.locations,\n contentSteering: parsedManifestInfo.contentSteeringInfo,\n sidxMapping: options.sidxMapping,\n previousManifest: options.previousManifest,\n eventStream: parsedManifestInfo.eventStream\n });\n};\n/**\n * Parses the manifest for a UTCTiming node, returning the nodes attributes if found\n *\n * @param {string} manifestString\n * XML string of the MPD manifest\n * @return {Object|null}\n * Attributes of UTCTiming node specified in the manifest. Null if none found\n */\n\n\nconst parseUTCTiming = manifestString => parseUTCTimingScheme(stringToMpdXml(manifestString));\n\nexport { VERSION, addSidxSegmentsToPlaylist$1 as addSidxSegmentsToPlaylist, generateSidxKey, inheritAttributes, parse, parseUTCTiming, stringToMpdXml, toM3u8, toPlaylists };\n","var win;\n\nif (typeof window !== \"undefined\") {\n win = window;\n} else if (typeof global !== \"undefined\") {\n win = global;\n} else if (typeof self !== \"undefined\"){\n win = self;\n} else {\n win = {};\n}\n\nmodule.exports = win;\n","/*! @name m3u8-parser @version 7.2.0 @license Apache-2.0 */\nimport Stream from '@videojs/vhs-utils/es/stream.js';\nimport _extends from '@babel/runtime/helpers/extends';\nimport decodeB64ToUint8Array from '@videojs/vhs-utils/es/decode-b64-to-uint8-array.js';\n\n/**\n * @file m3u8/line-stream.js\n */\n/**\n * A stream that buffers string input and generates a `data` event for each\n * line.\n *\n * @class LineStream\n * @extends Stream\n */\n\nclass LineStream extends Stream {\n constructor() {\n super();\n this.buffer = '';\n }\n /**\n * Add new data to be parsed.\n *\n * @param {string} data the text to process\n */\n\n\n push(data) {\n let nextNewline;\n this.buffer += data;\n nextNewline = this.buffer.indexOf('\\n');\n\n for (; nextNewline > -1; nextNewline = this.buffer.indexOf('\\n')) {\n this.trigger('data', this.buffer.substring(0, nextNewline));\n this.buffer = this.buffer.substring(nextNewline + 1);\n }\n }\n\n}\n\nconst TAB = String.fromCharCode(0x09);\n\nconst parseByterange = function (byterangeString) {\n // optionally match and capture 0+ digits before `@`\n // optionally match and capture 0+ digits after `@`\n const match = /([0-9.]*)?@?([0-9.]*)?/.exec(byterangeString || '');\n const result = {};\n\n if (match[1]) {\n result.length = parseInt(match[1], 10);\n }\n\n if (match[2]) {\n result.offset = parseInt(match[2], 10);\n }\n\n return result;\n};\n/**\n * \"forgiving\" attribute list psuedo-grammar:\n * attributes -> keyvalue (',' keyvalue)*\n * keyvalue -> key '=' value\n * key -> [^=]*\n * value -> '\"' [^\"]* '\"' | [^,]*\n */\n\n\nconst attributeSeparator = function () {\n const key = '[^=]*';\n const value = '\"[^\"]*\"|[^,]*';\n const keyvalue = '(?:' + key + ')=(?:' + value + ')';\n return new RegExp('(?:^|,)(' + keyvalue + ')');\n};\n/**\n * Parse attributes from a line given the separator\n *\n * @param {string} attributes the attribute line to parse\n */\n\n\nconst parseAttributes = function (attributes) {\n const result = {};\n\n if (!attributes) {\n return result;\n } // split the string using attributes as the separator\n\n\n const attrs = attributes.split(attributeSeparator());\n let i = attrs.length;\n let attr;\n\n while (i--) {\n // filter out unmatched portions of the string\n if (attrs[i] === '') {\n continue;\n } // split the key and value\n\n\n attr = /([^=]*)=(.*)/.exec(attrs[i]).slice(1); // trim whitespace and remove optional quotes around the value\n\n attr[0] = attr[0].replace(/^\\s+|\\s+$/g, '');\n attr[1] = attr[1].replace(/^\\s+|\\s+$/g, '');\n attr[1] = attr[1].replace(/^['\"](.*)['\"]$/g, '$1');\n result[attr[0]] = attr[1];\n }\n\n return result;\n};\n/**\n * Converts a string into a resolution object\n *\n * @param {string} resolution a string such as 3840x2160\n *\n * @return {Object} An object representing the resolution\n *\n */\n\n\nconst parseResolution = resolution => {\n const split = resolution.split('x');\n const result = {};\n\n if (split[0]) {\n result.width = parseInt(split[0], 10);\n }\n\n if (split[1]) {\n result.height = parseInt(split[1], 10);\n }\n\n return result;\n};\n/**\n * A line-level M3U8 parser event stream. It expects to receive input one\n * line at a time and performs a context-free parse of its contents. A stream\n * interpretation of a manifest can be useful if the manifest is expected to\n * be too large to fit comfortably into memory or the entirety of the input\n * is not immediately available. Otherwise, it's probably much easier to work\n * with a regular `Parser` object.\n *\n * Produces `data` events with an object that captures the parser's\n * interpretation of the input. That object has a property `tag` that is one\n * of `uri`, `comment`, or `tag`. URIs only have a single additional\n * property, `line`, which captures the entirety of the input without\n * interpretation. Comments similarly have a single additional property\n * `text` which is the input without the leading `#`.\n *\n * Tags always have a property `tagType` which is the lower-cased version of\n * the M3U8 directive without the `#EXT` or `#EXT-X-` prefix. For instance,\n * `#EXT-X-MEDIA-SEQUENCE` becomes `media-sequence` when parsed. Unrecognized\n * tags are given the tag type `unknown` and a single additional property\n * `data` with the remainder of the input.\n *\n * @class ParseStream\n * @extends Stream\n */\n\n\nclass ParseStream extends Stream {\n constructor() {\n super();\n this.customParsers = [];\n this.tagMappers = [];\n }\n /**\n * Parses an additional line of input.\n *\n * @param {string} line a single line of an M3U8 file to parse\n */\n\n\n push(line) {\n let match;\n let event; // strip whitespace\n\n line = line.trim();\n\n if (line.length === 0) {\n // ignore empty lines\n return;\n } // URIs\n\n\n if (line[0] !== '#') {\n this.trigger('data', {\n type: 'uri',\n uri: line\n });\n return;\n } // map tags\n\n\n const newLines = this.tagMappers.reduce((acc, mapper) => {\n const mappedLine = mapper(line); // skip if unchanged\n\n if (mappedLine === line) {\n return acc;\n }\n\n return acc.concat([mappedLine]);\n }, [line]);\n newLines.forEach(newLine => {\n for (let i = 0; i < this.customParsers.length; i++) {\n if (this.customParsers[i].call(this, newLine)) {\n return;\n }\n } // Comments\n\n\n if (newLine.indexOf('#EXT') !== 0) {\n this.trigger('data', {\n type: 'comment',\n text: newLine.slice(1)\n });\n return;\n } // strip off any carriage returns here so the regex matching\n // doesn't have to account for them.\n\n\n newLine = newLine.replace('\\r', ''); // Tags\n\n match = /^#EXTM3U/.exec(newLine);\n\n if (match) {\n this.trigger('data', {\n type: 'tag',\n tagType: 'm3u'\n });\n return;\n }\n\n match = /^#EXTINF:([0-9\\.]*)?,?(.*)?$/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'inf'\n };\n\n if (match[1]) {\n event.duration = parseFloat(match[1]);\n }\n\n if (match[2]) {\n event.title = match[2];\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-TARGETDURATION:([0-9.]*)?/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'targetduration'\n };\n\n if (match[1]) {\n event.duration = parseInt(match[1], 10);\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-VERSION:([0-9.]*)?/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'version'\n };\n\n if (match[1]) {\n event.version = parseInt(match[1], 10);\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-MEDIA-SEQUENCE:(\\-?[0-9.]*)?/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'media-sequence'\n };\n\n if (match[1]) {\n event.number = parseInt(match[1], 10);\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-DISCONTINUITY-SEQUENCE:(\\-?[0-9.]*)?/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'discontinuity-sequence'\n };\n\n if (match[1]) {\n event.number = parseInt(match[1], 10);\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-PLAYLIST-TYPE:(.*)?$/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'playlist-type'\n };\n\n if (match[1]) {\n event.playlistType = match[1];\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-BYTERANGE:(.*)?$/.exec(newLine);\n\n if (match) {\n event = _extends(parseByterange(match[1]), {\n type: 'tag',\n tagType: 'byterange'\n });\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-ALLOW-CACHE:(YES|NO)?/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'allow-cache'\n };\n\n if (match[1]) {\n event.allowed = !/NO/.test(match[1]);\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-MAP:(.*)$/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'map'\n };\n\n if (match[1]) {\n const attributes = parseAttributes(match[1]);\n\n if (attributes.URI) {\n event.uri = attributes.URI;\n }\n\n if (attributes.BYTERANGE) {\n event.byterange = parseByterange(attributes.BYTERANGE);\n }\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-STREAM-INF:(.*)$/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'stream-inf'\n };\n\n if (match[1]) {\n event.attributes = parseAttributes(match[1]);\n\n if (event.attributes.RESOLUTION) {\n event.attributes.RESOLUTION = parseResolution(event.attributes.RESOLUTION);\n }\n\n if (event.attributes.BANDWIDTH) {\n event.attributes.BANDWIDTH = parseInt(event.attributes.BANDWIDTH, 10);\n }\n\n if (event.attributes['FRAME-RATE']) {\n event.attributes['FRAME-RATE'] = parseFloat(event.attributes['FRAME-RATE']);\n }\n\n if (event.attributes['PROGRAM-ID']) {\n event.attributes['PROGRAM-ID'] = parseInt(event.attributes['PROGRAM-ID'], 10);\n }\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-MEDIA:(.*)$/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'media'\n };\n\n if (match[1]) {\n event.attributes = parseAttributes(match[1]);\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-ENDLIST/.exec(newLine);\n\n if (match) {\n this.trigger('data', {\n type: 'tag',\n tagType: 'endlist'\n });\n return;\n }\n\n match = /^#EXT-X-DISCONTINUITY/.exec(newLine);\n\n if (match) {\n this.trigger('data', {\n type: 'tag',\n tagType: 'discontinuity'\n });\n return;\n }\n\n match = /^#EXT-X-PROGRAM-DATE-TIME:(.*)$/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'program-date-time'\n };\n\n if (match[1]) {\n event.dateTimeString = match[1];\n event.dateTimeObject = new Date(match[1]);\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-KEY:(.*)$/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'key'\n };\n\n if (match[1]) {\n event.attributes = parseAttributes(match[1]); // parse the IV string into a Uint32Array\n\n if (event.attributes.IV) {\n if (event.attributes.IV.substring(0, 2).toLowerCase() === '0x') {\n event.attributes.IV = event.attributes.IV.substring(2);\n }\n\n event.attributes.IV = event.attributes.IV.match(/.{8}/g);\n event.attributes.IV[0] = parseInt(event.attributes.IV[0], 16);\n event.attributes.IV[1] = parseInt(event.attributes.IV[1], 16);\n event.attributes.IV[2] = parseInt(event.attributes.IV[2], 16);\n event.attributes.IV[3] = parseInt(event.attributes.IV[3], 16);\n event.attributes.IV = new Uint32Array(event.attributes.IV);\n }\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-START:(.*)$/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'start'\n };\n\n if (match[1]) {\n event.attributes = parseAttributes(match[1]);\n event.attributes['TIME-OFFSET'] = parseFloat(event.attributes['TIME-OFFSET']);\n event.attributes.PRECISE = /YES/.test(event.attributes.PRECISE);\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-CUE-OUT-CONT:(.*)?$/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'cue-out-cont'\n };\n\n if (match[1]) {\n event.data = match[1];\n } else {\n event.data = '';\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-CUE-OUT:(.*)?$/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'cue-out'\n };\n\n if (match[1]) {\n event.data = match[1];\n } else {\n event.data = '';\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-CUE-IN:?(.*)?$/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'cue-in'\n };\n\n if (match[1]) {\n event.data = match[1];\n } else {\n event.data = '';\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-SKIP:(.*)$/.exec(newLine);\n\n if (match && match[1]) {\n event = {\n type: 'tag',\n tagType: 'skip'\n };\n event.attributes = parseAttributes(match[1]);\n\n if (event.attributes.hasOwnProperty('SKIPPED-SEGMENTS')) {\n event.attributes['SKIPPED-SEGMENTS'] = parseInt(event.attributes['SKIPPED-SEGMENTS'], 10);\n }\n\n if (event.attributes.hasOwnProperty('RECENTLY-REMOVED-DATERANGES')) {\n event.attributes['RECENTLY-REMOVED-DATERANGES'] = event.attributes['RECENTLY-REMOVED-DATERANGES'].split(TAB);\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-PART:(.*)$/.exec(newLine);\n\n if (match && match[1]) {\n event = {\n type: 'tag',\n tagType: 'part'\n };\n event.attributes = parseAttributes(match[1]);\n ['DURATION'].forEach(function (key) {\n if (event.attributes.hasOwnProperty(key)) {\n event.attributes[key] = parseFloat(event.attributes[key]);\n }\n });\n ['INDEPENDENT', 'GAP'].forEach(function (key) {\n if (event.attributes.hasOwnProperty(key)) {\n event.attributes[key] = /YES/.test(event.attributes[key]);\n }\n });\n\n if (event.attributes.hasOwnProperty('BYTERANGE')) {\n event.attributes.byterange = parseByterange(event.attributes.BYTERANGE);\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-SERVER-CONTROL:(.*)$/.exec(newLine);\n\n if (match && match[1]) {\n event = {\n type: 'tag',\n tagType: 'server-control'\n };\n event.attributes = parseAttributes(match[1]);\n ['CAN-SKIP-UNTIL', 'PART-HOLD-BACK', 'HOLD-BACK'].forEach(function (key) {\n if (event.attributes.hasOwnProperty(key)) {\n event.attributes[key] = parseFloat(event.attributes[key]);\n }\n });\n ['CAN-SKIP-DATERANGES', 'CAN-BLOCK-RELOAD'].forEach(function (key) {\n if (event.attributes.hasOwnProperty(key)) {\n event.attributes[key] = /YES/.test(event.attributes[key]);\n }\n });\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-PART-INF:(.*)$/.exec(newLine);\n\n if (match && match[1]) {\n event = {\n type: 'tag',\n tagType: 'part-inf'\n };\n event.attributes = parseAttributes(match[1]);\n ['PART-TARGET'].forEach(function (key) {\n if (event.attributes.hasOwnProperty(key)) {\n event.attributes[key] = parseFloat(event.attributes[key]);\n }\n });\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-PRELOAD-HINT:(.*)$/.exec(newLine);\n\n if (match && match[1]) {\n event = {\n type: 'tag',\n tagType: 'preload-hint'\n };\n event.attributes = parseAttributes(match[1]);\n ['BYTERANGE-START', 'BYTERANGE-LENGTH'].forEach(function (key) {\n if (event.attributes.hasOwnProperty(key)) {\n event.attributes[key] = parseInt(event.attributes[key], 10);\n const subkey = key === 'BYTERANGE-LENGTH' ? 'length' : 'offset';\n event.attributes.byterange = event.attributes.byterange || {};\n event.attributes.byterange[subkey] = event.attributes[key]; // only keep the parsed byterange object.\n\n delete event.attributes[key];\n }\n });\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-RENDITION-REPORT:(.*)$/.exec(newLine);\n\n if (match && match[1]) {\n event = {\n type: 'tag',\n tagType: 'rendition-report'\n };\n event.attributes = parseAttributes(match[1]);\n ['LAST-MSN', 'LAST-PART'].forEach(function (key) {\n if (event.attributes.hasOwnProperty(key)) {\n event.attributes[key] = parseInt(event.attributes[key], 10);\n }\n });\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-DATERANGE:(.*)$/.exec(newLine);\n\n if (match && match[1]) {\n event = {\n type: 'tag',\n tagType: 'daterange'\n };\n event.attributes = parseAttributes(match[1]);\n ['ID', 'CLASS'].forEach(function (key) {\n if (event.attributes.hasOwnProperty(key)) {\n event.attributes[key] = String(event.attributes[key]);\n }\n });\n ['START-DATE', 'END-DATE'].forEach(function (key) {\n if (event.attributes.hasOwnProperty(key)) {\n event.attributes[key] = new Date(event.attributes[key]);\n }\n });\n ['DURATION', 'PLANNED-DURATION'].forEach(function (key) {\n if (event.attributes.hasOwnProperty(key)) {\n event.attributes[key] = parseFloat(event.attributes[key]);\n }\n });\n ['END-ON-NEXT'].forEach(function (key) {\n if (event.attributes.hasOwnProperty(key)) {\n event.attributes[key] = /YES/i.test(event.attributes[key]);\n }\n });\n ['SCTE35-CMD', ' SCTE35-OUT', 'SCTE35-IN'].forEach(function (key) {\n if (event.attributes.hasOwnProperty(key)) {\n event.attributes[key] = event.attributes[key].toString(16);\n }\n });\n const clientAttributePattern = /^X-([A-Z]+-)+[A-Z]+$/;\n\n for (const key in event.attributes) {\n if (!clientAttributePattern.test(key)) {\n continue;\n }\n\n const isHexaDecimal = /[0-9A-Fa-f]{6}/g.test(event.attributes[key]);\n const isDecimalFloating = /^\\d+(\\.\\d+)?$/.test(event.attributes[key]);\n event.attributes[key] = isHexaDecimal ? event.attributes[key].toString(16) : isDecimalFloating ? parseFloat(event.attributes[key]) : String(event.attributes[key]);\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-INDEPENDENT-SEGMENTS/.exec(newLine);\n\n if (match) {\n this.trigger('data', {\n type: 'tag',\n tagType: 'independent-segments'\n });\n return;\n }\n\n match = /^#EXT-X-I-FRAMES-ONLY/.exec(newLine);\n\n if (match) {\n this.trigger('data', {\n type: 'tag',\n tagType: 'i-frames-only'\n });\n return;\n }\n\n match = /^#EXT-X-CONTENT-STEERING:(.*)$/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'content-steering'\n };\n event.attributes = parseAttributes(match[1]);\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-I-FRAME-STREAM-INF:(.*)$/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'i-frame-playlist'\n };\n event.attributes = parseAttributes(match[1]);\n\n if (event.attributes.URI) {\n event.uri = event.attributes.URI;\n }\n\n if (event.attributes.BANDWIDTH) {\n event.attributes.BANDWIDTH = parseInt(event.attributes.BANDWIDTH, 10);\n }\n\n if (event.attributes.RESOLUTION) {\n event.attributes.RESOLUTION = parseResolution(event.attributes.RESOLUTION);\n }\n\n if (event.attributes['AVERAGE-BANDWIDTH']) {\n event.attributes['AVERAGE-BANDWIDTH'] = parseInt(event.attributes['AVERAGE-BANDWIDTH'], 10);\n }\n\n if (event.attributes['FRAME-RATE']) {\n event.attributes['FRAME-RATE'] = parseFloat(event.attributes['FRAME-RATE']);\n }\n\n this.trigger('data', event);\n return;\n }\n\n match = /^#EXT-X-DEFINE:(.*)$/.exec(newLine);\n\n if (match) {\n event = {\n type: 'tag',\n tagType: 'define'\n };\n event.attributes = parseAttributes(match[1]);\n this.trigger('data', event);\n return;\n } // unknown tag type\n\n\n this.trigger('data', {\n type: 'tag',\n data: newLine.slice(4)\n });\n });\n }\n /**\n * Add a parser for custom headers\n *\n * @param {Object} options a map of options for the added parser\n * @param {RegExp} options.expression a regular expression to match the custom header\n * @param {string} options.customType the custom type to register to the output\n * @param {Function} [options.dataParser] function to parse the line into an object\n * @param {boolean} [options.segment] should tag data be attached to the segment object\n */\n\n\n addParser({\n expression,\n customType,\n dataParser,\n segment\n }) {\n if (typeof dataParser !== 'function') {\n dataParser = line => line;\n }\n\n this.customParsers.push(line => {\n const match = expression.exec(line);\n\n if (match) {\n this.trigger('data', {\n type: 'custom',\n data: dataParser(line),\n customType,\n segment\n });\n return true;\n }\n });\n }\n /**\n * Add a custom header mapper\n *\n * @param {Object} options\n * @param {RegExp} options.expression a regular expression to match the custom header\n * @param {Function} options.map function to translate tag into a different tag\n */\n\n\n addTagMapper({\n expression,\n map\n }) {\n const mapFn = line => {\n if (expression.test(line)) {\n return map(line);\n }\n\n return line;\n };\n\n this.tagMappers.push(mapFn);\n }\n\n}\n\nconst camelCase = str => str.toLowerCase().replace(/-(\\w)/g, a => a[1].toUpperCase());\n\nconst camelCaseKeys = function (attributes) {\n const result = {};\n Object.keys(attributes).forEach(function (key) {\n result[camelCase(key)] = attributes[key];\n });\n return result;\n}; // set SERVER-CONTROL hold back based upon targetDuration and partTargetDuration\n// we need this helper because defaults are based upon targetDuration and\n// partTargetDuration being set, but they may not be if SERVER-CONTROL appears before\n// target durations are set.\n\n\nconst setHoldBack = function (manifest) {\n const {\n serverControl,\n targetDuration,\n partTargetDuration\n } = manifest;\n\n if (!serverControl) {\n return;\n }\n\n const tag = '#EXT-X-SERVER-CONTROL';\n const hb = 'holdBack';\n const phb = 'partHoldBack';\n const minTargetDuration = targetDuration && targetDuration * 3;\n const minPartDuration = partTargetDuration && partTargetDuration * 2;\n\n if (targetDuration && !serverControl.hasOwnProperty(hb)) {\n serverControl[hb] = minTargetDuration;\n this.trigger('info', {\n message: `${tag} defaulting HOLD-BACK to targetDuration * 3 (${minTargetDuration}).`\n });\n }\n\n if (minTargetDuration && serverControl[hb] < minTargetDuration) {\n this.trigger('warn', {\n message: `${tag} clamping HOLD-BACK (${serverControl[hb]}) to targetDuration * 3 (${minTargetDuration})`\n });\n serverControl[hb] = minTargetDuration;\n } // default no part hold back to part target duration * 3\n\n\n if (partTargetDuration && !serverControl.hasOwnProperty(phb)) {\n serverControl[phb] = partTargetDuration * 3;\n this.trigger('info', {\n message: `${tag} defaulting PART-HOLD-BACK to partTargetDuration * 3 (${serverControl[phb]}).`\n });\n } // if part hold back is too small default it to part target duration * 2\n\n\n if (partTargetDuration && serverControl[phb] < minPartDuration) {\n this.trigger('warn', {\n message: `${tag} clamping PART-HOLD-BACK (${serverControl[phb]}) to partTargetDuration * 2 (${minPartDuration}).`\n });\n serverControl[phb] = minPartDuration;\n }\n};\n/**\n * A parser for M3U8 files. The current interpretation of the input is\n * exposed as a property `manifest` on parser objects. It's just two lines to\n * create and parse a manifest once you have the contents available as a string:\n *\n * ```js\n * var parser = new m3u8.Parser();\n * parser.push(xhr.responseText);\n * ```\n *\n * New input can later be applied to update the manifest object by calling\n * `push` again.\n *\n * The parser attempts to create a usable manifest object even if the\n * underlying input is somewhat nonsensical. It emits `info` and `warning`\n * events during the parse if it encounters input that seems invalid or\n * requires some property of the manifest object to be defaulted.\n *\n * @class Parser\n * @param {Object} [opts] Options for the constructor, needed for substitutions\n * @param {string} [opts.uri] URL to check for query params\n * @param {Object} [opts.mainDefinitions] Definitions on main playlist that can be imported\n * @extends Stream\n */\n\n\nclass Parser extends Stream {\n constructor(opts = {}) {\n super();\n this.lineStream = new LineStream();\n this.parseStream = new ParseStream();\n this.lineStream.pipe(this.parseStream);\n this.mainDefinitions = opts.mainDefinitions || {};\n this.params = new URL(opts.uri, 'https://a.com').searchParams;\n this.lastProgramDateTime = null;\n /* eslint-disable consistent-this */\n\n const self = this;\n /* eslint-enable consistent-this */\n\n const uris = [];\n let currentUri = {}; // if specified, the active EXT-X-MAP definition\n\n let currentMap; // if specified, the active decryption key\n\n let key;\n let hasParts = false;\n\n const noop = function () {};\n\n const defaultMediaGroups = {\n 'AUDIO': {},\n 'VIDEO': {},\n 'CLOSED-CAPTIONS': {},\n 'SUBTITLES': {}\n }; // This is the Widevine UUID from DASH IF IOP. The same exact string is\n // used in MPDs with Widevine encrypted streams.\n\n const widevineUuid = 'urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed'; // group segments into numbered timelines delineated by discontinuities\n\n let currentTimeline = 0; // the manifest is empty until the parse stream begins delivering data\n\n this.manifest = {\n allowCache: true,\n discontinuityStarts: [],\n dateRanges: [],\n iFramePlaylists: [],\n segments: []\n }; // keep track of the last seen segment's byte range end, as segments are not required\n // to provide the offset, in which case it defaults to the next byte after the\n // previous segment\n\n let lastByterangeEnd = 0; // keep track of the last seen part's byte range end.\n\n let lastPartByterangeEnd = 0;\n const dateRangeTags = {};\n this.on('end', () => {\n // only add preloadSegment if we don't yet have a uri for it.\n // and we actually have parts/preloadHints\n if (currentUri.uri || !currentUri.parts && !currentUri.preloadHints) {\n return;\n }\n\n if (!currentUri.map && currentMap) {\n currentUri.map = currentMap;\n }\n\n if (!currentUri.key && key) {\n currentUri.key = key;\n }\n\n if (!currentUri.timeline && typeof currentTimeline === 'number') {\n currentUri.timeline = currentTimeline;\n }\n\n this.manifest.preloadSegment = currentUri;\n }); // update the manifest with the m3u8 entry from the parse stream\n\n this.parseStream.on('data', function (entry) {\n let mediaGroup;\n let rendition; // Replace variables in uris and attributes as defined in #EXT-X-DEFINE tags\n\n if (self.manifest.definitions) {\n for (const def in self.manifest.definitions) {\n if (entry.uri) {\n entry.uri = entry.uri.replace(`{$${def}}`, self.manifest.definitions[def]);\n }\n\n if (entry.attributes) {\n for (const attr in entry.attributes) {\n if (typeof entry.attributes[attr] === 'string') {\n entry.attributes[attr] = entry.attributes[attr].replace(`{$${def}}`, self.manifest.definitions[def]);\n }\n }\n }\n }\n }\n\n ({\n tag() {\n // switch based on the tag type\n (({\n version() {\n if (entry.version) {\n this.manifest.version = entry.version;\n }\n },\n\n 'allow-cache'() {\n this.manifest.allowCache = entry.allowed;\n\n if (!('allowed' in entry)) {\n this.trigger('info', {\n message: 'defaulting allowCache to YES'\n });\n this.manifest.allowCache = true;\n }\n },\n\n byterange() {\n const byterange = {};\n\n if ('length' in entry) {\n currentUri.byterange = byterange;\n byterange.length = entry.length;\n\n if (!('offset' in entry)) {\n /*\n * From the latest spec (as of this writing):\n * https://tools.ietf.org/html/draft-pantos-http-live-streaming-23#section-4.3.2.2\n *\n * Same text since EXT-X-BYTERANGE's introduction in draft 7:\n * https://tools.ietf.org/html/draft-pantos-http-live-streaming-07#section-3.3.1)\n *\n * \"If o [offset] is not present, the sub-range begins at the next byte\n * following the sub-range of the previous media segment.\"\n */\n entry.offset = lastByterangeEnd;\n }\n }\n\n if ('offset' in entry) {\n currentUri.byterange = byterange;\n byterange.offset = entry.offset;\n }\n\n lastByterangeEnd = byterange.offset + byterange.length;\n },\n\n endlist() {\n this.manifest.endList = true;\n },\n\n inf() {\n if (!('mediaSequence' in this.manifest)) {\n this.manifest.mediaSequence = 0;\n this.trigger('info', {\n message: 'defaulting media sequence to zero'\n });\n }\n\n if (!('discontinuitySequence' in this.manifest)) {\n this.manifest.discontinuitySequence = 0;\n this.trigger('info', {\n message: 'defaulting discontinuity sequence to zero'\n });\n }\n\n if (entry.title) {\n currentUri.title = entry.title;\n }\n\n if (entry.duration > 0) {\n currentUri.duration = entry.duration;\n }\n\n if (entry.duration === 0) {\n currentUri.duration = 0.01;\n this.trigger('info', {\n message: 'updating zero segment duration to a small value'\n });\n }\n\n this.manifest.segments = uris;\n },\n\n key() {\n if (!entry.attributes) {\n this.trigger('warn', {\n message: 'ignoring key declaration without attribute list'\n });\n return;\n } // clear the active encryption key\n\n\n if (entry.attributes.METHOD === 'NONE') {\n key = null;\n return;\n }\n\n if (!entry.attributes.URI) {\n this.trigger('warn', {\n message: 'ignoring key declaration without URI'\n });\n return;\n }\n\n if (entry.attributes.KEYFORMAT === 'com.apple.streamingkeydelivery') {\n this.manifest.contentProtection = this.manifest.contentProtection || {}; // TODO: add full support for this.\n\n this.manifest.contentProtection['com.apple.fps.1_0'] = {\n attributes: entry.attributes\n };\n return;\n }\n\n if (entry.attributes.KEYFORMAT === 'com.microsoft.playready') {\n this.manifest.contentProtection = this.manifest.contentProtection || {}; // TODO: add full support for this.\n\n this.manifest.contentProtection['com.microsoft.playready'] = {\n uri: entry.attributes.URI\n };\n return;\n } // check if the content is encrypted for Widevine\n // Widevine/HLS spec: https://storage.googleapis.com/wvdocs/Widevine_DRM_HLS.pdf\n\n\n if (entry.attributes.KEYFORMAT === widevineUuid) {\n const VALID_METHODS = ['SAMPLE-AES', 'SAMPLE-AES-CTR', 'SAMPLE-AES-CENC'];\n\n if (VALID_METHODS.indexOf(entry.attributes.METHOD) === -1) {\n this.trigger('warn', {\n message: 'invalid key method provided for Widevine'\n });\n return;\n }\n\n if (entry.attributes.METHOD === 'SAMPLE-AES-CENC') {\n this.trigger('warn', {\n message: 'SAMPLE-AES-CENC is deprecated, please use SAMPLE-AES-CTR instead'\n });\n }\n\n if (entry.attributes.URI.substring(0, 23) !== 'data:text/plain;base64,') {\n this.trigger('warn', {\n message: 'invalid key URI provided for Widevine'\n });\n return;\n }\n\n if (!(entry.attributes.KEYID && entry.attributes.KEYID.substring(0, 2) === '0x')) {\n this.trigger('warn', {\n message: 'invalid key ID provided for Widevine'\n });\n return;\n } // if Widevine key attributes are valid, store them as `contentProtection`\n // on the manifest to emulate Widevine tag structure in a DASH mpd\n\n\n this.manifest.contentProtection = this.manifest.contentProtection || {};\n this.manifest.contentProtection['com.widevine.alpha'] = {\n attributes: {\n schemeIdUri: entry.attributes.KEYFORMAT,\n // remove '0x' from the key id string\n keyId: entry.attributes.KEYID.substring(2)\n },\n // decode the base64-encoded PSSH box\n pssh: decodeB64ToUint8Array(entry.attributes.URI.split(',')[1])\n };\n return;\n }\n\n if (!entry.attributes.METHOD) {\n this.trigger('warn', {\n message: 'defaulting key method to AES-128'\n });\n } // setup an encryption key for upcoming segments\n\n\n key = {\n method: entry.attributes.METHOD || 'AES-128',\n uri: entry.attributes.URI\n };\n\n if (typeof entry.attributes.IV !== 'undefined') {\n key.iv = entry.attributes.IV;\n }\n },\n\n 'media-sequence'() {\n if (!isFinite(entry.number)) {\n this.trigger('warn', {\n message: 'ignoring invalid media sequence: ' + entry.number\n });\n return;\n }\n\n this.manifest.mediaSequence = entry.number;\n },\n\n 'discontinuity-sequence'() {\n if (!isFinite(entry.number)) {\n this.trigger('warn', {\n message: 'ignoring invalid discontinuity sequence: ' + entry.number\n });\n return;\n }\n\n this.manifest.discontinuitySequence = entry.number;\n currentTimeline = entry.number;\n },\n\n 'playlist-type'() {\n if (!/VOD|EVENT/.test(entry.playlistType)) {\n this.trigger('warn', {\n message: 'ignoring unknown playlist type: ' + entry.playlist\n });\n return;\n }\n\n this.manifest.playlistType = entry.playlistType;\n },\n\n map() {\n currentMap = {};\n\n if (entry.uri) {\n currentMap.uri = entry.uri;\n }\n\n if (entry.byterange) {\n currentMap.byterange = entry.byterange;\n }\n\n if (key) {\n currentMap.key = key;\n }\n },\n\n 'stream-inf'() {\n this.manifest.playlists = uris;\n this.manifest.mediaGroups = this.manifest.mediaGroups || defaultMediaGroups;\n\n if (!entry.attributes) {\n this.trigger('warn', {\n message: 'ignoring empty stream-inf attributes'\n });\n return;\n }\n\n if (!currentUri.attributes) {\n currentUri.attributes = {};\n }\n\n _extends(currentUri.attributes, entry.attributes);\n },\n\n media() {\n this.manifest.mediaGroups = this.manifest.mediaGroups || defaultMediaGroups;\n\n if (!(entry.attributes && entry.attributes.TYPE && entry.attributes['GROUP-ID'] && entry.attributes.NAME)) {\n this.trigger('warn', {\n message: 'ignoring incomplete or missing media group'\n });\n return;\n } // find the media group, creating defaults as necessary\n\n\n const mediaGroupType = this.manifest.mediaGroups[entry.attributes.TYPE];\n mediaGroupType[entry.attributes['GROUP-ID']] = mediaGroupType[entry.attributes['GROUP-ID']] || {};\n mediaGroup = mediaGroupType[entry.attributes['GROUP-ID']]; // collect the rendition metadata\n\n rendition = {\n default: /yes/i.test(entry.attributes.DEFAULT)\n };\n\n if (rendition.default) {\n rendition.autoselect = true;\n } else {\n rendition.autoselect = /yes/i.test(entry.attributes.AUTOSELECT);\n }\n\n if (entry.attributes.LANGUAGE) {\n rendition.language = entry.attributes.LANGUAGE;\n }\n\n if (entry.attributes.URI) {\n rendition.uri = entry.attributes.URI;\n }\n\n if (entry.attributes['INSTREAM-ID']) {\n rendition.instreamId = entry.attributes['INSTREAM-ID'];\n }\n\n if (entry.attributes.CHARACTERISTICS) {\n rendition.characteristics = entry.attributes.CHARACTERISTICS;\n }\n\n if (entry.attributes.FORCED) {\n rendition.forced = /yes/i.test(entry.attributes.FORCED);\n } // insert the new rendition\n\n\n mediaGroup[entry.attributes.NAME] = rendition;\n },\n\n discontinuity() {\n currentTimeline += 1;\n currentUri.discontinuity = true;\n this.manifest.discontinuityStarts.push(uris.length);\n },\n\n 'program-date-time'() {\n if (typeof this.manifest.dateTimeString === 'undefined') {\n // PROGRAM-DATE-TIME is a media-segment tag, but for backwards\n // compatibility, we add the first occurence of the PROGRAM-DATE-TIME tag\n // to the manifest object\n // TODO: Consider removing this in future major version\n this.manifest.dateTimeString = entry.dateTimeString;\n this.manifest.dateTimeObject = entry.dateTimeObject;\n }\n\n currentUri.dateTimeString = entry.dateTimeString;\n currentUri.dateTimeObject = entry.dateTimeObject;\n const {\n lastProgramDateTime\n } = this;\n this.lastProgramDateTime = new Date(entry.dateTimeString).getTime(); // We should extrapolate Program Date Time backward only during first program date time occurrence.\n // Once we have at least one program date time point, we can always extrapolate it forward using lastProgramDateTime reference.\n\n if (lastProgramDateTime === null) {\n // Extrapolate Program Date Time backward\n // Since it is first program date time occurrence we're assuming that\n // all this.manifest.segments have no program date time info\n this.manifest.segments.reduceRight((programDateTime, segment) => {\n segment.programDateTime = programDateTime - segment.duration * 1000;\n return segment.programDateTime;\n }, this.lastProgramDateTime);\n }\n },\n\n targetduration() {\n if (!isFinite(entry.duration) || entry.duration < 0) {\n this.trigger('warn', {\n message: 'ignoring invalid target duration: ' + entry.duration\n });\n return;\n }\n\n this.manifest.targetDuration = entry.duration;\n setHoldBack.call(this, this.manifest);\n },\n\n start() {\n if (!entry.attributes || isNaN(entry.attributes['TIME-OFFSET'])) {\n this.trigger('warn', {\n message: 'ignoring start declaration without appropriate attribute list'\n });\n return;\n }\n\n this.manifest.start = {\n timeOffset: entry.attributes['TIME-OFFSET'],\n precise: entry.attributes.PRECISE\n };\n },\n\n 'cue-out'() {\n currentUri.cueOut = entry.data;\n },\n\n 'cue-out-cont'() {\n currentUri.cueOutCont = entry.data;\n },\n\n 'cue-in'() {\n currentUri.cueIn = entry.data;\n },\n\n 'skip'() {\n this.manifest.skip = camelCaseKeys(entry.attributes);\n this.warnOnMissingAttributes_('#EXT-X-SKIP', entry.attributes, ['SKIPPED-SEGMENTS']);\n },\n\n 'part'() {\n hasParts = true; // parts are always specifed before a segment\n\n const segmentIndex = this.manifest.segments.length;\n const part = camelCaseKeys(entry.attributes);\n currentUri.parts = currentUri.parts || [];\n currentUri.parts.push(part);\n\n if (part.byterange) {\n if (!part.byterange.hasOwnProperty('offset')) {\n part.byterange.offset = lastPartByterangeEnd;\n }\n\n lastPartByterangeEnd = part.byterange.offset + part.byterange.length;\n }\n\n const partIndex = currentUri.parts.length - 1;\n this.warnOnMissingAttributes_(`#EXT-X-PART #${partIndex} for segment #${segmentIndex}`, entry.attributes, ['URI', 'DURATION']);\n\n if (this.manifest.renditionReports) {\n this.manifest.renditionReports.forEach((r, i) => {\n if (!r.hasOwnProperty('lastPart')) {\n this.trigger('warn', {\n message: `#EXT-X-RENDITION-REPORT #${i} lacks required attribute(s): LAST-PART`\n });\n }\n });\n }\n },\n\n 'server-control'() {\n const attrs = this.manifest.serverControl = camelCaseKeys(entry.attributes);\n\n if (!attrs.hasOwnProperty('canBlockReload')) {\n attrs.canBlockReload = false;\n this.trigger('info', {\n message: '#EXT-X-SERVER-CONTROL defaulting CAN-BLOCK-RELOAD to false'\n });\n }\n\n setHoldBack.call(this, this.manifest);\n\n if (attrs.canSkipDateranges && !attrs.hasOwnProperty('canSkipUntil')) {\n this.trigger('warn', {\n message: '#EXT-X-SERVER-CONTROL lacks required attribute CAN-SKIP-UNTIL which is required when CAN-SKIP-DATERANGES is set'\n });\n }\n },\n\n 'preload-hint'() {\n // parts are always specifed before a segment\n const segmentIndex = this.manifest.segments.length;\n const hint = camelCaseKeys(entry.attributes);\n const isPart = hint.type && hint.type === 'PART';\n currentUri.preloadHints = currentUri.preloadHints || [];\n currentUri.preloadHints.push(hint);\n\n if (hint.byterange) {\n if (!hint.byterange.hasOwnProperty('offset')) {\n // use last part byterange end or zero if not a part.\n hint.byterange.offset = isPart ? lastPartByterangeEnd : 0;\n\n if (isPart) {\n lastPartByterangeEnd = hint.byterange.offset + hint.byterange.length;\n }\n }\n }\n\n const index = currentUri.preloadHints.length - 1;\n this.warnOnMissingAttributes_(`#EXT-X-PRELOAD-HINT #${index} for segment #${segmentIndex}`, entry.attributes, ['TYPE', 'URI']);\n\n if (!hint.type) {\n return;\n } // search through all preload hints except for the current one for\n // a duplicate type.\n\n\n for (let i = 0; i < currentUri.preloadHints.length - 1; i++) {\n const otherHint = currentUri.preloadHints[i];\n\n if (!otherHint.type) {\n continue;\n }\n\n if (otherHint.type === hint.type) {\n this.trigger('warn', {\n message: `#EXT-X-PRELOAD-HINT #${index} for segment #${segmentIndex} has the same TYPE ${hint.type} as preload hint #${i}`\n });\n }\n }\n },\n\n 'rendition-report'() {\n const report = camelCaseKeys(entry.attributes);\n this.manifest.renditionReports = this.manifest.renditionReports || [];\n this.manifest.renditionReports.push(report);\n const index = this.manifest.renditionReports.length - 1;\n const required = ['LAST-MSN', 'URI'];\n\n if (hasParts) {\n required.push('LAST-PART');\n }\n\n this.warnOnMissingAttributes_(`#EXT-X-RENDITION-REPORT #${index}`, entry.attributes, required);\n },\n\n 'part-inf'() {\n this.manifest.partInf = camelCaseKeys(entry.attributes);\n this.warnOnMissingAttributes_('#EXT-X-PART-INF', entry.attributes, ['PART-TARGET']);\n\n if (this.manifest.partInf.partTarget) {\n this.manifest.partTargetDuration = this.manifest.partInf.partTarget;\n }\n\n setHoldBack.call(this, this.manifest);\n },\n\n 'daterange'() {\n this.manifest.dateRanges.push(camelCaseKeys(entry.attributes));\n const index = this.manifest.dateRanges.length - 1;\n this.warnOnMissingAttributes_(`#EXT-X-DATERANGE #${index}`, entry.attributes, ['ID', 'START-DATE']);\n const dateRange = this.manifest.dateRanges[index];\n\n if (dateRange.endDate && dateRange.startDate && new Date(dateRange.endDate) < new Date(dateRange.startDate)) {\n this.trigger('warn', {\n message: 'EXT-X-DATERANGE END-DATE must be equal to or later than the value of the START-DATE'\n });\n }\n\n if (dateRange.duration && dateRange.duration < 0) {\n this.trigger('warn', {\n message: 'EXT-X-DATERANGE DURATION must not be negative'\n });\n }\n\n if (dateRange.plannedDuration && dateRange.plannedDuration < 0) {\n this.trigger('warn', {\n message: 'EXT-X-DATERANGE PLANNED-DURATION must not be negative'\n });\n }\n\n const endOnNextYes = !!dateRange.endOnNext;\n\n if (endOnNextYes && !dateRange.class) {\n this.trigger('warn', {\n message: 'EXT-X-DATERANGE with an END-ON-NEXT=YES attribute must have a CLASS attribute'\n });\n }\n\n if (endOnNextYes && (dateRange.duration || dateRange.endDate)) {\n this.trigger('warn', {\n message: 'EXT-X-DATERANGE with an END-ON-NEXT=YES attribute must not contain DURATION or END-DATE attributes'\n });\n }\n\n if (dateRange.duration && dateRange.endDate) {\n const startDate = dateRange.startDate;\n const newDateInSeconds = startDate.getTime() + dateRange.duration * 1000;\n this.manifest.dateRanges[index].endDate = new Date(newDateInSeconds);\n }\n\n if (!dateRangeTags[dateRange.id]) {\n dateRangeTags[dateRange.id] = dateRange;\n } else {\n for (const attribute in dateRangeTags[dateRange.id]) {\n if (!!dateRange[attribute] && JSON.stringify(dateRangeTags[dateRange.id][attribute]) !== JSON.stringify(dateRange[attribute])) {\n this.trigger('warn', {\n message: 'EXT-X-DATERANGE tags with the same ID in a playlist must have the same attributes values'\n });\n break;\n }\n } // if tags with the same ID do not have conflicting attributes, merge them\n\n\n const dateRangeWithSameId = this.manifest.dateRanges.findIndex(dateRangeToFind => dateRangeToFind.id === dateRange.id);\n this.manifest.dateRanges[dateRangeWithSameId] = _extends(this.manifest.dateRanges[dateRangeWithSameId], dateRange);\n dateRangeTags[dateRange.id] = _extends(dateRangeTags[dateRange.id], dateRange); // after merging, delete the duplicate dateRange that was added last\n\n this.manifest.dateRanges.pop();\n }\n },\n\n 'independent-segments'() {\n this.manifest.independentSegments = true;\n },\n\n 'i-frames-only'() {\n this.manifest.iFramesOnly = true;\n this.requiredCompatibilityversion(this.manifest.version, 4);\n },\n\n 'content-steering'() {\n this.manifest.contentSteering = camelCaseKeys(entry.attributes);\n this.warnOnMissingAttributes_('#EXT-X-CONTENT-STEERING', entry.attributes, ['SERVER-URI']);\n },\n\n /** @this {Parser} */\n define() {\n this.manifest.definitions = this.manifest.definitions || {};\n\n const addDef = (n, v) => {\n if (n in this.manifest.definitions) {\n // An EXT-X-DEFINE tag MUST NOT specify the same Variable Name as any other\n // EXT-X-DEFINE tag in the same Playlist. Parsers that encounter duplicate\n // Variable Name declarations MUST fail to parse the Playlist.\n this.trigger('error', {\n message: `EXT-X-DEFINE: Duplicate name ${n}`\n });\n return;\n }\n\n this.manifest.definitions[n] = v;\n };\n\n if ('QUERYPARAM' in entry.attributes) {\n if ('NAME' in entry.attributes || 'IMPORT' in entry.attributes) {\n // An EXT-X-DEFINE tag MUST contain either a NAME, an IMPORT, or a\n // QUERYPARAM attribute, but only one of the three. Otherwise, the\n // client MUST fail to parse the Playlist.\n this.trigger('error', {\n message: 'EXT-X-DEFINE: Invalid attributes'\n });\n return;\n }\n\n const val = this.params.get(entry.attributes.QUERYPARAM);\n\n if (!val) {\n // If the QUERYPARAM attribute value does not match any query parameter in\n // the URI or the matching parameter has no associated value, the parser\n // MUST fail to parse the Playlist. If more than one parameter matches,\n // any of the associated values MAY be used.\n this.trigger('error', {\n message: `EXT-X-DEFINE: No query param ${entry.attributes.QUERYPARAM}`\n });\n return;\n }\n\n addDef(entry.attributes.QUERYPARAM, decodeURIComponent(val));\n return;\n }\n\n if ('NAME' in entry.attributes) {\n if ('IMPORT' in entry.attributes) {\n // An EXT-X-DEFINE tag MUST contain either a NAME, an IMPORT, or a\n // QUERYPARAM attribute, but only one of the three. Otherwise, the\n // client MUST fail to parse the Playlist.\n this.trigger('error', {\n message: 'EXT-X-DEFINE: Invalid attributes'\n });\n return;\n }\n\n if (!('VALUE' in entry.attributes) || typeof entry.attributes.VALUE !== 'string') {\n // This attribute is REQUIRED if the EXT-X-DEFINE tag has a NAME attribute.\n // The quoted-string MAY be empty.\n this.trigger('error', {\n message: `EXT-X-DEFINE: No value for ${entry.attributes.NAME}`\n });\n return;\n }\n\n addDef(entry.attributes.NAME, entry.attributes.VALUE);\n return;\n }\n\n if ('IMPORT' in entry.attributes) {\n if (!this.mainDefinitions[entry.attributes.IMPORT]) {\n // Covers two conditions, as mainDefinitions will always be empty on main\n //\n // EXT-X-DEFINE tags containing the IMPORT attribute MUST NOT occur in\n // Multivariant Playlists; they are only allowed in Media Playlists.\n //\n // If the IMPORT attribute value does not match any Variable Name in the\n // Multivariant Playlist, or if the Media Playlist loaded from a\n // Multivariant Playlist, the parser MUST fail the Playlist.\n this.trigger('error', {\n message: `EXT-X-DEFINE: No value ${entry.attributes.IMPORT} to import, or IMPORT used on main playlist`\n });\n return;\n }\n\n addDef(entry.attributes.IMPORT, this.mainDefinitions[entry.attributes.IMPORT]);\n return;\n } // An EXT-X-DEFINE tag MUST contain either a NAME, an IMPORT, or a QUERYPARAM\n // attribute, but only one of the three. Otherwise, the client MUST fail to\n // parse the Playlist.\n\n\n this.trigger('error', {\n message: 'EXT-X-DEFINE: No attribute'\n });\n },\n\n 'i-frame-playlist'() {\n this.manifest.iFramePlaylists.push({\n attributes: entry.attributes,\n uri: entry.uri,\n timeline: currentTimeline\n });\n this.warnOnMissingAttributes_('#EXT-X-I-FRAME-STREAM-INF', entry.attributes, ['BANDWIDTH', 'URI']);\n }\n\n })[entry.tagType] || noop).call(self);\n },\n\n uri() {\n currentUri.uri = entry.uri;\n uris.push(currentUri); // if no explicit duration was declared, use the target duration\n\n if (this.manifest.targetDuration && !('duration' in currentUri)) {\n this.trigger('warn', {\n message: 'defaulting segment duration to the target duration'\n });\n currentUri.duration = this.manifest.targetDuration;\n } // annotate with encryption information, if necessary\n\n\n if (key) {\n currentUri.key = key;\n }\n\n currentUri.timeline = currentTimeline; // annotate with initialization segment information, if necessary\n\n if (currentMap) {\n currentUri.map = currentMap;\n } // reset the last byterange end as it needs to be 0 between parts\n\n\n lastPartByterangeEnd = 0; // Once we have at least one program date time we can always extrapolate it forward\n\n if (this.lastProgramDateTime !== null) {\n currentUri.programDateTime = this.lastProgramDateTime;\n this.lastProgramDateTime += currentUri.duration * 1000;\n } // prepare for the next URI\n\n\n currentUri = {};\n },\n\n comment() {// comments are not important for playback\n },\n\n custom() {\n // if this is segment-level data attach the output to the segment\n if (entry.segment) {\n currentUri.custom = currentUri.custom || {};\n currentUri.custom[entry.customType] = entry.data; // if this is manifest-level data attach to the top level manifest object\n } else {\n this.manifest.custom = this.manifest.custom || {};\n this.manifest.custom[entry.customType] = entry.data;\n }\n }\n\n })[entry.type].call(self);\n });\n }\n\n requiredCompatibilityversion(currentVersion, targetVersion) {\n if (currentVersion < targetVersion || !currentVersion) {\n this.trigger('warn', {\n message: `manifest must be at least version ${targetVersion}`\n });\n }\n }\n\n warnOnMissingAttributes_(identifier, attributes, required) {\n const missing = [];\n required.forEach(function (key) {\n if (!attributes.hasOwnProperty(key)) {\n missing.push(key);\n }\n });\n\n if (missing.length) {\n this.trigger('warn', {\n message: `${identifier} lacks required attribute(s): ${missing.join(', ')}`\n });\n }\n }\n /**\n * Parse the input string and update the manifest object.\n *\n * @param {string} chunk a potentially incomplete portion of the manifest\n */\n\n\n push(chunk) {\n this.lineStream.push(chunk);\n }\n /**\n * Flush any remaining input. This can be handy if the last line of an M3U8\n * manifest did not contain a trailing newline but the file has been\n * completely received.\n */\n\n\n end() {\n // flush any buffered input\n this.lineStream.push('\\n');\n\n if (this.manifest.dateRanges.length && this.lastProgramDateTime === null) {\n this.trigger('warn', {\n message: 'A playlist with EXT-X-DATERANGE tag must contain atleast one EXT-X-PROGRAM-DATE-TIME tag'\n });\n }\n\n this.lastProgramDateTime = null;\n this.trigger('end');\n }\n /**\n * Add an additional parser for non-standard tags\n *\n * @param {Object} options a map of options for the added parser\n * @param {RegExp} options.expression a regular expression to match the custom header\n * @param {string} options.customType the custom type to register to the output\n * @param {Function} [options.dataParser] function to parse the line into an object\n * @param {boolean} [options.segment] should tag data be attached to the segment object\n */\n\n\n addParser(options) {\n this.parseStream.addParser(options);\n }\n /**\n * Add a custom header mapper\n *\n * @param {Object} options\n * @param {RegExp} options.expression a regular expression to match the custom header\n * @param {Function} options.map function to translate tag into a different tag\n */\n\n\n addTagMapper(options) {\n this.parseStream.addTagMapper(options);\n }\n\n}\n\nexport { LineStream, ParseStream, Parser };\n","/**\n * Copyright 2013 vtt.js Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */\nvar document = require('global/document');\n\nvar _objCreate = Object.create || (function() {\n function F() {}\n return function(o) {\n if (arguments.length !== 1) {\n throw new Error('Object.create shim only accepts one parameter.');\n }\n F.prototype = o;\n return new F();\n };\n})();\n\n// Creates a new ParserError object from an errorData object. The errorData\n// object should have default code and message properties. The default message\n// property can be overriden by passing in a message parameter.\n// See ParsingError.Errors below for acceptable errors.\nfunction ParsingError(errorData, message) {\n this.name = \"ParsingError\";\n this.code = errorData.code;\n this.message = message || errorData.message;\n}\nParsingError.prototype = _objCreate(Error.prototype);\nParsingError.prototype.constructor = ParsingError;\n\n// ParsingError metadata for acceptable ParsingErrors.\nParsingError.Errors = {\n BadSignature: {\n code: 0,\n message: \"Malformed WebVTT signature.\"\n },\n BadTimeStamp: {\n code: 1,\n message: \"Malformed time stamp.\"\n }\n};\n\n// Try to parse input as a time stamp.\nfunction parseTimeStamp(input) {\n\n function computeSeconds(h, m, s, f) {\n return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000;\n }\n\n var m = input.match(/^(\\d+):(\\d{1,2})(:\\d{1,2})?\\.(\\d{3})/);\n if (!m) {\n return null;\n }\n\n if (m[3]) {\n // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds]\n return computeSeconds(m[1], m[2], m[3].replace(\":\", \"\"), m[4]);\n } else if (m[1] > 59) {\n // Timestamp takes the form of [hours]:[minutes].[milliseconds]\n // First position is hours as it's over 59.\n return computeSeconds(m[1], m[2], 0, m[4]);\n } else {\n // Timestamp takes the form of [minutes]:[seconds].[milliseconds]\n return computeSeconds(0, m[1], m[2], m[4]);\n }\n}\n\n// A settings object holds key/value pairs and will ignore anything but the first\n// assignment to a specific key.\nfunction Settings() {\n this.values = _objCreate(null);\n}\n\nSettings.prototype = {\n // Only accept the first assignment to any key.\n set: function(k, v) {\n if (!this.get(k) && v !== \"\") {\n this.values[k] = v;\n }\n },\n // Return the value for a key, or a default value.\n // If 'defaultKey' is passed then 'dflt' is assumed to be an object with\n // a number of possible default values as properties where 'defaultKey' is\n // the key of the property that will be chosen; otherwise it's assumed to be\n // a single value.\n get: function(k, dflt, defaultKey) {\n if (defaultKey) {\n return this.has(k) ? this.values[k] : dflt[defaultKey];\n }\n return this.has(k) ? this.values[k] : dflt;\n },\n // Check whether we have a value for a key.\n has: function(k) {\n return k in this.values;\n },\n // Accept a setting if its one of the given alternatives.\n alt: function(k, v, a) {\n for (var n = 0; n < a.length; ++n) {\n if (v === a[n]) {\n this.set(k, v);\n break;\n }\n }\n },\n // Accept a setting if its a valid (signed) integer.\n integer: function(k, v) {\n if (/^-?\\d+$/.test(v)) { // integer\n this.set(k, parseInt(v, 10));\n }\n },\n // Accept a setting if its a valid percentage.\n percent: function(k, v) {\n var m;\n if ((m = v.match(/^([\\d]{1,3})(\\.[\\d]*)?%$/))) {\n v = parseFloat(v);\n if (v >= 0 && v <= 100) {\n this.set(k, v);\n return true;\n }\n }\n return false;\n }\n};\n\n// Helper function to parse input into groups separated by 'groupDelim', and\n// interprete each group as a key/value pair separated by 'keyValueDelim'.\nfunction parseOptions(input, callback, keyValueDelim, groupDelim) {\n var groups = groupDelim ? input.split(groupDelim) : [input];\n for (var i in groups) {\n if (typeof groups[i] !== \"string\") {\n continue;\n }\n var kv = groups[i].split(keyValueDelim);\n if (kv.length !== 2) {\n continue;\n }\n var k = kv[0].trim();\n var v = kv[1].trim();\n callback(k, v);\n }\n}\n\nfunction parseCue(input, cue, regionList) {\n // Remember the original input if we need to throw an error.\n var oInput = input;\n // 4.1 WebVTT timestamp\n function consumeTimeStamp() {\n var ts = parseTimeStamp(input);\n if (ts === null) {\n throw new ParsingError(ParsingError.Errors.BadTimeStamp,\n \"Malformed timestamp: \" + oInput);\n }\n // Remove time stamp from input.\n input = input.replace(/^[^\\sa-zA-Z-]+/, \"\");\n return ts;\n }\n\n // 4.4.2 WebVTT cue settings\n function consumeCueSettings(input, cue) {\n var settings = new Settings();\n\n parseOptions(input, function (k, v) {\n switch (k) {\n case \"region\":\n // Find the last region we parsed with the same region id.\n for (var i = regionList.length - 1; i >= 0; i--) {\n if (regionList[i].id === v) {\n settings.set(k, regionList[i].region);\n break;\n }\n }\n break;\n case \"vertical\":\n settings.alt(k, v, [\"rl\", \"lr\"]);\n break;\n case \"line\":\n var vals = v.split(\",\"),\n vals0 = vals[0];\n settings.integer(k, vals0);\n settings.percent(k, vals0) ? settings.set(\"snapToLines\", false) : null;\n settings.alt(k, vals0, [\"auto\"]);\n if (vals.length === 2) {\n settings.alt(\"lineAlign\", vals[1], [\"start\", \"center\", \"end\"]);\n }\n break;\n case \"position\":\n vals = v.split(\",\");\n settings.percent(k, vals[0]);\n if (vals.length === 2) {\n settings.alt(\"positionAlign\", vals[1], [\"start\", \"center\", \"end\"]);\n }\n break;\n case \"size\":\n settings.percent(k, v);\n break;\n case \"align\":\n settings.alt(k, v, [\"start\", \"center\", \"end\", \"left\", \"right\"]);\n break;\n }\n }, /:/, /\\s/);\n\n // Apply default values for any missing fields.\n cue.region = settings.get(\"region\", null);\n cue.vertical = settings.get(\"vertical\", \"\");\n try {\n cue.line = settings.get(\"line\", \"auto\");\n } catch (e) {}\n cue.lineAlign = settings.get(\"lineAlign\", \"start\");\n cue.snapToLines = settings.get(\"snapToLines\", true);\n cue.size = settings.get(\"size\", 100);\n // Safari still uses the old middle value and won't accept center\n try {\n cue.align = settings.get(\"align\", \"center\");\n } catch (e) {\n cue.align = settings.get(\"align\", \"middle\");\n }\n try {\n cue.position = settings.get(\"position\", \"auto\");\n } catch (e) {\n cue.position = settings.get(\"position\", {\n start: 0,\n left: 0,\n center: 50,\n middle: 50,\n end: 100,\n right: 100\n }, cue.align);\n }\n\n\n cue.positionAlign = settings.get(\"positionAlign\", {\n start: \"start\",\n left: \"start\",\n center: \"center\",\n middle: \"center\",\n end: \"end\",\n right: \"end\"\n }, cue.align);\n }\n\n function skipWhitespace() {\n input = input.replace(/^\\s+/, \"\");\n }\n\n // 4.1 WebVTT cue timings.\n skipWhitespace();\n cue.startTime = consumeTimeStamp(); // (1) collect cue start time\n skipWhitespace();\n if (input.substr(0, 3) !== \"-->\") { // (3) next characters must match \"-->\"\n throw new ParsingError(ParsingError.Errors.BadTimeStamp,\n \"Malformed time stamp (time stamps must be separated by '-->'): \" +\n oInput);\n }\n input = input.substr(3);\n skipWhitespace();\n cue.endTime = consumeTimeStamp(); // (5) collect cue end time\n\n // 4.1 WebVTT cue settings list.\n skipWhitespace();\n consumeCueSettings(input, cue);\n}\n\n// When evaluating this file as part of a Webpack bundle for server\n// side rendering, `document` is an empty object.\nvar TEXTAREA_ELEMENT = document.createElement && document.createElement(\"textarea\");\n\nvar TAG_NAME = {\n c: \"span\",\n i: \"i\",\n b: \"b\",\n u: \"u\",\n ruby: \"ruby\",\n rt: \"rt\",\n v: \"span\",\n lang: \"span\"\n};\n\n// 5.1 default text color\n// 5.2 default text background color is equivalent to text color with bg_ prefix\nvar DEFAULT_COLOR_CLASS = {\n white: 'rgba(255,255,255,1)',\n lime: 'rgba(0,255,0,1)',\n cyan: 'rgba(0,255,255,1)',\n red: 'rgba(255,0,0,1)',\n yellow: 'rgba(255,255,0,1)',\n magenta: 'rgba(255,0,255,1)',\n blue: 'rgba(0,0,255,1)',\n black: 'rgba(0,0,0,1)'\n};\n\nvar TAG_ANNOTATION = {\n v: \"title\",\n lang: \"lang\"\n};\n\nvar NEEDS_PARENT = {\n rt: \"ruby\"\n};\n\n// Parse content into a document fragment.\nfunction parseContent(window, input) {\n function nextToken() {\n // Check for end-of-string.\n if (!input) {\n return null;\n }\n\n // Consume 'n' characters from the input.\n function consume(result) {\n input = input.substr(result.length);\n return result;\n }\n\n var m = input.match(/^([^<]*)(<[^>]*>?)?/);\n // If there is some text before the next tag, return it, otherwise return\n // the tag.\n return consume(m[1] ? m[1] : m[2]);\n }\n\n function unescape(s) {\n TEXTAREA_ELEMENT.innerHTML = s;\n s = TEXTAREA_ELEMENT.textContent;\n TEXTAREA_ELEMENT.textContent = \"\";\n return s;\n }\n\n function shouldAdd(current, element) {\n return !NEEDS_PARENT[element.localName] ||\n NEEDS_PARENT[element.localName] === current.localName;\n }\n\n // Create an element for this tag.\n function createElement(type, annotation) {\n var tagName = TAG_NAME[type];\n if (!tagName) {\n return null;\n }\n var element = window.document.createElement(tagName);\n var name = TAG_ANNOTATION[type];\n if (name && annotation) {\n element[name] = annotation.trim();\n }\n return element;\n }\n\n var rootDiv = window.document.createElement(\"div\"),\n current = rootDiv,\n t,\n tagStack = [];\n\n while ((t = nextToken()) !== null) {\n if (t[0] === '<') {\n if (t[1] === \"/\") {\n // If the closing tag matches, move back up to the parent node.\n if (tagStack.length &&\n tagStack[tagStack.length - 1] === t.substr(2).replace(\">\", \"\")) {\n tagStack.pop();\n current = current.parentNode;\n }\n // Otherwise just ignore the end tag.\n continue;\n }\n var ts = parseTimeStamp(t.substr(1, t.length - 2));\n var node;\n if (ts) {\n // Timestamps are lead nodes as well.\n node = window.document.createProcessingInstruction(\"timestamp\", ts);\n current.appendChild(node);\n continue;\n }\n var m = t.match(/^<([^.\\s/0-9>]+)(\\.[^\\s\\\\>]+)?([^>\\\\]+)?(\\\\?)>?$/);\n // If we can't parse the tag, skip to the next tag.\n if (!m) {\n continue;\n }\n // Try to construct an element, and ignore the tag if we couldn't.\n node = createElement(m[1], m[3]);\n if (!node) {\n continue;\n }\n // Determine if the tag should be added based on the context of where it\n // is placed in the cuetext.\n if (!shouldAdd(current, node)) {\n continue;\n }\n // Set the class list (as a list of classes, separated by space).\n if (m[2]) {\n var classes = m[2].split('.');\n\n classes.forEach(function(cl) {\n var bgColor = /^bg_/.test(cl);\n // slice out `bg_` if it's a background color\n var colorName = bgColor ? cl.slice(3) : cl;\n\n if (DEFAULT_COLOR_CLASS.hasOwnProperty(colorName)) {\n var propName = bgColor ? 'background-color' : 'color';\n var propValue = DEFAULT_COLOR_CLASS[colorName];\n\n node.style[propName] = propValue;\n }\n });\n\n node.className = classes.join(' ');\n }\n // Append the node to the current node, and enter the scope of the new\n // node.\n tagStack.push(m[1]);\n current.appendChild(node);\n current = node;\n continue;\n }\n\n // Text nodes are leaf nodes.\n current.appendChild(window.document.createTextNode(unescape(t)));\n }\n\n return rootDiv;\n}\n\n// This is a list of all the Unicode characters that have a strong\n// right-to-left category. What this means is that these characters are\n// written right-to-left for sure. It was generated by pulling all the strong\n// right-to-left characters out of the Unicode data table. That table can\n// found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt\nvar strongRTLRanges = [[0x5be, 0x5be], [0x5c0, 0x5c0], [0x5c3, 0x5c3], [0x5c6, 0x5c6],\n [0x5d0, 0x5ea], [0x5f0, 0x5f4], [0x608, 0x608], [0x60b, 0x60b], [0x60d, 0x60d],\n [0x61b, 0x61b], [0x61e, 0x64a], [0x66d, 0x66f], [0x671, 0x6d5], [0x6e5, 0x6e6],\n [0x6ee, 0x6ef], [0x6fa, 0x70d], [0x70f, 0x710], [0x712, 0x72f], [0x74d, 0x7a5],\n [0x7b1, 0x7b1], [0x7c0, 0x7ea], [0x7f4, 0x7f5], [0x7fa, 0x7fa], [0x800, 0x815],\n [0x81a, 0x81a], [0x824, 0x824], [0x828, 0x828], [0x830, 0x83e], [0x840, 0x858],\n [0x85e, 0x85e], [0x8a0, 0x8a0], [0x8a2, 0x8ac], [0x200f, 0x200f],\n [0xfb1d, 0xfb1d], [0xfb1f, 0xfb28], [0xfb2a, 0xfb36], [0xfb38, 0xfb3c],\n [0xfb3e, 0xfb3e], [0xfb40, 0xfb41], [0xfb43, 0xfb44], [0xfb46, 0xfbc1],\n [0xfbd3, 0xfd3d], [0xfd50, 0xfd8f], [0xfd92, 0xfdc7], [0xfdf0, 0xfdfc],\n [0xfe70, 0xfe74], [0xfe76, 0xfefc], [0x10800, 0x10805], [0x10808, 0x10808],\n [0x1080a, 0x10835], [0x10837, 0x10838], [0x1083c, 0x1083c], [0x1083f, 0x10855],\n [0x10857, 0x1085f], [0x10900, 0x1091b], [0x10920, 0x10939], [0x1093f, 0x1093f],\n [0x10980, 0x109b7], [0x109be, 0x109bf], [0x10a00, 0x10a00], [0x10a10, 0x10a13],\n [0x10a15, 0x10a17], [0x10a19, 0x10a33], [0x10a40, 0x10a47], [0x10a50, 0x10a58],\n [0x10a60, 0x10a7f], [0x10b00, 0x10b35], [0x10b40, 0x10b55], [0x10b58, 0x10b72],\n [0x10b78, 0x10b7f], [0x10c00, 0x10c48], [0x1ee00, 0x1ee03], [0x1ee05, 0x1ee1f],\n [0x1ee21, 0x1ee22], [0x1ee24, 0x1ee24], [0x1ee27, 0x1ee27], [0x1ee29, 0x1ee32],\n [0x1ee34, 0x1ee37], [0x1ee39, 0x1ee39], [0x1ee3b, 0x1ee3b], [0x1ee42, 0x1ee42],\n [0x1ee47, 0x1ee47], [0x1ee49, 0x1ee49], [0x1ee4b, 0x1ee4b], [0x1ee4d, 0x1ee4f],\n [0x1ee51, 0x1ee52], [0x1ee54, 0x1ee54], [0x1ee57, 0x1ee57], [0x1ee59, 0x1ee59],\n [0x1ee5b, 0x1ee5b], [0x1ee5d, 0x1ee5d], [0x1ee5f, 0x1ee5f], [0x1ee61, 0x1ee62],\n [0x1ee64, 0x1ee64], [0x1ee67, 0x1ee6a], [0x1ee6c, 0x1ee72], [0x1ee74, 0x1ee77],\n [0x1ee79, 0x1ee7c], [0x1ee7e, 0x1ee7e], [0x1ee80, 0x1ee89], [0x1ee8b, 0x1ee9b],\n [0x1eea1, 0x1eea3], [0x1eea5, 0x1eea9], [0x1eeab, 0x1eebb], [0x10fffd, 0x10fffd]];\n\nfunction isStrongRTLChar(charCode) {\n for (var i = 0; i < strongRTLRanges.length; i++) {\n var currentRange = strongRTLRanges[i];\n if (charCode >= currentRange[0] && charCode <= currentRange[1]) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction determineBidi(cueDiv) {\n var nodeStack = [],\n text = \"\",\n charCode;\n\n if (!cueDiv || !cueDiv.childNodes) {\n return \"ltr\";\n }\n\n function pushNodes(nodeStack, node) {\n for (var i = node.childNodes.length - 1; i >= 0; i--) {\n nodeStack.push(node.childNodes[i]);\n }\n }\n\n function nextTextNode(nodeStack) {\n if (!nodeStack || !nodeStack.length) {\n return null;\n }\n\n var node = nodeStack.pop(),\n text = node.textContent || node.innerText;\n if (text) {\n // TODO: This should match all unicode type B characters (paragraph\n // separator characters). See issue #115.\n var m = text.match(/^.*(\\n|\\r)/);\n if (m) {\n nodeStack.length = 0;\n return m[0];\n }\n return text;\n }\n if (node.tagName === \"ruby\") {\n return nextTextNode(nodeStack);\n }\n if (node.childNodes) {\n pushNodes(nodeStack, node);\n return nextTextNode(nodeStack);\n }\n }\n\n pushNodes(nodeStack, cueDiv);\n while ((text = nextTextNode(nodeStack))) {\n for (var i = 0; i < text.length; i++) {\n charCode = text.charCodeAt(i);\n if (isStrongRTLChar(charCode)) {\n return \"rtl\";\n }\n }\n }\n return \"ltr\";\n}\n\nfunction computeLinePos(cue) {\n if (typeof cue.line === \"number\" &&\n (cue.snapToLines || (cue.line >= 0 && cue.line <= 100))) {\n return cue.line;\n }\n if (!cue.track || !cue.track.textTrackList ||\n !cue.track.textTrackList.mediaElement) {\n return -1;\n }\n var track = cue.track,\n trackList = track.textTrackList,\n count = 0;\n for (var i = 0; i < trackList.length && trackList[i] !== track; i++) {\n if (trackList[i].mode === \"showing\") {\n count++;\n }\n }\n return ++count * -1;\n}\n\nfunction StyleBox() {\n}\n\n// Apply styles to a div. If there is no div passed then it defaults to the\n// div on 'this'.\nStyleBox.prototype.applyStyles = function(styles, div) {\n div = div || this.div;\n for (var prop in styles) {\n if (styles.hasOwnProperty(prop)) {\n div.style[prop] = styles[prop];\n }\n }\n};\n\nStyleBox.prototype.formatStyle = function(val, unit) {\n return val === 0 ? 0 : val + unit;\n};\n\n// Constructs the computed display state of the cue (a div). Places the div\n// into the overlay which should be a block level element (usually a div).\nfunction CueStyleBox(window, cue, styleOptions) {\n StyleBox.call(this);\n this.cue = cue;\n\n // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will\n // have inline positioning and will function as the cue background box.\n this.cueDiv = parseContent(window, cue.text);\n var styles = {\n color: \"rgba(255, 255, 255, 1)\",\n backgroundColor: \"rgba(0, 0, 0, 0.8)\",\n position: \"relative\",\n left: 0,\n right: 0,\n top: 0,\n bottom: 0,\n display: \"inline\",\n writingMode: cue.vertical === \"\" ? \"horizontal-tb\"\n : cue.vertical === \"lr\" ? \"vertical-lr\"\n : \"vertical-rl\",\n unicodeBidi: \"plaintext\"\n };\n\n this.applyStyles(styles, this.cueDiv);\n\n // Create an absolutely positioned div that will be used to position the cue\n // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS\n // mirrors of them except middle instead of center on Safari.\n this.div = window.document.createElement(\"div\");\n styles = {\n direction: determineBidi(this.cueDiv),\n writingMode: cue.vertical === \"\" ? \"horizontal-tb\"\n : cue.vertical === \"lr\" ? \"vertical-lr\"\n : \"vertical-rl\",\n unicodeBidi: \"plaintext\",\n textAlign: cue.align === \"middle\" ? \"center\" : cue.align,\n font: styleOptions.font,\n whiteSpace: \"pre-line\",\n position: \"absolute\"\n };\n\n this.applyStyles(styles);\n this.div.appendChild(this.cueDiv);\n\n // Calculate the distance from the reference edge of the viewport to the text\n // position of the cue box. The reference edge will be resolved later when\n // the box orientation styles are applied.\n var textPos = 0;\n switch (cue.positionAlign) {\n case \"start\":\n case \"line-left\":\n textPos = cue.position;\n break;\n case \"center\":\n textPos = cue.position - (cue.size / 2);\n break;\n case \"end\":\n case \"line-right\":\n textPos = cue.position - cue.size;\n break;\n }\n\n // Horizontal box orientation; textPos is the distance from the left edge of the\n // area to the left edge of the box and cue.size is the distance extending to\n // the right from there.\n if (cue.vertical === \"\") {\n this.applyStyles({\n left: this.formatStyle(textPos, \"%\"),\n width: this.formatStyle(cue.size, \"%\")\n });\n // Vertical box orientation; textPos is the distance from the top edge of the\n // area to the top edge of the box and cue.size is the height extending\n // downwards from there.\n } else {\n this.applyStyles({\n top: this.formatStyle(textPos, \"%\"),\n height: this.formatStyle(cue.size, \"%\")\n });\n }\n\n this.move = function(box) {\n this.applyStyles({\n top: this.formatStyle(box.top, \"px\"),\n bottom: this.formatStyle(box.bottom, \"px\"),\n left: this.formatStyle(box.left, \"px\"),\n right: this.formatStyle(box.right, \"px\"),\n height: this.formatStyle(box.height, \"px\"),\n width: this.formatStyle(box.width, \"px\")\n });\n };\n}\nCueStyleBox.prototype = _objCreate(StyleBox.prototype);\nCueStyleBox.prototype.constructor = CueStyleBox;\n\n// Represents the co-ordinates of an Element in a way that we can easily\n// compute things with such as if it overlaps or intersects with another Element.\n// Can initialize it with either a StyleBox or another BoxPosition.\nfunction BoxPosition(obj) {\n // Either a BoxPosition was passed in and we need to copy it, or a StyleBox\n // was passed in and we need to copy the results of 'getBoundingClientRect'\n // as the object returned is readonly. All co-ordinate values are in reference\n // to the viewport origin (top left).\n var lh, height, width, top;\n if (obj.div) {\n height = obj.div.offsetHeight;\n width = obj.div.offsetWidth;\n top = obj.div.offsetTop;\n\n var rects = (rects = obj.div.childNodes) && (rects = rects[0]) &&\n rects.getClientRects && rects.getClientRects();\n obj = obj.div.getBoundingClientRect();\n // In certain cases the outter div will be slightly larger then the sum of\n // the inner div's lines. This could be due to bold text, etc, on some platforms.\n // In this case we should get the average line height and use that. This will\n // result in the desired behaviour.\n lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length)\n : 0;\n\n }\n this.left = obj.left;\n this.right = obj.right;\n this.top = obj.top || top;\n this.height = obj.height || height;\n this.bottom = obj.bottom || (top + (obj.height || height));\n this.width = obj.width || width;\n this.lineHeight = lh !== undefined ? lh : obj.lineHeight;\n}\n\n// Move the box along a particular axis. Optionally pass in an amount to move\n// the box. If no amount is passed then the default is the line height of the\n// box.\nBoxPosition.prototype.move = function(axis, toMove) {\n toMove = toMove !== undefined ? toMove : this.lineHeight;\n switch (axis) {\n case \"+x\":\n this.left += toMove;\n this.right += toMove;\n break;\n case \"-x\":\n this.left -= toMove;\n this.right -= toMove;\n break;\n case \"+y\":\n this.top += toMove;\n this.bottom += toMove;\n break;\n case \"-y\":\n this.top -= toMove;\n this.bottom -= toMove;\n break;\n }\n};\n\n// Check if this box overlaps another box, b2.\nBoxPosition.prototype.overlaps = function(b2) {\n return this.left < b2.right &&\n this.right > b2.left &&\n this.top < b2.bottom &&\n this.bottom > b2.top;\n};\n\n// Check if this box overlaps any other boxes in boxes.\nBoxPosition.prototype.overlapsAny = function(boxes) {\n for (var i = 0; i < boxes.length; i++) {\n if (this.overlaps(boxes[i])) {\n return true;\n }\n }\n return false;\n};\n\n// Check if this box is within another box.\nBoxPosition.prototype.within = function(container) {\n return this.top >= container.top &&\n this.bottom <= container.bottom &&\n this.left >= container.left &&\n this.right <= container.right;\n};\n\n// Check if this box is entirely within the container or it is overlapping\n// on the edge opposite of the axis direction passed. For example, if \"+x\" is\n// passed and the box is overlapping on the left edge of the container, then\n// return true.\nBoxPosition.prototype.overlapsOppositeAxis = function(container, axis) {\n switch (axis) {\n case \"+x\":\n return this.left < container.left;\n case \"-x\":\n return this.right > container.right;\n case \"+y\":\n return this.top < container.top;\n case \"-y\":\n return this.bottom > container.bottom;\n }\n};\n\n// Find the percentage of the area that this box is overlapping with another\n// box.\nBoxPosition.prototype.intersectPercentage = function(b2) {\n var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)),\n y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)),\n intersectArea = x * y;\n return intersectArea / (this.height * this.width);\n};\n\n// Convert the positions from this box to CSS compatible positions using\n// the reference container's positions. This has to be done because this\n// box's positions are in reference to the viewport origin, whereas, CSS\n// values are in referecne to their respective edges.\nBoxPosition.prototype.toCSSCompatValues = function(reference) {\n return {\n top: this.top - reference.top,\n bottom: reference.bottom - this.bottom,\n left: this.left - reference.left,\n right: reference.right - this.right,\n height: this.height,\n width: this.width\n };\n};\n\n// Get an object that represents the box's position without anything extra.\n// Can pass a StyleBox, HTMLElement, or another BoxPositon.\nBoxPosition.getSimpleBoxPosition = function(obj) {\n var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0;\n var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0;\n var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0;\n\n obj = obj.div ? obj.div.getBoundingClientRect() :\n obj.tagName ? obj.getBoundingClientRect() : obj;\n var ret = {\n left: obj.left,\n right: obj.right,\n top: obj.top || top,\n height: obj.height || height,\n bottom: obj.bottom || (top + (obj.height || height)),\n width: obj.width || width\n };\n return ret;\n};\n\n// Move a StyleBox to its specified, or next best, position. The containerBox\n// is the box that contains the StyleBox, such as a div. boxPositions are\n// a list of other boxes that the styleBox can't overlap with.\nfunction moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) {\n\n // Find the best position for a cue box, b, on the video. The axis parameter\n // is a list of axis, the order of which, it will move the box along. For example:\n // Passing [\"+x\", \"-x\"] will move the box first along the x axis in the positive\n // direction. If it doesn't find a good position for it there it will then move\n // it along the x axis in the negative direction.\n function findBestPosition(b, axis) {\n var bestPosition,\n specifiedPosition = new BoxPosition(b),\n percentage = 1; // Highest possible so the first thing we get is better.\n\n for (var i = 0; i < axis.length; i++) {\n while (b.overlapsOppositeAxis(containerBox, axis[i]) ||\n (b.within(containerBox) && b.overlapsAny(boxPositions))) {\n b.move(axis[i]);\n }\n // We found a spot where we aren't overlapping anything. This is our\n // best position.\n if (b.within(containerBox)) {\n return b;\n }\n var p = b.intersectPercentage(containerBox);\n // If we're outside the container box less then we were on our last try\n // then remember this position as the best position.\n if (percentage > p) {\n bestPosition = new BoxPosition(b);\n percentage = p;\n }\n // Reset the box position to the specified position.\n b = new BoxPosition(specifiedPosition);\n }\n return bestPosition || specifiedPosition;\n }\n\n var boxPosition = new BoxPosition(styleBox),\n cue = styleBox.cue,\n linePos = computeLinePos(cue),\n axis = [];\n\n // If we have a line number to align the cue to.\n if (cue.snapToLines) {\n var size;\n switch (cue.vertical) {\n case \"\":\n axis = [ \"+y\", \"-y\" ];\n size = \"height\";\n break;\n case \"rl\":\n axis = [ \"+x\", \"-x\" ];\n size = \"width\";\n break;\n case \"lr\":\n axis = [ \"-x\", \"+x\" ];\n size = \"width\";\n break;\n }\n\n var step = boxPosition.lineHeight,\n position = step * Math.round(linePos),\n maxPosition = containerBox[size] + step,\n initialAxis = axis[0];\n\n // If the specified intial position is greater then the max position then\n // clamp the box to the amount of steps it would take for the box to\n // reach the max position.\n if (Math.abs(position) > maxPosition) {\n position = position < 0 ? -1 : 1;\n position *= Math.ceil(maxPosition / step) * step;\n }\n\n // If computed line position returns negative then line numbers are\n // relative to the bottom of the video instead of the top. Therefore, we\n // need to increase our initial position by the length or width of the\n // video, depending on the writing direction, and reverse our axis directions.\n if (linePos < 0) {\n position += cue.vertical === \"\" ? containerBox.height : containerBox.width;\n axis = axis.reverse();\n }\n\n // Move the box to the specified position. This may not be its best\n // position.\n boxPosition.move(initialAxis, position);\n\n } else {\n // If we have a percentage line value for the cue.\n var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100;\n\n switch (cue.lineAlign) {\n case \"center\":\n linePos -= (calculatedPercentage / 2);\n break;\n case \"end\":\n linePos -= calculatedPercentage;\n break;\n }\n\n // Apply initial line position to the cue box.\n switch (cue.vertical) {\n case \"\":\n styleBox.applyStyles({\n top: styleBox.formatStyle(linePos, \"%\")\n });\n break;\n case \"rl\":\n styleBox.applyStyles({\n left: styleBox.formatStyle(linePos, \"%\")\n });\n break;\n case \"lr\":\n styleBox.applyStyles({\n right: styleBox.formatStyle(linePos, \"%\")\n });\n break;\n }\n\n axis = [ \"+y\", \"-x\", \"+x\", \"-y\" ];\n\n // Get the box position again after we've applied the specified positioning\n // to it.\n boxPosition = new BoxPosition(styleBox);\n }\n\n var bestPosition = findBestPosition(boxPosition, axis);\n styleBox.move(bestPosition.toCSSCompatValues(containerBox));\n}\n\nfunction WebVTT() {\n // Nothing\n}\n\n// Helper to allow strings to be decoded instead of the default binary utf8 data.\nWebVTT.StringDecoder = function() {\n return {\n decode: function(data) {\n if (!data) {\n return \"\";\n }\n if (typeof data !== \"string\") {\n throw new Error(\"Error - expected string data.\");\n }\n return decodeURIComponent(encodeURIComponent(data));\n }\n };\n};\n\nWebVTT.convertCueToDOMTree = function(window, cuetext) {\n if (!window || !cuetext) {\n return null;\n }\n return parseContent(window, cuetext);\n};\n\nvar FONT_SIZE_PERCENT = 0.05;\nvar FONT_STYLE = \"sans-serif\";\nvar CUE_BACKGROUND_PADDING = \"1.5%\";\n\n// Runs the processing model over the cues and regions passed to it.\n// @param overlay A block level element (usually a div) that the computed cues\n// and regions will be placed into.\nWebVTT.processCues = function(window, cues, overlay) {\n if (!window || !cues || !overlay) {\n return null;\n }\n\n // Remove all previous children.\n while (overlay.firstChild) {\n overlay.removeChild(overlay.firstChild);\n }\n\n var paddedOverlay = window.document.createElement(\"div\");\n paddedOverlay.style.position = \"absolute\";\n paddedOverlay.style.left = \"0\";\n paddedOverlay.style.right = \"0\";\n paddedOverlay.style.top = \"0\";\n paddedOverlay.style.bottom = \"0\";\n paddedOverlay.style.margin = CUE_BACKGROUND_PADDING;\n overlay.appendChild(paddedOverlay);\n\n // Determine if we need to compute the display states of the cues. This could\n // be the case if a cue's state has been changed since the last computation or\n // if it has not been computed yet.\n function shouldCompute(cues) {\n for (var i = 0; i < cues.length; i++) {\n if (cues[i].hasBeenReset || !cues[i].displayState) {\n return true;\n }\n }\n return false;\n }\n\n // We don't need to recompute the cues' display states. Just reuse them.\n if (!shouldCompute(cues)) {\n for (var i = 0; i < cues.length; i++) {\n paddedOverlay.appendChild(cues[i].displayState);\n }\n return;\n }\n\n var boxPositions = [],\n containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay),\n fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100;\n var styleOptions = {\n font: fontSize + \"px \" + FONT_STYLE\n };\n\n (function() {\n var styleBox, cue;\n\n for (var i = 0; i < cues.length; i++) {\n cue = cues[i];\n\n // Compute the intial position and styles of the cue div.\n styleBox = new CueStyleBox(window, cue, styleOptions);\n paddedOverlay.appendChild(styleBox.div);\n\n // Move the cue div to it's correct line position.\n moveBoxToLinePosition(window, styleBox, containerBox, boxPositions);\n\n // Remember the computed div so that we don't have to recompute it later\n // if we don't have too.\n cue.displayState = styleBox.div;\n\n boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox));\n }\n })();\n};\n\nWebVTT.Parser = function(window, vttjs, decoder) {\n if (!decoder) {\n decoder = vttjs;\n vttjs = {};\n }\n if (!vttjs) {\n vttjs = {};\n }\n\n this.window = window;\n this.vttjs = vttjs;\n this.state = \"INITIAL\";\n this.buffer = \"\";\n this.decoder = decoder || new TextDecoder(\"utf8\");\n this.regionList = [];\n};\n\nWebVTT.Parser.prototype = {\n // If the error is a ParsingError then report it to the consumer if\n // possible. If it's not a ParsingError then throw it like normal.\n reportOrThrowError: function(e) {\n if (e instanceof ParsingError) {\n this.onparsingerror && this.onparsingerror(e);\n } else {\n throw e;\n }\n },\n parse: function (data) {\n var self = this;\n\n // If there is no data then we won't decode it, but will just try to parse\n // whatever is in buffer already. This may occur in circumstances, for\n // example when flush() is called.\n if (data) {\n // Try to decode the data that we received.\n self.buffer += self.decoder.decode(data, {stream: true});\n }\n\n function collectNextLine() {\n var buffer = self.buffer;\n var pos = 0;\n while (pos < buffer.length && buffer[pos] !== '\\r' && buffer[pos] !== '\\n') {\n ++pos;\n }\n var line = buffer.substr(0, pos);\n // Advance the buffer early in case we fail below.\n if (buffer[pos] === '\\r') {\n ++pos;\n }\n if (buffer[pos] === '\\n') {\n ++pos;\n }\n self.buffer = buffer.substr(pos);\n return line;\n }\n\n // 3.4 WebVTT region and WebVTT region settings syntax\n function parseRegion(input) {\n var settings = new Settings();\n\n parseOptions(input, function (k, v) {\n switch (k) {\n case \"id\":\n settings.set(k, v);\n break;\n case \"width\":\n settings.percent(k, v);\n break;\n case \"lines\":\n settings.integer(k, v);\n break;\n case \"regionanchor\":\n case \"viewportanchor\":\n var xy = v.split(',');\n if (xy.length !== 2) {\n break;\n }\n // We have to make sure both x and y parse, so use a temporary\n // settings object here.\n var anchor = new Settings();\n anchor.percent(\"x\", xy[0]);\n anchor.percent(\"y\", xy[1]);\n if (!anchor.has(\"x\") || !anchor.has(\"y\")) {\n break;\n }\n settings.set(k + \"X\", anchor.get(\"x\"));\n settings.set(k + \"Y\", anchor.get(\"y\"));\n break;\n case \"scroll\":\n settings.alt(k, v, [\"up\"]);\n break;\n }\n }, /=/, /\\s/);\n\n // Create the region, using default values for any values that were not\n // specified.\n if (settings.has(\"id\")) {\n var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)();\n region.width = settings.get(\"width\", 100);\n region.lines = settings.get(\"lines\", 3);\n region.regionAnchorX = settings.get(\"regionanchorX\", 0);\n region.regionAnchorY = settings.get(\"regionanchorY\", 100);\n region.viewportAnchorX = settings.get(\"viewportanchorX\", 0);\n region.viewportAnchorY = settings.get(\"viewportanchorY\", 100);\n region.scroll = settings.get(\"scroll\", \"\");\n // Register the region.\n self.onregion && self.onregion(region);\n // Remember the VTTRegion for later in case we parse any VTTCues that\n // reference it.\n self.regionList.push({\n id: settings.get(\"id\"),\n region: region\n });\n }\n }\n\n // draft-pantos-http-live-streaming-20\n // https://tools.ietf.org/html/draft-pantos-http-live-streaming-20#section-3.5\n // 3.5 WebVTT\n function parseTimestampMap(input) {\n var settings = new Settings();\n\n parseOptions(input, function(k, v) {\n switch(k) {\n case \"MPEGT\":\n settings.integer(k + 'S', v);\n break;\n case \"LOCA\":\n settings.set(k + 'L', parseTimeStamp(v));\n break;\n }\n }, /[^\\d]:/, /,/);\n\n self.ontimestampmap && self.ontimestampmap({\n \"MPEGTS\": settings.get(\"MPEGTS\"),\n \"LOCAL\": settings.get(\"LOCAL\")\n });\n }\n\n // 3.2 WebVTT metadata header syntax\n function parseHeader(input) {\n if (input.match(/X-TIMESTAMP-MAP/)) {\n // This line contains HLS X-TIMESTAMP-MAP metadata\n parseOptions(input, function(k, v) {\n switch(k) {\n case \"X-TIMESTAMP-MAP\":\n parseTimestampMap(v);\n break;\n }\n }, /=/);\n } else {\n parseOptions(input, function (k, v) {\n switch (k) {\n case \"Region\":\n // 3.3 WebVTT region metadata header syntax\n parseRegion(v);\n break;\n }\n }, /:/);\n }\n\n }\n\n // 5.1 WebVTT file parsing.\n try {\n var line;\n if (self.state === \"INITIAL\") {\n // We can't start parsing until we have the first line.\n if (!/\\r\\n|\\n/.test(self.buffer)) {\n return this;\n }\n\n line = collectNextLine();\n\n var m = line.match(/^WEBVTT([ \\t].*)?$/);\n if (!m || !m[0]) {\n throw new ParsingError(ParsingError.Errors.BadSignature);\n }\n\n self.state = \"HEADER\";\n }\n\n var alreadyCollectedLine = false;\n while (self.buffer) {\n // We can't parse a line until we have the full line.\n if (!/\\r\\n|\\n/.test(self.buffer)) {\n return this;\n }\n\n if (!alreadyCollectedLine) {\n line = collectNextLine();\n } else {\n alreadyCollectedLine = false;\n }\n\n switch (self.state) {\n case \"HEADER\":\n // 13-18 - Allow a header (metadata) under the WEBVTT line.\n if (/:/.test(line)) {\n parseHeader(line);\n } else if (!line) {\n // An empty line terminates the header and starts the body (cues).\n self.state = \"ID\";\n }\n continue;\n case \"NOTE\":\n // Ignore NOTE blocks.\n if (!line) {\n self.state = \"ID\";\n }\n continue;\n case \"ID\":\n // Check for the start of NOTE blocks.\n if (/^NOTE($|[ \\t])/.test(line)) {\n self.state = \"NOTE\";\n break;\n }\n // 19-29 - Allow any number of line terminators, then initialize new cue values.\n if (!line) {\n continue;\n }\n self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, \"\");\n // Safari still uses the old middle value and won't accept center\n try {\n self.cue.align = \"center\";\n } catch (e) {\n self.cue.align = \"middle\";\n }\n self.state = \"CUE\";\n // 30-39 - Check if self line contains an optional identifier or timing data.\n if (line.indexOf(\"-->\") === -1) {\n self.cue.id = line;\n continue;\n }\n // Process line as start of a cue.\n /*falls through*/\n case \"CUE\":\n // 40 - Collect cue timings and settings.\n try {\n parseCue(line, self.cue, self.regionList);\n } catch (e) {\n self.reportOrThrowError(e);\n // In case of an error ignore rest of the cue.\n self.cue = null;\n self.state = \"BADCUE\";\n continue;\n }\n self.state = \"CUETEXT\";\n continue;\n case \"CUETEXT\":\n var hasSubstring = line.indexOf(\"-->\") !== -1;\n // 34 - If we have an empty line then report the cue.\n // 35 - If we have the special substring '-->' then report the cue,\n // but do not collect the line as we need to process the current\n // one as a new cue.\n if (!line || hasSubstring && (alreadyCollectedLine = true)) {\n // We are done parsing self cue.\n self.oncue && self.oncue(self.cue);\n self.cue = null;\n self.state = \"ID\";\n continue;\n }\n if (self.cue.text) {\n self.cue.text += \"\\n\";\n }\n self.cue.text += line.replace(/\\u2028/g, '\\n').replace(/u2029/g, '\\n');\n continue;\n case \"BADCUE\": // BADCUE\n // 54-62 - Collect and discard the remaining cue.\n if (!line) {\n self.state = \"ID\";\n }\n continue;\n }\n }\n } catch (e) {\n self.reportOrThrowError(e);\n\n // If we are currently parsing a cue, report what we have.\n if (self.state === \"CUETEXT\" && self.cue && self.oncue) {\n self.oncue(self.cue);\n }\n self.cue = null;\n // Enter BADWEBVTT state if header was not parsed correctly otherwise\n // another exception occurred so enter BADCUE state.\n self.state = self.state === \"INITIAL\" ? \"BADWEBVTT\" : \"BADCUE\";\n }\n return this;\n },\n flush: function () {\n var self = this;\n try {\n // Finish decoding the stream.\n self.buffer += self.decoder.decode();\n // Synthesize the end of the current cue or region.\n if (self.cue || self.state === \"HEADER\") {\n self.buffer += \"\\n\\n\";\n self.parse();\n }\n // If we've flushed, parsed, and we're still on the INITIAL state then\n // that means we don't have enough of the stream to parse the first\n // line.\n if (self.state === \"INITIAL\") {\n throw new ParsingError(ParsingError.Errors.BadSignature);\n }\n } catch(e) {\n self.reportOrThrowError(e);\n }\n self.onflush && self.onflush();\n return this;\n }\n};\n\nmodule.exports = WebVTT;\n","/**\n * Copyright 2013 vtt.js Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Default exports for Node. Export the extended versions of VTTCue and\n// VTTRegion in Node since we likely want the capability to convert back and\n// forth between JSON. If we don't then it's not that big of a deal since we're\n// off browser.\n\nvar window = require('global/window');\n\nvar vttjs = module.exports = {\n WebVTT: require(\"./vtt.js\"),\n VTTCue: require(\"./vttcue.js\"),\n VTTRegion: require(\"./vttregion.js\")\n};\n\nwindow.vttjs = vttjs;\nwindow.WebVTT = vttjs.WebVTT;\n\nvar cueShim = vttjs.VTTCue;\nvar regionShim = vttjs.VTTRegion;\nvar nativeVTTCue = window.VTTCue;\nvar nativeVTTRegion = window.VTTRegion;\n\nvttjs.shim = function() {\n window.VTTCue = cueShim;\n window.VTTRegion = regionShim;\n};\n\nvttjs.restore = function() {\n window.VTTCue = nativeVTTCue;\n window.VTTRegion = nativeVTTRegion;\n};\n\nif (!window.VTTCue) {\n vttjs.shim();\n}\n","var MAX_UINT32 = Math.pow(2, 32);\n\nvar getUint64 = function(uint8) {\n var dv = new DataView(uint8.buffer, uint8.byteOffset, uint8.byteLength);\n var value;\n\n if (dv.getBigUint64) {\n value = dv.getBigUint64(0);\n\n if (value < Number.MAX_SAFE_INTEGER) {\n return Number(value);\n }\n\n return value;\n }\n\n return (dv.getUint32(0) * MAX_UINT32) + dv.getUint32(4);\n};\n\nmodule.exports = {\n getUint64: getUint64,\n MAX_UINT32: MAX_UINT32\n};\n","/**\n * Copyright 2013 vtt.js Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nvar scrollSetting = {\n \"\": true,\n \"up\": true\n};\n\nfunction findScrollSetting(value) {\n if (typeof value !== \"string\") {\n return false;\n }\n var scroll = scrollSetting[value.toLowerCase()];\n return scroll ? value.toLowerCase() : false;\n}\n\nfunction isValidPercentValue(value) {\n return typeof value === \"number\" && (value >= 0 && value <= 100);\n}\n\n// VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface\nfunction VTTRegion() {\n var _width = 100;\n var _lines = 3;\n var _regionAnchorX = 0;\n var _regionAnchorY = 100;\n var _viewportAnchorX = 0;\n var _viewportAnchorY = 100;\n var _scroll = \"\";\n\n Object.defineProperties(this, {\n \"width\": {\n enumerable: true,\n get: function() {\n return _width;\n },\n set: function(value) {\n if (!isValidPercentValue(value)) {\n throw new Error(\"Width must be between 0 and 100.\");\n }\n _width = value;\n }\n },\n \"lines\": {\n enumerable: true,\n get: function() {\n return _lines;\n },\n set: function(value) {\n if (typeof value !== \"number\") {\n throw new TypeError(\"Lines must be set to a number.\");\n }\n _lines = value;\n }\n },\n \"regionAnchorY\": {\n enumerable: true,\n get: function() {\n return _regionAnchorY;\n },\n set: function(value) {\n if (!isValidPercentValue(value)) {\n throw new Error(\"RegionAnchorX must be between 0 and 100.\");\n }\n _regionAnchorY = value;\n }\n },\n \"regionAnchorX\": {\n enumerable: true,\n get: function() {\n return _regionAnchorX;\n },\n set: function(value) {\n if(!isValidPercentValue(value)) {\n throw new Error(\"RegionAnchorY must be between 0 and 100.\");\n }\n _regionAnchorX = value;\n }\n },\n \"viewportAnchorY\": {\n enumerable: true,\n get: function() {\n return _viewportAnchorY;\n },\n set: function(value) {\n if (!isValidPercentValue(value)) {\n throw new Error(\"ViewportAnchorY must be between 0 and 100.\");\n }\n _viewportAnchorY = value;\n }\n },\n \"viewportAnchorX\": {\n enumerable: true,\n get: function() {\n return _viewportAnchorX;\n },\n set: function(value) {\n if (!isValidPercentValue(value)) {\n throw new Error(\"ViewportAnchorX must be between 0 and 100.\");\n }\n _viewportAnchorX = value;\n }\n },\n \"scroll\": {\n enumerable: true,\n get: function() {\n return _scroll;\n },\n set: function(value) {\n var setting = findScrollSetting(value);\n // Have to check for false as an empty string is a legal value.\n if (setting === false) {\n console.warn(\"Scroll: an invalid or illegal string was specified.\");\n } else {\n _scroll = setting;\n }\n }\n }\n });\n}\n\nmodule.exports = VTTRegion;\n","var topLevel = typeof global !== 'undefined' ? global :\n typeof window !== 'undefined' ? window : {}\nvar minDoc = require('min-document');\n\nvar doccy;\n\nif (typeof document !== 'undefined') {\n doccy = document;\n} else {\n doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'];\n\n if (!doccy) {\n doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc;\n }\n}\n\nmodule.exports = doccy;\n"],"sourceRoot":""}