From ca84a259354a67ab06c9158f01c6d9e39cc48b7b Mon Sep 17 00:00:00 2001 From: alex-phillips Date: Thu, 18 Feb 2016 16:18:46 -0500 Subject: [PATCH] added verbose (level configurable) logging --- README.md | 11 + bin/VPAIDFlash.swf | Bin 5080 -> 5090 bytes bin/es5-shim.js | 264 +--- bin/videojs.vast.vpaid.css | 5 +- bin/videojs.vast.vpaid.min.css | 2 +- bin/videojs.vast.vpaid.min.css.map | 2 +- bin/videojs_4.vast.vpaid.js | 1493 +++------------------- bin/videojs_4.vast.vpaid.min.js | 7 +- bin/videojs_4.vast.vpaid.min.js.map | 2 +- bin/videojs_5.vast.vpaid.js | 1493 +++------------------- bin/videojs_5.vast.vpaid.min.js | 7 +- bin/videojs_5.vast.vpaid.min.js.map | 2 +- src/scripts/ads/vast/Companion.js | 23 + src/scripts/ads/vast/VASTClient.js | 4 + src/scripts/ads/vast/VASTIntegrator.js | 10 + src/scripts/ads/vpaid/VPAIDFlashTech.js | 10 +- src/scripts/ads/vpaid/VPAIDHTML5Tech.js | 6 +- src/scripts/ads/vpaid/VPAIDIntegrator.js | 10 +- src/scripts/plugin/videojs.vast.vpaid.js | 19 +- src/scripts/utils/consoleLogger.js | 94 ++ 20 files changed, 548 insertions(+), 2916 deletions(-) create mode 100644 src/scripts/utils/consoleLogger.js diff --git a/README.md b/README.md index 23b1a588..1e84b061 100644 --- a/README.md +++ b/README.md @@ -203,6 +203,17 @@ Flag to enable resize of the adUnit on window's `resize` and `orientationchange` Path to the vpaidFlashloader swf file. ```Defaults to '/VPAIDFlash.swf'``` +#### verbosity +verbosity of console logging; +```Defaults to 0``` + +- 0 - error +- 1 - error, warn +- 2 - error, warn, info +- 3 - error, warn, info, log +- 4 - error, warn, info, log, debug + + --- ## Returned object diff --git a/bin/VPAIDFlash.swf b/bin/VPAIDFlash.swf index 3e86d1d988c8c375b1a005525ad4ddbe4625333a..773f65132dbc2ccc2a004c2e22938985f48dd20c 100644 GIT binary patch literal 5090 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 EMq_Wd8UO$Q literal 5080 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 diff --git a/bin/es5-shim.js b/bin/es5-shim.js index 9a346c34..6022eee8 100644 --- a/bin/es5-shim.js +++ b/bin/es5-shim.js @@ -328,7 +328,7 @@ var arraySliceApply = apply.bind(array_slice); var strSlice = call.bind(StringPrototype.slice); var strSplit = call.bind(StringPrototype.split); var strIndexOf = call.bind(StringPrototype.indexOf); -var pushCall = call.bind(array_push); +var push = call.bind(array_push); var isEnum = call.bind(ObjectPrototype.propertyIsEnumerable); var arraySort = call.bind(ArrayPrototype.sort); @@ -384,23 +384,18 @@ var properlyBoxesContext = function properlyBoxed(method) { // Check node 0.6.21 bug where third parameter is not boxed var properlyBoxesNonStrict = true; var properlyBoxesStrict = true; - var threwException = false; if (method) { - try { - method.call('foo', function (_, __, context) { - if (typeof context !== 'object') { properlyBoxesNonStrict = false; } - }); + method.call('foo', function (_, __, context) { + if (typeof context !== 'object') { properlyBoxesNonStrict = false; } + }); - method.call([1], function () { - 'use strict'; + method.call([1], function () { + 'use strict'; - properlyBoxesStrict = typeof this === 'string'; - }, 'x'); - } catch (e) { - threwException = true; - } + properlyBoxesStrict = typeof this === 'string'; + }, 'x'); } - return !!method && !threwException && properlyBoxesNonStrict && properlyBoxesStrict; + return !!method && properlyBoxesNonStrict && properlyBoxesStrict; }; defineProperties(ArrayPrototype, { @@ -489,7 +484,7 @@ defineProperties(ArrayPrototype, { if (i in self) { value = self[i]; if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) { - pushCall(result, value); + push(result, value); } } } @@ -744,7 +739,7 @@ defineProperties(ArrayPrototype, { if (arguments.length > 0 && typeof deleteCount !== 'number') { args = arraySlice(arguments); if (args.length < 2) { - pushCall(args, this.length - start); + push(args, this.length - start); } else { args[1] = ES.ToInteger(deleteCount); } @@ -1032,14 +1027,14 @@ defineProperties($Object, { var skipProto = hasProtoEnumBug && isFn; if ((isStr && hasStringEnumBug) || isArgs) { for (var i = 0; i < object.length; ++i) { - pushCall(theKeys, $String(i)); + push(theKeys, $String(i)); } } if (!isArgs) { for (var name in object) { if (!(skipProto && name === 'prototype') && owns(object, name)) { - pushCall(theKeys, $String(name)); + push(theKeys, $String(name)); } } } @@ -1049,7 +1044,7 @@ defineProperties($Object, { for (var j = 0; j < dontEnumsLength; j++) { var dontEnum = dontEnums[j]; if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) { - pushCall(theKeys, dontEnum); + push(theKeys, dontEnum); } } } @@ -1081,190 +1076,6 @@ defineProperties($Object, { // ==== // -var hasNegativeMonthYearBug = new Date(-3509827329600292).getUTCMonth() !== 0; -var aNegativeTestDate = new Date(-1509842289600292); -var aPositiveTestDate = new Date(1449662400000); -var hasToUTCStringFormatBug = aNegativeTestDate.toUTCString() !== 'Mon, 01 Jan -45875 11:59:59 GMT'; -var hasToDateStringFormatBug; -var hasToStringFormatBug; -var timeZoneOffset = aNegativeTestDate.getTimezoneOffset(); -if (timeZoneOffset < -720) { - hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Tue Jan 02 -45875'; - hasToStringFormatBug = !(/^Thu Dec 10 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString()); -} else { - hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Mon Jan 01 -45875'; - hasToStringFormatBug = !(/^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString()); -} - -var originalGetFullYear = call.bind(Date.prototype.getFullYear); -var originalGetMonth = call.bind(Date.prototype.getMonth); -var originalGetDate = call.bind(Date.prototype.getDate); -var originalGetUTCFullYear = call.bind(Date.prototype.getUTCFullYear); -var originalGetUTCMonth = call.bind(Date.prototype.getUTCMonth); -var originalGetUTCDate = call.bind(Date.prototype.getUTCDate); -var originalGetUTCDay = call.bind(Date.prototype.getUTCDay); -var originalGetUTCHours = call.bind(Date.prototype.getUTCHours); -var originalGetUTCMinutes = call.bind(Date.prototype.getUTCMinutes); -var originalGetUTCSeconds = call.bind(Date.prototype.getUTCSeconds); -var originalGetUTCMilliseconds = call.bind(Date.prototype.getUTCMilliseconds); -var dayName = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri']; -var monthName = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; -var daysInMonth = function daysInMonth(month, year) { - return originalGetDate(new Date(year, month, 0)); -}; - -defineProperties(Date.prototype, { - getFullYear: function getFullYear() { - if (!this || !(this instanceof Date)) { - throw new TypeError('this is not a Date object.'); - } - var year = originalGetFullYear(this); - if (year < 0 && originalGetMonth(this) > 11) { - return year + 1; - } - return year; - }, - getMonth: function getMonth() { - if (!this || !(this instanceof Date)) { - throw new TypeError('this is not a Date object.'); - } - var year = originalGetFullYear(this); - var month = originalGetMonth(this); - if (year < 0 && month > 11) { - return 0; - } - return month; - }, - getDate: function getDate() { - if (!this || !(this instanceof Date)) { - throw new TypeError('this is not a Date object.'); - } - var year = originalGetFullYear(this); - var month = originalGetMonth(this); - var date = originalGetDate(this); - if (year < 0 && month > 11) { - if (month === 12) { - return date; - } - var days = daysInMonth(0, year + 1); - return (days - date) + 1; - } - return date; - }, - getUTCFullYear: function getUTCFullYear() { - if (!this || !(this instanceof Date)) { - throw new TypeError('this is not a Date object.'); - } - var year = originalGetUTCFullYear(this); - if (year < 0 && originalGetUTCMonth(this) > 11) { - return year + 1; - } - return year; - }, - getUTCMonth: function getUTCMonth() { - if (!this || !(this instanceof Date)) { - throw new TypeError('this is not a Date object.'); - } - var year = originalGetUTCFullYear(this); - var month = originalGetUTCMonth(this); - if (year < 0 && month > 11) { - return 0; - } - return month; - }, - getUTCDate: function getUTCDate() { - if (!this || !(this instanceof Date)) { - throw new TypeError('this is not a Date object.'); - } - var year = originalGetUTCFullYear(this); - var month = originalGetUTCMonth(this); - var date = originalGetUTCDate(this); - if (year < 0 && month > 11) { - if (month === 12) { - return date; - } - var days = daysInMonth(0, year + 1); - return (days - date) + 1; - } - return date; - } -}, hasNegativeMonthYearBug); - -defineProperties(Date.prototype, { - toUTCString: function toUTCString() { - if (!this || !(this instanceof Date)) { - throw new TypeError('this is not a Date object.'); - } - var day = originalGetUTCDay(this); - var date = originalGetUTCDate(this); - var month = originalGetUTCMonth(this); - var year = originalGetUTCFullYear(this); - var hour = originalGetUTCHours(this); - var minute = originalGetUTCMinutes(this); - var second = originalGetUTCSeconds(this); - return dayName[day] + ', ' + - (date < 10 ? '0' + date : date) + ' ' + - monthName[month] + ' ' + - year + ' ' + - (hour < 10 ? '0' + hour : hour) + ':' + - (minute < 10 ? '0' + minute : minute) + ':' + - (second < 10 ? '0' + second : second) + ' GMT'; - } -}, hasNegativeMonthYearBug || hasToUTCStringFormatBug); - -// Opera 12 has `,` -defineProperties(Date.prototype, { - toDateString: function toDateString() { - if (!this || !(this instanceof Date)) { - throw new TypeError('this is not a Date object.'); - } - var day = this.getDay(); - var date = this.getDate(); - var month = this.getMonth(); - var year = this.getFullYear(); - return dayName[day] + ' ' + - monthName[month] + ' ' + - (date < 10 ? '0' + date : date) + ' ' + - year; - } -}, hasNegativeMonthYearBug || hasToDateStringFormatBug); - -// can't use defineProperties here because of toString enumeration issue in IE <= 8 -if (hasNegativeMonthYearBug || hasToStringFormatBug) { - Date.prototype.toString = function toString() { - if (!this || !(this instanceof Date)) { - throw new TypeError('this is not a Date object.'); - } - var day = this.getDay(); - var date = this.getDate(); - var month = this.getMonth(); - var year = this.getFullYear(); - var hour = this.getHours(); - var minute = this.getMinutes(); - var second = this.getSeconds(); - var timezoneOffset = this.getTimezoneOffset(); - var hoursOffset = Math.floor(Math.abs(timezoneOffset) / 60); - var minutesOffset = Math.floor(Math.abs(timezoneOffset) % 60); - return dayName[day] + ' ' + - monthName[month] + ' ' + - (date < 10 ? '0' + date : date) + ' ' + - year + ' ' + - (hour < 10 ? '0' + hour : hour) + ':' + - (minute < 10 ? '0' + minute : minute) + ':' + - (second < 10 ? '0' + second : second) + ' GMT' + - (timezoneOffset > 0 ? '-' : '+') + - (hoursOffset < 10 ? '0' + hoursOffset : hoursOffset) + - (minutesOffset < 10 ? '0' + minutesOffset : minutesOffset); - }; - if (supportsDescriptors) { - $Object.defineProperty(Date.prototype, 'toString', { - configurable: true, - enumerable: false, - writable: true - }); - } -} - // ES5 15.9.5.43 // http://es5.github.com/#x15.9.5.43 // This function returns a String value represent the instance in time @@ -1279,33 +1090,39 @@ var hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString( defineProperties(Date.prototype, { toISOString: function toISOString() { + var result, length, value, year, month; if (!isFinite(this)) { throw new RangeError('Date.prototype.toISOString called on non-finite value.'); } - var year = originalGetUTCFullYear(this); + year = this.getUTCFullYear(); - var month = originalGetUTCMonth(this); + month = this.getUTCMonth(); // see https://github.com/es-shims/es5-shim/issues/111 year += Math.floor(month / 12); month = (month % 12 + 12) % 12; // the date time string format is specified in 15.9.1.15. - var result = [month + 1, originalGetUTCDate(this), originalGetUTCHours(this), originalGetUTCMinutes(this), originalGetUTCSeconds(this)]; + result = [month + 1, this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()]; year = ( (year < 0 ? '-' : (year > 9999 ? '+' : '')) + strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6) ); - for (var i = 0; i < result.length; ++i) { - // pad months, days, hours, minutes, and seconds to have two digits. - result[i] = strSlice('00' + result[i], -2); + length = result.length; + while (length--) { + value = result[length]; + // pad months, days, hours, minutes, and seconds to have two + // digits. + if (value < 10) { + result[length] = '0' + value; + } } // pad milliseconds to have three digits. return ( year + '-' + arraySlice(result, 0, 2).join('-') + 'T' + arraySlice(result, 2).join(':') + '.' + - strSlice('000' + originalGetUTCMilliseconds(this), -3) + 'Z' + strSlice('000' + this.getUTCMilliseconds(), -3) + 'Z' ); } }, hasNegativeDateBug || hasSafari51DateBug); @@ -1783,7 +1600,7 @@ if ( // `separatorCopy.lastIndex` is not reliable cross-browser lastIndex = match.index + match[0].length; if (lastIndex > lastLastIndex) { - pushCall(output, strSlice(string, lastLastIndex, match.index)); + push(output, strSlice(string, lastLastIndex, match.index)); // Fix browsers whose `exec` methods don't consistently return `undefined` for // nonparticipating capturing groups if (!compliantExecNpcg && match.length > 1) { @@ -1813,12 +1630,12 @@ if ( } if (lastLastIndex === string.length) { if (lastLength || !separatorCopy.test('')) { - pushCall(output, ''); + push(output, ''); } } else { - pushCall(output, strSlice(string, lastLastIndex)); + push(output, strSlice(string, lastLastIndex)); } - return output.length > splitLimit ? arraySlice(output, 0, splitLimit) : output; + return output.length > splitLimit ? strSlice(output, 0, splitLimit) : output; }; }()); @@ -1839,7 +1656,7 @@ var str_replace = StringPrototype.replace; var replaceReportsGroupsCorrectly = (function () { var groups = []; 'x'.replace(/x(.)?/g, function (match, group) { - pushCall(groups, group); + push(groups, group); }); return groups.length === 1 && typeof groups[0] === 'undefined'; }()); @@ -1857,7 +1674,7 @@ if (!replaceReportsGroupsCorrectly) { searchValue.lastIndex = 0; var args = searchValue.exec(match) || []; searchValue.lastIndex = originalLastIndex; - pushCall(args, arguments[length - 2], arguments[length - 1]); + push(args, arguments[length - 2], arguments[length - 1]); return replaceValue.apply(this, args); }; return str_replace.call(this, searchValue, wrappedReplaceValue); @@ -1902,7 +1719,6 @@ defineProperties(StringPrototype, { return $String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, ''); } }, hasTrimWhitespaceBug); -var trim = call.bind(String.prototype.trim); var hasLastIndexBug = StringPrototype.lastIndexOf && 'abcあい'.lastIndexOf('あい', 2) !== -1; defineProperties(StringPrototype, { @@ -1943,25 +1759,13 @@ if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) { parseInt = (function (origParseInt) { var hexRegex = /^[\-+]?0[xX]/; return function parseInt(str, radix) { - var string = trim(str); + var string = $String(str).trim(); var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10); return origParseInt(string, defaultedRadix); }; }(parseInt)); } -// https://es5.github.io/#x15.1.2.3 -if (1 / parseFloat('-0') !== -Infinity) { - /* global parseFloat: true */ - parseFloat = (function (origParseFloat) { - return function parseFloat(string) { - var inputString = trim(string); - var result = origParseFloat(inputString); - return result === 0 && strSlice(inputString, 0, 1) === '-' ? -0 : result; - }; - }(parseFloat)); -} - if (String(new RangeError('test')) !== 'RangeError: test') { var errorToStringShim = function toString() { if (typeof this === 'undefined' || this === null) { diff --git a/bin/videojs.vast.vpaid.css b/bin/videojs.vast.vpaid.css index e1d59d19..5c8530d8 100644 --- a/bin/videojs.vast.vpaid.css +++ b/bin/videojs.vast.vpaid.css @@ -31,9 +31,6 @@ .vjs-has-started .vjs-black-poster.vjs-hidden { display: none; } -.vjs-using-native-controls .vjs-black-poster { - display: none; } - div.VPAID-container { position: absolute; top: 0; @@ -125,4 +122,4 @@ div.vast-skip-button { .vjs-ad-playing .vjs-live-controls { display: none; } -/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlkZW9qcy52YXN0LnZwYWlkLmNzcyIsInNvdXJjZXMiOlsidmlkZW9qcy52YXN0LnZwYWlkLnNjc3MiLCJhZHMtbGFiZWwuc2NzcyIsImJsYWNrLXBvc3Rlci5zY3NzIiwidmlkZW9qcy52cGFpZC5zY3NzIiwidmlkZW9qcy52YXN0LnNjc3MiXSwic291cmNlc0NvbnRlbnQiOlsiQGltcG9ydCBcImFkcy1sYWJlbFwiO1xuQGltcG9ydCBcImJsYWNrLXBvc3RlclwiO1xuQGltcG9ydCBcInZpZGVvanMudnBhaWRcIjtcbkBpbXBvcnQgXCJ2aWRlb2pzLnZhc3RcIjsiLCIudmpzLWxhYmVsLWhpZGRlbiB7XG4gIGRpc3BsYXk6IG5vbmUhaW1wb3J0YW50O1xufVxuXG4udmpzLWRlZmF1bHQtc2tpbiBkaXYudmpzLWFkcy1sYWJlbCB7XG4gIGZvbnQtc2l6ZTogMTNweDtcbiAgbGluZS1oZWlnaHQ6IDMwcHg7XG4gIGZvbnQtd2VpZ2h0OiBub3JtYWw7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgY29sb3I6IHdoaXRlO1xuICBkaXNwbGF5OiBub25lO1xuICB3aWR0aDogYXV0bztcbiAgcGFkZGluZy1sZWZ0OiAxMHB4O1xufVxuXG4udmpzLWFkLXBsYXlpbmcgLnZqcy1jb250cm9sLnZqcy1hZHMtbGFiZWwge1xuICBkaXNwbGF5OiBibG9jaztcbn1cbiIsIi52anMtYmxhY2stcG9zdGVyIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0b3A6IDA7XG4gIHJpZ2h0OiAwO1xuICBib3R0b206IDA7XG4gIGxlZnQ6IDA7XG4gIG1hcmdpbjogMDtcbiAgcGFkZGluZzogMDtcbiAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcbiAgYmFja2dyb3VuZC1wb3NpdGlvbjogNTAlIDUwJTtcbiAgYmFja2dyb3VuZC1zaXplOiBjb250YWluO1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGJhY2tncm91bmQtY29sb3I6ICMwMDA7XG59XG5cbi52anMtaGFzLXN0YXJ0ZWQgLnZqcy1ibGFjay1wb3N0ZXIudmpzLWhpZGRlbiB7XG4gIGRpc3BsYXk6IG5vbmU7XG59XG5cbi8vIGlmIHdlIHVzZSBuYXRpdmUgY29udHJvbHMgd2UgZG9uJ3QgbmVlZCBibGFjayBwb3N0ZXJcbi52anMtdXNpbmctbmF0aXZlLWNvbnRyb2xzIC52anMtYmxhY2stcG9zdGVyIHtcbiAgICBkaXNwbGF5OiBub25lO1xufVxuIiwiZGl2LlZQQUlELWNvbnRhaW5lcntcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0b3A6IDA7XG4gIGxlZnQ6IDA7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwMCU7XG59XG5cbmRpdi52anMtdnBhaWQtYWQgZGl2LnZqcy1wcm9ncmVzcy1jb250cm9sLFxuZGl2LnZqcy12cGFpZC1hZCBkaXYudmpzLXRpbWUtY29udHJvbHMsXG5kaXYudmpzLXZwYWlkLWFkIGRpdi52anMtdGltZS1kaXZpZGVyIHtcbiAgZGlzcGxheTogbm9uZTtcbn1cblxuZGl2LnZqcy12cGFpZC1hZC52anMtdnBhaWQtZmxhc2gtYWQgZGl2LlZQQUlELWNvbnRhaW5lciB7XG4gIGJhY2tncm91bmQtY29sb3I6ICMwMDAwMDA7XG59XG5cbmRpdi52anMtdnBhaWQtYWQgLnZqcy10ZWNoIHtcbiAgei1pbmRleDogMDtcbn1cbiIsIi8qKlxuICogdmlkZW9qcy5hZHMuY3NzXG4gKi9cblxuLyogQWQgcGxheWJhY2sgKi9cbi52anMtYWQtcGxheWluZyAudmpzLXByb2dyZXNzLWNvbnRyb2wge1xuICBwb2ludGVyLWV2ZW50czogbm9uZTtcbn1cblxuLnZqcy1hZC1wbGF5aW5nIC52anMtcGxheS1jb250cm9sLnZqcy1wYXVzZWQsXG4udmpzLWFkLXBsYXlpbmcgLnZqcy12b2x1bWUtbGV2ZWwsXG4udmpzLWFkLXBsYXlpbmcgLnZqcy1wbGF5LXByb2dyZXNzIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZTQwMCAhaW1wb3J0YW50O1xufVxuXG5kaXYudmFzdC1za2lwLWJ1dHRvbiB7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIGJvdHRvbTogMjAlO1xuICByaWdodDogMDtcbiAgYmFja2dyb3VuZC1jb2xvcjogIzAwMDtcbiAgY29sb3I6IHdoaXRlO1xuICBmb250LXNpemU6IDE1cHg7XG4gIGZvbnQtd2VpZ2h0OiBib2xkO1xuICB3aWR0aDogYXV0bztcbiAgcGFkZGluZzogOHB4O1xuICB6LWluZGV4OiAyO1xuICBib3JkZXI6IDFweCBzb2xpZCB3aGl0ZTtcbiAgYm9yZGVyLXJpZ2h0OiBub25lO1xufVxuXG4udmFzdC1za2lwLWJ1dHRvbi5lbmFibGVkIHtcbiAgY3Vyc29yOiBwb2ludGVyO1xuICBjb2xvcjogI2ZmZjtcbn1cblxuLnZhc3Qtc2tpcC1idXR0b24uZW5hYmxlZDpob3ZlciB7XG4gIGN1cnNvcjogcG9pbnRlcjtcbiAgYmFja2dyb3VuZDogIzMzMztcbn1cblxuLnZhc3QtYmxvY2tlciB7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIG1hcmdpbjogMDtcbiAgcGFkZGluZzogMDtcbiAgaGVpZ2h0OiAxMDAlO1xuICB3aWR0aDogMTAwJTtcbiAgdG9wOiAwO1xuICBsZWZ0OiAwO1xuICByaWdodDogMDtcbiAgYm90dG9tOiAwO1xufVxuXG4udmFzdC1za2lwLWJ1dHRvbi5lbmFibGVkOmFmdGVyIHtcbiAgY29udGVudDogXCI+PlwiO1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIHRvcDogMXB4O1xuICBtYXJnaW4tbGVmdDogOHB4O1xufVxuLyogQWQgbG9hZGluZyAqL1xuLnZqcy1hZC1wbGF5aW5nLnZqcy12YXN0LWFkLWxvYWRpbmcgLnZqcy1sb2FkaW5nLXNwaW5uZXIge1xuICBkaXNwbGF5OiBibG9jaztcbiAgei1pbmRleDogMTA7XG5cbiAgLyogb25seSBhbmltYXRlIHdoZW4gc2hvd2luZyBiZWNhdXNlIGl0IGNhbiBiZSBwcm9jZXNzb3IgaGVhdnkgKi9cbiAgLyogYW5pbWF0aW9uICovXG4gIC13ZWJraXQtYW5pbWF0aW9uOiBzcGluIDEuNXMgaW5maW5pdGUgbGluZWFyO1xuICAtbW96LWFuaW1hdGlvbjogc3BpbiAxLjVzIGluZmluaXRlIGxpbmVhcjtcbiAgLW8tYW5pbWF0aW9uOiBzcGluIDEuNXMgaW5maW5pdGUgbGluZWFyO1xuICBhbmltYXRpb246IHNwaW4gMS41cyBpbmZpbml0ZSBsaW5lYXI7XG59XG5cbi52anMtdmFzdC1hZC1sb2FkaW5nIGRpdi52anMtYmlnLXBsYXktYnV0dG9uIHtcbiAgZGlzcGxheTogbm9uZSFpbXBvcnRhbnQ7XG59XG5cbi52anMtYWQtcGxheWluZyAudmpzLXNsaWRlci1oYW5kbGU6YmVmb3Jle1xuICBkaXNwbGF5OiBub25lO1xufVxuXG4udmpzLWFkLXBsYXlpbmcgIC52anMtbGl2ZS1jb250cm9sc3tcbiAgZGlzcGxheTogbm9uZTtcbn0iXSwibWFwcGluZ3MiOiJBQ0FBLGlCQUFpQixDQUFDO0VBQ2hCLE9BQU8sRUFBRSxJQUFJLENBQUEsVUFBVSxHQUN4Qjs7QUFFRCxpQkFBaUIsQ0FBQyxHQUFHLEFBQUEsY0FBYyxDQUFDO0VBQ2xDLFNBQVMsRUFBRSxJQUFLO0VBQ2hCLFdBQVcsRUFBRSxJQUFLO0VBQ2xCLFdBQVcsRUFBRSxNQUFPO0VBQ3BCLFVBQVUsRUFBRSxNQUFPO0VBQ25CLEtBQUssRUFBRSxLQUFNO0VBQ2IsT0FBTyxFQUFFLElBQUs7RUFDZCxLQUFLLEVBQUUsSUFBSztFQUNaLFlBQVksRUFBRSxJQUFLLEdBQ3BCOztBQUVELGVBQWUsQ0FBQyxZQUFZLEFBQUEsY0FBYyxDQUFDO0VBQ3pDLE9BQU8sRUFBRSxLQUFNLEdBQ2hCOztBQ2pCRCxpQkFBaUIsQ0FBQztFQUNoQixRQUFRLEVBQUUsUUFBUztFQUNuQixHQUFHLEVBQUUsQ0FBRTtFQUNQLEtBQUssRUFBRSxDQUFFO0VBQ1QsTUFBTSxFQUFFLENBQUU7RUFDVixJQUFJLEVBQUUsQ0FBRTtFQUNSLE1BQU0sRUFBRSxDQUFFO0VBQ1YsT0FBTyxFQUFFLENBQUU7RUFDWCxpQkFBaUIsRUFBRSxTQUFVO0VBQzdCLG1CQUFtQixFQUFFLE9BQVE7RUFDN0IsZUFBZSxFQUFFLE9BQVE7RUFDekIsTUFBTSxFQUFFLE9BQVE7RUFDaEIsZ0JBQWdCLEVBQUUsSUFBSyxHQUN4Qjs7QUFFRCxnQkFBZ0IsQ0FBQyxpQkFBaUIsQUFBQSxXQUFXLENBQUM7RUFDNUMsT0FBTyxFQUFFLElBQUssR0FDZjs7QUFHRCwwQkFBMEIsQ0FBQyxpQkFBaUIsQ0FBQztFQUN6QyxPQUFPLEVBQUUsSUFBSyxHQUNqQjs7QUN0QkQsR0FBRyxBQUFBLGdCQUFnQixDQUFBO0VBQ2pCLFFBQVEsRUFBRSxRQUFTO0VBQ25CLEdBQUcsRUFBRSxDQUFFO0VBQ1AsSUFBSSxFQUFFLENBQUU7RUFDUixLQUFLLEVBQUUsSUFBSztFQUNaLE1BQU0sRUFBRSxJQUFLLEdBQ2Q7O0FBRUQsR0FBRyxBQUFBLGFBQWEsQ0FBQyxHQUFHLEFBQUEscUJBQXFCO0FBQ3pDLEdBQUcsQUFBQSxhQUFhLENBQUMsR0FBRyxBQUFBLGtCQUFrQjtBQUN0QyxHQUFHLEFBQUEsYUFBYSxDQUFDLEdBQUcsQUFBQSxpQkFBaUIsQ0FBQztFQUNwQyxPQUFPLEVBQUUsSUFBSyxHQUNmOztBQUVELEdBQUcsQUFBQSxhQUFhLEFBQUEsbUJBQW1CLENBQUMsR0FBRyxBQUFBLGdCQUFnQixDQUFDO0VBQ3RELGdCQUFnQixFQUFFLE9BQVEsR0FDM0I7O0FBRUQsR0FBRyxBQUFBLGFBQWEsQ0FBQyxTQUFTLENBQUM7RUFDekIsT0FBTyxFQUFFLENBQUUsR0FDWjs7QUNwQkQ7O0dBRUc7QUFFSCxpQkFBaUI7QUFDakIsZUFBZSxDQUFDLHFCQUFxQixDQUFDO0VBQ3BDLGNBQWMsRUFBRSxJQUFLLEdBQ3RCOztBQUVELGVBQWUsQ0FBQyxpQkFBaUIsQUFBQSxXQUFXO0FBQzVDLGVBQWUsQ0FBQyxpQkFBaUI7QUFDakMsZUFBZSxDQUFDLGtCQUFrQixDQUFDO0VBQ2pDLGdCQUFnQixFQUFFLGtCQUFtQixHQUN0Qzs7QUFFRCxHQUFHLEFBQUEsaUJBQWlCLENBQUM7RUFDbkIsT0FBTyxFQUFFLEtBQU07RUFDZixRQUFRLEVBQUUsUUFBUztFQUNuQixNQUFNLEVBQUUsR0FBSTtFQUNaLEtBQUssRUFBRSxDQUFFO0VBQ1QsZ0JBQWdCLEVBQUUsSUFBSztFQUN2QixLQUFLLEVBQUUsS0FBTTtFQUNiLFNBQVMsRUFBRSxJQUFLO0VBQ2hCLFdBQVcsRUFBRSxJQUFLO0VBQ2xCLEtBQUssRUFBRSxJQUFLO0VBQ1osT0FBTyxFQUFFLEdBQUk7RUFDYixPQUFPLEVBQUUsQ0FBRTtFQUNYLE1BQU0sRUFBRSxlQUFnQjtFQUN4QixZQUFZLEVBQUUsSUFBSyxHQUNwQjs7QUFFRCxpQkFBaUIsQUFBQSxRQUFRLENBQUM7RUFDeEIsTUFBTSxFQUFFLE9BQVE7RUFDaEIsS0FBSyxFQUFFLElBQUssR0FDYjs7QUFFRCxpQkFBaUIsQUFBQSxRQUFRLEFBQUEsTUFBTSxDQUFDO0VBQzlCLE1BQU0sRUFBRSxPQUFRO0VBQ2hCLFVBQVUsRUFBRSxJQUFLLEdBQ2xCOztBQUVELGFBQWEsQ0FBQztFQUNaLE9BQU8sRUFBRSxLQUFNO0VBQ2YsUUFBUSxFQUFFLFFBQVM7RUFDbkIsTUFBTSxFQUFFLENBQUU7RUFDVixPQUFPLEVBQUUsQ0FBRTtFQUNYLE1BQU0sRUFBRSxJQUFLO0VBQ2IsS0FBSyxFQUFFLElBQUs7RUFDWixHQUFHLEVBQUUsQ0FBRTtFQUNQLElBQUksRUFBRSxDQUFFO0VBQ1IsS0FBSyxFQUFFLENBQUU7RUFDVCxNQUFNLEVBQUUsQ0FBRSxHQUNYOztBQUVELGlCQUFpQixBQUFBLFFBQVEsQUFBQSxNQUFNLENBQUM7RUFDOUIsT0FBTyxFQUFFLElBQUs7RUFDZCxRQUFRLEVBQUUsUUFBUztFQUNuQixHQUFHLEVBQUUsR0FBSTtFQUNULFdBQVcsRUFBRSxHQUFJLEdBQ2xCOztBQUNELGdCQUFnQjtBQUNoQixlQUFlLEFBQUEsb0JBQW9CLENBQUMsb0JBQW9CLENBQUM7RUFDdkQsT0FBTyxFQUFFLEtBQU07RUFDZixPQUFPLEVBQUUsRUFBRztFQUVaLGlFQUFpRTtFQUNqRSxlQUFlO0VBQ2YsaUJBQWlCLEVBQUUseUJBQTBCO0VBQzdDLGNBQWMsRUFBRSx5QkFBMEI7RUFDMUMsWUFBWSxFQUFFLHlCQUEwQjtFQUN4QyxTQUFTLEVBQUUseUJBQTBCLEdBQ3RDOztBQUVELG9CQUFvQixDQUFDLEdBQUcsQUFBQSxvQkFBb0IsQ0FBQztFQUMzQyxPQUFPLEVBQUUsSUFBSSxDQUFBLFVBQVUsR0FDeEI7O0FBRUQsZUFBZSxDQUFDLGtCQUFrQixBQUFBLE9BQU8sQ0FBQTtFQUN2QyxPQUFPLEVBQUUsSUFBSyxHQUNmOztBQUVELGVBQWUsQ0FBRSxrQkFBa0IsQ0FBQTtFQUNqQyxPQUFPLEVBQUUsSUFBSyxHQUNmIiwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiL3NvdXJjZS8ifQ== */ +/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlkZW9qcy52YXN0LnZwYWlkLmNzcyIsInNvdXJjZXMiOlsidmlkZW9qcy52YXN0LnZwYWlkLnNjc3MiLCJhZHMtbGFiZWwuc2NzcyIsImJsYWNrLXBvc3Rlci5zY3NzIiwidmlkZW9qcy52cGFpZC5zY3NzIiwidmlkZW9qcy52YXN0LnNjc3MiXSwic291cmNlc0NvbnRlbnQiOlsiQGltcG9ydCBcImFkcy1sYWJlbFwiO1xuQGltcG9ydCBcImJsYWNrLXBvc3RlclwiO1xuQGltcG9ydCBcInZpZGVvanMudnBhaWRcIjtcbkBpbXBvcnQgXCJ2aWRlb2pzLnZhc3RcIjsiLCIudmpzLWxhYmVsLWhpZGRlbiB7XG4gIGRpc3BsYXk6IG5vbmUhaW1wb3J0YW50O1xufVxuXG4udmpzLWRlZmF1bHQtc2tpbiBkaXYudmpzLWFkcy1sYWJlbCB7XG4gIGZvbnQtc2l6ZTogMTNweDtcbiAgbGluZS1oZWlnaHQ6IDMwcHg7XG4gIGZvbnQtd2VpZ2h0OiBub3JtYWw7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgY29sb3I6IHdoaXRlO1xuICBkaXNwbGF5OiBub25lO1xuICB3aWR0aDogYXV0bztcbiAgcGFkZGluZy1sZWZ0OiAxMHB4O1xufVxuXG4udmpzLWFkLXBsYXlpbmcgLnZqcy1jb250cm9sLnZqcy1hZHMtbGFiZWwge1xuICBkaXNwbGF5OiBibG9jaztcbn1cbiIsIi52anMtYmxhY2stcG9zdGVyIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0b3A6IDA7XG4gIHJpZ2h0OiAwO1xuICBib3R0b206IDA7XG4gIGxlZnQ6IDA7XG4gIG1hcmdpbjogMDtcbiAgcGFkZGluZzogMDtcbiAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcbiAgYmFja2dyb3VuZC1wb3NpdGlvbjogNTAlIDUwJTtcbiAgYmFja2dyb3VuZC1zaXplOiBjb250YWluO1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGJhY2tncm91bmQtY29sb3I6ICMwMDA7XG59XG5cbi52anMtaGFzLXN0YXJ0ZWQgLnZqcy1ibGFjay1wb3N0ZXIudmpzLWhpZGRlbiB7XG4gIGRpc3BsYXk6IG5vbmU7XG59XG4iLCJkaXYuVlBBSUQtY29udGFpbmVye1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMDtcbiAgbGVmdDogMDtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogMTAwJTtcbn1cblxuZGl2LnZqcy12cGFpZC1hZCBkaXYudmpzLXByb2dyZXNzLWNvbnRyb2wsXG5kaXYudmpzLXZwYWlkLWFkIGRpdi52anMtdGltZS1jb250cm9scyxcbmRpdi52anMtdnBhaWQtYWQgZGl2LnZqcy10aW1lLWRpdmlkZXIge1xuICBkaXNwbGF5OiBub25lO1xufVxuXG5kaXYudmpzLXZwYWlkLWFkLnZqcy12cGFpZC1mbGFzaC1hZCBkaXYuVlBBSUQtY29udGFpbmVyIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogIzAwMDAwMDtcbn1cblxuZGl2LnZqcy12cGFpZC1hZCAudmpzLXRlY2gge1xuICB6LWluZGV4OiAwO1xufVxuIiwiLyoqXG4gKiB2aWRlb2pzLmFkcy5jc3NcbiAqL1xuXG4vKiBBZCBwbGF5YmFjayAqL1xuLnZqcy1hZC1wbGF5aW5nIC52anMtcHJvZ3Jlc3MtY29udHJvbCB7XG4gIHBvaW50ZXItZXZlbnRzOiBub25lO1xufVxuXG4udmpzLWFkLXBsYXlpbmcgLnZqcy1wbGF5LWNvbnRyb2wudmpzLXBhdXNlZCxcbi52anMtYWQtcGxheWluZyAudmpzLXZvbHVtZS1sZXZlbCxcbi52anMtYWQtcGxheWluZyAudmpzLXBsYXktcHJvZ3Jlc3Mge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZlNDAwICFpbXBvcnRhbnQ7XG59XG5cbmRpdi52YXN0LXNraXAtYnV0dG9uIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgYm90dG9tOiAyMCU7XG4gIHJpZ2h0OiAwO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwO1xuICBjb2xvcjogd2hpdGU7XG4gIGZvbnQtc2l6ZTogMTVweDtcbiAgZm9udC13ZWlnaHQ6IGJvbGQ7XG4gIHdpZHRoOiBhdXRvO1xuICBwYWRkaW5nOiA4cHg7XG4gIHotaW5kZXg6IDI7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHdoaXRlO1xuICBib3JkZXItcmlnaHQ6IG5vbmU7XG59XG5cbi52YXN0LXNraXAtYnV0dG9uLmVuYWJsZWQge1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGNvbG9yOiAjZmZmO1xufVxuXG4udmFzdC1za2lwLWJ1dHRvbi5lbmFibGVkOmhvdmVyIHtcbiAgY3Vyc29yOiBwb2ludGVyO1xuICBiYWNrZ3JvdW5kOiAjMzMzO1xufVxuXG4udmFzdC1ibG9ja2VyIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgbWFyZ2luOiAwO1xuICBwYWRkaW5nOiAwO1xuICBoZWlnaHQ6IDEwMCU7XG4gIHdpZHRoOiAxMDAlO1xuICB0b3A6IDA7XG4gIGxlZnQ6IDA7XG4gIHJpZ2h0OiAwO1xuICBib3R0b206IDA7XG59XG5cbi52YXN0LXNraXAtYnV0dG9uLmVuYWJsZWQ6YWZ0ZXIge1xuICBjb250ZW50OiBcIj4+XCI7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgdG9wOiAxcHg7XG4gIG1hcmdpbi1sZWZ0OiA4cHg7XG59XG4vKiBBZCBsb2FkaW5nICovXG4udmpzLWFkLXBsYXlpbmcudmpzLXZhc3QtYWQtbG9hZGluZyAudmpzLWxvYWRpbmctc3Bpbm5lciB7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICB6LWluZGV4OiAxMDtcblxuICAvKiBvbmx5IGFuaW1hdGUgd2hlbiBzaG93aW5nIGJlY2F1c2UgaXQgY2FuIGJlIHByb2Nlc3NvciBoZWF2eSAqL1xuICAvKiBhbmltYXRpb24gKi9cbiAgLXdlYmtpdC1hbmltYXRpb246IHNwaW4gMS41cyBpbmZpbml0ZSBsaW5lYXI7XG4gIC1tb3otYW5pbWF0aW9uOiBzcGluIDEuNXMgaW5maW5pdGUgbGluZWFyO1xuICAtby1hbmltYXRpb246IHNwaW4gMS41cyBpbmZpbml0ZSBsaW5lYXI7XG4gIGFuaW1hdGlvbjogc3BpbiAxLjVzIGluZmluaXRlIGxpbmVhcjtcbn1cblxuLnZqcy12YXN0LWFkLWxvYWRpbmcgZGl2LnZqcy1iaWctcGxheS1idXR0b24ge1xuICBkaXNwbGF5OiBub25lIWltcG9ydGFudDtcbn1cblxuLnZqcy1hZC1wbGF5aW5nIC52anMtc2xpZGVyLWhhbmRsZTpiZWZvcmV7XG4gIGRpc3BsYXk6IG5vbmU7XG59XG5cbi52anMtYWQtcGxheWluZyAgLnZqcy1saXZlLWNvbnRyb2xze1xuICBkaXNwbGF5OiBub25lO1xufSJdLCJtYXBwaW5ncyI6IkFDQUEsaUJBQWlCLENBQUM7RUFDaEIsT0FBTyxFQUFFLElBQUksQ0FBQSxVQUFVLEdBQ3hCOztBQUVELGlCQUFpQixDQUFDLEdBQUcsQUFBQSxjQUFjLENBQUM7RUFDbEMsU0FBUyxFQUFFLElBQUs7RUFDaEIsV0FBVyxFQUFFLElBQUs7RUFDbEIsV0FBVyxFQUFFLE1BQU87RUFDcEIsVUFBVSxFQUFFLE1BQU87RUFDbkIsS0FBSyxFQUFFLEtBQU07RUFDYixPQUFPLEVBQUUsSUFBSztFQUNkLEtBQUssRUFBRSxJQUFLO0VBQ1osWUFBWSxFQUFFLElBQUssR0FDcEI7O0FBRUQsZUFBZSxDQUFDLFlBQVksQUFBQSxjQUFjLENBQUM7RUFDekMsT0FBTyxFQUFFLEtBQU0sR0FDaEI7O0FDakJELGlCQUFpQixDQUFDO0VBQ2hCLFFBQVEsRUFBRSxRQUFTO0VBQ25CLEdBQUcsRUFBRSxDQUFFO0VBQ1AsS0FBSyxFQUFFLENBQUU7RUFDVCxNQUFNLEVBQUUsQ0FBRTtFQUNWLElBQUksRUFBRSxDQUFFO0VBQ1IsTUFBTSxFQUFFLENBQUU7RUFDVixPQUFPLEVBQUUsQ0FBRTtFQUNYLGlCQUFpQixFQUFFLFNBQVU7RUFDN0IsbUJBQW1CLEVBQUUsT0FBUTtFQUM3QixlQUFlLEVBQUUsT0FBUTtFQUN6QixNQUFNLEVBQUUsT0FBUTtFQUNoQixnQkFBZ0IsRUFBRSxJQUFLLEdBQ3hCOztBQUVELGdCQUFn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 */ diff --git a/bin/videojs.vast.vpaid.min.css b/bin/videojs.vast.vpaid.min.css index 6005345b..8d3e48b5 100644 --- a/bin/videojs.vast.vpaid.min.css +++ b/bin/videojs.vast.vpaid.min.css @@ -1,2 +1,2 @@ -.vjs-label-hidden{display:none!important}.vjs-default-skin div.vjs-ads-label{font-size:13px;line-height:30px;font-weight:400;text-align:center;color:#fff;display:none;width:auto;padding-left:10px}.vjs-ad-playing .vjs-control.vjs-ads-label{display:block}.vjs-black-poster{position:absolute;top:0;right:0;bottom:0;left:0;margin:0;padding:0;background-repeat:no-repeat;background-position:50% 50%;background-size:contain;cursor:pointer;background-color:#000}.vjs-has-started .vjs-black-poster.vjs-hidden,.vjs-using-native-controls .vjs-black-poster{display:none}div.VPAID-container{position:absolute;top:0;left:0;width:100%;height:100%}div.vjs-vpaid-ad div.vjs-progress-control,div.vjs-vpaid-ad div.vjs-time-controls,div.vjs-vpaid-ad div.vjs-time-divider{display:none}div.vjs-vpaid-ad.vjs-vpaid-flash-ad div.VPAID-container{background-color:#000}div.vjs-vpaid-ad .vjs-tech{z-index:0}.vjs-ad-playing .vjs-progress-control{pointer-events:none}.vjs-ad-playing .vjs-play-control.vjs-paused,.vjs-ad-playing .vjs-play-progress,.vjs-ad-playing .vjs-volume-level{background-color:#ffe400!important}div.vast-skip-button{display:block;position:absolute;bottom:20%;right:0;background-color:#000;color:#fff;font-size:15px;font-weight:700;width:auto;padding:8px;z-index:1;border:1px solid #fff;border-right:none}.vast-skip-button.enabled{cursor:pointer;color:#fff}.vast-skip-button.enabled:hover{cursor:pointer;background:#333}.vast-blocker{display:block;position:absolute;margin:0;padding:0;height:100%;width:100%;top:0;left:0;right:0;bottom:0}.vast-skip-button.enabled:after{content:">>";position:relative;top:1px;margin-left:8px}.vjs-ad-playing.vjs-vast-ad-loading .vjs-loading-spinner{display:block;z-index:2;-webkit-animation:spin 1.5s infinite linear;animation:spin 1.5s infinite linear}.vjs-vast-ad-loading div.vjs-big-play-button{display:none!important}.vjs-ad-playing .vjs-live-controls,.vjs-ad-playing .vjs-slider-handle:before{display:none} +.vjs-label-hidden{display:none!important}.vjs-default-skin div.vjs-ads-label{font-size:13px;line-height:30px;font-weight:400;text-align:center;color:#fff;display:none;width:auto;padding-left:10px}.vjs-ad-playing .vjs-control.vjs-ads-label{display:block}.vjs-black-poster{position:absolute;top:0;right:0;bottom:0;left:0;margin:0;padding:0;background-repeat:no-repeat;background-position:50% 50%;background-size:contain;cursor:pointer;background-color:#000}.vjs-has-started .vjs-black-poster.vjs-hidden{display:none}div.VPAID-container{position:absolute;top:0;left:0;width:100%;height:100%}div.vjs-vpaid-ad div.vjs-progress-control,div.vjs-vpaid-ad div.vjs-time-controls,div.vjs-vpaid-ad div.vjs-time-divider{display:none}div.vjs-vpaid-ad.vjs-vpaid-flash-ad div.VPAID-container{background-color:#000}div.vjs-vpaid-ad .vjs-tech{z-index:0}.vjs-ad-playing .vjs-progress-control{pointer-events:none}.vjs-ad-playing .vjs-play-control.vjs-paused,.vjs-ad-playing .vjs-play-progress,.vjs-ad-playing .vjs-volume-level{background-color:#ffe400!important}div.vast-skip-button{display:block;position:absolute;bottom:20%;right:0;background-color:#000;color:#fff;font-size:15px;font-weight:700;width:auto;padding:8px;z-index:1;border:1px solid #fff;border-right:none}.vast-skip-button.enabled{cursor:pointer;color:#fff}.vast-skip-button.enabled:hover{cursor:pointer;background:#333}.vast-blocker{display:block;position:absolute;margin:0;padding:0;height:100%;width:100%;top:0;left:0;right:0;bottom:0}.vast-skip-button.enabled:after{content:">>";position:relative;top:1px;margin-left:8px}.vjs-ad-playing.vjs-vast-ad-loading .vjs-loading-spinner{display:block;z-index:2;-webkit-animation:spin 1.5s infinite linear;animation:spin 1.5s infinite linear}.vjs-vast-ad-loading div.vjs-big-play-button{display:none!important}.vjs-ad-playing .vjs-live-controls,.vjs-ad-playing .vjs-slider-handle:before{display:none} /*# sourceMappingURL=videojs.vast.vpaid.min.css.map */ diff --git a/bin/videojs.vast.vpaid.min.css.map b/bin/videojs.vast.vpaid.min.css.map index db43a13a..480cf9fd 100644 --- a/bin/videojs.vast.vpaid.min.css.map +++ b/bin/videojs.vast.vpaid.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["/source/ads-label.scss","/source/black-poster.scss","/source/videojs.vpaid.scss","/source/videojs.vast.scss"],"names":[],"mappings":"AAAA,kBACE,sBAAuB,CACxB,AAED,oCACE,eAAgB,AAChB,iBAAkB,AAClB,gBAAoB,AACpB,kBAAmB,AACnB,WAAa,AACb,aAAc,AACd,WAAY,AACZ,iBAAmB,CACpB,AAED,2CACE,aAAe,CAChB,ACjBD,kBACE,kBAAmB,AACnB,MAAO,AACP,QAAS,AACT,SAAU,AACV,OAAQ,AACR,SAAU,AACV,UAAW,AACX,4BAA6B,AAC7B,4BAA6B,AAC7B,wBAAyB,AACzB,eAAgB,AAChB,qBAAuB,CACxB,AAOD,2FACI,YAAc,CACjB,ACtBD,oBACE,kBAAmB,AACnB,MAAO,AACP,OAAQ,AACR,WAAY,AACZ,WAAa,CACd,AAED,uHAGE,YAAc,CACf,AAED,wDACE,qBAA0B,CAC3B,AAED,2BACE,SAAW,CACZ,ACfD,sCACE,mBAAqB,CACtB,AAED,kHAGE,kCAAqC,CACtC,AAED,qBACE,cAAe,AACf,kBAAmB,AACnB,WAAY,AACZ,QAAS,AACT,sBAAuB,AACvB,WAAa,AACb,eAAgB,AAChB,gBAAkB,AAClB,WAAY,AACZ,YAAa,AACb,UAAW,AACX,sBAAwB,AACxB,iBAAmB,CACpB,AAED,0BACE,eAAgB,AAChB,UAAY,CACb,AAED,gCACE,eAAgB,AAChB,eAAiB,CAClB,AAED,cACE,cAAe,AACf,kBAAmB,AACnB,SAAU,AACV,UAAW,AACX,YAAa,AACb,WAAY,AACZ,MAAO,AACP,OAAQ,AACR,QAAS,AACT,QAAU,CACX,AAED,gCACE,aAAc,AACd,kBAAmB,AACnB,QAAS,AACT,eAAiB,CAClB,AAED,yDACE,cAAe,AACf,UAAY,AAIZ,4CAA6C,AAG7C,mCAAqC,CACtC,AAED,6CACE,sBAAuB,CACxB,AAMD,6EACE,YAAc,CACf","file":"videojs.vast.vpaid.min.css","sourcesContent":[".vjs-label-hidden {\n display: none!important;\n}\n\n.vjs-default-skin div.vjs-ads-label {\n font-size: 13px;\n line-height: 30px;\n font-weight: normal;\n text-align: center;\n color: white;\n display: none;\n width: auto;\n padding-left: 10px;\n}\n\n.vjs-ad-playing .vjs-control.vjs-ads-label {\n display: block;\n}\n",".vjs-black-poster {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n margin: 0;\n padding: 0;\n background-repeat: no-repeat;\n background-position: 50% 50%;\n background-size: contain;\n cursor: pointer;\n background-color: #000;\n}\n\n.vjs-has-started .vjs-black-poster.vjs-hidden {\n display: none;\n}\n\n// if we use native controls we don't need black poster\n.vjs-using-native-controls .vjs-black-poster {\n display: none;\n}\n","div.VPAID-container{\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n}\n\ndiv.vjs-vpaid-ad div.vjs-progress-control,\ndiv.vjs-vpaid-ad div.vjs-time-controls,\ndiv.vjs-vpaid-ad div.vjs-time-divider {\n display: none;\n}\n\ndiv.vjs-vpaid-ad.vjs-vpaid-flash-ad div.VPAID-container {\n background-color: #000000;\n}\n\ndiv.vjs-vpaid-ad .vjs-tech {\n z-index: 0;\n}\n","/**\n * videojs.ads.css\n */\n\n/* Ad playback */\n.vjs-ad-playing .vjs-progress-control {\n pointer-events: none;\n}\n\n.vjs-ad-playing .vjs-play-control.vjs-paused,\n.vjs-ad-playing .vjs-volume-level,\n.vjs-ad-playing .vjs-play-progress {\n background-color: #ffe400 !important;\n}\n\ndiv.vast-skip-button {\n display: block;\n position: absolute;\n bottom: 20%;\n right: 0;\n background-color: #000;\n color: white;\n font-size: 15px;\n font-weight: bold;\n width: auto;\n padding: 8px;\n z-index: 2;\n border: 1px solid white;\n border-right: none;\n}\n\n.vast-skip-button.enabled {\n cursor: pointer;\n color: #fff;\n}\n\n.vast-skip-button.enabled:hover {\n cursor: pointer;\n background: #333;\n}\n\n.vast-blocker {\n display: block;\n position: absolute;\n margin: 0;\n padding: 0;\n height: 100%;\n width: 100%;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n}\n\n.vast-skip-button.enabled:after {\n content: \">>\";\n position: relative;\n top: 1px;\n margin-left: 8px;\n}\n/* Ad loading */\n.vjs-ad-playing.vjs-vast-ad-loading .vjs-loading-spinner {\n display: block;\n z-index: 10;\n\n /* only animate when showing because it can be processor heavy */\n /* animation */\n -webkit-animation: spin 1.5s infinite linear;\n -moz-animation: spin 1.5s infinite linear;\n -o-animation: spin 1.5s infinite linear;\n animation: spin 1.5s infinite linear;\n}\n\n.vjs-vast-ad-loading div.vjs-big-play-button {\n display: none!important;\n}\n\n.vjs-ad-playing .vjs-slider-handle:before{\n display: none;\n}\n\n.vjs-ad-playing .vjs-live-controls{\n display: none;\n}"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["/source/ads-label.scss","/source/black-poster.scss","/source/videojs.vpaid.scss","/source/videojs.vast.scss"],"names":[],"mappings":"AAAA,kBACE,sBAAuB,CACxB,AAED,oCACE,eAAgB,AAChB,iBAAkB,AAClB,gBAAoB,AACpB,kBAAmB,AACnB,WAAa,AACb,aAAc,AACd,WAAY,AACZ,iBAAmB,CACpB,AAED,2CACE,aAAe,CAChB,ACjBD,kBACE,kBAAmB,AACnB,MAAO,AACP,QAAS,AACT,SAAU,AACV,OAAQ,AACR,SAAU,AACV,UAAW,AACX,4BAA6B,AAC7B,4BAA6B,AAC7B,wBAAyB,AACzB,eAAgB,AAChB,qBAAuB,CACxB,AAED,8CACE,YAAc,CACf,ACjBD,oBACE,kBAAmB,AACnB,MAAO,AACP,OAAQ,AACR,WAAY,AACZ,WAAa,CACd,AAED,uHAGE,YAAc,CACf,AAED,wDACE,qBAA0B,CAC3B,AAED,2BACE,SAAW,CACZ,ACfD,sCACE,mBAAqB,CACtB,AAED,kHAGE,kCAAqC,CACtC,AAED,qBACE,cAAe,AACf,kBAAmB,AACnB,WAAY,AACZ,QAAS,AACT,sBAAuB,AACvB,WAAa,AACb,eAAgB,AAChB,gBAAkB,AAClB,WAAY,AACZ,YAAa,AACb,UAAW,AACX,sBAAwB,AACxB,iBAAmB,CACpB,AAED,0BACE,eAAgB,AAChB,UAAY,CACb,AAED,gCACE,eAAgB,AAChB,eAAiB,CAClB,AAED,cACE,cAAe,AACf,kBAAmB,AACnB,SAAU,AACV,UAAW,AACX,YAAa,AACb,WAAY,AACZ,MAAO,AACP,OAAQ,AACR,QAAS,AACT,QAAU,CACX,AAED,gCACE,aAAc,AACd,kBAAmB,AACnB,QAAS,AACT,eAAiB,CAClB,AAED,yDACE,cAAe,AACf,UAAY,AAIZ,4CAA6C,AAG7C,mCAAqC,CACtC,AAED,6CACE,sBAAuB,CACxB,AAMD,6EACE,YAAc,CACf","file":"videojs.vast.vpaid.min.css","sourcesContent":[".vjs-label-hidden {\n display: none!important;\n}\n\n.vjs-default-skin div.vjs-ads-label {\n font-size: 13px;\n line-height: 30px;\n font-weight: normal;\n text-align: center;\n color: white;\n display: none;\n width: auto;\n padding-left: 10px;\n}\n\n.vjs-ad-playing .vjs-control.vjs-ads-label {\n display: block;\n}\n",".vjs-black-poster {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n margin: 0;\n padding: 0;\n background-repeat: no-repeat;\n background-position: 50% 50%;\n background-size: contain;\n cursor: pointer;\n background-color: #000;\n}\n\n.vjs-has-started .vjs-black-poster.vjs-hidden {\n display: none;\n}\n","div.VPAID-container{\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n}\n\ndiv.vjs-vpaid-ad div.vjs-progress-control,\ndiv.vjs-vpaid-ad div.vjs-time-controls,\ndiv.vjs-vpaid-ad div.vjs-time-divider {\n display: none;\n}\n\ndiv.vjs-vpaid-ad.vjs-vpaid-flash-ad div.VPAID-container {\n background-color: #000000;\n}\n\ndiv.vjs-vpaid-ad .vjs-tech {\n z-index: 0;\n}\n","/**\n * videojs.ads.css\n */\n\n/* Ad playback */\n.vjs-ad-playing .vjs-progress-control {\n pointer-events: none;\n}\n\n.vjs-ad-playing .vjs-play-control.vjs-paused,\n.vjs-ad-playing .vjs-volume-level,\n.vjs-ad-playing .vjs-play-progress {\n background-color: #ffe400 !important;\n}\n\ndiv.vast-skip-button {\n display: block;\n position: absolute;\n bottom: 20%;\n right: 0;\n background-color: #000;\n color: white;\n font-size: 15px;\n font-weight: bold;\n width: auto;\n padding: 8px;\n z-index: 2;\n border: 1px solid white;\n border-right: none;\n}\n\n.vast-skip-button.enabled {\n cursor: pointer;\n color: #fff;\n}\n\n.vast-skip-button.enabled:hover {\n cursor: pointer;\n background: #333;\n}\n\n.vast-blocker {\n display: block;\n position: absolute;\n margin: 0;\n padding: 0;\n height: 100%;\n width: 100%;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n}\n\n.vast-skip-button.enabled:after {\n content: \">>\";\n position: relative;\n top: 1px;\n margin-left: 8px;\n}\n/* Ad loading */\n.vjs-ad-playing.vjs-vast-ad-loading .vjs-loading-spinner {\n display: block;\n z-index: 10;\n\n /* only animate when showing because it can be processor heavy */\n /* animation */\n -webkit-animation: spin 1.5s infinite linear;\n -moz-animation: spin 1.5s infinite linear;\n -o-animation: spin 1.5s infinite linear;\n animation: spin 1.5s infinite linear;\n}\n\n.vjs-vast-ad-loading div.vjs-big-play-button {\n display: none!important;\n}\n\n.vjs-ad-playing .vjs-slider-handle:before{\n display: none;\n}\n\n.vjs-ad-playing .vjs-live-controls{\n display: none;\n}"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/bin/videojs_4.vast.vpaid.js b/bin/videojs_4.vast.vpaid.js index 30323753..62d272da 100644 --- a/bin/videojs_4.vast.vpaid.js +++ b/bin/videojs_4.vast.vpaid.js @@ -3,25 +3,13 @@ //simple representation of the API -var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); - } - }return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; - }; -}(); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); Object.defineProperty(exports, "__esModule", { value: true }); -function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -} +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var IVPAIDAdUnit = exports.IVPAIDAdUnit = function () { function IVPAIDAdUnit() { @@ -144,39 +132,17 @@ Object.defineProperty(IVPAIDAdUnit, 'EVENTS', { },{}],2:[function(require,module,exports){ 'use strict'; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; - -var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); - } - }return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; - }; -}(); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); Object.defineProperty(exports, "__esModule", { value: true }); -function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -} +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -function _possibleConstructorReturn(self, call) { - if (!self) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); - }return call && ((typeof call === "undefined" ? "undefined" : _typeof(call)) === "object" || typeof call === "function") ? call : self; -} +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } -function _inherits(subClass, superClass) { - if (typeof superClass !== "function" && superClass !== null) { - throw new TypeError("Super expression must either be null or a function, not " + (typeof superClass === "undefined" ? "undefined" : _typeof(superClass))); - }subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; -} +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var IVPAIDAdUnit = require('./IVPAIDAdUnit').IVPAIDAdUnit; var ALL_VPAID_METHODS = Object.getOwnPropertyNames(IVPAIDAdUnit.prototype).filter(function (property) { @@ -379,23 +345,9 @@ var VPAIDAdUnit = exports.VPAIDAdUnit = function (_IVPAIDAdUnit) { },{"./IVPAIDAdUnit":1}],3:[function(require,module,exports){ 'use strict'; -var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); - } - }return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; - }; -}(); - -function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -} +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -var swfobject = require('swfobject'); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var JSFlashBridge = require('./jsFlashBridge').JSFlashBridge; var VPAIDAdUnit = require('./VPAIDAdUnit').VPAIDAdUnit; @@ -405,15 +357,10 @@ var callbackTimeout = require('./utils').callbackTimeout; var isPositiveInt = require('./utils').isPositiveInt; var createElementWithID = require('./utils').createElementWithID; var uniqueVPAID = require('./utils').unique('vpaid'); -var createFlashTester = require('./flashTester.js').createFlashTester; var ERROR = 'error'; var FLASH_VERSION = '10.1.0'; -var flashTester = { isSupported: function isSupported() { - return true; - } }; // if the runFlashTest is not run the flashTester will always return true - var VPAIDFLASHClient = function () { function VPAIDFLASHClient(vpaidParentEl, callback) { var swfConfig = arguments.length <= 2 || arguments[2] === undefined ? { data: 'VPAIDFlash.swf', width: 800, height: 400 } : arguments[2]; @@ -425,7 +372,9 @@ var VPAIDFLASHClient = function () { _classCallCheck(this, VPAIDFLASHClient); - var me = this; + if (!VPAIDFLASHClient.hasExternalDependencies()) { + return onError('no swfobject in global scope. check: https://github.com/swfobject/swfobject or https://code.google.com/p/swfobject/'); + } this._vpaidParentEl = vpaidParentEl; this._flashID = uniqueVPAID(); @@ -435,7 +384,7 @@ var VPAIDFLASHClient = function () { swfConfig.width = isPositiveInt(swfConfig.width, 800); swfConfig.height = isPositiveInt(swfConfig.height, 400); - createElementWithID(vpaidParentEl, this._flashID, true); + createElementWithID(vpaidParentEl, this._flashID); params.movie = swfConfig.data; params.FlashVars = 'flashid=' + this._flashID + '&handler=' + JSFlashBridge.VPAID_FLASH_HANDLER + '&debug=' + vpaidOptions.debug + '&salign=' + params.salign; @@ -463,7 +412,7 @@ var VPAIDFLASHClient = function () { setTimeout(function () { callback(new Error(error)); }, 0); - return me; + return this; } } @@ -552,16 +501,16 @@ var VPAIDFLASHClient = function () { }(); setStaticProperty('isSupported', function () { - return swfobject.hasFlashPlayerVersion(FLASH_VERSION) && flashTester.isSupported(); -}, true); + return VPAIDFLASHClient.hasExternalDependencies() && swfobject.hasFlashPlayerVersion(FLASH_VERSION); +}); -setStaticProperty('runFlashTest', function (swfConfig) { - flashTester = createFlashTester(document.body, swfConfig); +setStaticProperty('hasExternalDependencies', function () { + return !!window.swfobject; }); function $throwIfDestroyed() { if (this._destroyed) { - throw new Error('VPAIDFlashToJS is destroyed!'); + throw new error('VPAIDFlashToJS is destroyed!'); } } @@ -573,125 +522,26 @@ function $loadPendedAdUnit() { } function setStaticProperty(propertyName, value) { - var writable = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2]; - Object.defineProperty(VPAIDFLASHClient, propertyName, { - writable: writable, + writable: false, configurable: false, value: value }); } -VPAIDFLASHClient.swfobject = swfobject; - +window.VPAIDFLASHClient = VPAIDFLASHClient; module.exports = VPAIDFLASHClient; -},{"./VPAIDAdUnit":2,"./flashTester.js":4,"./jsFlashBridge":5,"./utils":8,"swfobject":14}],4:[function(require,module,exports){ +},{"./VPAIDAdUnit":2,"./jsFlashBridge":4,"./utils":7}],4:[function(require,module,exports){ 'use strict'; -var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); - } - }return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; - }; -}(); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); Object.defineProperty(exports, "__esModule", { value: true }); -function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -} - -var swfobject = require('swfobject'); - -var FLASH_TEST = 'vpaid_video_flash_tester'; -var FLASH_TEST_EL = 'vpaid_video_flash_tester_el'; -var JSFlashBridge = require('./jsFlashBridge').JSFlashBridge; -var utils = require('./utils'); -var MultipleValuesRegistry = require('./registry').MultipleValuesRegistry; - -var FlashTester = function () { - function FlashTester(parent) { - var _this = this; - - var swfConfig = arguments.length <= 1 || arguments[1] === undefined ? { data: 'VPAIDFlash.swf', width: 800, height: 400 } : arguments[1]; - - _classCallCheck(this, FlashTester); - - this.parentEl = utils.createElementWithID(parent, FLASH_TEST_EL); // some browsers create global variables using the element id http://stackoverflow.com/questions/3434278/do-dom-tree-elements-with-ids-become-global-variables - utils.hideFlashEl(this.parentEl); - var params = {}; - params.movie = swfConfig.data; - params.FlashVars = 'flashid=' + FLASH_TEST_EL + '&handler=' + JSFlashBridge.VPAID_FLASH_HANDLER; - - this.el = swfobject.createSWF(swfConfig, params, FLASH_TEST_EL); - this._handlers = new MultipleValuesRegistry(); - this._isSupported = false; - if (this.el) { - utils.hideFlashEl(this.el); - this._flash = new JSFlashBridge(this.el, swfConfig.data, FLASH_TEST_EL, 400, 400, function () { - var support = true; - _this._isSupported = support; - _this._handlers.get('change').forEach(function (callback) { - setTimeout(function () { - callback('change', support); - }, 0); - }); - }); - } - } - - _createClass(FlashTester, [{ - key: 'isSupported', - value: function isSupported() { - return this._isSupported; - } - }, { - key: 'on', - value: function on(eventName, callback) { - this._handlers.add(eventName, callback); - } - }]); - - return FlashTester; -}(); - -var createFlashTester = exports.createFlashTester = function createFlashTester(el, swfConfig) { - if (!window[FLASH_TEST]) { - window[FLASH_TEST] = new FlashTester(el, swfConfig); - } - return window[FLASH_TEST]; -}; - -},{"./jsFlashBridge":5,"./registry":7,"./utils":8,"swfobject":14}],5:[function(require,module,exports){ -'use strict'; - -var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); - } - }return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; - }; -}(); - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -} +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var unique = require('./utils').unique; var isPositiveInt = require('./utils').isPositiveInt; @@ -940,7 +790,7 @@ window[VPAID_FLASH_HANDLER] = function (flashID, typeID, typeName, callbackID, e } }; -},{"./jsFlashBridgeRegistry":6,"./registry":7,"./utils":8}],6:[function(require,module,exports){ +},{"./jsFlashBridgeRegistry":5,"./registry":6,"./utils":7}],5:[function(require,module,exports){ 'use strict'; var SingleValueRegistry = require('./registry').SingleValueRegistry; @@ -973,28 +823,16 @@ Object.defineProperty(JSFlashBridgeRegistry, 'removeInstanceByID', { module.exports = JSFlashBridgeRegistry; -},{"./registry":7}],7:[function(require,module,exports){ +},{"./registry":6}],6:[function(require,module,exports){ 'use strict'; -var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); - } - }return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; - }; -}(); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); Object.defineProperty(exports, "__esModule", { value: true }); -function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -} +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var MultipleValuesRegistry = exports.MultipleValuesRegistry = function () { function MultipleValuesRegistry() { @@ -1149,7 +987,7 @@ var SingleValueRegistry = exports.SingleValueRegistry = function () { return SingleValueRegistry; }(); -},{}],8:[function(require,module,exports){ +},{}],7:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { @@ -1161,7 +999,6 @@ exports.callbackTimeout = callbackTimeout; exports.createElementWithID = createElementWithID; exports.isPositiveInt = isPositiveInt; exports.stringEndsWith = stringEndsWith; -exports.hideFlashEl = hideFlashEl; function unique(prefix) { var count = -1; return function (f) { @@ -1186,13 +1023,9 @@ function callbackTimeout(timer, onSuccess, onTimeout) { } function createElementWithID(parent, id) { - var cleanContent = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2]; - var nEl = document.createElement('div'); nEl.id = id; - if (cleanContent) { - parent.innerHTML = ''; - } + parent.innerHTML = ''; parent.appendChild(nEl); return nEl; } @@ -1218,16 +1051,7 @@ function stringEndsWith(string, search) { return endsWith.call(string, search); } -function hideFlashEl(el) { - // can't use display none or visibility none because will block flash in some browsers - el.style.position = 'absolute'; - el.style.left = '-1px'; - el.style.top = '-1px'; - el.style.width = '1px'; - el.style.height = '1px'; -} - -},{}],9:[function(require,module,exports){ +},{}],8:[function(require,module,exports){ 'use strict'; var METHODS = [ @@ -1514,7 +1338,7 @@ function addStaticToInterface(Interface, name, value) { } -},{}],10:[function(require,module,exports){ +},{}],9:[function(require,module,exports){ 'use strict'; var IVPAIDAdUnit = require('./IVPAIDAdUnit'); @@ -1745,23 +1569,17 @@ function callOrTriggerEvent(callback, subscribers, error, result) { module.exports = VPAIDAdUnit; -},{"./IVPAIDAdUnit":9,"./subscriber":12,"./utils":13}],11:[function(require,module,exports){ +},{"./IVPAIDAdUnit":8,"./subscriber":11,"./utils":12}],10:[function(require,module,exports){ 'use strict'; var utils = require('./utils'); var unique = utils.unique('vpaidIframe'); var VPAIDAdUnit = require('./VPAIDAdUnit'); -var defaultTemplate = '' + - '' + - '' + - '
' + - '' + - '' + - '' + - ''; +var defaultTemplate = ''; +defaultTemplate += '
'; var AD_STOPPED = 'AdStopped'; @@ -1795,6 +1613,7 @@ function VPAIDHTML5Client(el, video, templateConfig, vpaidOptions) { template: templateConfig.template || defaultTemplate, extraOptions: templateConfig.extraOptions || {} }; + } /** @@ -1827,18 +1646,15 @@ VPAIDHTML5Client.prototype.isDestroyed = function isDestroyed() { VPAIDHTML5Client.prototype.loadAdUnit = function loadAdUnit(adURL, callback) { $throwIfDestroyed.call(this); $unloadPreviousAdUnit.call(this); - var that = this; var frame = utils.createIframeWithContent( this._frameContainer, this._templateConfig.template, utils.extend({ iframeURL_JS: adURL, - iframeID: this.getID(), - origin: getOrigin() + iframeID: this.getID() }, this._templateConfig.extraOptions) ); - this._frame = frame; this._onLoad = utils.callbackTimeout( @@ -1852,31 +1668,31 @@ VPAIDHTML5Client.prototype.loadAdUnit = function loadAdUnit(adURL, callback) { function onLoad (e) { /*jshint validthis: false */ //don't clear timeout - if (e.origin !== getOrigin()) return; + if (e.origin !== window.location.origin) return; var result = JSON.parse(e.data); //don't clear timeout - if (result.id !== that.getID()) return; + if (result.id !== this.getID()) return; var adUnit, error, createAd; - if (!that._frame.contentWindow) { + if (!this._frame.contentWindow) { error = 'the iframe is not anymore in the DOM tree'; } else { - createAd = that._frame.contentWindow.getVPAIDAd; + createAd = this._frame.contentWindow.getVPAIDAd; error = utils.validate(typeof createAd === 'function', 'the ad didn\'t return a function to create an ad'); } if (!error) { - var adEl = that._frame.contentWindow.document.querySelector('.ad-element'); - adUnit = new VPAIDAdUnit(createAd(), adEl, that._videoEl, that._frame); - adUnit.subscribe(AD_STOPPED, $adDestroyed.bind(that)); + var adEl = this._frame.contentWindow.document.querySelector('.ad-element'); + adUnit = new VPAIDAdUnit(createAd(), adEl, this._videoEl, this._frame); + adUnit.subscribe(AD_STOPPED, $adDestroyed.bind(this)); error = utils.validate(adUnit.isValidVPAIDAd(), 'the add is not fully complaint with VPAID specification'); } - that._adUnit = adUnit; - $destroyLoadListener.call(that); + this._adUnit = adUnit; + $destroyLoadListener.call(this); callback(error, error ? null : adUnit); //clear timeout @@ -1964,22 +1780,11 @@ function $throwIfDestroyed() { } } -function getOrigin() { - if( window.location.origin ) { - return window.location.origin; - } - else { - return window.location.protocol + "//" + - window.location.hostname + - (window.location.port ? ':' + window.location.port: ''); - } -} - module.exports = VPAIDHTML5Client; window.VPAIDHTML5Client = VPAIDHTML5Client; -},{"./VPAIDAdUnit":10,"./utils":13}],12:[function(require,module,exports){ +},{"./VPAIDAdUnit":9,"./utils":12}],11:[function(require,module,exports){ 'use strict'; function Subscriber() { @@ -1987,14 +1792,12 @@ function Subscriber() { } Subscriber.prototype.subscribe = function subscribe(handler, eventName, context) { - if (!this.isHandlerAttached(handler, eventName)) { - this.get(eventName).push({handler: handler, context: context, eventName: eventName}); - } + this.get(eventName).push({handler: handler, context: context}); }; Subscriber.prototype.unsubscribe = function unsubscribe(handler, eventName) { this._subscribers[eventName] = this.get(eventName).filter(function (subscriber) { - return handler !== subscriber.handler; + return handler === subscriber.handler; }); }; @@ -2004,12 +1807,9 @@ Subscriber.prototype.unsubscribeAll = function unsubscribeAll() { Subscriber.prototype.trigger = function(eventName, data) { var that = this; - var subscribers = this.get(eventName) - .concat(this.get('*')); - - subscribers.forEach(function (subscriber) { + that.get(eventName).forEach(function (subscriber) { setTimeout(function () { - if (that.isHandlerAttached(subscriber.handler, subscriber.eventName)) { + if (that.get(eventName)) { subscriber.handler.call(subscriber.context, data); } }, 0); @@ -2017,10 +1817,7 @@ Subscriber.prototype.trigger = function(eventName, data) { }; Subscriber.prototype.triggerSync = function(eventName, data) { - var subscribers = this.get(eventName) - .concat(this.get('*')); - - subscribers.forEach(function (subscriber) { + this.get(eventName).forEach(function (subscriber) { subscriber.handler.call(subscriber.context, data); }); }; @@ -2032,16 +1829,10 @@ Subscriber.prototype.get = function get(eventName) { return this._subscribers[eventName]; }; -Subscriber.prototype.isHandlerAttached = function isHandlerAttached(handler, eventName) { - return this.get(eventName).some(function(subscriber) { - return handler === subscriber.handler; - }) -}; - module.exports = Subscriber; -},{}],13:[function(require,module,exports){ +},{}],12:[function(require,module,exports){ 'use strict'; /** @@ -2125,7 +1916,7 @@ function createElementInEl(parent, tagName, id) { * @param {object} data */ function createIframeWithContent(parent, template, data) { - var iframe = createIframe(parent, null, data.zIndex); + var iframe = createIframe(parent); if (!setIframeContent(iframe, simpleTemplate(template, data))) return; return iframe; } @@ -2136,7 +1927,7 @@ function createIframeWithContent(parent, template, data) { * @param {HTMLElement} parent * @param {string} url */ -function createIframe(parent, url, zIndex) { +function createIframe(parent, url) { var nEl = document.createElement('iframe'); nEl.src = url || 'about:blank'; nEl.marginWidth = '0'; @@ -2150,11 +1941,6 @@ function createIframe(parent, url, zIndex) { nEl.style.margin = '0px'; nEl.style.padding = '0px'; nEl.style.border = 'none'; - - if(zIndex){ - nEl.style.zIndex = zIndex; - } - nEl.setAttribute('SCROLLING','NO'); parent.innerHTML = ''; parent.appendChild(nEl); @@ -2232,838 +2018,7 @@ module.exports = { }; -},{}],14:[function(require,module,exports){ -/*! SWFObject v2.3.20130521 - is released under the MIT License -*/ - -/* global ActiveXObject: false */ - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - // AMD - define(factory); - } else if (typeof module === 'object' && module.exports) { - // Node, CommonJS-like - module.exports = factory(); - } else { - // Browser globals (root is window) - root.swfobject = factory(); - } -}(this, function () { - - var UNDEF = "undefined", - OBJECT = "object", - SHOCKWAVE_FLASH = "Shockwave Flash", - SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash", - FLASH_MIME_TYPE = "application/x-shockwave-flash", - EXPRESS_INSTALL_ID = "SWFObjectExprInst", - ON_READY_STATE_CHANGE = "onreadystatechange", - - win = window, - doc = document, - nav = navigator, - - plugin = false, - domLoadFnArr = [], - regObjArr = [], - objIdArr = [], - listenersArr = [], - storedFbContent, - storedFbContentId, - storedCallbackFn, - storedCallbackObj, - isDomLoaded = false, - isExpressInstallActive = false, - dynamicStylesheet, - dynamicStylesheetMedia, - autoHideShow = true, - encodeURIEnabled = false, - - /* Centralized function for browser feature detection - - User agent string detection is only used when no good alternative is possible - - Is executed directly for optimal performance - */ - ua = function () { - var w3cdom = typeof doc.getElementById !== UNDEF && typeof doc.getElementsByTagName !== UNDEF && typeof doc.createElement !== UNDEF, - u = nav.userAgent.toLowerCase(), - p = nav.platform.toLowerCase(), - windows = p ? /win/.test(p) : /win/.test(u), - mac = p ? /mac/.test(p) : /mac/.test(u), - webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, // returns either the webkit version or false if not webkit - ie = nav.appName === "Microsoft Internet Explorer", - playerVersion = [0, 0, 0], - d = null; - if (typeof nav.plugins !== UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] === OBJECT) { - d = nav.plugins[SHOCKWAVE_FLASH].description; - // nav.mimeTypes["application/x-shockwave-flash"].enabledPlugin indicates whether plug-ins are enabled or disabled in Safari 3+ - if (d && (typeof nav.mimeTypes !== UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { - plugin = true; - ie = false; // cascaded feature detection for Internet Explorer - d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1"); - playerVersion[0] = toInt(d.replace(/^(.*)\..*$/, "$1")); - playerVersion[1] = toInt(d.replace(/^.*\.(.*)\s.*$/, "$1")); - playerVersion[2] = /[a-zA-Z]/.test(d) ? toInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1")) : 0; - } - } - else if (typeof win.ActiveXObject !== UNDEF) { - try { - var a = new ActiveXObject(SHOCKWAVE_FLASH_AX); - if (a) { // a will return null when ActiveX is disabled - d = a.GetVariable("$version"); - if (d) { - ie = true; // cascaded feature detection for Internet Explorer - d = d.split(" ")[1].split(","); - playerVersion = [toInt(d[0]), toInt(d[1]), toInt(d[2])]; - } - } - } - catch (e) {} - } - return {w3: w3cdom, pv: playerVersion, wk: webkit, ie: ie, win: windows, mac: mac}; - }(), - - /* Cross-browser onDomLoad - - Will fire an event as soon as the DOM of a web page is loaded - - Internet Explorer workaround based on Diego Perini's solution: http://javascript.nwbox.com/IEContentLoaded/ - - Regular onload serves as fallback - */ - onDomLoad = function () { - if (!ua.w3) { return; } - if ((typeof doc.readyState !== UNDEF && (doc.readyState === "complete" || doc.readyState === "interactive")) || (typeof doc.readyState === UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) { // function is fired after onload, e.g. when script is inserted dynamically - callDomLoadFunctions(); - } - if (!isDomLoaded) { - if (typeof doc.addEventListener !== UNDEF) { - doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false); - } - if (ua.ie) { - doc.attachEvent(ON_READY_STATE_CHANGE, function detach() { - if (doc.readyState === "complete") { - doc.detachEvent(ON_READY_STATE_CHANGE, detach); - callDomLoadFunctions(); - } - }); - if (win == top) { // if not inside an iframe - (function checkDomLoadedIE() { - if (isDomLoaded) { return; } - try { - doc.documentElement.doScroll("left"); - } - catch (e) { - setTimeout(checkDomLoadedIE, 0); - return; - } - callDomLoadFunctions(); - }()); - } - } - if (ua.wk) { - (function checkDomLoadedWK() { - if (isDomLoaded) { return; } - if (!/loaded|complete/.test(doc.readyState)) { - setTimeout(checkDomLoadedWK, 0); - return; - } - callDomLoadFunctions(); - }()); - } - } - }(); - - function callDomLoadFunctions() { - if (isDomLoaded || !document.getElementsByTagName("body")[0]) { return; } - try { // test if we can really add/remove elements to/from the DOM; we don't want to fire it too early - var t, span = createElement("span"); - span.style.display = "none"; //hide the span in case someone has styled spans via CSS - t = doc.getElementsByTagName("body")[0].appendChild(span); - t.parentNode.removeChild(t); - t = null; //clear the variables - span = null; - } - catch (e) { return; } - isDomLoaded = true; - var dl = domLoadFnArr.length; - for (var i = 0; i < dl; i++) { - domLoadFnArr[i](); - } - } - - function addDomLoadEvent(fn) { - if (isDomLoaded) { - fn(); - } - else { - domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+ - } - } - - /* Cross-browser onload - - Based on James Edwards' solution: http://brothercake.com/site/resources/scripts/onload/ - - Will fire an event as soon as a web page including all of its assets are loaded - */ - function addLoadEvent(fn) { - if (typeof win.addEventListener !== UNDEF) { - win.addEventListener("load", fn, false); - } - else if (typeof doc.addEventListener !== UNDEF) { - doc.addEventListener("load", fn, false); - } - else if (typeof win.attachEvent !== UNDEF) { - addListener(win, "onload", fn); - } - else if (typeof win.onload === "function") { - var fnOld = win.onload; - win.onload = function () { - fnOld(); - fn(); - }; - } - else { - win.onload = fn; - } - } - - /* Detect the Flash Player version for non-Internet Explorer browsers - - Detecting the plug-in version via the object element is more precise than using the plugins collection item's description: - a. Both release and build numbers can be detected - b. Avoid wrong descriptions by corrupt installers provided by Adobe - c. Avoid wrong descriptions by multiple Flash Player entries in the plugin Array, caused by incorrect browser imports - - Disadvantage of this method is that it depends on the availability of the DOM, while the plugins collection is immediately available - */ - function testPlayerVersion() { - var b = doc.getElementsByTagName("body")[0]; - var o = createElement(OBJECT); - o.setAttribute("style", "visibility: hidden;"); - o.setAttribute("type", FLASH_MIME_TYPE); - var t = b.appendChild(o); - if (t) { - var counter = 0; - (function checkGetVariable() { - if (typeof t.GetVariable !== UNDEF) { - try { - var d = t.GetVariable("$version"); - if (d) { - d = d.split(" ")[1].split(","); - ua.pv = [toInt(d[0]), toInt(d[1]), toInt(d[2])]; - } - } catch (e) { - //t.GetVariable("$version") is known to fail in Flash Player 8 on Firefox - //If this error is encountered, assume FP8 or lower. Time to upgrade. - ua.pv = [8, 0, 0]; - } - } - else if (counter < 10) { - counter++; - setTimeout(checkGetVariable, 10); - return; - } - b.removeChild(o); - t = null; - matchVersions(); - }()); - } - else { - matchVersions(); - } - } - - /* Perform Flash Player and SWF version matching; static publishing only - */ - function matchVersions() { - var rl = regObjArr.length; - if (rl > 0) { - for (var i = 0; i < rl; i++) { // for each registered object element - var id = regObjArr[i].id; - var cb = regObjArr[i].callbackFn; - var cbObj = {success: false, id: id}; - if (ua.pv[0] > 0) { - var obj = getElementById(id); - if (obj) { - if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { // Flash Player version >= published SWF version: Houston, we have a match! - setVisibility(id, true); - if (cb) { - cbObj.success = true; - cbObj.ref = getObjectById(id); - cbObj.id = id; - cb(cbObj); - } - } - else if (regObjArr[i].expressInstall && canExpressInstall()) { // show the Adobe Express Install dialog if set by the web page author and if supported - var att = {}; - att.data = regObjArr[i].expressInstall; - att.width = obj.getAttribute("width") || "0"; - att.height = obj.getAttribute("height") || "0"; - if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); } - if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); } - // parse HTML object param element's name-value pairs - var par = {}; - var p = obj.getElementsByTagName("param"); - var pl = p.length; - for (var j = 0; j < pl; j++) { - if (p[j].getAttribute("name").toLowerCase() !== "movie") { - par[p[j].getAttribute("name")] = p[j].getAttribute("value"); - } - } - showExpressInstall(att, par, id, cb); - } - else { // Flash Player and SWF version mismatch or an older Webkit engine that ignores the HTML object element's nested param elements: display fallback content instead of SWF - displayFbContent(obj); - if (cb) { cb(cbObj); } - } - } - } - else { // if no Flash Player is installed or the fp version cannot be detected we let the HTML object element do its job (either show a SWF or fallback content) - setVisibility(id, true); - if (cb) { - var o = getObjectById(id); // test whether there is an HTML object element or not - if (o && typeof o.SetVariable !== UNDEF) { - cbObj.success = true; - cbObj.ref = o; - cbObj.id = o.id; - } - cb(cbObj); - } - } - } - } - } - - /* Main function - - Will preferably execute onDomLoad, otherwise onload (as a fallback) - */ - domLoadFnArr[0] = function () { - if (plugin) { - testPlayerVersion(); - } - else { - matchVersions(); - } - }; - - function getObjectById(objectIdStr) { - var r = null, - o = getElementById(objectIdStr); - - if (o && o.nodeName.toUpperCase() === "OBJECT") { - //If targeted object is valid Flash file - if (typeof o.SetVariable !== UNDEF) { - r = o; - } else { - //If SetVariable is not working on targeted object but a nested object is - //available, assume classic nested object markup. Return nested object. - - //If SetVariable is not working on targeted object and there is no nested object, - //return the original object anyway. This is probably new simplified markup. - - r = o.getElementsByTagName(OBJECT)[0] || o; - } - } - - return r; - } - - /* Requirements for Adobe Express Install - - only one instance can be active at a time - - fp 6.0.65 or higher - - Win/Mac OS only - - no Webkit engines older than version 312 - */ - function canExpressInstall() { - return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312); - } - - /* Show the Adobe Express Install dialog - - Reference: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75 - */ - function showExpressInstall(att, par, replaceElemIdStr, callbackFn) { - - var obj = getElementById(replaceElemIdStr); - - //Ensure that replaceElemIdStr is really a string and not an element - replaceElemIdStr = getId(replaceElemIdStr); - - isExpressInstallActive = true; - storedCallbackFn = callbackFn || null; - storedCallbackObj = {success: false, id: replaceElemIdStr}; - - if (obj) { - if (obj.nodeName.toUpperCase() === "OBJECT") { // static publishing - storedFbContent = abstractFbContent(obj); - storedFbContentId = null; - } - else { // dynamic publishing - storedFbContent = obj; - storedFbContentId = replaceElemIdStr; - } - att.id = EXPRESS_INSTALL_ID; - if (typeof att.width === UNDEF || (!/%$/.test(att.width) && toInt(att.width) < 310)) { att.width = "310"; } - if (typeof att.height === UNDEF || (!/%$/.test(att.height) && toInt(att.height) < 137)) { att.height = "137"; } - var pt = ua.ie ? "ActiveX" : "PlugIn", - fv = "MMredirectURL=" + encodeURIComponent(win.location.toString().replace(/&/g, "%26")) + "&MMplayerType=" + pt + "&MMdoctitle=" + encodeURIComponent(doc.title.slice(0, 47) + " - Flash Player Installation"); - if (typeof par.flashvars !== UNDEF) { - par.flashvars += "&" + fv; - } - else { - par.flashvars = fv; - } - // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it, - // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work - if (ua.ie && obj.readyState != 4) { - var newObj = createElement("div"); - replaceElemIdStr += "SWFObjectNew"; - newObj.setAttribute("id", replaceElemIdStr); - obj.parentNode.insertBefore(newObj, obj); // insert placeholder div that will be replaced by the object element that loads expressinstall.swf - obj.style.display = "none"; - removeSWF(obj); //removeSWF accepts elements now - } - createSWF(att, par, replaceElemIdStr); - } - } - - /* Functions to abstract and display fallback content - */ - function displayFbContent(obj) { - if (ua.ie && obj.readyState != 4) { - // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it, - // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work - obj.style.display = "none"; - var el = createElement("div"); - obj.parentNode.insertBefore(el, obj); // insert placeholder div that will be replaced by the fallback content - el.parentNode.replaceChild(abstractFbContent(obj), el); - removeSWF(obj); //removeSWF accepts elements now - } - else { - obj.parentNode.replaceChild(abstractFbContent(obj), obj); - } - } - - function abstractFbContent(obj) { - var ac = createElement("div"); - if (ua.win && ua.ie) { - ac.innerHTML = obj.innerHTML; - } - else { - var nestedObj = obj.getElementsByTagName(OBJECT)[0]; - if (nestedObj) { - var c = nestedObj.childNodes; - if (c) { - var cl = c.length; - for (var i = 0; i < cl; i++) { - if (!(c[i].nodeType == 1 && c[i].nodeName === "PARAM") && !(c[i].nodeType == 8)) { - ac.appendChild(c[i].cloneNode(true)); - } - } - } - } - } - return ac; - } - - function createIeObject(url, paramStr) { - var div = createElement("div"); - div.innerHTML = "" + paramStr + ""; - return div.firstChild; - } - - /* Cross-browser dynamic SWF creation - */ - function createSWF(attObj, parObj, id) { - var r, el = getElementById(id); - id = getId(id); // ensure id is truly an ID and not an element - - if (ua.wk && ua.wk < 312) { return r; } - - if (el) { - var o = (ua.ie) ? createElement("div") : createElement(OBJECT), - attr, - attrLower, - param; - - if (typeof attObj.id === UNDEF) { // if no 'id' is defined for the object element, it will inherit the 'id' from the fallback content - attObj.id = id; - } - - //Add params - for (param in parObj) { - //filter out prototype additions from other potential libraries and IE specific param element - if (parObj.hasOwnProperty(param) && param.toLowerCase() !== "movie") { - createObjParam(o, param, parObj[param]); - } - } - - //Create IE object, complete with param nodes - if (ua.ie) { o = createIeObject(attObj.data, o.innerHTML); } - - //Add attributes to object - for (attr in attObj) { - if (attObj.hasOwnProperty(attr)) { // filter out prototype additions from other potential libraries - attrLower = attr.toLowerCase(); - - // 'class' is an ECMA4 reserved keyword - if (attrLower === "styleclass") { - o.setAttribute("class", attObj[attr]); - } else if (attrLower !== "classid" && attrLower !== "data") { - o.setAttribute(attr, attObj[attr]); - } - } - } - - if (ua.ie) { - objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on unload (dynamic publishing only) - } else { - o.setAttribute("type", FLASH_MIME_TYPE); - o.setAttribute("data", attObj.data); - } - - el.parentNode.replaceChild(o, el); - r = o; - } - - return r; - } - - function createObjParam(el, pName, pValue) { - var p = createElement("param"); - p.setAttribute("name", pName); - p.setAttribute("value", pValue); - el.appendChild(p); - } - - /* Cross-browser SWF removal - - Especially needed to safely and completely remove a SWF in Internet Explorer - */ - function removeSWF(id) { - var obj = getElementById(id); - if (obj && obj.nodeName.toUpperCase() === "OBJECT") { - if (ua.ie) { - obj.style.display = "none"; - (function removeSWFInIE() { - if (obj.readyState == 4) { - //This step prevents memory leaks in Internet Explorer - for (var i in obj) { - if (typeof obj[i] === "function") { - obj[i] = null; - } - } - obj.parentNode.removeChild(obj); - } else { - setTimeout(removeSWFInIE, 10); - } - }()); - } - else { - obj.parentNode.removeChild(obj); - } - } - } - - function isElement(id) { - return (id && id.nodeType && id.nodeType === 1); - } - - function getId(thing) { - return (isElement(thing)) ? thing.id : thing; - } - - /* Functions to optimize JavaScript compression - */ - function getElementById(id) { - - //Allow users to pass an element OR an element's ID - if (isElement(id)) { return id; } - - var el = null; - try { - el = doc.getElementById(id); - } - catch (e) {} - return el; - } - - function createElement(el) { - return doc.createElement(el); - } - - //To aid compression; replaces 14 instances of pareseInt with radix - function toInt(str) { - return parseInt(str, 10); - } - - /* Updated attachEvent function for Internet Explorer - - Stores attachEvent information in an Array, so on unload the detachEvent functions can be called to avoid memory leaks - */ - function addListener(target, eventType, fn) { - target.attachEvent(eventType, fn); - listenersArr[listenersArr.length] = [target, eventType, fn]; - } - - /* Flash Player and SWF content version matching - */ - function hasPlayerVersion(rv) { - rv += ""; //Coerce number to string, if needed. - var pv = ua.pv, v = rv.split("."); - v[0] = toInt(v[0]); - v[1] = toInt(v[1]) || 0; // supports short notation, e.g. "9" instead of "9.0.0" - v[2] = toInt(v[2]) || 0; - return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false; - } - - /* Cross-browser dynamic CSS creation - - Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php - */ - function createCSS(sel, decl, media, newStyle) { - var h = doc.getElementsByTagName("head")[0]; - if (!h) { return; } // to also support badly authored HTML pages that lack a head element - var m = (typeof media === "string") ? media : "screen"; - if (newStyle) { - dynamicStylesheet = null; - dynamicStylesheetMedia = null; - } - if (!dynamicStylesheet || dynamicStylesheetMedia != m) { - // create dynamic stylesheet + get a global reference to it - var s = createElement("style"); - s.setAttribute("type", "text/css"); - s.setAttribute("media", m); - dynamicStylesheet = h.appendChild(s); - if (ua.ie && typeof doc.styleSheets !== UNDEF && doc.styleSheets.length > 0) { - dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1]; - } - dynamicStylesheetMedia = m; - } - // add style rule - if (dynamicStylesheet) { - if (typeof dynamicStylesheet.addRule !== UNDEF) { - dynamicStylesheet.addRule(sel, decl); - } else if (typeof doc.createTextNode !== UNDEF) { - dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}")); - } - } - } - - function setVisibility(id, isVisible) { - if (!autoHideShow) { return; } - var v = isVisible ? "visible" : "hidden", - el = getElementById(id); - if (isDomLoaded && el) { - el.style.visibility = v; - } else if (typeof id === "string") { - createCSS("#" + id, "visibility:" + v); - } - } - - /* Filter to avoid XSS attacks - */ - function urlEncodeIfNecessary(s) { - var regex = /[\\\"<>\.;]/; - var hasBadChars = regex.exec(s) !== null; - return hasBadChars && typeof encodeURIComponent !== UNDEF ? encodeURIComponent(s) : s; - } - - /* Release memory to avoid memory leaks caused by closures, fix hanging audio/video threads and force open sockets/NetConnections to disconnect (Internet Explorer only) - */ - var cleanup = function () { - if (ua.ie) { - window.attachEvent("onunload", function () { - // remove listeners to avoid memory leaks - var ll = listenersArr.length; - for (var i = 0; i < ll; i++) { - listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]); - } - // cleanup dynamically embedded objects to fix audio/video threads and force open sockets and NetConnections to disconnect - var il = objIdArr.length; - for (var j = 0; j < il; j++) { - removeSWF(objIdArr[j]); - } - // cleanup library's main closures to avoid memory leaks - for (var k in ua) { - ua[k] = null; - } - ua = null; - for (var l in swfobject) { - swfobject[l] = null; - } - swfobject = null; - }); - } - }(); - - return { - /* Public API - - Reference: http://code.google.com/p/swfobject/wiki/documentation - */ - registerObject: function (objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) { - if (ua.w3 && objectIdStr && swfVersionStr) { - var regObj = {}; - regObj.id = objectIdStr; - regObj.swfVersion = swfVersionStr; - regObj.expressInstall = xiSwfUrlStr; - regObj.callbackFn = callbackFn; - regObjArr[regObjArr.length] = regObj; - setVisibility(objectIdStr, false); - } - else if (callbackFn) { - callbackFn({success: false, id: objectIdStr}); - } - }, - - getObjectById: function (objectIdStr) { - if (ua.w3) { - return getObjectById(objectIdStr); - } - }, - - embedSWF: function (swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) { - - var id = getId(replaceElemIdStr), - callbackObj = {success: false, id: id}; - - if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) { - setVisibility(id, false); - addDomLoadEvent(function () { - widthStr += ""; // auto-convert to string - heightStr += ""; - var att = {}; - if (attObj && typeof attObj === OBJECT) { - for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs - att[i] = attObj[i]; - } - } - att.data = swfUrlStr; - att.width = widthStr; - att.height = heightStr; - var par = {}; - if (parObj && typeof parObj === OBJECT) { - for (var j in parObj) { // copy object to avoid the use of references, because web authors often reuse parObj for multiple SWFs - par[j] = parObj[j]; - } - } - if (flashvarsObj && typeof flashvarsObj === OBJECT) { - for (var k in flashvarsObj) { // copy object to avoid the use of references, because web authors often reuse flashvarsObj for multiple SWFs - if (flashvarsObj.hasOwnProperty(k)) { - - var key = (encodeURIEnabled) ? encodeURIComponent(k) : k, - value = (encodeURIEnabled) ? encodeURIComponent(flashvarsObj[k]) : flashvarsObj[k]; - - if (typeof par.flashvars !== UNDEF) { - par.flashvars += "&" + key + "=" + value; - } - else { - par.flashvars = key + "=" + value; - } - - } - } - } - if (hasPlayerVersion(swfVersionStr)) { // create SWF - var obj = createSWF(att, par, replaceElemIdStr); - if (att.id == id) { - setVisibility(id, true); - } - callbackObj.success = true; - callbackObj.ref = obj; - callbackObj.id = obj.id; - } - else if (xiSwfUrlStr && canExpressInstall()) { // show Adobe Express Install - att.data = xiSwfUrlStr; - showExpressInstall(att, par, replaceElemIdStr, callbackFn); - return; - } - else { // show fallback content - setVisibility(id, true); - } - if (callbackFn) { callbackFn(callbackObj); } - }); - } - else if (callbackFn) { callbackFn(callbackObj); } - }, - - switchOffAutoHideShow: function () { - autoHideShow = false; - }, - - enableUriEncoding: function (bool) { - encodeURIEnabled = (typeof bool === UNDEF) ? true : bool; - }, - - ua: ua, - - getFlashPlayerVersion: function () { - return {major: ua.pv[0], minor: ua.pv[1], release: ua.pv[2]}; - }, - - hasFlashPlayerVersion: hasPlayerVersion, - - createSWF: function (attObj, parObj, replaceElemIdStr) { - if (ua.w3) { - return createSWF(attObj, parObj, replaceElemIdStr); - } - else { - return undefined; - } - }, - - showExpressInstall: function (att, par, replaceElemIdStr, callbackFn) { - if (ua.w3 && canExpressInstall()) { - showExpressInstall(att, par, replaceElemIdStr, callbackFn); - } - }, - - removeSWF: function (objElemIdStr) { - if (ua.w3) { - removeSWF(objElemIdStr); - } - }, - - createCSS: function (selStr, declStr, mediaStr, newStyleBoolean) { - if (ua.w3) { - createCSS(selStr, declStr, mediaStr, newStyleBoolean); - } - }, - - addDomLoadEvent: addDomLoadEvent, - - addLoadEvent: addLoadEvent, - - getQueryParamValue: function (param) { - var q = doc.location.search || doc.location.hash; - if (q) { - if (/\?/.test(q)) { q = q.split("?")[1]; } // strip question mark - if (!param) { - return urlEncodeIfNecessary(q); - } - var pairs = q.split("&"); - for (var i = 0; i < pairs.length; i++) { - if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) { - return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1))); - } - } - } - return ""; - }, - - // For internal usage only - expressInstallCallback: function () { - if (isExpressInstallActive) { - var obj = getElementById(EXPRESS_INSTALL_ID); - if (obj && storedFbContent) { - obj.parentNode.replaceChild(storedFbContent, obj); - if (storedFbContentId) { - setVisibility(storedFbContentId, true); - if (ua.ie) { storedFbContent.style.display = "block"; } - } - if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); } - } - isExpressInstallActive = false; - } - }, - - version: "2.3" - - }; -})); - -},{}],15:[function(require,module,exports){ +},{}],13:[function(require,module,exports){ 'use strict'; var InLine = require('./InLine'); @@ -3090,7 +2045,7 @@ Ad.prototype.initialize = function(adJTree) { }; module.exports = Ad; -},{"./InLine":18,"./Wrapper":28}],16:[function(require,module,exports){ +},{"./InLine":16,"./Wrapper":26}],14:[function(require,module,exports){ 'use strict'; var TrackingEvent = require('./TrackingEvent'); @@ -3153,7 +2108,7 @@ function Companion(companionJTree) { } module.exports = Companion; -},{"../../utils/utilityFunctions":45,"../../utils/xml":46,"./TrackingEvent":21}],17:[function(require,module,exports){ +},{"../../utils/utilityFunctions":43,"../../utils/xml":44,"./TrackingEvent":19}],15:[function(require,module,exports){ 'use strict'; var Linear = require('./Linear'); @@ -3177,46 +2132,20 @@ function Creative(creativeJTree) { if (creativeJTree.companionAds) { var companions = []; var companionAds = creativeJTree.companionAds && creativeJTree.companionAds.companion; - if (utilities.isDefined(companionAds)) { - companionAds = utilities.isArray(companionAds) ? companionAds : [companionAds]; - companionAds.forEach(function (companionData) { - companions.push(new Companion(companionData)); - }); - } + companionAds = utilities.isArray(companionAds) ? companionAds : [companionAds]; + companionAds.forEach(function (companionData) { + companions.push(new Companion(companionData)); + }); + this.companionAds = companions; } } -/** - * Returns true if the browser supports at the creative. - */ -Creative.prototype.isSupported = function(){ - if(this.linear) { - return this.linear.isSupported(); - } - - return true; -}; - -Creative.parseCreatives = function parseCreatives(creativesJTree) { - var creatives = []; - var creativesData; - if (utilities.isDefined(creativesJTree) && utilities.isDefined(creativesJTree.creative)) { - creativesData = utilities.isArray(creativesJTree.creative) ? creativesJTree.creative : [creativesJTree.creative]; - creativesData.forEach(function (creative) { - creatives.push(new Creative(creative)); - }); - } - return creatives; -}; - module.exports = Creative; - -},{"../../utils/utilityFunctions":45,"./Companion":16,"./Linear":19}],18:[function(require,module,exports){ +},{"../../utils/utilityFunctions":43,"./Companion":14,"./Linear":17}],16:[function(require,module,exports){ 'use strict'; var vastUtil = require('./vastUtil'); -var Creative = require('./Creative'); var utilities = require('../../utils/utilityFunctions'); var xml = require('../../utils/xml'); @@ -3230,7 +2159,7 @@ function InLine(inlineJTree) { this.adTitle = xml.keyValue(inlineJTree.adTitle); this.adSystem = xml.keyValue(inlineJTree.adSystem); this.impressions = vastUtil.parseImpressions(inlineJTree.impression); - this.creatives = Creative.parseCreatives(inlineJTree.creatives); + this.creatives = vastUtil.parseCreatives(inlineJTree.creatives); //Optional Fields this.description = xml.keyValue(inlineJTree.description); @@ -3258,28 +2187,8 @@ function InLine(inlineJTree) { } } - -/** - * Returns true if the browser supports all the creatives. - */ -InLine.prototype.isSupported = function(){ - var i,len; - - if(this.creatives.length === 0) { - return false; - } - - for(i = 0, len = this.creatives.length; i< len; i+=1){ - if(!this.creatives[i].isSupported()){ - return false; - } - } - return true; -}; - module.exports = InLine; - -},{"../../utils/utilityFunctions":45,"../../utils/xml":46,"./Creative":17,"./vastUtil":30}],19:[function(require,module,exports){ +},{"../../utils/utilityFunctions":43,"../../utils/xml":44,"./vastUtil":28}],17:[function(require,module,exports){ 'use strict'; var TrackingEvent = require('./TrackingEvent'); @@ -3342,26 +2251,11 @@ function Linear(linearJTree) { } } -/** - * Must return true if at least one of the MediaFiles' type is supported - */ -Linear.prototype.isSupported = function () { - var i, len; - for(i=0, len=this.mediaFiles.length; i 3 ) { - // Ignore ended event if the Ad time was not 'near' the end - // avoids issues where IOS controls could skip the Ad - return; - } - - player.off('ended', proceed); - player.off('vast.adsCancel', proceed); - player.off('vast.adSkip', proceed); - - //NOTE: if the ads get cancel we do nothing apart removing the listners + playerUtils.once(player, ['ended', 'vast.adsCancel', 'vast.adSkip'], function (evt) { if(evt.type === 'ended' || evt.type === 'vast.adSkip'){ callback(null, response); } - } + //NOTE: if the ads get cancel we do nothing + }); }); - player.play(); } }; @@ -4098,7 +2960,7 @@ VASTIntegrator.prototype._trackError = function trackError(error, response) { }; module.exports = VASTIntegrator; -},{"../../utils/async":40,"../../utils/dom":41,"../../utils/playerUtils":43,"../../utils/utilityFunctions":45,"./VASTError":23,"./VASTResponse":25,"./VASTTracker":26,"./vastUtil":30}],25:[function(require,module,exports){ +},{"../../utils/async":38,"../../utils/dom":39,"../../utils/playerUtils":41,"../../utils/utilityFunctions":43,"./VASTError":21,"./VASTResponse":23,"./VASTTracker":24,"./vastUtil":28}],23:[function(require,module,exports){ 'use strict'; var Ad = require('./Ad'); @@ -4282,7 +3144,7 @@ function appendToArray(array, items) { module.exports = VASTResponse; -},{"../../utils/utilityFunctions":45,"../../utils/xml":46,"./Ad":15,"./InLine":18,"./Linear":19,"./VideoClicks":27,"./Wrapper":28}],26:[function(require,module,exports){ +},{"../../utils/utilityFunctions":43,"../../utils/xml":44,"./Ad":13,"./InLine":16,"./Linear":17,"./VideoClicks":25,"./Wrapper":26}],24:[function(require,module,exports){ 'use strict'; var VASTError = require('./VASTError'); @@ -4503,7 +3365,7 @@ VASTTracker.prototype.trackClick = function trackClick() { module.exports = VASTTracker; -},{"../../utils/utilityFunctions":45,"./VASTError":23,"./VASTResponse":25,"./vastUtil":30}],27:[function(require,module,exports){ +},{"../../utils/utilityFunctions":43,"./VASTError":21,"./VASTResponse":23,"./vastUtil":28}],25:[function(require,module,exports){ 'use strict'; var utilities = require('../../utils/utilityFunctions'); @@ -4532,11 +3394,10 @@ function VideoClicks(videoClickJTree) { } module.exports = VideoClicks; -},{"../../utils/utilityFunctions":45,"../../utils/xml":46}],28:[function(require,module,exports){ +},{"../../utils/utilityFunctions":43,"../../utils/xml":44}],26:[function(require,module,exports){ 'use strict'; var vastUtil = require('./vastUtil'); -var Creative = require('./Creative'); var utilities = require('../../utils/utilityFunctions'); var xml = require('../../utils/xml'); @@ -4552,7 +3413,7 @@ function Wrapper(wrapperJTree) { this.VASTAdTagURI = xml.keyValue(wrapperJTree.vASTAdTagURI); //Optional elements - this.creatives = Creative.parseCreatives(wrapperJTree.creatives); + this.creatives = vastUtil.parseCreatives(wrapperJTree.creatives); this.error = xml.keyValue(wrapperJTree.error); this.extensions = wrapperJTree.extensions; @@ -4563,8 +3424,7 @@ function Wrapper(wrapperJTree) { } module.exports = Wrapper; - -},{"../../utils/utilityFunctions":45,"../../utils/xml":46,"./Creative":17,"./vastUtil":30}],29:[function(require,module,exports){ +},{"../../utils/utilityFunctions":43,"../../utils/xml":44,"./vastUtil":28}],27:[function(require,module,exports){ 'use strict'; var utilities = require('../../utils/utilityFunctions'); @@ -4628,13 +3488,11 @@ var parsers = { module.exports = parsers; -},{"../../utils/utilityFunctions":45}],30:[function(require,module,exports){ +},{"../../utils/utilityFunctions":43}],28:[function(require,module,exports){ 'use strict'; +var Creative = require('./Creative'); var utilities = require('../../utils/utilityFunctions'); -var VPAIDHTML5Tech = require('../vpaid/VPAIDHTML5Tech'); -var VPAIDFlashTech = require('../vpaid/VPAIDFlashTech'); -var VPAIDFLASHClient = require('VPAIDFLASHClient/js/VPAIDFLASHClient'); var vastUtil = { @@ -4725,6 +3583,17 @@ var vastUtil = { return []; }, + parseCreatives: function parseCreatives(creativesJTree) { + var creatives = []; + var creativesData; + if (utilities.isDefined(creativesJTree) && utilities.isDefined(creativesJTree.creative)) { + creativesData = utilities.isArray(creativesJTree.creative) ? creativesJTree.creative : [creativesJTree.creative]; + creativesData.forEach(function (creative) { + creatives.push(new Creative(creative)); + }); + } + return creatives; + }, //We assume that the progress is going to arrive in milliseconds formatProgress: function formatProgress(progress) { @@ -4739,8 +3608,8 @@ var vastUtil = { return utilities.toFixedDigits(hours, 2) + ':' + utilities.toFixedDigits(minutes, 2) + ':' + utilities.toFixedDigits(seconds, 2) + '.' + utilities.toFixedDigits(milliseconds, 3); }, - parseOffset: function parseOffset(offset, duration) { - if (isPercentage(offset)) { + parseOffset: function parseOffset(offset, duration) { + if(isPercentage(offset)){ return calculatePercentage(offset, duration); } return vastUtil.parseDuration(offset); @@ -4752,59 +3621,25 @@ var vastUtil = { } function calculatePercentage(percentStr, duration) { - if (duration) { + if(duration) { return calcPercent(duration, parseFloat(percentStr.replace('%', ''))); } return null; } - function calcPercent(quantity, percent) { + function calcPercent(quantity, percent){ return quantity * percent / 100; } }, - - //List of supported VPAID technologies - VPAID_techs: [ - VPAIDFlashTech, - VPAIDHTML5Tech - ], - isVPAID: function isVPAIDMediaFile(mediaFile) { return !!mediaFile && mediaFile.apiFramework === 'VPAID'; - }, - - findSupportedVPAIDTech: function findSupportedVPAIDTech(mimeType) { - var i, len, VPAIDTech; - - for (i = 0, len = this.VPAID_techs.length; i < len; i += 1) { - VPAIDTech = this.VPAID_techs[i]; - if (VPAIDTech.supports(mimeType)) { - return VPAIDTech; - } - } - return null; - }, - - isFlashSupported: function isFlashSupported() { - return VPAIDFLASHClient.isSupported(); - }, - - /** - * Necessary step for VPAIDFLAShClient to know if flash is supported and not blocked. - * IMPORTANT NOTE: This is an async test and needs to be run as soon as possible. - * - * @param vpaidFlashLoaderPath the path to the vpaidFlashLoader swf obj. - */ - runFlashSupportCheck: function runFlashSupportCheck(vpaidFlashLoaderPath) { - VPAIDFLASHClient.runFlashTest({data: vpaidFlashLoaderPath}); } - }; -module.exports = vastUtil; -},{"../../utils/utilityFunctions":45,"../vpaid/VPAIDFlashTech":32,"../vpaid/VPAIDHTML5Tech":33,"VPAIDFLASHClient/js/VPAIDFLASHClient":3}],31:[function(require,module,exports){ +module.exports = vastUtil; +},{"../../utils/utilityFunctions":43,"./Creative":15}],29:[function(require,module,exports){ 'use strict'; var VASTError = require('../vast/VASTError'); @@ -5027,7 +3862,7 @@ VPAIDAdUnitWrapper.prototype.setAdVolume = function(volume, cb){ module.exports = VPAIDAdUnitWrapper; -},{"../../utils/utilityFunctions":45,"../vast/VASTError":23}],32:[function(require,module,exports){ +},{"../../utils/utilityFunctions":43,"../vast/VASTError":21}],30:[function(require,module,exports){ 'use strict'; var VASTError = require('../vast/VASTError'); @@ -5108,8 +3943,7 @@ VPAIDFlashTech.prototype.unloadAdUnit = function () { }; module.exports = VPAIDFlashTech; - -},{"../../utils/dom":41,"../../utils/utilityFunctions":45,"../vast/VASTError":23,"VPAIDFLASHClient/js/VPAIDFLASHClient":3}],33:[function(require,module,exports){ +},{"../../utils/dom":39,"../../utils/utilityFunctions":43,"../vast/VASTError":21,"VPAIDFLASHClient/js/VPAIDFLASHClient":3}],31:[function(require,module,exports){ 'use strict'; var VASTError = require('../vast/VASTError'); @@ -5196,7 +4030,7 @@ VPAIDHTML5Tech.INVALID_DOM_VIDEO_EL = PREFIX + ', invalid HTMLVideoElement'; VPAIDHTML5Tech.MISSING_CALLBACK = PREFIX + ', missing valid callback'; module.exports = VPAIDHTML5Tech; -},{"../../utils/dom":41,"../../utils/utilityFunctions":45,"../vast/VASTError":23,"VPAIDHTML5Client/js/VPAIDHTML5Client":11}],34:[function(require,module,exports){ +},{"../../utils/dom":39,"../../utils/utilityFunctions":43,"../vast/VASTError":21,"VPAIDHTML5Client/js/VPAIDHTML5Client":10}],32:[function(require,module,exports){ 'use strict'; var VASTError = require('../vast/VASTError'); @@ -5205,6 +4039,8 @@ var VASTTracker = require('../vast/VASTTracker'); var vastUtil = require('../vast/vastUtil'); var VPAIDAdUnitWrapper = require('./VPAIDAdUnitWrapper'); +var VPAIDHTML5Tech = require('./VPAIDHTML5Tech'); +var VPAIDFlashTech = require('./VPAIDFlashTech'); var async = require('../../utils/async'); var dom = require('../../utils/dom'); @@ -5240,19 +4076,23 @@ function VPAIDIntegrator(player, settings) { } } -VPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) { - if (!(vastResponse instanceof VASTResponse)) { - return callback(new VASTError('on VASTIntegrator.playAd, missing required VASTResponse')); - } +//List of supported VPAID technologies +VPAIDIntegrator.techs = [ + VPAIDFlashTech, + VPAIDHTML5Tech +]; +VPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) { var that = this; + var tech; var player = this.player; - var tech = this._findSupportedTech(vastResponse, this.settings); callback = callback || utilities.noop; + if (!(vastResponse instanceof VASTResponse)) { + return callback(new VASTError('on VASTIntegrator.playAd, missing required VASTResponse')); + } - this._adUnit = null; - + tech = this._findSupportedTech(vastResponse, this.settings); dom.addClass(player.el(), 'vjs-vpaid-ad'); player.on('vast.adsCancel', triggerVpaidAdEnd); @@ -5270,7 +4110,13 @@ VPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) this._playAdUnit.bind(this), this._finishPlaying.bind(this) - ], adComplete); + ], function (error, adUnit, vastResponse) { + if (error) { + that._trackError(vastResponse); + } + player.trigger('vpaid.adEnd'); + callback(error, vastResponse); + }); this._adUnit = { _paused: true, @@ -5290,22 +4136,13 @@ VPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) } }; - } else { - var error = new VASTError('on VPAIDIntegrator.playAd, could not find a supported mediaFile', 403); - adComplete(error, this._adUnit, vastResponse); + return this._adUnit; } - return this._adUnit; + callback(new VASTError('on VPAIDIntegrator.playAd, could not find a supported mediaFile')); + return null; /*** Local functions ***/ - function adComplete(error, adUnit, vastResponse) { - if (error && vastResponse) { - that._trackError(vastResponse, error.code); - } - player.trigger('vpaid.adEnd'); - callback(error, vastResponse); - } - function triggerVpaidAdEnd(){ player.trigger('vpaid.adEnd'); } @@ -5328,12 +4165,25 @@ VPAIDIntegrator.prototype._findSupportedTech = function (vastResponse, settings) for (i = 0, len = vpaidMediaFiles.length; i < len; i += 1) { mediaFile = vpaidMediaFiles[i]; - VPAIDTech = vastUtil.findSupportedVPAIDTech(mediaFile.type); + VPAIDTech = findSupportedTech(mediaFile); if (VPAIDTech) { return new VPAIDTech(mediaFile, settings); } } return null; + + /*** Local functions ***/ + function findSupportedTech(mediafile) { + var type = mediafile.type; + var i, len, VPAIDTech; + for (i = 0, len = VPAIDIntegrator.techs.length; i < len; i += 1) { + VPAIDTech = VPAIDIntegrator.techs[i]; + if (VPAIDTech.supports(type)) { + return VPAIDTech; + } + } + return null; + } }; VPAIDIntegrator.prototype._createVPAIDAdUnitWrapper = function(adUnit, src, responseTimeout) { @@ -5715,8 +4565,8 @@ VPAIDIntegrator.prototype._finishPlaying = function (adUnit, vastResponse, next) } }; -VPAIDIntegrator.prototype._trackError = function trackError(response, errorCode) { - vastUtil.track(response.errorURLMacros, {ERRORCODE: errorCode || 901}); +VPAIDIntegrator.prototype._trackError = function trackError(response) { + vastUtil.track(response.errorURLMacros, {ERRORCODE: 901}); }; function resizeAd(player, adUnit, VIEW_MODE) { @@ -5733,7 +4583,7 @@ function logError(error) { } module.exports = VPAIDIntegrator; -},{"../../utils/async":40,"../../utils/dom":41,"../../utils/playerUtils":43,"../../utils/utilityFunctions":45,"../vast/VASTError":23,"../vast/VASTResponse":25,"../vast/VASTTracker":26,"../vast/vastUtil":30,"./VPAIDAdUnitWrapper":31}],35:[function(require,module,exports){ +},{"../../utils/async":38,"../../utils/dom":39,"../../utils/playerUtils":41,"../../utils/utilityFunctions":43,"../vast/VASTError":21,"../vast/VASTResponse":23,"../vast/VASTTracker":24,"../vast/vastUtil":28,"./VPAIDAdUnitWrapper":29,"./VPAIDFlashTech":30,"./VPAIDHTML5Tech":31}],33:[function(require,module,exports){ 'use strict'; var dom = require('../../utils/dom'); @@ -5766,7 +4616,7 @@ var AdsLabelFactory = function(baseComponent) { }; module.exports = AdsLabelFactory; -},{"../../utils/dom":41}],36:[function(require,module,exports){ +},{"../../utils/dom":39}],34:[function(require,module,exports){ 'use strict'; var baseVideoJsComponent = videojs.Component; @@ -5775,7 +4625,7 @@ var AdsLabel = require('./ads-label')(baseVideoJsComponent); videojs.AdsLabel = videojs.Component.extend(AdsLabel); -},{"./ads-label":35}],37:[function(require,module,exports){ +},{"./ads-label":33}],35:[function(require,module,exports){ 'use strict'; /** @@ -5818,7 +4668,7 @@ var BlackPosterFactory = function(baseComponent) { }; module.exports = BlackPosterFactory; -},{}],38:[function(require,module,exports){ +},{}],36:[function(require,module,exports){ 'use strict'; var baseVideoJsComponent = videojs.Component; @@ -5827,7 +4677,7 @@ var BlackPoster = require('./black-poster')(baseVideoJsComponent); videojs.BlackPoster = videojs.Component.extend(BlackPoster); -},{"./black-poster":37}],39:[function(require,module,exports){ +},{"./black-poster":35}],37:[function(require,module,exports){ 'use strict'; var VASTClient = require('../ads/vast/VASTClient'); @@ -5896,8 +4746,6 @@ module.exports = function VASTPlugin(options) { return trackAdError(new VASTError('on VideoJS VAST plugin, missing adTagUrl on options object')); } - vastUtil.runFlashSupportCheck(settings.vpaidFlashLoaderPath);// Necessary step for VPAIDFLASHClient to work. - playerUtils.prepareForAds(player); if (settings.playAdAlways) { @@ -6115,29 +4963,18 @@ module.exports = function VASTPlugin(options) { var previousTime = 0; var skipad_attempts = 0; - player.on('timeupdate', preventAdSeek); - player.on('ended', preventAdSkip); - + player.on('timeupdate', adTimeupdateHandler); playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel', 'vast.adError'], stopPreventManualProgress); /*** Local functions ***/ - function preventAdSkip() { - // Ignore ended event if the Ad time was not 'near' the end - // and revert time to the previous 'valid' time - if ((player.duration() - previousTime) > PROGRESS_THRESHOLD) { - player.pause(true); // this reduce the video jitter if the IOS skip button is pressed - player.play(true); // we need to trigger the play to put the video element back in a valid state - player.currentTime(previousTime); - } - } - - function preventAdSeek() { + function adTimeupdateHandler() { var currentTime = player.currentTime(); var progressDelta = Math.abs(currentTime - previousTime); + if (progressDelta > PROGRESS_THRESHOLD) { skipad_attempts += 1; if (skipad_attempts >= 2) { - player.pause(true); + player.pause(); } player.currentTime(previousTime); } else { @@ -6146,8 +4983,7 @@ module.exports = function VASTPlugin(options) { } function stopPreventManualProgress() { - player.off('timeupdate', preventAdSeek); - player.off('ended', preventAdSkip); + player.off('timeupdate', adTimeupdateHandler); } } } @@ -6171,8 +5007,7 @@ module.exports = function VASTPlugin(options) { return false; } }; - -},{"../ads/vast/VASTClient":22,"../ads/vast/VASTError":23,"../ads/vast/VASTIntegrator":24,"../ads/vast/vastUtil":30,"../ads/vpaid/VPAIDIntegrator":34,"../utils/async":40,"../utils/dom":41,"../utils/playerUtils":43,"../utils/utilityFunctions":45}],40:[function(require,module,exports){ +},{"../ads/vast/VASTClient":20,"../ads/vast/VASTError":21,"../ads/vast/VASTIntegrator":22,"../ads/vast/vastUtil":28,"../ads/vpaid/VPAIDIntegrator":32,"../utils/async":38,"../utils/dom":39,"../utils/playerUtils":41,"../utils/utilityFunctions":43}],38:[function(require,module,exports){ //Small subset of async var utilities = require('./utilityFunctions'); @@ -6259,7 +5094,7 @@ async.when = function (condition, callback) { module.exports = async; -},{"./utilityFunctions":45}],41:[function(require,module,exports){ +},{"./utilityFunctions":43}],39:[function(require,module,exports){ 'use strict'; var utilities = require('./utilityFunctions'); @@ -6475,7 +5310,7 @@ dom.getDimension = function getDimension(element) { }; module.exports = dom; -},{"./utilityFunctions":45}],42:[function(require,module,exports){ +},{"./utilityFunctions":43}],40:[function(require,module,exports){ 'use strict'; var urlUtils = require('./urlUtils'); @@ -6626,7 +5461,7 @@ module.exports = { createXhr: createXhr }; -},{"./urlUtils":44,"./utilityFunctions":45}],43:[function(require,module,exports){ +},{"./urlUtils":42,"./utilityFunctions":43}],41:[function(require,module,exports){ 'use strict'; var dom = require('./dom'); @@ -7021,7 +5856,7 @@ playerUtils.once = function once(player, events, handler) { module.exports = playerUtils; -},{"./dom":41,"./utilityFunctions":45}],44:[function(require,module,exports){ +},{"./dom":39,"./utilityFunctions":43}],42:[function(require,module,exports){ 'use strict'; var utilities = require('./utilityFunctions'); @@ -7167,7 +6002,7 @@ module.exports = { objToQueryString: objToQueryString }; -},{"./utilityFunctions":45}],45:[function(require,module,exports){ +},{"./utilityFunctions":43}],43:[function(require,module,exports){ /*jshint unused:false */ "use strict"; @@ -7495,7 +6330,7 @@ var utilities = { }; module.exports = utilities; -},{}],46:[function(require,module,exports){ +},{}],44:[function(require,module,exports){ 'use strict'; var utilities = require('./utilityFunctions'); @@ -7642,7 +6477,7 @@ xml.decode = function decodeXML(str) { }; module.exports = xml; -},{"./utilityFunctions":45}],47:[function(require,module,exports){ +},{"./utilityFunctions":43}],45:[function(require,module,exports){ 'use strict'; require('./plugin/components/ads-label_4'); @@ -7653,5 +6488,5 @@ var videoJsVAST = require('./plugin/videojs.vast.vpaid'); videojs.plugin('vastClient', videoJsVAST); -},{"./plugin/components/ads-label_4":36,"./plugin/components/black-poster_4":38,"./plugin/videojs.vast.vpaid":39}]},{},[47]) -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlERkxBU0hDbGllbnQvanMvSVZQQUlEQWRVbml0LmpzIiwiYm93ZXJfY29tcG9uZW50cy9WUEFJREZMQVNIQ2xpZW50L2pzL1ZQQUlEQWRVbml0LmpzIiwiYm93ZXJfY29tcG9uZW50cy9WUEFJREZMQVNIQ2xpZW50L2pzL1ZQQUlERkxBU0hDbGllbnQuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlERkxBU0hDbGllbnQvanMvZmxhc2hUZXN0ZXIuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlERkxBU0hDbGllbnQvanMvanNGbGFzaEJyaWRnZS5qcyIsImJvd2VyX2NvbXBvbmVudHMvVlBBSURGTEFTSENsaWVudC9qcy9qc0ZsYXNoQnJpZGdlUmVnaXN0cnkuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlERkxBU0hDbGllbnQvanMvcmVnaXN0cnkuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlERkxBU0hDbGllbnQvanMvdXRpbHMuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlESFRNTDVDbGllbnQvanMvSVZQQUlEQWRVbml0LmpzIiwiYm93ZXJfY29tcG9uZW50cy9WUEFJREhUTUw1Q2xpZW50L2pzL1ZQQUlEQWRVbml0LmpzIiwiYm93ZXJfY29tcG9uZW50cy9WUEFJREhUTUw1Q2xpZW50L2pzL1ZQQUlESFRNTDVDbGllbnQuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlESFRNTDVDbGllbnQvanMvc3Vic2NyaWJlci5qcyIsImJvd2VyX2NvbXBvbmVudHMvVlBBSURIVE1MNUNsaWVudC9qcy91dGlscy5qcyIsImJvd2VyX2NvbXBvbmVudHMvc3dmb2JqZWN0L3N3Zm9iamVjdC9zcmMvc3dmb2JqZWN0LmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvQWQuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9Db21wYW5pb24uanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9DcmVhdGl2ZS5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L0luTGluZS5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L0xpbmVhci5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L01lZGlhRmlsZS5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L1RyYWNraW5nRXZlbnQuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9WQVNUQ2xpZW50LmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvVkFTVEVycm9yLmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvVkFTVEludGVncmF0b3IuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9WQVNUUmVzcG9uc2UuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9WQVNUVHJhY2tlci5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L1ZpZGVvQ2xpY2tzLmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvV3JhcHBlci5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L3BhcnNlcnMuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC92YXN0VXRpbC5qcyIsInNyYy9zY3JpcHRzL2Fkcy92cGFpZC9WUEFJREFkVW5pdFdyYXBwZXIuanMiLCJzcmMvc2NyaXB0cy9hZHMvdnBhaWQvVlBBSURGbGFzaFRlY2guanMiLCJzcmMvc2NyaXB0cy9hZHMvdnBhaWQvVlBBSURIVE1MNVRlY2guanMiLCJzcmMvc2NyaXB0cy9hZHMvdnBhaWQvVlBBSURJbnRlZ3JhdG9yLmpzIiwic3JjL3NjcmlwdHMvcGx1Z2luL2NvbXBvbmVudHMvYWRzLWxhYmVsLmpzIiwic3JjL3NjcmlwdHMvcGx1Z2luL2NvbXBvbmVudHMvYWRzLWxhYmVsXzQuanMiLCJzcmMvc2NyaXB0cy9wbHVnaW4vY29tcG9uZW50cy9ibGFjay1wb3N0ZXIuanMiLCJzcmMvc2NyaXB0cy9wbHVnaW4vY29tcG9uZW50cy9ibGFjay1wb3N0ZXJfNC5qcyIsInNyYy9zY3JpcHRzL3BsdWdpbi92aWRlb2pzLnZhc3QudnBhaWQuanMiLCJzcmMvc2NyaXB0cy91dGlscy9hc3luYy5qcyIsInNyYy9zY3JpcHRzL3V0aWxzL2RvbS5qcyIsInNyYy9zY3JpcHRzL3V0aWxzL2h0dHAuanMiLCJzcmMvc2NyaXB0cy91dGlscy9wbGF5ZXJVdGlscy5qcyIsInNyYy9zY3JpcHRzL3V0aWxzL3VybFV0aWxzLmpzIiwic3JjL3NjcmlwdHMvdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucy5qcyIsInNyYy9zY3JpcHRzL3V0aWxzL3htbC5qcyIsInNyYy9zY3JpcHRzL3ZpZGVvanNfNC52YXN0LnZwYWlkLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQUdhOzs7Ozs7Ozs7OzJDQUkwRDtnQkFBbEQsMkVBQXFCLGtCQUE2QjtnQkFBdEIsaUVBQVcsc0JBQVc7Ozs7Ozs7K0JBRzNELE9BQU8sUUFBUSxVQUFVLGdCQUEyRztnQkFBM0YscUVBQWUsRUFBQyxjQUFBLEFBQWEsaUJBQThEO2dCQUF6RCx3RUFBa0IsRUFBQyxXQUFBLEFBQVcsaUJBQTJCO2dCQUF0QixpRUFBVyxzQkFBVzs7OztpQ0FDbkksT0FBTyxRQUFRLFVBQWdDO2dCQUF0QixpRUFBVyxzQkFBVzs7OztrQ0FFMUI7Z0JBQXRCLGlFQUFXLHNCQUFXOzs7O2lDQUNEO2dCQUF0QixpRUFBVyxzQkFBVzs7OztrQ0FDQztnQkFBdEIsaUVBQVcsc0JBQVc7Ozs7bUNBQ0M7Z0JBQXRCLGlFQUFXLHNCQUFXOzs7O21DQUNBO2dCQUF0QixpRUFBVyxzQkFBVzs7OztxQ0FDRTtnQkFBdEIsaUVBQVcsc0JBQVc7Ozs7aUNBQ0o7Z0JBQXRCLGlFQUFXLHNCQUFXOzs7Ozs7O29DQUdqQixVQUFVOzs7bUNBQ1gsVUFBVTs7O29DQUNULFVBQVU7OztzQ0FDUixVQUFVOzs7NENBQ0osVUFBVTs7OzJDQUNYLFVBQVU7OztzQ0FDZixVQUFVOzs7b0NBQ1osYUFBbUM7Z0JBQXRCLGlFQUFXLHNCQUFXOzs7O29DQUNuQyxVQUFVOzs7d0NBQ04sVUFBVTs7O21DQUNmLFVBQVU7OztXQTdCWjs7O0FBZ0NiLE9BQUEsQUFBTyxlQUFQLEFBQXNCLGNBQXRCLEFBQW9DLFVBQVUsQUFDMUM7Y0FBQSxBQUFVLEFBQ1Y7a0JBQUEsQUFBYyxBQUNkO1dBQU8sQ0FBQSxBQUNILFlBREcsQUFFSCxhQUZHLEFBR0gsYUFIRyxBQUlILGFBSkcsQUFLSCxBQUNBO0FBTkcsQUFPSDtBQVBHLHNCQUFBLEFBUUgsQUFDQTtBQVRHLHdCQUFBLEFBVUgsQUFDQTtBQVhHLHNCQUFBLEFBWUgsZ0JBWkcsQUFhSCxnQkFiRyxBQWNILHdCQWRHLEFBZUgsbUJBZkcsQUFnQkgsd0JBaEJHLEFBaUJILG1CQWpCRyxBQWtCSCxlQWxCRyxBQW1CSCxBQUNBO0FBcEJHLDhCQUFBLEFBcUJILGtCQXJCRyxBQXNCSCxlQXRCRyxBQXVCSCxZQXZCRyxBQXdCSCxhQXhCRyxBQXlCSCxTQTVCUixBQUdJLEFBQU8sQUEwQkg7Ozs7QUNoRVI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVBLElBQUksZUFBZSxRQUFBLEFBQVEsa0JBQVIsQUFBMEI7QUFDN0Msd0JBQXdCLE9BQUEsQUFBTyxvQkFBb0IsYUFBM0IsQUFBMkIsQUFBYSxXQUF4QyxBQUFtRCxpQkFBTyxBQUFVO1dBQ2pGLENBQUEsQUFBQyxlQUFELEFBQWdCLFFBQWhCLEFBQXdCLGNBQWMsQ0FEN0MsQUFBOEUsQUFBb0IsQUFDckQsQUFBQyxFQURvRCxBQUNsRztDQUQ4RSxDQUE5RTs7SUFJUzsyQkFDVDs7YUFEUyxBQUNULFlBQUEsQUFBYTs4QkFESixBQUNXOzsyRUFEWCxrQkFDVyxBQUVoQjs7Y0FBQSxBQUFLLGFBRlcsQUFFaEIsQUFBa0IsQUFDbEI7Y0FBQSxBQUFLLFNBSFcsQUFHaEIsQUFBYztlQUhsQixNQUFvQjs7O2lCQURYOzs7eUJBUUw7O2lCQUFBLEFBQUssYUFERSxBQUNQLEFBQWtCLEFBQ2xCOzhCQUFBLEFBQWtCLGtCQUFRLEFBQUMsWUFBZSxBQUN0Qzt1QkFBQSxBQUFLLE9BQUwsQUFBWSwyQkFIVCxBQUVQLEFBQTBCLEFBQWdCLEFBQ3RDLEFBQXVDLEFBRTNDO2FBSDBCLEVBRm5CO3lCQUtQLEFBQWEsT0FBYixBQUFvQixrQkFBUSxBQUFDO3VCQUN6QixBQUFLLE9BQUwsQUFBWSxTQU5ULEFBS1AsQUFBNEIsQUFBVyxBQUNuQyxBQUFxQixBQUd6QixPQUp1QyxBQUNuQzthQUR3Qjs7aUJBSTVCLEFBQUssU0FURSxBQVNQLEFBQWM7Ozs7O21CQUlQLEtBREksQUFDSixBQUFLLFdBREQsQUFDWDs7OzsyQkFHRCxXQUFXLFVBQVUsQUFDcEI7aUJBQUEsQUFBSyxPQUFMLEFBQVksR0FBWixBQUFlLFdBREssQUFDcEIsQUFBMEI7Ozs7NEJBRzFCLFdBQVcsVUFBVSxBQUNyQjtpQkFBQSxBQUFLLE9BQUwsQUFBWSxJQUFaLEFBQWdCLFdBREssQUFDckIsQUFBMkI7Ozs7Ozs7MkNBSW9DO2dCQUFsRCwyRUFBcUIsa0JBQTZCO2dCQUF0QixpRUFBVyxzQkFBVyxBQUMvRDs7aUJBQUEsQUFBSyxPQUFMLEFBQVksZ0JBQVosQUFBNEIsb0JBQW9CLENBQWhELEFBQWdELEFBQUMscUJBRGMsQUFDL0QsQUFBc0U7Ozs7K0JBRWxFLE9BQU8sUUFBUSxVQUFVO2dCQUFnQixxRUFBZSxFQUFDLGNBQUEsQUFBYyxpQkFBOEQ7Z0JBQXpELHdFQUFrQixFQUFDLFdBQUEsQUFBVyxpQkFBMkI7Z0JBQXRCLGlFQUFXLHNCQUFXLEFBRXpJOzs7QUFGeUksaUJBRXpJLEFBQUssT0FBTCxBQUFZLFFBQVosQUFBb0IsT0FGcUgsQUFFekksQUFBMkIsQUFDM0I7MkJBQWUsZ0JBQWdCLEVBQUMsY0FIeUcsQUFHMUgsQUFBaUIsQUFBYyxBQUM5Qzs4QkFBa0IsbUJBQW1CLEVBQUMsV0FKbUcsQUFJdkgsQUFBb0IsQUFBVyxBQUVqRDs7aUJBQUEsQUFBSyxPQUFMLEFBQVksZ0JBQVosQUFBNEIsVUFBVSxDQUFDLEtBQUEsQUFBSyxPQUFOLEFBQUMsQUFBWSxZQUFZLEtBQUEsQUFBSyxPQUE5QixBQUF5QixBQUFZLGFBQXJDLEFBQWtELFVBQWxELEFBQTRELGdCQUFnQixhQUFBLEFBQWEsZ0JBQWIsQUFBNkIsSUFBSSxnQkFBQSxBQUFnQixhQUFuSyxBQUFtSixBQUE2QixLQU52QyxBQU16SSxBQUFxTDs7OztpQ0FFaEwsT0FBTyxRQUFRO2dCQUFVLGlFQUFXLHNCQUFXLEFBRXBEOzs7QUFGb0QsaUJBRXBELEFBQUssT0FBTCxBQUFZLFFBQVosQUFBb0IsT0FGZ0MsQUFFcEQsQUFBMkI7OztnQkFHM0IsQ0FBQSxBQUFLLE9BQUwsQUFBWSxnQkFBWixBQUE0QixZQUFZLENBQUMsS0FBQSxBQUFLLE9BQU4sQUFBQyxBQUFZLFlBQVksS0FBQSxBQUFLLE9BQTlCLEFBQXlCLEFBQVksYUFBN0UsQUFBd0MsQUFBa0QsV0FMdEMsQUFLcEQsQUFBcUc7Ozs7a0NBRTNFO2dCQUF0QixpRUFBVyxzQkFBVyxBQUMxQjs7aUJBQUEsQUFBSyxPQUFMLEFBQVksZ0JBQVosQUFBNEIsV0FBNUIsQUFBdUMsSUFEYixBQUMxQixBQUEyQzs7OztpQ0FFbEI7Z0JBQXRCLGlFQUFXLHNCQUFXLEFBQ3pCOztpQkFBQSxBQUFLLE9BQUwsQUFBWSxnQkFBWixBQUE0QixVQUE1QixBQUFzQyxJQURiLEFBQ3pCLEFBQTBDOzs7O2tDQUVoQjtnQkFBdEIsaUVBQVcsc0JBQVcsQUFDMUI7O2lCQUFBLEFBQUssT0FBTCxBQUFZLGdCQUFaLEFBQTRCLFdBQTVCLEFBQXVDLElBRGIsQUFDMUIsQUFBMkM7Ozs7bUNBRWhCO2dCQUF0QixpRUFBVyxzQkFBVyxBQUMzQjs7aUJBQUEsQUFBSyxPQUFMLEFBQVksZ0JBQVosQUFBNEIsWUFBNUIsQUFBd0MsSUFEYixBQUMzQixBQUE0Qzs7OzttQ0FFakI7Z0JBQXRCLGlFQUFXLHNCQUFXLEFBQzNCOztpQkFBQSxBQUFLLE9BQUwsQUFBWSxnQkFBWixBQUE0QixZQUE1QixBQUF3QyxJQURiLEFBQzNCLEFBQTRDOzs7O3FDQUVmO2dCQUF0QixpRUFBVyxzQkFBVyxBQUM3Qjs7aUJBQUEsQUFBSyxPQUFMLEFBQVksZ0JBQVosQUFBNEIsY0FBNUIsQUFBMEMsSUFEYixBQUM3QixBQUE4Qzs7OztpQ0FFckI7Z0JBQXRCLGlFQUFXLHNCQUFXLEFBQ3pCOztpQkFBQSxBQUFLLE9BQUwsQUFBWSxnQkFBWixBQUE0QixVQUE1QixBQUFzQyxJQURiLEFBQ3pCLEFBQTBDOzs7Ozs7O29DQUlsQyxVQUFVLEFBQ2xCO2lCQUFBLEFBQUssT0FBTCxBQUFZLGdCQUFaLEFBQTRCLGVBQTVCLEFBQTJDLElBRHpCLEFBQ2xCLEFBQStDOzs7O21DQUV4QyxVQUFVLEFBQ2pCO2lCQUFBLEFBQUssT0FBTCxBQUFZLGdCQUFaLEFBQTRCLGNBQTVCLEFBQTBDLElBRHpCLEFBQ2pCLEFBQThDOzs7O29DQUV0QyxVQUFVLEFBQ2xCO2lCQUFBLEFBQUssT0FBTCxBQUFZLGdCQUFaLEFBQTRCLGVBQTVCLEFBQTJDLElBRHpCLEFBQ2xCLEFBQStDOzs7O3NDQUVyQyxVQUFVLEFBQ3BCO2lCQUFBLEFBQUssT0FBTCxBQUFZLGdCQUFaLEFBQTRCLGlCQUE1QixBQUE2QyxJQUR6QixBQUNwQixBQUFpRDs7Ozs0Q0FFakMsVUFBVSxBQUMxQjtpQkFBQSxBQUFLLE9BQUwsQUFBWSxnQkFBWixBQUE0Qix1QkFBNUIsQUFBbUQsSUFEekIsQUFDMUIsQUFBdUQ7Ozs7MkNBRXhDLFVBQVUsQUFDekI7aUJBQUEsQUFBSyxPQUFMLEFBQVksZ0JBQVosQUFBNEIsc0JBQTVCLEFBQWtELElBRHpCLEFBQ3pCLEFBQXNEOzs7O3NDQUU1QyxVQUFVLEFBQ3BCO2lCQUFBLEFBQUssT0FBTCxBQUFZLGdCQUFaLEFBQTRCLGlCQUE1QixBQUE2QyxJQUR6QixBQUNwQixBQUFpRDs7OztvQ0FFekMsUUFBOEI7Z0JBQXRCLGlFQUFXLHNCQUFXLEFBQ3RDOztpQkFBQSxBQUFLLE9BQUwsQUFBWSxnQkFBWixBQUE0QixlQUFlLENBQTNDLEFBQTJDLEFBQUMsU0FETixBQUN0QyxBQUFxRDs7OztvQ0FFN0MsVUFBVSxBQUNsQjtpQkFBQSxBQUFLLE9BQUwsQUFBWSxnQkFBWixBQUE0QixlQUE1QixBQUEyQyxJQUR6QixBQUNsQixBQUErQzs7Ozt3Q0FFbkMsVUFBVSxBQUN0QjtpQkFBQSxBQUFLLE9BQUwsQUFBWSxnQkFBWixBQUE0QixtQkFBNUIsQUFBK0MsSUFEekIsQUFDdEIsQUFBbUQ7Ozs7bUNBRTVDLFVBQVUsQUFDakI7aUJBQUEsQUFBSyxPQUFMLEFBQVksZ0JBQVosQUFBNEIsY0FBNUIsQUFBMEMsSUFEekIsQUFDakIsQUFBOEM7Ozs7V0F4R3pDO0VBQW9COzs7QUNQakM7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVBLElBQU0sWUFBWSxRQUFaLEFBQVksQUFBUTs7QUFFMUIsSUFBTSxnQkFBZ0IsUUFBQSxBQUFRLG1CQUFSLEFBQTJCO0FBQ2pELElBQU0sY0FBYyxRQUFBLEFBQVEsaUJBQVIsQUFBeUI7O0FBRTdDLElBQU0sT0FBTyxRQUFBLEFBQVEsV0FBUixBQUFtQjtBQUNoQyxJQUFNLGtCQUFrQixRQUFBLEFBQVEsV0FBUixBQUFtQjtBQUMzQyxJQUFNLGdCQUFnQixRQUFBLEFBQVEsV0FBUixBQUFtQjtBQUN6QyxJQUFNLHNCQUFzQixRQUFBLEFBQVEsV0FBUixBQUFtQjtBQUMvQyxJQUFNLGNBQWMsUUFBQSxBQUFRLFdBQVIsQUFBbUIsT0FBakMsQUFBYyxBQUEwQjtBQUM5QyxJQUFNLG9CQUFvQixRQUFBLEFBQVEsb0JBQVIsQUFBNEI7O0FBRXRELElBQU0sUUFBQSxBQUFRO0FBQ2QsSUFBTSxnQkFBQSxBQUFnQjs7QUFFdEIsSUFBSSxjQUFjLEVBQUM7ZUFBZixBQUE0QixBQUFLO0tBQUw7OzthQUUxQixBQUNGLGlCQUFBLEFBQWEsZUFBYixBQUE0QjtZQUFVLGtFQUFZLEVBQUMsTUFBQSxBQUFNLGtCQUFrQixPQUFBLEFBQU8sS0FBSyxRQUFBLEFBQVEsa0JBQStNOzs7O1lBQXpNLCtEQUFTLEVBQUUsT0FBQSxBQUFPLGVBQWUsUUFBQSxBQUFRLE1BQU0sT0FBQSxBQUFPLFFBQVEsbUJBQUEsQUFBbUIsVUFBVSxPQUFBLEFBQU8sV0FBVyxpQkFBQSxBQUFpQixRQUFRLFNBQUEsQUFBUyxxQkFBMEQ7WUFBakQscUVBQWUsRUFBRSxPQUFBLEFBQU8sT0FBTyxTQUFBLEFBQVMsb0JBQVM7OzhCQUQ1UyxBQUM0UyxBQUUxUzs7WUFBSSxLQUZzUyxBQUV0UyxBQUFLLEFBRVQ7O2FBQUEsQUFBSyxpQkFKcVMsQUFJMVMsQUFBc0IsQUFDdEI7YUFBQSxBQUFLLFdBTHFTLEFBSzFTLEFBQWdCLEFBQ2hCO2FBQUEsQUFBSyxhQU5xUyxBQU0xUyxBQUFrQixBQUNsQjttQkFBVyxZQVArUixBQU8vUixBQUFZLEFBRXZCOztrQkFBQSxBQUFVLFFBQVEsY0FBYyxVQUFBLEFBQVUsT0FUZ1EsQUFTMVMsQUFBa0IsQUFBK0IsQUFDakQ7a0JBQUEsQUFBVSxTQUFTLGNBQWMsVUFBQSxBQUFVLFFBVitQLEFBVTFTLEFBQW1CLEFBQWdDLEFBRW5EOzs0QkFBQSxBQUFvQixlQUFlLEtBQUEsQUFBSyxVQVprUSxBQVkxUyxBQUFrRCxBQUVsRDs7ZUFBQSxBQUFPLFFBQVEsVUFkMlIsQUFjM1IsQUFBVSxBQUN6QjtlQUFBLEFBQU8seUJBQXVCLEtBQUEsQUFBSyx5QkFBb0IsY0FBQSxBQUFjLGtDQUE2QixhQUFBLEFBQWEscUJBQWdCLE9BZjJLLEFBZTNLLEFBQU8sQUFFdEk7O1lBQUksQ0FBQyxpQkFBRCxBQUFDLEFBQWlCLGVBQWUsQUFDakM7bUJBQU8sUUFBUSxzRkFEbkIsQUFBcUMsQUFDakMsQUFBZSxBQUFzRixBQUd6Rzs7O2FBQUEsQUFBSyxLQUFLLFVBQUEsQUFBVSxVQUFWLEFBQW9CLFdBQXBCLEFBQStCLFFBQVEsS0FyQnlQLEFBcUIxUyxBQUFpRCxBQUFLLEFBRXREOztZQUFJLENBQUMsS0FBQSxBQUFLLElBQUksQUFDVjttQkFBTyxRQURYLEFBQWMsQUFDVixBQUFPLEFBQVMsQUFHcEI7OztzQkFBYyxnQkFBZ0IsYUFBQSxBQUFhLG1CQUN2QyxBQUFDLEtBQUQsQUFBTTs4QkFDRixBQUFrQixLQURQLEFBRVg7cUJBQUEsQUFBUyxLQUZiLEFBQWUsQUFFWCxBQUFjLE1BRkgsQUFDWDtTQURKLGNBR1MsQUFDTDtxQkFBUyw4QkFBOEIsYUFoQzJQLEFBMkJ0UyxBQUlHLEFBQU0sQUFDTCxBQUF1QyxBQUFhLEFBSTVEO1NBTE8sQ0FKSCxDQTNCc1M7O2FBb0MxUyxBQUFLLFNBQVMsSUFBQSxBQUFJLGNBQWMsS0FBQSxBQUFLLElBQUksVUFBQSxBQUFVLE1BQU0sS0FBQSxBQUFLLFVBQVUsVUFBQSxBQUFVLE9BQU8sVUFBQSxBQUFVLFFBcEN1TSxBQW9DMVMsQUFBYyxBQUE2RixBQUUzRzs7aUJBQUEsQUFBUyxRQUFULEFBQWlCO21DQUNJLEFBQ2I7eUJBQVMsSUFBQSxBQUFJLE1BRE4sQUFBTSxBQUNiLEFBQVMsQUFBVTthQURaLEVBRFMsQUFDcEIsQUFFRyxBQUNILEdBSm9CLEFBQ3BCO21CQXZDUixBQXNDSSxBQUF3QixBQUlwQixBQUFPOzs7O2lCQTNDYjs7O2lCQWdEUyxBQUNQLEFBQUssQUFFTDs7Z0JBQUksS0FBQSxBQUFLLFFBQVEsQUFDYjtxQkFBQSxBQUFLLE9BRFEsQUFDYixBQUFZLEFBQ1o7cUJBQUEsQUFBSyxTQUZULEFBQWlCLEFBRWIsQUFBYyxBQUVsQjs7aUJBQUEsQUFBSyxLQVBFLEFBT1AsQUFBVSxBQUNWLEtBUk8sQUFDUDtpQkFPQSxBQUFLLGFBUkUsQUFRUCxBQUFrQjs7Ozs7bUJBSVgsS0FESSxBQUNKLEFBQUssV0FERCxBQUNYOzs7OzttQkFJTyxLQURNLEFBQ04sQUFBSyxBQUVaLFdBSGEsQUFDYjs7Z0JBRUksS0FBQSxBQUFLLGFBQWEsQUFDbEI7cUJBQUEsQUFBSyxjQURhLEFBQ2xCLEFBQW1CLEFBQ25CO3FCQUFBLEFBQUssT0FBTCxBQUFZLGVBQWUsS0FGL0IsQUFBc0IsQUFFbEIsQUFBMkIsQUFBSyxBQUdwQzs7O2dCQUFJLEtBQUEsQUFBSyxTQUFTLEFBQ2Q7cUJBQUEsQUFBSyxRQURTLEFBQ2QsQUFBYSxBQUNiO3FCQUFBLEFBQUssVUFGVCxBQUFrQixBQUVkLEFBQWU7Ozs7O21DQUlaLE9BQU87eUJBQ2QsS0FEd0I7OzhCQUN4QixBQUFrQixLQURNLEFBQ3hCLEFBQXVCLEFBRXZCOztnQkFBSSxLQUFBLEFBQUssU0FBUyxBQUNkO3FCQURKLEFBQWtCLEFBQ2QsQUFBSyxBQUdUOzs7Z0JBQUksS0FBQSxBQUFLLE9BQVQsQUFBSSxBQUFZO3FCQUNaLEFBQUssd0JBQWMsQUFBQyxLQUFELEFBQU07d0JBQ2pCLENBQUEsQUFBQyxLQUFLLEFBQ047K0JBQUEsQUFBSyxVQUFVLElBQUEsQUFBSSxZQUFZLE9BRG5DLEFBQVUsQUFDTixBQUErQixBQUFLLEFBRXhDOzsyQkFBQSxBQUFLLGNBSjRCLEFBSWpDLEFBQW1CLEFBQ25CLEtBTGlDLEFBQ2pDOzZCQUlBLEFBQVMsS0FBSyxPQU5LLEFBQ0osQUFBa0IsQUFLakMsQUFBYyxBQUFLLEFBR3ZCO2lCQVJtQixDQURJLEFBQ3ZCOztxQkFRQSxBQUFLLE9BQUwsQUFBWSxnQkFBWixBQUE0QixjQUFjLENBQTFDLEFBQTBDLEFBQUMsUUFBUSxLQVR2RCxBQUEyQixBQVN2QixBQUFtRCxBQUFLO21CQUN0RCxBQUNGO3FCQUFBLEFBQUssYUFBYSxFQUFDLEtBQUEsQUFBSyxPQUFPLFVBWG5DLEFBVU0sQUFDRixBQUFrQjs7Ozs7O2dCQUliLGlFQUFXLHNCQUFXLEFBQy9COzs4QkFBQSxBQUFrQixLQURhLEFBQy9CLEFBQXVCLEFBRXZCOztpQkFIK0IsQUFHL0IsQUFBSyxBQUNMLGlCQUorQjtpQkFJL0IsQUFBSyxPQUFMLEFBQVksZ0JBQVosQUFBNEIsZ0JBQTVCLEFBQTRDLElBSmIsQUFJL0IsQUFBZ0Q7Ozs7cUNBRXZDLEFBQ1Q7OEJBQUEsQUFBa0IsS0FEVCxBQUNULEFBQXVCLEFBQ3ZCO21CQUFPLEtBQUEsQUFBSyxPQUZILEFBRVQsQUFBTyxBQUFZOzs7O3NDQUVULEFBQ1Y7OEJBQUEsQUFBa0IsS0FEUixBQUNWLEFBQXVCLEFBQ3ZCO21CQUFPLEtBQUEsQUFBSyxPQUZGLEFBRVYsQUFBTyxBQUFZOztRQTlHdkI7O1dBREU7R0FBQTs7QUFtSE4sa0JBQUEsQUFBa0IsMkJBQXFCLEFBQ25DO1dBQU8sVUFBQSxBQUFVLHNCQUFWLEFBQWdDLGtCQUFrQixZQUQ1QixBQUFNLEFBQzVCLEFBQWtELEFBQVk7Q0FEeEMsRUFBakMsQUFFRzs7QUFFSCxrQkFBQSxBQUFrQiwwQkFBZ0IsQUFBQyxXQUFjLEFBQzdDO2tCQUFjLGtCQUFrQixTQUFBLEFBQVMsTUFEN0MsQUFBa0MsQUFBZSxBQUM3QyxBQUFjLEFBQWlDO0NBRGpCOztBQUlsQyxTQUFBLEFBQVMsb0JBQW9CLEFBQ3pCO1FBQUcsS0FBQSxBQUFLLFlBQVksQUFDaEI7Y0FBTSxJQUFBLEFBQUksTUFGbEIsQUFDSSxBQUFvQixBQUNoQixBQUFNLEFBQVU7Ozs7QUFJeEIsU0FBQSxBQUFTLG9CQUFvQixBQUN6QjtRQUFJLEtBQUEsQUFBSyxZQUFZLEFBQ2pCO2FBQUEsQUFBSyxXQUFXLEtBQUEsQUFBSyxXQUFMLEFBQWdCLEtBQUssS0FBQSxBQUFLLFdBRHpCLEFBQ2pCLEFBQXFDLEFBQWdCLEFBQ3JEO2VBQU8sS0FIZixBQUNJLEFBQXFCLEFBRVYsQUFBSzs7OztBQUlwQixTQUFBLEFBQVMsa0JBQVQsQUFBMkIsY0FBM0IsQUFBeUM7UUFBTyxpRUFBVyxrQkFBTyxBQUM5RDs7V0FBQSxBQUFPLGVBQVAsQUFBc0Isa0JBQXRCLEFBQXdDLGNBQWMsQUFDbEQ7a0JBQUEsQUFBVSxBQUNWO3NCQUFBLEFBQWMsQUFDZDtlQUpSLEFBQWtFLEFBQzlELEFBR0ksQUFBTztPQUptRDs7O0FBUWxFLGlCQUFBLEFBQWlCLFlBQWpCLEFBQTZCOztBQUU3QixPQUFBLEFBQU8sVUFBUCxBQUFpQjs7O0FDcktqQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVBLElBQU0sWUFBWSxRQUFaLEFBQVksQUFBUTs7QUFFMUIsSUFBTSxhQUFBLEFBQWE7QUFDbkIsSUFBTSxnQkFBQSxBQUFnQjtBQUN0QixJQUFNLGdCQUFnQixRQUFBLEFBQVEsbUJBQVIsQUFBMkI7QUFDakQsSUFBTSxRQUFRLFFBQVIsQUFBUSxBQUFRO0FBQ3RCLElBQU0seUJBQXlCLFFBQUEsQUFBUSxjQUFSLEFBQXNCOzs7YUFFL0MsQUFDRixZQUFBLEFBQVk7OztZQUFRLGtFQUFZLEVBQUMsTUFBQSxBQUFNLGtCQUFrQixPQUFBLEFBQU8sS0FBSyxRQUFBLEFBQVEsa0JBQU07OzhCQURqRixBQUNpRixBQUMvRTs7YUFBQSxBQUFLLFdBQVcsTUFBQSxBQUFNLG9CQUFOLEFBQTBCLFFBRHFDLEFBQy9FLEFBQWdCLEFBQWtDO0FBRDZCLGFBRS9FLENBQUEsQUFBTSxZQUFZLEtBRjZELEFBRS9FLEFBQWtCLEFBQUssQUFDdkI7WUFBSSxTQUgyRSxBQUczRSxBQUFTLEFBQ2I7ZUFBQSxBQUFPLFFBQVEsVUFKZ0UsQUFJaEUsQUFBVSxBQUN6QjtlQUFBLEFBQU8seUJBQXVCLDhCQUF5QixjQUx3QixBQUt4QixBQUFjLEFBRXJFOzthQUFBLEFBQUssS0FBSyxVQUFBLEFBQVUsVUFBVixBQUFvQixXQUFwQixBQUErQixRQVBzQyxBQU8vRSxBQUFVLEFBQXVDLEFBQ2pEO2FBQUEsQUFBSyxZQUFZLElBUjhELEFBUS9FLEFBQWlCLEFBQUksQUFDckI7YUFBQSxBQUFLLGVBVDBFLEFBUy9FLEFBQW9CLEFBQ3BCO1lBQUksS0FBQSxBQUFLO2tCQUNMLEFBQU0sWUFBWSxLQURULEFBQ1QsQUFBa0IsQUFBSyxBQUN2QjtpQkFBQSxBQUFLLFNBQVMsSUFBQSxBQUFJLGNBQWMsS0FBQSxBQUFLLElBQUksVUFBQSxBQUFVLE1BQXJDLEFBQTJDLGVBQTNDLEFBQTBELEtBQTFELEFBQStEO29CQUNuRSxVQUQ2RSxBQUM3RSxBQUFVLEFBQ2hCO3NCQUFBLEFBQUssZUFGOEUsQUFFbkYsQUFBb0IsQUFDcEI7c0JBQUEsQUFBSyxVQUFMLEFBQWUsSUFBZixBQUFtQixVQUFuQixBQUE2QixrQkFBUSxBQUFDOzJDQUNsQixBQUNaO2lDQUFBLEFBQVMsVUFERixBQUFLLEFBQ1osQUFBbUI7cUJBRFosRUFoQjNCLEFBVUksQUFBYSxBQUVULEFBQWtGLEFBQUssQUFHbkYsQUFBcUMsQUFBYyxBQUMvQyxBQUVHLEdBSDRDLEFBQy9DO2lCQURpQyxFQUg4QyxBQUNuRjthQUQ4RSxFQUZ6RSxBQUNUOzs7O2lCQVpOOzs7bUJBeUJTLEtBREcsQUFDSCxBQUFLLGFBREYsQUFDVjs7OzsyQkFFRCxXQUFXLFVBQVUsQUFDcEI7aUJBQUEsQUFBSyxVQUFMLEFBQWUsSUFBZixBQUFtQixXQURDLEFBQ3BCLEFBQThCOztRQTNCbEM7O1dBREU7R0FBQTs7QUFnQ0MsSUFBSSx5REFBb0IsQUFBUyxrQkFBVCxBQUEyQixJQUEzQixBQUErQjtRQUN0RCxDQUFDLE9BQUQsQUFBQyxBQUFPLGFBQWEsQUFDckI7ZUFBQSxBQUFPLGNBQWMsSUFBQSxBQUFJLFlBQUosQUFBZ0IsSUFEekMsQUFBeUIsQUFDckIsQUFBcUIsQUFBb0IsQUFFN0M7O1dBQU8sT0FKb0IsQUFBMEMsQUFJckUsQUFBTyxBQUFPLFlBSnVELEFBQ3JFO0NBRDJCOzs7QUMxQy9COzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUEsSUFBSSxTQUFTLFFBQUEsQUFBUSxXQUFSLEFBQW1CO0FBQ2hDLElBQUksZ0JBQWdCLFFBQUEsQUFBUSxXQUFSLEFBQW1CO0FBQ3ZDLElBQUksaUJBQWlCLFFBQUEsQUFBUSxXQUFSLEFBQW1CO0FBQ3hDLElBQUksc0JBQXNCLFFBQUEsQUFBUSxjQUFSLEFBQXNCO0FBQ2hELElBQUkseUJBQXlCLFFBQUEsQUFBUSxjQUFSLEFBQXNCO0FBQ25ELElBQU0sV0FBVyxRQUFYLEFBQVcsQUFBUTtBQUN6QixJQUFNLHNCQUFBLEFBQXNCO0FBQzVCLElBQU0sUUFBQSxBQUFROztJQUVEO2FBQUEsQUFDVCxjQUFBLEFBQWEsSUFBYixBQUFpQixVQUFqQixBQUEyQixTQUEzQixBQUFvQyxPQUFwQyxBQUEyQyxRQUEzQyxBQUFtRDs4QkFEMUMsQUFDeUQsQUFDOUQ7O2FBQUEsQUFBSyxNQUR5RCxBQUM5RCxBQUFXLEFBQ1gsR0FGOEQ7YUFFOUQsQUFBSyxXQUZ5RCxBQUU5RCxBQUFnQixBQUNoQjthQUFBLEFBQUssWUFIeUQsQUFHOUQsQUFBaUIsQUFDakI7YUFBQSxBQUFLLFNBSnlELEFBSTlELEFBQWMsQUFDZDthQUFBLEFBQUssVUFMeUQsQUFLOUQsQUFBZSxBQUNmO2FBQUEsQUFBSyxZQUFZLElBTjZDLEFBTTlELEFBQWlCLEFBQUksQUFDckI7YUFBQSxBQUFLLGFBQWEsSUFQNEMsQUFPOUQsQUFBa0IsQUFBSSxBQUN0QjthQUFBLEFBQUssMEJBQTBCLE9BQU8sS0FSd0IsQUFROUQsQUFBc0MsQUFBSyxBQUMzQzthQUFBLEFBQUssU0FUeUQsQUFTOUQsQUFBYyxBQUNkO2FBQUEsQUFBSyxvQkFWeUQsQUFVOUQsQUFBeUIsQUFFekI7O2lCQUFBLEFBQVMsWUFBWSxLQUFBLEFBQUssVUFaOUIsQUFBa0UsQUFZOUQsQUFBb0M7OztpQkFiL0I7OzJCQWdCTixXQUFXLFVBQVUsQUFDcEI7aUJBQUEsQUFBSyxVQUFMLEFBQWUsSUFBZixBQUFtQixXQURDLEFBQ3BCLEFBQThCOzs7OzRCQUc5QixXQUFXLFVBQVUsQUFDckI7bUJBQU8sS0FBQSxBQUFLLFVBQUwsQUFBZSxPQUFmLEFBQXNCLFdBRFIsQUFDckIsQUFBTyxBQUFpQzs7OztpQ0FHbkMsV0FBVyxBQUNoQjttQkFBTyxLQUFBLEFBQUssVUFBTCxBQUFlLFlBRE4sQUFDaEIsQUFBTyxBQUEyQjs7OztpQ0FHN0IsQUFDTDttQkFBTyxLQUFBLEFBQUssVUFEUCxBQUNMLEFBQU8sQUFBZTs7Ozt3Q0FHVjtnQkFBWSw2REFBTyxlQUEwQjtnQkFBdEIsaUVBQVcsc0JBQVcsQUFDekQ7O2dCQUFJLGFBRHFELEFBQ3JELEFBQWE7O0FBRHdDLGdCQUd6RCxBQUFJLFVBQVUsQUFDVjs2QkFBZ0IsS0FBQSxBQUFLLGtDQURYLEFBQ1YsQUFBa0QsQUFDbEQ7cUJBQUEsQUFBSyxXQUFMLEFBQWdCLElBQWhCLEFBQW9CLFlBRnhCLEFBQWMsQUFFVixBQUFnQyxBQUlwQzs7O2dCQUFJLEFBR0E7OztxQkFBQSxBQUFLLElBQUwsQUFBUyxZQUFZLENBQUEsQUFBQyxZQUFELEFBQWEsT0FIdEMsQUFBSSxBQUdBLEFBQXFCLEFBQW9CO3FCQUUzQyxBQUFPLEdBQUcsQUFDUjtvQkFBQSxBQUFJLFVBQVUsQUFDVjttQ0FBQSxBQUFlLEtBQWYsQUFBb0IsTUFBcEIsQUFBMEIsWUFEOUIsQUFBYyxBQUNWLEFBQXNDO3VCQUNuQyxBQUdIOzs7eUJBQUEsQUFBSyxTQUFMLEFBQWMsT0FOcEIsQUFDRSxBQUVPLEFBR0gsQUFBcUI7O2FBTjNCOzs7O3VDQVdTLFVBQVUsQUFDckI7bUJBQU8sS0FBQSxBQUFLLFdBQUwsQUFBZ0IsY0FERixBQUNyQixBQUFPLEFBQThCOzs7O21EQUdkO3dCQUN2Qjs7aUJBQUEsQUFBSyxXQUFMLEFBQWdCLHFCQUFXLEFBQUM7dUJBQ2pCLGVBQUEsQUFBZSxLQUQxQixBQUEyQixBQUFTLEFBQ2hDLEFBQU8sQUFBb0IsUUFESyxBQUNoQzthQUR1QixFQUEzQixBQUVHLGtCQUFRLEFBQUMsS0FBUSxBQUNoQjtzQkFBQSxBQUFLLFdBQUwsQUFBZ0IsT0FKVyxBQUMvQixBQUVXLEFBQVMsQUFDaEIsQUFBdUI7YUFEaEIsRUFIb0I7Ozs7NkNBUWQsQUFDakI7bUJBQU8sS0FBQSxBQUFLLFdBREssQUFDakIsQUFBTyxBQUFnQjs7OztpQ0FHbEIsV0FBVzt5QkFDaEI7O2lCQUFBLEFBQUssVUFBTCxBQUFlLElBQWYsQUFBbUIsV0FBbkIsQUFBOEIsa0JBQVEsQUFBQyxVQUFhLEFBRWhEOztvQkFBSSxjQUFBLEFBQWM7NkJBQWxCLEFBQWlDLEFBQzdCLEFBQVMsT0FEb0IsQUFDN0I7dUJBQ0csQUFDSDsyQ0FBaUIsQUFDYjs0QkFBSSxPQUFBLEFBQUssVUFBTCxBQUFlLElBQWYsQUFBbUIsV0FBbkIsQUFBOEIsU0FBOUIsQUFBdUM7cUNBRHBDLEFBQ1AsQUFBOEMsQUFDMUMsQUFBUyxPQURpQyxBQUMxQzs7cUJBRkcsRUFOSSxBQUN2QixBQUFzQyxBQUVsQyxBQUVPLEFBQ0gsQUFJRzs7YUFUMkIsRUFEZjs7OztzQ0FlYixZQUFZLFlBQVksS0FBSzs7Z0JBRW5DLFdBQVcsS0FBQSxBQUFLLFdBQUwsQUFBZ0IsSUFGZ0IsQUFFM0MsQUFBVyxBQUFvQjs7OztBQUZZLEFBRS9DLGdCQUlJLENBQUEsQUFBQztvQkFDRyxPQUFPLGVBQUEsQUFBZTt5QkFDdEIsQUFBSyxRQUFMLEFBQWEsT0FEakIsQUFBOEIsQUFDMUIsQUFBb0IsQUFFeEIsS0FIOEIsQUFDMUI7O0FBRlIsQUFBZSxBQU9mLHVCQVBlLEFBQ1g7OzsyQkFNSixBQUFlLEtBQWYsQUFBb0IsTUFBcEIsQUFBMEIsWUFBMUIsQUFBc0MsS0FiUyxBQWEvQyxBQUEyQzs7OzttQ0FJcEMsS0FBSztpQkFDWixBQUFLLFNBRGEsQUFDbEIsQUFBYyxBQUNkLEtBRmtCLEFBQ2xCO2dCQUNJLEtBQUEsQUFBSyxtQkFBbUIsQUFDeEI7cUJBQUEsQUFBSyxrQkFBTCxBQUF1QixLQURDLEFBQ3hCLEFBQTRCLEFBQzVCO3VCQUFPLEtBRlgsQUFBNEIsQUFFakIsQUFBSzs7Ozs7Ozs7a0NBS1YsQUFDTjttQkFBTyxFQUFDLE9BQU8sS0FBQSxBQUFLLFFBQVEsUUFBUSxLQUQ5QixBQUNOLEFBQW9DLEFBQUs7Ozs7Z0NBRXJDLFVBQVUsV0FBVyxBQUN6QjtpQkFBQSxBQUFLLFNBQVMsY0FBQSxBQUFjLFVBQVUsS0FEYixBQUN6QixBQUFzQyxBQUFLLEFBQzNDO2lCQUFBLEFBQUssVUFBVSxjQUFBLEFBQWMsV0FBVyxLQUZmLEFBRXpCLEFBQXdDLEFBQUssQUFDN0M7aUJBQUEsQUFBSyxJQUFMLEFBQVMsYUFBVCxBQUFzQixTQUFTLEtBSE4sQUFHekIsQUFBK0IsQUFBSyxBQUNwQztpQkFBQSxBQUFLLElBQUwsQUFBUyxhQUFULEFBQXNCLFVBQVUsS0FKUCxBQUl6QixBQUFnQyxBQUFLOzs7OzttQkFHOUIsS0FEQSxBQUNBLEFBQUssT0FETCxBQUNQOzs7O2lDQUVLLFVBQVUsQUFDZjtpQkFBQSxBQUFLLFFBQUwsQUFBYSxVQUFVLEtBRFIsQUFDZixBQUF1QixBQUFLOzs7OzttQkFHckIsS0FEQyxBQUNELEFBQUssUUFESixBQUNSOzs7O2tDQUVNLFdBQVcsQUFDakI7aUJBQUEsQUFBSyxRQUFRLEtBQUEsQUFBSyxRQURELEFBQ2pCLEFBQTBCOzs7OzttQkFHbkIsS0FERSxBQUNGLEFBQUssU0FESCxBQUNUOzs7OzttQkFHTyxLQURHLEFBQ0gsQUFBSyxVQURGLEFBQ1Y7Ozs7O21CQUdPLEtBREQsQUFDQyxBQUFLLE9BRE4sQUFDTjs7Ozs7aUJBRU0sQUFDTixBQUFLLEFBQ0wsU0FGTSxBQUNOO2lCQURNLEFBRU4sQUFBSyxBQUNMO3FCQUFBLEFBQVMsbUJBQW1CLEtBSHRCLEFBR04sQUFBNEIsQUFBSyxBQUNqQztnQkFBSSxLQUFBLEFBQUssSUFBTCxBQUFTLGVBQWUsQUFDeEI7cUJBQUEsQUFBSyxJQUFMLEFBQVMsY0FBVCxBQUF1QixZQUFZLEtBRHZDLEFBQTRCLEFBQ3hCLEFBQW1DLEFBQUs7OztRQXBKaEQ7O1dBRFM7OztBQTBKYixTQUFBLEFBQVMsZUFBVCxBQUF3QixZQUF4QixBQUFvQyxLQUFwQyxBQUF5QztpQkFDckM7OzJCQUFpQixBQUNiO1lBQUksV0FBVyxPQUFBLEFBQUssV0FBTCxBQUFnQixJQURsQixBQUNULEFBQVcsQUFBb0IsQUFDbkM7WUFBQSxBQUFJLFVBQVUsQUFDVjttQkFBQSxBQUFLLFdBQUwsQUFBZ0IsT0FETixBQUNWLEFBQXVCLEFBQ3ZCO3FCQUFBLEFBQVMsS0FKTixBQUVQLEFBQWMsQUFFVixBQUFjOztLQUpYLEVBRGYsQUFBaUQsQUFDN0MsQUFNRyxHQVAwQzs7O0FBVWpELE9BQUEsQUFBTyxlQUFQLEFBQXNCLGVBQXRCLEFBQXFDLHVCQUF1QixBQUN4RDtjQUFBLEFBQVUsQUFDVjtrQkFBQSxBQUFjLEFBQ2Q7V0FISixBQUdJLEFBQU87Ozs7Ozs7Ozs7Ozs7QUFhWCxPQUFBLEFBQU8saUNBQXVCLEFBQUMsU0FBRCxBQUFVLFFBQVYsQUFBa0IsVUFBbEIsQUFBNEIsWUFBNUIsQUFBd0MsT0FBeEMsQUFBK0M7UUFDckUsV0FBVyxTQUFBLEFBQVMsZ0JBRDBELEFBQzlFLEFBQVcsQUFBeUIsQUFDeEMsU0FGa0YsQUFDbEY7UUFDSSxDQUFBLEFBQUMsVUFBTCxBQUFlLEFBQ2Y7UUFBSSxhQUFBLEFBQWEsYUFBYSxBQUMxQjtpQkFBQSxBQUFTLFdBQVQsQUFBb0IsT0FEeEIsQUFBOEIsQUFDMUIsQUFBMkI7V0FDeEIsQUFDSDtZQUFJLFdBQUEsQUFBVyxTQUFTLEFBQ3BCO3FCQUFBLEFBQVMsY0FBVCxBQUF1QixVQUF2QixBQUFpQyxZQUFqQyxBQUE2QyxPQURqRCxBQUF3QixBQUNwQixBQUFvRDtlQUNqRCxBQUNIO3FCQUFBLEFBQVMsU0FBVCxBQUFrQixVQVRBLEFBRzFCLEFBR0ksQUFFTyxBQUNILEFBQTRCOzs7Q0FUVjs7O0FDL0w5Qjs7QUFFQSxJQUFJLHNCQUFzQixRQUFBLEFBQVEsY0FBUixBQUFzQjtBQUNoRCxJQUFJLFlBQVksSUFBWixBQUFZLEFBQUk7O0FBRXBCLElBQU0sd0JBQUEsQUFBd0I7QUFDOUIsT0FBQSxBQUFPLGVBQVAsQUFBc0IsdUJBQXRCLEFBQTZDLGVBQWUsQUFDeEQ7Y0FBQSxBQUFVLEFBQ1Y7a0JBQUEsQUFBYyxBQUNkOzBCQUFPLEFBQVUsSUFBVixBQUFjO2tCQUNqQixBQUFVLElBQVYsQUFBYyxJQUp0QixBQUdXLEFBQXdCLEFBQzNCLEFBQWtCLFVBRFMsQUFDM0I7S0FERzs7O0FBS1gsT0FBQSxBQUFPLGVBQVAsQUFBc0IsdUJBQXRCLEFBQTZDLG1CQUFtQixBQUM1RDtjQUFBLEFBQVUsQUFDVjtrQkFBQSxBQUFjLEFBQ2Q7MEJBQU8sQUFBVSxJQUFJLEFBQ2pCO2VBQU8sVUFBQSxBQUFVLElBSnpCLEFBR1csQUFBYyxBQUNqQixBQUFPLEFBQWM7S0FEbEI7OztBQUtYLE9BQUEsQUFBTyxlQUFQLEFBQXNCLHVCQUF0QixBQUE2QyxzQkFBc0IsQUFDL0Q7Y0FBQSxBQUFVLEFBQ1Y7a0JBQUEsQUFBYyxBQUNkOzBCQUFPLEFBQVUsSUFBSSxBQUNqQjtlQUFPLFVBQUEsQUFBVSxPQUp6QixBQUdXLEFBQWMsQUFDakIsQUFBTyxBQUFpQjtLQURyQjs7O0FBS1gsT0FBQSxBQUFPLFVBQVAsQUFBaUI7OztBQzlCakI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFFYTthQUFBLEFBQ1Q7OEJBRFMsQUFDTSxBQUNYOzthQUFBLEFBQUssY0FEVCxBQUFlLEFBQ1gsQUFBbUIsR0FEUjs7O2lCQUROOzs0QkFJSixJQUFJLE9BQU8sQUFDWjtnQkFBSSxDQUFDLEtBQUEsQUFBSyxZQUFOLEFBQUMsQUFBaUIsS0FBSyxBQUN2QjtxQkFBQSxBQUFLLFlBQUwsQUFBaUIsTUFEckIsQUFBMkIsQUFDdkIsQUFBdUIsQUFFM0I7O2dCQUFJLEtBQUEsQUFBSyxZQUFMLEFBQWlCLElBQWpCLEFBQXFCLFFBQXJCLEFBQTZCLFdBQVcsQ0FBQSxBQUFDO3FCQUN6QyxBQUFLLFlBQUwsQUFBaUIsSUFBakIsQUFBcUIsS0FEekIsQUFBZ0QsQUFDNUMsQUFBMEIsT0FEa0IsQUFDNUM7Ozs7OzRCQUdILElBQUksQUFDTDttQkFBTyxLQUFBLEFBQUssWUFBTCxBQUFpQixPQURuQixBQUNFLEFBQXdCOzs7O21DQUV2QixTQUFTLEFBQ2pCO21CQUFPLE9BQUEsQUFBTyxLQUFLLEtBQVosQUFBWSxBQUFLLGFBQWpCLEFBQThCLE9BRHBCLEFBQ2pCLEFBQU8sQUFBcUM7Ozs7b0NBRW5DO3dCQUNUOzt1QkFBVyxPQUFBLEFBQU8sS0FBSyxLQUFaLEFBQVksQUFBSyxhQUFqQixBQUE4QixpQkFBTyxBQUFDO3VCQUN0QyxNQUFBLEFBQUssWUFBTCxBQUFpQixLQUFqQixBQUFzQixRQUF0QixBQUE4QixXQUFXLENBRnBDLEFBQ1osQUFBNEMsQUFBUyxBQUNMLEFBQUMsQUFHckQsRUFKeUQsQUFDckQ7YUFENEMsQ0FBNUMsQ0FEWTs7bUJBQUEsQUFLaEIsQUFBTzs7OzsrQkFFSixLQUFLLE9BQU8sQUFDZjtnQkFBSSxDQUFDLEtBQUEsQUFBSyxZQUFOLEFBQUMsQUFBaUI7QUFBdEIsQUFBNEIsQUFFNUIsdUJBRjRCLEFBQUU7OztnQkFFMUIsUUFBUSxLQUFBLEFBQUssWUFBTCxBQUFpQixLQUFqQixBQUFzQixRQUhuQixBQUdYLEFBQVEsQUFBOEIsQUFFMUM7O2dCQUFJLFFBQUEsQUFBUTtBQUFaLEFBQWUsQUFDZix1QkFEZSxBQUFFOzttQkFDVixLQUFBLEFBQUssWUFBTCxBQUFpQixLQUFqQixBQUFzQixPQUF0QixBQUE2QixPQU5yQixBQU1mLEFBQU8sQUFBb0M7Ozs7b0NBRWxDO2dCQUNMLE1BQU0sS0FBQSxBQUFLLFlBREYsQUFDVCxBQUFNLEFBQWlCLEFBQzNCO21CQUFPLEtBQUEsQUFBSyxZQUZDLEFBRWIsQUFBTyxBQUFpQixBQUN4QjttQkFIYSxBQUdiLEFBQU8sSUFITSxBQUNiOzs7O3NDQUlXO3lCQUNYOztnQkFBSSxPQUFPLEtBQUEsQUFBSyxZQURFLEFBQ2QsQUFBTyxBQUFpQixBQUM1QjttQkFBTyxLQUFBLEFBQUssY0FBSSxBQUFDLEtBQVEsQUFDckI7dUJBQU8sT0FBQSxBQUFLLE9BQUwsQUFBWSxLQUhMLEFBRWxCLEFBQWdCLEFBQVMsQUFDckIsQUFBTyxBQUFpQjthQURaLEVBRkU7Ozs7O2dCQU9kLE1BQU0sS0FERixBQUNFLEFBQUssQUFDZjtpQkFBQSxBQUFLLGNBRkcsQUFFUixBQUFtQixBQUNuQjttQkFIUSxBQUdSLEFBQU8sSUFIQyxBQUNSOzs7OytCQUlHLEFBQ0g7bUJBQU8sT0FBQSxBQUFPLEtBQUssS0FBWixBQUFZLEFBQUssYUFEckIsQUFDSSxBQUE4Qjs7UUFqRHpDOztXQURTOzs7SUFzREE7YUFBQSxBQUNUOzhCQURTLEFBQ00sQUFDWDs7YUFBQSxBQUFLLGNBRFQsQUFBZSxBQUNYLEFBQW1CLEdBRFI7OztpQkFETjs7NEJBSUosSUFBSSxPQUFPLEFBQ1o7aUJBQUEsQUFBSyxZQUFMLEFBQWlCLE1BREwsQUFDWixBQUF1Qjs7Ozs0QkFFdEIsSUFBSSxBQUNMO21CQUFPLEtBQUEsQUFBSyxZQURQLEFBQ0wsQUFBTyxBQUFpQjs7OzttQ0FFaEIsU0FBUyxBQUNqQjttQkFBTyxPQUFBLEFBQU8sS0FBSyxLQUFaLEFBQVksQUFBSyxhQUFqQixBQUE4QixPQURwQixBQUNqQixBQUFPLEFBQXFDOzs7O29DQUVuQzt5QkFDVDs7dUJBQVcsT0FBQSxBQUFPLEtBQUssS0FBWixBQUFZLEFBQUssYUFBakIsQUFBOEIsaUJBQU8sQUFBQzt1QkFDdEMsT0FBQSxBQUFLLFlBQUwsQUFBaUIsU0FGWixBQUNaLEFBQTRDLEFBQVMsQUFDOUMsQUFBMEIsQUFHckMsTUFKeUQsQUFDckQ7YUFENEMsQ0FBNUMsQ0FEWTs7bUJBQUEsQUFLaEIsQUFBTzs7OzsrQkFFSDtnQkFDQSxNQUFNLEtBQUEsQUFBSyxZQURQLEFBQ0osQUFBTSxBQUFpQixBQUMzQjttQkFBTyxLQUFBLEFBQUssWUFGSixBQUVSLEFBQU8sQUFBaUIsQUFDeEI7bUJBSFEsQUFHUixBQUFPLElBSEMsQUFDUjs7OztzQ0FJVzt5QkFDWDs7Z0JBQUksT0FBTyxLQUFBLEFBQUssWUFERSxBQUNkLEFBQU8sQUFBaUIsQUFDNUI7bUJBQU8sS0FBQSxBQUFLLGNBQUksQUFBQzt1QkFDTixPQUFBLEFBQUssT0FIRSxBQUVsQixBQUFnQixBQUFTLEFBQ3JCLEFBQU8sQUFBWSxLQURFLEFBQ3JCO2FBRFksRUFGRTs7Ozs7Z0JBT2QsTUFBTSxLQURGLEFBQ0UsQUFBSyxBQUNmO2lCQUFBLEFBQUssY0FGRyxBQUVSLEFBQW1CLEFBQ25CO21CQUhRLEFBR1IsQUFBTyxJQUhDLEFBQ1I7Ozs7K0JBSUcsQUFDSDttQkFBTyxPQUFBLEFBQU8sS0FBSyxLQUFaLEFBQVksQUFBSyxhQURyQixBQUNJLEFBQThCOztRQXBDekM7O1dBRFM7Ozs7QUN4RGI7Ozs7O1FBRWdCO1FBT0E7UUFJQTtRQWdCQTtRQVVBO1FBaUJBO1FBSUE7QUExRFQsU0FBQSxBQUFTLE9BQVQsQUFBZ0I7UUFDZixRQUFRLENBRGUsQUFDZixBQUFDLEFBQ2I7d0JBQVksQUFDUjtlQUFVLGVBQVUsRUFIckIsQUFBd0IsQUFFcEIsQUFBSyxBQUNZLEFBQUU7S0FEbkIsQ0FGb0IsQUFDM0I7OztBQU1HLFNBQUEsQUFBUyxPQUFULEFBQWdCOztBQUloQixTQUFBLEFBQVMsZ0JBQVQsQUFBeUIsT0FBekIsQUFBZ0MsV0FBaEMsQUFBMkM7O1FBRTFDOztvQkFBMkIsQUFFM0IsQUFBWSxBQUNaO0FBSHFCLEFBQU0sb0JBQUEsQUFFM0I7S0FGcUIsRUFGZ0MsQUFFckQsQUFBVSxBQUtYLEFBRUgsS0FQYzs7dUJBT0ssQUFDZjtxQkFEZSxBQUNmLEFBQWEsQUFDYjtrQkFBQSxBQUFVLE1BQVYsQUFBZ0IsTUFYakIsQUFBc0QsQUFTbEQsQUFBWSxBQUVmLEFBQXNCO0tBRm5CLENBVGtELEFBRXpEOzs7QUFjRyxTQUFBLEFBQVMsb0JBQVQsQUFBNkIsUUFBN0IsQUFBcUM7UUFBSSxxRUFBZSxrQkFBTyxBQUNsRTs7UUFBSSxNQUFNLFNBQUEsQUFBUyxjQUQrQyxBQUM5RCxBQUFNLEFBQXVCLEFBQ2pDO1FBQUEsQUFBSSxLQUY4RCxBQUVsRSxBQUFTLEFBQ1Q7UUFBQSxBQUFJLGNBQWMsQUFDZDtlQUFBLEFBQU8sWUFEWCxBQUFrQixBQUNkLEFBQW1CLEFBRXZCOztXQUFBLEFBQU8sWUFOMkQsQUFNbEUsQUFBbUIsQUFDbkI7V0FQRyxBQUErRCxBQU9sRSxBQUFPLElBUDJEOzs7QUFVL0QsU0FBQSxBQUFTLGNBQVQsQUFBdUIsUUFBdkIsQUFBK0IsUUFBUSxBQUMxQztXQUFPLENBQUMsTUFBTSxXQUFQLEFBQUMsQUFBTSxBQUFXLFlBQVksU0FBOUIsQUFBOEIsQUFBUyxXQUFXLFNBQUEsQUFBUyxJQUEzRCxBQUErRCxTQURuRSxBQUF1QyxBQUNuQyxBQUF3RTs7O0FBR25GO1FBQ1EsT0FBQSxBQUFPLFVBQVAsQUFBaUIsVUFBVSxPQUFPLE9BQUEsQUFBTyxVQUE3QyxBQUFzQyxBQUFpQixBQUN2RDtvQkFBTyxBQUFTLFNBQVQsQUFBbUIsY0FBbkIsQUFBaUM7WUFDaEMsZ0JBQWdCLEtBRDBCLEFBQzFDLEFBQWdCLEFBQUssQUFDekI7WUFBSSxhQUFBLEFBQWEsYUFBYSxXQUFXLGNBQUEsQUFBYzt1QkFDeEMsY0FEZixBQUErRCxBQUNoRCxBQUFjLEFBRTdCLE9BSCtELEFBQzNEOztvQkFFUSxhQUxrQyxBQUtsQyxBQUFhLEFBQ3pCLE9BTjhDLEFBQzlDO1lBS0ksWUFBWSxjQUFBLEFBQWMsUUFBZCxBQUFzQixjQU5RLEFBTTFDLEFBQVksQUFBb0MsQUFDcEQ7ZUFBTyxjQUFjLENBQUEsQUFBQyxLQUFLLGNBVC9CLEFBQVksQUFBWSxBQUVqQixBQUEyQyxBQU9uQixBQUFjO0tBUHRDLENBRmlCLEFBQ3hCO0NBRFcsRUFBWDs7QUFhRyxTQUFBLEFBQVMsZUFBVCxBQUF3QixRQUF4QixBQUFnQyxRQUFRLEFBQzNDO1dBQU8sU0FBQSxBQUFTLEtBQVQsQUFBYyxRQURsQixBQUF3QyxBQUMzQyxBQUFPLEFBQXNCOzs7QUFHMUIsU0FBQSxBQUFTLFlBQVQsQUFBcUIsSUFBSSxBQUU1Qjs7T0FBQSxBQUFHLE1BQUgsQUFBUyxXQUZtQixBQUU1QixBQUFvQixBQUNwQjtPQUFBLEFBQUcsTUFBSCxBQUFTLE9BSG1CLEFBRzVCLEFBQWdCLEFBQ2hCO09BQUEsQUFBRyxNQUFILEFBQVMsTUFKbUIsQUFJNUIsQUFBZSxBQUNmO09BQUEsQUFBRyxNQUFILEFBQVMsUUFMbUIsQUFLNUIsQUFBaUIsQUFDakI7T0FBQSxBQUFHLE1BQUgsQUFBUyxTQU5OLEFBQXlCLEFBTTVCLEFBQWtCOzs7O0FDbEV0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3UkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4T0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzd6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdFNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JXQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdExBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2VkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6WUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0VUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiJ3VzZSBzdHJpY3QnO1xuXG4vL3NpbXBsZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgQVBJXG5leHBvcnQgY2xhc3MgSVZQQUlEQWRVbml0IHtcblxuICAgIC8vYWxsIG1ldGhvZHMgYmVsb3dcbiAgICAvL2FyZSBhc3luYyBtZXRob2RzXG4gICAgaGFuZHNoYWtlVmVyc2lvbihwbGF5ZXJWUEFJRFZlcnNpb24gPSAnMi4wJywgY2FsbGJhY2sgPSB1bmRlZmluZWQpIHt9XG5cbiAgICAvL2NyZWF0aXZlRGF0YSBpcyBhbiBvYmplY3QgdG8gYmUgY29uc2lzdGVudCB3aXRoIFZQQUlESFRNTFxuICAgIGluaXRBZCAod2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGRlc2lyZWRCaXRyYXRlLCBjcmVhdGl2ZURhdGEgPSB7QWRQYXJhbWV0ZXJzOicnfSwgZW52aXJvbm1lbnRWYXJzID0ge2ZsYXNoVmFyczogJyd9LCBjYWxsYmFjayA9IHVuZGVmaW5lZCkge31cbiAgICByZXNpemVBZCh3aWR0aCwgaGVpZ2h0LCB2aWV3TW9kZSwgY2FsbGJhY2sgPSB1bmRlZmluZWQpIHt9XG5cbiAgICBzdGFydEFkKGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7fVxuICAgIHN0b3BBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge31cbiAgICBwYXVzZUFkKGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7fVxuICAgIHJlc3VtZUFkKGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7fVxuICAgIGV4cGFuZEFkKGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7fVxuICAgIGNvbGxhcHNlQWQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHt9XG4gICAgc2tpcEFkKGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7fVxuXG4gICAgLy9wcm9wZXJ0aWVzIHRoYXQgd2lsbCBiZSB0cmVhdCBhcyBhc3luYyBtZXRob2RzXG4gICAgZ2V0QWRMaW5lYXIoY2FsbGJhY2spIHt9XG4gICAgZ2V0QWRXaWR0aChjYWxsYmFjaykge31cbiAgICBnZXRBZEhlaWdodChjYWxsYmFjaykge31cbiAgICBnZXRBZEV4cGFuZGVkKGNhbGxiYWNrKSB7fVxuICAgIGdldEFkU2tpcHBhYmxlU3RhdGUoY2FsbGJhY2spIHt9XG4gICAgZ2V0QWRSZW1haW5pbmdUaW1lKGNhbGxiYWNrKSB7fVxuICAgIGdldEFkRHVyYXRpb24oY2FsbGJhY2spIHt9XG4gICAgc2V0QWRWb2x1bWUoc291bmRWb2x1bWUsIGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7fVxuICAgIGdldEFkVm9sdW1lKGNhbGxiYWNrKSB7fVxuICAgIGdldEFkQ29tcGFuaW9ucyhjYWxsYmFjaykge31cbiAgICBnZXRBZEljb25zKGNhbGxiYWNrKSB7fVxufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoSVZQQUlEQWRVbml0LCAnRVZFTlRTJywge1xuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgIHZhbHVlOiBbXG4gICAgICAgICdBZExvYWRlZCcsXG4gICAgICAgICdBZFN0YXJ0ZWQnLFxuICAgICAgICAnQWRTdG9wcGVkJyxcbiAgICAgICAgJ0FkU2tpcHBlZCcsXG4gICAgICAgICdBZFNraXBwYWJsZVN0YXRlQ2hhbmdlJywgLy8gVlBBSUQgMi4wIG5ldyBldmVudFxuICAgICAgICAnQWRTaXplQ2hhbmdlJywgLy8gVlBBSUQgMi4wIG5ldyBldmVudFxuICAgICAgICAnQWRMaW5lYXJDaGFuZ2UnLFxuICAgICAgICAnQWREdXJhdGlvbkNoYW5nZScsIC8vIFZQQUlEIDIuMCBuZXcgZXZlbnRcbiAgICAgICAgJ0FkRXhwYW5kZWRDaGFuZ2UnLFxuICAgICAgICAnQWRSZW1haW5pbmdUaW1lQ2hhbmdlJywgLy8gW0RlcHJlY2F0ZWQgaW4gMi4wXSBidXQgd2lsbCBiZSBzdGlsbCBmaXJlZCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHlcbiAgICAgICAgJ0FkVm9sdW1lQ2hhbmdlJyxcbiAgICAgICAgJ0FkSW1wcmVzc2lvbicsXG4gICAgICAgICdBZFZpZGVvU3RhcnQnLFxuICAgICAgICAnQWRWaWRlb0ZpcnN0UXVhcnRpbGUnLFxuICAgICAgICAnQWRWaWRlb01pZHBvaW50JyxcbiAgICAgICAgJ0FkVmlkZW9UaGlyZFF1YXJ0aWxlJyxcbiAgICAgICAgJ0FkVmlkZW9Db21wbGV0ZScsXG4gICAgICAgICdBZENsaWNrVGhydScsXG4gICAgICAgICdBZEludGVyYWN0aW9uJywgLy8gVlBBSUQgMi4wIG5ldyBldmVudFxuICAgICAgICAnQWRVc2VyQWNjZXB0SW52aXRhdGlvbicsXG4gICAgICAgICdBZFVzZXJNaW5pbWl6ZScsXG4gICAgICAgICdBZFVzZXJDbG9zZScsXG4gICAgICAgICdBZFBhdXNlZCcsXG4gICAgICAgICdBZFBsYXlpbmcnLFxuICAgICAgICAnQWRMb2cnLFxuICAgICAgICAnQWRFcnJvcidcbiAgICBdXG59KTtcblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgSVZQQUlEQWRVbml0ID0gcmVxdWlyZSgnLi9JVlBBSURBZFVuaXQnKS5JVlBBSURBZFVuaXQ7XG5sZXQgQUxMX1ZQQUlEX01FVEhPRFMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhJVlBBSURBZFVuaXQucHJvdG90eXBlKS5maWx0ZXIoZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gICAgcmV0dXJuIFsnY29uc3RydWN0b3InXS5pbmRleE9mKHByb3BlcnR5KSA9PT0gLTE7XG59KTtcblxuZXhwb3J0IGNsYXNzIFZQQUlEQWRVbml0IGV4dGVuZHMgSVZQQUlEQWRVbml0IHtcbiAgICBjb25zdHJ1Y3RvciAoZmxhc2gpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5fZGVzdHJveWVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX2ZsYXNoID0gZmxhc2g7XG4gICAgfVxuXG4gICAgX2Rlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuX2Rlc3Ryb3llZCA9IHRydWU7XG4gICAgICAgIEFMTF9WUEFJRF9NRVRIT0RTLmZvckVhY2goKG1ldGhvZE5hbWUpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2ZsYXNoLnJlbW92ZUNhbGxiYWNrQnlNZXRob2ROYW1lKG1ldGhvZE5hbWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgSVZQQUlEQWRVbml0LkVWRU5UUy5mb3JFYWNoKChldmVudCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fZmxhc2gub2ZmRXZlbnQoZXZlbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLl9mbGFzaCA9IG51bGw7XG4gICAgfVxuXG4gICAgaXNEZXN0cm95ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVzdHJveWVkO1xuICAgIH1cblxuICAgIG9uKGV2ZW50TmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fZmxhc2gub24oZXZlbnROYW1lLCBjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgb2ZmKGV2ZW50TmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fZmxhc2gub2ZmKGV2ZW50TmFtZSwgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIC8vVlBBSUQgaW50ZXJmYWNlXG4gICAgaGFuZHNoYWtlVmVyc2lvbihwbGF5ZXJWUEFJRFZlcnNpb24gPSAnMi4wJywgY2FsbGJhY2sgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdoYW5kc2hha2VWZXJzaW9uJywgW3BsYXllclZQQUlEVmVyc2lvbl0sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgaW5pdEFkICh3aWR0aCwgaGVpZ2h0LCB2aWV3TW9kZSwgZGVzaXJlZEJpdHJhdGUsIGNyZWF0aXZlRGF0YSA9IHtBZFBhcmFtZXRlcnM6ICcnfSwgZW52aXJvbm1lbnRWYXJzID0ge2ZsYXNoVmFyczogJyd9LCBjYWxsYmFjayA9IHVuZGVmaW5lZCkge1xuICAgICAgICAvL3Jlc2l6ZSBlbGVtZW50IHRoYXQgaGFzIHRoZSBmbGFzaCBvYmplY3RcbiAgICAgICAgdGhpcy5fZmxhc2guc2V0U2l6ZSh3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgY3JlYXRpdmVEYXRhID0gY3JlYXRpdmVEYXRhIHx8IHtBZFBhcmFtZXRlcnM6ICcnfTtcbiAgICAgICAgZW52aXJvbm1lbnRWYXJzID0gZW52aXJvbm1lbnRWYXJzIHx8IHtmbGFzaFZhcnM6ICcnfTtcblxuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2luaXRBZCcsIFt0aGlzLl9mbGFzaC5nZXRXaWR0aCgpLCB0aGlzLl9mbGFzaC5nZXRIZWlnaHQoKSwgdmlld01vZGUsIGRlc2lyZWRCaXRyYXRlLCBjcmVhdGl2ZURhdGEuQWRQYXJhbWV0ZXJzIHx8ICcnLCBlbnZpcm9ubWVudFZhcnMuZmxhc2hWYXJzIHx8ICcnXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICByZXNpemVBZCh3aWR0aCwgaGVpZ2h0LCB2aWV3TW9kZSwgY2FsbGJhY2sgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy9yZXNpemUgZWxlbWVudCB0aGF0IGhhcyB0aGUgZmxhc2ggb2JqZWN0XG4gICAgICAgIHRoaXMuX2ZsYXNoLnNldFNpemUod2lkdGgsIGhlaWdodCk7XG5cbiAgICAgICAgLy9yZXNpemUgYWQgaW5zaWRlIHRoZSBmbGFzaFxuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ3Jlc2l6ZUFkJywgW3RoaXMuX2ZsYXNoLmdldFdpZHRoKCksIHRoaXMuX2ZsYXNoLmdldEhlaWdodCgpLCB2aWV3TW9kZV0sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgc3RhcnRBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ3N0YXJ0QWQnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBzdG9wQWQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdzdG9wQWQnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBwYXVzZUFkKGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgncGF1c2VBZCcsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIHJlc3VtZUFkKGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgncmVzdW1lQWQnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBleHBhbmRBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2V4cGFuZEFkJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgY29sbGFwc2VBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2NvbGxhcHNlQWQnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBza2lwQWQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdza2lwQWQnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIC8vcHJvcGVydGllcyB0aGF0IHdpbGwgYmUgdHJlYXQgYXMgYXN5bmMgbWV0aG9kc1xuICAgIGdldEFkTGluZWFyKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnZ2V0QWRMaW5lYXInLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBnZXRBZFdpZHRoKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnZ2V0QWRXaWR0aCcsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGdldEFkSGVpZ2h0KGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnZ2V0QWRIZWlnaHQnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBnZXRBZEV4cGFuZGVkKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnZ2V0QWRFeHBhbmRlZCcsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGdldEFkU2tpcHBhYmxlU3RhdGUoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdnZXRBZFNraXBwYWJsZVN0YXRlJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgZ2V0QWRSZW1haW5pbmdUaW1lKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnZ2V0QWRSZW1haW5pbmdUaW1lJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgZ2V0QWREdXJhdGlvbihjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2dldEFkRHVyYXRpb24nLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBzZXRBZFZvbHVtZSh2b2x1bWUsIGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnc2V0QWRWb2x1bWUnLCBbdm9sdW1lXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBnZXRBZFZvbHVtZShjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2dldEFkVm9sdW1lJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgZ2V0QWRDb21wYW5pb25zKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnZ2V0QWRDb21wYW5pb25zJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgZ2V0QWRJY29ucyhjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2dldEFkSWNvbnMnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbn1cblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBzd2ZvYmplY3QgPSByZXF1aXJlKCdzd2ZvYmplY3QnKTtcblxuY29uc3QgSlNGbGFzaEJyaWRnZSA9IHJlcXVpcmUoJy4vanNGbGFzaEJyaWRnZScpLkpTRmxhc2hCcmlkZ2U7XG5jb25zdCBWUEFJREFkVW5pdCA9IHJlcXVpcmUoJy4vVlBBSURBZFVuaXQnKS5WUEFJREFkVW5pdDtcblxuY29uc3Qgbm9vcCA9IHJlcXVpcmUoJy4vdXRpbHMnKS5ub29wO1xuY29uc3QgY2FsbGJhY2tUaW1lb3V0ID0gcmVxdWlyZSgnLi91dGlscycpLmNhbGxiYWNrVGltZW91dDtcbmNvbnN0IGlzUG9zaXRpdmVJbnQgPSByZXF1aXJlKCcuL3V0aWxzJykuaXNQb3NpdGl2ZUludDtcbmNvbnN0IGNyZWF0ZUVsZW1lbnRXaXRoSUQgPSByZXF1aXJlKCcuL3V0aWxzJykuY3JlYXRlRWxlbWVudFdpdGhJRDtcbmNvbnN0IHVuaXF1ZVZQQUlEID0gcmVxdWlyZSgnLi91dGlscycpLnVuaXF1ZSgndnBhaWQnKTtcbmNvbnN0IGNyZWF0ZUZsYXNoVGVzdGVyID0gcmVxdWlyZSgnLi9mbGFzaFRlc3Rlci5qcycpLmNyZWF0ZUZsYXNoVGVzdGVyO1xuXG5jb25zdCBFUlJPUiA9ICdlcnJvcic7XG5jb25zdCBGTEFTSF9WRVJTSU9OID0gJzEwLjEuMCc7XG5cbmxldCBmbGFzaFRlc3RlciA9IHtpc1N1cHBvcnRlZDogKCk9PiB0cnVlfTsgLy8gaWYgdGhlIHJ1bkZsYXNoVGVzdCBpcyBub3QgcnVuIHRoZSBmbGFzaFRlc3RlciB3aWxsIGFsd2F5cyByZXR1cm4gdHJ1ZVxuXG5jbGFzcyBWUEFJREZMQVNIQ2xpZW50IHtcbiAgICBjb25zdHJ1Y3RvciAodnBhaWRQYXJlbnRFbCwgY2FsbGJhY2ssIHN3ZkNvbmZpZyA9IHtkYXRhOiAnVlBBSURGbGFzaC5zd2YnLCB3aWR0aDogODAwLCBoZWlnaHQ6IDQwMH0sIHBhcmFtcyA9IHsgd21vZGU6ICd0cmFuc3BhcmVudCcsIHNhbGlnbjogJ3RsJywgYWxpZ246ICdsZWZ0JywgYWxsb3dTY3JpcHRBY2Nlc3M6ICdhbHdheXMnLCBzY2FsZTogJ25vU2NhbGUnLCBhbGxvd0Z1bGxTY3JlZW46ICd0cnVlJywgcXVhbGl0eTogJ2hpZ2gnfSwgdnBhaWRPcHRpb25zID0geyBkZWJ1ZzogZmFsc2UsIHRpbWVvdXQ6IDEwMDAwIH0pIHtcblxuICAgICAgICB2YXIgbWUgPSB0aGlzO1xuXG4gICAgICAgIHRoaXMuX3ZwYWlkUGFyZW50RWwgPSB2cGFpZFBhcmVudEVsO1xuICAgICAgICB0aGlzLl9mbGFzaElEID0gdW5pcXVlVlBBSUQoKTtcbiAgICAgICAgdGhpcy5fZGVzdHJveWVkID0gZmFsc2U7XG4gICAgICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgfHwgbm9vcDtcblxuICAgICAgICBzd2ZDb25maWcud2lkdGggPSBpc1Bvc2l0aXZlSW50KHN3ZkNvbmZpZy53aWR0aCwgODAwKTtcbiAgICAgICAgc3dmQ29uZmlnLmhlaWdodCA9IGlzUG9zaXRpdmVJbnQoc3dmQ29uZmlnLmhlaWdodCwgNDAwKTtcblxuICAgICAgICBjcmVhdGVFbGVtZW50V2l0aElEKHZwYWlkUGFyZW50RWwsIHRoaXMuX2ZsYXNoSUQsIHRydWUpO1xuXG4gICAgICAgIHBhcmFtcy5tb3ZpZSA9IHN3ZkNvbmZpZy5kYXRhO1xuICAgICAgICBwYXJhbXMuRmxhc2hWYXJzID0gYGZsYXNoaWQ9JHt0aGlzLl9mbGFzaElEfSZoYW5kbGVyPSR7SlNGbGFzaEJyaWRnZS5WUEFJRF9GTEFTSF9IQU5ETEVSfSZkZWJ1Zz0ke3ZwYWlkT3B0aW9ucy5kZWJ1Z30mc2FsaWduPSR7cGFyYW1zLnNhbGlnbn1gO1xuXG4gICAgICAgIGlmICghVlBBSURGTEFTSENsaWVudC5pc1N1cHBvcnRlZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gb25FcnJvcigndXNlciBkb25cXCd0IHN1cHBvcnQgZmxhc2ggb3IgZG9lc25cXCd0IGhhdmUgdGhlIG1pbmltdW0gcmVxdWlyZWQgdmVyc2lvbiBvZiBmbGFzaCAnICsgRkxBU0hfVkVSU0lPTik7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmVsID0gc3dmb2JqZWN0LmNyZWF0ZVNXRihzd2ZDb25maWcsIHBhcmFtcywgdGhpcy5fZmxhc2hJRCk7XG5cbiAgICAgICAgaWYgKCF0aGlzLmVsKSB7XG4gICAgICAgICAgICByZXR1cm4gb25FcnJvciggJ3N3Zm9iamVjdCBmYWlsZWQgdG8gY3JlYXRlIG9iamVjdCBpbiBlbGVtZW50JyApO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGhhbmRsZXIgPSBjYWxsYmFja1RpbWVvdXQodnBhaWRPcHRpb25zLnRpbWVvdXQsXG4gICAgICAgICAgICAoZXJyLCBkYXRhKSA9PiB7XG4gICAgICAgICAgICAgICAgJGxvYWRQZW5kZWRBZFVuaXQuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnIsIGRhdGEpO1xuICAgICAgICAgICAgfSwgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCd2cGFpZCBmbGFzaCBsb2FkIHRpbWVvdXQgJyArIHZwYWlkT3B0aW9ucy50aW1lb3V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLl9mbGFzaCA9IG5ldyBKU0ZsYXNoQnJpZGdlKHRoaXMuZWwsIHN3ZkNvbmZpZy5kYXRhLCB0aGlzLl9mbGFzaElELCBzd2ZDb25maWcud2lkdGgsIHN3ZkNvbmZpZy5oZWlnaHQsIGhhbmRsZXIpO1xuXG4gICAgICAgIGZ1bmN0aW9uIG9uRXJyb3IoZXJyb3IpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKG5ldyBFcnJvcihlcnJvcikpO1xuICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgICAgICByZXR1cm4gbWU7XG4gICAgICAgIH1cblxuICAgIH1cblxuICAgIGRlc3Ryb3kgKCkge1xuICAgICAgICB0aGlzLl9kZXN0cm95QWRVbml0KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuX2ZsYXNoKSB7XG4gICAgICAgICAgICB0aGlzLl9mbGFzaC5kZXN0cm95KCk7XG4gICAgICAgICAgICB0aGlzLl9mbGFzaCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lbCA9IG51bGw7XG4gICAgICAgIHRoaXMuX2Rlc3Ryb3llZCA9IHRydWU7XG4gICAgfVxuXG4gICAgaXNEZXN0cm95ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVzdHJveWVkO1xuICAgIH1cblxuICAgIF9kZXN0cm95QWRVbml0KCkge1xuICAgICAgICBkZWxldGUgdGhpcy5fbG9hZExhdGVyO1xuXG4gICAgICAgIGlmICh0aGlzLl9hZFVuaXRMb2FkKSB7XG4gICAgICAgICAgICB0aGlzLl9hZFVuaXRMb2FkID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX2ZsYXNoLnJlbW92ZUNhbGxiYWNrKHRoaXMuX2FkVW5pdExvYWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuX2FkVW5pdCkge1xuICAgICAgICAgICAgdGhpcy5fYWRVbml0Ll9kZXN0cm95KCk7XG4gICAgICAgICAgICB0aGlzLl9hZFVuaXQgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbG9hZEFkVW5pdChhZFVSTCwgY2FsbGJhY2spIHtcbiAgICAgICAgJHRocm93SWZEZXN0cm95ZWQuY2FsbCh0aGlzKTtcblxuICAgICAgICBpZiAodGhpcy5fYWRVbml0KSB7XG4gICAgICAgICAgICB0aGlzLl9kZXN0cm95QWRVbml0KCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fZmxhc2guaXNSZWFkeSgpKSB7XG4gICAgICAgICAgICB0aGlzLl9hZFVuaXRMb2FkID0gKGVyciwgbWVzc2FnZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2FkVW5pdCA9IG5ldyBWUEFJREFkVW5pdCh0aGlzLl9mbGFzaCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX2FkVW5pdExvYWQgPSBudWxsO1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVyciwgdGhpcy5fYWRVbml0KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnbG9hZEFkVW5pdCcsIFthZFVSTF0sIHRoaXMuX2FkVW5pdExvYWQpO1xuICAgICAgICB9ZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9sb2FkTGF0ZXIgPSB7dXJsOiBhZFVSTCwgY2FsbGJhY2t9O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdW5sb2FkQWRVbml0KGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgICR0aHJvd0lmRGVzdHJveWVkLmNhbGwodGhpcyk7XG5cbiAgICAgICAgdGhpcy5fZGVzdHJveUFkVW5pdCgpO1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ3VubG9hZEFkVW5pdCcsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGdldEZsYXNoSUQoKSB7XG4gICAgICAgICR0aHJvd0lmRGVzdHJveWVkLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzLl9mbGFzaC5nZXRGbGFzaElEKCk7XG4gICAgfVxuICAgIGdldEZsYXNoVVJMKCkge1xuICAgICAgICAkdGhyb3dJZkRlc3Ryb3llZC5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdGhpcy5fZmxhc2guZ2V0Rmxhc2hVUkwoKTtcbiAgICB9XG59XG5cbnNldFN0YXRpY1Byb3BlcnR5KCdpc1N1cHBvcnRlZCcsICgpID0+IHtcbiAgICByZXR1cm4gc3dmb2JqZWN0Lmhhc0ZsYXNoUGxheWVyVmVyc2lvbihGTEFTSF9WRVJTSU9OKSAmJiBmbGFzaFRlc3Rlci5pc1N1cHBvcnRlZCgpO1xufSwgdHJ1ZSk7XG5cbnNldFN0YXRpY1Byb3BlcnR5KCdydW5GbGFzaFRlc3QnLCAoc3dmQ29uZmlnKSA9PiB7XG4gICAgZmxhc2hUZXN0ZXIgPSBjcmVhdGVGbGFzaFRlc3Rlcihkb2N1bWVudC5ib2R5LCBzd2ZDb25maWcpO1xufSk7XG5cbmZ1bmN0aW9uICR0aHJvd0lmRGVzdHJveWVkKCkge1xuICAgIGlmKHRoaXMuX2Rlc3Ryb3llZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1ZQQUlERmxhc2hUb0pTIGlzIGRlc3Ryb3llZCEnKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uICRsb2FkUGVuZGVkQWRVbml0KCkge1xuICAgIGlmICh0aGlzLl9sb2FkTGF0ZXIpIHtcbiAgICAgICAgdGhpcy5sb2FkQWRVbml0KHRoaXMuX2xvYWRMYXRlci51cmwsIHRoaXMuX2xvYWRMYXRlci5jYWxsYmFjayk7XG4gICAgICAgIGRlbGV0ZSB0aGlzLl9sb2FkTGF0ZXI7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBzZXRTdGF0aWNQcm9wZXJ0eShwcm9wZXJ0eU5hbWUsIHZhbHVlLCB3cml0YWJsZSA9IGZhbHNlKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFZQQUlERkxBU0hDbGllbnQsIHByb3BlcnR5TmFtZSwge1xuICAgICAgICB3cml0YWJsZTogd3JpdGFibGUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgIH0pO1xufVxuXG5WUEFJREZMQVNIQ2xpZW50LnN3Zm9iamVjdCA9IHN3Zm9iamVjdDtcblxubW9kdWxlLmV4cG9ydHMgPSBWUEFJREZMQVNIQ2xpZW50O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBzd2ZvYmplY3QgPSByZXF1aXJlKCdzd2ZvYmplY3QnKTtcblxuY29uc3QgRkxBU0hfVEVTVCA9ICd2cGFpZF92aWRlb19mbGFzaF90ZXN0ZXInO1xuY29uc3QgRkxBU0hfVEVTVF9FTCA9ICd2cGFpZF92aWRlb19mbGFzaF90ZXN0ZXJfZWwnO1xuY29uc3QgSlNGbGFzaEJyaWRnZSA9IHJlcXVpcmUoJy4vanNGbGFzaEJyaWRnZScpLkpTRmxhc2hCcmlkZ2U7XG5jb25zdCB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbmNvbnN0IE11bHRpcGxlVmFsdWVzUmVnaXN0cnkgPSByZXF1aXJlKCcuL3JlZ2lzdHJ5JykuTXVsdGlwbGVWYWx1ZXNSZWdpc3RyeTtcblxuY2xhc3MgRmxhc2hUZXN0ZXIge1xuICAgIGNvbnN0cnVjdG9yKHBhcmVudCwgc3dmQ29uZmlnID0ge2RhdGE6ICdWUEFJREZsYXNoLnN3ZicsIHdpZHRoOiA4MDAsIGhlaWdodDogNDAwfSkge1xuICAgICAgICB0aGlzLnBhcmVudEVsID0gdXRpbHMuY3JlYXRlRWxlbWVudFdpdGhJRChwYXJlbnQsIEZMQVNIX1RFU1RfRUwpOyAvLyBzb21lIGJyb3dzZXJzIGNyZWF0ZSBnbG9iYWwgdmFyaWFibGVzIHVzaW5nIHRoZSBlbGVtZW50IGlkIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzQzNDI3OC9kby1kb20tdHJlZS1lbGVtZW50cy13aXRoLWlkcy1iZWNvbWUtZ2xvYmFsLXZhcmlhYmxlc1xuICAgICAgICB1dGlscy5oaWRlRmxhc2hFbCh0aGlzLnBhcmVudEVsKTtcbiAgICAgICAgdmFyIHBhcmFtcyA9IHt9O1xuICAgICAgICBwYXJhbXMubW92aWUgPSBzd2ZDb25maWcuZGF0YTtcbiAgICAgICAgcGFyYW1zLkZsYXNoVmFycyA9IGBmbGFzaGlkPSR7RkxBU0hfVEVTVF9FTH0maGFuZGxlcj0ke0pTRmxhc2hCcmlkZ2UuVlBBSURfRkxBU0hfSEFORExFUn1gO1xuXG4gICAgICAgIHRoaXMuZWwgPSBzd2ZvYmplY3QuY3JlYXRlU1dGKHN3ZkNvbmZpZywgcGFyYW1zLCBGTEFTSF9URVNUX0VMKTtcbiAgICAgICAgdGhpcy5faGFuZGxlcnMgPSBuZXcgTXVsdGlwbGVWYWx1ZXNSZWdpc3RyeSgpO1xuICAgICAgICB0aGlzLl9pc1N1cHBvcnRlZCA9IGZhbHNlO1xuICAgICAgICBpZiAodGhpcy5lbCkge1xuICAgICAgICAgICAgdXRpbHMuaGlkZUZsYXNoRWwodGhpcy5lbCk7XG4gICAgICAgICAgICB0aGlzLl9mbGFzaCA9IG5ldyBKU0ZsYXNoQnJpZGdlKHRoaXMuZWwsIHN3ZkNvbmZpZy5kYXRhLCBGTEFTSF9URVNUX0VMLCA0MDAsIDQwMCwgKCk9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3VwcG9ydCA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5faXNTdXBwb3J0ZWQgPSBzdXBwb3J0O1xuICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZXJzLmdldCgnY2hhbmdlJykuZm9yRWFjaCgoY2FsbGJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKT0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKCdjaGFuZ2UnLCBzdXBwb3J0KTtcbiAgICAgICAgICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpc1N1cHBvcnRlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzU3VwcG9ydGVkO1xuICAgIH1cbiAgICBvbihldmVudE5hbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2hhbmRsZXJzLmFkZChldmVudE5hbWUsIGNhbGxiYWNrKTtcbiAgICB9XG59XG5cbmV4cG9ydCB2YXIgY3JlYXRlRmxhc2hUZXN0ZXIgPSBmdW5jdGlvbiBjcmVhdGVGbGFzaFRlc3RlcihlbCwgc3dmQ29uZmlnKSB7XG4gICAgaWYgKCF3aW5kb3dbRkxBU0hfVEVTVF0pIHtcbiAgICAgICAgd2luZG93W0ZMQVNIX1RFU1RdID0gbmV3IEZsYXNoVGVzdGVyKGVsLCBzd2ZDb25maWcpO1xuICAgIH1cbiAgICByZXR1cm4gd2luZG93W0ZMQVNIX1RFU1RdO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxubGV0IHVuaXF1ZSA9IHJlcXVpcmUoJy4vdXRpbHMnKS51bmlxdWU7XG5sZXQgaXNQb3NpdGl2ZUludCA9IHJlcXVpcmUoJy4vdXRpbHMnKS5pc1Bvc2l0aXZlSW50O1xubGV0IHN0cmluZ0VuZHNXaXRoID0gcmVxdWlyZSgnLi91dGlscycpLnN0cmluZ0VuZHNXaXRoO1xubGV0IFNpbmdsZVZhbHVlUmVnaXN0cnkgPSByZXF1aXJlKCcuL3JlZ2lzdHJ5JykuU2luZ2xlVmFsdWVSZWdpc3RyeTtcbmxldCBNdWx0aXBsZVZhbHVlc1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9yZWdpc3RyeScpLk11bHRpcGxlVmFsdWVzUmVnaXN0cnk7XG5jb25zdCByZWdpc3RyeSA9IHJlcXVpcmUoJy4vanNGbGFzaEJyaWRnZVJlZ2lzdHJ5Jyk7XG5jb25zdCBWUEFJRF9GTEFTSF9IQU5ETEVSID0gJ3ZwYWlkX3ZpZGVvX2ZsYXNoX2hhbmRsZXInO1xuY29uc3QgRVJST1IgPSAnQWRFcnJvcic7XG5cbmV4cG9ydCBjbGFzcyBKU0ZsYXNoQnJpZGdlIHtcbiAgICBjb25zdHJ1Y3RvciAoZWwsIGZsYXNoVVJMLCBmbGFzaElELCB3aWR0aCwgaGVpZ2h0LCBsb2FkSGFuZFNoYWtlKSB7XG4gICAgICAgIHRoaXMuX2VsID0gZWw7XG4gICAgICAgIHRoaXMuX2ZsYXNoSUQgPSBmbGFzaElEO1xuICAgICAgICB0aGlzLl9mbGFzaFVSTCA9IGZsYXNoVVJMO1xuICAgICAgICB0aGlzLl93aWR0aCA9IHdpZHRoO1xuICAgICAgICB0aGlzLl9oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAgIHRoaXMuX2hhbmRsZXJzID0gbmV3IE11bHRpcGxlVmFsdWVzUmVnaXN0cnkoKTtcbiAgICAgICAgdGhpcy5fY2FsbGJhY2tzID0gbmV3IFNpbmdsZVZhbHVlUmVnaXN0cnkoKTtcbiAgICAgICAgdGhpcy5fdW5pcXVlTWV0aG9kSWRlbnRpZmllciA9IHVuaXF1ZSh0aGlzLl9mbGFzaElEKTtcbiAgICAgICAgdGhpcy5fcmVhZHkgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5faGFuZFNoYWtlSGFuZGxlciA9IGxvYWRIYW5kU2hha2U7XG5cbiAgICAgICAgcmVnaXN0cnkuYWRkSW5zdGFuY2UodGhpcy5fZmxhc2hJRCwgdGhpcyk7XG4gICAgfVxuXG4gICAgb24oZXZlbnROYW1lLCBjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9oYW5kbGVycy5hZGQoZXZlbnROYW1lLCBjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgb2ZmKGV2ZW50TmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZXJzLnJlbW92ZShldmVudE5hbWUsIGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICBvZmZFdmVudChldmVudE5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZXJzLnJlbW92ZUJ5S2V5KGV2ZW50TmFtZSk7XG4gICAgfVxuXG4gICAgb2ZmQWxsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faGFuZGxlcnMucmVtb3ZlQWxsKCk7XG4gICAgfVxuXG4gICAgY2FsbEZsYXNoTWV0aG9kKG1ldGhvZE5hbWUsIGFyZ3MgPSBbXSwgY2FsbGJhY2sgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFyIGNhbGxiYWNrSUQgPSAnJztcbiAgICAgICAgLy8gaWYgbm8gY2FsbGJhY2ssIHNvbWUgbWV0aG9kcyB0aGUgcmV0dXJuIGlzIHZvaWQgc28gdGhleSBkb24ndCBuZWVkIGNhbGxiYWNrXG4gICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgY2FsbGJhY2tJRCA9IGAke3RoaXMuX3VuaXF1ZU1ldGhvZElkZW50aWZpZXIoKX1fJHttZXRob2ROYW1lfWA7XG4gICAgICAgICAgICB0aGlzLl9jYWxsYmFja3MuYWRkKGNhbGxiYWNrSUQsIGNhbGxiYWNrKTtcbiAgICAgICAgfVxuXG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vbWV0aG9kcyBhcmUgY3JlYXRlZCBieSBFeHRlcm5hbEludGVyZmFjZS5hZGRDYWxsYmFjayBpbiBhczMgY29kZSwgaWYgZm9yIHNvbWUgcmVhc29uIGl0IGZhaWxlZFxuICAgICAgICAgICAgLy90aGlzIGNvZGUgd2lsbCB0aHJvdyBhbiBlcnJvclxuICAgICAgICAgICAgdGhpcy5fZWxbbWV0aG9kTmFtZV0oW2NhbGxiYWNrSURdLmNvbmNhdChhcmdzKSk7XG5cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgJGFzeW5jQ2FsbGJhY2suY2FsbCh0aGlzLCBjYWxsYmFja0lELCBlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAvL2lmIHRoZXJlIGlzbid0IGFueSBjYWxsYmFjayB0byByZXR1cm4gZXJyb3IgdXNlIGVycm9yIGV2ZW50IGhhbmRsZXJcbiAgICAgICAgICAgICAgICB0aGlzLl90cmlnZ2VyKEVSUk9SLCBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlbW92ZUNhbGxiYWNrKGNhbGxiYWNrKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYWxsYmFja3MucmVtb3ZlQnlWYWx1ZShjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgcmVtb3ZlQ2FsbGJhY2tCeU1ldGhvZE5hbWUoc3VmZml4KSB7XG4gICAgICAgIHRoaXMuX2NhbGxiYWNrcy5maWx0ZXJLZXlzKChrZXkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBzdHJpbmdFbmRzV2l0aChrZXksIHN1ZmZpeCk7XG4gICAgICAgIH0pLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fY2FsbGJhY2tzLnJlbW92ZShrZXkpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZW1vdmVBbGxDYWxsYmFja3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYWxsYmFja3MucmVtb3ZlQWxsKCk7XG4gICAgfVxuXG4gICAgX3RyaWdnZXIoZXZlbnROYW1lLCBldmVudCkge1xuICAgICAgICB0aGlzLl9oYW5kbGVycy5nZXQoZXZlbnROYW1lKS5mb3JFYWNoKChjYWxsYmFjaykgPT4ge1xuICAgICAgICAgICAgLy9jbGlja1RocnUgaGFzIHRvIGJlIHN5bmMsIGlmIG5vdCB3aWxsIGJlIGJsb2NrIGJ5IHRoZSBwb3B1cGJsb2NrZXJcbiAgICAgICAgICAgIGlmIChldmVudE5hbWUgPT09ICdBZENsaWNrVGhydScpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5faGFuZGxlcnMuZ2V0KGV2ZW50TmFtZSkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIF9jYWxsQ2FsbGJhY2sobWV0aG9kTmFtZSwgY2FsbGJhY2tJRCwgZXJyLCByZXN1bHQpIHtcblxuICAgICAgICBsZXQgY2FsbGJhY2sgPSB0aGlzLl9jYWxsYmFja3MuZ2V0KGNhbGxiYWNrSUQpO1xuXG4gICAgICAgIC8vbm90IGFsbCBtZXRob2RzIGNhbGxiYWNrJ3MgYXJlIG1hbmRhdG9yeVxuICAgICAgICAvL2J1dCBpZiB0aGVyZSBleGlzdCBhbiBlcnJvciwgZmlyZSB0aGUgZXJyb3IgZXZlbnRcbiAgICAgICAgaWYgKCFjYWxsYmFjaykge1xuICAgICAgICAgICAgaWYgKGVyciAmJiBjYWxsYmFja0lEID09PSAnJykge1xuICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcihFUlJPUiwgZXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgICRhc3luY0NhbGxiYWNrLmNhbGwodGhpcywgY2FsbGJhY2tJRCwgZXJyLCByZXN1bHQpO1xuXG4gICAgfVxuXG4gICAgX2hhbmRTaGFrZShlcnIsIGRhdGEpIHtcbiAgICAgICAgdGhpcy5fcmVhZHkgPSB0cnVlO1xuICAgICAgICBpZiAodGhpcy5faGFuZFNoYWtlSGFuZGxlcikge1xuICAgICAgICAgICAgdGhpcy5faGFuZFNoYWtlSGFuZGxlcihlcnIsIGRhdGEpO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2hhbmRTaGFrZUhhbmRsZXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvL21ldGhvZHMgbGlrZSBwcm9wZXJ0aWVzIHNwZWNpZmljIHRvIHRoaXMgaW1wbGVtZW50YXRpb24gb2YgVlBBSURcbiAgICBnZXRTaXplKCkge1xuICAgICAgICByZXR1cm4ge3dpZHRoOiB0aGlzLl93aWR0aCwgaGVpZ2h0OiB0aGlzLl9oZWlnaHR9O1xuICAgIH1cbiAgICBzZXRTaXplKG5ld1dpZHRoLCBuZXdIZWlnaHQpIHtcbiAgICAgICAgdGhpcy5fd2lkdGggPSBpc1Bvc2l0aXZlSW50KG5ld1dpZHRoLCB0aGlzLl93aWR0aCk7XG4gICAgICAgIHRoaXMuX2hlaWdodCA9IGlzUG9zaXRpdmVJbnQobmV3SGVpZ2h0LCB0aGlzLl9oZWlnaHQpO1xuICAgICAgICB0aGlzLl9lbC5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgdGhpcy5fd2lkdGgpO1xuICAgICAgICB0aGlzLl9lbC5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIHRoaXMuX2hlaWdodCk7XG4gICAgfVxuICAgIGdldFdpZHRoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fd2lkdGg7XG4gICAgfVxuICAgIHNldFdpZHRoKG5ld1dpZHRoKSB7XG4gICAgICAgIHRoaXMuc2V0U2l6ZShuZXdXaWR0aCwgdGhpcy5faGVpZ2h0KTtcbiAgICB9XG4gICAgZ2V0SGVpZ2h0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faGVpZ2h0O1xuICAgIH1cbiAgICBzZXRIZWlnaHQobmV3SGVpZ2h0KSB7XG4gICAgICAgIHRoaXMuc2V0U2l6ZSh0aGlzLl93aWR0aCwgbmV3SGVpZ2h0KTtcbiAgICB9XG4gICAgZ2V0Rmxhc2hJRCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZsYXNoSUQ7XG4gICAgfVxuICAgIGdldEZsYXNoVVJMKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmxhc2hVUkw7XG4gICAgfVxuICAgIGlzUmVhZHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZWFkeTtcbiAgICB9XG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5vZmZBbGwoKTtcbiAgICAgICAgdGhpcy5yZW1vdmVBbGxDYWxsYmFja3MoKTtcbiAgICAgICAgcmVnaXN0cnkucmVtb3ZlSW5zdGFuY2VCeUlEKHRoaXMuX2ZsYXNoSUQpO1xuICAgICAgICBpZiAodGhpcy5fZWwucGFyZW50RWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5fZWwucGFyZW50RWxlbWVudC5yZW1vdmVDaGlsZCh0aGlzLl9lbCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uICRhc3luY0NhbGxiYWNrKGNhbGxiYWNrSUQsIGVyciwgcmVzdWx0KSB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGxldCBjYWxsYmFjayA9IHRoaXMuX2NhbGxiYWNrcy5nZXQoY2FsbGJhY2tJRCk7XG4gICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgdGhpcy5fY2FsbGJhY2tzLnJlbW92ZShjYWxsYmFja0lEKTtcbiAgICAgICAgICAgIGNhbGxiYWNrKGVyciwgcmVzdWx0KTtcbiAgICAgICAgfVxuICAgIH0sIDApO1xufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoSlNGbGFzaEJyaWRnZSwgJ1ZQQUlEX0ZMQVNIX0hBTkRMRVInLCB7XG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgdmFsdWU6IFZQQUlEX0ZMQVNIX0hBTkRMRVJcbn0pO1xuXG4vKipcbiAqIEV4dGVybmFsIGludGVyZmFjZSBoYW5kbGVyXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGZsYXNoSUQgaWRlbnRpZmllciBvZiB0aGUgZmxhc2ggd2hvIGNhbGwgdGhpc1xuICogQHBhcmFtIHtzdHJpbmd9IHR5cGVJRCB3aGF0IHR5cGUgb2YgbWVzc2FnZSBpcywgY2FuIGJlICdldmVudCcgb3IgJ2NhbGxiYWNrJ1xuICogQHBhcmFtIHtzdHJpbmd9IHR5cGVOYW1lIGlmIHRoZSB0eXBlSUQgaXMgYSBldmVudCB0aGUgdHlwZU5hbWUgd2lsbCBiZSB0aGUgZXZlbnROYW1lLCBpZiBpcyBhIGNhbGxiYWNrIHRoZSB0eXBlSUQgaXMgdGhlIG1ldGhvZE5hbWUgdGhhdCBpcyByZWxhdGVkIHRoaXMgY2FsbGJhY2tcbiAqIEBwYXJhbSB7c3RyaW5nfSBjYWxsYmFja0lEIG9ubHkgYXBwbGllcyB3aGVuIHRoZSB0eXBlSUQgaXMgJ2NhbGxiYWNrJywgaWRlbnRpZmllciBvZiB0aGUgY2FsbGJhY2sgdG8gY2FsbFxuICogQHBhcmFtIHtvYmplY3R9IGVycm9yIGVycm9yIG9iamVjdFxuICogQHBhcmFtIHtvYmplY3R9IGRhdGFcbiAqL1xud2luZG93W1ZQQUlEX0ZMQVNIX0hBTkRMRVJdID0gKGZsYXNoSUQsIHR5cGVJRCwgdHlwZU5hbWUsIGNhbGxiYWNrSUQsIGVycm9yLCBkYXRhKSA9PiB7XG4gICAgbGV0IGluc3RhbmNlID0gcmVnaXN0cnkuZ2V0SW5zdGFuY2VCeUlEKGZsYXNoSUQpO1xuICAgIGlmICghaW5zdGFuY2UpIHJldHVybjtcbiAgICBpZiAodHlwZU5hbWUgPT09ICdoYW5kU2hha2UnKSB7XG4gICAgICAgIGluc3RhbmNlLl9oYW5kU2hha2UoZXJyb3IsIGRhdGEpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0eXBlSUQgIT09ICdldmVudCcpIHtcbiAgICAgICAgICAgIGluc3RhbmNlLl9jYWxsQ2FsbGJhY2sodHlwZU5hbWUsIGNhbGxiYWNrSUQsIGVycm9yLCBkYXRhKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGluc3RhbmNlLl90cmlnZ2VyKHR5cGVOYW1lLCBkYXRhKTtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cbiIsIid1c2Ugc3RyaWN0JztcblxubGV0IFNpbmdsZVZhbHVlUmVnaXN0cnkgPSByZXF1aXJlKCcuL3JlZ2lzdHJ5JykuU2luZ2xlVmFsdWVSZWdpc3RyeTtcbmxldCBpbnN0YW5jZXMgPSBuZXcgU2luZ2xlVmFsdWVSZWdpc3RyeSgpO1xuXG5jb25zdCBKU0ZsYXNoQnJpZGdlUmVnaXN0cnkgPSB7fTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShKU0ZsYXNoQnJpZGdlUmVnaXN0cnksICdhZGRJbnN0YW5jZScsIHtcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICB2YWx1ZTogZnVuY3Rpb24gKGlkLCBpbnN0YW5jZSkge1xuICAgICAgICBpbnN0YW5jZXMuYWRkKGlkLCBpbnN0YW5jZSk7XG4gICAgfVxufSk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShKU0ZsYXNoQnJpZGdlUmVnaXN0cnksICdnZXRJbnN0YW5jZUJ5SUQnLCB7XG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIChpZCkge1xuICAgICAgICByZXR1cm4gaW5zdGFuY2VzLmdldChpZCk7XG4gICAgfVxufSk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShKU0ZsYXNoQnJpZGdlUmVnaXN0cnksICdyZW1vdmVJbnN0YW5jZUJ5SUQnLCB7XG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIChpZCkge1xuICAgICAgICByZXR1cm4gaW5zdGFuY2VzLnJlbW92ZShpZCk7XG4gICAgfVxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gSlNGbGFzaEJyaWRnZVJlZ2lzdHJ5O1xuXG4iLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydCBjbGFzcyBNdWx0aXBsZVZhbHVlc1JlZ2lzdHJ5IHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHRoaXMuX3JlZ2lzdHJpZXMgPSB7fTtcbiAgICB9XG4gICAgYWRkIChpZCwgdmFsdWUpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9yZWdpc3RyaWVzW2lkXSkge1xuICAgICAgICAgICAgdGhpcy5fcmVnaXN0cmllc1tpZF0gPSBbXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fcmVnaXN0cmllc1tpZF0uaW5kZXhPZih2YWx1ZSkgPT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLl9yZWdpc3RyaWVzW2lkXS5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgKGlkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZWdpc3RyaWVzW2lkXSB8fCBbXTtcbiAgICB9XG4gICAgZmlsdGVyS2V5cyAoaGFuZGxlcikge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5fcmVnaXN0cmllcykuZmlsdGVyKGhhbmRsZXIpO1xuICAgIH1cbiAgICBmaW5kQnlWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh0aGlzLl9yZWdpc3RyaWVzKS5maWx0ZXIoKGtleSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3JlZ2lzdHJpZXNba2V5XS5pbmRleE9mKHZhbHVlKSAhPT0gLTE7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBrZXlzO1xuICAgIH1cbiAgICByZW1vdmUoa2V5LCB2YWx1ZSkge1xuICAgICAgICBpZiAoIXRoaXMuX3JlZ2lzdHJpZXNba2V5XSkgeyByZXR1cm47IH1cblxuICAgICAgICB2YXIgaW5kZXggPSB0aGlzLl9yZWdpc3RyaWVzW2tleV0uaW5kZXhPZih2YWx1ZSk7XG5cbiAgICAgICAgaWYgKGluZGV4IDwgMCkgeyByZXR1cm47IH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlZ2lzdHJpZXNba2V5XS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH1cbiAgICByZW1vdmVCeUtleSAoaWQpIHtcbiAgICAgICAgbGV0IG9sZCA9IHRoaXMuX3JlZ2lzdHJpZXNbaWRdO1xuICAgICAgICBkZWxldGUgdGhpcy5fcmVnaXN0cmllc1tpZF07XG4gICAgICAgIHJldHVybiBvbGQ7XG4gICAgfVxuICAgIHJlbW92ZUJ5VmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIGxldCBrZXlzID0gdGhpcy5maW5kQnlWYWx1ZSh2YWx1ZSk7XG4gICAgICAgIHJldHVybiBrZXlzLm1hcCgoa2V5KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5yZW1vdmUoa2V5LCB2YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZW1vdmVBbGwoKSB7XG4gICAgICAgIGxldCBvbGQgPSB0aGlzLl9yZWdpc3RyaWVzO1xuICAgICAgICB0aGlzLl9yZWdpc3RyaWVzID0ge307XG4gICAgICAgIHJldHVybiBvbGQ7XG4gICAgfVxuICAgIHNpemUoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLl9yZWdpc3RyaWVzKS5sZW5ndGg7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgU2luZ2xlVmFsdWVSZWdpc3RyeSB7XG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICB0aGlzLl9yZWdpc3RyaWVzID0ge307XG4gICAgfVxuICAgIGFkZCAoaWQsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX3JlZ2lzdHJpZXNbaWRdID0gdmFsdWU7XG4gICAgfVxuICAgIGdldCAoaWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlZ2lzdHJpZXNbaWRdO1xuICAgIH1cbiAgICBmaWx0ZXJLZXlzIChoYW5kbGVyKSB7XG4gICAgICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLl9yZWdpc3RyaWVzKS5maWx0ZXIoaGFuZGxlcik7XG4gICAgfVxuICAgIGZpbmRCeVZhbHVlICh2YWx1ZSkge1xuICAgICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHRoaXMuX3JlZ2lzdHJpZXMpLmZpbHRlcigoa2V5KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVnaXN0cmllc1trZXldID09PSB2YWx1ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIGtleXM7XG4gICAgfVxuICAgIHJlbW92ZSAoaWQpIHtcbiAgICAgICAgbGV0IG9sZCA9IHRoaXMuX3JlZ2lzdHJpZXNbaWRdO1xuICAgICAgICBkZWxldGUgdGhpcy5fcmVnaXN0cmllc1tpZF07XG4gICAgICAgIHJldHVybiBvbGQ7XG4gICAgfVxuICAgIHJlbW92ZUJ5VmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIGxldCBrZXlzID0gdGhpcy5maW5kQnlWYWx1ZSh2YWx1ZSk7XG4gICAgICAgIHJldHVybiBrZXlzLm1hcCgoa2V5KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5yZW1vdmUoa2V5KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJlbW92ZUFsbCgpIHtcbiAgICAgICAgbGV0IG9sZCA9IHRoaXMuX3JlZ2lzdHJpZXM7XG4gICAgICAgIHRoaXMuX3JlZ2lzdHJpZXMgPSB7fTtcbiAgICAgICAgcmV0dXJuIG9sZDtcbiAgICB9XG4gICAgc2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuX3JlZ2lzdHJpZXMpLmxlbmd0aDtcbiAgICB9XG59XG5cbiIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0IGZ1bmN0aW9uIHVuaXF1ZShwcmVmaXgpIHtcbiAgICBsZXQgY291bnQgPSAtMTtcbiAgICByZXR1cm4gZiA9PiB7XG4gICAgICAgIHJldHVybiBgJHtwcmVmaXh9XyR7Kytjb3VudH1gO1xuICAgIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBub29wKCkge1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBjYWxsYmFja1RpbWVvdXQodGltZXIsIG9uU3VjY2Vzcywgb25UaW1lb3V0KSB7XG5cbiAgICBsZXQgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuXG4gICAgICAgIG9uU3VjY2VzcyA9IG5vb3A7XG4gICAgICAgIG9uVGltZW91dCgpO1xuXG4gICAgfSwgdGltZXIpO1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICBvblN1Y2Nlc3MuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVFbGVtZW50V2l0aElEKHBhcmVudCwgaWQsIGNsZWFuQ29udGVudCA9IGZhbHNlKSB7XG4gICAgdmFyIG5FbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIG5FbC5pZCA9IGlkO1xuICAgIGlmIChjbGVhbkNvbnRlbnQpIHtcbiAgICAgICAgcGFyZW50LmlubmVySFRNTCA9ICcnO1xuICAgIH1cbiAgICBwYXJlbnQuYXBwZW5kQ2hpbGQobkVsKTtcbiAgICByZXR1cm4gbkVsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNQb3NpdGl2ZUludChuZXdWYWwsIG9sZFZhbCkge1xuICAgIHJldHVybiAhaXNOYU4ocGFyc2VGbG9hdChuZXdWYWwpKSAmJiBpc0Zpbml0ZShuZXdWYWwpICYmIG5ld1ZhbCA+IDAgPyBuZXdWYWwgOiBvbGRWYWw7XG59XG5cbmxldCBlbmRzV2l0aCA9IChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKFN0cmluZy5wcm90b3R5cGUuZW5kc1dpdGgpIHJldHVybiBTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoO1xuICAgIHJldHVybiBmdW5jdGlvbiBlbmRzV2l0aCAoc2VhcmNoU3RyaW5nLCBwb3NpdGlvbikge1xuICAgICAgICB2YXIgc3ViamVjdFN0cmluZyA9IHRoaXMudG9TdHJpbmcoKTtcbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSB1bmRlZmluZWQgfHwgcG9zaXRpb24gPiBzdWJqZWN0U3RyaW5nLmxlbmd0aCkge1xuICAgICAgICAgICAgcG9zaXRpb24gPSBzdWJqZWN0U3RyaW5nLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBwb3NpdGlvbiAtPSBzZWFyY2hTdHJpbmcubGVuZ3RoO1xuICAgICAgICB2YXIgbGFzdEluZGV4ID0gc3ViamVjdFN0cmluZy5pbmRleE9mKHNlYXJjaFN0cmluZywgcG9zaXRpb24pO1xuICAgICAgICByZXR1cm4gbGFzdEluZGV4ICE9PSAtMSAmJiBsYXN0SW5kZXggPT09IHBvc2l0aW9uO1xuICAgIH07XG59KSgpO1xuXG5leHBvcnQgZnVuY3Rpb24gc3RyaW5nRW5kc1dpdGgoc3RyaW5nLCBzZWFyY2gpIHtcbiAgICByZXR1cm4gZW5kc1dpdGguY2FsbChzdHJpbmcsIHNlYXJjaCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoaWRlRmxhc2hFbChlbCkge1xuICAgIC8vIGNhbid0IHVzZSBkaXNwbGF5IG5vbmUgb3IgdmlzaWJpbGl0eSBub25lIGJlY2F1c2Ugd2lsbCBibG9jayBmbGFzaCBpbiBzb21lIGJyb3dzZXJzXG4gICAgZWwuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgIGVsLnN0eWxlLmxlZnQgPSAnLTFweCc7XG4gICAgZWwuc3R5bGUudG9wID0gJy0xcHgnO1xuICAgIGVsLnN0eWxlLndpZHRoID0gJzFweCc7XG4gICAgZWwuc3R5bGUuaGVpZ2h0ID0gJzFweCc7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBNRVRIT0RTID0gW1xuICAgICdoYW5kc2hha2VWZXJzaW9uJyxcbiAgICAnaW5pdEFkJyxcbiAgICAnc3RhcnRBZCcsXG4gICAgJ3N0b3BBZCcsXG4gICAgJ3NraXBBZCcsIC8vIFZQQUlEIDIuMCBuZXcgbWV0aG9kXG4gICAgJ3Jlc2l6ZUFkJyxcbiAgICAncGF1c2VBZCcsXG4gICAgJ3Jlc3VtZUFkJyxcbiAgICAnZXhwYW5kQWQnLFxuICAgICdjb2xsYXBzZUFkJyxcbiAgICAnc3Vic2NyaWJlJyxcbiAgICAndW5zdWJzY3JpYmUnXG5dO1xuXG52YXIgRVZFTlRTID0gW1xuICAgICdBZExvYWRlZCcsXG4gICAgJ0FkU3RhcnRlZCcsXG4gICAgJ0FkU3RvcHBlZCcsXG4gICAgJ0FkU2tpcHBlZCcsXG4gICAgJ0FkU2tpcHBhYmxlU3RhdGVDaGFuZ2UnLCAvLyBWUEFJRCAyLjAgbmV3IGV2ZW50XG4gICAgJ0FkU2l6ZUNoYW5nZScsIC8vIFZQQUlEIDIuMCBuZXcgZXZlbnRcbiAgICAnQWRMaW5lYXJDaGFuZ2UnLFxuICAgICdBZER1cmF0aW9uQ2hhbmdlJywgLy8gVlBBSUQgMi4wIG5ldyBldmVudFxuICAgICdBZEV4cGFuZGVkQ2hhbmdlJyxcbiAgICAnQWRSZW1haW5pbmdUaW1lQ2hhbmdlJywgLy8gW0RlcHJlY2F0ZWQgaW4gMi4wXSBidXQgd2lsbCBiZSBzdGlsbCBmaXJlZCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHlcbiAgICAnQWRWb2x1bWVDaGFuZ2UnLFxuICAgICdBZEltcHJlc3Npb24nLFxuICAgICdBZFZpZGVvU3RhcnQnLFxuICAgICdBZFZpZGVvRmlyc3RRdWFydGlsZScsXG4gICAgJ0FkVmlkZW9NaWRwb2ludCcsXG4gICAgJ0FkVmlkZW9UaGlyZFF1YXJ0aWxlJyxcbiAgICAnQWRWaWRlb0NvbXBsZXRlJyxcbiAgICAnQWRDbGlja1RocnUnLFxuICAgICdBZEludGVyYWN0aW9uJywgLy8gVlBBSUQgMi4wIG5ldyBldmVudFxuICAgICdBZFVzZXJBY2NlcHRJbnZpdGF0aW9uJyxcbiAgICAnQWRVc2VyTWluaW1pemUnLFxuICAgICdBZFVzZXJDbG9zZScsXG4gICAgJ0FkUGF1c2VkJyxcbiAgICAnQWRQbGF5aW5nJyxcbiAgICAnQWRMb2cnLFxuICAgICdBZEVycm9yJ1xuXTtcblxudmFyIEdFVFRFUlMgPSBbXG4gICAgJ2dldEFkTGluZWFyJyxcbiAgICAnZ2V0QWRXaWR0aCcsIC8vIFZQQUlEIDIuMCBuZXcgZ2V0dGVyXG4gICAgJ2dldEFkSGVpZ2h0JywgLy8gVlBBSUQgMi4wIG5ldyBnZXR0ZXJcbiAgICAnZ2V0QWRFeHBhbmRlZCcsXG4gICAgJ2dldEFkU2tpcHBhYmxlU3RhdGUnLCAvLyBWUEFJRCAyLjAgbmV3IGdldHRlclxuICAgICdnZXRBZFJlbWFpbmluZ1RpbWUnLFxuICAgICdnZXRBZER1cmF0aW9uJywgLy8gVlBBSUQgMi4wIG5ldyBnZXR0ZXJcbiAgICAnZ2V0QWRWb2x1bWUnLFxuICAgICdnZXRBZENvbXBhbmlvbnMnLCAvLyBWUEFJRCAyLjAgbmV3IGdldHRlclxuICAgICdnZXRBZEljb25zJyAvLyBWUEFJRCAyLjAgbmV3IGdldHRlclxuXTtcblxudmFyIFNFVFRFUlMgPSBbXG4gICAgJ3NldEFkVm9sdW1lJ1xuXTtcblxuXG4vKipcbiAqIFRoaXMgY2FsbGJhY2sgaXMgZGlzcGxheWVkIGFzIGdsb2JhbCBtZW1iZXIuIFRoZSBjYWxsYmFjayB1c2Ugbm9kZWpzIGVycm9yLWZpcnN0IGNhbGxiYWNrIHN0eWxlXG4gKiBAY2FsbGJhY2sgTm9kZVN0eWxlQ2FsbGJhY2tcbiAqIEBwYXJhbSB7c3RyaW5nfG51bGx9XG4gKiBAcGFyYW0ge3VuZGVmaW5lZHxvYmplY3R9XG4gKi9cblxuXG4vKipcbiAqIElWUEFJREFkVW5pdFxuICpcbiAqIEBjbGFzc1xuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBjcmVhdGl2ZVxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7SFRNTFZpZGVvRWxlbWVudH0gdmlkZW9cbiAqL1xuZnVuY3Rpb24gSVZQQUlEQWRVbml0KGNyZWF0aXZlLCBlbCwgdmlkZW8pIHt9XG5cblxuLyoqXG4gKiBoYW5kc2hha2VWZXJzaW9uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFZQQUlEVmVyc2lvblxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5oYW5kc2hha2VWZXJzaW9uID0gZnVuY3Rpb24gKFZQQUlEVmVyc2lvbiwgY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIGluaXRBZFxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSB3aWR0aFxuICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodFxuICogQHBhcmFtIHtzdHJpbmd9IHZpZXdNb2RlIGNhbiBiZSAnbm9ybWFsJywgJ3RodW1ibmFpbCcgb3IgJ2Z1bGxzY3JlZW4nXG4gKiBAcGFyYW0ge251bWJlcn0gZGVzaXJlZEJpdHJhdGUgaW5kaWNhdGVzIHRoZSBkZXNpcmVkIGJpdHJhdGUgaW4ga2Jwc1xuICogQHBhcmFtIHtvYmplY3R9IFtjcmVhdGl2ZURhdGFdIHVzZWQgZm9yIGFkZGl0aW9uYWwgaW5pdGlhbGl6YXRpb24gZGF0YVxuICogQHBhcmFtIHtvYmplY3R9IFtlbnZpcm9ubWVudFZhcnNdIHVzZWQgZm9yIHBhc3NpbmcgaW1wbGVtZW50YXRpb24tc3BlY2lmaWMgb2YganMgdmVyc2lvblxuICogQHBhcmFtIHtOb2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5pbml0QWQgPSBmdW5jdGlvbih3aWR0aCwgaGVpZ2h0LCB2aWV3TW9kZSwgZGVzaXJlZEJpdHJhdGUsIGNyZWF0aXZlRGF0YSwgZW52aXJvbm1lbnRWYXJzLCBjYWxsYmFjaykge307XG5cbi8qKlxuICogc3RhcnRBZFxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuc3RhcnRBZCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBzdG9wQWRcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLnN0b3BBZCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBza2lwQWRcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLnNraXBBZCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiByZXNpemVBZFxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUucmVzaXplQWQgPSBmdW5jdGlvbih3aWR0aCwgaGVpZ2h0LCB2aWV3TW9kZSwgY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIHBhdXNlQWRcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLnBhdXNlQWQgPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogcmVzdW1lQWRcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLnJlc3VtZUFkID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIGV4cGFuZEFkXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5leHBhbmRBZCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBjb2xsYXBzZUFkXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5jb2xsYXBzZUFkID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIHN1YnNjcmliZVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gaGFuZGxlclxuICogQHBhcmFtIHtvYmplY3R9IGNvbnRleHRcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5zdWJzY3JpYmUgPSBmdW5jdGlvbihldmVudCwgaGFuZGxlciwgY29udGV4dCkge307XG5cbi8qKlxuICogc3RhcnRBZFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtmdW5jdGlvbn0gaGFuZGxlclxuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLnVuc3Vic2NyaWJlID0gZnVuY3Rpb24oZXZlbnQsIGhhbmRsZXIpIHt9O1xuXG5cblxuLyoqXG4gKiBnZXRBZExpbmVhclxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuZ2V0QWRMaW5lYXIgPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogZ2V0QWRXaWR0aFxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuZ2V0QWRXaWR0aCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBnZXRBZEhlaWdodFxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuZ2V0QWRIZWlnaHQgPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogZ2V0QWRFeHBhbmRlZFxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuZ2V0QWRFeHBhbmRlZCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBnZXRBZFNraXBwYWJsZVN0YXRlXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5nZXRBZFNraXBwYWJsZVN0YXRlID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIGdldEFkUmVtYWluaW5nVGltZVxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuZ2V0QWRSZW1haW5pbmdUaW1lID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIGdldEFkRHVyYXRpb25cbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLmdldEFkRHVyYXRpb24gPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogZ2V0QWRWb2x1bWVcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLmdldEFkVm9sdW1lID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIGdldEFkQ29tcGFuaW9uc1xuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuZ2V0QWRDb21wYW5pb25zID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIGdldEFkSWNvbnNcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLmdldEFkSWNvbnMgPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogc2V0QWRWb2x1bWVcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gdm9sdW1lXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLnNldEFkVm9sdW1lID0gZnVuY3Rpb24odm9sdW1lLCBjYWxsYmFjaykge307XG5cbmFkZFN0YXRpY1RvSW50ZXJmYWNlKElWUEFJREFkVW5pdCwgJ01FVEhPRFMnLCBNRVRIT0RTKTtcbmFkZFN0YXRpY1RvSW50ZXJmYWNlKElWUEFJREFkVW5pdCwgJ0dFVFRFUlMnLCBHRVRURVJTKTtcbmFkZFN0YXRpY1RvSW50ZXJmYWNlKElWUEFJREFkVW5pdCwgJ1NFVFRFUlMnLCBTRVRURVJTKTtcbmFkZFN0YXRpY1RvSW50ZXJmYWNlKElWUEFJREFkVW5pdCwgJ0VWRU5UUycsICBFVkVOVFMpO1xuXG5cbnZhciBWUEFJRDFfTUVUSE9EUyA9IE1FVEhPRFMuZmlsdGVyKGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgIHJldHVybiBbJ3NraXBBZCddLmluZGV4T2YobWV0aG9kKSA9PT0gLTE7XG59KTtcblxuYWRkU3RhdGljVG9JbnRlcmZhY2UoSVZQQUlEQWRVbml0LCAnY2hlY2tWUEFJREludGVyZmFjZScsIGZ1bmN0aW9uIGNoZWNrVlBBSURJbnRlcmZhY2UgKGNyZWF0aXZlKSB7XG4gICAgdmFyIHJlc3VsdCA9IFZQQUlEMV9NRVRIT0RTLmV2ZXJ5KGZ1bmN0aW9uKGtleSkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIGNyZWF0aXZlW2tleV0gPT09ICdmdW5jdGlvbic7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IElWUEFJREFkVW5pdDtcblxuZnVuY3Rpb24gYWRkU3RhdGljVG9JbnRlcmZhY2UoSW50ZXJmYWNlLCBuYW1lLCB2YWx1ZSkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShJbnRlcmZhY2UsIG5hbWUsIHtcbiAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICB2YWx1ZTogdmFsdWVcbiAgICB9KTtcbn1cblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgSVZQQUlEQWRVbml0ID0gcmVxdWlyZSgnLi9JVlBBSURBZFVuaXQnKTtcbnZhciBTdWJzY3JpYmVyID0gcmVxdWlyZSgnLi9zdWJzY3JpYmVyJyk7XG52YXIgY2hlY2tWUEFJREludGVyZmFjZSA9IElWUEFJREFkVW5pdC5jaGVja1ZQQUlESW50ZXJmYWNlO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIE1FVEhPRFMgPSBJVlBBSURBZFVuaXQuTUVUSE9EUztcbnZhciBFUlJPUiA9ICdBZEVycm9yJztcbnZhciBBRF9DTElDSyA9ICdBZENsaWNrVGhydSc7XG52YXIgRklMVEVSRURfRVZFTlRTID0gSVZQQUlEQWRVbml0LkVWRU5UUy5maWx0ZXIoZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgcmV0dXJuIGV2ZW50ICE9IEFEX0NMSUNLO1xufSk7XG5cbi8qKlxuICogVGhpcyBjYWxsYmFjayBpcyBkaXNwbGF5ZWQgYXMgZ2xvYmFsIG1lbWJlci4gVGhlIGNhbGxiYWNrIHVzZSBub2RlanMgZXJyb3ItZmlyc3QgY2FsbGJhY2sgc3R5bGVcbiAqIEBjYWxsYmFjayBOb2RlU3R5bGVDYWxsYmFja1xuICogQHBhcmFtIHtzdHJpbmd8bnVsbH1cbiAqIEBwYXJhbSB7dW5kZWZpbmVkfG9iamVjdH1cbiAqL1xuXG5cbi8qKlxuICogVlBBSURBZFVuaXRcbiAqIEBjbGFzc1xuICpcbiAqIEBwYXJhbSBWUEFJRENyZWF0aXZlXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBbZWxdIHRoaXMgd2lsbCBiZSB1c2VkIGluIGluaXRBZCBlbnZpcm9ubWVudFZhcnMuc2xvdCBpZiBkZWZpbmVkXG4gKiBAcGFyYW0ge0hUTUxWaWRlb0VsZW1lbnR9IFt2aWRlb10gdGhpcyB3aWxsIGJlIHVzZWQgaW4gaW5pdEFkIGVudmlyb25tZW50VmFycy52aWRlb1Nsb3QgaWYgZGVmaW5lZFxuICovXG5mdW5jdGlvbiBWUEFJREFkVW5pdChWUEFJRENyZWF0aXZlLCBlbCwgdmlkZW8sIGlmcmFtZSkge1xuICAgIHRoaXMuX2lzVmFsaWQgPSBjaGVja1ZQQUlESW50ZXJmYWNlKFZQQUlEQ3JlYXRpdmUpO1xuICAgIGlmICh0aGlzLl9pc1ZhbGlkKSB7XG4gICAgICAgIHRoaXMuX2NyZWF0aXZlID0gVlBBSURDcmVhdGl2ZTtcbiAgICAgICAgdGhpcy5fZWwgPSBlbDtcbiAgICAgICAgdGhpcy5fdmlkZW9FbCA9IHZpZGVvO1xuICAgICAgICB0aGlzLl9pZnJhbWUgPSBpZnJhbWU7XG4gICAgICAgIHRoaXMuX3N1YnNjcmliZXJzID0gbmV3IFN1YnNjcmliZXIoKTtcbiAgICAgICAgJGFkZEV2ZW50c1N1YnNjcmliZXJzLmNhbGwodGhpcyk7XG4gICAgfVxufVxuXG5WUEFJREFkVW5pdC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKElWUEFJREFkVW5pdC5wcm90b3R5cGUpO1xuXG4vKipcbiAqIGlzVmFsaWRWUEFJREFkIHdpbGwgcmV0dXJuIGlmIHRoZSBWUEFJRENyZWF0aXZlIHBhc3NlZCBpbiBjb25zdHJ1Y3RvciBpcyB2YWxpZCBvciBub3RcbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5WUEFJREFkVW5pdC5wcm90b3R5cGUuaXNWYWxpZFZQQUlEQWQgPSBmdW5jdGlvbiBpc1ZhbGlkVlBBSURBZCgpIHtcbiAgICByZXR1cm4gdGhpcy5faXNWYWxpZDtcbn07XG5cbklWUEFJREFkVW5pdC5NRVRIT0RTLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgLy9OT1RFOiB0aGlzIG1ldGhvZHMgYXJndW1lbnRzIG9yZGVyIGFyZSBpbXBsZW1lbnRlZCBkaWZmZXJlbnRseSBmcm9tIHRoZSBzcGVjXG4gICAgdmFyIGlnbm9yZXMgPSBbXG4gICAgICAgICdzdWJzY3JpYmUnLFxuICAgICAgICAndW5zdWJzY3JpYmUnLFxuICAgICAgICAnaW5pdEFkJ1xuICAgIF07XG5cbiAgICBpZiAoaWdub3Jlcy5pbmRleE9mKG1ldGhvZCkgIT09IC0xKSByZXR1cm47XG5cbiAgICBWUEFJREFkVW5pdC5wcm90b3R5cGVbbWV0aG9kXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGFyaWF0eSA9IElWUEFJREFkVW5pdC5wcm90b3R5cGVbbWV0aG9kXS5sZW5ndGg7XG4gICAgICAgIC8vIFRPRE8gYXZvaWQgbGVha2luZyBhcmd1bWVudHNcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3BldGthYW50b25vdi9ibHVlYmlyZC93aWtpL09wdGltaXphdGlvbi1raWxsZXJzIzMyLWxlYWtpbmctYXJndW1lbnRzXG4gICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gKGFyaWF0eSA9PT0gYXJncy5sZW5ndGgpID8gYXJncy5wb3AoKSA6IHVuZGVmaW5lZDtcblxuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQsIGVycm9yID0gbnVsbDtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gdGhpcy5fY3JlYXRpdmVbbWV0aG9kXS5hcHBseSh0aGlzLl9jcmVhdGl2ZSwgYXJncyk7XG4gICAgICAgICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgICAgICAgICBlcnJvciA9IGU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhbGxPclRyaWdnZXJFdmVudChjYWxsYmFjaywgdGhpcy5fc3Vic2NyaWJlcnMsIGVycm9yLCByZXN1bHQpO1xuICAgICAgICB9LmJpbmQodGhpcyksIDApO1xuICAgIH07XG59KTtcblxuXG4vKipcbiAqIGluaXRBZCBjb25jcmVhdGUgaW1wbGVtZW50YXRpb25cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gd2lkdGhcbiAqIEBwYXJhbSB7bnVtYmVyfSBoZWlnaHRcbiAqIEBwYXJhbSB7c3RyaW5nfSB2aWV3TW9kZSBjYW4gYmUgJ25vcm1hbCcsICd0aHVtYm5haWwnIG9yICdmdWxsc2NyZWVuJ1xuICogQHBhcmFtIHtudW1iZXJ9IGRlc2lyZWRCaXRyYXRlIGluZGljYXRlcyB0aGUgZGVzaXJlZCBiaXRyYXRlIGluIGticHNcbiAqIEBwYXJhbSB7b2JqZWN0fSBbY3JlYXRpdmVEYXRhXSB1c2VkIGZvciBhZGRpdGlvbmFsIGluaXRpYWxpemF0aW9uIGRhdGFcbiAqIEBwYXJhbSB7b2JqZWN0fSBbZW52aXJvbm1lbnRWYXJzXSB1c2VkIGZvciBwYXNzaW5nIGltcGxlbWVudGF0aW9uLXNwZWNpZmljIG9mIGpzIHZlcnNpb24sIGlmIGVsICYgdmlkZW8gd2FzIHVzZWQgaW4gY29uc3RydWN0b3Igc2xvdCAmIHZpZGVvU2xvdCB3aWxsIGJlIGFkZGVkIHRvIHRoZSBvYmplY3RcbiAqIEBwYXJhbSB7Tm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cblZQQUlEQWRVbml0LnByb3RvdHlwZS5pbml0QWQgPSBmdW5jdGlvbiBpbml0QWQod2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGRlc2lyZWRCaXRyYXRlLCBjcmVhdGl2ZURhdGEsIGVudmlyb25tZW50VmFycywgY2FsbGJhY2spIHtcbiAgICBjcmVhdGl2ZURhdGEgPSBjcmVhdGl2ZURhdGEgfHwge307XG4gICAgZW52aXJvbm1lbnRWYXJzID0gdXRpbHMuZXh0ZW5kKHtcbiAgICAgICAgc2xvdDogdGhpcy5fZWwsXG4gICAgICAgIHZpZGVvU2xvdDogdGhpcy5fdmlkZW9FbFxuICAgIH0sIGVudmlyb25tZW50VmFycyB8fCB7fSk7XG5cbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGVycm9yO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRpdmUuaW5pdEFkKHdpZHRoLCBoZWlnaHQsIHZpZXdNb2RlLCBkZXNpcmVkQml0cmF0ZSwgY3JlYXRpdmVEYXRhLCBlbnZpcm9ubWVudFZhcnMpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBlcnJvciA9IGU7XG4gICAgICAgIH1cblxuICAgICAgICBjYWxsT3JUcmlnZ2VyRXZlbnQoY2FsbGJhY2ssIHRoaXMuX3N1YnNjcmliZXJzLCBlcnJvcik7XG4gICAgfS5iaW5kKHRoaXMpLCAwKTtcbn07XG5cbi8qKlxuICogc3Vic2NyaWJlXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBoYW5kbGVyXG4gKiBAcGFyYW0ge29iamVjdH0gY29udGV4dFxuICovXG5WUEFJREFkVW5pdC5wcm90b3R5cGUuc3Vic2NyaWJlID0gZnVuY3Rpb24gc3Vic2NyaWJlKGV2ZW50LCBoYW5kbGVyLCBjb250ZXh0KSB7XG4gICAgdGhpcy5fc3Vic2NyaWJlcnMuc3Vic2NyaWJlKGhhbmRsZXIsIGV2ZW50LCBjb250ZXh0KTtcbn07XG5cblxuLyoqXG4gKiB1bnN1YnNjcmliZVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gaGFuZGxlclxuICovXG5WUEFJREFkVW5pdC5wcm90b3R5cGUudW5zdWJzY3JpYmUgPSBmdW5jdGlvbiB1bnN1YnNjcmliZShldmVudCwgaGFuZGxlcikge1xuICAgIHRoaXMuX3N1YnNjcmliZXJzLnVuc3Vic2NyaWJlKGhhbmRsZXIsIGV2ZW50KTtcbn07XG5cbi8vYWxpYXNcblZQQUlEQWRVbml0LnByb3RvdHlwZS5vbiA9IFZQQUlEQWRVbml0LnByb3RvdHlwZS5zdWJzY3JpYmU7XG5WUEFJREFkVW5pdC5wcm90b3R5cGUub2ZmID0gVlBBSURBZFVuaXQucHJvdG90eXBlLnVuc3Vic2NyaWJlO1xuXG5JVlBBSURBZFVuaXQuR0VUVEVSUy5mb3JFYWNoKGZ1bmN0aW9uKGdldHRlcikge1xuICAgIFZQQUlEQWRVbml0LnByb3RvdHlwZVtnZXR0ZXJdID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICB2YXIgcmVzdWx0LCBlcnJvciA9IG51bGw7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRoaXMuX2NyZWF0aXZlW2dldHRlcl0oKTtcbiAgICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgICAgIGVycm9yID0gZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FsbE9yVHJpZ2dlckV2ZW50KGNhbGxiYWNrLCB0aGlzLl9zdWJzY3JpYmVycywgZXJyb3IsIHJlc3VsdCk7XG4gICAgICAgIH0uYmluZCh0aGlzKSwgMCk7XG4gICAgfTtcbn0pO1xuXG4vKipcbiAqIHNldEFkVm9sdW1lXG4gKlxuICogQHBhcmFtIHZvbHVtZVxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuVlBBSURBZFVuaXQucHJvdG90eXBlLnNldEFkVm9sdW1lID0gZnVuY3Rpb24gc2V0QWRWb2x1bWUodm9sdW1lLCBjYWxsYmFjaykge1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIHZhciByZXN1bHQsIGVycm9yID0gbnVsbDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0aXZlLnNldEFkVm9sdW1lKHZvbHVtZSk7XG4gICAgICAgICAgICByZXN1bHQgPSB0aGlzLl9jcmVhdGl2ZS5nZXRBZFZvbHVtZSgpO1xuICAgICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgICAgIGVycm9yID0gZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghZXJyb3IpIHtcbiAgICAgICAgICAgIGVycm9yID0gdXRpbHMudmFsaWRhdGUocmVzdWx0ID09PSB2b2x1bWUsICdmYWlsZWQgdG8gYXBwbHkgdm9sdW1lOiAnICsgdm9sdW1lKTtcbiAgICAgICAgfVxuICAgICAgICBjYWxsT3JUcmlnZ2VyRXZlbnQoY2FsbGJhY2ssIHRoaXMuX3N1YnNjcmliZXJzLCBlcnJvciwgcmVzdWx0KTtcbiAgICB9LmJpbmQodGhpcyksIDApO1xufTtcblxuVlBBSURBZFVuaXQucHJvdG90eXBlLl9kZXN0cm95ID0gZnVuY3Rpb24gZGVzdHJveSgpIHtcbiAgICB0aGlzLnN0b3BBZCgpO1xuICAgIHRoaXMuX3N1YnNjcmliZXJzLnVuc3Vic2NyaWJlQWxsKCk7XG59O1xuXG5mdW5jdGlvbiAkYWRkRXZlbnRzU3Vic2NyaWJlcnMoKSB7XG4gICAgLy8gc29tZSBhZHMgaW1wbGVtZW50XG4gICAgLy8gc28gdGhleSBvbmx5IGhhbmRsZSBvbmUgc3Vic2NyaWJlclxuICAgIC8vIHRvIGhhbmRsZSB0aGlzIHdlIGNyZWF0ZSBvdXIgb25lXG4gICAgRklMVEVSRURfRVZFTlRTLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuX2NyZWF0aXZlLnN1YnNjcmliZSgkdHJpZ2dlci5iaW5kKHRoaXMsIGV2ZW50KSwgZXZlbnQpO1xuICAgIH0uYmluZCh0aGlzKSk7XG5cbiAgICAvLyBtYXAgdGhlIGNsaWNrIGV2ZW50IHRvIGJlIGFuIG9iamVjdCBpbnN0ZWFkIG9mIGRlcGVuZGluZyBvZiB0aGUgb3JkZXIgb2YgdGhlIGFyZ3VtZW50c1xuICAgIC8vIGFuZCB0byBiZSBjb25zaXN0ZW50IHdpdGggdGhlIGZsYXNoXG4gICAgdGhpcy5fY3JlYXRpdmUuc3Vic2NyaWJlKCRjbGlja1RocnVIb29rLmJpbmQodGhpcyksIEFEX0NMSUNLKTtcblxuICAgIC8vIGJlY2F1c2Ugd2UgYXJlIGFkZGluZyB0aGUgZWxlbWVudCBpbnNpZGUgdGhlIGlmcmFtZVxuICAgIC8vIHRoZSB1c2VyIGlzIG5vdCBhYmxlIHRvIGNsaWNrIGluIHRoZSB2aWRlb1xuICAgIGlmICh0aGlzLl92aWRlb0VsKSB7XG4gICAgICAgIHZhciBkb2N1bWVudEVsZW1lbnQgPSB0aGlzLl9pZnJhbWUuY29udGVudERvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgICAgICAgdmFyIHZpZGVvRWwgPSB0aGlzLl92aWRlb0VsO1xuICAgICAgICBkb2N1bWVudEVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICBpZiAoZS50YXJnZXQgPT09IGRvY3VtZW50RWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHZpZGVvRWwuY2xpY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiAkY2xpY2tUaHJ1SG9vayh1cmwsIGlkLCBwbGF5ZXJIYW5kbGVzKSB7XG4gICAgdGhpcy5fc3Vic2NyaWJlcnMudHJpZ2dlclN5bmMoQURfQ0xJQ0ssIHt1cmw6IHVybCwgaWQ6IGlkLCBwbGF5ZXJIYW5kbGVzOiBwbGF5ZXJIYW5kbGVzfSk7XG59XG5cbmZ1bmN0aW9uICR0cmlnZ2VyKGV2ZW50KSB7XG4gICAgLy8gVE9ETyBhdm9pZCBsZWFraW5nIGFyZ3VtZW50c1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9wZXRrYWFudG9ub3YvYmx1ZWJpcmQvd2lraS9PcHRpbWl6YXRpb24ta2lsbGVycyMzMi1sZWFraW5nLWFyZ3VtZW50c1xuICAgIHRoaXMuX3N1YnNjcmliZXJzLnRyaWdnZXIoZXZlbnQsIEFycmF5LnByb3RvdHlwZS5zbGljZShhcmd1bWVudHMsIDEpKTtcbn1cblxuZnVuY3Rpb24gY2FsbE9yVHJpZ2dlckV2ZW50KGNhbGxiYWNrLCBzdWJzY3JpYmVycywgZXJyb3IsIHJlc3VsdCkge1xuICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICB9IGVsc2UgaWYgKGVycm9yKSB7XG4gICAgICAgIHN1YnNjcmliZXJzLnRyaWdnZXIoRVJST1IsIGVycm9yKTtcbiAgICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gVlBBSURBZFVuaXQ7XG5cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIHVuaXF1ZSA9IHV0aWxzLnVuaXF1ZSgndnBhaWRJZnJhbWUnKTtcbnZhciBWUEFJREFkVW5pdCA9IHJlcXVpcmUoJy4vVlBBSURBZFVuaXQnKTtcblxudmFyIGRlZmF1bHRUZW1wbGF0ZSA9ICc8IURPQ1RZUEUgaHRtbD4nICtcbiAgICAnPGh0bWwgbGFuZz1cImVuXCI+JyArXG4gICAgJzxoZWFkPjxtZXRhIGNoYXJzZXQ9XCJVVEYtOFwiPjwvaGVhZD4nICtcbiAgICAnPGJvZHkgc3R5bGU9XCJtYXJnaW46MDtwYWRkaW5nOjBcIj48ZGl2IGNsYXNzPVwiYWQtZWxlbWVudFwiPjwvZGl2PicgK1xuICAgICc8c2NyaXB0IHR5cGU9XCJ0ZXh0L2phdmFzY3JpcHRcIiBzcmM9XCJ7e2lmcmFtZVVSTF9KU319XCI+PC9zY3JpcHQ+JyArXG4gICAgJzxzY3JpcHQgdHlwZT1cInRleHQvamF2YXNjcmlwdFwiPicgK1xuICAgICd3aW5kb3cucGFyZW50LnBvc3RNZXNzYWdlKFxcJ3tcImV2ZW50XCI6IFwicmVhZHlcIiwgXCJpZFwiOiBcInt7aWZyYW1lSUR9fVwifVxcJywgXFwne3tvcmlnaW59fVxcJyk7JyArXG4gICAgJzwvc2NyaXB0PicgK1xuICAgICc8L2JvZHk+JyArXG4gICAgJzwvaHRtbD4nO1xuXG52YXIgQURfU1RPUFBFRCA9ICdBZFN0b3BwZWQnO1xuXG4vKipcbiAqIFRoaXMgY2FsbGJhY2sgaXMgZGlzcGxheWVkIGFzIGdsb2JhbCBtZW1iZXIuIFRoZSBjYWxsYmFjayB1c2Ugbm9kZWpzIGVycm9yLWZpcnN0IGNhbGxiYWNrIHN0eWxlXG4gKiBAY2FsbGJhY2sgTm9kZVN0eWxlQ2FsbGJhY2tcbiAqIEBwYXJhbSB7c3RyaW5nfG51bGx9XG4gKiBAcGFyYW0ge3VuZGVmaW5lZHxvYmplY3R9XG4gKi9cblxuLyoqXG4gKiBWUEFJREhUTUw1Q2xpZW50XG4gKiBAY2xhc3NcbiAqXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbCB0aGF0IHdpbGwgY29udGFpbiB0aGUgaWZyYW1lIHRvIGxvYWQgYWRVbml0IGFuZCBhIGVsIHRvIGFkZCB0byBhZFVuaXQgc2xvdFxuICogQHBhcmFtIHtIVE1MVmlkZW9FbGVtZW50fSB2aWRlbyBkZWZhdWx0IHZpZGVvIGVsZW1lbnQgdG8gYmUgdXNlZCBieSBhZFVuaXRcbiAqIEBwYXJhbSB7b2JqZWN0fSBbdGVtcGxhdGVDb25maWddIHRlbXBsYXRlOiBodG1sIHRlbXBsYXRlIHRvIGJlIHVzZWQgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCwgZXh0cmFPcHRpb25zOiB0byBiZSB1c2VkIHdoZW4gcmVuZGVyaW5nIHRoZSB0ZW1wbGF0ZVxuICogQHBhcmFtIHtvYmplY3R9IFt2cGFpZE9wdGlvbnNdIHRpbWVvdXQ6IHdoZW4gbG9hZGluZyBhZFVuaXRcbiAqL1xuZnVuY3Rpb24gVlBBSURIVE1MNUNsaWVudChlbCwgdmlkZW8sIHRlbXBsYXRlQ29uZmlnLCB2cGFpZE9wdGlvbnMpIHtcbiAgICB0ZW1wbGF0ZUNvbmZpZyA9IHRlbXBsYXRlQ29uZmlnIHx8IHt9O1xuXG4gICAgdGhpcy5faWQgPSB1bmlxdWUoKTtcbiAgICB0aGlzLl9kZXN0cm95ZWQgPSBmYWxzZTtcblxuICAgIHRoaXMuX2ZyYW1lQ29udGFpbmVyID0gdXRpbHMuY3JlYXRlRWxlbWVudEluRWwoZWwsICdkaXYnKTtcbiAgICB0aGlzLl92aWRlb0VsID0gdmlkZW87XG4gICAgdGhpcy5fdnBhaWRPcHRpb25zID0gdnBhaWRPcHRpb25zIHx8IHt0aW1lb3V0OiAxMDAwMH07XG5cbiAgICB0aGlzLl90ZW1wbGF0ZUNvbmZpZyA9IHtcbiAgICAgICAgdGVtcGxhdGU6IHRlbXBsYXRlQ29uZmlnLnRlbXBsYXRlIHx8IGRlZmF1bHRUZW1wbGF0ZSxcbiAgICAgICAgZXh0cmFPcHRpb25zOiB0ZW1wbGF0ZUNvbmZpZy5leHRyYU9wdGlvbnMgfHwge31cbiAgICB9O1xufVxuXG4vKipcbiAqIGRlc3Ryb3lcbiAqXG4gKi9cblZQQUlESFRNTDVDbGllbnQucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiBkZXN0cm95KCkge1xuICAgIGlmICh0aGlzLl9kZXN0cm95ZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9kZXN0cm95ZWQgPSB0cnVlO1xuICAgICR1bmxvYWRQcmV2aW91c0FkVW5pdC5jYWxsKHRoaXMpO1xufTtcblxuLyoqXG4gKiBpc0Rlc3Ryb3llZFxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cblZQQUlESFRNTDVDbGllbnQucHJvdG90eXBlLmlzRGVzdHJveWVkID0gZnVuY3Rpb24gaXNEZXN0cm95ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2Rlc3Ryb3llZDtcbn07XG5cbi8qKlxuICogbG9hZEFkVW5pdFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBhZFVSTCB1cmwgb2YgdGhlIGpzIG9mIHRoZSBhZFVuaXRcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cblZQQUlESFRNTDVDbGllbnQucHJvdG90eXBlLmxvYWRBZFVuaXQgPSBmdW5jdGlvbiBsb2FkQWRVbml0KGFkVVJMLCBjYWxsYmFjaykge1xuICAgICR0aHJvd0lmRGVzdHJveWVkLmNhbGwodGhpcyk7XG4gICAgJHVubG9hZFByZXZpb3VzQWRVbml0LmNhbGwodGhpcyk7XG4gICAgdmFyIHRoYXQgPSB0aGlzO1xuXG4gICAgdmFyIGZyYW1lID0gdXRpbHMuY3JlYXRlSWZyYW1lV2l0aENvbnRlbnQoXG4gICAgICAgIHRoaXMuX2ZyYW1lQ29udGFpbmVyLFxuICAgICAgICB0aGlzLl90ZW1wbGF0ZUNvbmZpZy50ZW1wbGF0ZSxcbiAgICAgICAgdXRpbHMuZXh0ZW5kKHtcbiAgICAgICAgICAgIGlmcmFtZVVSTF9KUzogYWRVUkwsXG4gICAgICAgICAgICBpZnJhbWVJRDogdGhpcy5nZXRJRCgpLFxuICAgICAgICAgICAgb3JpZ2luOiBnZXRPcmlnaW4oKVxuICAgICAgICB9LCB0aGlzLl90ZW1wbGF0ZUNvbmZpZy5leHRyYU9wdGlvbnMpXG4gICAgKTtcblxuICAgIHRoaXMuX2ZyYW1lID0gZnJhbWU7XG5cbiAgICB0aGlzLl9vbkxvYWQgPSB1dGlscy5jYWxsYmFja1RpbWVvdXQoXG4gICAgICAgIHRoaXMuX3ZwYWlkT3B0aW9ucy50aW1lb3V0LFxuICAgICAgICBvbkxvYWQuYmluZCh0aGlzKSxcbiAgICAgICAgb25UaW1lb3V0LmJpbmQodGhpcylcbiAgICApO1xuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0aGlzLl9vbkxvYWQpO1xuXG4gICAgZnVuY3Rpb24gb25Mb2FkIChlKSB7XG4gICAgICAgIC8qanNoaW50IHZhbGlkdGhpczogZmFsc2UgKi9cbiAgICAgICAgLy9kb24ndCBjbGVhciB0aW1lb3V0XG4gICAgICAgIGlmIChlLm9yaWdpbiAhPT0gZ2V0T3JpZ2luKCkpIHJldHVybjtcbiAgICAgICAgdmFyIHJlc3VsdCA9IEpTT04ucGFyc2UoZS5kYXRhKTtcblxuICAgICAgICAvL2Rvbid0IGNsZWFyIHRpbWVvdXRcbiAgICAgICAgaWYgKHJlc3VsdC5pZCAhPT0gdGhhdC5nZXRJRCgpKSByZXR1cm47XG5cbiAgICAgICAgdmFyIGFkVW5pdCwgZXJyb3IsIGNyZWF0ZUFkO1xuICAgICAgICBpZiAoIXRoYXQuX2ZyYW1lLmNvbnRlbnRXaW5kb3cpIHtcblxuICAgICAgICAgICAgZXJyb3IgPSAndGhlIGlmcmFtZSBpcyBub3QgYW55bW9yZSBpbiB0aGUgRE9NIHRyZWUnO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjcmVhdGVBZCA9IHRoYXQuX2ZyYW1lLmNvbnRlbnRXaW5kb3cuZ2V0VlBBSURBZDtcbiAgICAgICAgICAgIGVycm9yID0gdXRpbHMudmFsaWRhdGUodHlwZW9mIGNyZWF0ZUFkID09PSAnZnVuY3Rpb24nLCAndGhlIGFkIGRpZG5cXCd0IHJldHVybiBhIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhbiBhZCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFlcnJvcikge1xuICAgICAgICAgICAgdmFyIGFkRWwgPSB0aGF0Ll9mcmFtZS5jb250ZW50V2luZG93LmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5hZC1lbGVtZW50Jyk7XG4gICAgICAgICAgICBhZFVuaXQgPSBuZXcgVlBBSURBZFVuaXQoY3JlYXRlQWQoKSwgYWRFbCwgdGhhdC5fdmlkZW9FbCwgdGhhdC5fZnJhbWUpO1xuICAgICAgICAgICAgYWRVbml0LnN1YnNjcmliZShBRF9TVE9QUEVELCAkYWREZXN0cm95ZWQuYmluZCh0aGF0KSk7XG4gICAgICAgICAgICBlcnJvciA9IHV0aWxzLnZhbGlkYXRlKGFkVW5pdC5pc1ZhbGlkVlBBSURBZCgpLCAndGhlIGFkZCBpcyBub3QgZnVsbHkgY29tcGxhaW50IHdpdGggVlBBSUQgc3BlY2lmaWNhdGlvbicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhhdC5fYWRVbml0ID0gYWRVbml0O1xuICAgICAgICAkZGVzdHJveUxvYWRMaXN0ZW5lci5jYWxsKHRoYXQpO1xuICAgICAgICBjYWxsYmFjayhlcnJvciwgZXJyb3IgPyBudWxsIDogYWRVbml0KTtcblxuICAgICAgICAvL2NsZWFyIHRpbWVvdXRcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gb25UaW1lb3V0KCkge1xuICAgICAgICBjYWxsYmFjaygndGltZW91dCcsIG51bGwpO1xuICAgIH1cbn07XG5cbi8qKlxuICogdW5sb2FkQWRVbml0XG4gKlxuICovXG5WUEFJREhUTUw1Q2xpZW50LnByb3RvdHlwZS51bmxvYWRBZFVuaXQgPSBmdW5jdGlvbiB1bmxvYWRBZFVuaXQoKSB7XG4gICAgJHVubG9hZFByZXZpb3VzQWRVbml0LmNhbGwodGhpcyk7XG59O1xuXG4vKipcbiAqIGdldElEIHdpbGwgcmV0dXJuIHRoZSB1bmlxdWUgaWRcbiAqXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cblZQQUlESFRNTDVDbGllbnQucHJvdG90eXBlLmdldElEID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLl9pZDtcbn07XG5cblxuLyoqXG4gKiAkcmVtb3ZlRWxcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gKi9cbmZ1bmN0aW9uICRyZW1vdmVFbChrZXkpIHtcbiAgICB2YXIgZWwgPSB0aGlzW2tleV07XG4gICAgaWYgKGVsKSB7XG4gICAgICAgIGVsLnJlbW92ZSgpO1xuICAgICAgICBkZWxldGUgdGhpc1trZXldO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gJGFkRGVzdHJveWVkKCkge1xuICAgICRyZW1vdmVBZEVsZW1lbnRzLmNhbGwodGhpcyk7XG4gICAgZGVsZXRlIHRoaXMuX2FkVW5pdDtcbn1cblxuZnVuY3Rpb24gJHVubG9hZFByZXZpb3VzQWRVbml0KCkge1xuICAgICRyZW1vdmVBZEVsZW1lbnRzLmNhbGwodGhpcyk7XG4gICAgJGRlc3Ryb3lBZFVuaXQuY2FsbCh0aGlzKTtcbn1cblxuZnVuY3Rpb24gJHJlbW92ZUFkRWxlbWVudHMoKSB7XG4gICAgJHJlbW92ZUVsLmNhbGwodGhpcywgJ19mcmFtZScpO1xuICAgICRkZXN0cm95TG9hZExpc3RlbmVyLmNhbGwodGhpcyk7XG59XG5cbi8qKlxuICogJGRlc3Ryb3lMb2FkTGlzdGVuZXJcbiAqXG4gKi9cbmZ1bmN0aW9uICRkZXN0cm95TG9hZExpc3RlbmVyKCkge1xuICAgIGlmICh0aGlzLl9vbkxvYWQpIHtcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0aGlzLl9vbkxvYWQpO1xuICAgICAgICB1dGlscy5jbGVhckNhbGxiYWNrVGltZW91dCh0aGlzLl9vbkxvYWQpO1xuICAgICAgICBkZWxldGUgdGhpcy5fb25Mb2FkO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiAkZGVzdHJveUFkVW5pdCgpIHtcbiAgICBpZiAodGhpcy5fYWRVbml0KSB7XG4gICAgICAgIHRoaXMuX2FkVW5pdC5zdG9wQWQoKTtcbiAgICAgICAgZGVsZXRlIHRoaXMuX2FkVW5pdDtcbiAgICB9XG59XG5cbi8qKlxuICogJHRocm93SWZEZXN0cm95ZWRcbiAqXG4gKi9cbmZ1bmN0aW9uICR0aHJvd0lmRGVzdHJveWVkKCkge1xuICAgIGlmICh0aGlzLl9kZXN0cm95ZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yICgnVlBBSURIVE1MNUNsaWVudCBhbHJlYWR5IGRlc3Ryb3llZCEnKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGdldE9yaWdpbigpIHtcbiAgICBpZiggd2luZG93LmxvY2F0aW9uLm9yaWdpbiApIHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdy5sb2NhdGlvbi5vcmlnaW47XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gd2luZG93LmxvY2F0aW9uLnByb3RvY29sICsgXCIvL1wiICtcbiAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZSArXG4gICAgICAgICAgICAod2luZG93LmxvY2F0aW9uLnBvcnQgPyAnOicgKyB3aW5kb3cubG9jYXRpb24ucG9ydDogJycpO1xuICAgIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBWUEFJREhUTUw1Q2xpZW50O1xud2luZG93LlZQQUlESFRNTDVDbGllbnQgPSBWUEFJREhUTUw1Q2xpZW50O1xuXG4iLCIndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIFN1YnNjcmliZXIoKSB7XG4gICAgdGhpcy5fc3Vic2NyaWJlcnMgPSB7fTtcbn1cblxuU3Vic2NyaWJlci5wcm90b3R5cGUuc3Vic2NyaWJlID0gZnVuY3Rpb24gc3Vic2NyaWJlKGhhbmRsZXIsIGV2ZW50TmFtZSwgY29udGV4dCkge1xuICAgIGlmICghdGhpcy5pc0hhbmRsZXJBdHRhY2hlZChoYW5kbGVyLCBldmVudE5hbWUpKSB7XG4gICAgICAgIHRoaXMuZ2V0KGV2ZW50TmFtZSkucHVzaCh7aGFuZGxlcjogaGFuZGxlciwgY29udGV4dDogY29udGV4dCwgZXZlbnROYW1lOiBldmVudE5hbWV9KTtcbiAgICB9XG59O1xuXG5TdWJzY3JpYmVyLnByb3RvdHlwZS51bnN1YnNjcmliZSA9IGZ1bmN0aW9uIHVuc3Vic2NyaWJlKGhhbmRsZXIsIGV2ZW50TmFtZSkge1xuICAgIHRoaXMuX3N1YnNjcmliZXJzW2V2ZW50TmFtZV0gPSB0aGlzLmdldChldmVudE5hbWUpLmZpbHRlcihmdW5jdGlvbiAoc3Vic2NyaWJlcikge1xuICAgICAgICByZXR1cm4gaGFuZGxlciAhPT0gc3Vic2NyaWJlci5oYW5kbGVyO1xuICAgIH0pO1xufTtcblxuU3Vic2NyaWJlci5wcm90b3R5cGUudW5zdWJzY3JpYmVBbGwgPSBmdW5jdGlvbiB1bnN1YnNjcmliZUFsbCgpIHtcbiAgICB0aGlzLl9zdWJzY3JpYmVycyA9IHt9O1xufTtcblxuU3Vic2NyaWJlci5wcm90b3R5cGUudHJpZ2dlciA9IGZ1bmN0aW9uKGV2ZW50TmFtZSwgZGF0YSkge1xuICAgIHZhciB0aGF0ID0gdGhpcztcbiAgICB2YXIgc3Vic2NyaWJlcnMgPSB0aGlzLmdldChldmVudE5hbWUpXG4gICAgICAgIC5jb25jYXQodGhpcy5nZXQoJyonKSk7XG5cbiAgICBzdWJzY3JpYmVycy5mb3JFYWNoKGZ1bmN0aW9uIChzdWJzY3JpYmVyKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKHRoYXQuaXNIYW5kbGVyQXR0YWNoZWQoc3Vic2NyaWJlci5oYW5kbGVyLCBzdWJzY3JpYmVyLmV2ZW50TmFtZSkpIHtcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVyLmhhbmRsZXIuY2FsbChzdWJzY3JpYmVyLmNvbnRleHQsIGRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCAwKTtcbiAgICB9KTtcbn07XG5cblN1YnNjcmliZXIucHJvdG90eXBlLnRyaWdnZXJTeW5jID0gZnVuY3Rpb24oZXZlbnROYW1lLCBkYXRhKSB7XG4gICAgdmFyIHN1YnNjcmliZXJzID0gdGhpcy5nZXQoZXZlbnROYW1lKVxuICAgICAgICAuY29uY2F0KHRoaXMuZ2V0KCcqJykpO1xuXG4gICAgc3Vic2NyaWJlcnMuZm9yRWFjaChmdW5jdGlvbiAoc3Vic2NyaWJlcikge1xuICAgICAgICBzdWJzY3JpYmVyLmhhbmRsZXIuY2FsbChzdWJzY3JpYmVyLmNvbnRleHQsIGRhdGEpO1xuICAgIH0pO1xufTtcblxuU3Vic2NyaWJlci5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gZ2V0KGV2ZW50TmFtZSkge1xuICAgIGlmICghdGhpcy5fc3Vic2NyaWJlcnNbZXZlbnROYW1lXSkge1xuICAgICAgICB0aGlzLl9zdWJzY3JpYmVyc1tldmVudE5hbWVdID0gW107XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9zdWJzY3JpYmVyc1tldmVudE5hbWVdO1xufTtcblxuU3Vic2NyaWJlci5wcm90b3R5cGUuaXNIYW5kbGVyQXR0YWNoZWQgPSBmdW5jdGlvbiBpc0hhbmRsZXJBdHRhY2hlZChoYW5kbGVyLCBldmVudE5hbWUpIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoZXZlbnROYW1lKS5zb21lKGZ1bmN0aW9uKHN1YnNjcmliZXIpIHtcbiAgICAgICAgcmV0dXJuIGhhbmRsZXIgPT09IHN1YnNjcmliZXIuaGFuZGxlcjtcbiAgICB9KVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBTdWJzY3JpYmVyO1xuXG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogbm9vcCBhIGVtcHR5IGZ1bmN0aW9uXG4gKi9cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuXG4vKipcbiAqIHZhbGlkYXRlIGlmIGlzIG5vdCB2YWxpZGF0ZSB3aWxsIHJldHVybiBhbiBFcnJvciB3aXRoIHRoZSBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtib29sZWFufSBpc1ZhbGlkXG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZShpc1ZhbGlkLCBtZXNzYWdlKSB7XG4gICAgcmV0dXJuIGlzVmFsaWQgPyBudWxsIDogbmV3IEVycm9yKG1lc3NhZ2UpO1xufVxuXG52YXIgdGltZW91dHMgPSB7fTtcbi8qKlxuICogY2xlYXJDYWxsYmFja1RpbWVvdXRcbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBmdW5jIGhhbmRsZXIgdG8gcmVtb3ZlXG4gKi9cbmZ1bmN0aW9uIGNsZWFyQ2FsbGJhY2tUaW1lb3V0KGZ1bmMpIHtcbiAgICB2YXIgdGltZW91dCA9IHRpbWVvdXRzW2Z1bmNdO1xuICAgIGlmICh0aW1lb3V0KSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgZGVsZXRlIHRpbWVvdXRzW2Z1bmNdO1xuICAgIH1cbn1cblxuLyoqXG4gKiBjYWxsYmFja1RpbWVvdXQgaWYgdGhlIG9uU3VjY2VzcyBpcyBub3QgY2FsbGVkIGFuZCByZXR1cm5zIHRydWUgaW4gdGhlIHRpbWVsaW1pdCB0aGVuIG9uVGltZW91dCB3aWxsIGJlIGNhbGxlZFxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lclxuICogQHBhcmFtIHtmdW5jdGlvbn0gb25TdWNjZXNzXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBvblRpbWVvdXRcbiAqL1xuZnVuY3Rpb24gY2FsbGJhY2tUaW1lb3V0KHRpbWVyLCBvblN1Y2Nlc3MsIG9uVGltZW91dCkge1xuICAgIHZhciBjYWxsYmFjaywgdGltZW91dDtcblxuICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgb25TdWNjZXNzID0gbm9vcDtcbiAgICAgICAgZGVsZXRlIHRpbWVvdXRbY2FsbGJhY2tdO1xuICAgICAgICBvblRpbWVvdXQoKTtcbiAgICB9LCB0aW1lcik7XG5cbiAgICBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gVE9ETyBhdm9pZCBsZWFraW5nIGFyZ3VtZW50c1xuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vcGV0a2FhbnRvbm92L2JsdWViaXJkL3dpa2kvT3B0aW1pemF0aW9uLWtpbGxlcnMjMzItbGVha2luZy1hcmd1bWVudHNcbiAgICAgICAgaWYgKG9uU3VjY2Vzcy5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSB7XG4gICAgICAgICAgICBjbGVhckNhbGxiYWNrVGltZW91dChjYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgdGltZW91dHNbY2FsbGJhY2tdID0gdGltZW91dDtcblxuICAgIHJldHVybiBjYWxsYmFjaztcbn1cblxuXG4vKipcbiAqIGNyZWF0ZUVsZW1lbnRJbkVsXG4gKlxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gcGFyZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gdGFnTmFtZVxuICogQHBhcmFtIHtzdHJpbmd9IGlkXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnRJbkVsKHBhcmVudCwgdGFnTmFtZSwgaWQpIHtcbiAgICB2YXIgbkVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWdOYW1lKTtcbiAgICBpZiAoaWQpIG5FbC5pZCA9IGlkO1xuICAgIHBhcmVudC5hcHBlbmRDaGlsZChuRWwpO1xuICAgIHJldHVybiBuRWw7XG59XG5cbi8qKlxuICogY3JlYXRlSWZyYW1lV2l0aENvbnRlbnRcbiAqXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBwYXJlbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZW1wbGF0ZSBzaW1wbGUgdGVtcGxhdGUgdXNpbmcge3t2YXJ9fVxuICogQHBhcmFtIHtvYmplY3R9IGRhdGFcbiAqL1xuZnVuY3Rpb24gY3JlYXRlSWZyYW1lV2l0aENvbnRlbnQocGFyZW50LCB0ZW1wbGF0ZSwgZGF0YSkge1xuICAgIHZhciBpZnJhbWUgPSBjcmVhdGVJZnJhbWUocGFyZW50LCBudWxsLCBkYXRhLnpJbmRleCk7XG4gICAgaWYgKCFzZXRJZnJhbWVDb250ZW50KGlmcmFtZSwgc2ltcGxlVGVtcGxhdGUodGVtcGxhdGUsIGRhdGEpKSkgcmV0dXJuO1xuICAgIHJldHVybiBpZnJhbWU7XG59XG5cbi8qKlxuICogY3JlYXRlSWZyYW1lXG4gKlxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gcGFyZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gdXJsXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUlmcmFtZShwYXJlbnQsIHVybCwgekluZGV4KSB7XG4gICAgdmFyIG5FbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lmcmFtZScpO1xuICAgIG5FbC5zcmMgPSB1cmwgfHwgJ2Fib3V0OmJsYW5rJztcbiAgICBuRWwubWFyZ2luV2lkdGggPSAnMCc7XG4gICAgbkVsLm1hcmdpbkhlaWdodCA9ICcwJztcbiAgICBuRWwuZnJhbWVCb3JkZXIgPSAnMCc7XG4gICAgbkVsLndpZHRoID0gJzEwMCUnO1xuICAgIG5FbC5oZWlnaHQgPSAnMTAwJSc7XG4gICAgbkVsLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICBuRWwuc3R5bGUubGVmdCA9ICcwJztcbiAgICBuRWwuc3R5bGUudG9wID0gJzAnO1xuICAgIG5FbC5zdHlsZS5tYXJnaW4gPSAnMHB4JztcbiAgICBuRWwuc3R5bGUucGFkZGluZyA9ICcwcHgnO1xuICAgIG5FbC5zdHlsZS5ib3JkZXIgPSAnbm9uZSc7XG5cbiAgICBpZih6SW5kZXgpe1xuICAgICAgICBuRWwuc3R5bGUuekluZGV4ID0gekluZGV4O1xuICAgIH1cblxuICAgIG5FbC5zZXRBdHRyaWJ1dGUoJ1NDUk9MTElORycsJ05PJyk7XG4gICAgcGFyZW50LmlubmVySFRNTCA9ICcnO1xuICAgIHBhcmVudC5hcHBlbmRDaGlsZChuRWwpO1xuICAgIHJldHVybiBuRWw7XG59XG5cbi8qKlxuICogc2ltcGxlVGVtcGxhdGVcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGVtcGxhdGVcbiAqIEBwYXJhbSB7b2JqZWN0fSBkYXRhXG4gKi9cbmZ1bmN0aW9uIHNpbXBsZVRlbXBsYXRlKHRlbXBsYXRlLCBkYXRhKSB7XG4gICAgT2JqZWN0LmtleXMoZGF0YSkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIHZhciB2YWx1ZSA9ICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSA/IEpTT04uc3RyaW5naWZ5KGRhdGFba2V5XSkgOiBkYXRhW2tleV07XG4gICAgICAgIHRlbXBsYXRlID0gdGVtcGxhdGUucmVwbGFjZShuZXcgUmVnRXhwKCd7eycgKyBrZXkgKyAnfX0nLCAnZycpLCB2YWx1ZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRlbXBsYXRlO1xufVxuXG4vKipcbiAqIHNldElmcmFtZUNvbnRlbnRcbiAqXG4gKiBAcGFyYW0ge0hUTUxJZnJhbWVFbGVtZW50fSBpZnJhbWVFbFxuICogQHBhcmFtIGNvbnRlbnRcbiAqL1xuZnVuY3Rpb24gc2V0SWZyYW1lQ29udGVudChpZnJhbWVFbCwgY29udGVudCkge1xuICAgIHZhciBpZnJhbWVEb2MgPSBpZnJhbWVFbC5jb250ZW50V2luZG93ICYmIGlmcmFtZUVsLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnQ7XG4gICAgaWYgKCFpZnJhbWVEb2MpIHJldHVybiBmYWxzZTtcblxuICAgIGlmcmFtZURvYy53cml0ZShjb250ZW50KTtcblxuICAgIHJldHVybiB0cnVlO1xufVxuXG5cbi8qKlxuICogZXh0ZW5kIG9iamVjdCB3aXRoIGtleXMgZnJvbSBhbm90aGVyIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSB0b0V4dGVuZFxuICogQHBhcmFtIHtvYmplY3R9IGZyb21Tb3VyY2VcbiAqL1xuZnVuY3Rpb24gZXh0ZW5kKHRvRXh0ZW5kLCBmcm9tU291cmNlKSB7XG4gICAgT2JqZWN0LmtleXMoZnJvbVNvdXJjZSkuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgdG9FeHRlbmRba2V5XSA9IGZyb21Tb3VyY2Vba2V5XTtcbiAgICB9KTtcbiAgICByZXR1cm4gdG9FeHRlbmQ7XG59XG5cblxuLyoqXG4gKiB1bmlxdWUgd2lsbCBjcmVhdGUgYSB1bmlxdWUgc3RyaW5nIGV2ZXJ5dGltZSBpcyBjYWxsZWQsIHNlcXVlbnRpYWxseSBhbmQgcHJlZml4ZWRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJlZml4XG4gKi9cbmZ1bmN0aW9uIHVuaXF1ZShwcmVmaXgpIHtcbiAgICB2YXIgY291bnQgPSAtMTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gcHJlZml4ICsgJ18nICsgKCsrY291bnQpO1xuICAgIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIG5vb3A6IG5vb3AsXG4gICAgdmFsaWRhdGU6IHZhbGlkYXRlLFxuICAgIGNsZWFyQ2FsbGJhY2tUaW1lb3V0OiBjbGVhckNhbGxiYWNrVGltZW91dCxcbiAgICBjYWxsYmFja1RpbWVvdXQ6IGNhbGxiYWNrVGltZW91dCxcbiAgICBjcmVhdGVFbGVtZW50SW5FbDogY3JlYXRlRWxlbWVudEluRWwsXG4gICAgY3JlYXRlSWZyYW1lV2l0aENvbnRlbnQ6IGNyZWF0ZUlmcmFtZVdpdGhDb250ZW50LFxuICAgIGNyZWF0ZUlmcmFtZTogY3JlYXRlSWZyYW1lLFxuICAgIHNpbXBsZVRlbXBsYXRlOiBzaW1wbGVUZW1wbGF0ZSxcbiAgICBzZXRJZnJhbWVDb250ZW50OiBzZXRJZnJhbWVDb250ZW50LFxuICAgIGV4dGVuZDogZXh0ZW5kLFxuICAgIHVuaXF1ZTogdW5pcXVlXG59O1xuXG4iLCIvKiEgICAgU1dGT2JqZWN0IHYyLjMuMjAxMzA1MjEgPGh0dHA6Ly9naXRodWIuY29tL3N3Zm9iamVjdC9zd2ZvYmplY3Q+XHJcbiAgICBpcyByZWxlYXNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UgPGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwPlxyXG4qL1xyXG5cclxuLyogZ2xvYmFsIEFjdGl2ZVhPYmplY3Q6IGZhbHNlICovXHJcblxyXG4oZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcclxuICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XHJcbiAgICAvLyBBTURcclxuICAgIGRlZmluZShmYWN0b3J5KTtcclxuICB9IGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7XHJcbiAgICAvLyBOb2RlLCBDb21tb25KUy1saWtlXHJcbiAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcclxuICB9IGVsc2Uge1xyXG4gICAgLy8gQnJvd3NlciBnbG9iYWxzIChyb290IGlzIHdpbmRvdylcclxuICAgIHJvb3Quc3dmb2JqZWN0ID0gZmFjdG9yeSgpO1xyXG4gIH1cclxufSh0aGlzLCBmdW5jdGlvbiAoKSB7XHJcblxyXG4gICAgdmFyIFVOREVGID0gXCJ1bmRlZmluZWRcIixcclxuICAgICAgICBPQkpFQ1QgPSBcIm9iamVjdFwiLFxyXG4gICAgICAgIFNIT0NLV0FWRV9GTEFTSCA9IFwiU2hvY2t3YXZlIEZsYXNoXCIsXHJcbiAgICAgICAgU0hPQ0tXQVZFX0ZMQVNIX0FYID0gXCJTaG9ja3dhdmVGbGFzaC5TaG9ja3dhdmVGbGFzaFwiLFxyXG4gICAgICAgIEZMQVNIX01JTUVfVFlQRSA9IFwiYXBwbGljYXRpb24veC1zaG9ja3dhdmUtZmxhc2hcIixcclxuICAgICAgICBFWFBSRVNTX0lOU1RBTExfSUQgPSBcIlNXRk9iamVjdEV4cHJJbnN0XCIsXHJcbiAgICAgICAgT05fUkVBRFlfU1RBVEVfQ0hBTkdFID0gXCJvbnJlYWR5c3RhdGVjaGFuZ2VcIixcclxuXHJcbiAgICAgICAgd2luID0gd2luZG93LFxyXG4gICAgICAgIGRvYyA9IGRvY3VtZW50LFxyXG4gICAgICAgIG5hdiA9IG5hdmlnYXRvcixcclxuXHJcbiAgICAgICAgcGx1Z2luID0gZmFsc2UsXHJcbiAgICAgICAgZG9tTG9hZEZuQXJyID0gW10sXHJcbiAgICAgICAgcmVnT2JqQXJyID0gW10sXHJcbiAgICAgICAgb2JqSWRBcnIgPSBbXSxcclxuICAgICAgICBsaXN0ZW5lcnNBcnIgPSBbXSxcclxuICAgICAgICBzdG9yZWRGYkNvbnRlbnQsXHJcbiAgICAgICAgc3RvcmVkRmJDb250ZW50SWQsXHJcbiAgICAgICAgc3RvcmVkQ2FsbGJhY2tGbixcclxuICAgICAgICBzdG9yZWRDYWxsYmFja09iaixcclxuICAgICAgICBpc0RvbUxvYWRlZCA9IGZhbHNlLFxyXG4gICAgICAgIGlzRXhwcmVzc0luc3RhbGxBY3RpdmUgPSBmYWxzZSxcclxuICAgICAgICBkeW5hbWljU3R5bGVzaGVldCxcclxuICAgICAgICBkeW5hbWljU3R5bGVzaGVldE1lZGlhLFxyXG4gICAgICAgIGF1dG9IaWRlU2hvdyA9IHRydWUsXHJcbiAgICAgICAgZW5jb2RlVVJJRW5hYmxlZCA9IGZhbHNlLFxyXG5cclxuICAgIC8qIENlbnRyYWxpemVkIGZ1bmN0aW9uIGZvciBicm93c2VyIGZlYXR1cmUgZGV0ZWN0aW9uXHJcbiAgICAgICAgLSBVc2VyIGFnZW50IHN0cmluZyBkZXRlY3Rpb24gaXMgb25seSB1c2VkIHdoZW4gbm8gZ29vZCBhbHRlcm5hdGl2ZSBpcyBwb3NzaWJsZVxyXG4gICAgICAgIC0gSXMgZXhlY3V0ZWQgZGlyZWN0bHkgZm9yIG9wdGltYWwgcGVyZm9ybWFuY2VcclxuICAgICovXHJcbiAgICB1YSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgdzNjZG9tID0gdHlwZW9mIGRvYy5nZXRFbGVtZW50QnlJZCAhPT0gVU5ERUYgJiYgdHlwZW9mIGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSAhPT0gVU5ERUYgJiYgdHlwZW9mIGRvYy5jcmVhdGVFbGVtZW50ICE9PSBVTkRFRixcclxuICAgICAgICAgICAgdSA9IG5hdi51c2VyQWdlbnQudG9Mb3dlckNhc2UoKSxcclxuICAgICAgICAgICAgcCA9IG5hdi5wbGF0Zm9ybS50b0xvd2VyQ2FzZSgpLFxyXG4gICAgICAgICAgICB3aW5kb3dzID0gcCA/IC93aW4vLnRlc3QocCkgOiAvd2luLy50ZXN0KHUpLFxyXG4gICAgICAgICAgICBtYWMgPSBwID8gL21hYy8udGVzdChwKSA6IC9tYWMvLnRlc3QodSksXHJcbiAgICAgICAgICAgIHdlYmtpdCA9IC93ZWJraXQvLnRlc3QodSkgPyBwYXJzZUZsb2F0KHUucmVwbGFjZSgvXi4qd2Via2l0XFwvKFxcZCsoXFwuXFxkKyk/KS4qJC8sIFwiJDFcIikpIDogZmFsc2UsIC8vIHJldHVybnMgZWl0aGVyIHRoZSB3ZWJraXQgdmVyc2lvbiBvciBmYWxzZSBpZiBub3Qgd2Via2l0XHJcbiAgICAgICAgICAgIGllID0gbmF2LmFwcE5hbWUgPT09IFwiTWljcm9zb2Z0IEludGVybmV0IEV4cGxvcmVyXCIsXHJcbiAgICAgICAgICAgIHBsYXllclZlcnNpb24gPSBbMCwgMCwgMF0sXHJcbiAgICAgICAgICAgIGQgPSBudWxsO1xyXG4gICAgICAgIGlmICh0eXBlb2YgbmF2LnBsdWdpbnMgIT09IFVOREVGICYmIHR5cGVvZiBuYXYucGx1Z2luc1tTSE9DS1dBVkVfRkxBU0hdID09PSBPQkpFQ1QpIHtcclxuICAgICAgICAgICAgZCA9IG5hdi5wbHVnaW5zW1NIT0NLV0FWRV9GTEFTSF0uZGVzY3JpcHRpb247XHJcbiAgICAgICAgICAgIC8vIG5hdi5taW1lVHlwZXNbXCJhcHBsaWNhdGlvbi94LXNob2Nrd2F2ZS1mbGFzaFwiXS5lbmFibGVkUGx1Z2luIGluZGljYXRlcyB3aGV0aGVyIHBsdWctaW5zIGFyZSBlbmFibGVkIG9yIGRpc2FibGVkIGluIFNhZmFyaSAzK1xyXG4gICAgICAgICAgICBpZiAoZCAmJiAodHlwZW9mIG5hdi5taW1lVHlwZXMgIT09IFVOREVGICYmIG5hdi5taW1lVHlwZXNbRkxBU0hfTUlNRV9UWVBFXSAmJiBuYXYubWltZVR5cGVzW0ZMQVNIX01JTUVfVFlQRV0uZW5hYmxlZFBsdWdpbikpIHtcclxuICAgICAgICAgICAgICAgIHBsdWdpbiA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBpZSA9IGZhbHNlOyAvLyBjYXNjYWRlZCBmZWF0dXJlIGRldGVjdGlvbiBmb3IgSW50ZXJuZXQgRXhwbG9yZXJcclxuICAgICAgICAgICAgICAgIGQgPSBkLnJlcGxhY2UoL14uKlxccysoXFxTK1xccytcXFMrJCkvLCBcIiQxXCIpO1xyXG4gICAgICAgICAgICAgICAgcGxheWVyVmVyc2lvblswXSA9IHRvSW50KGQucmVwbGFjZSgvXiguKilcXC4uKiQvLCBcIiQxXCIpKTtcclxuICAgICAgICAgICAgICAgIHBsYXllclZlcnNpb25bMV0gPSB0b0ludChkLnJlcGxhY2UoL14uKlxcLiguKilcXHMuKiQvLCBcIiQxXCIpKTtcclxuICAgICAgICAgICAgICAgIHBsYXllclZlcnNpb25bMl0gPSAvW2EtekEtWl0vLnRlc3QoZCkgPyB0b0ludChkLnJlcGxhY2UoL14uKlthLXpBLVpdKyguKikkLywgXCIkMVwiKSkgOiAwO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiB3aW4uQWN0aXZlWE9iamVjdCAhPT0gVU5ERUYpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHZhciBhID0gbmV3IEFjdGl2ZVhPYmplY3QoU0hPQ0tXQVZFX0ZMQVNIX0FYKTtcclxuICAgICAgICAgICAgICAgIGlmIChhKSB7IC8vIGEgd2lsbCByZXR1cm4gbnVsbCB3aGVuIEFjdGl2ZVggaXMgZGlzYWJsZWRcclxuICAgICAgICAgICAgICAgICAgICBkID0gYS5HZXRWYXJpYWJsZShcIiR2ZXJzaW9uXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGllID0gdHJ1ZTsgLy8gY2FzY2FkZWQgZmVhdHVyZSBkZXRlY3Rpb24gZm9yIEludGVybmV0IEV4cGxvcmVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGQgPSBkLnNwbGl0KFwiIFwiKVsxXS5zcGxpdChcIixcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBsYXllclZlcnNpb24gPSBbdG9JbnQoZFswXSksIHRvSW50KGRbMV0pLCB0b0ludChkWzJdKV07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhdGNoIChlKSB7fVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4ge3czOiB3M2Nkb20sIHB2OiBwbGF5ZXJWZXJzaW9uLCB3azogd2Via2l0LCBpZTogaWUsIHdpbjogd2luZG93cywgbWFjOiBtYWN9O1xyXG4gICAgfSgpLFxyXG5cclxuICAgIC8qIENyb3NzLWJyb3dzZXIgb25Eb21Mb2FkXHJcbiAgICAgICAgLSBXaWxsIGZpcmUgYW4gZXZlbnQgYXMgc29vbiBhcyB0aGUgRE9NIG9mIGEgd2ViIHBhZ2UgaXMgbG9hZGVkXHJcbiAgICAgICAgLSBJbnRlcm5ldCBFeHBsb3JlciB3b3JrYXJvdW5kIGJhc2VkIG9uIERpZWdvIFBlcmluaSdzIHNvbHV0aW9uOiBodHRwOi8vamF2YXNjcmlwdC5ud2JveC5jb20vSUVDb250ZW50TG9hZGVkL1xyXG4gICAgICAgIC0gUmVndWxhciBvbmxvYWQgc2VydmVzIGFzIGZhbGxiYWNrXHJcbiAgICAqL1xyXG4gICAgb25Eb21Mb2FkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmICghdWEudzMpIHsgcmV0dXJuOyB9XHJcbiAgICAgICAgaWYgKCh0eXBlb2YgZG9jLnJlYWR5U3RhdGUgIT09IFVOREVGICYmIChkb2MucmVhZHlTdGF0ZSA9PT0gXCJjb21wbGV0ZVwiIHx8IGRvYy5yZWFkeVN0YXRlID09PSBcImludGVyYWN0aXZlXCIpKSB8fCAodHlwZW9mIGRvYy5yZWFkeVN0YXRlID09PSBVTkRFRiAmJiAoZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiYm9keVwiKVswXSB8fCBkb2MuYm9keSkpKSB7IC8vIGZ1bmN0aW9uIGlzIGZpcmVkIGFmdGVyIG9ubG9hZCwgZS5nLiB3aGVuIHNjcmlwdCBpcyBpbnNlcnRlZCBkeW5hbWljYWxseVxyXG4gICAgICAgICAgICBjYWxsRG9tTG9hZEZ1bmN0aW9ucygpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWlzRG9tTG9hZGVkKSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZG9jLmFkZEV2ZW50TGlzdGVuZXIgIT09IFVOREVGKSB7XHJcbiAgICAgICAgICAgICAgICBkb2MuYWRkRXZlbnRMaXN0ZW5lcihcIkRPTUNvbnRlbnRMb2FkZWRcIiwgY2FsbERvbUxvYWRGdW5jdGlvbnMsIGZhbHNlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodWEuaWUpIHtcclxuICAgICAgICAgICAgICAgIGRvYy5hdHRhY2hFdmVudChPTl9SRUFEWV9TVEFURV9DSEFOR0UsIGZ1bmN0aW9uIGRldGFjaCgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZG9jLnJlYWR5U3RhdGUgPT09IFwiY29tcGxldGVcIikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkb2MuZGV0YWNoRXZlbnQoT05fUkVBRFlfU1RBVEVfQ0hBTkdFLCBkZXRhY2gpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYWxsRG9tTG9hZEZ1bmN0aW9ucygpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgaWYgKHdpbiA9PSB0b3ApIHsgLy8gaWYgbm90IGluc2lkZSBhbiBpZnJhbWVcclxuICAgICAgICAgICAgICAgICAgICAoZnVuY3Rpb24gY2hlY2tEb21Mb2FkZWRJRSgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzRG9tTG9hZGVkKSB7IHJldHVybjsgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jLmRvY3VtZW50RWxlbWVudC5kb1Njcm9sbChcImxlZnRcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoY2hlY2tEb21Mb2FkZWRJRSwgMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FsbERvbUxvYWRGdW5jdGlvbnMoKTtcclxuICAgICAgICAgICAgICAgICAgICB9KCkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh1YS53aykge1xyXG4gICAgICAgICAgICAgICAgKGZ1bmN0aW9uIGNoZWNrRG9tTG9hZGVkV0soKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzRG9tTG9hZGVkKSB7IHJldHVybjsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghL2xvYWRlZHxjb21wbGV0ZS8udGVzdChkb2MucmVhZHlTdGF0ZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChjaGVja0RvbUxvYWRlZFdLLCAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjYWxsRG9tTG9hZEZ1bmN0aW9ucygpO1xyXG4gICAgICAgICAgICAgICAgfSgpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH0oKTtcclxuXHJcbiAgICBmdW5jdGlvbiBjYWxsRG9tTG9hZEZ1bmN0aW9ucygpIHtcclxuICAgICAgICBpZiAoaXNEb21Mb2FkZWQgfHwgIWRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiYm9keVwiKVswXSkgeyByZXR1cm47IH1cclxuICAgICAgICB0cnkgeyAvLyB0ZXN0IGlmIHdlIGNhbiByZWFsbHkgYWRkL3JlbW92ZSBlbGVtZW50cyB0by9mcm9tIHRoZSBET007IHdlIGRvbid0IHdhbnQgdG8gZmlyZSBpdCB0b28gZWFybHlcclxuICAgICAgICAgICAgdmFyIHQsIHNwYW4gPSBjcmVhdGVFbGVtZW50KFwic3BhblwiKTtcclxuICAgICAgICAgICAgc3Bhbi5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7IC8vaGlkZSB0aGUgc3BhbiBpbiBjYXNlIHNvbWVvbmUgaGFzIHN0eWxlZCBzcGFucyB2aWEgQ1NTXHJcbiAgICAgICAgICAgIHQgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJib2R5XCIpWzBdLmFwcGVuZENoaWxkKHNwYW4pO1xyXG4gICAgICAgICAgICB0LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodCk7XHJcbiAgICAgICAgICAgIHQgPSBudWxsOyAvL2NsZWFyIHRoZSB2YXJpYWJsZXNcclxuICAgICAgICAgICAgc3BhbiA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlKSB7IHJldHVybjsgfVxyXG4gICAgICAgIGlzRG9tTG9hZGVkID0gdHJ1ZTtcclxuICAgICAgICB2YXIgZGwgPSBkb21Mb2FkRm5BcnIubGVuZ3RoO1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGw7IGkrKykge1xyXG4gICAgICAgICAgICBkb21Mb2FkRm5BcnJbaV0oKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gYWRkRG9tTG9hZEV2ZW50KGZuKSB7XHJcbiAgICAgICAgaWYgKGlzRG9tTG9hZGVkKSB7XHJcbiAgICAgICAgICAgIGZuKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBkb21Mb2FkRm5BcnJbZG9tTG9hZEZuQXJyLmxlbmd0aF0gPSBmbjsgLy8gQXJyYXkucHVzaCgpIGlzIG9ubHkgYXZhaWxhYmxlIGluIElFNS41K1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKiBDcm9zcy1icm93c2VyIG9ubG9hZFxyXG4gICAgICAgIC0gQmFzZWQgb24gSmFtZXMgRWR3YXJkcycgc29sdXRpb246IGh0dHA6Ly9icm90aGVyY2FrZS5jb20vc2l0ZS9yZXNvdXJjZXMvc2NyaXB0cy9vbmxvYWQvXHJcbiAgICAgICAgLSBXaWxsIGZpcmUgYW4gZXZlbnQgYXMgc29vbiBhcyBhIHdlYiBwYWdlIGluY2x1ZGluZyBhbGwgb2YgaXRzIGFzc2V0cyBhcmUgbG9hZGVkXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGFkZExvYWRFdmVudChmbikge1xyXG4gICAgICAgIGlmICh0eXBlb2Ygd2luLmFkZEV2ZW50TGlzdGVuZXIgIT09IFVOREVGKSB7XHJcbiAgICAgICAgICAgIHdpbi5hZGRFdmVudExpc3RlbmVyKFwibG9hZFwiLCBmbiwgZmFsc2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICh0eXBlb2YgZG9jLmFkZEV2ZW50TGlzdGVuZXIgIT09IFVOREVGKSB7XHJcbiAgICAgICAgICAgIGRvYy5hZGRFdmVudExpc3RlbmVyKFwibG9hZFwiLCBmbiwgZmFsc2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygd2luLmF0dGFjaEV2ZW50ICE9PSBVTkRFRikge1xyXG4gICAgICAgICAgICBhZGRMaXN0ZW5lcih3aW4sIFwib25sb2FkXCIsIGZuKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIHdpbi5vbmxvYWQgPT09IFwiZnVuY3Rpb25cIikge1xyXG4gICAgICAgICAgICB2YXIgZm5PbGQgPSB3aW4ub25sb2FkO1xyXG4gICAgICAgICAgICB3aW4ub25sb2FkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgZm5PbGQoKTtcclxuICAgICAgICAgICAgICAgIGZuKCk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB3aW4ub25sb2FkID0gZm47XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qIERldGVjdCB0aGUgRmxhc2ggUGxheWVyIHZlcnNpb24gZm9yIG5vbi1JbnRlcm5ldCBFeHBsb3JlciBicm93c2Vyc1xyXG4gICAgICAgIC0gRGV0ZWN0aW5nIHRoZSBwbHVnLWluIHZlcnNpb24gdmlhIHRoZSBvYmplY3QgZWxlbWVudCBpcyBtb3JlIHByZWNpc2UgdGhhbiB1c2luZyB0aGUgcGx1Z2lucyBjb2xsZWN0aW9uIGl0ZW0ncyBkZXNjcmlwdGlvbjpcclxuICAgICAgICAgIGEuIEJvdGggcmVsZWFzZSBhbmQgYnVpbGQgbnVtYmVycyBjYW4gYmUgZGV0ZWN0ZWRcclxuICAgICAgICAgIGIuIEF2b2lkIHdyb25nIGRlc2NyaXB0aW9ucyBieSBjb3JydXB0IGluc3RhbGxlcnMgcHJvdmlkZWQgYnkgQWRvYmVcclxuICAgICAgICAgIGMuIEF2b2lkIHdyb25nIGRlc2NyaXB0aW9ucyBieSBtdWx0aXBsZSBGbGFzaCBQbGF5ZXIgZW50cmllcyBpbiB0aGUgcGx1Z2luIEFycmF5LCBjYXVzZWQgYnkgaW5jb3JyZWN0IGJyb3dzZXIgaW1wb3J0c1xyXG4gICAgICAgIC0gRGlzYWR2YW50YWdlIG9mIHRoaXMgbWV0aG9kIGlzIHRoYXQgaXQgZGVwZW5kcyBvbiB0aGUgYXZhaWxhYmlsaXR5IG9mIHRoZSBET00sIHdoaWxlIHRoZSBwbHVnaW5zIGNvbGxlY3Rpb24gaXMgaW1tZWRpYXRlbHkgYXZhaWxhYmxlXHJcbiAgICAqL1xyXG4gICAgZnVuY3Rpb24gdGVzdFBsYXllclZlcnNpb24oKSB7XHJcbiAgICAgICAgdmFyIGIgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJib2R5XCIpWzBdO1xyXG4gICAgICAgIHZhciBvID0gY3JlYXRlRWxlbWVudChPQkpFQ1QpO1xyXG4gICAgICAgIG8uc2V0QXR0cmlidXRlKFwic3R5bGVcIiwgXCJ2aXNpYmlsaXR5OiBoaWRkZW47XCIpO1xyXG4gICAgICAgIG8uc2V0QXR0cmlidXRlKFwidHlwZVwiLCBGTEFTSF9NSU1FX1RZUEUpO1xyXG4gICAgICAgIHZhciB0ID0gYi5hcHBlbmRDaGlsZChvKTtcclxuICAgICAgICBpZiAodCkge1xyXG4gICAgICAgICAgICB2YXIgY291bnRlciA9IDA7XHJcbiAgICAgICAgICAgIChmdW5jdGlvbiBjaGVja0dldFZhcmlhYmxlKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0LkdldFZhcmlhYmxlICE9PSBVTkRFRikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkID0gdC5HZXRWYXJpYWJsZShcIiR2ZXJzaW9uXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZCA9IGQuc3BsaXQoXCIgXCIpWzFdLnNwbGl0KFwiLFwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVhLnB2ID0gW3RvSW50KGRbMF0pLCB0b0ludChkWzFdKSwgdG9JbnQoZFsyXSldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3QuR2V0VmFyaWFibGUoXCIkdmVyc2lvblwiKSBpcyBrbm93biB0byBmYWlsIGluIEZsYXNoIFBsYXllciA4IG9uIEZpcmVmb3hcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9JZiB0aGlzIGVycm9yIGlzIGVuY291bnRlcmVkLCBhc3N1bWUgRlA4IG9yIGxvd2VyLiBUaW1lIHRvIHVwZ3JhZGUuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHVhLnB2ID0gWzgsIDAsIDBdO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvdW50ZXIgPCAxMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvdW50ZXIrKztcclxuICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGNoZWNrR2V0VmFyaWFibGUsIDEwKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBiLnJlbW92ZUNoaWxkKG8pO1xyXG4gICAgICAgICAgICAgICAgdCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICBtYXRjaFZlcnNpb25zKCk7XHJcbiAgICAgICAgICAgIH0oKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBtYXRjaFZlcnNpb25zKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qIFBlcmZvcm0gRmxhc2ggUGxheWVyIGFuZCBTV0YgdmVyc2lvbiBtYXRjaGluZzsgc3RhdGljIHB1Ymxpc2hpbmcgb25seVxyXG4gICAgKi9cclxuICAgIGZ1bmN0aW9uIG1hdGNoVmVyc2lvbnMoKSB7XHJcbiAgICAgICAgdmFyIHJsID0gcmVnT2JqQXJyLmxlbmd0aDtcclxuICAgICAgICBpZiAocmwgPiAwKSB7XHJcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmw7IGkrKykgeyAvLyBmb3IgZWFjaCByZWdpc3RlcmVkIG9iamVjdCBlbGVtZW50XHJcbiAgICAgICAgICAgICAgICB2YXIgaWQgPSByZWdPYmpBcnJbaV0uaWQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgY2IgPSByZWdPYmpBcnJbaV0uY2FsbGJhY2tGbjtcclxuICAgICAgICAgICAgICAgIHZhciBjYk9iaiA9IHtzdWNjZXNzOiBmYWxzZSwgaWQ6IGlkfTtcclxuICAgICAgICAgICAgICAgIGlmICh1YS5wdlswXSA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgb2JqID0gZ2V0RWxlbWVudEJ5SWQoaWQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvYmopIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhhc1BsYXllclZlcnNpb24ocmVnT2JqQXJyW2ldLnN3ZlZlcnNpb24pICYmICEodWEud2sgJiYgdWEud2sgPCAzMTIpKSB7IC8vIEZsYXNoIFBsYXllciB2ZXJzaW9uID49IHB1Ymxpc2hlZCBTV0YgdmVyc2lvbjogSG91c3Rvbiwgd2UgaGF2ZSBhIG1hdGNoIVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VmlzaWJpbGl0eShpZCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYk9iai5zdWNjZXNzID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYk9iai5yZWYgPSBnZXRPYmplY3RCeUlkKGlkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYk9iai5pZCA9IGlkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNiKGNiT2JqKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChyZWdPYmpBcnJbaV0uZXhwcmVzc0luc3RhbGwgJiYgY2FuRXhwcmVzc0luc3RhbGwoKSkgeyAvLyBzaG93IHRoZSBBZG9iZSBFeHByZXNzIEluc3RhbGwgZGlhbG9nIGlmIHNldCBieSB0aGUgd2ViIHBhZ2UgYXV0aG9yIGFuZCBpZiBzdXBwb3J0ZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhdHQgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dC5kYXRhID0gcmVnT2JqQXJyW2ldLmV4cHJlc3NJbnN0YWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0LndpZHRoID0gb2JqLmdldEF0dHJpYnV0ZShcIndpZHRoXCIpIHx8IFwiMFwiO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0LmhlaWdodCA9IG9iai5nZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIikgfHwgXCIwXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob2JqLmdldEF0dHJpYnV0ZShcImNsYXNzXCIpKSB7IGF0dC5zdHlsZWNsYXNzID0gb2JqLmdldEF0dHJpYnV0ZShcImNsYXNzXCIpOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob2JqLmdldEF0dHJpYnV0ZShcImFsaWduXCIpKSB7IGF0dC5hbGlnbiA9IG9iai5nZXRBdHRyaWJ1dGUoXCJhbGlnblwiKTsgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcGFyc2UgSFRNTCBvYmplY3QgcGFyYW0gZWxlbWVudCdzIG5hbWUtdmFsdWUgcGFpcnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXIgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwID0gb2JqLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwicGFyYW1cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGwgPSBwLmxlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgcGw7IGorKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwW2pdLmdldEF0dHJpYnV0ZShcIm5hbWVcIikudG9Mb3dlckNhc2UoKSAhPT0gXCJtb3ZpZVwiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcltwW2pdLmdldEF0dHJpYnV0ZShcIm5hbWVcIildID0gcFtqXS5nZXRBdHRyaWJ1dGUoXCJ2YWx1ZVwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG93RXhwcmVzc0luc3RhbGwoYXR0LCBwYXIsIGlkLCBjYik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7IC8vIEZsYXNoIFBsYXllciBhbmQgU1dGIHZlcnNpb24gbWlzbWF0Y2ggb3IgYW4gb2xkZXIgV2Via2l0IGVuZ2luZSB0aGF0IGlnbm9yZXMgdGhlIEhUTUwgb2JqZWN0IGVsZW1lbnQncyBuZXN0ZWQgcGFyYW0gZWxlbWVudHM6IGRpc3BsYXkgZmFsbGJhY2sgY29udGVudCBpbnN0ZWFkIG9mIFNXRlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheUZiQ29udGVudChvYmopO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNiKSB7IGNiKGNiT2JqKTsgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7IC8vIGlmIG5vIEZsYXNoIFBsYXllciBpcyBpbnN0YWxsZWQgb3IgdGhlIGZwIHZlcnNpb24gY2Fubm90IGJlIGRldGVjdGVkIHdlIGxldCB0aGUgSFRNTCBvYmplY3QgZWxlbWVudCBkbyBpdHMgam9iIChlaXRoZXIgc2hvdyBhIFNXRiBvciBmYWxsYmFjayBjb250ZW50KVxyXG4gICAgICAgICAgICAgICAgICAgIHNldFZpc2liaWxpdHkoaWQsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjYikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbyA9IGdldE9iamVjdEJ5SWQoaWQpOyAvLyB0ZXN0IHdoZXRoZXIgdGhlcmUgaXMgYW4gSFRNTCBvYmplY3QgZWxlbWVudCBvciBub3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG8gJiYgdHlwZW9mIG8uU2V0VmFyaWFibGUgIT09IFVOREVGKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYk9iai5zdWNjZXNzID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNiT2JqLnJlZiA9IG87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYk9iai5pZCA9IG8uaWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgY2IoY2JPYmopO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKiBNYWluIGZ1bmN0aW9uXHJcbiAgICAgICAgLSBXaWxsIHByZWZlcmFibHkgZXhlY3V0ZSBvbkRvbUxvYWQsIG90aGVyd2lzZSBvbmxvYWQgKGFzIGEgZmFsbGJhY2spXHJcbiAgICAqL1xyXG4gICAgZG9tTG9hZEZuQXJyWzBdID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmIChwbHVnaW4pIHtcclxuICAgICAgICAgICAgdGVzdFBsYXllclZlcnNpb24oKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIG1hdGNoVmVyc2lvbnMoKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIGZ1bmN0aW9uIGdldE9iamVjdEJ5SWQob2JqZWN0SWRTdHIpIHtcclxuICAgICAgICB2YXIgciA9IG51bGwsXHJcbiAgICAgICAgICAgIG8gPSBnZXRFbGVtZW50QnlJZChvYmplY3RJZFN0cik7XHJcblxyXG4gICAgICAgIGlmIChvICYmIG8ubm9kZU5hbWUudG9VcHBlckNhc2UoKSA9PT0gXCJPQkpFQ1RcIikge1xyXG4gICAgICAgICAgICAvL0lmIHRhcmdldGVkIG9iamVjdCBpcyB2YWxpZCBGbGFzaCBmaWxlXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygby5TZXRWYXJpYWJsZSAhPT0gVU5ERUYpIHtcclxuICAgICAgICAgICAgICAgIHIgPSBvO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy9JZiBTZXRWYXJpYWJsZSBpcyBub3Qgd29ya2luZyBvbiB0YXJnZXRlZCBvYmplY3QgYnV0IGEgbmVzdGVkIG9iamVjdCBpc1xyXG4gICAgICAgICAgICAgICAgLy9hdmFpbGFibGUsIGFzc3VtZSBjbGFzc2ljIG5lc3RlZCBvYmplY3QgbWFya3VwLiBSZXR1cm4gbmVzdGVkIG9iamVjdC5cclxuXHJcbiAgICAgICAgICAgICAgICAvL0lmIFNldFZhcmlhYmxlIGlzIG5vdCB3b3JraW5nIG9uIHRhcmdldGVkIG9iamVjdCBhbmQgdGhlcmUgaXMgbm8gbmVzdGVkIG9iamVjdCxcclxuICAgICAgICAgICAgICAgIC8vcmV0dXJuIHRoZSBvcmlnaW5hbCBvYmplY3QgYW55d2F5LiBUaGlzIGlzIHByb2JhYmx5IG5ldyBzaW1wbGlmaWVkIG1hcmt1cC5cclxuXHJcbiAgICAgICAgICAgICAgICByID0gby5nZXRFbGVtZW50c0J5VGFnTmFtZShPQkpFQ1QpWzBdIHx8IG87XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiByO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIFJlcXVpcmVtZW50cyBmb3IgQWRvYmUgRXhwcmVzcyBJbnN0YWxsXHJcbiAgICAgICAgLSBvbmx5IG9uZSBpbnN0YW5jZSBjYW4gYmUgYWN0aXZlIGF0IGEgdGltZVxyXG4gICAgICAgIC0gZnAgNi4wLjY1IG9yIGhpZ2hlclxyXG4gICAgICAgIC0gV2luL01hYyBPUyBvbmx5XHJcbiAgICAgICAgLSBubyBXZWJraXQgZW5naW5lcyBvbGRlciB0aGFuIHZlcnNpb24gMzEyXHJcbiAgICAqL1xyXG4gICAgZnVuY3Rpb24gY2FuRXhwcmVzc0luc3RhbGwoKSB7XHJcbiAgICAgICAgcmV0dXJuICFpc0V4cHJlc3NJbnN0YWxsQWN0aXZlICYmIGhhc1BsYXllclZlcnNpb24oXCI2LjAuNjVcIikgJiYgKHVhLndpbiB8fCB1YS5tYWMpICYmICEodWEud2sgJiYgdWEud2sgPCAzMTIpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIFNob3cgdGhlIEFkb2JlIEV4cHJlc3MgSW5zdGFsbCBkaWFsb2dcclxuICAgICAgICAtIFJlZmVyZW5jZTogaHR0cDovL3d3dy5hZG9iZS5jb20vY2Z1c2lvbi9rbm93bGVkZ2ViYXNlL2luZGV4LmNmbT9pZD02YTI1M2I3NVxyXG4gICAgKi9cclxuICAgIGZ1bmN0aW9uIHNob3dFeHByZXNzSW5zdGFsbChhdHQsIHBhciwgcmVwbGFjZUVsZW1JZFN0ciwgY2FsbGJhY2tGbikge1xyXG5cclxuICAgICAgICB2YXIgb2JqID0gZ2V0RWxlbWVudEJ5SWQocmVwbGFjZUVsZW1JZFN0cik7XHJcblxyXG4gICAgICAgIC8vRW5zdXJlIHRoYXQgcmVwbGFjZUVsZW1JZFN0ciBpcyByZWFsbHkgYSBzdHJpbmcgYW5kIG5vdCBhbiBlbGVtZW50XHJcbiAgICAgICAgcmVwbGFjZUVsZW1JZFN0ciA9IGdldElkKHJlcGxhY2VFbGVtSWRTdHIpO1xyXG5cclxuICAgICAgICBpc0V4cHJlc3NJbnN0YWxsQWN0aXZlID0gdHJ1ZTtcclxuICAgICAgICBzdG9yZWRDYWxsYmFja0ZuID0gY2FsbGJhY2tGbiB8fCBudWxsO1xyXG4gICAgICAgIHN0b3JlZENhbGxiYWNrT2JqID0ge3N1Y2Nlc3M6IGZhbHNlLCBpZDogcmVwbGFjZUVsZW1JZFN0cn07XHJcblxyXG4gICAgICAgIGlmIChvYmopIHtcclxuICAgICAgICAgICAgaWYgKG9iai5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpID09PSBcIk9CSkVDVFwiKSB7IC8vIHN0YXRpYyBwdWJsaXNoaW5nXHJcbiAgICAgICAgICAgICAgICBzdG9yZWRGYkNvbnRlbnQgPSBhYnN0cmFjdEZiQ29udGVudChvYmopO1xyXG4gICAgICAgICAgICAgICAgc3RvcmVkRmJDb250ZW50SWQgPSBudWxsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgeyAvLyBkeW5hbWljIHB1Ymxpc2hpbmdcclxuICAgICAgICAgICAgICAgIHN0b3JlZEZiQ29udGVudCA9IG9iajtcclxuICAgICAgICAgICAgICAgIHN0b3JlZEZiQ29udGVudElkID0gcmVwbGFjZUVsZW1JZFN0cjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBhdHQuaWQgPSBFWFBSRVNTX0lOU1RBTExfSUQ7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYXR0LndpZHRoID09PSBVTkRFRiB8fCAoIS8lJC8udGVzdChhdHQud2lkdGgpICYmIHRvSW50KGF0dC53aWR0aCkgPCAzMTApKSB7IGF0dC53aWR0aCA9IFwiMzEwXCI7IH1cclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBhdHQuaGVpZ2h0ID09PSBVTkRFRiB8fCAoIS8lJC8udGVzdChhdHQuaGVpZ2h0KSAmJiB0b0ludChhdHQuaGVpZ2h0KSA8IDEzNykpIHsgYXR0LmhlaWdodCA9IFwiMTM3XCI7IH1cclxuICAgICAgICAgICAgdmFyIHB0ID0gdWEuaWUgPyBcIkFjdGl2ZVhcIiA6IFwiUGx1Z0luXCIsXHJcbiAgICAgICAgICAgICAgICBmdiA9IFwiTU1yZWRpcmVjdFVSTD1cIiArIGVuY29kZVVSSUNvbXBvbmVudCh3aW4ubG9jYXRpb24udG9TdHJpbmcoKS5yZXBsYWNlKC8mL2csIFwiJTI2XCIpKSArIFwiJk1NcGxheWVyVHlwZT1cIiArIHB0ICsgXCImTU1kb2N0aXRsZT1cIiArIGVuY29kZVVSSUNvbXBvbmVudChkb2MudGl0bGUuc2xpY2UoMCwgNDcpICsgXCIgLSBGbGFzaCBQbGF5ZXIgSW5zdGFsbGF0aW9uXCIpO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHBhci5mbGFzaHZhcnMgIT09IFVOREVGKSB7XHJcbiAgICAgICAgICAgICAgICBwYXIuZmxhc2h2YXJzICs9IFwiJlwiICsgZnY7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBwYXIuZmxhc2h2YXJzID0gZnY7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gSUUgb25seTogd2hlbiBhIFNXRiBpcyBsb2FkaW5nIChBTkQ6IG5vdCBhdmFpbGFibGUgaW4gY2FjaGUpIHdhaXQgZm9yIHRoZSByZWFkeVN0YXRlIG9mIHRoZSBvYmplY3QgZWxlbWVudCB0byBiZWNvbWUgNCBiZWZvcmUgcmVtb3ZpbmcgaXQsXHJcbiAgICAgICAgICAgIC8vIGJlY2F1c2UgeW91IGNhbm5vdCBwcm9wZXJseSBjYW5jZWwgYSBsb2FkaW5nIFNXRiBmaWxlIHdpdGhvdXQgYnJlYWtpbmcgYnJvd3NlciBsb2FkIHJlZmVyZW5jZXMsIGFsc28gb2JqLm9ucmVhZHlzdGF0ZWNoYW5nZSBkb2Vzbid0IHdvcmtcclxuICAgICAgICAgICAgaWYgKHVhLmllICYmIG9iai5yZWFkeVN0YXRlICE9IDQpIHtcclxuICAgICAgICAgICAgICAgIHZhciBuZXdPYmogPSBjcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xyXG4gICAgICAgICAgICAgICAgcmVwbGFjZUVsZW1JZFN0ciArPSBcIlNXRk9iamVjdE5ld1wiO1xyXG4gICAgICAgICAgICAgICAgbmV3T2JqLnNldEF0dHJpYnV0ZShcImlkXCIsIHJlcGxhY2VFbGVtSWRTdHIpO1xyXG4gICAgICAgICAgICAgICAgb2JqLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5ld09iaiwgb2JqKTsgLy8gaW5zZXJ0IHBsYWNlaG9sZGVyIGRpdiB0aGF0IHdpbGwgYmUgcmVwbGFjZWQgYnkgdGhlIG9iamVjdCBlbGVtZW50IHRoYXQgbG9hZHMgZXhwcmVzc2luc3RhbGwuc3dmXHJcbiAgICAgICAgICAgICAgICBvYmouc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xyXG4gICAgICAgICAgICAgICAgcmVtb3ZlU1dGKG9iaik7IC8vcmVtb3ZlU1dGIGFjY2VwdHMgZWxlbWVudHMgbm93XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY3JlYXRlU1dGKGF0dCwgcGFyLCByZXBsYWNlRWxlbUlkU3RyKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyogRnVuY3Rpb25zIHRvIGFic3RyYWN0IGFuZCBkaXNwbGF5IGZhbGxiYWNrIGNvbnRlbnRcclxuICAgICovXHJcbiAgICBmdW5jdGlvbiBkaXNwbGF5RmJDb250ZW50KG9iaikge1xyXG4gICAgICAgIGlmICh1YS5pZSAmJiBvYmoucmVhZHlTdGF0ZSAhPSA0KSB7XHJcbiAgICAgICAgICAgIC8vIElFIG9ubHk6IHdoZW4gYSBTV0YgaXMgbG9hZGluZyAoQU5EOiBub3QgYXZhaWxhYmxlIGluIGNhY2hlKSB3YWl0IGZvciB0aGUgcmVhZHlTdGF0ZSBvZiB0aGUgb2JqZWN0IGVsZW1lbnQgdG8gYmVjb21lIDQgYmVmb3JlIHJlbW92aW5nIGl0LFxyXG4gICAgICAgICAgICAvLyBiZWNhdXNlIHlvdSBjYW5ub3QgcHJvcGVybHkgY2FuY2VsIGEgbG9hZGluZyBTV0YgZmlsZSB3aXRob3V0IGJyZWFraW5nIGJyb3dzZXIgbG9hZCByZWZlcmVuY2VzLCBhbHNvIG9iai5vbnJlYWR5c3RhdGVjaGFuZ2UgZG9lc24ndCB3b3JrXHJcbiAgICAgICAgICAgIG9iai5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XHJcbiAgICAgICAgICAgIHZhciBlbCA9IGNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XHJcbiAgICAgICAgICAgIG9iai5wYXJlbnROb2RlLmluc2VydEJlZm9yZShlbCwgb2JqKTsgLy8gaW5zZXJ0IHBsYWNlaG9sZGVyIGRpdiB0aGF0IHdpbGwgYmUgcmVwbGFjZWQgYnkgdGhlIGZhbGxiYWNrIGNvbnRlbnRcclxuICAgICAgICAgICAgZWwucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoYWJzdHJhY3RGYkNvbnRlbnQob2JqKSwgZWwpO1xyXG4gICAgICAgICAgICByZW1vdmVTV0Yob2JqKTsgLy9yZW1vdmVTV0YgYWNjZXB0cyBlbGVtZW50cyBub3dcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIG9iai5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChhYnN0cmFjdEZiQ29udGVudChvYmopLCBvYmopO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBhYnN0cmFjdEZiQ29udGVudChvYmopIHtcclxuICAgICAgICB2YXIgYWMgPSBjcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xyXG4gICAgICAgIGlmICh1YS53aW4gJiYgdWEuaWUpIHtcclxuICAgICAgICAgICAgYWMuaW5uZXJIVE1MID0gb2JqLmlubmVySFRNTDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHZhciBuZXN0ZWRPYmogPSBvYmouZ2V0RWxlbWVudHNCeVRhZ05hbWUoT0JKRUNUKVswXTtcclxuICAgICAgICAgICAgaWYgKG5lc3RlZE9iaikge1xyXG4gICAgICAgICAgICAgICAgdmFyIGMgPSBuZXN0ZWRPYmouY2hpbGROb2RlcztcclxuICAgICAgICAgICAgICAgIGlmIChjKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsID0gYy5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjbDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKGNbaV0ubm9kZVR5cGUgPT0gMSAmJiBjW2ldLm5vZGVOYW1lID09PSBcIlBBUkFNXCIpICYmICEoY1tpXS5ub2RlVHlwZSA9PSA4KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWMuYXBwZW5kQ2hpbGQoY1tpXS5jbG9uZU5vZGUodHJ1ZSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBhYztcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBjcmVhdGVJZU9iamVjdCh1cmwsIHBhcmFtU3RyKSB7XHJcbiAgICAgICAgdmFyIGRpdiA9IGNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XHJcbiAgICAgICAgZGl2LmlubmVySFRNTCA9IFwiPG9iamVjdCBjbGFzc2lkPSdjbHNpZDpEMjdDREI2RS1BRTZELTExY2YtOTZCOC00NDQ1NTM1NDAwMDAnPjxwYXJhbSBuYW1lPSdtb3ZpZScgdmFsdWU9J1wiICsgdXJsICsgXCInPlwiICsgcGFyYW1TdHIgKyBcIjwvb2JqZWN0PlwiO1xyXG4gICAgICAgIHJldHVybiBkaXYuZmlyc3RDaGlsZDtcclxuICAgIH1cclxuXHJcbiAgICAvKiBDcm9zcy1icm93c2VyIGR5bmFtaWMgU1dGIGNyZWF0aW9uXHJcbiAgICAqL1xyXG4gICAgZnVuY3Rpb24gY3JlYXRlU1dGKGF0dE9iaiwgcGFyT2JqLCBpZCkge1xyXG4gICAgICAgIHZhciByLCBlbCA9IGdldEVsZW1lbnRCeUlkKGlkKTtcclxuICAgICAgICBpZCA9IGdldElkKGlkKTsgLy8gZW5zdXJlIGlkIGlzIHRydWx5IGFuIElEIGFuZCBub3QgYW4gZWxlbWVudFxyXG5cclxuICAgICAgICBpZiAodWEud2sgJiYgdWEud2sgPCAzMTIpIHsgcmV0dXJuIHI7IH1cclxuXHJcbiAgICAgICAgaWYgKGVsKSB7XHJcbiAgICAgICAgICAgIHZhciBvID0gKHVhLmllKSA/IGNyZWF0ZUVsZW1lbnQoXCJkaXZcIikgOiBjcmVhdGVFbGVtZW50KE9CSkVDVCksXHJcbiAgICAgICAgICAgICAgICBhdHRyLFxyXG4gICAgICAgICAgICAgICAgYXR0ckxvd2VyLFxyXG4gICAgICAgICAgICAgICAgcGFyYW07XHJcblxyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGF0dE9iai5pZCA9PT0gVU5ERUYpIHsgLy8gaWYgbm8gJ2lkJyBpcyBkZWZpbmVkIGZvciB0aGUgb2JqZWN0IGVsZW1lbnQsIGl0IHdpbGwgaW5oZXJpdCB0aGUgJ2lkJyBmcm9tIHRoZSBmYWxsYmFjayBjb250ZW50XHJcbiAgICAgICAgICAgICAgICBhdHRPYmouaWQgPSBpZDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy9BZGQgcGFyYW1zXHJcbiAgICAgICAgICAgIGZvciAocGFyYW0gaW4gcGFyT2JqKSB7XHJcbiAgICAgICAgICAgICAgICAvL2ZpbHRlciBvdXQgcHJvdG90eXBlIGFkZGl0aW9ucyBmcm9tIG90aGVyIHBvdGVudGlhbCBsaWJyYXJpZXMgYW5kIElFIHNwZWNpZmljIHBhcmFtIGVsZW1lbnRcclxuICAgICAgICAgICAgICAgIGlmIChwYXJPYmouaGFzT3duUHJvcGVydHkocGFyYW0pICYmIHBhcmFtLnRvTG93ZXJDYXNlKCkgIT09IFwibW92aWVcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZU9ialBhcmFtKG8sIHBhcmFtLCBwYXJPYmpbcGFyYW1dKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy9DcmVhdGUgSUUgb2JqZWN0LCBjb21wbGV0ZSB3aXRoIHBhcmFtIG5vZGVzXHJcbiAgICAgICAgICAgIGlmICh1YS5pZSkgeyBvID0gY3JlYXRlSWVPYmplY3QoYXR0T2JqLmRhdGEsIG8uaW5uZXJIVE1MKTsgfVxyXG5cclxuICAgICAgICAgICAgLy9BZGQgYXR0cmlidXRlcyB0byBvYmplY3RcclxuICAgICAgICAgICAgZm9yIChhdHRyIGluIGF0dE9iaikge1xyXG4gICAgICAgICAgICAgICAgaWYgKGF0dE9iai5oYXNPd25Qcm9wZXJ0eShhdHRyKSkgeyAvLyBmaWx0ZXIgb3V0IHByb3RvdHlwZSBhZGRpdGlvbnMgZnJvbSBvdGhlciBwb3RlbnRpYWwgbGlicmFyaWVzXHJcbiAgICAgICAgICAgICAgICAgICAgYXR0ckxvd2VyID0gYXR0ci50b0xvd2VyQ2FzZSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyAnY2xhc3MnIGlzIGFuIEVDTUE0IHJlc2VydmVkIGtleXdvcmRcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ckxvd2VyID09PSBcInN0eWxlY2xhc3NcIikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIGF0dE9ialthdHRyXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhdHRyTG93ZXIgIT09IFwiY2xhc3NpZFwiICYmIGF0dHJMb3dlciAhPT0gXCJkYXRhXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgby5zZXRBdHRyaWJ1dGUoYXR0ciwgYXR0T2JqW2F0dHJdKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICh1YS5pZSkge1xyXG4gICAgICAgICAgICAgICAgb2JqSWRBcnJbb2JqSWRBcnIubGVuZ3RoXSA9IGF0dE9iai5pZDsgLy8gc3RvcmVkIHRvIGZpeCBvYmplY3QgJ2xlYWtzJyBvbiB1bmxvYWQgKGR5bmFtaWMgcHVibGlzaGluZyBvbmx5KVxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgby5zZXRBdHRyaWJ1dGUoXCJ0eXBlXCIsIEZMQVNIX01JTUVfVFlQRSk7XHJcbiAgICAgICAgICAgICAgICBvLnNldEF0dHJpYnV0ZShcImRhdGFcIiwgYXR0T2JqLmRhdGEpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBlbC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChvLCBlbCk7XHJcbiAgICAgICAgICAgIHIgPSBvO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHI7XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gY3JlYXRlT2JqUGFyYW0oZWwsIHBOYW1lLCBwVmFsdWUpIHtcclxuICAgICAgICB2YXIgcCA9IGNyZWF0ZUVsZW1lbnQoXCJwYXJhbVwiKTtcclxuICAgICAgICBwLnNldEF0dHJpYnV0ZShcIm5hbWVcIiwgcE5hbWUpO1xyXG4gICAgICAgIHAuc2V0QXR0cmlidXRlKFwidmFsdWVcIiwgcFZhbHVlKTtcclxuICAgICAgICBlbC5hcHBlbmRDaGlsZChwKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiBDcm9zcy1icm93c2VyIFNXRiByZW1vdmFsXHJcbiAgICAgICAgLSBFc3BlY2lhbGx5IG5lZWRlZCB0byBzYWZlbHkgYW5kIGNvbXBsZXRlbHkgcmVtb3ZlIGEgU1dGIGluIEludGVybmV0IEV4cGxvcmVyXHJcbiAgICAqL1xyXG4gICAgZnVuY3Rpb24gcmVtb3ZlU1dGKGlkKSB7XHJcbiAgICAgICAgdmFyIG9iaiA9IGdldEVsZW1lbnRCeUlkKGlkKTtcclxuICAgICAgICBpZiAob2JqICYmIG9iai5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpID09PSBcIk9CSkVDVFwiKSB7XHJcbiAgICAgICAgICAgIGlmICh1YS5pZSkge1xyXG4gICAgICAgICAgICAgICAgb2JqLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcclxuICAgICAgICAgICAgICAgIChmdW5jdGlvbiByZW1vdmVTV0ZJbklFKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvYmoucmVhZHlTdGF0ZSA9PSA0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vVGhpcyBzdGVwIHByZXZlbnRzIG1lbW9yeSBsZWFrcyBpbiBJbnRlcm5ldCBFeHBsb3JlclxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIG9iaikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmpbaV0gPT09IFwiZnVuY3Rpb25cIikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ialtpXSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQob2JqKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KHJlbW92ZVNXRkluSUUsIDEwKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgb2JqLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQob2JqKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBpc0VsZW1lbnQoaWQpIHtcclxuICAgICAgICByZXR1cm4gKGlkICYmIGlkLm5vZGVUeXBlICYmIGlkLm5vZGVUeXBlID09PSAxKTtcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBnZXRJZCh0aGluZykge1xyXG4gICAgICAgIHJldHVybiAoaXNFbGVtZW50KHRoaW5nKSkgPyB0aGluZy5pZCA6IHRoaW5nO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIEZ1bmN0aW9ucyB0byBvcHRpbWl6ZSBKYXZhU2NyaXB0IGNvbXByZXNzaW9uXHJcbiAgICAqL1xyXG4gICAgZnVuY3Rpb24gZ2V0RWxlbWVudEJ5SWQoaWQpIHtcclxuXHJcbiAgICAgICAgLy9BbGxvdyB1c2VycyB0byBwYXNzIGFuIGVsZW1lbnQgT1IgYW4gZWxlbWVudCdzIElEXHJcbiAgICAgICAgaWYgKGlzRWxlbWVudChpZCkpIHsgcmV0dXJuIGlkOyB9XHJcblxyXG4gICAgICAgIHZhciBlbCA9IG51bGw7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgZWwgPSBkb2MuZ2V0RWxlbWVudEJ5SWQoaWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZSkge31cclxuICAgICAgICByZXR1cm4gZWw7XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gY3JlYXRlRWxlbWVudChlbCkge1xyXG4gICAgICAgIHJldHVybiBkb2MuY3JlYXRlRWxlbWVudChlbCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy9UbyBhaWQgY29tcHJlc3Npb247IHJlcGxhY2VzIDE0IGluc3RhbmNlcyBvZiBwYXJlc2VJbnQgd2l0aCByYWRpeFxyXG4gICAgZnVuY3Rpb24gdG9JbnQoc3RyKSB7XHJcbiAgICAgICAgcmV0dXJuIHBhcnNlSW50KHN0ciwgMTApO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIFVwZGF0ZWQgYXR0YWNoRXZlbnQgZnVuY3Rpb24gZm9yIEludGVybmV0IEV4cGxvcmVyXHJcbiAgICAgICAgLSBTdG9yZXMgYXR0YWNoRXZlbnQgaW5mb3JtYXRpb24gaW4gYW4gQXJyYXksIHNvIG9uIHVubG9hZCB0aGUgZGV0YWNoRXZlbnQgZnVuY3Rpb25zIGNhbiBiZSBjYWxsZWQgdG8gYXZvaWQgbWVtb3J5IGxlYWtzXHJcbiAgICAqL1xyXG4gICAgZnVuY3Rpb24gYWRkTGlzdGVuZXIodGFyZ2V0LCBldmVudFR5cGUsIGZuKSB7XHJcbiAgICAgICAgdGFyZ2V0LmF0dGFjaEV2ZW50KGV2ZW50VHlwZSwgZm4pO1xyXG4gICAgICAgIGxpc3RlbmVyc0FycltsaXN0ZW5lcnNBcnIubGVuZ3RoXSA9IFt0YXJnZXQsIGV2ZW50VHlwZSwgZm5dO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIEZsYXNoIFBsYXllciBhbmQgU1dGIGNvbnRlbnQgdmVyc2lvbiBtYXRjaGluZ1xyXG4gICAgKi9cclxuICAgIGZ1bmN0aW9uIGhhc1BsYXllclZlcnNpb24ocnYpIHtcclxuICAgICAgICBydiArPSBcIlwiOyAvL0NvZXJjZSBudW1iZXIgdG8gc3RyaW5nLCBpZiBuZWVkZWQuXHJcbiAgICAgICAgdmFyIHB2ID0gdWEucHYsIHYgPSBydi5zcGxpdChcIi5cIik7XHJcbiAgICAgICAgdlswXSA9IHRvSW50KHZbMF0pO1xyXG4gICAgICAgIHZbMV0gPSB0b0ludCh2WzFdKSB8fCAwOyAvLyBzdXBwb3J0cyBzaG9ydCBub3RhdGlvbiwgZS5nLiBcIjlcIiBpbnN0ZWFkIG9mIFwiOS4wLjBcIlxyXG4gICAgICAgIHZbMl0gPSB0b0ludCh2WzJdKSB8fCAwO1xyXG4gICAgICAgIHJldHVybiAocHZbMF0gPiB2WzBdIHx8IChwdlswXSA9PSB2WzBdICYmIHB2WzFdID4gdlsxXSkgfHwgKHB2WzBdID09IHZbMF0gJiYgcHZbMV0gPT0gdlsxXSAmJiBwdlsyXSA+PSB2WzJdKSkgPyB0cnVlIDogZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLyogQ3Jvc3MtYnJvd3NlciBkeW5hbWljIENTUyBjcmVhdGlvblxyXG4gICAgICAgIC0gQmFzZWQgb24gQm9iYnkgdmFuIGRlciBTbHVpcycgc29sdXRpb246IGh0dHA6Ly93d3cuYm9iYnl2YW5kZXJzbHVpcy5jb20vYXJ0aWNsZXMvZHluYW1pY0NTUy5waHBcclxuICAgICovXHJcbiAgICBmdW5jdGlvbiBjcmVhdGVDU1Moc2VsLCBkZWNsLCBtZWRpYSwgbmV3U3R5bGUpIHtcclxuICAgICAgICB2YXIgaCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZShcImhlYWRcIilbMF07XHJcbiAgICAgICAgaWYgKCFoKSB7IHJldHVybjsgfSAvLyB0byBhbHNvIHN1cHBvcnQgYmFkbHkgYXV0aG9yZWQgSFRNTCBwYWdlcyB0aGF0IGxhY2sgYSBoZWFkIGVsZW1lbnRcclxuICAgICAgICB2YXIgbSA9ICh0eXBlb2YgbWVkaWEgPT09IFwic3RyaW5nXCIpID8gbWVkaWEgOiBcInNjcmVlblwiO1xyXG4gICAgICAgIGlmIChuZXdTdHlsZSkge1xyXG4gICAgICAgICAgICBkeW5hbWljU3R5bGVzaGVldCA9IG51bGw7XHJcbiAgICAgICAgICAgIGR5bmFtaWNTdHlsZXNoZWV0TWVkaWEgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWR5bmFtaWNTdHlsZXNoZWV0IHx8IGR5bmFtaWNTdHlsZXNoZWV0TWVkaWEgIT0gbSkge1xyXG4gICAgICAgICAgICAvLyBjcmVhdGUgZHluYW1pYyBzdHlsZXNoZWV0ICsgZ2V0IGEgZ2xvYmFsIHJlZmVyZW5jZSB0byBpdFxyXG4gICAgICAgICAgICB2YXIgcyA9IGNyZWF0ZUVsZW1lbnQoXCJzdHlsZVwiKTtcclxuICAgICAgICAgICAgcy5zZXRBdHRyaWJ1dGUoXCJ0eXBlXCIsIFwidGV4dC9jc3NcIik7XHJcbiAgICAgICAgICAgIHMuc2V0QXR0cmlidXRlKFwibWVkaWFcIiwgbSk7XHJcbiAgICAgICAgICAgIGR5bmFtaWNTdHlsZXNoZWV0ID0gaC5hcHBlbmRDaGlsZChzKTtcclxuICAgICAgICAgICAgaWYgKHVhLmllICYmIHR5cGVvZiBkb2Muc3R5bGVTaGVldHMgIT09IFVOREVGICYmIGRvYy5zdHlsZVNoZWV0cy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICBkeW5hbWljU3R5bGVzaGVldCA9IGRvYy5zdHlsZVNoZWV0c1tkb2Muc3R5bGVTaGVldHMubGVuZ3RoIC0gMV07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZHluYW1pY1N0eWxlc2hlZXRNZWRpYSA9IG07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGFkZCBzdHlsZSBydWxlXHJcbiAgICAgICAgaWYgKGR5bmFtaWNTdHlsZXNoZWV0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZHluYW1pY1N0eWxlc2hlZXQuYWRkUnVsZSAhPT0gVU5ERUYpIHtcclxuICAgICAgICAgICAgICAgIGR5bmFtaWNTdHlsZXNoZWV0LmFkZFJ1bGUoc2VsLCBkZWNsKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZG9jLmNyZWF0ZVRleHROb2RlICE9PSBVTkRFRikge1xyXG4gICAgICAgICAgICAgICAgZHluYW1pY1N0eWxlc2hlZXQuYXBwZW5kQ2hpbGQoZG9jLmNyZWF0ZVRleHROb2RlKHNlbCArIFwiIHtcIiArIGRlY2wgKyBcIn1cIikpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIHNldFZpc2liaWxpdHkoaWQsIGlzVmlzaWJsZSkge1xyXG4gICAgICAgIGlmICghYXV0b0hpZGVTaG93KSB7IHJldHVybjsgfVxyXG4gICAgICAgIHZhciB2ID0gaXNWaXNpYmxlID8gXCJ2aXNpYmxlXCIgOiBcImhpZGRlblwiLFxyXG4gICAgICAgICAgICBlbCA9IGdldEVsZW1lbnRCeUlkKGlkKTtcclxuICAgICAgICBpZiAoaXNEb21Mb2FkZWQgJiYgZWwpIHtcclxuICAgICAgICAgICAgZWwuc3R5bGUudmlzaWJpbGl0eSA9IHY7XHJcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaWQgPT09IFwic3RyaW5nXCIpIHtcclxuICAgICAgICAgICAgY3JlYXRlQ1NTKFwiI1wiICsgaWQsIFwidmlzaWJpbGl0eTpcIiArIHYpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKiBGaWx0ZXIgdG8gYXZvaWQgWFNTIGF0dGFja3NcclxuICAgICovXHJcbiAgICBmdW5jdGlvbiB1cmxFbmNvZGVJZk5lY2Vzc2FyeShzKSB7XHJcbiAgICAgICAgdmFyIHJlZ2V4ID0gL1tcXFxcXFxcIjw+XFwuO10vO1xyXG4gICAgICAgIHZhciBoYXNCYWRDaGFycyA9IHJlZ2V4LmV4ZWMocykgIT09IG51bGw7XHJcbiAgICAgICAgcmV0dXJuIGhhc0JhZENoYXJzICYmIHR5cGVvZiBlbmNvZGVVUklDb21wb25lbnQgIT09IFVOREVGID8gZW5jb2RlVVJJQ29tcG9uZW50KHMpIDogcztcclxuICAgIH1cclxuXHJcbiAgICAvKiBSZWxlYXNlIG1lbW9yeSB0byBhdm9pZCBtZW1vcnkgbGVha3MgY2F1c2VkIGJ5IGNsb3N1cmVzLCBmaXggaGFuZ2luZyBhdWRpby92aWRlbyB0aHJlYWRzIGFuZCBmb3JjZSBvcGVuIHNvY2tldHMvTmV0Q29ubmVjdGlvbnMgdG8gZGlzY29ubmVjdCAoSW50ZXJuZXQgRXhwbG9yZXIgb25seSlcclxuICAgICovXHJcbiAgICB2YXIgY2xlYW51cCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAodWEuaWUpIHtcclxuICAgICAgICAgICAgd2luZG93LmF0dGFjaEV2ZW50KFwib251bmxvYWRcIiwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgLy8gcmVtb3ZlIGxpc3RlbmVycyB0byBhdm9pZCBtZW1vcnkgbGVha3NcclxuICAgICAgICAgICAgICAgIHZhciBsbCA9IGxpc3RlbmVyc0Fyci5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxsOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnNBcnJbaV1bMF0uZGV0YWNoRXZlbnQobGlzdGVuZXJzQXJyW2ldWzFdLCBsaXN0ZW5lcnNBcnJbaV1bMl0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gY2xlYW51cCBkeW5hbWljYWxseSBlbWJlZGRlZCBvYmplY3RzIHRvIGZpeCBhdWRpby92aWRlbyB0aHJlYWRzIGFuZCBmb3JjZSBvcGVuIHNvY2tldHMgYW5kIE5ldENvbm5lY3Rpb25zIHRvIGRpc2Nvbm5lY3RcclxuICAgICAgICAgICAgICAgIHZhciBpbCA9IG9iaklkQXJyLmxlbmd0aDtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgaWw7IGorKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZVNXRihvYmpJZEFycltqXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBjbGVhbnVwIGxpYnJhcnkncyBtYWluIGNsb3N1cmVzIHRvIGF2b2lkIG1lbW9yeSBsZWFrc1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgayBpbiB1YSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHVhW2tdID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHVhID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIGwgaW4gc3dmb2JqZWN0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3dmb2JqZWN0W2xdID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHN3Zm9iamVjdCA9IG51bGw7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH0oKTtcclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIC8qIFB1YmxpYyBBUElcclxuICAgICAgICAgICAgLSBSZWZlcmVuY2U6IGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9zd2ZvYmplY3Qvd2lraS9kb2N1bWVudGF0aW9uXHJcbiAgICAgICAgKi9cclxuICAgICAgICByZWdpc3Rlck9iamVjdDogZnVuY3Rpb24gKG9iamVjdElkU3RyLCBzd2ZWZXJzaW9uU3RyLCB4aVN3ZlVybFN0ciwgY2FsbGJhY2tGbikge1xyXG4gICAgICAgICAgICBpZiAodWEudzMgJiYgb2JqZWN0SWRTdHIgJiYgc3dmVmVyc2lvblN0cikge1xyXG4gICAgICAgICAgICAgICAgdmFyIHJlZ09iaiA9IHt9O1xyXG4gICAgICAgICAgICAgICAgcmVnT2JqLmlkID0gb2JqZWN0SWRTdHI7XHJcbiAgICAgICAgICAgICAgICByZWdPYmouc3dmVmVyc2lvbiA9IHN3ZlZlcnNpb25TdHI7XHJcbiAgICAgICAgICAgICAgICByZWdPYmouZXhwcmVzc0luc3RhbGwgPSB4aVN3ZlVybFN0cjtcclxuICAgICAgICAgICAgICAgIHJlZ09iai5jYWxsYmFja0ZuID0gY2FsbGJhY2tGbjtcclxuICAgICAgICAgICAgICAgIHJlZ09iakFycltyZWdPYmpBcnIubGVuZ3RoXSA9IHJlZ09iajtcclxuICAgICAgICAgICAgICAgIHNldFZpc2liaWxpdHkob2JqZWN0SWRTdHIsIGZhbHNlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChjYWxsYmFja0ZuKSB7XHJcbiAgICAgICAgICAgICAgICBjYWxsYmFja0ZuKHtzdWNjZXNzOiBmYWxzZSwgaWQ6IG9iamVjdElkU3RyfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBnZXRPYmplY3RCeUlkOiBmdW5jdGlvbiAob2JqZWN0SWRTdHIpIHtcclxuICAgICAgICAgICAgaWYgKHVhLnczKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0T2JqZWN0QnlJZChvYmplY3RJZFN0cik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBlbWJlZFNXRjogZnVuY3Rpb24gKHN3ZlVybFN0ciwgcmVwbGFjZUVsZW1JZFN0ciwgd2lkdGhTdHIsIGhlaWdodFN0ciwgc3dmVmVyc2lvblN0ciwgeGlTd2ZVcmxTdHIsIGZsYXNodmFyc09iaiwgcGFyT2JqLCBhdHRPYmosIGNhbGxiYWNrRm4pIHtcclxuXHJcbiAgICAgICAgICAgIHZhciBpZCA9IGdldElkKHJlcGxhY2VFbGVtSWRTdHIpLFxyXG4gICAgICAgICAgICAgICAgY2FsbGJhY2tPYmogPSB7c3VjY2VzczogZmFsc2UsIGlkOiBpZH07XHJcblxyXG4gICAgICAgICAgICBpZiAodWEudzMgJiYgISh1YS53ayAmJiB1YS53ayA8IDMxMikgJiYgc3dmVXJsU3RyICYmIHJlcGxhY2VFbGVtSWRTdHIgJiYgd2lkdGhTdHIgJiYgaGVpZ2h0U3RyICYmIHN3ZlZlcnNpb25TdHIpIHtcclxuICAgICAgICAgICAgICAgIHNldFZpc2liaWxpdHkoaWQsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIGFkZERvbUxvYWRFdmVudChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2lkdGhTdHIgKz0gXCJcIjsgLy8gYXV0by1jb252ZXJ0IHRvIHN0cmluZ1xyXG4gICAgICAgICAgICAgICAgICAgIGhlaWdodFN0ciArPSBcIlwiO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhdHQgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYXR0T2JqICYmIHR5cGVvZiBhdHRPYmogPT09IE9CSkVDVCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIGF0dE9iaikgeyAvLyBjb3B5IG9iamVjdCB0byBhdm9pZCB0aGUgdXNlIG9mIHJlZmVyZW5jZXMsIGJlY2F1c2Ugd2ViIGF1dGhvcnMgb2Z0ZW4gcmV1c2UgYXR0T2JqIGZvciBtdWx0aXBsZSBTV0ZzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRbaV0gPSBhdHRPYmpbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYXR0LmRhdGEgPSBzd2ZVcmxTdHI7XHJcbiAgICAgICAgICAgICAgICAgICAgYXR0LndpZHRoID0gd2lkdGhTdHI7XHJcbiAgICAgICAgICAgICAgICAgICAgYXR0LmhlaWdodCA9IGhlaWdodFN0cjtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFyID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhck9iaiAmJiB0eXBlb2YgcGFyT2JqID09PSBPQkpFQ1QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiBpbiBwYXJPYmopIHsgLy8gY29weSBvYmplY3QgdG8gYXZvaWQgdGhlIHVzZSBvZiByZWZlcmVuY2VzLCBiZWNhdXNlIHdlYiBhdXRob3JzIG9mdGVuIHJldXNlIHBhck9iaiBmb3IgbXVsdGlwbGUgU1dGc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyW2pdID0gcGFyT2JqW2pdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmbGFzaHZhcnNPYmogJiYgdHlwZW9mIGZsYXNodmFyc09iaiA9PT0gT0JKRUNUKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGsgaW4gZmxhc2h2YXJzT2JqKSB7IC8vIGNvcHkgb2JqZWN0IHRvIGF2b2lkIHRoZSB1c2Ugb2YgcmVmZXJlbmNlcywgYmVjYXVzZSB3ZWIgYXV0aG9ycyBvZnRlbiByZXVzZSBmbGFzaHZhcnNPYmogZm9yIG11bHRpcGxlIFNXRnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmbGFzaHZhcnNPYmouaGFzT3duUHJvcGVydHkoaykpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGtleSA9IChlbmNvZGVVUklFbmFibGVkKSA/IGVuY29kZVVSSUNvbXBvbmVudChrKSA6IGssXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gKGVuY29kZVVSSUVuYWJsZWQpID8gZW5jb2RlVVJJQ29tcG9uZW50KGZsYXNodmFyc09ialtrXSkgOiBmbGFzaHZhcnNPYmpba107XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcGFyLmZsYXNodmFycyAhPT0gVU5ERUYpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyLmZsYXNodmFycyArPSBcIiZcIiArIGtleSArIFwiPVwiICsgdmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXIuZmxhc2h2YXJzID0ga2V5ICsgXCI9XCIgKyB2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChoYXNQbGF5ZXJWZXJzaW9uKHN3ZlZlcnNpb25TdHIpKSB7IC8vIGNyZWF0ZSBTV0ZcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9iaiA9IGNyZWF0ZVNXRihhdHQsIHBhciwgcmVwbGFjZUVsZW1JZFN0cik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHQuaWQgPT0gaWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFZpc2liaWxpdHkoaWQsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrT2JqLnN1Y2Nlc3MgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFja09iai5yZWYgPSBvYmo7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrT2JqLmlkID0gb2JqLmlkO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh4aVN3ZlVybFN0ciAmJiBjYW5FeHByZXNzSW5zdGFsbCgpKSB7IC8vIHNob3cgQWRvYmUgRXhwcmVzcyBJbnN0YWxsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0dC5kYXRhID0geGlTd2ZVcmxTdHI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNob3dFeHByZXNzSW5zdGFsbChhdHQsIHBhciwgcmVwbGFjZUVsZW1JZFN0ciwgY2FsbGJhY2tGbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7IC8vIHNob3cgZmFsbGJhY2sgY29udGVudFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRWaXNpYmlsaXR5KGlkLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNhbGxiYWNrRm4pIHsgY2FsbGJhY2tGbihjYWxsYmFja09iaik7IH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGNhbGxiYWNrRm4pIHsgY2FsbGJhY2tGbihjYWxsYmFja09iaik7IH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBzd2l0Y2hPZmZBdXRvSGlkZVNob3c6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgYXV0b0hpZGVTaG93ID0gZmFsc2U7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgZW5hYmxlVXJpRW5jb2Rpbmc6IGZ1bmN0aW9uIChib29sKSB7XHJcbiAgICAgICAgICAgIGVuY29kZVVSSUVuYWJsZWQgPSAodHlwZW9mIGJvb2wgPT09IFVOREVGKSA/IHRydWUgOiBib29sO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIHVhOiB1YSxcclxuXHJcbiAgICAgICAgZ2V0Rmxhc2hQbGF5ZXJWZXJzaW9uOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7bWFqb3I6IHVhLnB2WzBdLCBtaW5vcjogdWEucHZbMV0sIHJlbGVhc2U6IHVhLnB2WzJdfTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBoYXNGbGFzaFBsYXllclZlcnNpb246IGhhc1BsYXllclZlcnNpb24sXHJcblxyXG4gICAgICAgIGNyZWF0ZVNXRjogZnVuY3Rpb24gKGF0dE9iaiwgcGFyT2JqLCByZXBsYWNlRWxlbUlkU3RyKSB7XHJcbiAgICAgICAgICAgIGlmICh1YS53Mykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZVNXRihhdHRPYmosIHBhck9iaiwgcmVwbGFjZUVsZW1JZFN0cik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgc2hvd0V4cHJlc3NJbnN0YWxsOiBmdW5jdGlvbiAoYXR0LCBwYXIsIHJlcGxhY2VFbGVtSWRTdHIsIGNhbGxiYWNrRm4pIHtcclxuICAgICAgICAgICAgaWYgKHVhLnczICYmIGNhbkV4cHJlc3NJbnN0YWxsKCkpIHtcclxuICAgICAgICAgICAgICAgIHNob3dFeHByZXNzSW5zdGFsbChhdHQsIHBhciwgcmVwbGFjZUVsZW1JZFN0ciwgY2FsbGJhY2tGbik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICByZW1vdmVTV0Y6IGZ1bmN0aW9uIChvYmpFbGVtSWRTdHIpIHtcclxuICAgICAgICAgICAgaWYgKHVhLnczKSB7XHJcbiAgICAgICAgICAgICAgICByZW1vdmVTV0Yob2JqRWxlbUlkU3RyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIGNyZWF0ZUNTUzogZnVuY3Rpb24gKHNlbFN0ciwgZGVjbFN0ciwgbWVkaWFTdHIsIG5ld1N0eWxlQm9vbGVhbikge1xyXG4gICAgICAgICAgICBpZiAodWEudzMpIHtcclxuICAgICAgICAgICAgICAgIGNyZWF0ZUNTUyhzZWxTdHIsIGRlY2xTdHIsIG1lZGlhU3RyLCBuZXdTdHlsZUJvb2xlYW4pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgYWRkRG9tTG9hZEV2ZW50OiBhZGREb21Mb2FkRXZlbnQsXHJcblxyXG4gICAgICAgIGFkZExvYWRFdmVudDogYWRkTG9hZEV2ZW50LFxyXG5cclxuICAgICAgICBnZXRRdWVyeVBhcmFtVmFsdWU6IGZ1bmN0aW9uIChwYXJhbSkge1xyXG4gICAgICAgICAgICB2YXIgcSA9IGRvYy5sb2NhdGlvbi5zZWFyY2ggfHwgZG9jLmxvY2F0aW9uLmhhc2g7XHJcbiAgICAgICAgICAgIGlmIChxKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoL1xcPy8udGVzdChxKSkgeyBxID0gcS5zcGxpdChcIj9cIilbMV07IH0gLy8gc3RyaXAgcXVlc3Rpb24gbWFya1xyXG4gICAgICAgICAgICAgICAgaWYgKCFwYXJhbSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB1cmxFbmNvZGVJZk5lY2Vzc2FyeShxKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHZhciBwYWlycyA9IHEuc3BsaXQoXCImXCIpO1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYWlycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYWlyc1tpXS5zdWJzdHJpbmcoMCwgcGFpcnNbaV0uaW5kZXhPZihcIj1cIikpID09IHBhcmFtKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB1cmxFbmNvZGVJZk5lY2Vzc2FyeShwYWlyc1tpXS5zdWJzdHJpbmcoKHBhaXJzW2ldLmluZGV4T2YoXCI9XCIpICsgMSkpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIFwiXCI7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLy8gRm9yIGludGVybmFsIHVzYWdlIG9ubHlcclxuICAgICAgICBleHByZXNzSW5zdGFsbENhbGxiYWNrOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChpc0V4cHJlc3NJbnN0YWxsQWN0aXZlKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgb2JqID0gZ2V0RWxlbWVudEJ5SWQoRVhQUkVTU19JTlNUQUxMX0lEKTtcclxuICAgICAgICAgICAgICAgIGlmIChvYmogJiYgc3RvcmVkRmJDb250ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JqLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKHN0b3JlZEZiQ29udGVudCwgb2JqKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc3RvcmVkRmJDb250ZW50SWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VmlzaWJpbGl0eShzdG9yZWRGYkNvbnRlbnRJZCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1YS5pZSkgeyBzdG9yZWRGYkNvbnRlbnQuc3R5bGUuZGlzcGxheSA9IFwiYmxvY2tcIjsgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc3RvcmVkQ2FsbGJhY2tGbikgeyBzdG9yZWRDYWxsYmFja0ZuKHN0b3JlZENhbGxiYWNrT2JqKTsgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaXNFeHByZXNzSW5zdGFsbEFjdGl2ZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgdmVyc2lvbjogXCIyLjNcIlxyXG5cclxuICAgIH07XHJcbn0pKTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgSW5MaW5lID0gcmVxdWlyZSgnLi9JbkxpbmUnKTtcbnZhciBXcmFwcGVyID0gcmVxdWlyZSgnLi9XcmFwcGVyJyk7XG5cbmZ1bmN0aW9uIEFkKGFkSlRyZWUpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEFkKSkge1xuICAgIHJldHVybiBuZXcgQWQoYWRKVHJlZSk7XG4gIH1cbiAgdGhpcy5pbml0aWFsaXplKGFkSlRyZWUpO1xufVxuXG5BZC5wcm90b3R5cGUuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKGFkSlRyZWUpIHtcbiAgdGhpcy5pZCA9IGFkSlRyZWUuYXR0cignaWQnKTtcbiAgdGhpcy5zZXF1ZW5jZSA9IGFkSlRyZWUuYXR0cignc2VxdWVuY2UnKTtcblxuICBpZihhZEpUcmVlLmluTGluZSkge1xuICAgIHRoaXMuaW5MaW5lID0gbmV3IEluTGluZShhZEpUcmVlLmluTGluZSk7XG4gIH1cblxuICBpZihhZEpUcmVlLndyYXBwZXIpe1xuICAgIHRoaXMud3JhcHBlciA9IG5ldyBXcmFwcGVyKGFkSlRyZWUud3JhcHBlcik7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gQWQ7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHJhY2tpbmdFdmVudCA9IHJlcXVpcmUoJy4vVHJhY2tpbmdFdmVudCcpO1xuXG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucycpO1xuXG52YXIgeG1sID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMveG1sJyk7XG5cblxuZnVuY3Rpb24gQ29tcGFuaW9uKGNvbXBhbmlvbkpUcmVlKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBDb21wYW5pb24pKSB7XG4gICAgcmV0dXJuIG5ldyBDb21wYW5pb24oY29tcGFuaW9uSlRyZWUpO1xuICB9XG5cbiAgLy9SZXF1aXJlZCBFbGVtZW50c1xuICB0aGlzLmNyZWF0aXZlVHlwZSA9IHhtbC5hdHRyKGNvbXBhbmlvbkpUcmVlLnN0YXRpY1Jlc291cmNlLCAnY3JlYXRpdmVUeXBlJyk7XG4gIHRoaXMuc3RhdGljUmVzb3VyY2UgPSB4bWwua2V5VmFsdWUoY29tcGFuaW9uSlRyZWUuc3RhdGljUmVzb3VyY2UpO1xuXG4gIC8vIFdlaXJkIGJ1ZyB3aGVuIHRoZSBKWE9OIHRyZWUgaXMgYnVpbHQgaXQgZG9lc24ndCBoYW5kbGUgY2FzaW5nIHByb3Blcmx5IGluIHRoaXMgc2l0dWF0aW9uLi4uXG4gIHZhciBodG1sUmVzb3VyY2UgPSBudWxsO1xuICBpZiAoeG1sLmtleVZhbHVlKGNvbXBhbmlvbkpUcmVlLkhUTUxSZXNvdXJjZSkpIHtcbiAgICBodG1sUmVzb3VyY2UgPSB4bWwua2V5VmFsdWUoY29tcGFuaW9uSlRyZWUuSFRNTFJlc291cmNlKTtcbiAgfSBlbHNlIGlmICh4bWwua2V5VmFsdWUoY29tcGFuaW9uSlRyZWUuaFRNTFJlc291cmNlKSkge1xuICAgIGh0bWxSZXNvdXJjZSA9IHhtbC5rZXlWYWx1ZShjb21wYW5pb25KVHJlZS5oVE1MUmVzb3VyY2UpO1xuICB9XG4gIHRoaXMuaHRtbFJlc291cmNlID0gaHRtbFJlc291cmNlO1xuXG4gIHZhciBpZnJhbWVSZXNvdXJjZSA9IG51bGw7XG4gIGlmICh4bWwua2V5VmFsdWUoY29tcGFuaW9uSlRyZWUuSUZyYW1lUmVzb3VyY2UpKSB7XG4gICAgaWZyYW1lUmVzb3VyY2UgPSB4bWwua2V5VmFsdWUoY29tcGFuaW9uSlRyZWUuSUZyYW1lUmVzb3VyY2UpO1xuICB9IGVsc2UgaWYgKHhtbC5rZXlWYWx1ZShjb21wYW5pb25KVHJlZS5pRnJhbWVyZXNvdXJjZSkpIHtcbiAgICBpZnJhbWVSZXNvdXJjZSA9IHhtbC5rZXlWYWx1ZShjb21wYW5pb25KVHJlZS5pRnJhbWVyZXNvdXJjZSk7XG4gIH1cbiAgdGhpcy5pZnJhbWVSZXNvdXJjZSA9IGlmcmFtZVJlc291cmNlO1xuXG4gIC8vT3B0aW9uYWwgZmllbGRzXG4gIHRoaXMuaWQgPSB4bWwuYXR0cihjb21wYW5pb25KVHJlZSwgJ2lkJyk7XG4gIHRoaXMud2lkdGggPSB4bWwuYXR0cihjb21wYW5pb25KVHJlZSwgJ3dpZHRoJyk7XG4gIHRoaXMuaGVpZ2h0ID0geG1sLmF0dHIoY29tcGFuaW9uSlRyZWUsICdoZWlnaHQnKTtcbiAgdGhpcy5leHBhbmRlZFdpZHRoID0geG1sLmF0dHIoY29tcGFuaW9uSlRyZWUsICdleHBhbmRlZFdpZHRoJyk7XG4gIHRoaXMuZXhwYW5kZWRIZWlnaHQgPSB4bWwuYXR0cihjb21wYW5pb25KVHJlZSwgJ2V4cGFuZGVkSGVpZ2h0Jyk7XG4gIHRoaXMuc2NhbGFibGUgPSB4bWwuYXR0cihjb21wYW5pb25KVHJlZSwgJ3NjYWxhYmxlJyk7XG4gIHRoaXMubWFpbnRhaW5Bc3BlY3RSYXRpbyA9IHhtbC5hdHRyKGNvbXBhbmlvbkpUcmVlLCAnbWFpbnRhaW5Bc3BlY3RSYXRpbycpO1xuICB0aGlzLm1pblN1Z2dlc3RlZER1cmF0aW9uID0geG1sLmF0dHIoY29tcGFuaW9uSlRyZWUsICdtaW5TdWdnZXN0ZWREdXJhdGlvbicpO1xuICB0aGlzLmFwaUZyYW1ld29yayA9IHhtbC5hdHRyKGNvbXBhbmlvbkpUcmVlLCAnYXBpRnJhbWV3b3JrJyk7XG4gIHRoaXMuY29tcGFuaW9uQ2xpY2tUaHJvdWdoID0geG1sLmtleVZhbHVlKGNvbXBhbmlvbkpUcmVlLmNvbXBhbmlvbkNsaWNrVGhyb3VnaCk7XG4gIHRoaXMudHJhY2tpbmdFdmVudHMgPSBwYXJzZVRyYWNraW5nRXZlbnRzKGNvbXBhbmlvbkpUcmVlLnRyYWNraW5nRXZlbnRzICYmIGNvbXBhbmlvbkpUcmVlLnRyYWNraW5nRXZlbnRzLnRyYWNraW5nKTtcblxuICAvKioqIExvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIHBhcnNlVHJhY2tpbmdFdmVudHModHJhY2tpbmdFdmVudHMpIHtcbiAgICB2YXIgdHJhY2tpbmdzID0gW107XG4gICAgaWYgKHV0aWxpdGllcy5pc0RlZmluZWQodHJhY2tpbmdFdmVudHMpKSB7XG4gICAgICB0cmFja2luZ0V2ZW50cyA9IHV0aWxpdGllcy5pc0FycmF5KHRyYWNraW5nRXZlbnRzKSA/IHRyYWNraW5nRXZlbnRzIDogW3RyYWNraW5nRXZlbnRzXTtcbiAgICAgIHRyYWNraW5nRXZlbnRzLmZvckVhY2goZnVuY3Rpb24gKHRyYWNraW5nRGF0YSkge1xuICAgICAgICB0cmFja2luZ3MucHVzaChuZXcgVHJhY2tpbmdFdmVudCh0cmFja2luZ0RhdGEpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdHJhY2tpbmdzO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQ29tcGFuaW9uOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIExpbmVhciA9IHJlcXVpcmUoJy4vTGluZWFyJyk7XG52YXIgQ29tcGFuaW9uID0gcmVxdWlyZSgnLi9Db21wYW5pb24nKTtcbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbmZ1bmN0aW9uIENyZWF0aXZlKGNyZWF0aXZlSlRyZWUpIHtcbiAgaWYoISh0aGlzIGluc3RhbmNlb2YgQ3JlYXRpdmUpKSB7XG4gICAgcmV0dXJuIG5ldyBDcmVhdGl2ZShjcmVhdGl2ZUpUcmVlKTtcbiAgfVxuXG4gIHRoaXMuaWQgPSBjcmVhdGl2ZUpUcmVlLmF0dHIoJ2lkJyk7XG4gIHRoaXMuc2VxdWVuY2UgPSBjcmVhdGl2ZUpUcmVlLmF0dHIoJ3NlcXVlbmNlJyk7XG4gIHRoaXMuYWRJZCA9IGNyZWF0aXZlSlRyZWUuYXR0cignYWRJZCcpO1xuICB0aGlzLmFwaUZyYW1ld29yayA9IGNyZWF0aXZlSlRyZWUuYXR0cignYXBpRnJhbWV3b3JrJyk7XG5cbiAgaWYoY3JlYXRpdmVKVHJlZS5saW5lYXIpIHtcbiAgICB0aGlzLmxpbmVhciA9IG5ldyBMaW5lYXIoY3JlYXRpdmVKVHJlZS5saW5lYXIpO1xuICB9XG5cbiAgaWYgKGNyZWF0aXZlSlRyZWUuY29tcGFuaW9uQWRzKSB7XG4gICAgdmFyIGNvbXBhbmlvbnMgPSBbXTtcbiAgICB2YXIgY29tcGFuaW9uQWRzID0gY3JlYXRpdmVKVHJlZS5jb21wYW5pb25BZHMgJiYgY3JlYXRpdmVKVHJlZS5jb21wYW5pb25BZHMuY29tcGFuaW9uO1xuICAgIGlmICh1dGlsaXRpZXMuaXNEZWZpbmVkKGNvbXBhbmlvbkFkcykpIHtcbiAgICAgIGNvbXBhbmlvbkFkcyA9IHV0aWxpdGllcy5pc0FycmF5KGNvbXBhbmlvbkFkcykgPyBjb21wYW5pb25BZHMgOiBbY29tcGFuaW9uQWRzXTtcbiAgICAgIGNvbXBhbmlvbkFkcy5mb3JFYWNoKGZ1bmN0aW9uIChjb21wYW5pb25EYXRhKSB7XG4gICAgICAgIGNvbXBhbmlvbnMucHVzaChuZXcgQ29tcGFuaW9uKGNvbXBhbmlvbkRhdGEpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLmNvbXBhbmlvbkFkcyA9IGNvbXBhbmlvbnM7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgYXQgdGhlIGNyZWF0aXZlLlxuICovXG5DcmVhdGl2ZS5wcm90b3R5cGUuaXNTdXBwb3J0ZWQgPSBmdW5jdGlvbigpe1xuICBpZih0aGlzLmxpbmVhcikge1xuICAgIHJldHVybiB0aGlzLmxpbmVhci5pc1N1cHBvcnRlZCgpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5DcmVhdGl2ZS5wYXJzZUNyZWF0aXZlcyA9IGZ1bmN0aW9uIHBhcnNlQ3JlYXRpdmVzKGNyZWF0aXZlc0pUcmVlKSB7XG4gIHZhciBjcmVhdGl2ZXMgPSBbXTtcbiAgdmFyIGNyZWF0aXZlc0RhdGE7XG4gIGlmICh1dGlsaXRpZXMuaXNEZWZpbmVkKGNyZWF0aXZlc0pUcmVlKSAmJiB1dGlsaXRpZXMuaXNEZWZpbmVkKGNyZWF0aXZlc0pUcmVlLmNyZWF0aXZlKSkge1xuICAgIGNyZWF0aXZlc0RhdGEgPSB1dGlsaXRpZXMuaXNBcnJheShjcmVhdGl2ZXNKVHJlZS5jcmVhdGl2ZSkgPyBjcmVhdGl2ZXNKVHJlZS5jcmVhdGl2ZSA6IFtjcmVhdGl2ZXNKVHJlZS5jcmVhdGl2ZV07XG4gICAgY3JlYXRpdmVzRGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChjcmVhdGl2ZSkge1xuICAgICAgY3JlYXRpdmVzLnB1c2gobmV3IENyZWF0aXZlKGNyZWF0aXZlKSk7XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIGNyZWF0aXZlcztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gQ3JlYXRpdmU7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB2YXN0VXRpbCA9IHJlcXVpcmUoJy4vdmFzdFV0aWwnKTtcbnZhciBDcmVhdGl2ZSA9IHJlcXVpcmUoJy4vQ3JlYXRpdmUnKTtcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcbnZhciB4bWwgPSByZXF1aXJlKCcuLi8uLi91dGlscy94bWwnKTtcblxuZnVuY3Rpb24gSW5MaW5lKGlubGluZUpUcmVlKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBJbkxpbmUpKSB7XG4gICAgcmV0dXJuIG5ldyBJbkxpbmUoaW5saW5lSlRyZWUpO1xuICB9XG5cbiAgLy9SZXF1aXJlZCBGaWVsZHNcbiAgdGhpcy5hZFRpdGxlID0geG1sLmtleVZhbHVlKGlubGluZUpUcmVlLmFkVGl0bGUpO1xuICB0aGlzLmFkU3lzdGVtID0geG1sLmtleVZhbHVlKGlubGluZUpUcmVlLmFkU3lzdGVtKTtcbiAgdGhpcy5pbXByZXNzaW9ucyA9IHZhc3RVdGlsLnBhcnNlSW1wcmVzc2lvbnMoaW5saW5lSlRyZWUuaW1wcmVzc2lvbik7XG4gIHRoaXMuY3JlYXRpdmVzID0gQ3JlYXRpdmUucGFyc2VDcmVhdGl2ZXMoaW5saW5lSlRyZWUuY3JlYXRpdmVzKTtcblxuICAvL09wdGlvbmFsIEZpZWxkc1xuICB0aGlzLmRlc2NyaXB0aW9uID0geG1sLmtleVZhbHVlKGlubGluZUpUcmVlLmRlc2NyaXB0aW9uKTtcbiAgdGhpcy5hZHZlcnRpc2VyID0geG1sLmtleVZhbHVlKGlubGluZUpUcmVlLmFkdmVydGlzZXIpO1xuICB0aGlzLnN1cnZleXMgPSBwYXJzZVN1cnZleXMoaW5saW5lSlRyZWUuc3VydmV5KTtcbiAgdGhpcy5lcnJvciA9IHhtbC5rZXlWYWx1ZShpbmxpbmVKVHJlZS5lcnJvcik7XG4gIHRoaXMucHJpY2luZyA9IHhtbC5rZXlWYWx1ZShpbmxpbmVKVHJlZS5wcmljaW5nKTtcbiAgdGhpcy5leHRlbnNpb25zID0gaW5saW5lSlRyZWUuZXh0ZW5zaW9ucztcblxuICAvKioqIExvY2FsIEZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIHBhcnNlU3VydmV5cyhpbmxpbmVTdXJ2ZXlzKSB7XG4gICAgaWYgKGlubGluZVN1cnZleXMpIHtcbiAgICAgIHJldHVybiB1dGlsaXRpZXMudHJhbnNmb3JtQXJyYXkodXRpbGl0aWVzLmlzQXJyYXkoaW5saW5lU3VydmV5cykgPyBpbmxpbmVTdXJ2ZXlzIDogW2lubGluZVN1cnZleXNdLCBmdW5jdGlvbiAoc3VydmV5KSB7XG4gICAgICAgIGlmKHV0aWxpdGllcy5pc05vdEVtcHR5U3RyaW5nKHN1cnZleS5rZXlWYWx1ZSkpe1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB1cmk6IHN1cnZleS5rZXlWYWx1ZSxcbiAgICAgICAgICAgIHR5cGU6IHN1cnZleS5hdHRyKCd0eXBlJylcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gW107XG4gIH1cbn1cblxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBhbGwgdGhlIGNyZWF0aXZlcy5cbiAqL1xuSW5MaW5lLnByb3RvdHlwZS5pc1N1cHBvcnRlZCA9IGZ1bmN0aW9uKCl7XG4gIHZhciBpLGxlbjtcblxuICBpZih0aGlzLmNyZWF0aXZlcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBmb3IoaSA9IDAsIGxlbiA9IHRoaXMuY3JlYXRpdmVzLmxlbmd0aDsgaTwgbGVuOyBpKz0xKXtcbiAgICBpZighdGhpcy5jcmVhdGl2ZXNbaV0uaXNTdXBwb3J0ZWQoKSl7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBJbkxpbmU7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUcmFja2luZ0V2ZW50ID0gcmVxdWlyZSgnLi9UcmFja2luZ0V2ZW50Jyk7XG52YXIgTWVkaWFGaWxlID0gcmVxdWlyZSgnLi9NZWRpYUZpbGUnKTtcbnZhciBWaWRlb0NsaWNrcyA9IHJlcXVpcmUoJy4vVmlkZW9DbGlja3MnKTtcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcbnZhciBwYXJzZXJzID0gcmVxdWlyZSgnLi9wYXJzZXJzJyk7XG5cbnZhciB4bWwgPSByZXF1aXJlKCcuLi8uLi91dGlscy94bWwnKTtcblxuXG5mdW5jdGlvbiBMaW5lYXIobGluZWFySlRyZWUpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIExpbmVhcikpIHtcbiAgICByZXR1cm4gbmV3IExpbmVhcihsaW5lYXJKVHJlZSk7XG4gIH1cblxuICAvL1JlcXVpcmVkIEVsZW1lbnRzXG4gIHRoaXMuZHVyYXRpb24gPSBwYXJzZXJzLmR1cmF0aW9uKHhtbC5rZXlWYWx1ZShsaW5lYXJKVHJlZS5kdXJhdGlvbikpO1xuICB0aGlzLm1lZGlhRmlsZXMgPSBwYXJzZU1lZGlhRmlsZXMobGluZWFySlRyZWUubWVkaWFGaWxlcyAmJiBsaW5lYXJKVHJlZS5tZWRpYUZpbGVzLm1lZGlhRmlsZSk7XG5cbiAgLy9PcHRpb25hbCBmaWVsZHNcbiAgdGhpcy50cmFja2luZ0V2ZW50cyA9IHBhcnNlVHJhY2tpbmdFdmVudHMobGluZWFySlRyZWUudHJhY2tpbmdFdmVudHMgJiYgbGluZWFySlRyZWUudHJhY2tpbmdFdmVudHMudHJhY2tpbmcsIHRoaXMuZHVyYXRpb24pO1xuICB0aGlzLnNraXBvZmZzZXQgPSBwYXJzZXJzLm9mZnNldCh4bWwuYXR0cihsaW5lYXJKVHJlZSwgJ3NraXBvZmZzZXQnKSwgdGhpcy5kdXJhdGlvbik7XG5cbiAgaWYgKGxpbmVhckpUcmVlLnZpZGVvQ2xpY2tzKSB7XG4gICAgdGhpcy52aWRlb0NsaWNrcyA9IG5ldyBWaWRlb0NsaWNrcyhsaW5lYXJKVHJlZS52aWRlb0NsaWNrcyk7XG4gIH1cblxuICBpZihsaW5lYXJKVHJlZS5hZFBhcmFtZXRlcnMpIHtcbiAgICB0aGlzLmFkUGFyYW1ldGVycyA9IHhtbC5rZXlWYWx1ZShsaW5lYXJKVHJlZS5hZFBhcmFtZXRlcnMpO1xuXG4gICAgaWYoeG1sLmF0dHIobGluZWFySlRyZWUuYWRQYXJhbWV0ZXJzLCAneG1sRW5jb2RlZCcpKXtcbiAgICAgIHRoaXMuYWRQYXJhbWV0ZXJzID0geG1sLmRlY29kZSh0aGlzLmFkUGFyYW1ldGVycyk7XG4gICAgfVxuICB9XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBwYXJzZVRyYWNraW5nRXZlbnRzKHRyYWNraW5nRXZlbnRzLCBkdXJhdGlvbikge1xuICAgIHZhciB0cmFja2luZ3MgPSBbXTtcbiAgICBpZiAodXRpbGl0aWVzLmlzRGVmaW5lZCh0cmFja2luZ0V2ZW50cykpIHtcbiAgICAgIHRyYWNraW5nRXZlbnRzID0gdXRpbGl0aWVzLmlzQXJyYXkodHJhY2tpbmdFdmVudHMpID8gdHJhY2tpbmdFdmVudHMgOiBbdHJhY2tpbmdFdmVudHNdO1xuICAgICAgdHJhY2tpbmdFdmVudHMuZm9yRWFjaChmdW5jdGlvbiAodHJhY2tpbmdEYXRhKSB7XG4gICAgICAgIHRyYWNraW5ncy5wdXNoKG5ldyBUcmFja2luZ0V2ZW50KHRyYWNraW5nRGF0YSwgZHVyYXRpb24pKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdHJhY2tpbmdzO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VNZWRpYUZpbGVzKG1lZGlhRmlsZXNKeG9uVHJlZSkge1xuICAgIHZhciBtZWRpYUZpbGVzID0gW107XG4gICAgaWYgKHV0aWxpdGllcy5pc0RlZmluZWQobWVkaWFGaWxlc0p4b25UcmVlKSkge1xuICAgICAgbWVkaWFGaWxlc0p4b25UcmVlID0gdXRpbGl0aWVzLmlzQXJyYXkobWVkaWFGaWxlc0p4b25UcmVlKSA/IG1lZGlhRmlsZXNKeG9uVHJlZSA6IFttZWRpYUZpbGVzSnhvblRyZWVdO1xuXG4gICAgICBtZWRpYUZpbGVzSnhvblRyZWUuZm9yRWFjaChmdW5jdGlvbiAobWZEYXRhKSB7XG4gICAgICAgIG1lZGlhRmlsZXMucHVzaChuZXcgTWVkaWFGaWxlKG1mRGF0YSkpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBtZWRpYUZpbGVzO1xuICB9XG59XG5cbi8qKlxuICogTXVzdCByZXR1cm4gdHJ1ZSBpZiBhdCBsZWFzdCBvbmUgb2YgdGhlIE1lZGlhRmlsZXMnIHR5cGUgaXMgc3VwcG9ydGVkXG4gKi9cbkxpbmVhci5wcm90b3R5cGUuaXNTdXBwb3J0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBpLCBsZW47XG4gIGZvcihpPTAsIGxlbj10aGlzLm1lZGlhRmlsZXMubGVuZ3RoOyBpPGxlbjsgaSs9MSkge1xuICAgIGlmKHRoaXMubWVkaWFGaWxlc1tpXS5pc1N1cHBvcnRlZCgpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IExpbmVhcjsiLCIndXNlIHN0cmljdCc7XG5cbnZhciB4bWwgPSByZXF1aXJlKCcuLi8uLi91dGlscy94bWwnKTtcbnZhciB2YXN0VXRpbCA9IHJlcXVpcmUoJy4vdmFzdFV0aWwnKTtcblxudmFyIGF0dHJpYnV0ZXNMaXN0ID0gW1xuICAvL1JlcXVpcmVkIGF0dHJpYnV0ZXNcbiAgJ2RlbGl2ZXJ5JyxcbiAgJ3R5cGUnLFxuICAnd2lkdGgnLFxuICAnaGVpZ2h0JyxcbiAgLy9PcHRpb25hbCBhdHRyaWJ1dGVzXG4gICdjb2RlYycsXG4gICdpZCcsXG4gICdiaXRyYXRlJyxcbiAgJ21pbkJpdHJhdGUnLFxuICAnbWF4Qml0cmF0ZScsXG4gICdzY2FsYWJsZScsXG4gICdtYWludGFpbkFzcGVjdFJhdGlvJyxcbiAgJ2FwaUZyYW1ld29yaydcbl07XG5cbmZ1bmN0aW9uIE1lZGlhRmlsZShtZWRpYUZpbGVKVHJlZSkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgTWVkaWFGaWxlKSkge1xuICAgIHJldHVybiBuZXcgTWVkaWFGaWxlKG1lZGlhRmlsZUpUcmVlKTtcbiAgfVxuXG4gIC8vUmVxdWlyZWQgYXR0cmlidXRlc1xuICB0aGlzLnNyYyA9IHhtbC5rZXlWYWx1ZShtZWRpYUZpbGVKVHJlZSk7XG5cbiAgZm9yKHZhciB4PTA7IHg8YXR0cmlidXRlc0xpc3QubGVuZ3RoOyB4KyspIHtcbiAgICB2YXIgYXR0cmlidXRlID0gYXR0cmlidXRlc0xpc3RbeF07XG4gICAgdGhpc1thdHRyaWJ1dGVdID0gbWVkaWFGaWxlSlRyZWUuYXR0cihhdHRyaWJ1dGUpO1xuICB9XG59XG5cbk1lZGlhRmlsZS5wcm90b3R5cGUuaXNTdXBwb3J0ZWQgPSBmdW5jdGlvbigpe1xuICBpZih2YXN0VXRpbC5pc1ZQQUlEKHRoaXMpKSB7XG4gICAgcmV0dXJuICEhdmFzdFV0aWwuZmluZFN1cHBvcnRlZFZQQUlEVGVjaCh0aGlzLnR5cGUpO1xuICB9XG5cbiAgaWYgKHRoaXMudHlwZSA9PT0gJ3ZpZGVvL3gtZmx2Jykge1xuICAgIHJldHVybiB2YXN0VXRpbC5pc0ZsYXNoU3VwcG9ydGVkKCk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gTWVkaWFGaWxlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgcGFyc2VycyA9IHJlcXVpcmUoJy4vcGFyc2VycycpO1xuXG52YXIgeG1sID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMveG1sJyk7XG5cbmZ1bmN0aW9uIFRyYWNraW5nRXZlbnQodHJhY2tpbmdKVHJlZSwgZHVyYXRpb24pIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFRyYWNraW5nRXZlbnQpKSB7XG4gICAgcmV0dXJuIG5ldyBUcmFja2luZ0V2ZW50KHRyYWNraW5nSlRyZWUsIGR1cmF0aW9uKTtcbiAgfVxuXG4gIHRoaXMubmFtZSA9IHRyYWNraW5nSlRyZWUuYXR0cignZXZlbnQnKTtcbiAgdGhpcy51cmkgPSB4bWwua2V5VmFsdWUodHJhY2tpbmdKVHJlZSk7XG5cbiAgaWYoJ3Byb2dyZXNzJyA9PT0gdGhpcy5uYW1lKSB7XG4gICAgdGhpcy5vZmZzZXQgPSBwYXJzZXJzLm9mZnNldCh0cmFja2luZ0pUcmVlLmF0dHIoJ29mZnNldCcpLCBkdXJhdGlvbik7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBUcmFja2luZ0V2ZW50OyIsIid1c2Ugc3RyaWN0JztcblxudmFyIEFkID0gcmVxdWlyZSgnLi9BZCcpO1xudmFyIFZBU1RFcnJvciA9IHJlcXVpcmUoJy4vVkFTVEVycm9yJyk7XG52YXIgVkFTVFJlc3BvbnNlID0gcmVxdWlyZSgnLi9WQVNUUmVzcG9uc2UnKTtcbnZhciB2YXN0VXRpbCA9IHJlcXVpcmUoJy4vdmFzdFV0aWwnKTtcblxudmFyIGFzeW5jID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvYXN5bmMnKTtcbnZhciBodHRwID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvaHR0cCcpLmh0dHA7XG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucycpO1xudmFyIHhtbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3htbCcpO1xuXG5mdW5jdGlvbiBWQVNUQ2xpZW50KG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFZBU1RDbGllbnQpKSB7XG4gICAgcmV0dXJuIG5ldyBWQVNUQ2xpZW50KG9wdGlvbnMpO1xuICB9XG4gIHZhciBkZWZhdWx0T3B0aW9ucyA9IHtcbiAgICBXUkFQUEVSX0xJTUlUOiA1XG4gIH07XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHRoaXMuc2V0dGluZ3MgPSB1dGlsaXRpZXMuZXh0ZW5kKHt9LCBvcHRpb25zLCBkZWZhdWx0T3B0aW9ucyk7XG4gIHRoaXMuZXJyb3JVUkxNYWNyb3MgPSBbXTtcbn1cblxuVkFTVENsaWVudC5wcm90b3R5cGUuZ2V0VkFTVFJlc3BvbnNlID0gZnVuY3Rpb24gZ2V0VkFTVFJlc3BvbnNlKGFkVGFnVXJsLCBjYWxsYmFjaykge1xuICB2YXIgdGhhdCA9IHRoaXM7XG5cbiAgdmFyIGVycm9yID0gc2FuaXR5Q2hlY2soYWRUYWdVcmwsIGNhbGxiYWNrKTtcbiAgaWYgKGVycm9yKSB7XG4gICAgaWYgKHV0aWxpdGllcy5pc0Z1bmN0aW9uKGNhbGxiYWNrKSkge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycm9yKTtcbiAgICB9XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cblxuICBhc3luYy53YXRlcmZhbGwoW1xuICAgICAgdGhpcy5fZ2V0VkFTVEFkLmJpbmQodGhpcywgYWRUYWdVcmwpLFxuICAgICAgYnVpbGRWQVNUUmVzcG9uc2VcbiAgICBdLFxuICAgIGNhbGxiYWNrKTtcblxuICAvKioqIExvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIGJ1aWxkVkFTVFJlc3BvbnNlKGFkc0NoYWluLCBjYikge1xuICAgIHRyeSB7XG4gICAgICB2YXIgcmVzcG9uc2UgPSB0aGF0Ll9idWlsZFZBU1RSZXNwb25zZShhZHNDaGFpbik7XG4gICAgICBjYihudWxsLCByZXNwb25zZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY2IoZSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gc2FuaXR5Q2hlY2soYWRUYWdVcmwsIGNiKSB7XG4gICAgaWYgKCFhZFRhZ1VybCkge1xuICAgICAgcmV0dXJuIG5ldyBWQVNURXJyb3IoJ29uIFZBU1RDbGllbnQuZ2V0VkFTVFJlc3BvbnNlLCBtaXNzaW5nIGFkIHRhZyBVUkwnKTtcbiAgICB9XG5cbiAgICBpZiAoIXV0aWxpdGllcy5pc0Z1bmN0aW9uKGNiKSkge1xuICAgICAgcmV0dXJuIG5ldyBWQVNURXJyb3IoJ29uIFZBU1RDbGllbnQuZ2V0VkFTVFJlc3BvbnNlLCBtaXNzaW5nIGNhbGxiYWNrIGZ1bmN0aW9uJyk7XG4gICAgfVxuICB9XG59O1xuXG5WQVNUQ2xpZW50LnByb3RvdHlwZS5fZ2V0VkFTVEFkID0gZnVuY3Rpb24gKGFkVGFnVXJsLCBjYWxsYmFjaykge1xuICB2YXIgdGhhdCA9IHRoaXM7XG5cbiAgZ2V0QWRXYXRlcmZhbGwoYWRUYWdVcmwsIGZ1bmN0aW9uIChlcnJvciwgdmFzdFRyZWUpIHtcbiAgICB2YXIgd2F0ZXJmYWxsQWRzID0gdmFzdFRyZWUgJiYgdXRpbGl0aWVzLmlzQXJyYXkodmFzdFRyZWUuYWRzKSA/IHZhc3RUcmVlLmFkcyA6IG51bGw7XG4gICAgaWYgKGVycm9yKSB7XG4gICAgICB0aGF0Ll90cmFja0Vycm9yKGVycm9yLCB3YXRlcmZhbGxBZHMpO1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycm9yLCB3YXRlcmZhbGxBZHMpO1xuICAgIH1cblxuICAgIGdldEFkKHdhdGVyZmFsbEFkcy5zaGlmdCgpLCBbXSwgd2F0ZXJmYWxsSGFuZGxlcik7XG5cbiAgICAvKioqIExvY2FsIGZ1bmN0aW9ucyAqKiovXG4gICAgZnVuY3Rpb24gd2F0ZXJmYWxsSGFuZGxlcihlcnJvciwgYWRDaGFpbikge1xuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIHRoYXQuX3RyYWNrRXJyb3IoZXJyb3IsIGFkQ2hhaW4pO1xuICAgICAgICBpZiAod2F0ZXJmYWxsQWRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBnZXRBZCh3YXRlcmZhbGxBZHMuc2hpZnQoKSxbXSwgd2F0ZXJmYWxsSGFuZGxlcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2FsbGJhY2soZXJyb3IsIGFkQ2hhaW4pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYWxsYmFjayhudWxsLCBhZENoYWluKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gZ2V0QWRXYXRlcmZhbGwoYWRUYWdVcmwsIGNhbGxiYWNrKSB7XG4gICAgdmFyIHJlcXVlc3RWYXN0WE1MID0gdGhhdC5fcmVxdWVzdFZBU1RYbWwuYmluZCh0aGF0LCBhZFRhZ1VybCk7XG4gICAgYXN5bmMud2F0ZXJmYWxsKFtcbiAgICAgIHJlcXVlc3RWYXN0WE1MLFxuICAgICAgYnVpbGRWYXN0V2F0ZXJmYWxsXG4gICAgXSwgY2FsbGJhY2spO1xuICB9XG5cbiAgZnVuY3Rpb24gYnVpbGRWYXN0V2F0ZXJmYWxsKHhtbFN0ciwgY2FsbGJhY2spIHtcbiAgICB2YXIgdmFzdFRyZWU7XG4gICAgdHJ5IHtcbiAgICAgIHZhc3RUcmVlID0geG1sLnRvSlhPTlRyZWUoeG1sU3RyKTtcblxuICAgICAgaWYodXRpbGl0aWVzLmlzQXJyYXkodmFzdFRyZWUuYWQpKSB7XG4gICAgICAgIHZhc3RUcmVlLmFkcyA9IHZhc3RUcmVlLmFkO1xuICAgICAgfSBlbHNlIGlmKHZhc3RUcmVlLmFkKXtcbiAgICAgICAgdmFzdFRyZWUuYWRzID0gW3Zhc3RUcmVlLmFkXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhc3RUcmVlLmFkcyA9IFtdO1xuICAgICAgfVxuICAgICAgY2FsbGJhY2sodmFsaWRhdGVWQVNUVHJlZSh2YXN0VHJlZSksIHZhc3RUcmVlKTtcblxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNhbGxiYWNrKG5ldyBWQVNURXJyb3IoXCJvbiBWQVNUQ2xpZW50LmdldFZBU1RBZC5idWlsZFZhc3RXYXRlcmZhbGwsIGVycm9yIHBhcnNpbmcgeG1sXCIsIDEwMCksIG51bGwpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHZhbGlkYXRlVkFTVFRyZWUodmFzdFRyZWUpIHtcbiAgICB2YXIgdmFzdFZlcnNpb24gPSB4bWwuYXR0cih2YXN0VHJlZSwgJ3ZlcnNpb24nKTtcblxuICAgIGlmICghdmFzdFRyZWUuYWQpIHtcbiAgICAgIHJldHVybiBuZXcgVkFTVEVycm9yKCdvbiBWQVNUQ2xpZW50LmdldFZBU1RBZC52YWxpZGF0ZVZBU1RUcmVlLCBubyBBZCBpbiBWQVNUIHRyZWUnLCAzMDMpO1xuICAgIH1cblxuICAgIGlmICh2YXN0VmVyc2lvbiAmJiAodmFzdFZlcnNpb24gIT0gMyAmJiB2YXN0VmVyc2lvbiAhPSAyKSkge1xuICAgICAgcmV0dXJuIG5ldyBWQVNURXJyb3IoJ29uIFZBU1RDbGllbnQuZ2V0VkFTVEFkLnZhbGlkYXRlVkFTVFRyZWUsIG5vdCBzdXBwb3J0ZWQgVkFTVCB2ZXJzaW9uIFwiJyArIHZhc3RWZXJzaW9uICsgJ1wiJywgMTAyKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldEFkKGFkVGFnVXJsLCBhZENoYWluLCBjYWxsYmFjaykge1xuICAgIGlmIChhZENoYWluLmxlbmd0aCA+PSB0aGF0LldSQVBQRVJfTElNSVQpIHtcbiAgICAgIHJldHVybiBjYWxsYmFjayhuZXcgVkFTVEVycm9yKFwib24gVkFTVENsaWVudC5nZXRWQVNUQWQuZ2V0QWQsIHBsYXllcnMgd3JhcHBlciBsaW1pdCByZWFjaGVkICh0aGUgbGltaXQgaXMgXCIgKyB0aGF0LldSQVBQRVJfTElNSVQgKyBcIilcIiwgMzAyKSwgYWRDaGFpbik7XG4gICAgfVxuXG4gICAgYXN5bmMud2F0ZXJmYWxsKFtcbiAgICAgIGZ1bmN0aW9uIChuZXh0KSB7XG4gICAgICAgIGlmICh1dGlsaXRpZXMuaXNTdHJpbmcoYWRUYWdVcmwpKSB7XG4gICAgICAgICAgcmVxdWVzdFZBU1RBZChhZFRhZ1VybCwgbmV4dCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbmV4dChudWxsLCBhZFRhZ1VybCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBidWlsZEFkXG4gICAgXSwgZnVuY3Rpb24gKGVycm9yLCBhZCkge1xuICAgICAgaWYgKGFkKSB7XG4gICAgICAgIGFkQ2hhaW4ucHVzaChhZCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChlcnJvcikge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyb3IsIGFkQ2hhaW4pO1xuICAgICAgfVxuXG4gICAgICBpZiAoYWQud3JhcHBlcikge1xuICAgICAgICByZXR1cm4gZ2V0QWQoYWQud3JhcHBlci5WQVNUQWRUYWdVUkksIGFkQ2hhaW4sIGNhbGxiYWNrKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGFkQ2hhaW4pO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gYnVpbGRBZChhZEp4b25UcmVlLCBjYWxsYmFjaykge1xuICAgIHRyeSB7XG4gICAgICB2YXIgYWQgPSBuZXcgQWQoYWRKeG9uVHJlZSk7XG4gICAgICBjYWxsYmFjayh2YWxpZGF0ZUFkKGFkKSwgYWQpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNhbGxiYWNrKG5ldyBWQVNURXJyb3IoJ29uIFZBU1RDbGllbnQuZ2V0VkFTVEFkLmJ1aWxkQWQsIGVycm9yIHBhcnNpbmcgeG1sJywgMTAwKSwgbnVsbCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdmFsaWRhdGVBZChhZCkge1xuICAgIHZhciB3cmFwcGVyID0gYWQud3JhcHBlcjtcbiAgICB2YXIgaW5MaW5lID0gYWQuaW5MaW5lO1xuICAgIHZhciBlcnJNc2dQcmVmaXggPSAnb24gVkFTVENsaWVudC5nZXRWQVNUQWQudmFsaWRhdGVBZCwgJztcblxuICAgIGlmIChpbkxpbmUgJiYgd3JhcHBlcikge1xuICAgICAgcmV0dXJuIG5ldyBWQVNURXJyb3IoZXJyTXNnUHJlZml4ICtcIkluTGluZSBhbmQgV3JhcHBlciBib3RoIGZvdW5kIG9uIHRoZSBzYW1lIEFkXCIsIDEwMSk7XG4gICAgfVxuXG4gICAgaWYgKCFpbkxpbmUgJiYgIXdyYXBwZXIpIHtcbiAgICAgIHJldHVybiBuZXcgVkFTVEVycm9yKGVyck1zZ1ByZWZpeCArIFwibm9yIHdyYXBwZXIgbm9yIGlubGluZSBlbGVtZW50cyBmb3VuZCBvbiB0aGUgQWRcIiwgMTAxKTtcbiAgICB9XG5cbiAgICBpZiAoaW5MaW5lICYmICFpbkxpbmUuaXNTdXBwb3J0ZWQoKSkge1xuICAgICAgcmV0dXJuIG5ldyBWQVNURXJyb3IoZXJyTXNnUHJlZml4ICsgXCJjb3VsZCBub3QgZmluZCBNZWRpYUZpbGUgdGhhdCBpcyBzdXBwb3J0ZWQgYnkgdGhpcyB2aWRlbyBwbGF5ZXJcIiwgNDAzKTtcbiAgICB9XG5cbiAgICBpZiAod3JhcHBlciAmJiAhd3JhcHBlci5WQVNUQWRUYWdVUkkpIHtcbiAgICAgIHJldHVybiBuZXcgVkFTVEVycm9yKGVyck1zZ1ByZWZpeCArIFwibWlzc2luZyAnVkFTVEFkVGFnVVJJJyBpbiB3cmFwcGVyXCIsIDEwMSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBmdW5jdGlvbiByZXF1ZXN0VkFTVEFkKGFkVGFnVXJsLCBjYWxsYmFjaykge1xuICAgIHRoYXQuX3JlcXVlc3RWQVNUWG1sKGFkVGFnVXJsLCBmdW5jdGlvbiAoZXJyb3IsIHhtbFN0cikge1xuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnJvcik7XG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICB2YXIgdmFzdFRyZWUgPSB4bWwudG9KWE9OVHJlZSh4bWxTdHIpO1xuICAgICAgICBjYWxsYmFjayh2YWxpZGF0ZVZBU1RUcmVlKHZhc3RUcmVlKSwgdmFzdFRyZWUuYWQpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWxsYmFjayhuZXcgVkFTVEVycm9yKFwib24gVkFTVENsaWVudC5nZXRWQVNUQWQucmVxdWVzdFZBU1RBZCwgZXJyb3IgcGFyc2luZyB4bWxcIiwgMTAwKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn07XG5cblZBU1RDbGllbnQucHJvdG90eXBlLl9yZXF1ZXN0VkFTVFhtbCA9IGZ1bmN0aW9uIHJlcXVlc3RWQVNUWG1sKGFkVGFnVXJsLCBjYWxsYmFjaykge1xuICB0cnkge1xuICAgIGlmICh1dGlsaXRpZXMuaXNGdW5jdGlvbihhZFRhZ1VybCkpIHtcbiAgICAgIGFkVGFnVXJsKHJlcXVlc3RIYW5kbGVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaHR0cC5nZXQoYWRUYWdVcmwsIHJlcXVlc3RIYW5kbGVyLCB7XG4gICAgICAgIHdpdGhDcmVkZW50aWFsczogdHJ1ZVxuICAgICAgfSk7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgY2FsbGJhY2soZSk7XG4gIH1cblxuICAvKioqIExvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIHJlcXVlc3RIYW5kbGVyKGVycm9yLCByZXNwb25zZSwgc3RhdHVzKSB7XG4gICAgaWYgKGVycm9yKSB7XG4gICAgICB2YXIgZXJyTXNnID0gdXRpbGl0aWVzLmlzRGVmaW5lZChzdGF0dXMpID9cbiAgICAgIFwib24gVkFTVENsaWVudC5yZXF1ZXN0VmFzdFhNTCwgSFRUUCByZXF1ZXN0IGVycm9yIHdpdGggc3RhdHVzICdcIiArIHN0YXR1cyArIFwiJ1wiIDpcbiAgICAgICAgXCJvbiBWQVNUQ2xpZW50LnJlcXVlc3RWYXN0WE1MLCBFcnJvciBnZXR0aW5nIHRoZSB0aGUgVkFTVCBYTUwgd2l0aCBoZSBwYXNzZWQgYWRUYWdYTUwgZm5cIjtcbiAgICAgIHJldHVybiBjYWxsYmFjayhuZXcgVkFTVEVycm9yKGVyck1zZywgMzAxKSwgbnVsbCk7XG4gICAgfVxuXG4gICAgY2FsbGJhY2sobnVsbCwgcmVzcG9uc2UpO1xuICB9XG59O1xuXG5WQVNUQ2xpZW50LnByb3RvdHlwZS5fYnVpbGRWQVNUUmVzcG9uc2UgPSBmdW5jdGlvbiBidWlsZFZBU1RSZXNwb25zZShhZHNDaGFpbikge1xuICB2YXIgcmVzcG9uc2UgPSBuZXcgVkFTVFJlc3BvbnNlKCk7XG4gIGFkZEFkc1RvUmVzcG9uc2UocmVzcG9uc2UsIGFkc0NoYWluKTtcbiAgdmFsaWRhdGVSZXNwb25zZShyZXNwb25zZSk7XG5cbiAgcmV0dXJuIHJlc3BvbnNlO1xuXG4gIC8vKioqIExvY2FsIGZ1bmN0aW9uICoqKipcbiAgZnVuY3Rpb24gYWRkQWRzVG9SZXNwb25zZShyZXNwb25zZSwgYWRzKSB7XG4gICAgYWRzLmZvckVhY2goZnVuY3Rpb24gKGFkKSB7XG4gICAgICByZXNwb25zZS5hZGRBZChhZCk7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiB2YWxpZGF0ZVJlc3BvbnNlKHJlc3BvbnNlKSB7XG4gICAgdmFyIHByb2dyZXNzRXZlbnRzID0gcmVzcG9uc2UudHJhY2tpbmdFdmVudHMucHJvZ3Jlc3M7XG5cbiAgICBpZiAoIXJlc3BvbnNlLmhhc0xpbmVhcigpKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFwib24gVkFTVENsaWVudC5fYnVpbGRWQVNUUmVzcG9uc2UsIFJlY2VpdmVkIGFuIEFkIHR5cGUgdGhhdCBpcyBub3Qgc3VwcG9ydGVkXCIsIDIwMCk7XG4gICAgfVxuXG4gICAgaWYgKHJlc3BvbnNlLmR1cmF0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoXCJvbiBWQVNUQ2xpZW50Ll9idWlsZFZBU1RSZXNwb25zZSwgTWlzc2luZyBkdXJhdGlvbiBmaWVsZCBpbiBWQVNUIHJlc3BvbnNlXCIsIDEwMSk7XG4gICAgfVxuXG4gICAgaWYgKHByb2dyZXNzRXZlbnRzKSB7XG4gICAgICBwcm9ncmVzc0V2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChwcm9ncmVzc0V2ZW50KSB7XG4gICAgICAgIGlmICghdXRpbGl0aWVzLmlzTnVtYmVyKHByb2dyZXNzRXZlbnQub2Zmc2V0KSkge1xuICAgICAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoXCJvbiBWQVNUQ2xpZW50Ll9idWlsZFZBU1RSZXNwb25zZSwgbWlzc2luZyBvciB3cm9uZyBvZmZzZXQgYXR0cmlidXRlIG9uIHByb2dyZXNzIHRyYWNraW5nIGV2ZW50XCIsIDEwMSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufTtcblxuVkFTVENsaWVudC5wcm90b3R5cGUuX3RyYWNrRXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IsIGFkQ2hhaW4pIHtcbiAgaWYgKCF1dGlsaXRpZXMuaXNBcnJheShhZENoYWluKSB8fCBhZENoYWluLmxlbmd0aCA9PT0gMCkgeyAvL1RoZXJlIGlzIG5vdGhpbmcgdG8gdHJhY2tcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgZXJyb3JVUkxNYWNyb3MgPSBbXTtcbiAgYWRDaGFpbi5mb3JFYWNoKGFkZEVycm9yVXJsTWFjcm9zKTtcbiAgdmFzdFV0aWwudHJhY2soZXJyb3JVUkxNYWNyb3MsIHtFUlJPUkNPREU6IGVycm9yLmNvZGUgfHwgOTAwfSk7ICAvLzkwMCA8PT0gVW5kZWZpbmVkIGVycm9yXG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgICoqKi9cbiAgZnVuY3Rpb24gYWRkRXJyb3JVcmxNYWNyb3MoYWQpIHtcbiAgICBpZiAoYWQud3JhcHBlciAmJiBhZC53cmFwcGVyLmVycm9yKSB7XG4gICAgICBlcnJvclVSTE1hY3Jvcy5wdXNoKGFkLndyYXBwZXIuZXJyb3IpO1xuICAgIH1cblxuICAgIGlmIChhZC5pbkxpbmUgJiYgYWQuaW5MaW5lLmVycm9yKSB7XG4gICAgICBlcnJvclVSTE1hY3Jvcy5wdXNoKGFkLmluTGluZS5lcnJvcik7XG4gICAgfVxuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZBU1RDbGllbnQ7XG4iLCIndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIFZBU1RFcnJvcihtZXNzYWdlLCBjb2RlKSB7XG4gIHRoaXMubWVzc2FnZSA9ICdWQVNUIEVycm9yOiAnICsgKG1lc3NhZ2UgfHwgJycpO1xuICBpZiAoY29kZSkge1xuICAgIHRoaXMuY29kZSA9IGNvZGU7XG4gIH1cbn1cblxuVkFTVEVycm9yLnByb3RvdHlwZSA9IG5ldyBFcnJvcigpO1xuVkFTVEVycm9yLnByb3RvdHlwZS5uYW1lID0gXCJWQVNUIEVycm9yXCI7XG5cbm1vZHVsZS5leHBvcnRzID0gVkFTVEVycm9yOyIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBJbm5lciBoZWxwZXIgY2xhc3MgdGhhdCBkZWFscyB3aXRoIHRoZSBsb2dpYyBvZiB0aGUgaW5kaXZpZHVhbCBzdGVwcyBuZWVkZWQgdG8gc2V0dXAgYW4gYWQgaW4gdGhlIHBsYXllci5cbiAqXG4gKiBAcGFyYW0gcGxheWVyIHtvYmplY3R9IGluc3RhbmNlIG9mIHRoZSBwbGF5ZXIgdGhhdCB3aWxsIHBsYXkgdGhlIGFkLiBJdCBhc3N1bWVzIHRoYXQgdGhlIHZpZGVvanMtY29udHJpYi1hZHMgcGx1Z2luXG4gKiAgICAgICAgICAgICAgICAgICAgICAgIGhhcyBiZWVuIGluaXRpYWxpemVkIHdoZW4geW91IHVzZSBpdHMgdXRpbGl0eSBmdW5jdGlvbnMuXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cblxudmFyIFZBU1RSZXNwb25zZSA9IHJlcXVpcmUoJy4vVkFTVFJlc3BvbnNlJyk7XG52YXIgVkFTVEVycm9yID0gcmVxdWlyZSgnLi9WQVNURXJyb3InKTtcbnZhciBWQVNUVHJhY2tlciA9IHJlcXVpcmUoJy4vVkFTVFRyYWNrZXInKTtcbnZhciB2YXN0VXRpbCA9IHJlcXVpcmUoJy4vdmFzdFV0aWwnKTtcblxudmFyIGFzeW5jID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvYXN5bmMnKTtcbnZhciBkb20gPSByZXF1aXJlKCcuLi8uLi91dGlscy9kb20nKTtcbnZhciBwbGF5ZXJVdGlscyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3BsYXllclV0aWxzJyk7XG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucycpO1xuXG5mdW5jdGlvbiBWQVNUSW50ZWdyYXRvcihwbGF5ZXIpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFZBU1RJbnRlZ3JhdG9yKSkge1xuICAgIHJldHVybiBuZXcgVkFTVEludGVncmF0b3IocGxheWVyKTtcbiAgfVxuXG4gIHRoaXMucGxheWVyID0gcGxheWVyO1xufVxuXG5WQVNUSW50ZWdyYXRvci5wcm90b3R5cGUucGxheUFkID0gZnVuY3Rpb24gcGxheUFkKHZhc3RSZXNwb25zZSwgY2FsbGJhY2spIHtcbiAgdmFyIHRoYXQgPSB0aGlzO1xuICBjYWxsYmFjayA9IGNhbGxiYWNrIHx8IHV0aWxpdGllcy5ub29wO1xuXG4gIGlmICghKHZhc3RSZXNwb25zZSBpbnN0YW5jZW9mIFZBU1RSZXNwb25zZSkpIHtcbiAgICByZXR1cm4gY2FsbGJhY2sobmV3IFZBU1RFcnJvcignT24gVkFTVEludGVncmF0b3IsIG1pc3NpbmcgcmVxdWlyZWQgVkFTVFJlc3BvbnNlJykpO1xuICB9XG5cbiAgYXN5bmMud2F0ZXJmYWxsKFtcbiAgICBmdW5jdGlvbiAobmV4dCkge1xuICAgICAgbmV4dChudWxsLCB2YXN0UmVzcG9uc2UpO1xuICAgIH0sXG4gICAgdGhpcy5fc2VsZWN0QWRTb3VyY2UuYmluZCh0aGlzKSxcbiAgICB0aGlzLl9jcmVhdGVWQVNUVHJhY2tlci5iaW5kKHRoaXMpLFxuICAgIHRoaXMuX2FkZENsaWNrVGhyb3VnaC5iaW5kKHRoaXMpLFxuICAgIHRoaXMuX2FkZFNraXBCdXR0b24uYmluZCh0aGlzKSxcbiAgICB0aGlzLl9zZXR1cEV2ZW50cy5iaW5kKHRoaXMpLFxuICAgIHRoaXMuX3BsYXlTZWxlY3RlZEFkLmJpbmQodGhpcylcbiAgXSwgZnVuY3Rpb24gKGVycm9yLCByZXNwb25zZSkge1xuICAgIGlmIChlcnJvciAmJiByZXNwb25zZSkge1xuICAgICAgdGhhdC5fdHJhY2tFcnJvcihlcnJvciwgcmVzcG9uc2UpO1xuICAgIH1cbiAgICBjYWxsYmFjayhlcnJvciwgcmVzcG9uc2UpO1xuICB9KTtcblxuICB0aGlzLl9hZFVuaXQgPSB7XG4gICAgX3NyYzogbnVsbCxcbiAgICB0eXBlOiAnVkFTVCcsXG4gICAgcGF1c2VBZDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhhdC5wbGF5ZXIucGF1c2UodHJ1ZSk7XG4gICAgfSxcblxuICAgIHJlc3VtZUFkOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGF0LnBsYXllci5wbGF5KHRydWUpO1xuICAgIH0sXG5cbiAgICBpc1BhdXNlZDogZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIHRoYXQucGxheWVyLnBhdXNlZCh0cnVlKTtcbiAgICB9LFxuXG4gICAgZ2V0U3JjOiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fc3JjO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gdGhpcy5fYWRVbml0O1xufTtcblxuVkFTVEludGVncmF0b3IucHJvdG90eXBlLl9zZWxlY3RBZFNvdXJjZSA9IGZ1bmN0aW9uIHNlbGVjdEFkU291cmNlKHJlc3BvbnNlLCBjYWxsYmFjaykge1xuICB2YXIgc291cmNlO1xuXG4gIHZhciBwbGF5ZXJXaWR0aCA9IGRvbS5nZXREaW1lbnNpb24odGhpcy5wbGF5ZXIuZWwoKSkud2lkdGg7XG4gIHJlc3BvbnNlLm1lZGlhRmlsZXMuc29ydChmdW5jdGlvbiBjb21wYXJlVG8oYSwgYikge1xuICAgIHZhciBkZWx0YUEgPSBNYXRoLmFicyhwbGF5ZXJXaWR0aCAtIGEud2lkdGgpO1xuICAgIHZhciBkZWx0YUIgPSBNYXRoLmFicyhwbGF5ZXJXaWR0aCAtIGIud2lkdGgpO1xuICAgIHJldHVybiBkZWx0YUEgLSBkZWx0YUI7XG4gIH0pO1xuXG4gIHNvdXJjZSA9IHRoaXMucGxheWVyLnNlbGVjdFNvdXJjZShyZXNwb25zZS5tZWRpYUZpbGVzKS5zb3VyY2U7XG5cbiAgaWYgKHNvdXJjZSkge1xuICAgIGlmICh0aGlzLl9hZFVuaXQpIHtcbiAgICAgIHRoaXMuX2FkVW5pdC5fc3JjID0gc291cmNlO1xuICAgIH1cbiAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgc291cmNlLCByZXNwb25zZSk7XG4gIH1cblxuICAvLyBjb2RlIDQwMyA8PT0gQ291bGRuJ3QgZmluZCBNZWRpYUZpbGUgdGhhdCBpcyBzdXBwb3J0ZWQgYnkgdGhpcyB2aWRlbyBwbGF5ZXJcbiAgY2FsbGJhY2sobmV3IFZBU1RFcnJvcihcIkNvdWxkIG5vdCBmaW5kIEFkIG1lZGlhZmlsZSBzdXBwb3J0ZWQgYnkgdGhpcyBwbGF5ZXJcIiwgNDAzKSwgcmVzcG9uc2UpO1xufTtcblxuVkFTVEludGVncmF0b3IucHJvdG90eXBlLl9jcmVhdGVWQVNUVHJhY2tlciA9IGZ1bmN0aW9uIGNyZWF0ZVZBU1RUcmFja2VyKGFkTWVkaWFGaWxlLCByZXNwb25zZSwgY2FsbGJhY2spIHtcbiAgdHJ5IHtcbiAgICBjYWxsYmFjayhudWxsLCBhZE1lZGlhRmlsZSwgbmV3IFZBU1RUcmFja2VyKGFkTWVkaWFGaWxlLnNyYywgcmVzcG9uc2UpLCByZXNwb25zZSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjYWxsYmFjayhlLCByZXNwb25zZSk7XG4gIH1cbn07XG5cblZBU1RJbnRlZ3JhdG9yLnByb3RvdHlwZS5fc2V0dXBFdmVudHMgPSBmdW5jdGlvbiBzZXR1cEV2ZW50cyhhZE1lZGlhRmlsZSwgdHJhY2tlciwgcmVzcG9uc2UsIGNhbGxiYWNrKSB7XG4gIHZhciBwcmV2aW91c2x5TXV0ZWQ7XG4gIHZhciBwbGF5ZXIgPSB0aGlzLnBsYXllcjtcbiAgcGxheWVyLm9uKCdmdWxsc2NyZWVuY2hhbmdlJywgdHJhY2tGdWxsc2NyZWVuQ2hhbmdlKTtcbiAgcGxheWVyLm9uKCd2YXN0LmFkU3RhcnQnLCB0cmFja0ltcHJlc3Npb25zKTtcbiAgcGxheWVyLm9uKCdwYXVzZScsIHRyYWNrUGF1c2UpO1xuICBwbGF5ZXIub24oJ3RpbWV1cGRhdGUnLCB0cmFja1Byb2dyZXNzKTtcbiAgcGxheWVyLm9uKCd2b2x1bWVjaGFuZ2UnLCB0cmFja1ZvbHVtZUNoYW5nZSk7XG5cbiAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsndmFzdC5hZEVuZCcsICd2YXN0LmFkc0NhbmNlbCddLCB1bmJpbmRFdmVudHMpO1xuICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWyd2YXN0LmFkRW5kJywgJ3Zhc3QuYWRzQ2FuY2VsJywgJ3Zhc3QuYWRTa2lwJ10sIGZ1bmN0aW9uKGV2dCl7XG4gICAgaWYoZXZ0LnR5cGUgPT09ICd2YXN0LmFkRW5kJyl7XG4gICAgICB0cmFja2VyLnRyYWNrQ29tcGxldGUoKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBjYWxsYmFjayhudWxsLCBhZE1lZGlhRmlsZSwgcmVzcG9uc2UpO1xuXG4gIC8qKiogTG9jYWwgRnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gdW5iaW5kRXZlbnRzKCkge1xuICAgIHBsYXllci5vZmYoJ2Z1bGxzY3JlZW5jaGFuZ2UnLCB0cmFja0Z1bGxzY3JlZW5DaGFuZ2UpO1xuICAgIHBsYXllci5vZmYoJ3Zhc3QuYWRTdGFydCcsIHRyYWNrSW1wcmVzc2lvbnMpO1xuICAgIHBsYXllci5vZmYoJ3BhdXNlJywgdHJhY2tQYXVzZSk7XG4gICAgcGxheWVyLm9mZigndGltZXVwZGF0ZScsIHRyYWNrUHJvZ3Jlc3MpO1xuICAgIHBsYXllci5vZmYoJ3ZvbHVtZWNoYW5nZScsIHRyYWNrVm9sdW1lQ2hhbmdlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYWNrRnVsbHNjcmVlbkNoYW5nZSgpIHtcbiAgICBpZiAocGxheWVyLmlzRnVsbHNjcmVlbigpKSB7XG4gICAgICB0cmFja2VyLnRyYWNrRnVsbHNjcmVlbigpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0cmFja2VyLnRyYWNrRXhpdEZ1bGxzY3JlZW4oKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB0cmFja1BhdXNlKCkge1xuICAgIC8vTk9URTogd2hlbmV2ZXIgYSB2aWRlbyBlbmRzIHRoZSB2aWRlbyBFbGVtZW50IHRyaWdnZXJzIGEgJ3BhdXNlJyBldmVudCBiZWZvcmUgdGhlICdlbmRlZCcgZXZlbnQuXG4gICAgLy8gICAgICBXZSBzaG91bGQgbm90IHRyYWNrIHRoaXMgcGF1c2UgZXZlbnQgYmVjYXVzZSBpdCBtYWtlcyB0aGUgVkFTVCB0cmFja2luZyBjb25mdXNpbmcgYWdhaW4gd2UgdXNlIGFcbiAgICAvLyAgICAgIFRocmVzaG9sZCBvZiAyIHNlY29uZHMgdG8gcHJldmVudCBmYWxzZSBwb3NpdGl2ZXMgb24gSU9TLlxuICAgIGlmIChNYXRoLmFicyhwbGF5ZXIuZHVyYXRpb24oKSAtIHBsYXllci5jdXJyZW50VGltZSgpKSA8IDIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cmFja2VyLnRyYWNrUGF1c2UoKTtcbiAgICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWydwbGF5JywgJ3Zhc3QuYWRFbmQnLCAndmFzdC5hZHNDYW5jZWwnXSwgZnVuY3Rpb24gKGV2dCkge1xuICAgICAgaWYoZXZ0LnR5cGUgPT09ICdwbGF5Jyl7XG4gICAgICAgIHRyYWNrZXIudHJhY2tSZXN1bWUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYWNrUHJvZ3Jlc3MoKSB7XG4gICAgdmFyIGN1cnJlbnRUaW1lSW5NcyA9IHBsYXllci5jdXJyZW50VGltZSgpICogMTAwMDtcbiAgICB0cmFja2VyLnRyYWNrUHJvZ3Jlc3MoY3VycmVudFRpbWVJbk1zKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYWNrSW1wcmVzc2lvbnMoKSB7XG4gICAgdHJhY2tlci50cmFja0ltcHJlc3Npb25zKCk7XG4gICAgdHJhY2tlci50cmFja0NyZWF0aXZlVmlldygpO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJhY2tWb2x1bWVDaGFuZ2UoKSB7XG4gICAgdmFyIG11dGVkID0gcGxheWVyLm11dGVkKCk7XG4gICAgaWYgKG11dGVkKSB7XG4gICAgICB0cmFja2VyLnRyYWNrTXV0ZSgpO1xuICAgIH0gZWxzZSBpZiAocHJldmlvdXNseU11dGVkKSB7XG4gICAgICB0cmFja2VyLnRyYWNrVW5tdXRlKCk7XG4gICAgfVxuICAgIHByZXZpb3VzbHlNdXRlZCA9IG11dGVkO1xuICB9XG59O1xuXG5WQVNUSW50ZWdyYXRvci5wcm90b3R5cGUuX2FkZFNraXBCdXR0b24gPSBmdW5jdGlvbiBhZGRTa2lwQnV0dG9uKHNvdXJjZSwgdHJhY2tlciwgcmVzcG9uc2UsIGNhbGxiYWNrKSB7XG4gIHZhciBza2lwT2Zmc2V0SW5TZWM7XG4gIHZhciB0aGF0ID0gdGhpcztcblxuICBpZiAodXRpbGl0aWVzLmlzTnVtYmVyKHJlc3BvbnNlLnNraXBvZmZzZXQpKSB7XG4gICAgc2tpcE9mZnNldEluU2VjID0gcmVzcG9uc2Uuc2tpcG9mZnNldCAvIDEwMDA7XG4gICAgYWRkU2tpcEJ1dHRvblRvUGxheWVyKHRoaXMucGxheWVyLCBza2lwT2Zmc2V0SW5TZWMpO1xuICB9XG4gIGNhbGxiYWNrKG51bGwsIHNvdXJjZSwgdHJhY2tlciwgcmVzcG9uc2UpO1xuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb24gKioqL1xuICBmdW5jdGlvbiBhZGRTa2lwQnV0dG9uVG9QbGF5ZXIocGxheWVyLCBza2lwT2Zmc2V0KSB7XG4gICAgdmFyIHNraXBCdXR0b24gPSBjcmVhdGVTa2lwQnV0dG9uKHBsYXllcik7XG4gICAgdmFyIHVwZGF0ZVNraXBCdXR0b24gPSB1cGRhdGVTa2lwQnV0dG9uU3RhdGUuYmluZCh0aGF0LCBza2lwQnV0dG9uLCBza2lwT2Zmc2V0LCBwbGF5ZXIpO1xuXG4gICAgcGxheWVyLmVsKCkuYXBwZW5kQ2hpbGQoc2tpcEJ1dHRvbik7XG4gICAgcGxheWVyLm9uKCd0aW1ldXBkYXRlJywgdXBkYXRlU2tpcEJ1dHRvbik7XG5cbiAgICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWyd2YXN0LmFkRW5kJywgJ3Zhc3QuYWRzQ2FuY2VsJ10sIHJlbW92ZVNraXBCdXR0b24pO1xuXG4gICAgZnVuY3Rpb24gcmVtb3ZlU2tpcEJ1dHRvbigpIHtcbiAgICAgIHBsYXllci5vZmYoJ3RpbWV1cGRhdGUnLCB1cGRhdGVTa2lwQnV0dG9uKTtcbiAgICAgIGRvbS5yZW1vdmUoc2tpcEJ1dHRvbik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlU2tpcEJ1dHRvbihwbGF5ZXIpIHtcbiAgICB2YXIgc2tpcEJ1dHRvbiA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgIGRvbS5hZGRDbGFzcyhza2lwQnV0dG9uLCBcInZhc3Qtc2tpcC1idXR0b25cIik7XG5cbiAgICBza2lwQnV0dG9uLm9uY2xpY2sgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgaWYgKGRvbS5oYXNDbGFzcyhza2lwQnV0dG9uLCAnZW5hYmxlZCcpKSB7XG4gICAgICAgIHRyYWNrZXIudHJhY2tTa2lwKCk7XG4gICAgICAgIHBsYXllci50cmlnZ2VyKCd2YXN0LmFkU2tpcCcpO1xuICAgICAgfVxuXG4gICAgICAvL1dlIHByZXZlbnQgZXZlbnQgcHJvcGFnYXRpb24gdG8gYXZvaWQgcHJvYmxlbXMgd2l0aCB0aGUgY2xpY2tUaHJvdWdoIGFuZCBzbyBvblxuICAgICAgaWYgKHdpbmRvdy5FdmVudC5wcm90b3R5cGUuc3RvcFByb3BhZ2F0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIHNraXBCdXR0b247XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVTa2lwQnV0dG9uU3RhdGUoc2tpcEJ1dHRvbiwgc2tpcE9mZnNldCwgcGxheWVyKSB7XG4gICAgdmFyIHRpbWVMZWZ0ID0gTWF0aC5jZWlsKHNraXBPZmZzZXQgLSBwbGF5ZXIuY3VycmVudFRpbWUoKSk7XG4gICAgaWYgKHRpbWVMZWZ0ID4gMCkge1xuICAgICAgc2tpcEJ1dHRvbi5pbm5lckhUTUwgPSBcIlNraXAgaW4gXCIgKyB1dGlsaXRpZXMudG9GaXhlZERpZ2l0cyh0aW1lTGVmdCwgMikgKyBcIi4uLlwiO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIWRvbS5oYXNDbGFzcyhza2lwQnV0dG9uLCAnZW5hYmxlZCcpKSB7XG4gICAgICAgIGRvbS5hZGRDbGFzcyhza2lwQnV0dG9uLCAnZW5hYmxlZCcpO1xuICAgICAgICBza2lwQnV0dG9uLmlubmVySFRNTCA9IFwiU2tpcCBhZFwiO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuVkFTVEludGVncmF0b3IucHJvdG90eXBlLl9hZGRDbGlja1Rocm91Z2ggPSBmdW5jdGlvbiBhZGRDbGlja1Rocm91Z2gobWVkaWFGaWxlLCB0cmFja2VyLCByZXNwb25zZSwgY2FsbGJhY2spIHtcbiAgdmFyIHBsYXllciA9IHRoaXMucGxheWVyO1xuICB2YXIgYmxvY2tlciA9IGNyZWF0ZUNsaWNrVGhyb3VnaEJsb2NrZXIocGxheWVyLCB0cmFja2VyLCByZXNwb25zZSk7XG4gIHZhciB1cGRhdGVCbG9ja2VyID0gdXBkYXRlQmxvY2tlclVSTC5iaW5kKHRoaXMsIGJsb2NrZXIsIHJlc3BvbnNlLCBwbGF5ZXIpO1xuXG4gIHBsYXllci5lbCgpLmluc2VydEJlZm9yZShibG9ja2VyLCBwbGF5ZXIuY29udHJvbEJhci5lbCgpKTtcbiAgcGxheWVyLm9uKCd0aW1ldXBkYXRlJywgdXBkYXRlQmxvY2tlcik7XG4gIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3Zhc3QuYWRFbmQnLCAndmFzdC5hZHNDYW5jZWwnXSwgcmVtb3ZlQmxvY2tlcik7XG5cbiAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIG1lZGlhRmlsZSwgdHJhY2tlciwgcmVzcG9uc2UpO1xuXG4gIC8qKiogTG9jYWwgRnVuY3Rpb25zICoqKi9cblxuICBmdW5jdGlvbiBjcmVhdGVDbGlja1Rocm91Z2hCbG9ja2VyKHBsYXllciwgdHJhY2tlciwgcmVzcG9uc2UpIHtcbiAgICB2YXIgYmxvY2tlciA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYVwiKTtcbiAgICB2YXIgY2xpY2tUaHJvdWdoTWFjcm8gPSByZXNwb25zZS5jbGlja1Rocm91Z2g7XG5cbiAgICBkb20uYWRkQ2xhc3MoYmxvY2tlciwgJ3Zhc3QtYmxvY2tlcicpO1xuICAgIGJsb2NrZXIuaHJlZiA9IGdlbmVyYXRlQ2xpY2tUaHJvdWdoVVJMKGNsaWNrVGhyb3VnaE1hY3JvLCBwbGF5ZXIpO1xuXG4gICAgaWYgKHV0aWxpdGllcy5pc1N0cmluZyhjbGlja1Rocm91Z2hNYWNybykpIHtcbiAgICAgIGJsb2NrZXIudGFyZ2V0ID0gXCJfYmxhbmtcIjtcbiAgICB9XG5cbiAgICBibG9ja2VyLm9uY2xpY2sgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgaWYgKHBsYXllci5wYXVzZWQoKSkge1xuICAgICAgICBwbGF5ZXIucGxheSgpO1xuXG4gICAgICAgIC8vV2UgcHJldmVudCBldmVudCBwcm9wYWdhdGlvbiB0byBhdm9pZCBwcm9ibGVtcyB3aXRoIHRoZSBwbGF5ZXIncyBub3JtYWwgcGF1c2UgbWVjaGFuaXNtXG4gICAgICAgIGlmICh3aW5kb3cuRXZlbnQucHJvdG90eXBlLnN0b3BQcm9wYWdhdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHBsYXllci5wYXVzZSgpO1xuICAgICAgdHJhY2tlci50cmFja0NsaWNrKCk7XG4gICAgfTtcblxuICAgIHJldHVybiBibG9ja2VyO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlQmxvY2tlclVSTChibG9ja2VyLCByZXNwb25zZSwgcGxheWVyKSB7XG4gICAgYmxvY2tlci5ocmVmID0gZ2VuZXJhdGVDbGlja1Rocm91Z2hVUkwocmVzcG9uc2UuY2xpY2tUaHJvdWdoLCBwbGF5ZXIpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2VuZXJhdGVDbGlja1Rocm91Z2hVUkwoY2xpY2tUaHJvdWdoTWFjcm8sIHBsYXllcikge1xuICAgIHZhciB2YXJpYWJsZXMgPSB7XG4gICAgICBBU1NFVFVSSTogbWVkaWFGaWxlLnNyYyxcbiAgICAgIENPTlRFTlRQTEFZSEVBRDogdmFzdFV0aWwuZm9ybWF0UHJvZ3Jlc3MocGxheWVyLmN1cnJlbnRUaW1lKCkgKiAxMDAwKVxuICAgIH07XG5cbiAgICByZXR1cm4gY2xpY2tUaHJvdWdoTWFjcm8gPyB2YXN0VXRpbC5wYXJzZVVSTE1hY3JvKGNsaWNrVGhyb3VnaE1hY3JvLCB2YXJpYWJsZXMpIDogJyMnO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVtb3ZlQmxvY2tlcigpIHtcbiAgICBwbGF5ZXIub2ZmKCd0aW1ldXBkYXRlJywgdXBkYXRlQmxvY2tlcik7XG4gICAgZG9tLnJlbW92ZShibG9ja2VyKTtcbiAgfVxufTtcblxuVkFTVEludGVncmF0b3IucHJvdG90eXBlLl9wbGF5U2VsZWN0ZWRBZCA9IGZ1bmN0aW9uIHBsYXlTZWxlY3RlZEFkKHNvdXJjZSwgcmVzcG9uc2UsIGNhbGxiYWNrKSB7XG4gIHZhciBwbGF5ZXIgPSB0aGlzLnBsYXllcjtcblxuICBwbGF5ZXIucHJlbG9hZChcImF1dG9cIik7IC8vd2l0aG91dCBwcmVsb2FkPWF1dG8gdGhlIGR1cmF0aW9uY2hhbmdlIGV2ZW50IGlzIG5ldmVyIGZpcmVkXG4gIHBsYXllci5zcmMoc291cmNlKTtcblxuICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWydkdXJhdGlvbmNoYW5nZScsICdlcnJvcicsICd2YXN0LmFkc0NhbmNlbCddLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgaWYgKGV2dC50eXBlID09PSAnZHVyYXRpb25jaGFuZ2UnKSB7XG4gICAgICBwbGF5QWQoKTtcbiAgICB9IGVsc2UgaWYoZXZ0LnR5cGUgPT09ICdlcnJvcicpIHtcbiAgICAgIGNhbGxiYWNrKG5ldyBWQVNURXJyb3IoXCJvbiBWQVNUSW50ZWdyYXRvciwgUGxheWVyIGlzIHVuYWJsZSB0byBwbGF5IHRoZSBBZFwiLCA0MDApLCByZXNwb25zZSk7XG4gICAgfVxuICAgIC8vTk9URTogSWYgdGhlIGFkcyBnZXQgY2FuY2VsZWQgd2UgZG8gbm90aGluZy9cbiAgfSk7XG5cbiAgLyoqKiogbG9jYWwgZnVuY3Rpb25zICoqKioqKi9cbiAgZnVuY3Rpb24gcGxheUFkKCkge1xuXG4gICAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsncGxheWluZycsICd2YXN0LmFkc0NhbmNlbCddLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICBpZihldnQudHlwZSA9PT0gJ3Zhc3QuYWRzQ2FuY2VsJyl7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgcGxheWVyLnRyaWdnZXIoJ3Zhc3QuYWRTdGFydCcpO1xuXG4gICAgICBwbGF5ZXIub24oJ2VuZGVkJywgcHJvY2VlZCk7XG4gICAgICBwbGF5ZXIub24oJ3Zhc3QuYWRzQ2FuY2VsJywgcHJvY2VlZCk7XG4gICAgICBwbGF5ZXIub24oJ3Zhc3QuYWRTa2lwJywgcHJvY2VlZCk7XG5cbiAgICAgIGZ1bmN0aW9uIHByb2NlZWQoZXZ0KSB7XG5cbiAgICAgICAgaWYoZXZ0LnR5cGUgPT09ICdlbmRlZCcgJiYgKHBsYXllci5kdXJhdGlvbigpIC0gcGxheWVyLmN1cnJlbnRUaW1lKCkpID4gMyApIHtcbiAgICAgICAgICAvLyBJZ25vcmUgZW5kZWQgZXZlbnQgaWYgdGhlIEFkIHRpbWUgd2FzIG5vdCAnbmVhcicgdGhlIGVuZFxuICAgICAgICAgIC8vIGF2b2lkcyBpc3N1ZXMgd2hlcmUgSU9TIGNvbnRyb2xzIGNvdWxkIHNraXAgdGhlIEFkXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcGxheWVyLm9mZignZW5kZWQnLCBwcm9jZWVkKTtcbiAgICAgICAgcGxheWVyLm9mZigndmFzdC5hZHNDYW5jZWwnLCBwcm9jZWVkKTtcbiAgICAgICAgcGxheWVyLm9mZigndmFzdC5hZFNraXAnLCBwcm9jZWVkKTtcblxuICAgICAgICAvL05PVEU6IGlmIHRoZSBhZHMgZ2V0IGNhbmNlbCB3ZSBkbyBub3RoaW5nIGFwYXJ0IHJlbW92aW5nIHRoZSBsaXN0bmVyc1xuICAgICAgICBpZihldnQudHlwZSA9PT0gJ2VuZGVkJyB8fCBldnQudHlwZSA9PT0gJ3Zhc3QuYWRTa2lwJyl7XG4gICAgICAgICAgY2FsbGJhY2sobnVsbCwgcmVzcG9uc2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBwbGF5ZXIucGxheSgpO1xuICB9XG59O1xuXG5WQVNUSW50ZWdyYXRvci5wcm90b3R5cGUuX3RyYWNrRXJyb3IgPSBmdW5jdGlvbiB0cmFja0Vycm9yKGVycm9yLCByZXNwb25zZSkge1xuICB2YXN0VXRpbC50cmFjayhyZXNwb25zZS5lcnJvclVSTE1hY3Jvcywge0VSUk9SQ09ERTogZXJyb3IuY29kZSB8fCA5MDB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gVkFTVEludGVncmF0b3I7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQWQgPSByZXF1aXJlKCcuL0FkJyk7XG52YXIgVmlkZW9DbGlja3MgPSByZXF1aXJlKCcuL1ZpZGVvQ2xpY2tzJyk7XG52YXIgTGluZWFyID0gcmVxdWlyZSgnLi9MaW5lYXInKTtcbnZhciBJbkxpbmUgPSByZXF1aXJlKCcuL0luTGluZScpO1xudmFyIFdyYXBwZXIgPSByZXF1aXJlKCcuL1dyYXBwZXInKTtcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcbnZhciB4bWwgPSByZXF1aXJlKCcuLi8uLi91dGlscy94bWwnKTtcblxud2luZG93LkluTGluZV9fQSA9IEluTGluZTtcbmZ1bmN0aW9uIFZBU1RSZXNwb25zZSgpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFZBU1RSZXNwb25zZSkpIHtcbiAgICByZXR1cm4gbmV3IFZBU1RSZXNwb25zZSgpO1xuICB9XG5cbiAgdGhpcy5fbGluZWFyQWRkZWQgPSBmYWxzZTtcbiAgdGhpcy5hZHMgPSBbXTtcbiAgdGhpcy5lcnJvclVSTE1hY3JvcyA9IFtdO1xuICB0aGlzLmltcHJlc3Npb25zID0gW107XG4gIHRoaXMuY2xpY2tUcmFja2luZ3MgPSBbXTtcbiAgdGhpcy5jdXN0b21DbGlja3MgPSBbXTtcbiAgdGhpcy50cmFja2luZ0V2ZW50cyA9IHt9O1xuICB0aGlzLm1lZGlhRmlsZXMgPSBbXTtcbiAgdGhpcy5jbGlja1Rocm91Z2ggPSB1bmRlZmluZWQ7XG4gIHRoaXMuYWRUaXRsZSA9ICcnO1xuICB0aGlzLmR1cmF0aW9uID0gdW5kZWZpbmVkO1xuICB0aGlzLnNraXBvZmZzZXQgPSB1bmRlZmluZWQ7XG59XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuYWRkQWQgPSBmdW5jdGlvbiAoYWQpIHtcbiAgdmFyIGluTGluZSwgd3JhcHBlcjtcbiAgaWYgKGFkIGluc3RhbmNlb2YgQWQpIHtcbiAgICBpbkxpbmUgPSBhZC5pbkxpbmU7XG4gICAgd3JhcHBlciA9IGFkLndyYXBwZXI7XG5cbiAgICB0aGlzLmFkcy5wdXNoKGFkKTtcblxuICAgIGlmIChpbkxpbmUpIHtcbiAgICAgIHRoaXMuX2FkZEluTGluZShpbkxpbmUpO1xuICAgIH1cblxuICAgIGlmICh3cmFwcGVyKSB7XG4gICAgICB0aGlzLl9hZGRXcmFwcGVyKHdyYXBwZXIpO1xuICAgIH1cbiAgfVxufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkRXJyb3JUcmFja1VybCA9IGZ1bmN0aW9uIChlcnJvcikge1xuICB2YXIgZXJyb3JVUkwgPSBlcnJvciBpbnN0YW5jZW9mIHhtbC5KWE9OVHJlZSA/IHhtbC5rZXlWYWx1ZShlcnJvcikgOiBlcnJvcjtcbiAgaWYgKGVycm9yVVJMKSB7XG4gICAgdGhpcy5lcnJvclVSTE1hY3Jvcy5wdXNoKGVycm9yVVJMKTtcbiAgfVxufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkSW1wcmVzc2lvbnMgPSBmdW5jdGlvbiAoaW1wcmVzc2lvbnMpIHtcbiAgdXRpbGl0aWVzLmlzQXJyYXkoaW1wcmVzc2lvbnMpICYmIGFwcGVuZFRvQXJyYXkodGhpcy5pbXByZXNzaW9ucywgaW1wcmVzc2lvbnMpO1xufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkQ2xpY2tUaHJvdWdoID0gZnVuY3Rpb24gKGNsaWNrVGhyb3VnaCkge1xuICBpZiAodXRpbGl0aWVzLmlzTm90RW1wdHlTdHJpbmcoY2xpY2tUaHJvdWdoKSkge1xuICAgIHRoaXMuY2xpY2tUaHJvdWdoID0gY2xpY2tUaHJvdWdoO1xuICB9XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRDbGlja1RyYWNraW5ncyA9IGZ1bmN0aW9uIChjbGlja1RyYWNraW5ncykge1xuICB1dGlsaXRpZXMuaXNBcnJheShjbGlja1RyYWNraW5ncykgJiYgYXBwZW5kVG9BcnJheSh0aGlzLmNsaWNrVHJhY2tpbmdzLCBjbGlja1RyYWNraW5ncyk7XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRDdXN0b21DbGlja3MgPSBmdW5jdGlvbiAoY3VzdG9tQ2xpY2tzKSB7XG4gIHV0aWxpdGllcy5pc0FycmF5KGN1c3RvbUNsaWNrcykgJiYgYXBwZW5kVG9BcnJheSh0aGlzLmN1c3RvbUNsaWNrcywgY3VzdG9tQ2xpY2tzKTtcbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZFRyYWNraW5nRXZlbnRzID0gZnVuY3Rpb24gKHRyYWNraW5nRXZlbnRzKSB7XG4gIHZhciBldmVudHNNYXAgPSB0aGlzLnRyYWNraW5nRXZlbnRzO1xuXG4gIGlmICh0cmFja2luZ0V2ZW50cykge1xuICAgIHRyYWNraW5nRXZlbnRzID0gdXRpbGl0aWVzLmlzQXJyYXkodHJhY2tpbmdFdmVudHMpID8gdHJhY2tpbmdFdmVudHMgOiBbdHJhY2tpbmdFdmVudHNdO1xuICAgIHRyYWNraW5nRXZlbnRzLmZvckVhY2goZnVuY3Rpb24gKHRyYWNraW5nRXZlbnQpIHtcbiAgICAgIGlmICghZXZlbnRzTWFwW3RyYWNraW5nRXZlbnQubmFtZV0pIHtcbiAgICAgICAgZXZlbnRzTWFwW3RyYWNraW5nRXZlbnQubmFtZV0gPSBbXTtcbiAgICAgIH1cbiAgICAgIGV2ZW50c01hcFt0cmFja2luZ0V2ZW50Lm5hbWVdLnB1c2godHJhY2tpbmdFdmVudCk7XG4gICAgfSk7XG4gIH1cbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZFRpdGxlID0gZnVuY3Rpb24gKHRpdGxlKSB7XG4gIGlmICh1dGlsaXRpZXMuaXNOb3RFbXB0eVN0cmluZyh0aXRsZSkpIHtcbiAgICB0aGlzLmFkVGl0bGUgPSB0aXRsZTtcbiAgfVxufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkRHVyYXRpb24gPSBmdW5jdGlvbiAoZHVyYXRpb24pIHtcbiAgaWYgKHV0aWxpdGllcy5pc051bWJlcihkdXJhdGlvbikpIHtcbiAgICB0aGlzLmR1cmF0aW9uID0gZHVyYXRpb247XG4gIH1cbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZFZpZGVvQ2xpY2tzID0gZnVuY3Rpb24gKHZpZGVvQ2xpY2tzKSB7XG4gIGlmICh2aWRlb0NsaWNrcyBpbnN0YW5jZW9mIFZpZGVvQ2xpY2tzKSB7XG4gICAgdGhpcy5fYWRkQ2xpY2tUaHJvdWdoKHZpZGVvQ2xpY2tzLmNsaWNrVGhyb3VnaCk7XG4gICAgdGhpcy5fYWRkQ2xpY2tUcmFja2luZ3ModmlkZW9DbGlja3MuY2xpY2tUcmFja2luZ3MpO1xuICAgIHRoaXMuX2FkZEN1c3RvbUNsaWNrcyh2aWRlb0NsaWNrcy5jdXN0b21DbGlja3MpO1xuICB9XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRNZWRpYUZpbGVzID0gZnVuY3Rpb24gKG1lZGlhRmlsZXMpIHtcbiAgdXRpbGl0aWVzLmlzQXJyYXkobWVkaWFGaWxlcykgJiYgYXBwZW5kVG9BcnJheSh0aGlzLm1lZGlhRmlsZXMsIG1lZGlhRmlsZXMpO1xufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkU2tpcG9mZnNldCA9IGZ1bmN0aW9uIChvZmZzZXQpIHtcbiAgaWYgKG9mZnNldCkge1xuICAgIHRoaXMuc2tpcG9mZnNldCA9IG9mZnNldDtcbiAgfVxufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkQWRQYXJhbWV0ZXJzID0gZnVuY3Rpb24gKGFkUGFyYW1ldGVycykge1xuICBpZiAoYWRQYXJhbWV0ZXJzKSB7XG4gICAgdGhpcy5hZFBhcmFtZXRlcnMgPSBhZFBhcmFtZXRlcnM7XG4gIH1cbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZExpbmVhciA9IGZ1bmN0aW9uIChsaW5lYXIpIHtcbiAgaWYgKGxpbmVhciBpbnN0YW5jZW9mIExpbmVhcikge1xuICAgIHRoaXMuX2FkZER1cmF0aW9uKGxpbmVhci5kdXJhdGlvbik7XG4gICAgdGhpcy5fYWRkVHJhY2tpbmdFdmVudHMobGluZWFyLnRyYWNraW5nRXZlbnRzKTtcbiAgICB0aGlzLl9hZGRWaWRlb0NsaWNrcyhsaW5lYXIudmlkZW9DbGlja3MpO1xuICAgIHRoaXMuX2FkZE1lZGlhRmlsZXMobGluZWFyLm1lZGlhRmlsZXMpO1xuICAgIHRoaXMuX2FkZFNraXBvZmZzZXQobGluZWFyLnNraXBvZmZzZXQpO1xuICAgIHRoaXMuX2FkZEFkUGFyYW1ldGVycyhsaW5lYXIuYWRQYXJhbWV0ZXJzKTtcbiAgICB0aGlzLl9saW5lYXJBZGRlZCA9IHRydWU7XG4gIH1cbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZEluTGluZSA9IGZ1bmN0aW9uIChpbkxpbmUpIHtcbiAgdmFyIHRoYXQgPSB0aGlzO1xuXG4gIGlmIChpbkxpbmUgaW5zdGFuY2VvZiBJbkxpbmUpIHtcbiAgICB0aGlzLl9hZGRUaXRsZShpbkxpbmUuYWRUaXRsZSk7XG4gICAgdGhpcy5fYWRkRXJyb3JUcmFja1VybChpbkxpbmUuZXJyb3IpO1xuICAgIHRoaXMuX2FkZEltcHJlc3Npb25zKGluTGluZS5pbXByZXNzaW9ucyk7XG5cbiAgICBpbkxpbmUuY3JlYXRpdmVzLmZvckVhY2goZnVuY3Rpb24gKGNyZWF0aXZlKSB7XG4gICAgICBpZiAoY3JlYXRpdmUubGluZWFyKSB7XG4gICAgICAgIHRoYXQuX2FkZExpbmVhcihjcmVhdGl2ZS5saW5lYXIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRXcmFwcGVyID0gZnVuY3Rpb24gKHdyYXBwZXIpIHtcbiAgdmFyIHRoYXQgPSB0aGlzO1xuXG4gIGlmICh3cmFwcGVyIGluc3RhbmNlb2YgV3JhcHBlcikge1xuICAgIHRoaXMuX2FkZEVycm9yVHJhY2tVcmwod3JhcHBlci5lcnJvcik7XG4gICAgdGhpcy5fYWRkSW1wcmVzc2lvbnMod3JhcHBlci5pbXByZXNzaW9ucyk7XG5cbiAgICB3cmFwcGVyLmNyZWF0aXZlcy5mb3JFYWNoKGZ1bmN0aW9uIChjcmVhdGl2ZSkge1xuICAgICAgdmFyIGxpbmVhciA9IGNyZWF0aXZlLmxpbmVhcjtcbiAgICAgIGlmIChsaW5lYXIpIHtcbiAgICAgICAgdGhhdC5fYWRkVmlkZW9DbGlja3MobGluZWFyLnZpZGVvQ2xpY2tzKTtcbiAgICAgICAgdGhhdC5jbGlja1Rocm91Z2ggPSB1bmRlZmluZWQ7Ly9XZSBlbnN1cmUgdGhhdCBubyBjbGlja1Rocm91Z2ggaGFzIGJlZW4gYWRkZWRcbiAgICAgICAgdGhhdC5fYWRkVHJhY2tpbmdFdmVudHMobGluZWFyLnRyYWNraW5nRXZlbnRzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5oYXNMaW5lYXIgPSBmdW5jdGlvbigpe1xuICByZXR1cm4gdGhpcy5fbGluZWFyQWRkZWQ7XG59O1xuXG5mdW5jdGlvbiBhcHBlbmRUb0FycmF5KGFycmF5LCBpdGVtcykge1xuICBpdGVtcy5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgYXJyYXkucHVzaChpdGVtKTtcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gVkFTVFJlc3BvbnNlO1xuXG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBWQVNURXJyb3IgPSByZXF1aXJlKCcuL1ZBU1RFcnJvcicpO1xudmFyIFZBU1RSZXNwb25zZSA9IHJlcXVpcmUoJy4vVkFTVFJlc3BvbnNlJyk7XG52YXIgdmFzdFV0aWwgPSByZXF1aXJlKCcuL3Zhc3RVdGlsJyk7XG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucycpO1xuXG5mdW5jdGlvbiBWQVNUVHJhY2tlcihhc3NldFVSSSwgdmFzdFJlc3BvbnNlKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBWQVNUVHJhY2tlcikpIHtcbiAgICByZXR1cm4gbmV3IFZBU1RUcmFja2VyKGFzc2V0VVJJLCB2YXN0UmVzcG9uc2UpO1xuICB9XG5cbiAgdGhpcy5zYW5pdHlDaGVjayhhc3NldFVSSSwgdmFzdFJlc3BvbnNlKTtcbiAgdGhpcy5pbml0aWFsaXplKGFzc2V0VVJJLCB2YXN0UmVzcG9uc2UpO1xuXG59XG5cblZBU1RUcmFja2VyLnByb3RvdHlwZS5pbml0aWFsaXplID0gZnVuY3Rpb24oYXNzZXRVUkksIHZhc3RSZXNwb25zZSkge1xuICB0aGlzLnJlc3BvbnNlID0gdmFzdFJlc3BvbnNlO1xuICB0aGlzLmFzc2V0VVJJID0gYXNzZXRVUkk7XG4gIHRoaXMucHJvZ3Jlc3MgPSAwO1xuICB0aGlzLnF1YXJ0aWxlcyA9IHtcbiAgICBmaXJzdFF1YXJ0aWxlOiB7dHJhY2tlZDogZmFsc2UsIHRpbWU6IE1hdGgucm91bmQoMjUgKiB2YXN0UmVzcG9uc2UuZHVyYXRpb24pIC8gMTAwfSxcbiAgICBtaWRwb2ludDoge3RyYWNrZWQ6IGZhbHNlLCB0aW1lOiBNYXRoLnJvdW5kKDUwICogdmFzdFJlc3BvbnNlLmR1cmF0aW9uKSAvIDEwMH0sXG4gICAgdGhpcmRRdWFydGlsZToge3RyYWNrZWQ6IGZhbHNlLCB0aW1lOiBNYXRoLnJvdW5kKDc1ICogdmFzdFJlc3BvbnNlLmR1cmF0aW9uKSAvIDEwMH1cbiAgfTtcbn07XG5cblZBU1RUcmFja2VyLnByb3RvdHlwZS5zYW5pdHlDaGVjayA9IGZ1bmN0aW9uKGFzc2V0VVJJLCB2YXN0UmVzcG9uc2UpIHtcbiAgaWYgKCF1dGlsaXRpZXMuaXNTdHJpbmcoYXNzZXRVUkkpIHx8IHV0aWxpdGllcy5pc0VtcHR5U3RyaW5nKGFzc2V0VVJJKSkge1xuICAgIHRocm93IG5ldyBWQVNURXJyb3IoJ29uIFZBU1RUcmFja2VyIGNvbnN0cnVjdG9yLCBtaXNzaW5nIHJlcXVpcmVkIHRoZSBVUkkgb2YgdGhlIGFkIGFzc2V0IGJlaW5nIHBsYXllZCcpO1xuICB9XG5cbiAgaWYgKCEodmFzdFJlc3BvbnNlIGluc3RhbmNlb2YgVkFTVFJlc3BvbnNlKSkge1xuICAgIHRocm93IG5ldyBWQVNURXJyb3IoJ29uIFZBU1RUcmFja2VyIGNvbnN0cnVjdG9yLCBtaXNzaW5nIHJlcXVpcmVkIFZBU1QgcmVzcG9uc2UnKTtcbiAgfVxufTtcblxuVkFTVFRyYWNrZXIucHJvdG90eXBlLnRyYWNrVVJMcyA9IGZ1bmN0aW9uIHRyYWNrVVJMcyh1cmxzLCB2YXJpYWJsZXMpIHtcbiAgaWYgKHV0aWxpdGllcy5pc0FycmF5KHVybHMpICYmIHVybHMubGVuZ3RoID4gMCkge1xuICAgIHZhcmlhYmxlcyA9IHV0aWxpdGllcy5leHRlbmQoe1xuICAgICAgQVNTRVRVUkk6IHRoaXMuYXNzZXRVUkksXG4gICAgICBDT05URU5UUExBWUhFQUQ6IHZhc3RVdGlsLmZvcm1hdFByb2dyZXNzKHRoaXMucHJvZ3Jlc3MpXG4gICAgfSwgdmFyaWFibGVzIHx8IHt9KTtcblxuICAgIHZhc3RVdGlsLnRyYWNrKHVybHMsIHZhcmlhYmxlcyk7XG4gIH1cbn07XG5cblZBU1RUcmFja2VyLnByb3RvdHlwZS50cmFja0V2ZW50ID0gZnVuY3Rpb24gdHJhY2tFdmVudChldmVudE5hbWUsIHRyYWNrT25jZSkge1xuICB0aGlzLnRyYWNrVVJMcyhnZXRFdmVudFVyaXModGhpcy5yZXNwb25zZS50cmFja2luZ0V2ZW50c1tldmVudE5hbWVdKSk7XG4gIGlmICh0cmFja09uY2UpIHtcbiAgICB0aGlzLnJlc3BvbnNlLnRyYWNraW5nRXZlbnRzW2V2ZW50TmFtZV0gPSB1bmRlZmluZWQ7XG4gIH1cblxuICAvKioqIExvY2FsIGZ1bmN0aW9uICoqKi9cbiAgZnVuY3Rpb24gZ2V0RXZlbnRVcmlzKHRyYWNraW5nRXZlbnRzKSB7XG4gICAgdmFyIHVyaXM7XG5cbiAgICBpZiAodHJhY2tpbmdFdmVudHMpIHtcbiAgICAgIHVyaXMgPSBbXTtcbiAgICAgIHRyYWNraW5nRXZlbnRzLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIHVyaXMucHVzaChldmVudC51cmkpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB1cmlzO1xuICB9XG59O1xuXG5WQVNUVHJhY2tlci5wcm90b3R5cGUudHJhY2tQcm9ncmVzcyA9IGZ1bmN0aW9uIHRyYWNrUHJvZ3Jlc3MobmV3UHJvZ3Jlc3NJbk1zKSB7XG4gIHZhciB0aGF0ID0gdGhpcztcbiAgdmFyIGV2ZW50cyA9IFtdO1xuICB2YXIgT05DRSA9IHRydWU7XG4gIHZhciBBTFdBWVMgPSBmYWxzZTtcbiAgdmFyIHRyYWNraW5nRXZlbnRzID0gdGhpcy5yZXNwb25zZS50cmFja2luZ0V2ZW50cztcblxuICBpZiAodXRpbGl0aWVzLmlzTnVtYmVyKG5ld1Byb2dyZXNzSW5NcykpIHtcbiAgICBhZGRUcmFja0V2ZW50KCdzdGFydCcsIE9OQ0UsIG5ld1Byb2dyZXNzSW5NcyA+IDApO1xuICAgIGFkZFRyYWNrRXZlbnQoJ3Jld2luZCcsIEFMV0FZUywgaGFzUmV3b3VuZCh0aGlzLnByb2dyZXNzLCBuZXdQcm9ncmVzc0luTXMpKTtcbiAgICBhZGRRdWFydGlsZUV2ZW50cyhuZXdQcm9ncmVzc0luTXMpO1xuICAgIHRyYWNrUHJvZ3Jlc3NFdmVudHMobmV3UHJvZ3Jlc3NJbk1zKTtcbiAgICB0cmFja0V2ZW50cygpO1xuICAgIHRoaXMucHJvZ3Jlc3MgPSBuZXdQcm9ncmVzc0luTXM7XG4gIH1cblxuICAvKioqIExvY2FsIGZ1bmN0aW9uICoqKi9cbiAgZnVuY3Rpb24gaGFzUmV3b3VuZChjdXJyZW50UHJvZ3Jlc3MsIG5ld1Byb2dyZXNzKSB7XG4gICAgdmFyIFJFV0lORF9USFJFU0hPTEQgPSAzMDAwOyAvL0lPUyB2aWRlbyBjbG9jayBpcyB2ZXJ5IHVucmVsaWFibGUgYW5kIHdlIG5lZWQgYSAzIHNlY29uZHMgdGhyZXNob2xkIHRvIGVuc3VyZSB0aGF0IHRoZXJlIHdhcyBhIHJld2luZCBhbiB0aGF0IGl0IHdhcyBvbiBwdXJwb3NlLlxuICAgIHJldHVybiBjdXJyZW50UHJvZ3Jlc3MgPiBuZXdQcm9ncmVzc0luTXMgJiYgTWF0aC5hYnMobmV3UHJvZ3Jlc3MgLSBjdXJyZW50UHJvZ3Jlc3MpID4gUkVXSU5EX1RIUkVTSE9MRDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZFRyYWNrRXZlbnQoZXZlbnROYW1lLCB0cmFja09uY2UsIGNhbkJlQWRkZWQpIHtcbiAgICBpZiAodHJhY2tpbmdFdmVudHNbZXZlbnROYW1lXSAmJiBjYW5CZUFkZGVkKSB7XG4gICAgICBldmVudHMucHVzaCh7XG4gICAgICAgIG5hbWU6IGV2ZW50TmFtZSxcbiAgICAgICAgdHJhY2tPbmNlOiAhIXRyYWNrT25jZVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gYWRkUXVhcnRpbGVFdmVudHMocHJvZ3Jlc3MpIHtcbiAgICB2YXIgcXVhcnRpbGVzID0gdGhhdC5xdWFydGlsZXM7XG4gICAgdmFyIGZpcnN0UXVhcnRpbGUgPSB0aGF0LnF1YXJ0aWxlcy5maXJzdFF1YXJ0aWxlO1xuICAgIHZhciBtaWRwb2ludCA9IHRoYXQucXVhcnRpbGVzLm1pZHBvaW50O1xuICAgIHZhciB0aGlyZFF1YXJ0aWxlID0gdGhhdC5xdWFydGlsZXMudGhpcmRRdWFydGlsZTtcblxuICAgIGlmICghZmlyc3RRdWFydGlsZS50cmFja2VkKSB7XG4gICAgICB0cmFja1F1YXJ0aWxlKCdmaXJzdFF1YXJ0aWxlJywgcHJvZ3Jlc3MpO1xuICAgIH0gZWxzZSBpZiAoIW1pZHBvaW50LnRyYWNrZWQpIHtcbiAgICAgIHRyYWNrUXVhcnRpbGUoJ21pZHBvaW50JywgcHJvZ3Jlc3MpO1xuICAgIH0gZWxzZSBpZiAoIXRoaXJkUXVhcnRpbGUudHJhY2tlZCl7XG4gICAgICB0cmFja1F1YXJ0aWxlKCd0aGlyZFF1YXJ0aWxlJywgcHJvZ3Jlc3MpO1xuICAgIH1cblxuICAgIC8qKiogTG9jYWwgZnVuY3Rpb24gKioqL1xuICAgIGZ1bmN0aW9uIHRyYWNrUXVhcnRpbGUocXVhcnRpbGVOYW1lLCBwcm9ncmVzcyl7XG4gICAgICB2YXIgcXVhcnRpbGUgPSBxdWFydGlsZXNbcXVhcnRpbGVOYW1lXTtcbiAgICAgIGlmKGNhbkJlVHJhY2tlZChxdWFydGlsZSwgcHJvZ3Jlc3MpKXtcbiAgICAgICAgcXVhcnRpbGUudHJhY2tlZCA9IHRydWU7XG4gICAgICAgIGFkZFRyYWNrRXZlbnQocXVhcnRpbGVOYW1lLCBPTkNFLCB0cnVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjYW5CZVRyYWNrZWQocXVhcnRpbGUsIHByb2dyZXNzKSB7XG4gICAgdmFyIHF1YXJ0aWxlVGltZSA9IHF1YXJ0aWxlLnRpbWU7XG4gICAgLy9XZSBvbmx5IGZpcmUgdGhlIHF1YXJ0aWxlIGV2ZW50IGlmIHRoZSBwcm9ncmVzcyBpcyBiaWdnZXIgdGhhbiB0aGUgcXVhcnRpbGUgdGltZSBieSA1IHNlY29uZHMgYXQgbW9zdC5cbiAgICByZXR1cm4gcHJvZ3Jlc3MgPj0gcXVhcnRpbGVUaW1lICYmIHByb2dyZXNzIDw9IChxdWFydGlsZVRpbWUgKyA1MDAwKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYWNrUHJvZ3Jlc3NFdmVudHMocHJvZ3Jlc3MpIHtcbiAgICBpZiAoIXV0aWxpdGllcy5pc0FycmF5KHRyYWNraW5nRXZlbnRzLnByb2dyZXNzKSkge1xuICAgICAgcmV0dXJuOyAvL05vdGhpbmcgdG8gdHJhY2tcbiAgICB9XG5cbiAgICB2YXIgcGVuZGluZ1Byb2dyZXNzRXZ0cyA9IFtdO1xuXG4gICAgdHJhY2tpbmdFdmVudHMucHJvZ3Jlc3MuZm9yRWFjaChmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICBpZiAoZXZ0Lm9mZnNldCA8PSBwcm9ncmVzcykge1xuICAgICAgICB0aGF0LnRyYWNrVVJMcyhbZXZ0LnVyaV0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGVuZGluZ1Byb2dyZXNzRXZ0cy5wdXNoKGV2dCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdHJhY2tpbmdFdmVudHMucHJvZ3Jlc3MgPSBwZW5kaW5nUHJvZ3Jlc3NFdnRzO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJhY2tFdmVudHMoKSB7XG4gICAgZXZlbnRzLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICB0aGF0LnRyYWNrRXZlbnQoZXZlbnQubmFtZSwgZXZlbnQudHJhY2tPbmNlKTtcbiAgICB9KTtcbiAgfVxufTtcblxuW1xuICAncmV3aW5kJyxcbiAgJ2Z1bGxzY3JlZW4nLFxuICAnZXhpdEZ1bGxzY3JlZW4nLFxuICAncGF1c2UnLFxuICAncmVzdW1lJyxcbiAgJ211dGUnLFxuICAndW5tdXRlJyxcbiAgJ2FjY2VwdEludml0YXRpb24nLFxuICAnYWNjZXB0SW52aXRhdGlvbkxpbmVhcicsXG4gICdjb2xsYXBzZScsXG4gICdleHBhbmQnXG5dLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xuICAgIFZBU1RUcmFja2VyLnByb3RvdHlwZVsndHJhY2snICsgdXRpbGl0aWVzLmNhcGl0YWxpemUoZXZlbnROYW1lKV0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLnRyYWNrRXZlbnQoZXZlbnROYW1lKTtcbiAgICB9O1xuICB9KTtcblxuW1xuICAnc3RhcnQnLFxuICAnc2tpcCcsXG4gICdjbG9zZScsXG4gICdjbG9zZUxpbmVhcidcbl0uZm9yRWFjaChmdW5jdGlvbiAoZXZlbnROYW1lKSB7XG4gICAgVkFTVFRyYWNrZXIucHJvdG90eXBlWyd0cmFjaycgKyB1dGlsaXRpZXMuY2FwaXRhbGl6ZShldmVudE5hbWUpXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMudHJhY2tFdmVudChldmVudE5hbWUsIHRydWUpO1xuICAgIH07XG4gIH0pO1xuXG5bXG4gICdmaXJzdFF1YXJ0aWxlJyxcbiAgJ21pZHBvaW50JyxcbiAgJ3RoaXJkUXVhcnRpbGUnXG5dLmZvckVhY2goZnVuY3Rpb24gKHF1YXJ0aWxlKSB7XG4gICAgVkFTVFRyYWNrZXIucHJvdG90eXBlWyd0cmFjaycgKyB1dGlsaXRpZXMuY2FwaXRhbGl6ZShxdWFydGlsZSldID0gZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5xdWFydGlsZXNbcXVhcnRpbGVdLnRyYWNrZWQgPSB0cnVlO1xuICAgICAgdGhpcy50cmFja0V2ZW50KHF1YXJ0aWxlLCB0cnVlKTtcbiAgICB9O1xuICB9KTtcblxuVkFTVFRyYWNrZXIucHJvdG90eXBlLnRyYWNrQ29tcGxldGUgPSBmdW5jdGlvbiAoKSB7XG4gIGlmKHRoaXMucXVhcnRpbGVzLnRoaXJkUXVhcnRpbGUudHJhY2tlZCl7XG4gICAgdGhpcy50cmFja0V2ZW50KCdjb21wbGV0ZScsIHRydWUpO1xuICB9XG59O1xuXG5WQVNUVHJhY2tlci5wcm90b3R5cGUudHJhY2tFcnJvcldpdGhDb2RlID0gZnVuY3Rpb24gdHJhY2tFcnJvcldpdGhDb2RlKGVycm9yY29kZSkge1xuICBpZiAodXRpbGl0aWVzLmlzTnVtYmVyKGVycm9yY29kZSkpIHtcbiAgICB0aGlzLnRyYWNrVVJMcyh0aGlzLnJlc3BvbnNlLmVycm9yVVJMTWFjcm9zLCB7RVJST1JDT0RFOiBlcnJvcmNvZGV9KTtcbiAgfVxufTtcblxuVkFTVFRyYWNrZXIucHJvdG90eXBlLnRyYWNrSW1wcmVzc2lvbnMgPSBmdW5jdGlvbiB0cmFja0ltcHJlc3Npb25zKCkge1xuICB0aGlzLnRyYWNrVVJMcyh0aGlzLnJlc3BvbnNlLmltcHJlc3Npb25zKTtcbn07XG5cblZBU1RUcmFja2VyLnByb3RvdHlwZS50cmFja0NyZWF0aXZlVmlldyA9IGZ1bmN0aW9uIHRyYWNrQ3JlYXRpdmVWaWV3KCkge1xuICB0aGlzLnRyYWNrRXZlbnQoJ2NyZWF0aXZlVmlldycpO1xufTtcblxuVkFTVFRyYWNrZXIucHJvdG90eXBlLnRyYWNrQ2xpY2sgPSBmdW5jdGlvbiB0cmFja0NsaWNrKCkge1xuICB0aGlzLnRyYWNrVVJMcyh0aGlzLnJlc3BvbnNlLmNsaWNrVHJhY2tpbmdzKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gVkFTVFRyYWNrZXI7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG52YXIgeG1sID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMveG1sJyk7XG5cbmZ1bmN0aW9uIFZpZGVvQ2xpY2tzKHZpZGVvQ2xpY2tKVHJlZSkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVmlkZW9DbGlja3MpKSB7XG4gICAgcmV0dXJuIG5ldyBWaWRlb0NsaWNrcyh2aWRlb0NsaWNrSlRyZWUpO1xuICB9XG5cbiAgdGhpcy5jbGlja1Rocm91Z2ggPSB4bWwua2V5VmFsdWUodmlkZW9DbGlja0pUcmVlLmNsaWNrVGhyb3VnaCk7XG4gIHRoaXMuY2xpY2tUcmFja2luZ3MgPSBwYXJzZUNsaWNrVHJhY2tpbmdzKHZpZGVvQ2xpY2tKVHJlZS5jbGlja1RyYWNraW5nKTtcbiAgdGhpcy5jdXN0b21DbGlja3MgPSBwYXJzZUNsaWNrVHJhY2tpbmdzKHZpZGVvQ2xpY2tKVHJlZS5jdXN0b21DbGljayk7XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBwYXJzZUNsaWNrVHJhY2tpbmdzKHRyYWNraW5nRGF0YSkge1xuICAgIHZhciBjbGlja1RyYWNraW5ncyA9IFtdO1xuICAgIGlmICh0cmFja2luZ0RhdGEpIHtcbiAgICAgIHRyYWNraW5nRGF0YSA9IHV0aWxpdGllcy5pc0FycmF5KHRyYWNraW5nRGF0YSkgPyB0cmFja2luZ0RhdGEgOiBbdHJhY2tpbmdEYXRhXTtcbiAgICAgIHRyYWNraW5nRGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChjbGlja1RyYWNraW5nRGF0YSkge1xuICAgICAgICBjbGlja1RyYWNraW5ncy5wdXNoKHhtbC5rZXlWYWx1ZShjbGlja1RyYWNraW5nRGF0YSkpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBjbGlja1RyYWNraW5ncztcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFZpZGVvQ2xpY2tzOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIHZhc3RVdGlsID0gcmVxdWlyZSgnLi92YXN0VXRpbCcpO1xudmFyIENyZWF0aXZlID0gcmVxdWlyZSgnLi9DcmVhdGl2ZScpO1xuXG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucycpO1xudmFyIHhtbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3htbCcpO1xuXG5mdW5jdGlvbiBXcmFwcGVyKHdyYXBwZXJKVHJlZSkge1xuICBpZighKHRoaXMgaW5zdGFuY2VvZiBXcmFwcGVyKSkge1xuICAgIHJldHVybiBuZXcgV3JhcHBlcih3cmFwcGVySlRyZWUpO1xuICB9XG5cbiAgLy9SZXF1aXJlZCBlbGVtZW50c1xuICB0aGlzLmFkU3lzdGVtID0geG1sLmtleVZhbHVlKHdyYXBwZXJKVHJlZS5hZFN5c3RlbSk7XG4gIHRoaXMuaW1wcmVzc2lvbnMgPSB2YXN0VXRpbC5wYXJzZUltcHJlc3Npb25zKHdyYXBwZXJKVHJlZS5pbXByZXNzaW9uKTtcbiAgdGhpcy5WQVNUQWRUYWdVUkkgPSB4bWwua2V5VmFsdWUod3JhcHBlckpUcmVlLnZBU1RBZFRhZ1VSSSk7XG5cbiAgLy9PcHRpb25hbCBlbGVtZW50c1xuICB0aGlzLmNyZWF0aXZlcyA9IENyZWF0aXZlLnBhcnNlQ3JlYXRpdmVzKHdyYXBwZXJKVHJlZS5jcmVhdGl2ZXMpO1xuICB0aGlzLmVycm9yID0geG1sLmtleVZhbHVlKHdyYXBwZXJKVHJlZS5lcnJvcik7XG4gIHRoaXMuZXh0ZW5zaW9ucyA9IHdyYXBwZXJKVHJlZS5leHRlbnNpb25zO1xuXG4gIC8vT3B0aW9uYWwgYXR0cnNcbiAgdGhpcy5mb2xsb3dBZGRpdGlvbmFsV3JhcHBlcnMgPSB1dGlsaXRpZXMuaXNEZWZpbmVkKHhtbC5hdHRyKHdyYXBwZXJKVHJlZSwgJ2ZvbGxvd0FkZGl0aW9uYWxXcmFwcGVycycpKT8geG1sLmF0dHIod3JhcHBlckpUcmVlLCAnZm9sbG93QWRkaXRpb25hbFdyYXBwZXJzJyk6IHRydWU7XG4gIHRoaXMuYWxsb3dNdWx0aXBsZUFkcyA9IHhtbC5hdHRyKHdyYXBwZXJKVHJlZSwgJ2FsbG93TXVsdGlwbGVBZHMnKTtcbiAgdGhpcy5mYWxsYmFja09uTm9BZCA9IHhtbC5hdHRyKHdyYXBwZXJKVHJlZSwgJ2ZhbGxiYWNrT25Ob0FkJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gV3JhcHBlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxudmFyIGR1cmF0aW9uUmVnZXggPSAvKFxcZFxcZCk6KFxcZFxcZCk6KFxcZFxcZCkoXFwuKFxcZFxcZFxcZCkpPy87XG5cbnZhciBwYXJzZXJzID0ge1xuXG4gIGR1cmF0aW9uOiBmdW5jdGlvbiBwYXJzZUR1cmF0aW9uKGR1cmF0aW9uU3RyKSB7XG5cbiAgICB2YXIgbWF0Y2gsIGR1cmF0aW9uSW5NcztcblxuICAgIGlmICh1dGlsaXRpZXMuaXNTdHJpbmcoZHVyYXRpb25TdHIpKSB7XG4gICAgICBtYXRjaCA9IGR1cmF0aW9uU3RyLm1hdGNoKGR1cmF0aW9uUmVnZXgpO1xuICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgIGR1cmF0aW9uSW5NcyA9IHBhcnNlSG91cnNUb01zKG1hdGNoWzFdKSArIHBhcnNlTWluVG9NcyhtYXRjaFsyXSkgKyBwYXJzZVNlY1RvTXMobWF0Y2hbM10pICsgcGFyc2VJbnQobWF0Y2hbNV0gfHwgMCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGlzTmFOKGR1cmF0aW9uSW5NcykgPyBudWxsIDogZHVyYXRpb25Jbk1zO1xuXG4gICAgLyoqKiBsb2NhbCBmdW5jdGlvbnMgKioqL1xuICAgIGZ1bmN0aW9uIHBhcnNlSG91cnNUb01zKGhvdXJTdHIpIHtcbiAgICAgIHJldHVybiBwYXJzZUludChob3VyU3RyLCAxMCkgKiA2MCAqIDYwICogMTAwMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZU1pblRvTXMobWluU3RyKSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQobWluU3RyLCAxMCkgKiA2MCAqIDEwMDA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VTZWNUb01zKHNlY1N0cikge1xuICAgICAgcmV0dXJuIHBhcnNlSW50KHNlY1N0ciwgMTApICogMTAwMDtcbiAgICB9XG4gIH0sXG5cbiAgb2Zmc2V0OiBmdW5jdGlvbiBwYXJzZU9mZnNldChvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgaWYoaXNQZXJjZW50YWdlKG9mZnNldCkpe1xuICAgICAgcmV0dXJuIGNhbGN1bGF0ZVBlcmNlbnRhZ2Uob2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgfVxuICAgIHJldHVybiBwYXJzZXJzLmR1cmF0aW9uKG9mZnNldCk7XG5cbiAgICAvKioqIExvY2FsIGZ1bmN0aW9uICoqKi9cbiAgICBmdW5jdGlvbiBpc1BlcmNlbnRhZ2Uob2Zmc2V0KSB7XG4gICAgICB2YXIgcGVyY2VudGFnZVJlZ2V4ID0gL15cXGQrKFxcLlxcZCspPyUkL2c7XG4gICAgICByZXR1cm4gcGVyY2VudGFnZVJlZ2V4LnRlc3Qob2Zmc2V0KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjYWxjdWxhdGVQZXJjZW50YWdlKHBlcmNlbnRTdHIsIGR1cmF0aW9uKSB7XG4gICAgICBpZihkdXJhdGlvbikge1xuICAgICAgICByZXR1cm4gY2FsY1BlcmNlbnQoZHVyYXRpb24sIHBhcnNlRmxvYXQocGVyY2VudFN0ci5yZXBsYWNlKCclJywgJycpKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjYWxjUGVyY2VudChxdWFudGl0eSwgcGVyY2VudCl7XG4gICAgICByZXR1cm4gcXVhbnRpdHkgKiBwZXJjZW50IC8gMTAwO1xuICAgIH1cbiAgfVxuXG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gcGFyc2VyczsiLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG52YXIgVlBBSURIVE1MNVRlY2ggPSByZXF1aXJlKCcuLi92cGFpZC9WUEFJREhUTUw1VGVjaCcpO1xudmFyIFZQQUlERmxhc2hUZWNoID0gcmVxdWlyZSgnLi4vdnBhaWQvVlBBSURGbGFzaFRlY2gnKTtcbnZhciBWUEFJREZMQVNIQ2xpZW50ID0gcmVxdWlyZSgnVlBBSURGTEFTSENsaWVudC9qcy9WUEFJREZMQVNIQ2xpZW50Jyk7XG5cbnZhciB2YXN0VXRpbCA9IHtcblxuICB0cmFjazogZnVuY3Rpb24gdHJhY2soVVJMTWFjcm9zLCB2YXJpYWJsZXMpIHtcbiAgICB2YXIgc291cmNlcyA9IHZhc3RVdGlsLnBhcnNlVVJMTWFjcm9zKFVSTE1hY3JvcywgdmFyaWFibGVzKTtcbiAgICB2YXIgdHJhY2tJbWdzID0gW107XG4gICAgc291cmNlcy5mb3JFYWNoKGZ1bmN0aW9uIChzcmMpIHtcbiAgICAgIHZhciBpbWcgPSBuZXcgSW1hZ2UoKTtcbiAgICAgIGltZy5zcmMgPSBzcmM7XG4gICAgICB0cmFja0ltZ3MucHVzaChpbWcpO1xuICAgIH0pO1xuICAgIHJldHVybiB0cmFja0ltZ3M7XG4gIH0sXG5cbiAgcGFyc2VVUkxNYWNyb3M6IGZ1bmN0aW9uIHBhcnNlTWFjcm9zKFVSTE1hY3JvcywgdmFyaWFibGVzKSB7XG4gICAgdmFyIHBhcnNlZFVSTHMgPSBbXTtcblxuICAgIHZhcmlhYmxlcyA9IHZhcmlhYmxlcyB8fCB7fTtcblxuICAgIGlmICghKHZhcmlhYmxlc1tcIkNBQ0hFQlVTVElOR1wiXSkpIHtcbiAgICAgIHZhcmlhYmxlc1tcIkNBQ0hFQlVTVElOR1wiXSA9IE1hdGgucm91bmQoTWF0aC5yYW5kb20oKSAqIDEuMGUrMTApO1xuICAgIH1cblxuICAgIFVSTE1hY3Jvcy5mb3JFYWNoKGZ1bmN0aW9uIChVUkxNYWNybykge1xuICAgICAgcGFyc2VkVVJMcy5wdXNoKHZhc3RVdGlsLl9wYXJzZVVSTE1hY3JvKFVSTE1hY3JvLCB2YXJpYWJsZXMpKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBwYXJzZWRVUkxzO1xuICB9LFxuXG4gIHBhcnNlVVJMTWFjcm86IGZ1bmN0aW9uIHBhcnNlTWFjcm8oVVJMTWFjcm8sIHZhcmlhYmxlcykge1xuICAgIHZhcmlhYmxlcyA9IHZhcmlhYmxlcyB8fCB7fTtcblxuICAgIGlmICghKHZhcmlhYmxlc1tcIkNBQ0hFQlVTVElOR1wiXSkpIHtcbiAgICAgIHZhcmlhYmxlc1tcIkNBQ0hFQlVTVElOR1wiXSA9IE1hdGgucm91bmQoTWF0aC5yYW5kb20oKSAqIDEuMGUrMTApO1xuICAgIH1cblxuICAgIHJldHVybiB2YXN0VXRpbC5fcGFyc2VVUkxNYWNybyhVUkxNYWNybywgdmFyaWFibGVzKTtcbiAgfSxcblxuICBfcGFyc2VVUkxNYWNybzogZnVuY3Rpb24gcGFyc2VNYWNybyhVUkxNYWNybywgdmFyaWFibGVzKSB7XG4gICAgdmFyaWFibGVzID0gdmFyaWFibGVzIHx8IHt9O1xuXG4gICAgdXRpbGl0aWVzLmZvckVhY2godmFyaWFibGVzLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgVVJMTWFjcm8gPSBVUkxNYWNyby5yZXBsYWNlKG5ldyBSZWdFeHAoXCJcXFxcW1wiICsga2V5ICsgXCJcXFxcXFxdXCIsICdnbScpLCB2YWx1ZSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gVVJMTWFjcm87XG4gIH0sXG5cbiAgcGFyc2VEdXJhdGlvbjogZnVuY3Rpb24gcGFyc2VEdXJhdGlvbihkdXJhdGlvblN0cikge1xuICAgIHZhciBkdXJhdGlvblJlZ2V4ID0gLyhcXGRcXGQpOihcXGRcXGQpOihcXGRcXGQpKFxcLihcXGRcXGRcXGQpKT8vO1xuICAgIHZhciBtYXRjaCwgZHVyYXRpb25Jbk1zO1xuXG4gICAgaWYgKHV0aWxpdGllcy5pc1N0cmluZyhkdXJhdGlvblN0cikpIHtcbiAgICAgIG1hdGNoID0gZHVyYXRpb25TdHIubWF0Y2goZHVyYXRpb25SZWdleCk7XG4gICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgZHVyYXRpb25Jbk1zID0gcGFyc2VIb3Vyc1RvTXMobWF0Y2hbMV0pICsgcGFyc2VNaW5Ub01zKG1hdGNoWzJdKSArIHBhcnNlU2VjVG9NcyhtYXRjaFszXSkgKyBwYXJzZUludChtYXRjaFs1XSB8fCAwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gaXNOYU4oZHVyYXRpb25Jbk1zKSA/IG51bGwgOiBkdXJhdGlvbkluTXM7XG5cbiAgICAvKioqIGxvY2FsIGZ1bmN0aW9ucyAqKiovXG4gICAgZnVuY3Rpb24gcGFyc2VIb3Vyc1RvTXMoaG91clN0cikge1xuICAgICAgcmV0dXJuIHBhcnNlSW50KGhvdXJTdHIsIDEwKSAqIDYwICogNjAgKiAxMDAwO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlTWluVG9NcyhtaW5TdHIpIHtcbiAgICAgIHJldHVybiBwYXJzZUludChtaW5TdHIsIDEwKSAqIDYwICogMTAwMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZVNlY1RvTXMoc2VjU3RyKSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQoc2VjU3RyLCAxMCkgKiAxMDAwO1xuICAgIH1cbiAgfSxcblxuICBwYXJzZUltcHJlc3Npb25zOiBmdW5jdGlvbiBwYXJzZUltcHJlc3Npb25zKGltcHJlc3Npb25zKSB7XG4gICAgaWYgKGltcHJlc3Npb25zKSB7XG4gICAgICBpbXByZXNzaW9ucyA9IHV0aWxpdGllcy5pc0FycmF5KGltcHJlc3Npb25zKSA/IGltcHJlc3Npb25zIDogW2ltcHJlc3Npb25zXTtcbiAgICAgIHJldHVybiB1dGlsaXRpZXMudHJhbnNmb3JtQXJyYXkoaW1wcmVzc2lvbnMsIGZ1bmN0aW9uIChpbXByZXNzaW9uKSB7XG4gICAgICAgIGlmICh1dGlsaXRpZXMuaXNOb3RFbXB0eVN0cmluZyhpbXByZXNzaW9uLmtleVZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiBpbXByZXNzaW9uLmtleVZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xuICB9LFxuXG5cbiAgLy9XZSBhc3N1bWUgdGhhdCB0aGUgcHJvZ3Jlc3MgaXMgZ29pbmcgdG8gYXJyaXZlIGluIG1pbGxpc2Vjb25kc1xuICBmb3JtYXRQcm9ncmVzczogZnVuY3Rpb24gZm9ybWF0UHJvZ3Jlc3MocHJvZ3Jlc3MpIHtcbiAgICB2YXIgaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMsIG1pbGxpc2Vjb25kcztcbiAgICBob3VycyA9IHByb2dyZXNzIC8gKDYwICogNjAgKiAxMDAwKTtcbiAgICBob3VycyA9IE1hdGguZmxvb3IoaG91cnMpO1xuICAgIG1pbnV0ZXMgPSAocHJvZ3Jlc3MgLyAoNjAgKiAxMDAwKSkgJSA2MDtcbiAgICBtaW51dGVzID0gTWF0aC5mbG9vcihtaW51dGVzKTtcbiAgICBzZWNvbmRzID0gKHByb2dyZXNzIC8gMTAwMCkgJSA2MDtcbiAgICBzZWNvbmRzID0gTWF0aC5mbG9vcihzZWNvbmRzKTtcbiAgICBtaWxsaXNlY29uZHMgPSBwcm9ncmVzcyAlIDEwMDA7XG4gICAgcmV0dXJuIHV0aWxpdGllcy50b0ZpeGVkRGlnaXRzKGhvdXJzLCAyKSArICc6JyArIHV0aWxpdGllcy50b0ZpeGVkRGlnaXRzKG1pbnV0ZXMsIDIpICsgJzonICsgdXRpbGl0aWVzLnRvRml4ZWREaWdpdHMoc2Vjb25kcywgMikgKyAnLicgKyB1dGlsaXRpZXMudG9GaXhlZERpZ2l0cyhtaWxsaXNlY29uZHMsIDMpO1xuICB9LFxuXG4gIHBhcnNlT2Zmc2V0OiBmdW5jdGlvbiBwYXJzZU9mZnNldChvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgaWYgKGlzUGVyY2VudGFnZShvZmZzZXQpKSB7XG4gICAgICByZXR1cm4gY2FsY3VsYXRlUGVyY2VudGFnZShvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhc3RVdGlsLnBhcnNlRHVyYXRpb24ob2Zmc2V0KTtcblxuICAgIC8qKiogTG9jYWwgZnVuY3Rpb24gKioqL1xuICAgIGZ1bmN0aW9uIGlzUGVyY2VudGFnZShvZmZzZXQpIHtcbiAgICAgIHZhciBwZXJjZW50YWdlUmVnZXggPSAvXlxcZCsoXFwuXFxkKyk/JSQvZztcbiAgICAgIHJldHVybiBwZXJjZW50YWdlUmVnZXgudGVzdChvZmZzZXQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNhbGN1bGF0ZVBlcmNlbnRhZ2UocGVyY2VudFN0ciwgZHVyYXRpb24pIHtcbiAgICAgIGlmIChkdXJhdGlvbikge1xuICAgICAgICByZXR1cm4gY2FsY1BlcmNlbnQoZHVyYXRpb24sIHBhcnNlRmxvYXQocGVyY2VudFN0ci5yZXBsYWNlKCclJywgJycpKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjYWxjUGVyY2VudChxdWFudGl0eSwgcGVyY2VudCkge1xuICAgICAgcmV0dXJuIHF1YW50aXR5ICogcGVyY2VudCAvIDEwMDtcbiAgICB9XG4gIH0sXG5cblxuICAvL0xpc3Qgb2Ygc3VwcG9ydGVkIFZQQUlEIHRlY2hub2xvZ2llc1xuICBWUEFJRF90ZWNoczogW1xuICAgIFZQQUlERmxhc2hUZWNoLFxuICAgIFZQQUlESFRNTDVUZWNoXG4gIF0sXG5cbiAgaXNWUEFJRDogZnVuY3Rpb24gaXNWUEFJRE1lZGlhRmlsZShtZWRpYUZpbGUpIHtcbiAgICByZXR1cm4gISFtZWRpYUZpbGUgJiYgbWVkaWFGaWxlLmFwaUZyYW1ld29yayA9PT0gJ1ZQQUlEJztcbiAgfSxcblxuICBmaW5kU3VwcG9ydGVkVlBBSURUZWNoOiBmdW5jdGlvbiBmaW5kU3VwcG9ydGVkVlBBSURUZWNoKG1pbWVUeXBlKSB7XG4gICAgdmFyIGksIGxlbiwgVlBBSURUZWNoO1xuXG4gICAgZm9yIChpID0gMCwgbGVuID0gdGhpcy5WUEFJRF90ZWNocy5sZW5ndGg7IGkgPCBsZW47IGkgKz0gMSkge1xuICAgICAgVlBBSURUZWNoID0gdGhpcy5WUEFJRF90ZWNoc1tpXTtcbiAgICAgIGlmIChWUEFJRFRlY2guc3VwcG9ydHMobWltZVR5cGUpKSB7XG4gICAgICAgIHJldHVybiBWUEFJRFRlY2g7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9LFxuXG4gIGlzRmxhc2hTdXBwb3J0ZWQ6IGZ1bmN0aW9uIGlzRmxhc2hTdXBwb3J0ZWQoKSB7XG4gICAgcmV0dXJuIFZQQUlERkxBU0hDbGllbnQuaXNTdXBwb3J0ZWQoKTtcbiAgfSxcblxuICAvKipcbiAgICogTmVjZXNzYXJ5IHN0ZXAgZm9yIFZQQUlERkxBU2hDbGllbnQgdG8ga25vdyBpZiBmbGFzaCBpcyBzdXBwb3J0ZWQgYW5kIG5vdCBibG9ja2VkLlxuICAgKiBJTVBPUlRBTlQgTk9URTogVGhpcyBpcyBhbiBhc3luYyB0ZXN0IGFuZCBuZWVkcyB0byBiZSBydW4gYXMgc29vbiBhcyBwb3NzaWJsZS5cbiAgICpcbiAgICogQHBhcmFtIHZwYWlkRmxhc2hMb2FkZXJQYXRoIHRoZSBwYXRoIHRvIHRoZSB2cGFpZEZsYXNoTG9hZGVyIHN3ZiBvYmouXG4gICAqL1xuICBydW5GbGFzaFN1cHBvcnRDaGVjazogZnVuY3Rpb24gcnVuRmxhc2hTdXBwb3J0Q2hlY2sodnBhaWRGbGFzaExvYWRlclBhdGgpIHtcbiAgICBWUEFJREZMQVNIQ2xpZW50LnJ1bkZsYXNoVGVzdCh7ZGF0YTogdnBhaWRGbGFzaExvYWRlclBhdGh9KTtcbiAgfVxuXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHZhc3RVdGlsO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVkFTVEVycm9yID0gcmVxdWlyZSgnLi4vdmFzdC9WQVNURXJyb3InKTtcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxuZnVuY3Rpb24gVlBBSURBZFVuaXRXcmFwcGVyKHZwYWlkQWRVbml0LCBvcHRzKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBWUEFJREFkVW5pdFdyYXBwZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBWUEFJREFkVW5pdFdyYXBwZXIodnBhaWRBZFVuaXQsIG9wdHMpO1xuICB9XG4gIHNhbml0eUNoZWNrKHZwYWlkQWRVbml0LCBvcHRzKTtcblxuICB0aGlzLm9wdGlvbnMgPSB1dGlsaXRpZXMuZXh0ZW5kKHt9LCBvcHRzKTtcblxuICB0aGlzLl9hZFVuaXQgPSB2cGFpZEFkVW5pdDtcblxuICAvKioqIExvY2FsIEZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIHNhbml0eUNoZWNrKGFkVW5pdCwgb3B0cykge1xuICAgIGlmICghYWRVbml0IHx8ICFWUEFJREFkVW5pdFdyYXBwZXIuY2hlY2tWUEFJREludGVyZmFjZShhZFVuaXQpKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKCdvbiBWUEFJREFkVW5pdFdyYXBwZXIsIHRoZSBwYXNzZWQgVlBBSUQgYWRVbml0IGRvZXMgbm90IGZ1bGx5IGltcGxlbWVudCB0aGUgVlBBSUQgaW50ZXJmYWNlJyk7XG4gICAgfVxuXG4gICAgaWYgKCF1dGlsaXRpZXMuaXNPYmplY3Qob3B0cykpIHtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoXCJvbiBWUEFJREFkVW5pdFdyYXBwZXIsIGV4cGVjdGVkIG9wdGlvbnMgaGFzaCAgYnV0IGdvdCAnXCIgKyBvcHRzICsgXCInXCIpO1xuICAgIH1cblxuICAgIGlmICghKFwicmVzcG9uc2VUaW1lb3V0XCIgaW4gb3B0cykgfHwgIXV0aWxpdGllcy5pc051bWJlcihvcHRzLnJlc3BvbnNlVGltZW91dCkgKXtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoXCJvbiBWUEFJREFkVW5pdFdyYXBwZXIsIGV4cGVjdGVkIHJlc3BvbnNlVGltZW91dCBpbiBvcHRpb25zXCIpO1xuICAgIH1cbiAgfVxufVxuXG5WUEFJREFkVW5pdFdyYXBwZXIuY2hlY2tWUEFJREludGVyZmFjZSA9IGZ1bmN0aW9uIGNoZWNrVlBBSURJbnRlcmZhY2UoVlBBSURBZFVuaXQpIHtcbiAgLy9OT1RFOiBza2lwQWQgaXMgbm90IHBhcnQgb2YgdGhlIG1ldGhvZCBsaXN0IGJlY2F1c2UgaXQgb25seSBhcHBlYXJzIGluIFZQQUlEIDIuMCBhbmQgd2Ugc3VwcG9ydCBWUEFJRCAxLjBcbiAgdmFyIFZQQUlESW50ZXJmYWNlTWV0aG9kcyA9IFtcbiAgICAnaGFuZHNoYWtlVmVyc2lvbicsICdpbml0QWQnLCAnc3RhcnRBZCcsICdzdG9wQWQnLCAncmVzaXplQWQnLCAncGF1c2VBZCcsICdleHBhbmRBZCcsICdjb2xsYXBzZUFkJ1xuICBdO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBWUEFJREludGVyZmFjZU1ldGhvZHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBpZiAoIVZQQUlEQWRVbml0IHx8ICF1dGlsaXRpZXMuaXNGdW5jdGlvbihWUEFJREFkVW5pdFtWUEFJREludGVyZmFjZU1ldGhvZHNbaV1dKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG5cbiAgcmV0dXJuIGNhblN1YnNjcmliZVRvRXZlbnRzKFZQQUlEQWRVbml0KSAmJiBjYW5VbnN1YnNjcmliZUZyb21FdmVudHMoVlBBSURBZFVuaXQpO1xuXG4gIC8qKiogTG9jYWwgRnVuY3Rpb25zICoqKi9cblxuICBmdW5jdGlvbiBjYW5TdWJzY3JpYmVUb0V2ZW50cyhhZFVuaXQpIHtcbiAgICByZXR1cm4gdXRpbGl0aWVzLmlzRnVuY3Rpb24oYWRVbml0LnN1YnNjcmliZSkgfHwgdXRpbGl0aWVzLmlzRnVuY3Rpb24oYWRVbml0LmFkZEV2ZW50TGlzdGVuZXIpIHx8IHV0aWxpdGllcy5pc0Z1bmN0aW9uKGFkVW5pdC5vbik7XG4gIH1cblxuICBmdW5jdGlvbiBjYW5VbnN1YnNjcmliZUZyb21FdmVudHMoYWRVbml0KSB7XG4gICAgcmV0dXJuIHV0aWxpdGllcy5pc0Z1bmN0aW9uKGFkVW5pdC51bnN1YnNjcmliZSkgfHwgdXRpbGl0aWVzLmlzRnVuY3Rpb24oYWRVbml0LnJlbW92ZUV2ZW50TGlzdGVuZXIpIHx8IHV0aWxpdGllcy5pc0Z1bmN0aW9uKGFkVW5pdC5vZmYpO1xuXG4gIH1cbn07XG5cblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUuYWRVbml0QXN5bmNDYWxsID0gZnVuY3Rpb24gKCkge1xuICB2YXIgYXJncyA9IHV0aWxpdGllcy5hcnJheUxpa2VPYmpUb0FycmF5KGFyZ3VtZW50cyk7XG4gIHZhciBtZXRob2QgPSBhcmdzLnNoaWZ0KCk7XG4gIHZhciBjYiA9IGFyZ3MucG9wKCk7XG4gIHZhciB0aW1lb3V0SWQ7XG5cbiAgc2FuaXR5Q2hlY2sobWV0aG9kLCBjYiwgdGhpcy5fYWRVbml0KTtcbiAgYXJncy5wdXNoKHdyYXBDYWxsYmFjaygpKTtcblxuICB0aGlzLl9hZFVuaXRbbWV0aG9kXS5hcHBseSh0aGlzLl9hZFVuaXQsIGFyZ3MpO1xuICB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICB0aW1lb3V0SWQgPSBudWxsO1xuICAgIGNiKG5ldyBWQVNURXJyb3IoXCJvbiBWUEFJREFkVW5pdFdyYXBwZXIsIHRpbWVvdXQgd2hpbGUgd2FpdGluZyBmb3IgYSByZXNwb25zZSBvbiBjYWxsICdcIiArIG1ldGhvZCArIFwiJ1wiKSk7XG4gICAgY2IgPSB1dGlsaXRpZXMubm9vcDtcbiAgfSwgdGhpcy5vcHRpb25zLnJlc3BvbnNlVGltZW91dCk7XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBzYW5pdHlDaGVjayhtZXRob2QsIGNiLCBhZFVuaXQpIHtcbiAgICBpZiAoIXV0aWxpdGllcy5pc1N0cmluZyhtZXRob2QpIHx8ICF1dGlsaXRpZXMuaXNGdW5jdGlvbihhZFVuaXRbbWV0aG9kXSkpIHtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoXCJvbiBWUEFJREFkVW5pdFdyYXBwZXIuYWRVbml0QXN5bmNDYWxsLCBpbnZhbGlkIG1ldGhvZCBuYW1lXCIpO1xuICAgIH1cblxuICAgIGlmICghdXRpbGl0aWVzLmlzRnVuY3Rpb24oY2IpKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFwib24gVlBBSURBZFVuaXRXcmFwcGVyLmFkVW5pdEFzeW5jQ2FsbCwgbWlzc2luZyBjYWxsYmFja1wiKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB3cmFwQ2FsbGJhY2soKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmICh0aW1lb3V0SWQpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICB9XG4gICAgICBjYi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH1cbn07XG5cblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUub24gPSBmdW5jdGlvbiAoZXZ0TmFtZSwgaGFuZGxlcikge1xuICB2YXIgYWRkRXZlbnRMaXN0ZW5lciA9IHRoaXMuX2FkVW5pdC5hZGRFdmVudExpc3RlbmVyIHx8IHRoaXMuX2FkVW5pdC5zdWJzY3JpYmUgfHwgdGhpcy5fYWRVbml0Lm9uO1xuICBhZGRFdmVudExpc3RlbmVyLmNhbGwodGhpcy5fYWRVbml0LCBldnROYW1lLCBoYW5kbGVyKTtcbn07XG5cblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUub2ZmID0gZnVuY3Rpb24gKGV2dE5hbWUsIGhhbmRsZXIpIHtcbiAgdmFyIHJlbW92ZUV2ZW50TGlzdGVuZXIgPSB0aGlzLl9hZFVuaXQucmVtb3ZlRXZlbnRMaXN0ZW5lciB8fCB0aGlzLl9hZFVuaXQudW5zdWJzY3JpYmUgfHwgdGhpcy5fYWRVbml0Lm9mZjtcbiAgcmVtb3ZlRXZlbnRMaXN0ZW5lci5jYWxsKHRoaXMuX2FkVW5pdCwgZXZ0TmFtZSwgaGFuZGxlcik7XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLndhaXRGb3JFdmVudCA9IGZ1bmN0aW9uIChldnROYW1lLCBjYiwgY29udGV4dCkge1xuICB2YXIgdGltZW91dElkO1xuICBzYW5pdHlDaGVjayhldnROYW1lLCBjYik7XG4gIGNvbnRleHQgPSBjb250ZXh0IHx8IG51bGw7XG5cbiAgdGhpcy5vbihldnROYW1lLCByZXNwb25zZUxpc3RlbmVyKTtcblxuICB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICBjYihuZXcgVkFTVEVycm9yKFwib24gVlBBSURBZFVuaXRXcmFwcGVyLndhaXRGb3JFdmVudCwgdGltZW91dCB3aGlsZSB3YWl0aW5nIGZvciBldmVudCAnXCIgKyBldnROYW1lICsgXCInXCIpKTtcbiAgICB0aW1lb3V0SWQgPSBudWxsO1xuICAgIGNiID0gdXRpbGl0aWVzLm5vb3A7XG4gIH0sIHRoaXMub3B0aW9ucy5yZXNwb25zZVRpbWVvdXQpO1xuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gc2FuaXR5Q2hlY2soZXZ0TmFtZSwgY2IpIHtcbiAgICBpZiAoIXV0aWxpdGllcy5pc1N0cmluZyhldnROYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcihcIm9uIFZQQUlEQWRVbml0V3JhcHBlci53YWl0Rm9yRXZlbnQsIG1pc3NpbmcgZXZ0IG5hbWVcIik7XG4gICAgfVxuXG4gICAgaWYgKCF1dGlsaXRpZXMuaXNGdW5jdGlvbihjYikpIHtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoXCJvbiBWUEFJREFkVW5pdFdyYXBwZXIud2FpdEZvckV2ZW50LCBtaXNzaW5nIGNhbGxiYWNrXCIpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc3BvbnNlTGlzdGVuZXIoKSB7XG4gICAgdmFyIGFyZ3MgPSB1dGlsaXRpZXMuYXJyYXlMaWtlT2JqVG9BcnJheShhcmd1bWVudHMpO1xuXG4gICAgaWYgKHRpbWVvdXRJZCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICB0aW1lb3V0SWQgPSBudWxsO1xuICAgIH1cblxuICAgIGFyZ3MudW5zaGlmdChudWxsKTtcbiAgICBjYi5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgfVxufTtcblxuLy8gVlBBSUQgTUVUSE9EU1xuVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZS5oYW5kc2hha2VWZXJzaW9uID0gZnVuY3Rpb24gKHZlcnNpb24sIGNiKSB7XG4gIHRoaXMuYWRVbml0QXN5bmNDYWxsKCdoYW5kc2hha2VWZXJzaW9uJywgdmVyc2lvbiwgY2IpO1xufTtcblxuLyoganNoaW50IG1heHBhcmFtczo2ICovXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLmluaXRBZCA9IGZ1bmN0aW9uICh3aWR0aCwgaGVpZ2h0LCB2aWV3TW9kZSwgZGVzaXJlZEJpdHJhdGUsIGFkVW5pdERhdGEsIGNiKSB7XG4gIHRoaXMud2FpdEZvckV2ZW50KCdBZExvYWRlZCcsIGNiKTtcbiAgdGhpcy5fYWRVbml0LmluaXRBZCh3aWR0aCwgaGVpZ2h0LCB2aWV3TW9kZSwgZGVzaXJlZEJpdHJhdGUsIGFkVW5pdERhdGEpO1xufTtcblxuVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZS5yZXNpemVBZCA9IGZ1bmN0aW9uICh3aWR0aCwgaGVpZ2h0LCB2aWV3TW9kZSwgY2IpIHtcbiAgLy8gTk9URTogQWRTaXplQ2hhbmdlIGV2ZW50IGlzIG9ubHkgc3VwcG9ydGVkIG9uIFZQQUlEIDIuMCBzbyBmb3IgdGhlIG1vbWVudCB3ZSBhcmUgbm90IGdvaW5nIHRvIHVzZSBpdFxuICAvLyBhbmQgd2lsbCBhc3N1bWUgdGhhdCBldmVyeXRoaW5nIGlzIGZpbmUgYWZ0ZXIgdGhlIGFzeW5jIGNhbGxcbiAgdGhpcy5hZFVuaXRBc3luY0NhbGwoJ3Jlc2l6ZUFkJywgd2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGNiKTtcbn07XG5cblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUuc3RhcnRBZCA9IGZ1bmN0aW9uIChjYikge1xuICB0aGlzLndhaXRGb3JFdmVudCgnQWRTdGFydGVkJywgY2IpO1xuICB0aGlzLl9hZFVuaXQuc3RhcnRBZCgpO1xufTtcblxuVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZS5zdG9wQWQgPSBmdW5jdGlvbiAoY2IpIHtcbiAgdGhpcy53YWl0Rm9yRXZlbnQoJ0FkU3RvcHBlZCcsIGNiKTtcbiAgdGhpcy5fYWRVbml0LnN0b3BBZCgpO1xufTtcblxuVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZS5wYXVzZUFkID0gZnVuY3Rpb24gKGNiKSB7XG4gIHRoaXMud2FpdEZvckV2ZW50KCdBZFBhdXNlZCcsIGNiKTtcbiAgdGhpcy5fYWRVbml0LnBhdXNlQWQoKTtcbn07XG5cblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUucmVzdW1lQWQgPSBmdW5jdGlvbiAoY2IpIHtcbiAgdGhpcy53YWl0Rm9yRXZlbnQoJ0FkUGxheWluZycsIGNiKTtcbiAgdGhpcy5fYWRVbml0LnJlc3VtZUFkKCk7XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLmV4cGFuZEFkID0gZnVuY3Rpb24gKGNiKSB7XG4gIHRoaXMud2FpdEZvckV2ZW50KCdBZEV4cGFuZGVkQ2hhbmdlJywgY2IpO1xuICB0aGlzLl9hZFVuaXQuZXhwYW5kQWQoKTtcbn07XG5cblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUuY29sbGFwc2VBZCA9IGZ1bmN0aW9uIChjYikge1xuICB0aGlzLndhaXRGb3JFdmVudCgnQWRFeHBhbmRlZENoYW5nZScsIGNiKTtcbiAgdGhpcy5fYWRVbml0LmNvbGxhcHNlQWQoKTtcbn07XG5cblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUuc2tpcEFkID0gZnVuY3Rpb24gKGNiKSB7XG4gIHRoaXMud2FpdEZvckV2ZW50KCdBZFNraXBwZWQnLCBjYik7XG4gIHRoaXMuX2FkVW5pdC5za2lwQWQoKTtcbn07XG5cbi8vVlBBSUQgcHJvcGVydHkgZ2V0dGVyc1xuW1xuICAnYWRMaW5lYXInLFxuICAnYWRXaWR0aCcsXG4gICdhZEhlaWdodCcsXG4gICdhZEV4cGFuZGVkJyxcbiAgJ2FkU2tpcHBhYmxlU3RhdGUnLFxuICAnYWRSZW1haW5pbmdUaW1lJyxcbiAgJ2FkRHVyYXRpb24nLFxuICAnYWRWb2x1bWUnLFxuICAnYWRDb21wYW5pb25zJyxcbiAgJ2FkSWNvbnMnXG5dLmZvckVhY2goZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gIHZhciBnZXR0ZXJOYW1lID0gJ2dldCcgKyB1dGlsaXRpZXMuY2FwaXRhbGl6ZShwcm9wZXJ0eSk7XG5cbiAgVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZVtnZXR0ZXJOYW1lXSA9IGZ1bmN0aW9uIChjYikge1xuICAgIHRoaXMuYWRVbml0QXN5bmNDYWxsKGdldHRlck5hbWUsIGNiKTtcbiAgfTtcbn0pO1xuXG4vL1ZQQUlEIHByb3BlcnR5IHNldHRlcnNcblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUuc2V0QWRWb2x1bWUgPSBmdW5jdGlvbih2b2x1bWUsIGNiKXtcbiAgdGhpcy5hZFVuaXRBc3luY0NhbGwoJ3NldEFkVm9sdW1lJyx2b2x1bWUsIGNiKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gVlBBSURBZFVuaXRXcmFwcGVyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVkFTVEVycm9yID0gcmVxdWlyZSgnLi4vdmFzdC9WQVNURXJyb3InKTtcblxudmFyIFZQQUlERkxBU0hDbGllbnQgPSByZXF1aXJlKCdWUEFJREZMQVNIQ2xpZW50L2pzL1ZQQUlERkxBU0hDbGllbnQnKTtcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcbnZhciBkb20gPSByZXF1aXJlKCcuLi8uLi91dGlscy9kb20nKTtcblxuZnVuY3Rpb24gVlBBSURGbGFzaFRlY2gobWVkaWFGaWxlLCBzZXR0aW5ncykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVlBBSURGbGFzaFRlY2gpKSB7XG4gICAgcmV0dXJuIG5ldyBWUEFJREZsYXNoVGVjaChtZWRpYUZpbGUpO1xuICB9XG4gIHNhbml0eUNoZWNrKG1lZGlhRmlsZSk7XG4gIHRoaXMubmFtZSA9ICd2cGFpZC1mbGFzaCc7XG4gIHRoaXMubWVkaWFGaWxlID0gbWVkaWFGaWxlO1xuICB0aGlzLmNvbnRhaW5lckVsID0gbnVsbDtcbiAgdGhpcy52cGFpZEZsYXNoQ2xpZW50ID0gbnVsbDtcbiAgdGhpcy5zZXR0aW5ncyA9IHNldHRpbmdzO1xuXG4gIC8qKiogbG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gc2FuaXR5Q2hlY2sobWVkaWFGaWxlKSB7XG4gICAgaWYgKCFtZWRpYUZpbGUgfHwgIXV0aWxpdGllcy5pc1N0cmluZyhtZWRpYUZpbGUuc3JjKSkge1xuICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcignb24gVlBBSURGbGFzaFRlY2gsIGludmFsaWQgTWVkaWFGaWxlJyk7XG4gICAgfVxuICB9XG59XG5cblZQQUlERmxhc2hUZWNoLlZQQUlERkxBU0hDbGllbnQgPSBWUEFJREZMQVNIQ2xpZW50O1xuXG5WUEFJREZsYXNoVGVjaC5zdXBwb3J0cyA9IGZ1bmN0aW9uICh0eXBlKSB7XG4gIHJldHVybiB0eXBlID09PSAnYXBwbGljYXRpb24veC1zaG9ja3dhdmUtZmxhc2gnICYmIFZQQUlERmxhc2hUZWNoLlZQQUlERkxBU0hDbGllbnQuaXNTdXBwb3J0ZWQoKTtcbn07XG5cblZQQUlERmxhc2hUZWNoLnByb3RvdHlwZS5sb2FkQWRVbml0ID0gZnVuY3Rpb24gbG9hZEZsYXNoQ3JlYXRpdmUoY29udGFpbmVyRWwsIG9iamVjdEVsLCBjYWxsYmFjaykge1xuICB2YXIgdGhhdCA9IHRoaXM7XG4gIHZhciBmbGFzaENsaWVudE9wdHMgPSB0aGlzLnNldHRpbmdzICYmIHRoaXMuc2V0dGluZ3MudnBhaWRGbGFzaExvYWRlclBhdGggPyB7ZGF0YTogdGhpcy5zZXR0aW5ncy52cGFpZEZsYXNoTG9hZGVyUGF0aH0gOiB1bmRlZmluZWQ7XG4gIHNhbml0eUNoZWNrKGNvbnRhaW5lckVsLCBjYWxsYmFjayk7XG5cbiAgdGhpcy5jb250YWluZXJFbCA9IGNvbnRhaW5lckVsO1xuICB0aGlzLnZwYWlkRmxhc2hDbGllbnQgPSBuZXcgVlBBSURGbGFzaFRlY2guVlBBSURGTEFTSENsaWVudChjb250YWluZXJFbCwgZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgaWYgKGVycm9yKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2soZXJyb3IpO1xuICAgIH1cblxuICAgIHRoYXQudnBhaWRGbGFzaENsaWVudC5sb2FkQWRVbml0KHRoYXQubWVkaWFGaWxlLnNyYywgY2FsbGJhY2spO1xuICB9LCBmbGFzaENsaWVudE9wdHMpO1xuXG4gIC8qKiogTG9jYWwgRnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gc2FuaXR5Q2hlY2soY29udGFpbmVyLCBjYikge1xuXG4gICAgaWYgKCFkb20uaXNEb21FbGVtZW50KGNvbnRhaW5lcikpIHtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoJ29uIFZQQUlERmxhc2hUZWNoLmxvYWRBZFVuaXQsIGludmFsaWQgZG9tIGNvbnRhaW5lciBlbGVtZW50Jyk7XG4gICAgfVxuXG4gICAgaWYgKCF1dGlsaXRpZXMuaXNGdW5jdGlvbihjYikpIHtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoJ29uIFZQQUlERmxhc2hUZWNoLmxvYWRBZFVuaXQsIG1pc3NpbmcgdmFsaWQgY2FsbGJhY2snKTtcbiAgICB9XG4gIH1cbn07XG5cblZQQUlERmxhc2hUZWNoLnByb3RvdHlwZS51bmxvYWRBZFVuaXQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnZwYWlkRmxhc2hDbGllbnQpIHtcbiAgICB0cnl7XG4gICAgICB0aGlzLnZwYWlkRmxhc2hDbGllbnQuZGVzdHJveSgpO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICBpZihjb25zb2xlICYmIHV0aWxpdGllcy5pc0Z1bmN0aW9uKGNvbnNvbGUubG9nKSl7XG4gICAgICAgIGNvbnNvbGUubG9nKCdWQVNUIEVSUk9SOiB0cnlpbmcgdG8gdW5sb2FkIHRoZSBWUEFJRCBhZHVuaXQnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy52cGFpZEZsYXNoQ2xpZW50ID0gbnVsbDtcbiAgfVxuXG4gIGlmICh0aGlzLmNvbnRhaW5lckVsKSB7XG4gICAgZG9tLnJlbW92ZSh0aGlzLmNvbnRhaW5lckVsKTtcbiAgICB0aGlzLmNvbnRhaW5lckVsID0gbnVsbDtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBWUEFJREZsYXNoVGVjaDtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFZBU1RFcnJvciA9IHJlcXVpcmUoJy4uL3Zhc3QvVkFTVEVycm9yJyk7XG5cbnZhciBWUEFJREhUTUw1Q2xpZW50ID0gcmVxdWlyZSgnVlBBSURIVE1MNUNsaWVudC9qcy9WUEFJREhUTUw1Q2xpZW50Jyk7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG52YXIgZG9tID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvZG9tJyk7XG5cbmZ1bmN0aW9uIFZQQUlESFRNTDVUZWNoKG1lZGlhRmlsZSkge1xuXG4gIGlmKCEodGhpcyBpbnN0YW5jZW9mIFZQQUlESFRNTDVUZWNoKSkge1xuICAgIHJldHVybiBuZXcgVlBBSURIVE1MNVRlY2gobWVkaWFGaWxlKTtcbiAgfVxuXG4gIHNhbml0eUNoZWNrKG1lZGlhRmlsZSk7XG5cbiAgdGhpcy5uYW1lID0gJ3ZwYWlkLWh0bWw1JztcbiAgdGhpcy5jb250YWluZXJFbCA9IG51bGw7XG4gIHRoaXMudmlkZW9FbCA9IG51bGw7XG4gIHRoaXMudnBhaWRIVE1MQ2xpZW50ID0gbnVsbDtcblxuICB0aGlzLm1lZGlhRmlsZSA9IG1lZGlhRmlsZTtcblxuICBmdW5jdGlvbiBzYW5pdHlDaGVjayhtZWRpYUZpbGUpIHtcbiAgICAgIGlmICghbWVkaWFGaWxlIHx8ICF1dGlsaXRpZXMuaXNTdHJpbmcobWVkaWFGaWxlLnNyYykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcihWUEFJREhUTUw1VGVjaC5JTlZBTElEX01FRElBX0ZJTEUpO1xuICAgICAgfVxuICB9XG59XG5cblZQQUlESFRNTDVUZWNoLlZQQUlESFRNTDVDbGllbnQgPSBWUEFJREhUTUw1Q2xpZW50O1xuXG5WUEFJREhUTUw1VGVjaC5zdXBwb3J0cyA9IGZ1bmN0aW9uICh0eXBlKSB7XG4gIHJldHVybiAhdXRpbGl0aWVzLmlzT2xkSUUoKSAmJiB0eXBlID09PSAnYXBwbGljYXRpb24vamF2YXNjcmlwdCc7XG59O1xuXG5WUEFJREhUTUw1VGVjaC5wcm90b3R5cGUubG9hZEFkVW5pdCA9IGZ1bmN0aW9uIGxvYWRBZFVuaXQoY29udGFpbmVyRWwsIHZpZGVvRWwsIGNhbGxiYWNrKSB7XG4gIHNhbml0eUNoZWNrKGNvbnRhaW5lckVsLCB2aWRlb0VsLCBjYWxsYmFjayk7XG5cbiAgdGhpcy5jb250YWluZXJFbCA9IGNvbnRhaW5lckVsO1xuICB0aGlzLnZpZGVvRWwgPSB2aWRlb0VsO1xuICB0aGlzLnZwYWlkSFRNTENsaWVudCA9IG5ldyBWUEFJREhUTUw1VGVjaC5WUEFJREhUTUw1Q2xpZW50KGNvbnRhaW5lckVsLCB2aWRlb0VsLCB7fSk7XG4gIHRoaXMudnBhaWRIVE1MQ2xpZW50LmxvYWRBZFVuaXQodGhpcy5tZWRpYUZpbGUuc3JjLCBjYWxsYmFjayk7XG5cbiAgZnVuY3Rpb24gc2FuaXR5Q2hlY2soY29udGFpbmVyLCB2aWRlbywgY2IpIHtcbiAgICBpZiAoIWRvbS5pc0RvbUVsZW1lbnQoY29udGFpbmVyKSkge1xuICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcihWUEFJREhUTUw1VGVjaC5JTlZBTElEX0RPTV9DT05UQUlORVJfRUwpO1xuICAgIH1cblxuICAgIGlmICghZG9tLmlzRG9tRWxlbWVudCh2aWRlbykgfHwgdmlkZW8udGFnTmFtZS50b0xvd2VyQ2FzZSgpICE9PSAndmlkZW8nKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFZQQUlESFRNTDVUZWNoLklOVkFMSURfRE9NX0NPTlRBSU5FUl9FTCk7XG4gICAgfVxuXG4gICAgaWYgKCF1dGlsaXRpZXMuaXNGdW5jdGlvbihjYikpIHtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoVlBBSURIVE1MNVRlY2guTUlTU0lOR19DQUxMQkFDSyk7XG4gICAgfVxuICB9XG59O1xuXG5WUEFJREhUTUw1VGVjaC5wcm90b3R5cGUudW5sb2FkQWRVbml0ID0gZnVuY3Rpb24gdW5sb2FkQWRVbml0KCkge1xuICBpZiAodGhpcy52cGFpZEhUTUxDbGllbnQpIHtcbiAgICB0cnkge1xuICAgICAgdGhpcy52cGFpZEhUTUxDbGllbnQuZGVzdHJveSgpO1xuICAgIH0gY2F0Y2goZSkge1xuICAgICAgaWYgKGNvbnNvbGUgJiYgdXRpbGl0aWVzLmlzRnVuY3Rpb24oY29uc29sZS5sb2cpKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdWQVNUIEVSUk9SOiB0cnlpbmcgdG8gdW5sb2FkIHRoZSBWUEFJRCBhZHVuaXQnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnZwYWlkSFRNTENsaWVudCA9IG51bGw7XG4gIH1cblxuICBpZiAodGhpcy5jb250YWluZXJFbCkge1xuICAgIGRvbS5yZW1vdmUodGhpcy5jb250YWluZXJFbCk7XG4gICAgdGhpcy5jb250YWluZXJFbCA9IG51bGw7XG4gIH1cbn07XG5cbnZhciBQUkVGSVggPSAnb24gVlBBSURIVE1MNVRlY2gnO1xuVlBBSURIVE1MNVRlY2guSU5WQUxJRF9NRURJQV9GSUxFID0gUFJFRklYICsgJywgaW52YWxpZCBNZWRpYUZpbGUnO1xuVlBBSURIVE1MNVRlY2guSU5WQUxJRF9ET01fQ09OVEFJTkVSX0VMID0gUFJFRklYICsgJywgaW52YWxpZCBjb250YWluZXIgSHRtbEVsZW1lbnQnO1xuVlBBSURIVE1MNVRlY2guSU5WQUxJRF9ET01fVklERU9fRUwgPSBQUkVGSVggKyAnLCBpbnZhbGlkIEhUTUxWaWRlb0VsZW1lbnQnO1xuVlBBSURIVE1MNVRlY2guTUlTU0lOR19DQUxMQkFDSyA9IFBSRUZJWCArICcsIG1pc3NpbmcgdmFsaWQgY2FsbGJhY2snO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZQQUlESFRNTDVUZWNoOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIFZBU1RFcnJvciA9IHJlcXVpcmUoJy4uL3Zhc3QvVkFTVEVycm9yJyk7XG52YXIgVkFTVFJlc3BvbnNlID0gcmVxdWlyZSgnLi4vdmFzdC9WQVNUUmVzcG9uc2UnKTtcbnZhciBWQVNUVHJhY2tlciA9IHJlcXVpcmUoJy4uL3Zhc3QvVkFTVFRyYWNrZXInKTtcbnZhciB2YXN0VXRpbCA9IHJlcXVpcmUoJy4uL3Zhc3QvdmFzdFV0aWwnKTtcblxudmFyIFZQQUlEQWRVbml0V3JhcHBlciA9IHJlcXVpcmUoJy4vVlBBSURBZFVuaXRXcmFwcGVyJyk7XG5cbnZhciBhc3luYyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL2FzeW5jJyk7XG52YXIgZG9tID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvZG9tJyk7XG52YXIgcGxheWVyVXRpbHMgPSByZXF1aXJlKCcuLi8uLi91dGlscy9wbGF5ZXJVdGlscycpO1xudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxuZnVuY3Rpb24gVlBBSURJbnRlZ3JhdG9yKHBsYXllciwgc2V0dGluZ3MpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFZQQUlESW50ZWdyYXRvcikpIHtcbiAgICByZXR1cm4gbmV3IFZQQUlESW50ZWdyYXRvcihwbGF5ZXIpO1xuICB9XG5cbiAgdGhpcy5WSUVXX01PREUgPSB7XG4gICAgTk9STUFMOiAnbm9ybWFsJyxcbiAgICBGVUxMU0NSRUVOOiBcImZ1bGxzY3JlZW5cIixcbiAgICBUSFVNQk5BSUw6IFwidGh1bWJuYWlsXCJcbiAgfTtcbiAgdGhpcy5wbGF5ZXIgPSBwbGF5ZXI7XG4gIHRoaXMuY29udGFpbmVyRWwgPSBjcmVhdGVWUEFJRENvbnRhaW5lckVsKHBsYXllcik7XG4gIHRoaXMub3B0aW9ucyA9IHtcbiAgICByZXNwb25zZVRpbWVvdXQ6IDUwMDAsXG4gICAgVlBBSURfVkVSU0lPTjogJzIuMCdcbiAgfTtcbiAgdGhpcy5zZXR0aW5ncyA9IHNldHRpbmdzO1xuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cblxuICBmdW5jdGlvbiBjcmVhdGVWUEFJRENvbnRhaW5lckVsKCkge1xuICAgIHZhciBjb250YWluZXJFbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRvbS5hZGRDbGFzcyhjb250YWluZXJFbCwgJ1ZQQUlELWNvbnRhaW5lcicpO1xuICAgIHBsYXllci5lbCgpLmluc2VydEJlZm9yZShjb250YWluZXJFbCwgcGxheWVyLmNvbnRyb2xCYXIuZWwoKSk7XG4gICAgcmV0dXJuIGNvbnRhaW5lckVsO1xuXG4gIH1cbn1cblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5wbGF5QWQgPSBmdW5jdGlvbiBwbGF5VlBhaWRBZCh2YXN0UmVzcG9uc2UsIGNhbGxiYWNrKSB7XG4gIGlmICghKHZhc3RSZXNwb25zZSBpbnN0YW5jZW9mIFZBU1RSZXNwb25zZSkpIHtcbiAgICByZXR1cm4gY2FsbGJhY2sobmV3IFZBU1RFcnJvcignb24gVkFTVEludGVncmF0b3IucGxheUFkLCBtaXNzaW5nIHJlcXVpcmVkIFZBU1RSZXNwb25zZScpKTtcbiAgfVxuXG4gIHZhciB0aGF0ID0gdGhpcztcbiAgdmFyIHBsYXllciA9IHRoaXMucGxheWVyO1xuICB2YXIgdGVjaCA9IHRoaXMuX2ZpbmRTdXBwb3J0ZWRUZWNoKHZhc3RSZXNwb25zZSwgdGhpcy5zZXR0aW5ncyk7XG5cbiAgY2FsbGJhY2sgPSBjYWxsYmFjayB8fCB1dGlsaXRpZXMubm9vcDtcblxuICB0aGlzLl9hZFVuaXQgPSBudWxsO1xuXG4gIGRvbS5hZGRDbGFzcyhwbGF5ZXIuZWwoKSwgJ3Zqcy12cGFpZC1hZCcpO1xuXG4gIHBsYXllci5vbigndmFzdC5hZHNDYW5jZWwnLCB0cmlnZ2VyVnBhaWRBZEVuZCk7XG4gIHBsYXllci5vbmUoJ3ZwYWlkLmFkRW5kJywgZnVuY3Rpb24oKXtcbiAgICBwbGF5ZXIub2ZmKCd2YXN0LmFkc0NhbmNlbCcsIHRyaWdnZXJWcGFpZEFkRW5kKTtcbiAgICByZW1vdmVBZFVuaXQoKTtcbiAgfSk7XG5cbiAgaWYgKHRlY2gpIHtcbiAgICBhc3luYy53YXRlcmZhbGwoW1xuICAgICAgZnVuY3Rpb24gKG5leHQpIHtcbiAgICAgICAgbmV4dChudWxsLCB0ZWNoLCB2YXN0UmVzcG9uc2UpO1xuICAgICAgfSxcbiAgICAgIHRoaXMuX2xvYWRBZFVuaXQuYmluZCh0aGlzKSxcbiAgICAgIHRoaXMuX3BsYXlBZFVuaXQuYmluZCh0aGlzKSxcbiAgICAgIHRoaXMuX2ZpbmlzaFBsYXlpbmcuYmluZCh0aGlzKVxuXG4gICAgXSwgYWRDb21wbGV0ZSk7XG5cbiAgICB0aGlzLl9hZFVuaXQgPSB7XG4gICAgICBfcGF1c2VkOiB0cnVlLFxuICAgICAgdHlwZTogJ1ZQQUlEJyxcbiAgICAgIHBhdXNlQWQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQucGF1c2VBZCcpO1xuICAgICAgICBwbGF5ZXIucGF1c2UodHJ1ZSk7Ly93ZSBtYWtlIHN1cmUgdGhhdCB0aGUgdmlkZW8gY29udGVudCBnZXRzIHN0b3BwZWQuXG4gICAgICB9LFxuICAgICAgcmVzdW1lQWQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5yZXN1bWVBZCcpO1xuICAgICAgfSxcbiAgICAgIGlzUGF1c2VkOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhdXNlZDtcbiAgICAgIH0sXG4gICAgICBnZXRTcmM6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGVjaC5tZWRpYUZpbGU7XG4gICAgICB9XG4gICAgfTtcblxuICB9IGVsc2Uge1xuICAgIHZhciBlcnJvciA9IG5ldyBWQVNURXJyb3IoJ29uIFZQQUlESW50ZWdyYXRvci5wbGF5QWQsIGNvdWxkIG5vdCBmaW5kIGEgc3VwcG9ydGVkIG1lZGlhRmlsZScsIDQwMyk7XG4gICAgYWRDb21wbGV0ZShlcnJvciwgdGhpcy5fYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuX2FkVW5pdDtcblxuICAvKioqIExvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIGFkQ29tcGxldGUoZXJyb3IsIGFkVW5pdCwgdmFzdFJlc3BvbnNlKSB7XG4gICAgaWYgKGVycm9yICYmIHZhc3RSZXNwb25zZSkge1xuICAgICAgdGhhdC5fdHJhY2tFcnJvcih2YXN0UmVzcG9uc2UsIGVycm9yLmNvZGUpO1xuICAgIH1cbiAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuYWRFbmQnKTtcbiAgICBjYWxsYmFjayhlcnJvciwgdmFzdFJlc3BvbnNlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyaWdnZXJWcGFpZEFkRW5kKCl7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLmFkRW5kJyk7XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVBZFVuaXQoKSB7XG4gICAgaWYgKHRlY2gpIHtcbiAgICAgIHRlY2gudW5sb2FkQWRVbml0KCk7XG4gICAgfVxuICAgIGRvbS5yZW1vdmVDbGFzcyhwbGF5ZXIuZWwoKSwgJ3Zqcy12cGFpZC1hZCcpO1xuICB9XG59O1xuXG5WUEFJREludGVncmF0b3IucHJvdG90eXBlLl9maW5kU3VwcG9ydGVkVGVjaCA9IGZ1bmN0aW9uICh2YXN0UmVzcG9uc2UsIHNldHRpbmdzKSB7XG4gIGlmICghKHZhc3RSZXNwb25zZSBpbnN0YW5jZW9mIFZBU1RSZXNwb25zZSkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciB2cGFpZE1lZGlhRmlsZXMgPSB2YXN0UmVzcG9uc2UubWVkaWFGaWxlcy5maWx0ZXIodmFzdFV0aWwuaXNWUEFJRCk7XG4gIHZhciBpLCBsZW4sIG1lZGlhRmlsZSwgVlBBSURUZWNoO1xuXG4gIGZvciAoaSA9IDAsIGxlbiA9IHZwYWlkTWVkaWFGaWxlcy5sZW5ndGg7IGkgPCBsZW47IGkgKz0gMSkge1xuICAgIG1lZGlhRmlsZSA9IHZwYWlkTWVkaWFGaWxlc1tpXTtcbiAgICBWUEFJRFRlY2ggPSB2YXN0VXRpbC5maW5kU3VwcG9ydGVkVlBBSURUZWNoKG1lZGlhRmlsZS50eXBlKTtcbiAgICBpZiAoVlBBSURUZWNoKSB7XG4gICAgICByZXR1cm4gbmV3IFZQQUlEVGVjaChtZWRpYUZpbGUsIHNldHRpbmdzKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59O1xuXG5WUEFJREludGVncmF0b3IucHJvdG90eXBlLl9jcmVhdGVWUEFJREFkVW5pdFdyYXBwZXIgPSBmdW5jdGlvbihhZFVuaXQsIHNyYywgcmVzcG9uc2VUaW1lb3V0KSB7XG4gIHJldHVybiBuZXcgVlBBSURBZFVuaXRXcmFwcGVyKGFkVW5pdCwge3NyYzogc3JjLCByZXNwb25zZVRpbWVvdXQ6IHJlc3BvbnNlVGltZW91dH0pO1xufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5fbG9hZEFkVW5pdCA9IGZ1bmN0aW9uICh0ZWNoLCB2YXN0UmVzcG9uc2UsIG5leHQpIHtcbiAgdmFyIHRoYXQgPSB0aGlzO1xuICB2YXIgcGxheWVyID0gdGhpcy5wbGF5ZXI7XG4gIHZhciB2anNUZWNoRWwgPSBwbGF5ZXIuZWwoKS5xdWVyeVNlbGVjdG9yKCcudmpzLXRlY2gnKTtcbiAgdmFyIHJlc3BvbnNlVGltZW91dCA9IHRoaXMuc2V0dGluZ3MucmVzcG9uc2VUaW1lb3V0IHx8IHRoaXMub3B0aW9ucy5yZXNwb25zZVRpbWVvdXQ7XG4gIHRlY2gubG9hZEFkVW5pdCh0aGlzLmNvbnRhaW5lckVsLCB2anNUZWNoRWwsIGZ1bmN0aW9uIChlcnJvciwgYWRVbml0KSB7XG4gICAgaWYgKGVycm9yKSB7XG4gICAgICByZXR1cm4gbmV4dChlcnJvciwgYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICB2YXIgV3JhcHBlZEFkVW5pdCA9IHRoYXQuX2NyZWF0ZVZQQUlEQWRVbml0V3JhcHBlcihhZFVuaXQsIHRlY2gubWVkaWFGaWxlLnNyYywgcmVzcG9uc2VUaW1lb3V0KTtcbiAgICAgIHZhciB0ZWNoQ2xhc3MgPSAndmpzLScgKyB0ZWNoLm5hbWUgKyAnLWFkJztcbiAgICAgIGRvbS5hZGRDbGFzcyhwbGF5ZXIuZWwoKSwgdGVjaENsYXNzKTtcbiAgICAgIHBsYXllci5vbmUoJ3ZwYWlkLmFkRW5kJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGRvbS5yZW1vdmVDbGFzcyhwbGF5ZXIuZWwoKSx0ZWNoQ2xhc3MpO1xuICAgICAgfSk7XG4gICAgICBuZXh0KG51bGwsIFdyYXBwZWRBZFVuaXQsIHZhc3RSZXNwb25zZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbmV4dChlLCBhZFVuaXQsIHZhc3RSZXNwb25zZSk7XG4gICAgfVxuICB9KTtcbn07XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUuX3BsYXlBZFVuaXQgPSBmdW5jdGlvbiAoYWRVbml0LCB2YXN0UmVzcG9uc2UsIGNhbGxiYWNrKSB7XG4gIGFzeW5jLndhdGVyZmFsbChbXG4gICAgZnVuY3Rpb24gKG5leHQpIHtcbiAgICAgIG5leHQobnVsbCwgYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuICAgIH0sXG4gICAgdGhpcy5faGFuZHNoYWtlLmJpbmQodGhpcyksXG4gICAgdGhpcy5faW5pdEFkLmJpbmQodGhpcyksXG4gICAgdGhpcy5fc2V0dXBFdmVudHMuYmluZCh0aGlzKSxcbiAgICB0aGlzLl9hZGRTa2lwQnV0dG9uLmJpbmQodGhpcyksXG4gICAgdGhpcy5fbGlua1BsYXllckNvbnRyb2xzLmJpbmQodGhpcyksXG4gICAgdGhpcy5fc3RhcnRBZC5iaW5kKHRoaXMpXG4gIF0sIGNhbGxiYWNrKTtcbn07XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUuX2hhbmRzaGFrZSA9IGZ1bmN0aW9uIGhhbmRzaGFrZShhZFVuaXQsIHZhc3RSZXNwb25zZSwgbmV4dCkge1xuICBhZFVuaXQuaGFuZHNoYWtlVmVyc2lvbih0aGlzLm9wdGlvbnMuVlBBSURfVkVSU0lPTiwgZnVuY3Rpb24gKGVycm9yLCB2ZXJzaW9uKSB7XG4gICAgaWYgKGVycm9yKSB7XG4gICAgICByZXR1cm4gbmV4dChlcnJvciwgYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuICAgIH1cblxuICAgIGlmICh2ZXJzaW9uICYmIGlzU3VwcG9ydGVkVmVyc2lvbih2ZXJzaW9uKSkge1xuICAgICAgcmV0dXJuIG5leHQobnVsbCwgYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXh0KG5ldyBWQVNURXJyb3IoJ29uIFZQQUlESW50ZWdyYXRvci5faGFuZHNoYWtlLCB1bnN1cHBvcnRlZCB2ZXJzaW9uIFwiJyArIHZlcnNpb24gKyAnXCInKSwgYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuICB9KTtcblxuICBmdW5jdGlvbiBpc1N1cHBvcnRlZFZlcnNpb24odmVyc2lvbikge1xuICAgIHZhciBtYWpvck51bSA9IG1ham9yKHZlcnNpb24pO1xuICAgIHJldHVybiBtYWpvck51bSA+PSAxICYmIG1ham9yTnVtIDw9IDI7XG4gIH1cblxuICBmdW5jdGlvbiBtYWpvcih2ZXJzaW9uKSB7XG4gICAgdmFyIHBhcnRzID0gdmVyc2lvbi5zcGxpdCgnLicpO1xuICAgIHJldHVybiBwYXJzZUludChwYXJ0c1swXSwgMTApO1xuICB9XG59O1xuXG5WUEFJREludGVncmF0b3IucHJvdG90eXBlLl9pbml0QWQgPSBmdW5jdGlvbiAoYWRVbml0LCB2YXN0UmVzcG9uc2UsIG5leHQpIHtcbiAgdmFyIHRlY2ggPSB0aGlzLnBsYXllci5lbCgpLnF1ZXJ5U2VsZWN0b3IoJy52anMtdGVjaCcpO1xuICB2YXIgZGltZW5zaW9uID0gZG9tLmdldERpbWVuc2lvbih0ZWNoKTtcbiAgYWRVbml0LmluaXRBZChkaW1lbnNpb24ud2lkdGgsIGRpbWVuc2lvbi5oZWlnaHQsIHRoaXMuVklFV19NT0RFLk5PUk1BTCwgLTEsIHtBZFBhcmFtZXRlcnM6IHZhc3RSZXNwb25zZS5hZFBhcmFtZXRlcnMgfHwgJyd9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICBuZXh0KGVycm9yLCBhZFVuaXQsIHZhc3RSZXNwb25zZSk7XG4gIH0pO1xufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5fY3JlYXRlVkFTVFRyYWNrZXIgPSBmdW5jdGlvbihhZFVuaXRTcmMsIHZhc3RSZXNwb25zZSkge1xuICByZXR1cm4gbmV3IFZBU1RUcmFja2VyKGFkVW5pdFNyYywgdmFzdFJlc3BvbnNlKTtcbn07XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUuX3NldHVwRXZlbnRzID0gZnVuY3Rpb24gKGFkVW5pdCwgdmFzdFJlc3BvbnNlLCBuZXh0KSB7XG4gIHZhciBhZFVuaXRTcmMgPSBhZFVuaXQub3B0aW9ucy5zcmM7XG4gIHZhciB0cmFja2VyID0gdGhpcy5fY3JlYXRlVkFTVFRyYWNrZXIoYWRVbml0U3JjLCB2YXN0UmVzcG9uc2UpO1xuICB2YXIgcGxheWVyID0gdGhpcy5wbGF5ZXI7XG4gIHZhciB0aGF0ID0gdGhpcztcblxuICBhZFVuaXQub24oJ0FkU2tpcHBlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuQWRTa2lwcGVkJyk7XG4gICAgdHJhY2tlci50cmFja1NraXAoKTtcbiAgfSk7XG5cbiAgYWRVbml0Lm9uKCdBZEltcHJlc3Npb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkSW1wcmVzc2lvbicpO1xuICAgIHRyYWNrZXIudHJhY2tJbXByZXNzaW9ucygpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkU3RhcnRlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuQWRTdGFydGVkJyk7XG4gICAgdHJhY2tlci50cmFja0NyZWF0aXZlVmlldygpO1xuICAgIG5vdGlmeVBsYXlUb1BsYXllcigpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkVmlkZW9TdGFydCcsIGZ1bmN0aW9uICgpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuQWRWaWRlb1N0YXJ0Jyk7XG4gICAgdHJhY2tlci50cmFja1N0YXJ0KCk7XG4gICAgbm90aWZ5UGxheVRvUGxheWVyKCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRQbGF5aW5nJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFBsYXlpbmcnKTtcbiAgICB0cmFja2VyLnRyYWNrUmVzdW1lKCk7XG4gICAgbm90aWZ5UGxheVRvUGxheWVyKCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRQYXVzZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkUGF1c2VkJyk7XG4gICAgdHJhY2tlci50cmFja1BhdXNlKCk7XG4gICAgbm90aWZ5UGF1c2VUb1BsYXllcigpO1xuICB9KTtcblxuICBmdW5jdGlvbiBub3RpZnlQbGF5VG9QbGF5ZXIoKXtcbiAgICBpZih0aGF0Ll9hZFVuaXQgJiYgdGhhdC5fYWRVbml0LmlzUGF1c2VkKCkpe1xuICAgICAgdGhhdC5fYWRVbml0Ll9wYXVzZWQgPSBmYWxzZTtcbiAgICB9XG4gICAgcGxheWVyLnRyaWdnZXIoJ3BsYXknKTtcblxuICB9XG5cbiAgZnVuY3Rpb24gbm90aWZ5UGF1c2VUb1BsYXllcigpIHtcbiAgICBpZih0aGF0Ll9hZFVuaXQpe1xuICAgICAgdGhhdC5fYWRVbml0Ll9wYXVzZWQgPSB0cnVlO1xuICAgIH1cbiAgICBwbGF5ZXIudHJpZ2dlcigncGF1c2UnKTtcbiAgfVxuXG4gIGFkVW5pdC5vbignQWRWaWRlb0ZpcnN0UXVhcnRpbGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkVmlkZW9GaXJzdFF1YXJ0aWxlJyk7XG4gICAgdHJhY2tlci50cmFja0ZpcnN0UXVhcnRpbGUoKTtcbiAgfSk7XG5cbiAgYWRVbml0Lm9uKCdBZFZpZGVvTWlkcG9pbnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkVmlkZW9NaWRwb2ludCcpO1xuICAgIHRyYWNrZXIudHJhY2tNaWRwb2ludCgpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkVmlkZW9UaGlyZFF1YXJ0aWxlJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFZpZGVvVGhpcmRRdWFydGlsZScpO1xuICAgIHRyYWNrZXIudHJhY2tUaGlyZFF1YXJ0aWxlKCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRWaWRlb0NvbXBsZXRlJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFZpZGVvQ29tcGxldGUnKTtcbiAgICB0cmFja2VyLnRyYWNrQ29tcGxldGUoKTtcbiAgfSk7XG5cbiAgYWRVbml0Lm9uKCdBZENsaWNrVGhydScsIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkQ2xpY2tUaHJ1Jyk7XG4gICAgdmFyIHVybCA9IGRhdGEudXJsO1xuICAgIHZhciBwbGF5ZXJIYW5kbGVzID0gZGF0YS5wbGF5ZXJIYW5kbGVzO1xuICAgIHZhciBjbGlja1RocnVVcmwgPSB1dGlsaXRpZXMuaXNOb3RFbXB0eVN0cmluZyh1cmwpID8gdXJsIDogZ2VuZXJhdGVDbGlja1Rocm91Z2hVUkwodmFzdFJlc3BvbnNlLmNsaWNrVGhyb3VnaCk7XG5cbiAgICB0cmFja2VyLnRyYWNrQ2xpY2soKTtcbiAgICBpZiAocGxheWVySGFuZGxlcyAmJiBjbGlja1RocnVVcmwpIHtcbiAgICAgIHdpbmRvdy5vcGVuKGNsaWNrVGhydVVybCwgJ19ibGFuaycpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdlbmVyYXRlQ2xpY2tUaHJvdWdoVVJMKGNsaWNrVGhyb3VnaE1hY3JvKSB7XG4gICAgICB2YXIgdmFyaWFibGVzID0ge1xuICAgICAgICBBU1NFVFVSSTogYWRVbml0Lm9wdGlvbnMuc3JjLFxuICAgICAgICBDT05URU5UUExBWUhFQUQ6IDAgLy9JbiBWUEFJRCB0aGVyZSBpcyBubyBtZXRob2QgdG8ga25vdyB0aGUgY3VycmVudCB0aW1lIGZyb20gdGhlIGFkVW5pdFxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIGNsaWNrVGhyb3VnaE1hY3JvID8gdmFzdFV0aWwucGFyc2VVUkxNYWNybyhjbGlja1Rocm91Z2hNYWNybywgdmFyaWFibGVzKSA6IG51bGw7XG4gICAgfVxuICB9KTtcblxuICBhZFVuaXQub24oJ0FkVXNlckFjY2VwdEludml0YXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkVXNlckFjY2VwdEludml0YXRpb24nKTtcbiAgICB0cmFja2VyLnRyYWNrQWNjZXB0SW52aXRhdGlvbigpO1xuICAgIHRyYWNrZXIudHJhY2tBY2NlcHRJbnZpdGF0aW9uTGluZWFyKCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRVc2VyQ2xvc2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkVXNlckNsb3NlJyk7XG4gICAgdHJhY2tlci50cmFja0Nsb3NlKCk7XG4gICAgdHJhY2tlci50cmFja0Nsb3NlTGluZWFyKCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRVc2VyTWluaW1pemUnLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkVXNlck1pbmltaXplJyk7XG4gICAgdHJhY2tlci50cmFja0NvbGxhcHNlKCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRFcnJvcicsIGZ1bmN0aW9uICgpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuQWRFcnJvcicpO1xuICAgIC8vTk9URTogd2UgdHJhY2sgZXJyb3JzIGNvZGUgOTAxLCBhcyBub3RlZCBpbiBWQVNUIDMuMFxuICAgIHRyYWNrZXIudHJhY2tFcnJvcldpdGhDb2RlKDkwMSk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRWb2x1bWVDaGFuZ2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkVm9sdW1lQ2hhbmdlJyk7XG4gICAgdmFyIGxhc3RWb2x1bWUgPSBwbGF5ZXIudm9sdW1lKCk7XG4gICAgYWRVbml0LmdldEFkVm9sdW1lKGZ1bmN0aW9uIChlcnJvciwgY3VycmVudFZvbHVtZSkge1xuICAgICAgaWYgKGN1cnJlbnRWb2x1bWUgPT09IDAgJiYgbGFzdFZvbHVtZSA+IDApIHtcbiAgICAgICAgdHJhY2tlci50cmFja011dGUoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGN1cnJlbnRWb2x1bWUgPiAwICYmIGxhc3RWb2x1bWUgPT09IDApIHtcbiAgICAgICAgdHJhY2tlci50cmFja1VubXV0ZSgpO1xuICAgICAgfVxuXG4gICAgICBwbGF5ZXIudm9sdW1lKGN1cnJlbnRWb2x1bWUpO1xuICAgIH0pO1xuICB9KTtcblxuICB2YXIgdXBkYXRlVmlld1NpemUgPSByZXNpemVBZC5iaW5kKHRoaXMsIHBsYXllciwgYWRVbml0LCB0aGlzLlZJRVdfTU9ERSk7XG4gIHZhciB1cGRhdGVWaWV3U2l6ZVRocm90dGxlZCA9IHV0aWxpdGllcy50aHJvdHRsZSh1cGRhdGVWaWV3U2l6ZSwgMTAwKTtcbiAgdmFyIGF1dG9SZXNpemUgPSB0aGlzLnNldHRpbmdzLmF1dG9SZXNpemU7XG5cbiAgaWYgKGF1dG9SZXNpemUpIHtcbiAgICBkb20uYWRkRXZlbnRMaXN0ZW5lcih3aW5kb3csICdyZXNpemUnLCB1cGRhdGVWaWV3U2l6ZVRocm90dGxlZCk7XG4gICAgZG9tLmFkZEV2ZW50TGlzdGVuZXIod2luZG93LCAnb3JpZW50YXRpb25jaGFuZ2UnLCB1cGRhdGVWaWV3U2l6ZVRocm90dGxlZCk7XG4gIH1cblxuICBwbGF5ZXIub24oJ3Zhc3QucmVzaXplJywgdXBkYXRlVmlld1NpemUpO1xuICBwbGF5ZXIub24oJ3ZwYWlkLnBhdXNlQWQnLCBwYXVzZUFkVW5pdCk7XG4gIHBsYXllci5vbigndnBhaWQucmVzdW1lQWQnLCByZXN1bWVBZFVuaXQpO1xuXG4gIHBsYXllci5vbmUoJ3ZwYWlkLmFkRW5kJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci5vZmYoJ3Zhc3QucmVzaXplJywgdXBkYXRlVmlld1NpemUpO1xuICAgIHBsYXllci5vZmYoJ3ZwYWlkLnBhdXNlQWQnLCBwYXVzZUFkVW5pdCk7XG4gICAgcGxheWVyLm9mZigndnBhaWQucmVzdW1lQWQnLCByZXN1bWVBZFVuaXQpO1xuXG4gICAgaWYgKGF1dG9SZXNpemUpIHtcbiAgICAgIGRvbS5yZW1vdmVFdmVudExpc3RlbmVyKHdpbmRvdywgJ3Jlc2l6ZScsIHVwZGF0ZVZpZXdTaXplVGhyb3R0bGVkKTtcbiAgICAgIGRvbS5yZW1vdmVFdmVudExpc3RlbmVyKHdpbmRvdywgJ29yaWVudGF0aW9uY2hhbmdlJywgdXBkYXRlVmlld1NpemVUaHJvdHRsZWQpO1xuICAgIH1cbiAgfSk7XG5cbiAgbmV4dChudWxsLCBhZFVuaXQsIHZhc3RSZXNwb25zZSk7XG5cbiAgLyoqKiBMb2NhbCBGdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBwYXVzZUFkVW5pdCgpIHtcbiAgICBhZFVuaXQucGF1c2VBZCh1dGlsaXRpZXMubm9vcCk7XG4gIH1cblxuICBmdW5jdGlvbiByZXN1bWVBZFVuaXQoKSB7XG4gICAgYWRVbml0LnJlc3VtZUFkKHV0aWxpdGllcy5ub29wKTtcbiAgfVxufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5fYWRkU2tpcEJ1dHRvbiA9IGZ1bmN0aW9uIChhZFVuaXQsIHZhc3RSZXNwb25zZSwgbmV4dCkge1xuICB2YXIgc2tpcEJ1dHRvbjtcbiAgdmFyIHBsYXllciA9IHRoaXMucGxheWVyO1xuXG4gIGFkVW5pdC5vbignQWRTa2lwcGFibGVTdGF0ZUNoYW5nZScsIHVwZGF0ZVNraXBCdXR0b25TdGF0ZSk7XG5cbiAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsndmFzdC5hZEVuZCcsICd2YXN0LmFkc0NhbmNlbCddLCByZW1vdmVTa2lwQnV0dG9uKTtcblxuICBuZXh0KG51bGwsIGFkVW5pdCwgdmFzdFJlc3BvbnNlKTtcblxuICAvKioqIExvY2FsIGZ1bmN0aW9uICoqKi9cbiAgZnVuY3Rpb24gdXBkYXRlU2tpcEJ1dHRvblN0YXRlKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFNraXBwYWJsZVN0YXRlQ2hhbmdlJyk7XG4gICAgYWRVbml0LmdldEFkU2tpcHBhYmxlU3RhdGUoZnVuY3Rpb24gKGVycm9yLCBpc1NraXBwYWJsZSkge1xuICAgICAgaWYgKGlzU2tpcHBhYmxlKSB7XG4gICAgICAgIGlmICghc2tpcEJ1dHRvbikge1xuICAgICAgICAgIGFkZFNraXBCdXR0b24ocGxheWVyKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVtb3ZlU2tpcEJ1dHRvbihwbGF5ZXIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gYWRkU2tpcEJ1dHRvbihwbGF5ZXIpIHtcbiAgICBza2lwQnV0dG9uID0gY3JlYXRlU2tpcEJ1dHRvbihwbGF5ZXIpO1xuICAgIHBsYXllci5lbCgpLmFwcGVuZENoaWxkKHNraXBCdXR0b24pO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVtb3ZlU2tpcEJ1dHRvbigpIHtcbiAgICBkb20ucmVtb3ZlKHNraXBCdXR0b24pO1xuICAgIHNraXBCdXR0b24gPSBudWxsO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlU2tpcEJ1dHRvbigpIHtcbiAgICB2YXIgc2tpcEJ1dHRvbiA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgIGRvbS5hZGRDbGFzcyhza2lwQnV0dG9uLCBcInZhc3Qtc2tpcC1idXR0b25cIik7XG4gICAgZG9tLmFkZENsYXNzKHNraXBCdXR0b24sIFwiZW5hYmxlZFwiKTtcbiAgICBza2lwQnV0dG9uLmlubmVySFRNTCA9IFwiU2tpcCBhZFwiO1xuXG4gICAgc2tpcEJ1dHRvbi5vbmNsaWNrID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgIGFkVW5pdC5za2lwQWQodXRpbGl0aWVzLm5vb3ApOy8vV2Ugc2tpcCB0aGUgYWRVbml0XG5cbiAgICAgIC8vV2UgcHJldmVudCBldmVudCBwcm9wYWdhdGlvbiB0byBhdm9pZCBwcm9ibGVtcyB3aXRoIHRoZSBjbGlja1Rocm91Z2ggYW5kIHNvIG9uXG4gICAgICBpZiAod2luZG93LkV2ZW50LnByb3RvdHlwZS5zdG9wUHJvcGFnYXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gc2tpcEJ1dHRvbjtcbiAgfVxufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5fbGlua1BsYXllckNvbnRyb2xzID0gZnVuY3Rpb24gKGFkVW5pdCwgdmFzdFJlc3BvbnNlLCBuZXh0KSB7XG4gIHZhciB0aGF0ID0gdGhpcztcbiAgbGlua1ZvbHVtZUNvbnRyb2wodGhpcy5wbGF5ZXIsIGFkVW5pdCk7XG4gIGxpbmtGdWxsU2NyZWVuQ29udHJvbCh0aGlzLnBsYXllciwgYWRVbml0LCB0aGlzLlZJRVdfTU9ERSk7XG5cbiAgbmV4dChudWxsLCBhZFVuaXQsIHZhc3RSZXNwb25zZSk7XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBsaW5rVm9sdW1lQ29udHJvbChwbGF5ZXIsIGFkVW5pdCkge1xuICAgIHBsYXllci5vbigndm9sdW1lY2hhbmdlJywgdXBkYXRlQWRVbml0Vm9sdW1lKTtcbiAgICBhZFVuaXQub24oJ0FkVm9sdW1lQ2hhbmdlJywgdXBkYXRlUGxheWVyVm9sdW1lKTtcblxuICAgIHBsYXllci5vbmUoJ3ZwYWlkLmFkRW5kJywgZnVuY3Rpb24gKCkge1xuICAgICAgcGxheWVyLm9mZigndm9sdW1lY2hhbmdlJywgdXBkYXRlQWRVbml0Vm9sdW1lKTtcbiAgICB9KTtcblxuXG4gICAgLyoqKiBsb2NhbCBmdW5jdGlvbnMgKioqL1xuICAgIGZ1bmN0aW9uIHVwZGF0ZUFkVW5pdFZvbHVtZSgpIHtcbiAgICAgIHZhciB2b2wgPSBwbGF5ZXIubXV0ZWQoKSA/IDAgOiBwbGF5ZXIudm9sdW1lKCk7XG4gICAgICBhZFVuaXQuc2V0QWRWb2x1bWUodm9sLCBsb2dFcnJvcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdXBkYXRlUGxheWVyVm9sdW1lKCkge1xuICAgICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkVm9sdW1lQ2hhbmdlJyk7XG4gICAgICBhZFVuaXQuZ2V0QWRWb2x1bWUoZnVuY3Rpb24gKGVycm9yLCB2b2wpIHtcbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgbG9nRXJyb3IoZXJyb3IpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBsYXllci52b2x1bWUodm9sKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gbGlua0Z1bGxTY3JlZW5Db250cm9sKHBsYXllciwgYWRVbml0LCBWSUVXX01PREUpIHtcbiAgICB2YXIgdXBkYXRlVmlld1NpemUgPSByZXNpemVBZC5iaW5kKHRoYXQsIHBsYXllciwgYWRVbml0LCBWSUVXX01PREUpO1xuXG4gICAgcGxheWVyLm9uKCdmdWxsc2NyZWVuY2hhbmdlJywgdXBkYXRlVmlld1NpemUpO1xuXG4gICAgcGxheWVyLm9uZSgndnBhaWQuYWRFbmQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBwbGF5ZXIub2ZmKCdmdWxsc2NyZWVuY2hhbmdlJywgdXBkYXRlVmlld1NpemUpO1xuICAgIH0pO1xuICB9XG59O1xuXG5WUEFJREludGVncmF0b3IucHJvdG90eXBlLl9zdGFydEFkID0gZnVuY3Rpb24gKGFkVW5pdCwgdmFzdFJlc3BvbnNlLCBuZXh0KSB7XG4gIHZhciBwbGF5ZXIgPSB0aGlzLnBsYXllcjtcblxuICBhZFVuaXQuc3RhcnRBZChmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICBpZiAoIWVycm9yKSB7XG4gICAgICBwbGF5ZXIudHJpZ2dlcigndmFzdC5hZFN0YXJ0Jyk7XG4gICAgfVxuICAgIG5leHQoZXJyb3IsIGFkVW5pdCwgdmFzdFJlc3BvbnNlKTtcbiAgfSk7XG59O1xuXG5WUEFJREludGVncmF0b3IucHJvdG90eXBlLl9maW5pc2hQbGF5aW5nID0gZnVuY3Rpb24gKGFkVW5pdCwgdmFzdFJlc3BvbnNlLCBuZXh0KSB7XG4gIHZhciBwbGF5ZXIgPSB0aGlzLnBsYXllcjtcbiAgYWRVbml0Lm9uKCdBZFN0b3BwZWQnLCBmdW5jdGlvbiAoKSB7XG4gICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuQWRTdG9wcGVkJyk7XG4gICBmaW5pc2hQbGF5aW5nQWQobnVsbCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRFcnJvcicsIGZ1bmN0aW9uIChlcnJvcikge1xuICAgIHZhciBlcnJNc2cgPSBlcnJvcj8gZXJyb3IubWVzc2FnZSA6ICdvbiBWUEFJREludGVncmF0b3IsIGVycm9yIHdoaWxlIHdhaXRpbmcgZm9yIHRoZSBhZFVuaXQgdG8gZmluaXNoIHBsYXlpbmcnO1xuICAgIGZpbmlzaFBsYXlpbmdBZChuZXcgVkFTVEVycm9yKGVyck1zZykpO1xuICB9KTtcblxuICAvKioqIGxvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIGZpbmlzaFBsYXlpbmdBZChlcnJvcikge1xuICAgIG5leHQoZXJyb3IsIGFkVW5pdCwgdmFzdFJlc3BvbnNlKTtcbiAgfVxufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5fdHJhY2tFcnJvciA9IGZ1bmN0aW9uIHRyYWNrRXJyb3IocmVzcG9uc2UsIGVycm9yQ29kZSkge1xuICB2YXN0VXRpbC50cmFjayhyZXNwb25zZS5lcnJvclVSTE1hY3Jvcywge0VSUk9SQ09ERTogZXJyb3JDb2RlIHx8IDkwMX0pO1xufTtcblxuZnVuY3Rpb24gcmVzaXplQWQocGxheWVyLCBhZFVuaXQsIFZJRVdfTU9ERSkge1xuICB2YXIgdGVjaCA9IHBsYXllci5lbCgpLnF1ZXJ5U2VsZWN0b3IoJy52anMtdGVjaCcpO1xuICB2YXIgZGltZW5zaW9uID0gZG9tLmdldERpbWVuc2lvbih0ZWNoKTtcbiAgdmFyIE1PREUgPSBwbGF5ZXIuaXNGdWxsc2NyZWVuKCkgPyBWSUVXX01PREUuRlVMTFNDUkVFTiA6IFZJRVdfTU9ERS5OT1JNQUw7XG4gIGFkVW5pdC5yZXNpemVBZChkaW1lbnNpb24ud2lkdGgsIGRpbWVuc2lvbi5oZWlnaHQsIE1PREUsIGxvZ0Vycm9yKTtcbn1cblxuZnVuY3Rpb24gbG9nRXJyb3IoZXJyb3IpIHtcbiAgaWYgKGVycm9yICYmIGNvbnNvbGUgJiYgY29uc29sZS5sb2cpIHtcbiAgICBjb25zb2xlLmxvZygnRVJST1I6ICcgKyBlcnJvci5tZXNzYWdlLCBlcnJvcik7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBWUEFJREludGVncmF0b3I7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZG9tID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvZG9tJyk7XG5cbnZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG5lbGVtZW50LmNsYXNzTmFtZSA9ICd2anMtYWRzLWxhYmVsIHZqcy1jb250cm9sIHZqcy1sYWJlbC1oaWRkZW4nO1xuZWxlbWVudC5pbm5lckhUTUwgPSAnQWR2ZXJ0aXNlbWVudCc7XG5cbnZhciBBZHNMYWJlbEZhY3RvcnkgPSBmdW5jdGlvbihiYXNlQ29tcG9uZW50KSB7XG4gIHJldHVybiB7XG4gICAgLyoqIEBjb25zdHJ1Y3RvciAqL1xuICAgIGluaXQ6IGZ1bmN0aW9uIGluaXQocGxheWVyLCBvcHRpb25zKSB7XG4gICAgICBvcHRpb25zLmVsID0gZWxlbWVudDtcbiAgICAgIGJhc2VDb21wb25lbnQuY2FsbCh0aGlzLCBwbGF5ZXIsIG9wdGlvbnMpO1xuXG4gICAgICAvLyBXZSBhc3luY2hyb25vdXNseSByZXBvc2l0aW9uIHRoZSBhZHMgbGFiZWwgZWxlbWVudFxuICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjdXJyZW50VGltZUNvbXAgPSBwbGF5ZXIuY29udHJvbEJhciAmJiggcGxheWVyLmNvbnRyb2xCYXIuZ2V0Q2hpbGQoXCJ0aW1lckNvbnRyb2xzXCIpIHx8IHBsYXllci5jb250cm9sQmFyLmdldENoaWxkKFwiY3VycmVudFRpbWVEaXNwbGF5XCIpICk7XG4gICAgICAgIGlmKGN1cnJlbnRUaW1lQ29tcCkge1xuICAgICAgICAgIHBsYXllci5jb250cm9sQmFyLmVsKCkuaW5zZXJ0QmVmb3JlKGVsZW1lbnQsIGN1cnJlbnRUaW1lQ29tcC5lbCgpKTtcbiAgICAgICAgfVxuICAgICAgICBkb20ucmVtb3ZlQ2xhc3MoZWxlbWVudCwgJ3Zqcy1sYWJlbC1oaWRkZW4nKTtcbiAgICAgIH0sIDApO1xuICAgIH0sXG5cbiAgICBlbDogZnVuY3Rpb24gZ2V0RWxlbWVudCgpIHtcbiAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH1cbiAgfTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gQWRzTGFiZWxGYWN0b3J5OyIsIid1c2Ugc3RyaWN0JztcblxudmFyIGJhc2VWaWRlb0pzQ29tcG9uZW50ID0gdmlkZW9qcy5Db21wb25lbnQ7XG5cbnZhciBBZHNMYWJlbCA9IHJlcXVpcmUoJy4vYWRzLWxhYmVsJykoYmFzZVZpZGVvSnNDb21wb25lbnQpO1xuXG52aWRlb2pzLkFkc0xhYmVsID0gdmlkZW9qcy5Db21wb25lbnQuZXh0ZW5kKEFkc0xhYmVsKTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBUaGUgY29tcG9uZW50IHRoYXQgc2hvd3MgYSBibGFjayBzY3JlZW4gdW50aWwgdGhlIGFkcyBwbHVnaW4gaGFzIGRlY2lkZWQgaWYgaXQgY2FuIG9yIGl0IGNhbiBub3QgcGxheSB0aGUgYWQuXG4gKlxuICogTm90ZTogSW4gY2FzZSB5b3Ugd29uZGVyIHdoeSBpbnN0ZWFkIG9mIHRoaXMgYmxhY2sgcG9zdGVyIHdlIGRvbid0IGp1c3Qgc2hvdyB0aGUgc3Bpbm5lciBsb2FkZXIuXG4gKiAgICAgICBJT1MgZGV2aWNlcyBkbyBub3Qgd29yayB3ZWxsIHdpdGggYW5pbWF0aW9ucyBhbmQgdGhlIGJyb3dzZXIgY2hyYXNoZXMgZnJvbSB0aW1lIHRvIHRpbWUgVGhhdCBpcyB3aHkgd2UgY2hvc2UgdG9cbiAqICAgICAgIGhhdmUgYSBzZWNvbmRhcnkgYmxhY2sgcG9zdGVyLlxuICpcbiAqICAgICAgIEl0IGFsc28gbWFrZXMgaXQgbXVjaCBtb3JlIGVhc2llciBmb3IgdGhlIHVzZXJzIG9mIHRoZSBwbHVnaW4gc2luY2UgaXQgZG9lcyBub3QgY2hhbmdlIHRoZSBkZWZhdWx0IGJlaGF2aW91ciBvZiB0aGVcbiAqICAgICAgIHNwaW5uZXIgYW5kIHRoZSBwbGF5ZXIgd29ya3MgdGhlIHNhbWUgd2F5IHdpdGggYW5kIHdpdGhvdXQgdGhlIHBsdWdpbi5cbiAqXG4gKiBAcGFyYW0ge3Zqcy5QbGF5ZXJ8T2JqZWN0fSBwbGF5ZXJcbiAqIEBwYXJhbSB7T2JqZWN0PX0gb3B0aW9uc1xuICogQGNvbnN0cnVjdG9yXG4gKi9cbnZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG5cbnZhciBCbGFja1Bvc3RlckZhY3RvcnkgPSBmdW5jdGlvbihiYXNlQ29tcG9uZW50KSB7XG4gIHJldHVybiB7XG4gICAgLyoqIEBjb25zdHJ1Y3RvciAqL1xuICAgIGluaXQ6IGZ1bmN0aW9uIGluaXQocGxheWVyLCBvcHRpb25zKSB7XG4gICAgICBvcHRpb25zLmVsID0gZWxlbWVudDtcbiAgICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gJ3Zqcy1ibGFjay1wb3N0ZXInO1xuICAgICAgYmFzZUNvbXBvbmVudC5jYWxsKHRoaXMsIHBsYXllciwgb3B0aW9ucyk7XG5cbiAgICAgIHZhciBwb3N0ZXJJbWcgPSBwbGF5ZXIuZ2V0Q2hpbGQoJ3Bvc3RlckltYWdlJyk7XG5cbiAgICAgIC8vV2UgbmVlZCB0byBkbyBpdCBhc3luY2hyb25vdXNseSB0byBiZSBzdXJlIHRoYXQgdGhlIGJsYWNrIHBvc3RlciBlbCBpcyBvbiB0aGUgZG9tLlxuICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgaWYocG9zdGVySW1nICYmIHBsYXllciAmJiBwbGF5ZXIuZWwoKSkge1xuICAgICAgICAgIHBsYXllci5lbCgpLmluc2VydEJlZm9yZShlbGVtZW50LCBwb3N0ZXJJbWcuZWwoKSk7XG4gICAgICAgIH1cbiAgICAgIH0sIDApO1xuICAgIH0sXG4gICAgZWw6IGZ1bmN0aW9uIGdldEVsZW1lbnQoKSB7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEJsYWNrUG9zdGVyRmFjdG9yeTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBiYXNlVmlkZW9Kc0NvbXBvbmVudCA9IHZpZGVvanMuQ29tcG9uZW50O1xuXG52YXIgQmxhY2tQb3N0ZXIgPSByZXF1aXJlKCcuL2JsYWNrLXBvc3RlcicpKGJhc2VWaWRlb0pzQ29tcG9uZW50KTtcblxudmlkZW9qcy5CbGFja1Bvc3RlciA9IHZpZGVvanMuQ29tcG9uZW50LmV4dGVuZChCbGFja1Bvc3Rlcik7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBWQVNUQ2xpZW50ID0gcmVxdWlyZSgnLi4vYWRzL3Zhc3QvVkFTVENsaWVudCcpO1xudmFyIFZBU1RFcnJvciA9IHJlcXVpcmUoJy4uL2Fkcy92YXN0L1ZBU1RFcnJvcicpO1xudmFyIHZhc3RVdGlsID0gcmVxdWlyZSgnLi4vYWRzL3Zhc3QvdmFzdFV0aWwnKTtcblxudmFyIFZBU1RJbnRlZ3JhdG9yID0gcmVxdWlyZSgnLi4vYWRzL3Zhc3QvVkFTVEludGVncmF0b3InKTtcbnZhciBWUEFJREludGVncmF0b3IgPSByZXF1aXJlKCcuLi9hZHMvdnBhaWQvVlBBSURJbnRlZ3JhdG9yJyk7XG5cbnZhciBhc3luYyA9IHJlcXVpcmUoJy4uL3V0aWxzL2FzeW5jJyk7XG52YXIgZG9tID0gcmVxdWlyZSgnLi4vdXRpbHMvZG9tJyk7XG52YXIgcGxheWVyVXRpbHMgPSByZXF1aXJlKCcuLi91dGlscy9wbGF5ZXJVdGlscycpO1xudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBWQVNUUGx1Z2luKG9wdGlvbnMpIHtcbiAgdmFyIHNuYXBzaG90O1xuICB2YXIgcGxheWVyID0gdGhpcztcbiAgdmFyIHZhc3QgPSBuZXcgVkFTVENsaWVudCgpO1xuICB2YXIgYWRzQ2FuY2VsZWQgPSBmYWxzZTtcbiAgdmFyIGRlZmF1bHRPcHRzID0ge1xuICAgIC8vIG1heGltdW0gYW1vdW50IG9mIHRpbWUgaW4gbXMgdG8gd2FpdCB0byByZWNlaXZlIGBhZHNyZWFkeWAgZnJvbSB0aGUgYWRcbiAgICAvLyBpbXBsZW1lbnRhdGlvbiBhZnRlciBwbGF5IGhhcyBiZWVuIHJlcXVlc3RlZC4gQWQgaW1wbGVtZW50YXRpb25zIGFyZVxuICAgIC8vIGV4cGVjdGVkIHRvIGxvYWQgYW55IGR5bmFtaWMgbGlicmFyaWVzIGFuZCBtYWtlIGFueSByZXF1ZXN0cyB0byBkZXRlcm1pbmVcbiAgICAvLyBhZCBwb2xpY2llcyBmb3IgYSB2aWRlbyBkdXJpbmcgdGhpcyB0aW1lLlxuICAgIHRpbWVvdXQ6IDUwMCxcblxuICAgIC8vVE9ETzpmaW5pc2ggdGhpcyBJT1MgRklYXG4gICAgLy9XaGVuZXZlciB5b3UgcGxheSBhbiBhZGQgb24gSU9TLCB0aGUgbmF0aXZlIHBsYXllciBraWNrcyBpbiBhbmQgd2UgbG9vc2UgY29udHJvbCBvZiBpdC4gT24gdmVyeSBoZWF2eSBwYWdlcyB0aGUgJ3BsYXknIGV2ZW50XG4gICAgLy8gTWF5IG9jY3VyIGFmdGVyIHRoZSB2aWRlbyBjb250ZW50IGhhcyBhbHJlYWR5IHN0YXJ0ZWQuIFRoaXMgaXMgd3JvbmcgaWYgeW91IHdhbnQgdG8gcGxheSBhIHByZXJvbGwgYWQgdGhhdCBuZWVkcyB0byBoYXBwZW4gYmVmb3JlIHRoZSB1c2VyXG4gICAgLy8gc3RhcnRzIHdhdGNoaW5nIHRoZSBjb250ZW50LiBUbyBwcmV2ZW50IHRoaXMgdXNlY1xuICAgIGlvc1ByZXJvbGxDYW5jZWxUaW1lb3V0OiAyMDAwLFxuXG4gICAgLy8gbWF4aW11biBhbW91bnQgb2YgdGltZSBmb3IgdGhlIGFkIHRvIGFjdHVhbGx5IHN0YXJ0IHBsYXlpbmcuIElmIHRoaXMgdGltZW91dCBnZXRzXG4gICAgLy8gdHJpZ2dlcmVkIHRoZSBhZHMgd2lsbCBiZSBjYW5jZWxsZWRcbiAgICBhZENhbmNlbFRpbWVvdXQ6IDMwMDAsXG5cbiAgICAvLyBCb29sZWFuIGZsYWcgdGhhdCBjb25maWd1cmVzIHRoZSBwbGF5ZXIgdG8gcGxheSBhIG5ldyBhZCBiZWZvcmUgdGhlIHVzZXIgc2VlcyB0aGUgdmlkZW8gYWdhaW5cbiAgICAvLyB0aGUgY3VycmVudCB2aWRlb1xuICAgIHBsYXlBZEFsd2F5czogZmFsc2UsXG5cbiAgICAvLyBGbGFnIHRvIGVuYWJsZSBvciBkaXNhYmxlIHRoZSBhZHMgYnkgZGVmYXVsdC5cbiAgICBhZHNFbmFibGVkOiB0cnVlLFxuXG4gICAgLy8gQm9vbGVhbiBmbGFnIHRvIGVuYWJsZSBvciBkaXNhYmxlIHRoZSByZXNpemUgd2l0aCB3aW5kb3cucmVzaXplIG9yIG9yaWVudGF0aW9uY2hhbmdlXG4gICAgYXV0b1Jlc2l6ZTogdHJ1ZSxcblxuICAgIC8vIFBhdGggdG8gdGhlIFZQQUlEIGZsYXNoIGFkJ3MgbG9hZGVyXG4gICAgdnBhaWRGbGFzaExvYWRlclBhdGg6ICcvVlBBSURGbGFzaC5zd2YnXG4gIH07XG5cbiAgdmFyIHNldHRpbmdzID0gdXRpbGl0aWVzLmV4dGVuZCh7fSwgZGVmYXVsdE9wdHMsIG9wdGlvbnMgfHwge30pO1xuXG4gIGlmKHV0aWxpdGllcy5pc1VuZGVmaW5lZChzZXR0aW5ncy5hZFRhZ1VybCkgJiYgdXRpbGl0aWVzLmlzRGVmaW5lZChzZXR0aW5ncy51cmwpKXtcbiAgICBzZXR0aW5ncy5hZFRhZ1VybCA9IHNldHRpbmdzLnVybDtcbiAgfVxuXG4gIGlmICh1dGlsaXRpZXMuaXNTdHJpbmcoc2V0dGluZ3MuYWRUYWdVcmwpKSB7XG4gICAgc2V0dGluZ3MuYWRUYWdVcmwgPSB1dGlsaXRpZXMuZWNob0ZuKHNldHRpbmdzLmFkVGFnVXJsKTtcbiAgfVxuXG4gIGlmICh1dGlsaXRpZXMuaXNEZWZpbmVkKHNldHRpbmdzLmFkVGFnWE1MKSAmJiAhdXRpbGl0aWVzLmlzRnVuY3Rpb24oc2V0dGluZ3MuYWRUYWdYTUwpKSB7XG4gICAgcmV0dXJuIHRyYWNrQWRFcnJvcihuZXcgVkFTVEVycm9yKCdvbiBWaWRlb0pTIFZBU1QgcGx1Z2luLCB0aGUgcGFzc2VkIGFkVGFnWE1MIG9wdGlvbiBkb2VzIG5vdCBjb250YWluIGEgZnVuY3Rpb24nKSk7XG4gIH1cblxuICBpZiAoIXV0aWxpdGllcy5pc0RlZmluZWQoc2V0dGluZ3MuYWRUYWdVcmwpICYmICF1dGlsaXRpZXMuaXNGdW5jdGlvbihzZXR0aW5ncy5hZFRhZ1hNTCkpIHtcbiAgICByZXR1cm4gdHJhY2tBZEVycm9yKG5ldyBWQVNURXJyb3IoJ29uIFZpZGVvSlMgVkFTVCBwbHVnaW4sIG1pc3NpbmcgYWRUYWdVcmwgb24gb3B0aW9ucyBvYmplY3QnKSk7XG4gIH1cblxuICB2YXN0VXRpbC5ydW5GbGFzaFN1cHBvcnRDaGVjayhzZXR0aW5ncy52cGFpZEZsYXNoTG9hZGVyUGF0aCk7Ly8gTmVjZXNzYXJ5IHN0ZXAgZm9yIFZQQUlERkxBU0hDbGllbnQgdG8gd29yay5cblxuICBwbGF5ZXJVdGlscy5wcmVwYXJlRm9yQWRzKHBsYXllcik7XG5cbiAgaWYgKHNldHRpbmdzLnBsYXlBZEFsd2F5cykge1xuICAgIC8vIE5vIG1hdHRlciB3aGF0IGhhcHBlbnMgd2UgcGxheSBhIG5ldyBhZCBiZWZvcmUgdGhlIHVzZXIgc2VlcyB0aGUgdmlkZW8gYWdhaW4uXG4gICAgcGxheWVyLm9uKCd2YXN0LmNvbnRlbnRFbmQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcGxheWVyLnRyaWdnZXIoJ3Zhc3QucmVzZXQnKTtcbiAgICAgIH0sIDApO1xuICAgIH0pO1xuICB9XG5cbiAgcGxheWVyLm9uKCd2YXN0LmZpcnN0UGxheScsIHRyeVRvUGxheVByZXJvbGxBZCk7XG5cbiAgcGxheWVyLm9uKCd2YXN0LnJlc2V0JywgZnVuY3Rpb24gKCkge1xuICAgIC8vSWYgd2UgYXJlIHJlc2V0aW5nIHRoZSBwbHVnaW4sIHdlIGRvbid0IHdhbnQgdG8gcmVzdG9yZSB0aGUgY29udGVudFxuICAgIHNuYXBzaG90ID0gbnVsbDtcbiAgICBjYW5jZWxBZHMoKTtcbiAgfSk7XG5cbiAgcGxheWVyLnZhc3QgPSB7XG4gICAgaXNFbmFibGVkOiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gc2V0dGluZ3MuYWRzRW5hYmxlZDtcbiAgICB9LFxuXG4gICAgZW5hYmxlOiBmdW5jdGlvbiAoKSB7XG4gICAgICBzZXR0aW5ncy5hZHNFbmFibGVkID0gdHJ1ZTtcbiAgICB9LFxuXG4gICAgZGlzYWJsZTogZnVuY3Rpb24gKCkge1xuICAgICAgc2V0dGluZ3MuYWRzRW5hYmxlZCA9IGZhbHNlO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gcGxheWVyLnZhc3Q7XG5cbiAgLyoqKiogTG9jYWwgZnVuY3Rpb25zICoqKiovXG4gIGZ1bmN0aW9uIHRyeVRvUGxheVByZXJvbGxBZCgpIHtcbiAgICAvL1dlIHJlbW92ZSB0aGUgcG9zdGVyIHRvIHByZXZlbnQgZmxpY2tlcmluZyB3aGVuZXZlciB0aGUgY29udGVudCBzdGFydHMgcGxheWluZ1xuICAgIHBsYXllclV0aWxzLnJlbW92ZU5hdGl2ZVBvc3RlcihwbGF5ZXIpO1xuXG4gICAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsndmFzdC5hZHNDYW5jZWwnLCAndmFzdC5hZEVuZCddLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZW1vdmVBZFVuaXQoKTtcbiAgICAgIHJlc3RvcmVWaWRlb0NvbnRlbnQoKTtcbiAgICB9KTtcblxuICAgIGFzeW5jLndhdGVyZmFsbChbXG4gICAgICBjaGVja0Fkc0VuYWJsZWQsXG4gICAgICBwcmVwYXJlUGxheWVyRm9yQWQsXG4gICAgICBzdGFydEFkQ2FuY2VsVGltZW91dCxcbiAgICAgIHBsYXlQcmVyb2xsQWRcbiAgICBdLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3BvbnNlKSB7XG4gICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgdHJhY2tBZEVycm9yKGVycm9yLCByZXNwb25zZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwbGF5ZXIudHJpZ2dlcigndmFzdC5hZEVuZCcpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqL1xuXG4gICAgZnVuY3Rpb24gcmVtb3ZlQWRVbml0KCkge1xuICAgICAgaWYgKHBsYXllci52YXN0ICYmIHBsYXllci52YXN0LmFkVW5pdCkge1xuICAgICAgICBwbGF5ZXIudmFzdC5hZFVuaXQgPSBudWxsOyAvL1dlIHJlbW92ZSB0aGUgYWRVbml0XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVzdG9yZVZpZGVvQ29udGVudCgpIHtcbiAgICAgIHNldHVwQ29udGVudEV2ZW50cygpO1xuICAgICAgaWYgKHNuYXBzaG90KSB7XG4gICAgICAgIHBsYXllclV0aWxzLnJlc3RvcmVQbGF5ZXJTbmFwc2hvdChwbGF5ZXIsIHNuYXBzaG90KTtcbiAgICAgICAgc25hcHNob3QgPSBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNldHVwQ29udGVudEV2ZW50cygpIHtcbiAgICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3BsYXlpbmcnLCAndmFzdC5yZXNldCcsICd2YXN0LmZpcnN0UGxheSddLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIGlmIChldnQudHlwZSAhPT0gJ3BsYXlpbmcnKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcGxheWVyLnRyaWdnZXIoJ3Zhc3QuY29udGVudFN0YXJ0Jyk7XG5cbiAgICAgICAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsnZW5kZWQnLCAndmFzdC5yZXNldCcsICd2YXN0LmZpcnN0UGxheSddLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgICAgaWYgKGV2dC50eXBlID09PSAnZW5kZWQnKSB7XG4gICAgICAgICAgICBwbGF5ZXIudHJpZ2dlcigndmFzdC5jb250ZW50RW5kJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNoZWNrQWRzRW5hYmxlZChuZXh0KSB7XG4gICAgICBpZiAoc2V0dGluZ3MuYWRzRW5hYmxlZCkge1xuICAgICAgICByZXR1cm4gbmV4dChudWxsKTtcbiAgICAgIH1cbiAgICAgIG5leHQobmV3IFZBU1RFcnJvcignQWRzIGFyZSBub3QgZW5hYmxlZCcpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmVwYXJlUGxheWVyRm9yQWQobmV4dCkge1xuICAgICAgaWYgKGNhblBsYXlQcmVyb2xsQWQoKSkge1xuICAgICAgICBzbmFwc2hvdCA9IHBsYXllclV0aWxzLmdldFBsYXllclNuYXBzaG90KHBsYXllcik7XG4gICAgICAgIHBsYXllci5wYXVzZSgpO1xuICAgICAgICBhZGRTcGlubmVySWNvbigpO1xuXG4gICAgICAgIGlmKHBsYXllci5wYXVzZWQoKSkge1xuICAgICAgICAgIG5leHQobnVsbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsncGxheWluZyddLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHBsYXllci5wYXVzZSgpO1xuICAgICAgICAgICAgbmV4dChudWxsKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV4dChuZXcgVkFTVEVycm9yKCd2aWRlbyBjb250ZW50IGhhcyBiZWVuIHBsYXlpbmcgYmVmb3JlIHByZXJvbGwgYWQnKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FuUGxheVByZXJvbGxBZCgpIHtcbiAgICAgIHJldHVybiAhdXRpbGl0aWVzLmlzSVBob25lKCkgfHwgcGxheWVyLmN1cnJlbnRUaW1lKCkgPD0gc2V0dGluZ3MuaW9zUHJlcm9sbENhbmNlbFRpbWVvdXQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc3RhcnRBZENhbmNlbFRpbWVvdXQobmV4dCkge1xuICAgICAgdmFyIGFkQ2FuY2VsVGltZW91dElkO1xuICAgICAgYWRzQ2FuY2VsZWQgPSBmYWxzZTtcblxuICAgICAgYWRDYW5jZWxUaW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdHJhY2tBZEVycm9yKG5ldyBWQVNURXJyb3IoJ3RpbWVvdXQgd2hpbGUgd2FpdGluZyBmb3IgdGhlIHZpZGVvIHRvIHN0YXJ0IHBsYXlpbmcnLCA0MDIpKTtcbiAgICAgIH0sIHNldHRpbmdzLmFkQ2FuY2VsVGltZW91dCk7XG5cbiAgICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3Zhc3QuYWRTdGFydCcsICd2YXN0LmFkc0NhbmNlbCddLCBjbGVhckFkQ2FuY2VsVGltZW91dCk7XG5cbiAgICAgIC8qKiogbG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgICAgIGZ1bmN0aW9uIGNsZWFyQWRDYW5jZWxUaW1lb3V0KCkge1xuICAgICAgICBpZiAoYWRDYW5jZWxUaW1lb3V0SWQpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQoYWRDYW5jZWxUaW1lb3V0SWQpO1xuICAgICAgICAgIGFkQ2FuY2VsVGltZW91dElkID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBuZXh0KG51bGwpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkZFNwaW5uZXJJY29uKCkge1xuICAgICAgZG9tLmFkZENsYXNzKHBsYXllci5lbCgpLCAndmpzLXZhc3QtYWQtbG9hZGluZycpO1xuICAgICAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsndmFzdC5hZFN0YXJ0JywgJ3Zhc3QuYWRzQ2FuY2VsJ10sIHJlbW92ZVNwaW5uZXJJY29uKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZW1vdmVTcGlubmVySWNvbigpIHtcbiAgICAgIC8vSU1QT1JUQU5UIE5PVEU6IFdlIHJlbW92ZSB0aGUgc3Bpbm5lckljb24gYXN5bmNocm9ub3VzbHkgdG8gZ2l2ZSB0aW1lIHRvIHRoZSBicm93c2VyIHRvIHN0YXJ0IHRoZSB2aWRlby5cbiAgICAgIC8vIElmIHdlIHJlbW92ZSBpdCBzeW5jaHJvbm91c2x5IHdlIHNlZSBhIGZsYXNoIG9mIHRoZSBjb250ZW50IHZpZGVvIGJlZm9yZSB0aGUgYWQgc3RhcnRzIHBsYXlpbmcuXG4gICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZG9tLnJlbW92ZUNsYXNzKHBsYXllci5lbCgpLCAndmpzLXZhc3QtYWQtbG9hZGluZycpO1xuICAgICAgfSwgMTAwKTtcbiAgICB9XG5cbiAgfVxuXG4gIGZ1bmN0aW9uIGNhbmNlbEFkcygpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcigndmFzdC5hZHNDYW5jZWwnKTtcbiAgICBhZHNDYW5jZWxlZCA9IHRydWU7XG4gIH1cblxuICBmdW5jdGlvbiBwbGF5UHJlcm9sbEFkKGNhbGxiYWNrKSB7XG4gICAgYXN5bmMud2F0ZXJmYWxsKFtcbiAgICAgIGdldFZhc3RSZXNwb25zZSxcbiAgICAgIHBsYXlBZFxuICAgIF0sIGNhbGxiYWNrKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldFZhc3RSZXNwb25zZShjYWxsYmFjaykge1xuICAgIHZhc3QuZ2V0VkFTVFJlc3BvbnNlKHNldHRpbmdzLmFkVGFnVXJsID8gc2V0dGluZ3MuYWRUYWdVcmwoKSA6IHNldHRpbmdzLmFkVGFnWE1MLCBjYWxsYmFjayk7XG4gIH1cblxuICBmdW5jdGlvbiBwbGF5QWQodmFzdFJlc3BvbnNlLCBjYWxsYmFjaykge1xuICAgIC8vVE9ETzogRmluZCBhIGJldHRlciB3YXkgdG8gc3RvcCB0aGUgcGxheS4gVGhlICdwbGF5UHJlcm9sbFdhdGVyZmFsbCcgZW5kcyBpbiBhbiBpbmNvbnNpc3RlbnQgc2l0dWF0aW9uXG4gICAgLy9JZiB0aGUgc3RhdGUgaXMgbm90ICdwcmVyb2xsPycgaXQgbWVhbnMgdGhlIGFkcyB3ZXJlIGNhbmNlbGVkIHRoZXJlZm9yZSwgd2UgYnJlYWsgdGhlIHdhdGVyZmFsbFxuICAgIGlmIChhZHNDYW5jZWxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBhZEludGVncmF0b3IgPSBpc1ZQQUlEKHZhc3RSZXNwb25zZSkgPyBuZXcgVlBBSURJbnRlZ3JhdG9yKHBsYXllciwgc2V0dGluZ3MpIDogbmV3IFZBU1RJbnRlZ3JhdG9yKHBsYXllcik7XG4gICAgdmFyIGFkRmluaXNoZWQgPSBmYWxzZTtcblxuICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3Zhc3QuYWRTdGFydCcsICd2YXN0LmFkc0NhbmNlbCddLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICBpZiAoZXZ0LnR5cGUgPT09ICd2YXN0LmFkU3RhcnQnKSB7XG4gICAgICAgIGFkZEFkc0xhYmVsKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWyd2YXN0LmFkRW5kJywgJ3Zhc3QuYWRzQ2FuY2VsJ10sIHJlbW92ZUFkc0xhYmVsKTtcblxuICAgIGlmICh1dGlsaXRpZXMuaXNJRGV2aWNlKCkpIHtcbiAgICAgIHByZXZlbnRNYW51YWxQcm9ncmVzcygpO1xuICAgIH1cblxuICAgIHBsYXllci52YXN0LnZhc3RSZXNwb25zZSA9IHZhc3RSZXNwb25zZTtcbiAgICBwbGF5ZXIudmFzdC5hZFVuaXQgPSBhZEludGVncmF0b3IucGxheUFkKHZhc3RSZXNwb25zZSwgY2FsbGJhY2spO1xuXG4gICAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqKi9cbiAgICBmdW5jdGlvbiBhZGRBZHNMYWJlbCgpIHtcbiAgICAgIGlmIChhZEZpbmlzaGVkIHx8IHBsYXllci5jb250cm9sQmFyLmdldENoaWxkKCdBZHNMYWJlbCcpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgcGxheWVyLmNvbnRyb2xCYXIuYWRkQ2hpbGQoJ0Fkc0xhYmVsJyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVtb3ZlQWRzTGFiZWwoKSB7XG4gICAgICBwbGF5ZXIuY29udHJvbEJhci5yZW1vdmVDaGlsZCgnQWRzTGFiZWwnKTtcbiAgICAgIGFkRmluaXNoZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByZXZlbnRNYW51YWxQcm9ncmVzcygpIHtcbiAgICAgIC8vSU9TIHZpZGVvIGNsb2NrIGlzIHZlcnkgdW5yZWxpYWJsZSBhbmQgd2UgbmVlZCBhIDMgc2Vjb25kcyB0aHJlc2hvbGQgdG8gZW5zdXJlIHRoYXQgdGhlIHVzZXIgZm9yd2FyZGVkL3Jld291bmQgdGhlIGFkXG4gICAgICB2YXIgUFJPR1JFU1NfVEhSRVNIT0xEID0gMztcbiAgICAgIHZhciBwcmV2aW91c1RpbWUgPSAwO1xuICAgICAgdmFyIHNraXBhZF9hdHRlbXB0cyA9IDA7XG5cbiAgICAgIHBsYXllci5vbigndGltZXVwZGF0ZScsIHByZXZlbnRBZFNlZWspO1xuICAgICAgcGxheWVyLm9uKCdlbmRlZCcsIHByZXZlbnRBZFNraXApO1xuXG4gICAgICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWyd2YXN0LmFkRW5kJywgJ3Zhc3QuYWRzQ2FuY2VsJywgJ3Zhc3QuYWRFcnJvciddLCBzdG9wUHJldmVudE1hbnVhbFByb2dyZXNzKTtcblxuICAgICAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqL1xuICAgICAgZnVuY3Rpb24gcHJldmVudEFkU2tpcCgpIHtcbiAgICAgICAgLy8gSWdub3JlIGVuZGVkIGV2ZW50IGlmIHRoZSBBZCB0aW1lIHdhcyBub3QgJ25lYXInIHRoZSBlbmRcbiAgICAgICAgLy8gYW5kIHJldmVydCB0aW1lIHRvIHRoZSBwcmV2aW91cyAndmFsaWQnIHRpbWVcbiAgICAgICAgaWYgKChwbGF5ZXIuZHVyYXRpb24oKSAtIHByZXZpb3VzVGltZSkgPiBQUk9HUkVTU19USFJFU0hPTEQpIHtcbiAgICAgICAgICBwbGF5ZXIucGF1c2UodHJ1ZSk7IC8vIHRoaXMgcmVkdWNlIHRoZSB2aWRlbyBqaXR0ZXIgaWYgdGhlIElPUyBza2lwIGJ1dHRvbiBpcyBwcmVzc2VkXG4gICAgICAgICAgcGxheWVyLnBsYXkodHJ1ZSk7IC8vIHdlIG5lZWQgdG8gdHJpZ2dlciB0aGUgcGxheSB0byBwdXQgdGhlIHZpZGVvIGVsZW1lbnQgYmFjayBpbiBhIHZhbGlkIHN0YXRlXG4gICAgICAgICAgcGxheWVyLmN1cnJlbnRUaW1lKHByZXZpb3VzVGltZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gcHJldmVudEFkU2VlaygpIHtcbiAgICAgICAgdmFyIGN1cnJlbnRUaW1lID0gcGxheWVyLmN1cnJlbnRUaW1lKCk7XG4gICAgICAgIHZhciBwcm9ncmVzc0RlbHRhID0gTWF0aC5hYnMoY3VycmVudFRpbWUgLSBwcmV2aW91c1RpbWUpO1xuICAgICAgICBpZiAocHJvZ3Jlc3NEZWx0YSA+IFBST0dSRVNTX1RIUkVTSE9MRCkge1xuICAgICAgICAgIHNraXBhZF9hdHRlbXB0cyArPSAxO1xuICAgICAgICAgIGlmIChza2lwYWRfYXR0ZW1wdHMgPj0gMikge1xuICAgICAgICAgICAgcGxheWVyLnBhdXNlKHRydWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBwbGF5ZXIuY3VycmVudFRpbWUocHJldmlvdXNUaW1lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcmV2aW91c1RpbWUgPSBjdXJyZW50VGltZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBzdG9wUHJldmVudE1hbnVhbFByb2dyZXNzKCkge1xuICAgICAgICBwbGF5ZXIub2ZmKCd0aW1ldXBkYXRlJywgcHJldmVudEFkU2Vlayk7XG4gICAgICAgIHBsYXllci5vZmYoJ2VuZGVkJywgcHJldmVudEFkU2tpcCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdHJhY2tBZEVycm9yKGVycm9yLCB2YXN0UmVzcG9uc2UpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcih7dHlwZTogJ3Zhc3QuYWRFcnJvcicsIGVycm9yOiBlcnJvcn0pO1xuICAgIGNhbmNlbEFkcygpO1xuICAgIGlmIChjb25zb2xlICYmIGNvbnNvbGUubG9nKSB7XG4gICAgICBjb25zb2xlLmxvZygnQUQgRVJST1I6JywgZXJyb3IubWVzc2FnZSwgZXJyb3IsIHZhc3RSZXNwb25zZSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaXNWUEFJRCh2YXN0UmVzcG9uc2UpIHtcbiAgICB2YXIgaSwgbGVuO1xuICAgIHZhciBtZWRpYUZpbGVzID0gdmFzdFJlc3BvbnNlLm1lZGlhRmlsZXM7XG4gICAgZm9yIChpID0gMCwgbGVuID0gbWVkaWFGaWxlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgaWYgKHZhc3RVdGlsLmlzVlBBSUQobWVkaWFGaWxlc1tpXSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcbiIsIi8vU21hbGwgc3Vic2V0IG9mIGFzeW5jXG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxudmFyIGFzeW5jID0ge307XG5cbmFzeW5jLnNldEltbWVkaWF0ZSA9IGZ1bmN0aW9uIChmbikge1xuICBzZXRUaW1lb3V0KGZuLCAwKTtcbn07XG5cbmFzeW5jLml0ZXJhdG9yID0gZnVuY3Rpb24gKHRhc2tzKSB7XG4gIHZhciBtYWtlQ2FsbGJhY2sgPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICB2YXIgZm4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAodGFza3MubGVuZ3RoKSB7XG4gICAgICAgIHRhc2tzW2luZGV4XS5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZuLm5leHQoKTtcbiAgICB9O1xuICAgIGZuLm5leHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gKGluZGV4IDwgdGFza3MubGVuZ3RoIC0gMSkgPyBtYWtlQ2FsbGJhY2soaW5kZXggKyAxKSA6IG51bGw7XG4gICAgfTtcbiAgICByZXR1cm4gZm47XG4gIH07XG4gIHJldHVybiBtYWtlQ2FsbGJhY2soMCk7XG59O1xuXG5cbmFzeW5jLndhdGVyZmFsbCA9IGZ1bmN0aW9uICh0YXNrcywgY2FsbGJhY2spIHtcbiAgY2FsbGJhY2sgPSBjYWxsYmFjayB8fCBmdW5jdGlvbiAoKSB7IH07XG4gIGlmICghdXRpbGl0aWVzLmlzQXJyYXkodGFza3MpKSB7XG4gICAgdmFyIGVyciA9IG5ldyBFcnJvcignRmlyc3QgYXJndW1lbnQgdG8gd2F0ZXJmYWxsIG11c3QgYmUgYW4gYXJyYXkgb2YgZnVuY3Rpb25zJyk7XG4gICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gIH1cbiAgaWYgKCF0YXNrcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgfVxuICB2YXIgd3JhcEl0ZXJhdG9yID0gZnVuY3Rpb24gKGl0ZXJhdG9yKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgY2FsbGJhY2suYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICAgICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICB2YXIgbmV4dCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgaWYgKG5leHQpIHtcbiAgICAgICAgICBhcmdzLnB1c2god3JhcEl0ZXJhdG9yKG5leHQpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBhcmdzLnB1c2goY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGFzeW5jLnNldEltbWVkaWF0ZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaXRlcmF0b3IuYXBwbHkobnVsbCwgYXJncyk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH07XG4gIH07XG4gIHdyYXBJdGVyYXRvcihhc3luYy5pdGVyYXRvcih0YXNrcykpKCk7XG59O1xuXG5hc3luYy53aGVuID0gZnVuY3Rpb24gKGNvbmRpdGlvbiwgY2FsbGJhY2spIHtcbiAgaWYgKCF1dGlsaXRpZXMuaXNGdW5jdGlvbihjYWxsYmFjaykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJhc3luYy53aGVuIGVycm9yOiBtaXNzaW5nIGNhbGxiYWNrIGFyZ3VtZW50XCIpO1xuICB9XG5cbiAgdmFyIGlzQWxsb3dlZCA9IHV0aWxpdGllcy5pc0Z1bmN0aW9uKGNvbmRpdGlvbikgPyBjb25kaXRpb24gOiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICEhY29uZGl0aW9uO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGFyZ3MgPSB1dGlsaXRpZXMuYXJyYXlMaWtlT2JqVG9BcnJheShhcmd1bWVudHMpO1xuICAgIHZhciBuZXh0ID0gYXJncy5wb3AoKTtcblxuICAgIGlmIChpc0FsbG93ZWQuYXBwbHkobnVsbCwgYXJncykpIHtcbiAgICAgIHJldHVybiBjYWxsYmFjay5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIGFyZ3MudW5zaGlmdChudWxsKTtcbiAgICByZXR1cm4gbmV4dC5hcHBseShudWxsLCBhcmdzKTtcbiAgfTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gYXN5bmM7XG5cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4vdXRpbGl0eUZ1bmN0aW9ucycpO1xuXG52YXIgZG9tID0ge307XG5cbmRvbS5pc1Zpc2libGUgPSBmdW5jdGlvbiBpc1Zpc2libGUoZWwpIHtcbiAgdmFyIHN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWwpO1xuICByZXR1cm4gc3R5bGUudmlzaWJpbGl0eSAhPT0gJ2hpZGRlbic7XG59O1xuXG5kb20uaXNIaWRkZW4gPSBmdW5jdGlvbiBpc0hpZGRlbihlbCkge1xuICB2YXIgc3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbCk7XG4gIHJldHVybiBzdHlsZS5kaXNwbGF5ID09PSAnbm9uZSc7XG59O1xuXG5kb20uaXNTaG93biA9IGZ1bmN0aW9uIGlzU2hvd24oZWwpIHtcbiAgcmV0dXJuICFkb20uaXNIaWRkZW4oZWwpO1xufTtcblxuZG9tLmhpZGUgPSBmdW5jdGlvbiBoaWRlKGVsKSB7XG4gIGVsLl9fcHJldl9zdHlsZV9kaXNwbGF5XyA9IGVsLnN0eWxlLmRpc3BsYXk7XG4gIGVsLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG59O1xuXG5kb20uc2hvdyA9IGZ1bmN0aW9uIHNob3coZWwpIHtcbiAgaWYgKGRvbS5pc0hpZGRlbihlbCkpIHtcbiAgICBlbC5zdHlsZS5kaXNwbGF5ID0gZWwuX19wcmV2X3N0eWxlX2Rpc3BsYXlfO1xuICB9XG4gIGVsLl9fcHJldl9zdHlsZV9kaXNwbGF5XyA9IHVuZGVmaW5lZDtcbn07XG5cbmRvbS5oYXNDbGFzcyA9IGZ1bmN0aW9uIGhhc0NsYXNzKGVsLCBjc3NDbGFzcykge1xuICB2YXIgY2xhc3NlcywgaSwgbGVuO1xuXG4gIGlmICh1dGlsaXRpZXMuaXNOb3RFbXB0eVN0cmluZyhjc3NDbGFzcykpIHtcbiAgICBpZiAoZWwuY2xhc3NMaXN0KSB7XG4gICAgICByZXR1cm4gZWwuY2xhc3NMaXN0LmNvbnRhaW5zKGNzc0NsYXNzKTtcbiAgICB9XG5cbiAgICBjbGFzc2VzID0gdXRpbGl0aWVzLmlzU3RyaW5nKGVsLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSkgPyBlbC5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykuc3BsaXQoL1xccysvKSA6IFtdO1xuICAgIGNzc0NsYXNzID0gKGNzc0NsYXNzIHx8ICcnKTtcblxuICAgIGZvciAoaSA9IDAsIGxlbiA9IGNsYXNzZXMubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgIGlmIChjbGFzc2VzW2ldID09PSBjc3NDbGFzcykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuZG9tLmFkZENsYXNzID0gZnVuY3Rpb24gKGVsLCBjc3NDbGFzcykge1xuICB2YXIgY2xhc3NlcztcblxuICBpZiAodXRpbGl0aWVzLmlzTm90RW1wdHlTdHJpbmcoY3NzQ2xhc3MpKSB7XG4gICAgaWYgKGVsLmNsYXNzTGlzdCkge1xuICAgICAgcmV0dXJuIGVsLmNsYXNzTGlzdC5hZGQoY3NzQ2xhc3MpO1xuICAgIH1cblxuICAgIGNsYXNzZXMgPSB1dGlsaXRpZXMuaXNTdHJpbmcoZWwuZ2V0QXR0cmlidXRlKCdjbGFzcycpKSA/IGVsLmdldEF0dHJpYnV0ZSgnY2xhc3MnKS5zcGxpdCgvXFxzKy8pIDogW107XG4gICAgaWYgKHV0aWxpdGllcy5pc1N0cmluZyhjc3NDbGFzcykgJiYgdXRpbGl0aWVzLmlzTm90RW1wdHlTdHJpbmcoY3NzQ2xhc3MucmVwbGFjZSgvXFxzKy8sICcnKSkpIHtcbiAgICAgIGNsYXNzZXMucHVzaChjc3NDbGFzcyk7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgY2xhc3Nlcy5qb2luKCcgJykpO1xuICAgIH1cbiAgfVxufTtcblxuZG9tLnJlbW92ZUNsYXNzID0gZnVuY3Rpb24gKGVsLCBjc3NDbGFzcykge1xuICB2YXIgY2xhc3NlcztcblxuICBpZiAodXRpbGl0aWVzLmlzTm90RW1wdHlTdHJpbmcoY3NzQ2xhc3MpKSB7XG4gICAgaWYgKGVsLmNsYXNzTGlzdCkge1xuICAgICAgcmV0dXJuIGVsLmNsYXNzTGlzdC5yZW1vdmUoY3NzQ2xhc3MpO1xuICAgIH1cblxuICAgIGNsYXNzZXMgPSB1dGlsaXRpZXMuaXNTdHJpbmcoZWwuZ2V0QXR0cmlidXRlKCdjbGFzcycpKSA/IGVsLmdldEF0dHJpYnV0ZSgnY2xhc3MnKS5zcGxpdCgvXFxzKy8pIDogW107XG4gICAgdmFyIG5ld0NsYXNzZXMgPSBbXTtcbiAgICB2YXIgaSwgbGVuO1xuICAgIGlmICh1dGlsaXRpZXMuaXNTdHJpbmcoY3NzQ2xhc3MpICYmIHV0aWxpdGllcy5pc05vdEVtcHR5U3RyaW5nKGNzc0NsYXNzLnJlcGxhY2UoL1xccysvLCAnJykpKSB7XG5cbiAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGNsYXNzZXMubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgICAgaWYgKGNzc0NsYXNzICE9PSBjbGFzc2VzW2ldKSB7XG4gICAgICAgICAgbmV3Q2xhc3Nlcy5wdXNoKGNsYXNzZXNbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgbmV3Q2xhc3Nlcy5qb2luKCcgJykpO1xuICAgIH1cbiAgfVxufTtcblxuZG9tLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRFdmVudExpc3RlbmVyKGVsLCB0eXBlLCBoYW5kbGVyKSB7XG4gIGlmKHV0aWxpdGllcy5pc0FycmF5KGVsKSl7XG4gICAgdXRpbGl0aWVzLmZvckVhY2goZWwsIGZ1bmN0aW9uKGUpIHtcbiAgICAgIGRvbS5hZGRFdmVudExpc3RlbmVyKGUsIHR5cGUsIGhhbmRsZXIpO1xuICAgIH0pO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmKHV0aWxpdGllcy5pc0FycmF5KHR5cGUpKXtcbiAgICB1dGlsaXRpZXMuZm9yRWFjaCh0eXBlLCBmdW5jdGlvbih0KSB7XG4gICAgICBkb20uYWRkRXZlbnRMaXN0ZW5lcihlbCwgdCwgaGFuZGxlcik7XG4gICAgfSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGVsLmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICBlbC5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGhhbmRsZXIsIGZhbHNlKTtcbiAgfSBlbHNlIGlmIChlbC5hdHRhY2hFdmVudCkge1xuICAgIC8vIFdBUk5JTkchISEgdGhpcyBpcyBhIHZlcnkgbmFpdmUgaW1wbGVtZW50YXRpb24gIVxuICAgIC8vIHRoZSBldmVudCBvYmplY3QgdGhhdCBzaG91bGQgYmUgcGFzc2VkIHRvIHRoZSBoYW5kbGVyXG4gICAgLy8gd291bGQgbm90IGJlIHRoZXJlIGZvciBJRThcbiAgICAvLyB3ZSBzaG91bGQgdXNlIFwid2luZG93LmV2ZW50XCIgYW5kIHRoZW4gXCJldmVudC5zcmNFbGVtZW50XCJcbiAgICAvLyBpbnN0ZWFkIG9mIFwiZXZlbnQudGFyZ2V0XCJcbiAgICBlbC5hdHRhY2hFdmVudChcIm9uXCIgKyB0eXBlLCBoYW5kbGVyKTtcbiAgfVxufTtcblxuZG9tLnJlbW92ZUV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiByZW1vdmVFdmVudExpc3RlbmVyKGVsLCB0eXBlLCBoYW5kbGVyKSB7XG4gIGlmKHV0aWxpdGllcy5pc0FycmF5KGVsKSl7XG4gICAgdXRpbGl0aWVzLmZvckVhY2goZWwsIGZ1bmN0aW9uKGUpIHtcbiAgICAgIGRvbS5yZW1vdmVFdmVudExpc3RlbmVyKGUsIHR5cGUsIGhhbmRsZXIpO1xuICAgIH0pO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmKHV0aWxpdGllcy5pc0FycmF5KHR5cGUpKXtcbiAgICB1dGlsaXRpZXMuZm9yRWFjaCh0eXBlLCBmdW5jdGlvbih0KSB7XG4gICAgICBkb20ucmVtb3ZlRXZlbnRMaXN0ZW5lcihlbCwgdCwgaGFuZGxlcik7XG4gICAgfSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIpIHtcbiAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGhhbmRsZXIsIGZhbHNlKTtcbiAgfSBlbHNlIGlmIChlbC5kZXRhY2hFdmVudCkge1xuICAgIGVsLmRldGFjaEV2ZW50KFwib25cIiArIHR5cGUsIGhhbmRsZXIpO1xuICB9IGVsc2Uge1xuICAgIGVsW1wib25cIiArIHR5cGVdID0gbnVsbDtcbiAgfVxufTtcblxuZG9tLmRpc3BhdGNoRXZlbnQgPSBmdW5jdGlvbiBkaXNwYXRjaEV2ZW50KGVsLCBldmVudCkge1xuICBpZiAoZWwuZGlzcGF0Y2hFdmVudCkge1xuICAgIGVsLmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICB9IGVsc2Uge1xuICAgIGVsLmZpcmVFdmVudChcIm9uXCIgKyBldmVudC5ldmVudFR5cGUsIGV2ZW50KTtcbiAgfVxufTtcblxuZG9tLmlzRGVzY2VuZGFudCA9IGZ1bmN0aW9uIGlzRGVzY2VuZGFudChwYXJlbnQsIGNoaWxkKSB7XG4gIHZhciBub2RlID0gY2hpbGQucGFyZW50Tm9kZTtcbiAgd2hpbGUgKG5vZGUgIT09IG51bGwpIHtcbiAgICBpZiAobm9kZSA9PT0gcGFyZW50KSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59O1xuXG5kb20uZ2V0VGV4dENvbnRlbnQgPSBmdW5jdGlvbiBnZXRUZXh0Q29udGVudChlbCl7XG4gIHJldHVybiBlbC50ZXh0Q29udGVudCB8fCBlbC50ZXh0O1xufTtcblxuZG9tLnByZXBlbmRDaGlsZCA9IGZ1bmN0aW9uIHByZXBlbmRDaGlsZChwYXJlbnQsIGNoaWxkKSB7XG4gIGlmKGNoaWxkLnBhcmVudE5vZGUpe1xuICAgIGNoaWxkLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoY2hpbGQpO1xuICB9XG4gIHJldHVybiBwYXJlbnQuaW5zZXJ0QmVmb3JlKGNoaWxkLCBwYXJlbnQuZmlyc3RDaGlsZCk7XG59O1xuXG5kb20ucmVtb3ZlID0gZnVuY3Rpb24gcmVtb3ZlTm9kZShub2RlKXtcbiAgaWYobm9kZSAmJiBub2RlLnBhcmVudE5vZGUpe1xuICAgIG5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChub2RlKTtcbiAgfVxufTtcblxuZG9tLmlzRG9tRWxlbWVudCA9IGZ1bmN0aW9uIGlzRG9tRWxlbWVudChvKSB7XG4gIHJldHVybiBvIGluc3RhbmNlb2YgRWxlbWVudDtcbn07XG5cbmRvbS5jbGljayA9IGZ1bmN0aW9uKGVsLCBoYW5kbGVyKSB7XG4gIGRvbS5hZGRFdmVudExpc3RlbmVyKGVsLCAnY2xpY2snLCBoYW5kbGVyKTtcbn07XG5cbmRvbS5vbmNlID0gZnVuY3Rpb24oZWwsIHR5cGUsIGhhbmRsZXIpIHtcbiAgZnVuY3Rpb24gaGFuZGxlcldyYXAoKSB7XG4gICAgaGFuZGxlci5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuICAgIGRvbS5yZW1vdmVFdmVudExpc3RlbmVyKGVsLCB0eXBlLCBoYW5kbGVyV3JhcCk7XG4gIH1cblxuICBkb20uYWRkRXZlbnRMaXN0ZW5lcihlbCwgdHlwZSwgaGFuZGxlcldyYXApO1xufTtcblxuLy9Ob3RlOiB0aGVyZSBpcyBubyBnZXRCb3VuZGluZ0NsaWVudFJlY3Qgb24gaVBhZCBzbyB3ZSBuZWVkIGEgZmFsbGJhY2tcbmRvbS5nZXREaW1lbnNpb24gPSBmdW5jdGlvbiBnZXREaW1lbnNpb24oZWxlbWVudCkge1xuICB2YXIgcmVjdDtcblxuICAvL09uIElFOSBhbmQgYmVsb3cgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IGRvZXMgbm90IHdvcmsgY29uc2lzdGVudGx5XG4gIGlmKCF1dGlsaXRpZXMuaXNPbGRJRSgpICYmIGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KSB7XG4gICAgcmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHdpZHRoOiByZWN0LndpZHRoLFxuICAgICAgaGVpZ2h0OiByZWN0LmhlaWdodFxuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHdpZHRoOiBlbGVtZW50Lm9mZnNldFdpZHRoLFxuICAgIGhlaWdodDogZWxlbWVudC5vZmZzZXRIZWlnaHRcbiAgfTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZG9tOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIHVybFV0aWxzID0gcmVxdWlyZSgnLi91cmxVdGlscycpO1xudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4vdXRpbGl0eUZ1bmN0aW9ucycpO1xuXG5mdW5jdGlvbiBIdHRwUmVxdWVzdEVycm9yKG1lc3NhZ2UpIHtcbiAgdGhpcy5tZXNzYWdlID0gJ0h0dHBSZXF1ZXN0IEVycm9yOiAnICsgKG1lc3NhZ2UgfHwgJycpO1xufVxuSHR0cFJlcXVlc3RFcnJvci5wcm90b3R5cGUgPSBuZXcgRXJyb3IoKTtcbkh0dHBSZXF1ZXN0RXJyb3IucHJvdG90eXBlLm5hbWUgPSBcIkh0dHBSZXF1ZXN0IEVycm9yXCI7XG5cbmZ1bmN0aW9uIEh0dHBSZXF1ZXN0KGNyZWF0ZVhocikge1xuICBpZiAoIXV0aWxpdGllcy5pc0Z1bmN0aW9uKGNyZWF0ZVhocikpIHtcbiAgICB0aHJvdyBuZXcgSHR0cFJlcXVlc3RFcnJvcignTWlzc2luZyBYTUxIdHRwUmVxdWVzdCBmYWN0b3J5IG1ldGhvZCcpO1xuICB9XG5cbiAgdGhpcy5jcmVhdGVYaHIgPSBjcmVhdGVYaHI7XG59XG5cbkh0dHBSZXF1ZXN0LnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAobWV0aG9kLCB1cmwsIGNhbGxiYWNrLCBvcHRpb25zKSB7XG4gIHNhbml0eUNoZWNrKHVybCwgY2FsbGJhY2ssIG9wdGlvbnMpO1xuICB2YXIgdGltZW91dCwgdGltZW91dElkO1xuICB2YXIgeGhyID0gdGhpcy5jcmVhdGVYaHIoKTtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHRpbWVvdXQgPSB1dGlsaXRpZXMuaXNOdW1iZXIob3B0aW9ucy50aW1lb3V0KSA/IG9wdGlvbnMudGltZW91dCA6IDA7XG5cbiAgeGhyLm9wZW4obWV0aG9kLCB1cmxVdGlscy51cmxQYXJ0cyh1cmwpLmhyZWYsIHRydWUpO1xuXG4gIGlmIChvcHRpb25zLmhlYWRlcnMpIHtcbiAgICBzZXRIZWFkZXJzKHhociwgb3B0aW9ucy5oZWFkZXJzKTtcbiAgfVxuXG4gIGlmIChvcHRpb25zLndpdGhDcmVkZW50aWFscykge1xuICAgIHhoci53aXRoQ3JlZGVudGlhbHMgPSB0cnVlO1xuICB9XG5cbiAgeGhyLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc3RhdHVzVGV4dCwgcmVzcG9uc2UsIHN0YXR1cztcblxuICAgIC8qKlxuICAgICAqIFRoZSBvbmx5IHdheSB0byBkbyBhIHNlY3VyZSByZXF1ZXN0IG9uIElFOCBhbmQgSUU5IGlzIHdpdGggdGhlIFhEb21haW5SZXF1ZXN0IG9iamVjdC4gVW5mb3J0dW5hdGVseSwgbWljcm9zb2Z0IGlzXG4gICAgICogc28gbmljZSB0aGF0IGRlY2lkZWQgdGhhdCB0aGUgc3RhdHVzIHByb3BlcnR5IGFuZCB0aGUgJ2dldEFsbFJlc3BvbnNlSGVhZGVycycgbWV0aG9kIHdoZXJlIG5vdCBuZWVkZWQgc28gd2UgaGF2ZSB0b1xuICAgICAqIGZha2UgdGhlbS4gSWYgdGhlIHJlcXVlc3QgZ2V0cyBkb25lIHdpdGggYW4gWERvbWFpblJlcXVlc3QgaW5zdGFuY2UsIHdlIHdpbGwgYXNzdW1lIHRoYXQgdGhlcmUgYXJlIG5vIGhlYWRlcnMgYW5kXG4gICAgICogdGhlIHN0YXR1cyB3aWxsIGFsd2F5cyBiZSAyMDAuIElmIHlvdSBkb24ndCBsaWtlIGl0LCBETyBOT1QgVVNFIEFOQ0lFTlQgQlJPV1NFUlMhISFcbiAgICAgKlxuICAgICAqIEZvciBtb3IgaW5mbyBnbyB0bzogaHR0cHM6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9jYzI4ODA2MCh2PXZzLjg1KS5hc3B4XG4gICAgICovXG4gICAgaWYgKCF4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKSB7XG4gICAgICB4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKCF4aHIuc3RhdHVzKSB7XG4gICAgICB4aHIuc3RhdHVzID0gMjAwO1xuICAgIH1cblxuICAgIGlmICh1dGlsaXRpZXMuaXNEZWZpbmVkKHRpbWVvdXRJZCkpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgdGltZW91dElkID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHN0YXR1c1RleHQgPSB4aHIuc3RhdHVzVGV4dCB8fCAnJztcblxuICAgIC8vIHJlc3BvbnNlVGV4dCBpcyB0aGUgb2xkLXNjaG9vbCB3YXkgb2YgcmV0cmlldmluZyByZXNwb25zZSAoc3VwcG9ydGVkIGJ5IElFOCAmIDkpXG4gICAgLy8gcmVzcG9uc2UvcmVzcG9uc2VUeXBlIHByb3BlcnRpZXMgd2VyZSBpbnRyb2R1Y2VkIGluIFhIUiBMZXZlbDIgc3BlYyAoc3VwcG9ydGVkIGJ5IElFMTApXG4gICAgcmVzcG9uc2UgPSAoJ3Jlc3BvbnNlJyBpbiB4aHIpID8geGhyLnJlc3BvbnNlIDogeGhyLnJlc3BvbnNlVGV4dDtcblxuICAgIC8vIG5vcm1hbGl6ZSBJRTkgYnVnIChodHRwOi8vYnVncy5qcXVlcnkuY29tL3RpY2tldC8xNDUwKVxuICAgIHN0YXR1cyA9IHhoci5zdGF0dXMgPT09IDEyMjMgPyAyMDQgOiB4aHIuc3RhdHVzO1xuXG4gICAgY2FsbGJhY2soXG4gICAgICBzdGF0dXMsXG4gICAgICByZXNwb25zZSxcbiAgICAgIHhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSxcbiAgICAgIHN0YXR1c1RleHQpO1xuICB9O1xuXG4gIHhoci5vbmVycm9yID0gcmVxdWVzdEVycm9yO1xuICB4aHIub25hYm9ydCA9IHJlcXVlc3RFcnJvcjtcblxuICB4aHIuc2VuZCgpO1xuXG4gIGlmICh0aW1lb3V0ID4gMCkge1xuICAgIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgeGhyICYmIHhoci5hYm9ydCgpO1xuICAgIH0sIHRpbWVvdXQpO1xuICB9XG5cbiAgZnVuY3Rpb24gc2FuaXR5Q2hlY2sodXJsLCBjYWxsYmFjaywgb3B0aW9ucykge1xuICAgIGlmICghdXRpbGl0aWVzLmlzU3RyaW5nKHVybCkgfHwgdXRpbGl0aWVzLmlzRW1wdHlTdHJpbmcodXJsKSkge1xuICAgICAgdGhyb3cgbmV3IEh0dHBSZXF1ZXN0RXJyb3IoXCJJbnZhbGlkIHVybCAnXCIgKyB1cmwgKyBcIidcIik7XG4gICAgfVxuXG4gICAgaWYgKCF1dGlsaXRpZXMuaXNGdW5jdGlvbihjYWxsYmFjaykpIHtcbiAgICAgIHRocm93IG5ldyBIdHRwUmVxdWVzdEVycm9yKFwiSW52YWxpZCBoYW5kbGVyICdcIiArIGNhbGxiYWNrICsgXCInIGZvciB0aGUgaHR0cCByZXF1ZXN0XCIpO1xuICAgIH1cblxuICAgIGlmICh1dGlsaXRpZXMuaXNEZWZpbmVkKG9wdGlvbnMpICYmICF1dGlsaXRpZXMuaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgIHRocm93IG5ldyBIdHRwUmVxdWVzdEVycm9yKFwiSW52YWxpZCBvcHRpb25zIG1hcCAnXCIgKyBvcHRpb25zICsgXCInXCIpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNldEhlYWRlcnMoeGhyLCBoZWFkZXJzKSB7XG4gICAgdXRpbGl0aWVzLmZvckVhY2goaGVhZGVycywgZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcbiAgICAgIGlmICh1dGlsaXRpZXMuaXNEZWZpbmVkKHZhbHVlKSkge1xuICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihrZXksIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlcXVlc3RFcnJvcigpIHtcbiAgICBjYWxsYmFjaygtMSwgbnVsbCwgbnVsbCwgJycpO1xuICB9XG59O1xuXG5IdHRwUmVxdWVzdC5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKHVybCwgY2FsbGJhY2ssIG9wdGlvbnMpIHtcbiAgdGhpcy5ydW4oJ0dFVCcsIHVybCwgcHJvY2Vzc1Jlc3BvbnNlLCBvcHRpb25zKTtcblxuICBmdW5jdGlvbiBwcm9jZXNzUmVzcG9uc2Uoc3RhdHVzLCByZXNwb25zZSwgaGVhZGVyc1N0cmluZywgc3RhdHVzVGV4dCkge1xuICAgIGlmIChpc1N1Y2Nlc3Moc3RhdHVzKSkge1xuICAgICAgY2FsbGJhY2sobnVsbCwgcmVzcG9uc2UsIHN0YXR1cywgaGVhZGVyc1N0cmluZywgc3RhdHVzVGV4dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNhbGxiYWNrKG5ldyBIdHRwUmVxdWVzdEVycm9yKHN0YXR1c1RleHQpLCByZXNwb25zZSwgc3RhdHVzLCBoZWFkZXJzU3RyaW5nLCBzdGF0dXNUZXh0KTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpc1N1Y2Nlc3Moc3RhdHVzKSB7XG4gICAgcmV0dXJuIDIwMCA8PSBzdGF0dXMgJiYgc3RhdHVzIDwgMzAwO1xuICB9XG59O1xuXG5mdW5jdGlvbiBjcmVhdGVYaHIoKSB7XG4gIHZhciB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgaWYgKCEoXCJ3aXRoQ3JlZGVudGlhbHNcIiBpbiB4aHIpKSB7XG4gICAgLy8gWERvbWFpblJlcXVlc3QgZm9yIElFLlxuICAgIHhociA9IG5ldyBYRG9tYWluUmVxdWVzdCgpO1xuICB9XG4gIHJldHVybiB4aHI7XG59XG5cbnZhciBodHRwID0gbmV3IEh0dHBSZXF1ZXN0KGNyZWF0ZVhocik7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBodHRwOiBodHRwLFxuICBIdHRwUmVxdWVzdDogSHR0cFJlcXVlc3QsXG4gIEh0dHBSZXF1ZXN0RXJyb3I6IEh0dHBSZXF1ZXN0RXJyb3IsXG4gIGNyZWF0ZVhocjogY3JlYXRlWGhyXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZG9tID0gcmVxdWlyZSgnLi9kb20nKTtcbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxudmFyIHBsYXllclV0aWxzID0ge307XG5cbi8qKlxuICogUmV0dXJucyBhbiBvYmplY3QgdGhhdCBjYXB0dXJlcyB0aGUgcG9ydGlvbnMgb2YgcGxheWVyIHN0YXRlIHJlbGV2YW50IHRvXG4gKiB2aWRlbyBwbGF5YmFjay4gVGhlIHJlc3VsdCBvZiB0aGlzIGZ1bmN0aW9uIGNhbiBiZSBwYXNzZWQgdG9cbiAqIHJlc3RvcmVQbGF5ZXJTbmFwc2hvdCB3aXRoIGEgcGxheWVyIHRvIHJldHVybiB0aGUgcGxheWVyIHRvIHRoZSBzdGF0ZSBpdFxuICogd2FzIGluIHdoZW4gdGhpcyBmdW5jdGlvbiB3YXMgaW52b2tlZC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBwbGF5ZXIgVGhlIHZpZGVvanMgcGxheWVyIG9iamVjdFxuICovXG5wbGF5ZXJVdGlscy5nZXRQbGF5ZXJTbmFwc2hvdCA9IGZ1bmN0aW9uIGdldFBsYXllclNuYXBzaG90KHBsYXllcikge1xuICB2YXIgdGVjaCA9IHBsYXllci5lbCgpLnF1ZXJ5U2VsZWN0b3IoJy52anMtdGVjaCcpO1xuXG4gIHZhciBzbmFwc2hvdCA9IHtcbiAgICBlbmRlZDogcGxheWVyLmVuZGVkKCksXG4gICAgc3JjOiBwbGF5ZXIuY3VycmVudFNyYygpLFxuICAgIGN1cnJlbnRUaW1lOiBwbGF5ZXIuY3VycmVudFRpbWUoKSxcbiAgICB0eXBlOiBwbGF5ZXIuY3VycmVudFR5cGUoKSxcbiAgICBwbGF5aW5nOiAhcGxheWVyLnBhdXNlZCgpLFxuICAgIHN1cHByZXNzZWRUcmFja3M6IGdldFN1cHByZXNzZWRUcmFja3MocGxheWVyKVxuICB9O1xuXG4gIGlmICh0ZWNoKSB7XG4gICAgc25hcHNob3QubmF0aXZlUG9zdGVyID0gdGVjaC5wb3N0ZXI7XG4gICAgc25hcHNob3Quc3R5bGUgPSB0ZWNoLmdldEF0dHJpYnV0ZSgnc3R5bGUnKTtcbiAgfVxuICByZXR1cm4gc25hcHNob3Q7XG5cbiAgLyoqKiogTG9jYWwgRnVuY3Rpb25zICoqKiovXG4gIGZ1bmN0aW9uIGdldFN1cHByZXNzZWRUcmFja3MocGxheWVyKSB7XG4gICAgdmFyIHRyYWNrcyA9IHBsYXllci5yZW1vdGVUZXh0VHJhY2tzID8gcGxheWVyLnJlbW90ZVRleHRUcmFja3MoKSA6IFtdO1xuXG4gICAgaWYgKHRyYWNrcyAmJiB1dGlsaXRpZXMuaXNBcnJheSh0cmFja3MudHJhY2tzXykpIHtcbiAgICAgIHRyYWNrcyA9IHRyYWNrcy50cmFja3NfO1xuICAgIH1cblxuICAgIGlmICghdXRpbGl0aWVzLmlzQXJyYXkodHJhY2tzKSkge1xuICAgICAgdHJhY2tzID0gW107XG4gICAgfVxuXG4gICAgdmFyIHN1cHByZXNzZWRUcmFja3MgPSBbXTtcbiAgICB0cmFja3MuZm9yRWFjaChmdW5jdGlvbiAodHJhY2spIHtcbiAgICAgIHN1cHByZXNzZWRUcmFja3MucHVzaCh7XG4gICAgICAgIHRyYWNrOiB0cmFjayxcbiAgICAgICAgbW9kZTogdHJhY2subW9kZVxuICAgICAgfSk7XG4gICAgICB0cmFjay5tb2RlID0gJ2Rpc2FibGVkJztcbiAgICB9KTtcblxuICAgIHJldHVybiBzdXBwcmVzc2VkVHJhY2tzO1xuICB9XG59O1xuXG4vKipcbiAqIEF0dGVtcHRzIHRvIG1vZGlmeSB0aGUgc3BlY2lmaWVkIHBsYXllciBzbyB0aGF0IGl0cyBzdGF0ZSBpcyBlcXVpdmFsZW50IHRvXG4gKiB0aGUgc3RhdGUgb2YgdGhlIHNuYXBzaG90LlxuICogQHBhcmFtIHtvYmplY3R9IHNuYXBzaG90IC0gdGhlIHBsYXllciBzdGF0ZSB0byBhcHBseVxuICovXG5wbGF5ZXJVdGlscy5yZXN0b3JlUGxheWVyU25hcHNob3QgPSBmdW5jdGlvbiByZXN0b3JlUGxheWVyU25hcHNob3QocGxheWVyLCBzbmFwc2hvdCkge1xuICB2YXIgdGVjaCA9IHBsYXllci5lbCgpLnF1ZXJ5U2VsZWN0b3IoJy52anMtdGVjaCcpO1xuICB2YXIgYXR0ZW1wdHMgPSAyMDsgLy8gdGhlIG51bWJlciBvZiByZW1haW5pbmcgYXR0ZW1wdHMgdG8gcmVzdG9yZSB0aGUgc25hcHNob3RcblxuICBpZiAoc25hcHNob3QubmF0aXZlUG9zdGVyKSB7XG4gICAgdGVjaC5wb3N0ZXIgPSBzbmFwc2hvdC5uYXRpdmVQb3N0ZXI7XG4gIH1cblxuICBpZiAoJ3N0eWxlJyBpbiBzbmFwc2hvdCkge1xuICAgIC8vIG92ZXJ3cml0ZSBhbGwgY3NzIHN0eWxlIHByb3BlcnRpZXMgdG8gcmVzdG9yZSBzdGF0ZSBwcmVjaXNlbHlcbiAgICB0ZWNoLnNldEF0dHJpYnV0ZSgnc3R5bGUnLCBzbmFwc2hvdC5zdHlsZSB8fCAnJyk7XG4gIH1cblxuICBpZiAoaGFzU3JjQ2hhbmdlZChwbGF5ZXIsIHNuYXBzaG90KSkge1xuXG4gICAgLy8gb24gaW9zNywgZmlkZGxpbmcgd2l0aCB0ZXh0VHJhY2tzIHRvbyBlYXJseSB3aWxsIGNhdXNlIHNhZmFyaSB0byBjcmFzaFxuICAgIHBsYXllci5vbmUoJ2NvbnRlbnRsb2FkZWRtZXRhZGF0YScsIHJlc3RvcmVUcmFja3MpO1xuXG4gICAgcGxheWVyLm9uZSgnY2FucGxheScsIHRyeVRvUmVzdW1lKTtcbiAgICBlbnN1cmVDYW5wbGF5RXZ0R2V0c0ZpcmVkKCk7XG5cbiAgICAvLyBpZiB0aGUgc3JjIGNoYW5nZWQgZm9yIGFkIHBsYXliYWNrLCByZXNldCBpdFxuICAgIHBsYXllci5zcmMoe3NyYzogc25hcHNob3Quc3JjLCB0eXBlOiBzbmFwc2hvdC50eXBlfSk7XG5cbiAgICAvLyBzYWZhcmkgcmVxdWlyZXMgYSBjYWxsIHRvIGBsb2FkYCB0byBwaWNrIHVwIGEgY2hhbmdlZCBzb3VyY2VcbiAgICBwbGF5ZXIubG9hZCgpO1xuXG4gIH0gZWxzZSB7XG4gICAgcmVzdG9yZVRyYWNrcygpO1xuXG4gICAgaWYgKHNuYXBzaG90LnBsYXlpbmcpIHtcbiAgICAgIHBsYXllci5wbGF5KCk7XG4gICAgfVxuICB9XG5cbiAgLyoqKiBMb2NhbCBGdW5jdGlvbnMgKioqL1xuXG4gIC8qKlxuICAgKiBTb21ldGltZXMgZmlyZWZveCBkb2VzIG5vdCB0cmlnZ2VyIHRoZSAnY2FucGxheScgZXZ0LlxuICAgKiBUaGlzIGNvZGUgZW5zdXJlIHRoYXQgaXQgYWx3YXlzIGdldHMgdHJpZ2dlcmVkIHRyaWdnZXJlZC5cbiAgICovXG4gIGZ1bmN0aW9uIGVuc3VyZUNhbnBsYXlFdnRHZXRzRmlyZWQoKSB7XG4gICAgdmFyIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICBwbGF5ZXIudHJpZ2dlcignY2FucGxheScpO1xuICAgIH0sIDEwMDApO1xuXG4gICAgcGxheWVyLm9uZSgnY2FucGxheScsIGZ1bmN0aW9uKCl7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgcGxheWVyIG5lZWRzIHRvIGJlIHJlc3RvcmVkIHRvIGl0cyBzdGF0ZVxuICAgKiBiZWZvcmUgYWQgcGxheWJhY2sgYmVnYW4uIFdpdGggYSBjdXN0b20gYWQgZGlzcGxheSBvciBidXJuZWQtaW5cbiAgICogYWRzLCB0aGUgY29udGVudCBwbGF5ZXIgc3RhdGUgaGFzbid0IGJlZW4gbW9kaWZpZWQgYW5kIHNvIG5vXG4gICAqIHJlc3RvcmF0aW9uIGlzIHJlcXVpcmVkXG4gICAqL1xuICBmdW5jdGlvbiBoYXNTcmNDaGFuZ2VkKHBsYXllciwgc25hcHNob3QpIHtcbiAgICBpZiAocGxheWVyLnNyYygpKSB7XG4gICAgICByZXR1cm4gcGxheWVyLnNyYygpICE9PSBzbmFwc2hvdC5zcmM7XG4gICAgfVxuICAgIC8vIHRoZSBwbGF5ZXIgd2FzIGNvbmZpZ3VyZWQgdGhyb3VnaCBzb3VyY2UgZWxlbWVudCBjaGlsZHJlblxuICAgIHJldHVybiBwbGF5ZXIuY3VycmVudFNyYygpICE9PSBzbmFwc2hvdC5zcmM7XG4gIH1cblxuICBmdW5jdGlvbiByZXN0b3JlVHJhY2tzKCkge1xuICAgIHZhciBzdXBwcmVzc2VkVHJhY2tzID0gc25hcHNob3Quc3VwcHJlc3NlZFRyYWNrcztcbiAgICBzdXBwcmVzc2VkVHJhY2tzLmZvckVhY2goZnVuY3Rpb24gKHRyYWNrU25hcHNob3QpIHtcbiAgICAgIHRyYWNrU25hcHNob3QudHJhY2subW9kZSA9IHRyYWNrU25hcHNob3QubW9kZTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmUgaWYgdGhlIHZpZGVvIGVsZW1lbnQgaGFzIGxvYWRlZCBlbm91Z2ggb2YgdGhlIHNuYXBzaG90IHNvdXJjZVxuICAgKiB0byBiZSByZWFkeSB0byBhcHBseSB0aGUgcmVzdCBvZiB0aGUgc3RhdGVcbiAgICovXG4gIGZ1bmN0aW9uIHRyeVRvUmVzdW1lKCkge1xuXG4gICAgLy8gaWYgc29tZSBwZXJpb2Qgb2YgdGhlIHZpZGVvIGlzIHNlZWthYmxlLCByZXN1bWUgcGxheWJhY2tcbiAgICAvLyBvdGhlcndpc2UgZGVsYXkgYSBiaXQgYW5kIHRoZW4gY2hlY2sgYWdhaW4gdW5sZXNzIHdlJ3JlIG91dCBvZiBhdHRlbXB0c1xuXG4gICAgaWYgKCFwbGF5ZXJVdGlscy5pc1JlYWR5VG9SZXN1bWUocGxheWVyKSAmJiBhdHRlbXB0cy0tKSB7XG4gICAgICBzZXRUaW1lb3V0KHRyeVRvUmVzdW1lLCA1MCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmKHBsYXllci5jdXJyZW50VGltZSgpICE9PSBzbmFwc2hvdC5jdXJyZW50VGltZSkge1xuICAgICAgICAgIGlmIChzbmFwc2hvdC5wbGF5aW5nKSB7IC8vIGlmIG5lZWRlZCByZXN0b3JlIHBsYXlpbmcgc3RhdHVzIGFmdGVyIHNlZWsgY29tcGxldGVzXG4gICAgICAgICAgICBwbGF5ZXIub25lKCdzZWVrZWQnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgcGxheWVyLnBsYXkoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBwbGF5ZXIuY3VycmVudFRpbWUoc25hcHNob3QuY3VycmVudFRpbWUpO1xuXG4gICAgICAgIH0gZWxzZSBpZiAoc25hcHNob3QucGxheWluZykge1xuICAgICAgICAgIC8vIGlmIG5lZWRlZCBhbmQgbm8gc2VlayBoYXMgYmVlbiBwZXJmb3JtZWQsIHJlc3RvcmUgcGxheWluZyBzdGF0dXMgaW1tZWRpYXRlbHlcbiAgICAgICAgICBwbGF5ZXIucGxheSgpO1xuICAgICAgICB9XG5cbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdmlkZW9qcy5sb2cud2FybignRmFpbGVkIHRvIHJlc3VtZSB0aGUgY29udGVudCBhZnRlciBhbiBhZHZlcnRpc2VtZW50JywgZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG5wbGF5ZXJVdGlscy5pc1JlYWR5VG9SZXN1bWUgPSBmdW5jdGlvbiAocGxheWVyKSB7XG5cbiAgaWYgKHBsYXllci5yZWFkeVN0YXRlKCkgPiAxKSB7XG4gICAgLy8gc29tZSBicm93c2VycyBhbmQgbWVkaWEgYXJlbid0IFwic2Vla2FibGVcIi5cbiAgICAvLyByZWFkeVN0YXRlIGdyZWF0ZXIgdGhhbiAxIGFsbG93cyBmb3Igc2Vla2luZyB3aXRob3V0IGV4Y2VwdGlvbnNcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChwbGF5ZXIuc2Vla2FibGUoKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gaWYgdGhlIHBsYXllciBkb2Vzbid0IGV4cG9zZSB0aGUgc2Vla2FibGUgdGltZSByYW5nZXMsIHRyeSB0b1xuICAgIC8vIHJlc3VtZSBwbGF5YmFjayBpbW1lZGlhdGVseVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKHBsYXllci5zZWVrYWJsZSgpLmxlbmd0aCA+IDApIHtcbiAgICAvLyBpZiBzb21lIHBlcmlvZCBvZiB0aGUgdmlkZW8gaXMgc2Vla2FibGUsIHJlc3VtZSBwbGF5YmFja1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIHByZXBhcmVzIHRoZSBwbGF5ZXIgdG8gZGlzcGxheSBhZHMuXG4gKiBBZGRpbmcgY29udmVuaWVuY2UgZXZlbnRzIGxpa2UgdGhlICd2YXN0LmZpcnNQbGF5JyB0aGF0IGdldHMgZmlyZWQgd2hlbiB0aGUgdmlkZW8gaXMgZmlyc3QgcGxheWVkXG4gKiBhbmQgYWRzIHRoZSBibGFja1Bvc3RlciB0byB0aGUgcGxheWVyIHRvIHByZXZlbnQgY29udGVudCBmcm9tIGJlaW5nIGRpc3BsYXllZCBiZWZvcmUgdGhlIHByZXJvbGwgYWQuXG4gKlxuICogQHBhcmFtIHBsYXllclxuICovXG5wbGF5ZXJVdGlscy5wcmVwYXJlRm9yQWRzID0gZnVuY3Rpb24gKHBsYXllcikge1xuICB2YXIgYmxhY2tQb3N0ZXIgPSBwbGF5ZXIuYWRkQ2hpbGQoJ2JsYWNrUG9zdGVyJyk7XG4gIHZhciBfZmlyc3RQbGF5ID0gdHJ1ZTtcbiAgdmFyIHZvbHVtZVNuYXBzaG90O1xuXG5cbiAgbW9ua2V5UGF0Y2hQbGF5ZXJBcGkoKTtcblxuICBwbGF5ZXIub24oJ3BsYXknLCB0cnlUb1RyaWdnZXJGaXJzdFBsYXkpO1xuICBwbGF5ZXIub24oJ3Zhc3QucmVzZXQnLCByZXNldEZpcnN0UGxheSk7Ly9FdmVyeSB0aW1lIHdlIGNoYW5nZSB0aGUgc291cmNlcyB3ZSByZXNldCB0aGUgZmlyc3QgcGxheS5cbiAgcGxheWVyLm9uKCd2YXN0LmZpcnN0UGxheScsIHJlc3RvcmVDb250ZW50Vm9sdW1lKTtcbiAgcGxheWVyLm9uKCdlcnJvcicsIGhpZGVCbGFja1Bvc3Rlcik7Ly9JZiB0aGVyZSBpcyBhbiBlcnJvciBpbiB0aGUgcGxheWVyIHdlIHJlbW92ZSB0aGUgYmxhY2twb3N0ZXIgdG8gc2hvdyB0aGUgZXJyIG1zZ1xuICBwbGF5ZXIub24oJ3Zhc3QuYWRTdGFydCcsIGhpZGVCbGFja1Bvc3Rlcik7XG4gIHBsYXllci5vbigndmFzdC5hZHNDYW5jZWwnLCBoaWRlQmxhY2tQb3N0ZXIpO1xuICBwbGF5ZXIub24oJ3Zhc3QuYWRFcnJvcicsIGhpZGVCbGFja1Bvc3Rlcik7XG4gIHBsYXllci5vbigndmFzdC5hZFN0YXJ0JywgYWRkU3R5bGVzKTtcbiAgcGxheWVyLm9uKCd2YXN0LmFkRW5kJywgcmVtb3ZlU3R5bGVzKTtcbiAgcGxheWVyLm9uKCd2YXN0LmFkc0NhbmNlbCcsIHJlbW92ZVN0eWxlcyk7XG5cbiAgLyoqKiBMb2NhbCBGdW5jdGlvbnMgKioqL1xuXG4gIC8qKlxuICAgV2hhdCB0aGlzIGZ1bmN0aW9uIGRvZXMgaXMgdWdseSBhbmQgaG9ycmlibGUgYW5kIEkgc2hvdWxkIHRoaW5rIHR3aWNlIGJlZm9yZSBjYWxsaW5nIG15c2VsZiBhIGdvb2QgZGV2ZWxvcGVyLiBXaXRoIHRoYXQgc2FpZCxcbiAgIGl0IGlzIHRoZSBiZXN0IHNvbHV0aW9uIEkgY291bGQgZmluZCB0byBtdXRlIHRoZSB2aWRlbyB1bnRpbCB0aGUgJ3BsYXknIGV2ZW50IGhhcHBlbnMgKG9uIG1vYmlsZSBkZXZpY2VzKSBhbmQgdGhlIHBsdWdpbiBjYW4gZGVjaWRlIHdoZXRoZXJcbiAgIHRvIHBsYXkgdGhlIGFkIG9yIG5vdC5cblxuICAgV2UgYWxzbyBuZWVkIHRoaXMgbW9ua2V5cGF0Y2ggdG8gYmUgYWJsZSB0byBwYXVzZSBhbmQgcmVzdW1lIGFuIGFkIHVzaW5nIHRoZSBwbGF5ZXIncyBBUElcblxuICAgSWYgeW91IGhhdmUgYSBiZXR0ZXIgc29sdXRpb24gcGxlYXNlIGRvIHRlbGwgbWUuXG4gICAqL1xuICBmdW5jdGlvbiBtb25rZXlQYXRjaFBsYXllckFwaSgpIHtcblxuICAgIC8qKlxuICAgICAqIE1vbmtleSBwYXRjaCBuZWVkZWQgdG8gaGFuZGxlIGZpcnN0UGxheSBhbmQgcmVzdW1lIG9mIHBsYXlpbmcgYWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY2FsbE9yaWdQbGF5IG5lY2Vzc2FyeSBmbGFnIHRvIHByZXZlbnQgaW5maW5pdGUgbG9vcCB3aGVuIHlvdSBhcmUgcmVzdG9yaW5nIGEgVkFTVCBhZC5cbiAgICAgKiBAcmV0dXJucyB7cGxheWVyfVxuICAgICAqL1xuICAgIHZhciBvcmlnUGxheSA9IHBsYXllci5wbGF5O1xuICAgIHBsYXllci5wbGF5ID0gZnVuY3Rpb24gKGNhbGxPcmlnUGxheSkge1xuICAgICAgdmFyIHRoYXQgPSB0aGlzO1xuXG4gICAgICBpZiAoaXNGaXJzdFBsYXkoKSkge1xuICAgICAgICBmaXJzdFBsYXkoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VtZShjYWxsT3JpZ1BsYXkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcblxuICAgICAgLyoqKiBsb2NhbCBmdW5jdGlvbnMgKioqL1xuICAgICAgZnVuY3Rpb24gZmlyc3RQbGF5KCkge1xuICAgICAgICBpZiAoIXV0aWxpdGllcy5pc0lQaG9uZSgpKSB7XG4gICAgICAgICAgdm9sdW1lU25hcHNob3QgPSBzYXZlVm9sdW1lU25hcHNob3QoKTtcbiAgICAgICAgICBwbGF5ZXIubXV0ZWQodHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBvcmlnUGxheS5hcHBseSh0aGF0LCBhcmd1bWVudHMpO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiByZXN1bWUoY2FsbE9yaWdQbGF5KSB7XG4gICAgICAgIGlmIChpc0FkUGxheWluZygpICYmICFjYWxsT3JpZ1BsYXkpIHtcbiAgICAgICAgICBwbGF5ZXIudmFzdC5hZFVuaXQucmVzdW1lQWQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvcmlnUGxheS5hcHBseSh0aGF0LCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuXG4gICAgLyoqXG4gICAgICogTmVlZGVkIG1vbmtleSBwYXRjaCB0byBoYW5kbGUgcGF1c2Ugb2YgcGxheWluZyBhZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBjYWxsT3JpZ1BsYXkgbmVjZXNzYXJ5IGZsYWcgdG8gcHJldmVudCBpbmZpbml0ZSBsb29wIHdoZW4geW91IGFyZSBwYXVzaW5nIGEgVkFTVCBhZC5cbiAgICAgKiBAcmV0dXJucyB7cGxheWVyfVxuICAgICAqL1xuICAgIHZhciBvcmlnUGF1c2UgPSBwbGF5ZXIucGF1c2U7XG4gICAgcGxheWVyLnBhdXNlID0gZnVuY3Rpb24gKGNhbGxPcmlnUGF1c2UpIHtcbiAgICAgIGlmIChpc0FkUGxheWluZygpICYmICFjYWxsT3JpZ1BhdXNlKSB7XG4gICAgICAgIHBsYXllci52YXN0LmFkVW5pdC5wYXVzZUFkKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcmlnUGF1c2UuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cblxuICAgIC8qKlxuICAgICAqIE5lZWRlZCBtb25rZXkgcGF0Y2ggdG8gaGFuZGxlIHBhdXNlZCBzdGF0ZSBvZiB0aGUgcGxheWVyIHdoZW4gYWRzIGFyZSBwbGF5aW5nLlxuICAgICAqXG4gICAgICogQHBhcmFtIGNhbGxPcmlnUGxheSBuZWNlc3NhcnkgZmxhZyB0byBwcmV2ZW50IGluZmluaXRlIGxvb3Agd2hlbiB5b3UgYXJlIHBhdXNpbmcgYSBWQVNUIGFkLlxuICAgICAqIEByZXR1cm5zIHtwbGF5ZXJ9XG4gICAgICovXG4gICAgdmFyIG9yaWdQYXVzZWQgPSBwbGF5ZXIucGF1c2VkO1xuICAgIHBsYXllci5wYXVzZWQgPSBmdW5jdGlvbiAoY2FsbE9yaWdQYXVzZWQpIHtcbiAgICAgIGlmIChpc0FkUGxheWluZygpICYmICFjYWxsT3JpZ1BhdXNlZCkge1xuICAgICAgICByZXR1cm4gcGxheWVyLnZhc3QuYWRVbml0LmlzUGF1c2VkKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gb3JpZ1BhdXNlZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBpc0FkUGxheWluZygpIHtcbiAgICByZXR1cm4gcGxheWVyLnZhc3QgJiYgcGxheWVyLnZhc3QuYWRVbml0O1xuICB9XG5cbiAgZnVuY3Rpb24gdHJ5VG9UcmlnZ2VyRmlyc3RQbGF5KCkge1xuICAgIGlmIChpc0ZpcnN0UGxheSgpKSB7XG4gICAgICBfZmlyc3RQbGF5ID0gZmFsc2U7XG4gICAgICBwbGF5ZXIudHJpZ2dlcigndmFzdC5maXJzdFBsYXknKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZXNldEZpcnN0UGxheSgpIHtcbiAgICBfZmlyc3RQbGF5ID0gdHJ1ZTtcbiAgICBibGFja1Bvc3Rlci5zaG93KCk7XG4gICAgcmVzdG9yZUNvbnRlbnRWb2x1bWUoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzRmlyc3RQbGF5KCkge1xuICAgIHJldHVybiBfZmlyc3RQbGF5O1xuICB9XG5cbiAgZnVuY3Rpb24gc2F2ZVZvbHVtZVNuYXBzaG90KCkge1xuICAgIHJldHVybiB7XG4gICAgICBtdXRlZDogcGxheWVyLm11dGVkKCksXG4gICAgICB2b2x1bWU6IHBsYXllci52b2x1bWUoKVxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiByZXN0b3JlQ29udGVudFZvbHVtZSgpIHtcbiAgICBpZiAodm9sdW1lU25hcHNob3QpIHtcbiAgICAgIHBsYXllci5jdXJyZW50VGltZSgwKTtcbiAgICAgIHJlc3RvcmVWb2x1bWVTbmFwc2hvdCh2b2x1bWVTbmFwc2hvdCk7XG4gICAgICB2b2x1bWVTbmFwc2hvdCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVzdG9yZVZvbHVtZVNuYXBzaG90KHNuYXBzaG90KSB7XG4gICAgaWYgKHV0aWxpdGllcy5pc09iamVjdChzbmFwc2hvdCkpIHtcbiAgICAgIHBsYXllci52b2x1bWUoc25hcHNob3Qudm9sdW1lKTtcbiAgICAgIHBsYXllci5tdXRlZChzbmFwc2hvdC5tdXRlZCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaGlkZUJsYWNrUG9zdGVyKCkge1xuICAgIGlmICghZG9tLmhhc0NsYXNzKGJsYWNrUG9zdGVyLmVsKCksICd2anMtaGlkZGVuJykpIHtcbiAgICAgIGJsYWNrUG9zdGVyLmhpZGUoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBhZGRTdHlsZXMoKSB7XG4gICAgZG9tLmFkZENsYXNzKHBsYXllci5lbCgpLCAndmpzLWFkLXBsYXlpbmcnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbW92ZVN0eWxlcygpIHtcbiAgICBkb20ucmVtb3ZlQ2xhc3MocGxheWVyLmVsKCksICd2anMtYWQtcGxheWluZycpO1xuICB9XG59O1xuXG4vKipcbiAqIFJlbW92ZSB0aGUgcG9zdGVyIGF0dHJpYnV0ZSBmcm9tIHRoZSB2aWRlbyBlbGVtZW50IHRlY2gsIGlmIHByZXNlbnQuIFdoZW5cbiAqIHJldXNpbmcgYSB2aWRlbyBlbGVtZW50IGZvciBtdWx0aXBsZSB2aWRlb3MsIHRoZSBwb3N0ZXIgaW1hZ2Ugd2lsbCBicmllZmx5XG4gKiByZWFwcGVhciB3aGlsZSB0aGUgbmV3IHNvdXJjZSBsb2Fkcy4gUmVtb3ZpbmcgdGhlIGF0dHJpYnV0ZSBhaGVhZCBvZiB0aW1lXG4gKiBwcmV2ZW50cyB0aGUgcG9zdGVyIGZyb20gc2hvd2luZyB1cCBiZXR3ZWVuIHZpZGVvcy5cbiAqIEBwYXJhbSB7b2JqZWN0fSBwbGF5ZXIgVGhlIHZpZGVvanMgcGxheWVyIG9iamVjdFxuICovXG5wbGF5ZXJVdGlscy5yZW1vdmVOYXRpdmVQb3N0ZXIgPSBmdW5jdGlvbiAocGxheWVyKSB7XG4gIHZhciB0ZWNoID0gcGxheWVyLmVsKCkucXVlcnlTZWxlY3RvcignLnZqcy10ZWNoJyk7XG4gIGlmICh0ZWNoKSB7XG4gICAgdGVjaC5yZW1vdmVBdHRyaWJ1dGUoJ3Bvc3RlcicpO1xuICB9XG59O1xuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBsaXN0ZW4gdG8gbWFueSBldmVudHMgdW50aWwgb25lIG9mIHRoZW0gZ2V0cyBmaXJlZCwgdGhlbiB3ZVxuICogZXhlY3V0ZSB0aGUgaGFuZGxlciBhbmQgdW5zdWJzY3JpYmUgYWxsIHRoZSBldmVudCBsaXN0ZW5lcnM7XG4gKlxuICogQHBhcmFtIHBsYXllciBzcGVjaWZpYyBwbGF5ZXIgZnJvbSB3aGVyZSB0byBsaXN0ZW4gZm9yIHRoZSBldmVudHNcbiAqIEBwYXJhbSBldmVudHMgYXJyYXkgb2YgZXZlbnRzXG4gKiBAcGFyYW0gaGFuZGxlciBmdW5jdGlvbiB0byBleGVjdXRlIG9uY2Ugb25lIG9mIHRoZSBldmVudHMgZmlyZXNcbiAqL1xucGxheWVyVXRpbHMub25jZSA9IGZ1bmN0aW9uIG9uY2UocGxheWVyLCBldmVudHMsIGhhbmRsZXIpIHtcbiAgZnVuY3Rpb24gbGlzdGVuZXIoKSB7XG4gICAgaGFuZGxlci5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuXG4gICAgZXZlbnRzLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICBwbGF5ZXIub2ZmKGV2ZW50LCBsaXN0ZW5lcik7XG4gICAgfSk7XG4gIH1cblxuICBldmVudHMuZm9yRWFjaChmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICBwbGF5ZXIub24oZXZlbnQsIGxpc3RlbmVyKTtcbiAgfSk7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gcGxheWVyVXRpbHM7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbi8qKlxuICpcbiAqIElNUE9SVEFOVCBOT1RFOiBUaGlzIGZ1bmN0aW9uIGNvbWVzIGZyb20gYW5ndWxhckpzIGFuZCB3YXMgb3JpZ2luYWxseSBjYWxsZWQgdXJsUmVzb2x2ZVxuICogICAgICAgICAgICAgICAgIHlvdSBjYW4gdGFrZSBhIGxvb2sgYXQgdGhlIG9yaWdpbmFsIGNvZGUgaGVyZSBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyLmpzL2Jsb2IvbWFzdGVyL3NyYy9uZy91cmxVdGlscy5qc1xuICpcbiAqIEltcGxlbWVudGF0aW9uIE5vdGVzIGZvciBub24tSUUgYnJvd3NlcnNcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEFzc2lnbmluZyBhIFVSTCB0byB0aGUgaHJlZiBwcm9wZXJ0eSBvZiBhbiBhbmNob3IgRE9NIG5vZGUsIGV2ZW4gb25lIGF0dGFjaGVkIHRvIHRoZSBET00sXG4gKiByZXN1bHRzIGJvdGggaW4gdGhlIG5vcm1hbGl6aW5nIGFuZCBwYXJzaW5nIG9mIHRoZSBVUkwuICBOb3JtYWxpemluZyBtZWFucyB0aGF0IGEgcmVsYXRpdmVcbiAqIFVSTCB3aWxsIGJlIHJlc29sdmVkIGludG8gYW4gYWJzb2x1dGUgVVJMIGluIHRoZSBjb250ZXh0IG9mIHRoZSBhcHBsaWNhdGlvbiBkb2N1bWVudC5cbiAqIFBhcnNpbmcgbWVhbnMgdGhhdCB0aGUgYW5jaG9yIG5vZGUncyBob3N0LCBob3N0bmFtZSwgcHJvdG9jb2wsIHBvcnQsIHBhdGhuYW1lIGFuZCByZWxhdGVkXG4gKiBwcm9wZXJ0aWVzIGFyZSBhbGwgcG9wdWxhdGVkIHRvIHJlZmxlY3QgdGhlIG5vcm1hbGl6ZWQgVVJMLiAgVGhpcyBhcHByb2FjaCBoYXMgd2lkZVxuICogY29tcGF0aWJpbGl0eSAtIFNhZmFyaSAxKywgTW96aWxsYSAxKywgT3BlcmEgNyssZSBldGMuICBTZWVcbiAqIGh0dHA6Ly93d3cuYXB0YW5hLmNvbS9yZWZlcmVuY2UvaHRtbC9hcGkvSFRNTEFuY2hvckVsZW1lbnQuaHRtbFxuICpcbiAqIEltcGxlbWVudGF0aW9uIE5vdGVzIGZvciBJRVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBJRSA+PSA4IGFuZCA8PSAxMCBub3JtYWxpemVzIHRoZSBVUkwgd2hlbiBhc3NpZ25lZCB0byB0aGUgYW5jaG9yIG5vZGUgc2ltaWxhciB0byB0aGUgb3RoZXJcbiAqIGJyb3dzZXJzLiAgSG93ZXZlciwgdGhlIHBhcnNlZCBjb21wb25lbnRzIHdpbGwgbm90IGJlIHNldCBpZiB0aGUgVVJMIGFzc2lnbmVkIGRpZCBub3Qgc3BlY2lmeVxuICogdGhlbS4gIChlLmcuIGlmIHlvdSBhc3NpZ24gYS5ocmVmID0gXCJmb29cIiwgdGhlbiBhLnByb3RvY29sLCBhLmhvc3QsIGV0Yy4gd2lsbCBiZSBlbXB0eS4pICBXZVxuICogd29yayBhcm91bmQgdGhhdCBieSBwZXJmb3JtaW5nIHRoZSBwYXJzaW5nIGluIGEgMm5kIHN0ZXAgYnkgdGFraW5nIGEgcHJldmlvdXNseSBub3JtYWxpemVkXG4gKiBVUkwgKGUuZy4gYnkgYXNzaWduaW5nIHRvIGEuaHJlZikgYW5kIGFzc2lnbmluZyBpdCBhLmhyZWYgYWdhaW4uICBUaGlzIGNvcnJlY3RseSBwb3B1bGF0ZXMgdGhlXG4gKiBwcm9wZXJ0aWVzIHN1Y2ggYXMgcHJvdG9jb2wsIGhvc3RuYW1lLCBwb3J0LCBldGMuXG4gKlxuICogSUU3IGRvZXMgbm90IG5vcm1hbGl6ZSB0aGUgVVJMIHdoZW4gYXNzaWduZWQgdG8gYW4gYW5jaG9yIG5vZGUuICAoQXBwYXJlbnRseSwgaXQgZG9lcywgaWYgb25lXG4gKiB1c2VzIHRoZSBpbm5lciBIVE1MIGFwcHJvYWNoIHRvIGFzc2lnbiB0aGUgVVJMIGFzIHBhcnQgb2YgYW4gSFRNTCBzbmlwcGV0IC1cbiAqIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzQ3MjcyOSkgIEhvd2V2ZXIsIHNldHRpbmcgaW1nW3NyY10gZG9lcyBub3JtYWxpemUgdGhlIFVSTC5cbiAqIFVuZm9ydHVuYXRlbHksIHNldHRpbmcgaW1nW3NyY10gdG8gc29tZXRoaW5nIGxpa2UgXCJqYXZhc2NyaXB0OmZvb1wiIG9uIElFIHRocm93cyBhbiBleGNlcHRpb24uXG4gKiBTaW5jZSB0aGUgcHJpbWFyeSB1c2FnZSBmb3Igbm9ybWFsaXppbmcgVVJMcyBpcyB0byBzYW5pdGl6ZSBzdWNoIFVSTHMsIHdlIGNhbid0IHVzZSB0aGF0XG4gKiBtZXRob2QgYW5kIElFIDwgOCBpcyB1bnN1cHBvcnRlZC5cbiAqXG4gKiBSZWZlcmVuY2VzOlxuICogICBodHRwOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9IVE1MQW5jaG9yRWxlbWVudFxuICogICBodHRwOi8vd3d3LmFwdGFuYS5jb20vcmVmZXJlbmNlL2h0bWwvYXBpL0hUTUxBbmNob3JFbGVtZW50Lmh0bWxcbiAqICAgaHR0cDovL3VybC5zcGVjLndoYXR3Zy5vcmcvI3VybHV0aWxzXG4gKiAgIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2FuZ3VsYXIuanMvcHVsbC8yOTAyXG4gKiAgIGh0dHA6Ly9qYW1lcy5wYWRvbHNleS5jb20vamF2YXNjcmlwdC9wYXJzaW5nLXVybHMtd2l0aC10aGUtZG9tL1xuICpcbiAqIEBraW5kIGZ1bmN0aW9uXG4gKiBAcGFyYW0ge3N0cmluZ30gdXJsIFRoZSBVUkwgdG8gYmUgcGFyc2VkLlxuICogQGRlc2NyaXB0aW9uIE5vcm1hbGl6ZXMgYW5kIHBhcnNlcyBhIFVSTC5cbiAqIEByZXR1cm5zIHtvYmplY3R9IFJldHVybnMgdGhlIG5vcm1hbGl6ZWQgVVJMIGFzIGEgZGljdGlvbmFyeS5cbiAqXG4gKiAgIHwgbWVtYmVyIG5hbWUgICB8IERlc2NyaXB0aW9uICAgIHxcbiAqICAgfC0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tfFxuICogICB8IGhyZWYgICAgICAgICAgfCBBIG5vcm1hbGl6ZWQgdmVyc2lvbiBvZiB0aGUgcHJvdmlkZWQgVVJMIGlmIGl0IHdhcyBub3QgYW4gYWJzb2x1dGUgVVJMIHxcbiAqICAgfCBwcm90b2NvbCAgICAgIHwgVGhlIHByb3RvY29sIGluY2x1ZGluZyB0aGUgdHJhaWxpbmcgY29sb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgIHwgaG9zdCAgICAgICAgICB8IFRoZSBob3N0IGFuZCBwb3J0IChpZiB0aGUgcG9ydCBpcyBub24tZGVmYXVsdCkgb2YgdGhlIG5vcm1hbGl6ZWRVcmwgICAgfFxuICogICB8IHNlYXJjaCAgICAgICAgfCBUaGUgc2VhcmNoIHBhcmFtcywgbWludXMgdGhlIHF1ZXN0aW9uIG1hcmsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICAgfCBoYXNoICAgICAgICAgIHwgVGhlIGhhc2ggc3RyaW5nLCBtaW51cyB0aGUgaGFzaCBzeW1ib2xcbiAqICAgfCBob3N0bmFtZSAgICAgIHwgVGhlIGhvc3RuYW1lXG4gKiAgIHwgcG9ydCAgICAgICAgICB8IFRoZSBwb3J0LCB3aXRob3V0IFwiOlwiXG4gKiAgIHwgcGF0aG5hbWUgICAgICB8IFRoZSBwYXRobmFtZSwgYmVnaW5uaW5nIHdpdGggXCIvXCJcbiAqXG4gKi9cblxudmFyIHVybFBhcnNpbmdOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImFcIik7XG4vKipcbiAqIGRvY3VtZW50TW9kZSBpcyBhbiBJRS1vbmx5IHByb3BlcnR5XG4gKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaWUvY2MxOTY5ODgodj12cy44NSkuYXNweFxuICovXG52YXIgbXNpZSA9IGRvY3VtZW50LmRvY3VtZW50TW9kZTtcblxuZnVuY3Rpb24gdXJsUGFydHModXJsKSB7XG4gIHZhciBocmVmID0gdXJsO1xuXG4gIGlmIChtc2llKSB7XG4gICAgLy8gTm9ybWFsaXplIGJlZm9yZSBwYXJzZS4gIFJlZmVyIEltcGxlbWVudGF0aW9uIE5vdGVzIG9uIHdoeSB0aGlzIGlzXG4gICAgLy8gZG9uZSBpbiB0d28gc3RlcHMgb24gSUUuXG4gICAgdXJsUGFyc2luZ05vZGUuc2V0QXR0cmlidXRlKFwiaHJlZlwiLCBocmVmKTtcbiAgICBocmVmID0gdXJsUGFyc2luZ05vZGUuaHJlZjtcbiAgfVxuXG4gIHVybFBhcnNpbmdOb2RlLnNldEF0dHJpYnV0ZSgnaHJlZicsIGhyZWYpO1xuXG4gIC8vIHVybFBhcnNpbmdOb2RlIHByb3ZpZGVzIHRoZSBVcmxVdGlscyBpbnRlcmZhY2UgLSBodHRwOi8vdXJsLnNwZWMud2hhdHdnLm9yZy8jdXJsdXRpbHNcbiAgcmV0dXJuIHtcbiAgICBocmVmOiB1cmxQYXJzaW5nTm9kZS5ocmVmLFxuICAgIHByb3RvY29sOiB1cmxQYXJzaW5nTm9kZS5wcm90b2NvbCA/IHVybFBhcnNpbmdOb2RlLnByb3RvY29sLnJlcGxhY2UoLzokLywgJycpIDogJycsXG4gICAgaG9zdDogdXJsUGFyc2luZ05vZGUuaG9zdCxcbiAgICBzZWFyY2g6IHVybFBhcnNpbmdOb2RlLnNlYXJjaCA/IHVybFBhcnNpbmdOb2RlLnNlYXJjaC5yZXBsYWNlKC9eXFw/LywgJycpIDogJycsXG4gICAgaGFzaDogdXJsUGFyc2luZ05vZGUuaGFzaCA/IHVybFBhcnNpbmdOb2RlLmhhc2gucmVwbGFjZSgvXiMvLCAnJykgOiAnJyxcbiAgICBob3N0bmFtZTogdXJsUGFyc2luZ05vZGUuaG9zdG5hbWUsXG4gICAgcG9ydDogdXRpbGl0aWVzLmlzTm90RW1wdHlTdHJpbmcodXJsUGFyc2luZ05vZGUucG9ydCk/IHVybFBhcnNpbmdOb2RlLnBvcnQ6IDgwLFxuICAgIHBhdGhuYW1lOiAodXJsUGFyc2luZ05vZGUucGF0aG5hbWUuY2hhckF0KDApID09PSAnLycpXG4gICAgICA/IHVybFBhcnNpbmdOb2RlLnBhdGhuYW1lXG4gICAgICA6ICcvJyArIHVybFBhcnNpbmdOb2RlLnBhdGhuYW1lXG4gIH07XG59XG5cblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGFjY2VwdHMgYSBxdWVyeSBzdHJpbmcgKHNlYXJjaCBwYXJ0IG9mIGEgdXJsKSBhbmQgcmV0dXJucyBhIGRpY3Rpb25hcnkgd2l0aFxuICogdGhlIGRpZmZlcmVudCBrZXkgdmFsdWUgcGFpcnNcbiAqIEBwYXJhbSB7c3RyaW5nfSBxcyBxdWVyeVN0cmluZ1xuICovXG5mdW5jdGlvbiBxdWVyeVN0cmluZ1RvT2JqKHFzLCBjb25kKSB7XG4gIHZhciBwYWlycywgcXNPYmo7XG5cbiAgY29uZCA9IHV0aWxpdGllcy5pc0Z1bmN0aW9uKGNvbmQpPyBjb25kIDogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgcXMgPSBxcy50cmltKCkucmVwbGFjZSgvXlxcPy8sICcnKTtcbiAgcGFpcnMgPSBxcy5zcGxpdCgnJicpO1xuICBxc09iaiA9IHt9O1xuXG4gIHV0aWxpdGllcy5mb3JFYWNoKHBhaXJzLCBmdW5jdGlvbiAocGFpcikge1xuICAgIHZhciBrZXlWYWx1ZSwga2V5LCB2YWx1ZTtcbiAgICBpZiAocGFpciAhPT0gJycpIHtcbiAgICAgIGtleVZhbHVlID0gcGFpci5zcGxpdCgnPScpO1xuICAgICAga2V5ID0ga2V5VmFsdWVbMF07XG4gICAgICB2YWx1ZSA9IGtleVZhbHVlWzFdO1xuICAgICAgaWYoY29uZChrZXksIHZhbHVlKSl7XG4gICAgICAgIHFzT2JqW2tleV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBxc09iajtcbn1cblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGFjY2VwdHMgYW4gb2JqZWN0IGFuZCBzZXJpYWxpemVzIGl0IGludG8gYSBxdWVyeSBzdHJpbmcgd2l0aG91dCB0aGUgbGVhZGluZyAnPydcbiAqIEBwYXJhbSBvYmpcbiAqIEByZXR1cm5zIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIG9ialRvUXVlcnlTdHJpbmcob2JqKSB7XG4gIHZhciBwYWlycyA9IFtdO1xuICB1dGlsaXRpZXMuZm9yRWFjaChvYmosIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgcGFpcnMucHVzaChrZXkgKyAnPScgKyB2YWx1ZSk7XG4gIH0pO1xuICByZXR1cm4gcGFpcnMuam9pbignJicpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdXJsUGFydHM6IHVybFBhcnRzLFxuICBxdWVyeVN0cmluZ1RvT2JqOiBxdWVyeVN0cmluZ1RvT2JqLFxuICBvYmpUb1F1ZXJ5U3RyaW5nOiBvYmpUb1F1ZXJ5U3RyaW5nXG59O1xuIiwiLypqc2hpbnQgdW51c2VkOmZhbHNlICovXG5cInVzZSBzdHJpY3RcIjtcblxudmFyIE5PREVfVFlQRV9FTEVNRU5UID0gMTtcbnZhciBTTkFLRV9DQVNFX1JFR0VYUCA9IC9bQS1aXS9nO1xudmFyIEVNQUlMX1JFR0VYUCA9IC9eW2EtejAtOSEjJCUmJyorXFwvPT9eX2B7fH1+Li1dK0BbYS16MC05XShbYS16MC05LV0qW2EtejAtOV0pPyhcXC5bYS16MC05XShbYS16MC05LV0qW2EtejAtOV0pPykrJC9pO1xuLypqc2xpbnQgbWF4bGVuOiA1MDAgKi9cbnZhciBJU084MDg2X1JFR0VYUCA9IC9eKFtcXCstXT9cXGR7NH0oPyFcXGR7Mn1cXGIpKSgoLT8pKCgwWzEtOV18MVswLTJdKShcXDMoWzEyXVxcZHwwWzEtOV18M1swMV0pKT98VyhbMC00XVxcZHw1WzAtMl0pKC0/WzEtN10pP3woMDBbMS05XXwwWzEtOV1cXGR8WzEyXVxcZHsyfXwzKFswLTVdXFxkfDZbMS02XSkpKShbVFxcc10oKChbMDFdXFxkfDJbMC0zXSkoKDo/KVswLTVdXFxkKT98MjRcXDo/MDApKFtcXC4sXVxcZCsoPyE6KSk/KT8oXFwxN1swLTVdXFxkKFtcXC4sXVxcZCspPyk/KFt6Wl18KFtcXCstXSkoWzAxXVxcZHwyWzAtM10pOj8oWzAtNV1cXGQpPyk/KT8pPyQvO1xuXG5cbmZ1bmN0aW9uIG5vb3AoKXsgfVxuXG5mdW5jdGlvbiBpc051bGwobykge1xuICByZXR1cm4gbyA9PT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNEZWZpbmVkKG8pe1xuICByZXR1cm4gbyAhPT0gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChvKXtcbiAgcmV0dXJuIG8gPT09IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gaXNPYmplY3Qob2JqKSB7XG4gIHJldHVybiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jztcbn1cblxuZnVuY3Rpb24gaXNGdW5jdGlvbihzdHIpe1xuICByZXR1cm4gdHlwZW9mIHN0ciA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuZnVuY3Rpb24gaXNOdW1iZXIobnVtKXtcbiAgcmV0dXJuIHR5cGVvZiBudW0gPT09ICdudW1iZXInO1xufVxuXG5mdW5jdGlvbiBpc1dpbmRvdyhvYmopIHtcbiAgcmV0dXJuIHV0aWxpdGllcy5pc09iamVjdChvYmopICYmIG9iai53aW5kb3cgPT09IG9iajtcbn1cblxuZnVuY3Rpb24gaXNBcnJheShhcnJheSl7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoIGFycmF5ICkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXlMaWtlKG9iaikge1xuICBpZiAob2JqID09PSBudWxsIHx8IHV0aWxpdGllcy5pc1dpbmRvdyhvYmopIHx8IHV0aWxpdGllcy5pc0Z1bmN0aW9uKG9iaikgfHwgdXRpbGl0aWVzLmlzVW5kZWZpbmVkKG9iaikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgbGVuZ3RoID0gb2JqLmxlbmd0aDtcblxuICBpZiAob2JqLm5vZGVUeXBlID09PSBOT0RFX1RZUEVfRUxFTUVOVCAmJiBsZW5ndGgpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiB1dGlsaXRpZXMuaXNTdHJpbmcob2JqKSB8fCB1dGlsaXRpZXMuaXNBcnJheShvYmopIHx8IGxlbmd0aCA9PT0gMCB8fFxuICAgIHR5cGVvZiBsZW5ndGggPT09ICdudW1iZXInICYmIGxlbmd0aCA+IDAgJiYgKGxlbmd0aCAtIDEpIGluIG9iajtcbn1cblxuZnVuY3Rpb24gaXNTdHJpbmcoc3RyKXtcbiAgcmV0dXJuIHR5cGVvZiBzdHIgPT09ICdzdHJpbmcnO1xufVxuXG5mdW5jdGlvbiBpc0VtcHR5U3RyaW5nKHN0cikge1xuICByZXR1cm4gdXRpbGl0aWVzLmlzU3RyaW5nKHN0cikgJiYgc3RyLmxlbmd0aCA9PT0gMDtcbn1cblxuZnVuY3Rpb24gaXNOb3RFbXB0eVN0cmluZyhzdHIpIHtcbiAgcmV0dXJuIHV0aWxpdGllcy5pc1N0cmluZyhzdHIpICYmIHN0ci5sZW5ndGggIT09IDA7XG59XG5cbmZ1bmN0aW9uIGFycmF5TGlrZU9ialRvQXJyYXkoYXJncykge1xuICByZXR1cm4gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJncyk7XG59XG5cbmZ1bmN0aW9uIGZvckVhY2gob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICB2YXIga2V5LCBsZW5ndGg7XG4gIGlmIChvYmopIHtcbiAgICBpZiAoaXNGdW5jdGlvbihvYmopKSB7XG4gICAgICBmb3IgKGtleSBpbiBvYmopIHtcbiAgICAgICAgLy8gTmVlZCB0byBjaGVjayBpZiBoYXNPd25Qcm9wZXJ0eSBleGlzdHMsXG4gICAgICAgIC8vIGFzIG9uIElFOCB0aGUgcmVzdWx0IG9mIHF1ZXJ5U2VsZWN0b3JBbGwgaXMgYW4gb2JqZWN0IHdpdGhvdXQgYSBoYXNPd25Qcm9wZXJ0eSBmdW5jdGlvblxuICAgICAgICBpZiAoa2V5ICE9PSAncHJvdG90eXBlJyAmJiBrZXkgIT09ICdsZW5ndGgnICYmIGtleSAhPT0gJ25hbWUnICYmICghb2JqLmhhc093blByb3BlcnR5IHx8IG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSkge1xuICAgICAgICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgb2JqW2tleV0sIGtleSwgb2JqKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNBcnJheShvYmopKSB7XG4gICAgICB2YXIgaXNQcmltaXRpdmUgPSB0eXBlb2Ygb2JqICE9PSAnb2JqZWN0JztcbiAgICAgIGZvciAoa2V5ID0gMCwgbGVuZ3RoID0gb2JqLmxlbmd0aDsga2V5IDwgbGVuZ3RoOyBrZXkrKykge1xuICAgICAgICBpZiAoaXNQcmltaXRpdmUgfHwga2V5IGluIG9iaikge1xuICAgICAgICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgb2JqW2tleV0sIGtleSwgb2JqKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAob2JqLmZvckVhY2ggJiYgb2JqLmZvckVhY2ggIT09IGZvckVhY2gpIHtcbiAgICAgIG9iai5mb3JFYWNoKGl0ZXJhdG9yLCBjb250ZXh0LCBvYmopO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGtleSBpbiBvYmopIHtcbiAgICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgaXRlcmF0b3IuY2FsbChjb250ZXh0LCBvYmpba2V5XSwga2V5LCBvYmopO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBvYmo7XG59XG5cbmZ1bmN0aW9uIHNuYWtlX2Nhc2UobmFtZSwgc2VwYXJhdG9yKSB7XG4gIHNlcGFyYXRvciA9IHNlcGFyYXRvciB8fCAnXyc7XG4gIHJldHVybiBuYW1lLnJlcGxhY2UoU05BS0VfQ0FTRV9SRUdFWFAsIGZ1bmN0aW9uKGxldHRlciwgcG9zKSB7XG4gICAgcmV0dXJuIChwb3MgPyBzZXBhcmF0b3IgOiAnJykgKyBsZXR0ZXIudG9Mb3dlckNhc2UoKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGlzVmFsaWRFbWFpbChlbWFpbCl7XG4gIGlmKCF1dGlsaXRpZXMuaXNTdHJpbmcoZW1haWwpKXtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gRU1BSUxfUkVHRVhQLnRlc3QoZW1haWwudHJpbSgpKTtcbn1cblxuZnVuY3Rpb24gZXh0ZW5kIChvYmopIHtcbiAgdmFyIGFyZywgaSwgaztcbiAgZm9yIChpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIGFyZyA9IGFyZ3VtZW50c1tpXTtcbiAgICBmb3IgKGsgaW4gYXJnKSB7XG4gICAgICBpZiAoYXJnLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgIGlmKGlzT2JqZWN0KG9ialtrXSkgJiYgIWlzTnVsbChvYmpba10pICYmIGlzT2JqZWN0KGFyZ1trXSkpe1xuICAgICAgICAgIG9ialtrXSA9IGV4dGVuZCh7fSwgb2JqW2tdLCBhcmdba10pO1xuICAgICAgICB9ZWxzZSB7XG4gICAgICAgICAgb2JqW2tdID0gYXJnW2tdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBvYmo7XG59XG5cbmZ1bmN0aW9uIGNhcGl0YWxpemUocyl7XG4gIHJldHVybiBzLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgcy5zbGljZSgxKTtcbn1cblxuZnVuY3Rpb24gZGVjYXBpdGFsaXplKHMpIHtcbiAgcmV0dXJuIHMuY2hhckF0KDApLnRvTG93ZXJDYXNlKCkgKyBzLnNsaWNlKDEpO1xufVxuXG4vKipcbiAqIFRoaXMgbWV0aG9kIHdvcmtzIHRoZSBzYW1lIHdheSBhcnJheS5wcm90b3R5cGUubWFwIHdvcmtzIGJ1dCBpZiB0aGUgdHJhbnNmb3JtZXIgcmV0dXJucyB1bmRlZmluZSwgdGhlblxuICogaXQgd29uJ3QgYmUgYWRkZWQgdG8gdGhlIHRyYW5zZm9ybWVkIEFycmF5LlxuICovXG5mdW5jdGlvbiB0cmFuc2Zvcm1BcnJheShhcnJheSwgdHJhbnNmb3JtZXIpIHtcbiAgdmFyIHRyYW5zZm9ybWVkQXJyYXkgPSBbXTtcblxuICBhcnJheS5mb3JFYWNoKGZ1bmN0aW9uKGl0ZW0sIGluZGV4KXtcbiAgICB2YXIgdHJhbnNmb3JtZWRJdGVtID0gdHJhbnNmb3JtZXIoaXRlbSwgaW5kZXgpO1xuICAgIGlmKHV0aWxpdGllcy5pc0RlZmluZWQodHJhbnNmb3JtZWRJdGVtKSkge1xuICAgICAgdHJhbnNmb3JtZWRBcnJheS5wdXNoKHRyYW5zZm9ybWVkSXRlbSk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gdHJhbnNmb3JtZWRBcnJheTtcbn1cblxuZnVuY3Rpb24gdG9GaXhlZERpZ2l0cyhudW0sIGRpZ2l0cykge1xuICB2YXIgZm9ybWF0dGVkTnVtID0gbnVtICsgJyc7XG4gIGRpZ2l0cyA9IHV0aWxpdGllcy5pc051bWJlcihkaWdpdHMpID8gZGlnaXRzIDogMDtcbiAgbnVtID0gdXRpbGl0aWVzLmlzTnVtYmVyKG51bSkgPyBudW0gOiBwYXJzZUludChudW0sIDEwKTtcbiAgaWYodXRpbGl0aWVzLmlzTnVtYmVyKG51bSkgJiYgIWlzTmFOKG51bSkpe1xuICAgIGZvcm1hdHRlZE51bSA9IG51bSArICcnO1xuICAgIHdoaWxlKGZvcm1hdHRlZE51bS5sZW5ndGggPCBkaWdpdHMpIHtcbiAgICAgIGZvcm1hdHRlZE51bSA9ICcwJyArIGZvcm1hdHRlZE51bTtcbiAgICB9XG4gICAgcmV0dXJuIGZvcm1hdHRlZE51bTtcbiAgfVxuICByZXR1cm4gTmFOICsgJyc7XG59XG5cbmZ1bmN0aW9uIHRocm90dGxlKGNhbGxiYWNrLCBkZWxheSkge1xuICB2YXIgcHJldmlvdXNDYWxsID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgLSAoZGVsYXkgKyAxKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciB0aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgaWYgKCh0aW1lIC0gcHJldmlvdXNDYWxsKSA+PSBkZWxheSkge1xuICAgICAgcHJldmlvdXNDYWxsID0gdGltZTtcbiAgICAgIGNhbGxiYWNrLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBkZWJvdW5jZSAoY2FsbGJhY2ssIHdhaXQpIHtcbiAgdmFyIHRpbWVvdXRJZDtcblxuICByZXR1cm4gZnVuY3Rpb24gKCl7XG4gICAgaWYodGltZW91dElkKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICB9XG4gICAgdGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbigpe1xuICAgICAgY2FsbGJhY2suYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIHRpbWVvdXRJZCA9IHVuZGVmaW5lZDtcbiAgICB9LCB3YWl0KTtcbiAgfTtcbn1cblxuLy8gYSBmdW5jdGlvbiBkZXNpZ25lZCB0byBibG93IHVwIHRoZSBzdGFjayBpbiBhIG5haXZlIHdheVxuLy8gYnV0IGl0IGlzIG9rIGZvciB2aWRlb0pzIGNoaWxkcmVuIGNvbXBvbmVudHNcbmZ1bmN0aW9uIHRyZWVTZWFyY2gocm9vdCwgZ2V0Q2hpbGRyZW4sIGZvdW5kKXtcbiAgdmFyIGNoaWxkcmVuID0gZ2V0Q2hpbGRyZW4ocm9vdCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspe1xuICAgIGlmIChmb3VuZChjaGlsZHJlbltpXSkpIHtcbiAgICAgIHJldHVybiBjaGlsZHJlbltpXTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB2YXIgZWwgPSB0cmVlU2VhcmNoKGNoaWxkcmVuW2ldLCBnZXRDaGlsZHJlbiwgZm91bmQpO1xuICAgICAgaWYgKGVsKXtcbiAgICAgICAgcmV0dXJuIGVsO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBlY2hvRm4odmFsKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHZhbDtcbiAgfTtcbn1cblxuLy9Ob3RlOiBTdXBwb3J0ZWQgZm9ybWF0cyBjb21lIGZyb20gaHR0cDovL3d3dy53My5vcmcvVFIvTk9URS1kYXRldGltZVxuLy8gYW5kIHRoZSBpc284NjAxIHJlZ2V4IGNvbWVzIGZyb20gaHR0cDovL3d3dy5wZWxhZ29kZXNpZ24uY29tL2Jsb2cvMjAwOS8wNS8yMC9pc28tODYwMS1kYXRlLXZhbGlkYXRpb24tdGhhdC1kb2VzbnQtc3Vjay9cbmZ1bmN0aW9uIGlzSVNPODYwMSh2YWx1ZSkge1xuICBpZih1dGlsaXRpZXMuaXNOdW1iZXIodmFsdWUpKXtcbiAgICB2YWx1ZSA9IHZhbHVlICsgJyc7ICAvL3dlIG1ha2Ugc3VyZSB0aGF0IHdlIGFyZSB3b3JraW5nIHdpdGggc3RyaW5nc1xuICB9XG5cbiAgaWYoIXV0aWxpdGllcy5pc1N0cmluZyh2YWx1ZSkpe1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBJU084MDg2X1JFR0VYUC50ZXN0KHZhbHVlLnRyaW0oKSk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBCcm93c2VyIGlzIElFOSBhbmQgYmVsb3dcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBpc09sZElFKCkge1xuICB2YXIgdmVyc2lvbiA9IHV0aWxpdGllcy5nZXRJbnRlcm5ldEV4cGxvcmVyVmVyc2lvbihuYXZpZ2F0b3IpO1xuICBpZiAodmVyc2lvbiA9PT0gLTEpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdmVyc2lvbiA8IDEwO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHZlcnNpb24gb2YgSW50ZXJuZXQgRXhwbG9yZXIgb3IgYSAtMSAoaW5kaWNhdGluZyB0aGUgdXNlIG9mIGFub3RoZXIgYnJvd3NlcikuXG4gKiBTb3VyY2U6IGh0dHBzOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvbXM1Mzc1MDkodj12cy44NSkuYXNweFxuICogQHJldHVybnMge251bWJlcn0gdGhlIHZlcnNpb24gb2YgSW50ZXJuZXQgRXhwbG9yZXIgb3IgYSAtMSAoaW5kaWNhdGluZyB0aGUgdXNlIG9mIGFub3RoZXIgYnJvd3NlcikuXG4gKi9cbmZ1bmN0aW9uIGdldEludGVybmV0RXhwbG9yZXJWZXJzaW9uKG5hdmlnYXRvcikge1xuICB2YXIgcnYgPSAtMTtcblxuICBpZiAobmF2aWdhdG9yLmFwcE5hbWUgPT0gJ01pY3Jvc29mdCBJbnRlcm5ldCBFeHBsb3JlcicpIHtcbiAgICB2YXIgdWEgPSBuYXZpZ2F0b3IudXNlckFnZW50O1xuICAgIHZhciByZSA9IG5ldyBSZWdFeHAoXCJNU0lFIChbMC05XXsxLH1bXFwuMC05XXswLH0pXCIpO1xuICAgIHZhciByZXMgPSByZS5leGVjKHVhKTtcbiAgICBpZiAocmVzICE9PSBudWxsKSB7XG4gICAgICBydiA9IHBhcnNlRmxvYXQocmVzWzFdKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcnY7XG59XG5cbi8qKiogTW9iaWxlIFV0aWxpdHkgZnVuY3Rpb25zICoqKi9cbmZ1bmN0aW9uIGlzSURldmljZSgpIHtcbiAgcmV0dXJuIC9pUChob25lfGFkKS8udGVzdCh1dGlsaXRpZXMuX1VBKTtcbn1cblxuZnVuY3Rpb24gaXNNb2JpbGUoKSB7XG4gIHJldHVybiAvaVAoaG9uZXxhZHxvZCl8QW5kcm9pZHxXaW5kb3dzIFBob25lLy50ZXN0KHV0aWxpdGllcy5fVUEpO1xufVxuXG5mdW5jdGlvbiBpc0lQaG9uZSgpIHtcbiAgcmV0dXJuIC9pUChob25lfG9kKS8udGVzdCh1dGlsaXRpZXMuX1VBKTtcbn1cblxuZnVuY3Rpb24gaXNBbmRyb2lkKCkge1xuICByZXR1cm4gL0FuZHJvaWQvLnRlc3QodXRpbGl0aWVzLl9VQSk7XG59XG5cbnZhciB1dGlsaXRpZXMgPSB7XG4gIF9VQTogbmF2aWdhdG9yLnVzZXJBZ2VudCxcbiAgbm9vcDogbm9vcCxcbiAgaXNOdWxsOiBpc051bGwsXG4gIGlzRGVmaW5lZDogaXNEZWZpbmVkLFxuICBpc1VuZGVmaW5lZDogaXNVbmRlZmluZWQsXG4gIGlzT2JqZWN0OiBpc09iamVjdCxcbiAgaXNGdW5jdGlvbjogaXNGdW5jdGlvbixcbiAgaXNOdW1iZXI6IGlzTnVtYmVyLFxuICBpc1dpbmRvdzogaXNXaW5kb3csXG4gIGlzQXJyYXk6IGlzQXJyYXksXG4gIGlzQXJyYXlMaWtlOiBpc0FycmF5TGlrZSxcbiAgaXNTdHJpbmc6IGlzU3RyaW5nLFxuICBpc0VtcHR5U3RyaW5nOiBpc0VtcHR5U3RyaW5nLFxuICBpc05vdEVtcHR5U3RyaW5nOiBpc05vdEVtcHR5U3RyaW5nLFxuICBhcnJheUxpa2VPYmpUb0FycmF5OiBhcnJheUxpa2VPYmpUb0FycmF5LFxuICBmb3JFYWNoOiBmb3JFYWNoLFxuICBzbmFrZV9jYXNlOiBzbmFrZV9jYXNlLFxuICBpc1ZhbGlkRW1haWw6IGlzVmFsaWRFbWFpbCxcbiAgZXh0ZW5kOiBleHRlbmQsXG4gIGNhcGl0YWxpemU6IGNhcGl0YWxpemUsXG4gIGRlY2FwaXRhbGl6ZTogZGVjYXBpdGFsaXplLFxuICB0cmFuc2Zvcm1BcnJheTogdHJhbnNmb3JtQXJyYXksXG4gIHRvRml4ZWREaWdpdHM6IHRvRml4ZWREaWdpdHMsXG4gIHRocm90dGxlOiB0aHJvdHRsZSxcbiAgZGVib3VuY2U6IGRlYm91bmNlLFxuICB0cmVlU2VhcmNoOiB0cmVlU2VhcmNoLFxuICBlY2hvRm46IGVjaG9GbixcbiAgaXNJU084NjAxOiBpc0lTTzg2MDEsXG4gIGlzT2xkSUU6IGlzT2xkSUUsXG4gIGdldEludGVybmV0RXhwbG9yZXJWZXJzaW9uOiBnZXRJbnRlcm5ldEV4cGxvcmVyVmVyc2lvbixcbiAgaXNJRGV2aWNlOiBpc0lEZXZpY2UsXG4gIGlzTW9iaWxlOiBpc01vYmlsZSxcbiAgaXNJUGhvbmU6IGlzSVBob25lLFxuICBpc0FuZHJvaWQ6IGlzQW5kcm9pZFxufTtcblxubW9kdWxlLmV4cG9ydHMgPSB1dGlsaXRpZXM7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbnZhciB4bWwgPSB7fTtcblxueG1sLnN0clRvWE1MRG9jID0gZnVuY3Rpb24gc3RyVG9YTUxEb2Moc3RyaW5nQ29udGFpbmluZ1hNTFNvdXJjZSl7XG4gIC8vSUUgOFxuICBpZih0eXBlb2Ygd2luZG93LkRPTVBhcnNlciA9PT0gJ3VuZGVmaW5lZCcpe1xuICAgIHZhciB4bWxEb2N1bWVudCA9IG5ldyBBY3RpdmVYT2JqZWN0KCdNaWNyb3NvZnQuWE1MRE9NJyk7XG4gICAgeG1sRG9jdW1lbnQuYXN5bmMgPSBmYWxzZTtcbiAgICB4bWxEb2N1bWVudC5sb2FkWE1MKHN0cmluZ0NvbnRhaW5pbmdYTUxTb3VyY2UpO1xuICAgIHJldHVybiB4bWxEb2N1bWVudDtcbiAgfVxuXG4gIHJldHVybiBwYXJzZVN0cmluZyhzdHJpbmdDb250YWluaW5nWE1MU291cmNlKTtcblxuICBmdW5jdGlvbiBwYXJzZVN0cmluZyhzdHJpbmdDb250YWluaW5nWE1MU291cmNlKXtcbiAgICB2YXIgcGFyc2VyID0gbmV3IERPTVBhcnNlcigpO1xuICAgIHZhciBwYXJzZWREb2N1bWVudDtcblxuICAgIC8vTm90ZTogVGhpcyB0cnkgY2F0Y2ggaXMgdG8gZGVhbCB3aXRoIHRoZSBmYWN0IHRoYXQgb24gSUUgcGFyc2VyLnBhcnNlRnJvbVN0cmluZyBkb2VzIHRocm93IGFuIGVycm9yIGJ1dCB0aGUgcmVzdCBvZiB0aGUgYnJvd3NlcnMgZG9uJ3QuXG4gICAgdHJ5IHtcbiAgICAgIHBhcnNlZERvY3VtZW50ID0gcGFyc2VyLnBhcnNlRnJvbVN0cmluZyhzdHJpbmdDb250YWluaW5nWE1MU291cmNlLCBcImFwcGxpY2F0aW9uL3htbFwiKTtcblxuICAgICAgaWYoaXNQYXJzZUVycm9yKHBhcnNlZERvY3VtZW50KSB8fCB1dGlsaXRpZXMuaXNFbXB0eVN0cmluZyhzdHJpbmdDb250YWluaW5nWE1MU291cmNlKSl7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgfVxuICAgIH1jYXRjaChlKXtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcInhtbC5zdHJUb1hNTERPQzogRXJyb3IgcGFyc2luZyB0aGUgc3RyaW5nOiAnXCIgKyBzdHJpbmdDb250YWluaW5nWE1MU291cmNlICsgXCInXCIpO1xuICAgIH1cblxuICAgIHJldHVybiBwYXJzZWREb2N1bWVudDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzUGFyc2VFcnJvcihwYXJzZWREb2N1bWVudCkge1xuICAgIHRyeSB7IC8vIHBhcnNlciBhbmQgcGFyc2VyZXJyb3JOUyBjb3VsZCBiZSBjYWNoZWQgb24gc3RhcnR1cCBmb3IgZWZmaWNpZW5jeVxuICAgICAgdmFyIHBhcnNlciA9IG5ldyBET01QYXJzZXIoKSxcbiAgICAgICAgZXJyb25lb3VzUGFyc2UgPSBwYXJzZXIucGFyc2VGcm9tU3RyaW5nKCdJTlZBTElEJywgJ3RleHQveG1sJyksXG4gICAgICAgIHBhcnNlcmVycm9yTlMgPSBlcnJvbmVvdXNQYXJzZS5nZXRFbGVtZW50c0J5VGFnTmFtZShcInBhcnNlcmVycm9yXCIpWzBdLm5hbWVzcGFjZVVSSTtcblxuICAgICAgaWYgKHBhcnNlcmVycm9yTlMgPT09ICdodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sJykge1xuICAgICAgICAvLyBJbiBQaGFudG9tSlMgdGhlIHBhcnNlZXJyb3IgZWxlbWVudCBkb2Vzbid0IHNlZW0gdG8gaGF2ZSBhIHNwZWNpYWwgbmFtZXNwYWNlLCBzbyB3ZSBhcmUganVzdCBndWVzc2luZyBoZXJlIDooXG4gICAgICAgIHJldHVybiBwYXJzZWREb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcInBhcnNlcmVycm9yXCIpLmxlbmd0aCA+IDA7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYXJzZWREb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKHBhcnNlcmVycm9yTlMsICdwYXJzZXJlcnJvcicpLmxlbmd0aCA+IDA7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy9Ob3RlIG9uIElFIHBhcnNlU3RyaW5nIHRocm93cyBhbiBlcnJvciBieSBpdHNlbGYgYW5kIGl0IHdpbGwgbmV2ZXIgcmVhY2ggdGhpcyBjb2RlLiBCZWNhdXNlIGl0IHdpbGwgaGF2ZSBmYWlsZWQgYmVmb3JlXG4gICAgfVxuICB9XG59O1xuXG54bWwucGFyc2VUZXh0ID0gZnVuY3Rpb24gcGFyc2VUZXh0IChzVmFsdWUpIHtcbiAgaWYgKC9eXFxzKiQvLnRlc3Qoc1ZhbHVlKSkgeyByZXR1cm4gbnVsbDsgfVxuICBpZiAoL14oPzp0cnVlfGZhbHNlKSQvaS50ZXN0KHNWYWx1ZSkpIHsgcmV0dXJuIHNWYWx1ZS50b0xvd2VyQ2FzZSgpID09PSBcInRydWVcIjsgfVxuICBpZiAoaXNGaW5pdGUoc1ZhbHVlKSkgeyByZXR1cm4gcGFyc2VGbG9hdChzVmFsdWUpOyB9XG4gIGlmICh1dGlsaXRpZXMuaXNJU084NjAxKHNWYWx1ZSkpIHsgcmV0dXJuIG5ldyBEYXRlKHNWYWx1ZSk7IH1cbiAgcmV0dXJuIHNWYWx1ZS50cmltKCk7XG59O1xuXG54bWwuSlhPTlRyZWUgPSBmdW5jdGlvbiBKWE9OVHJlZSAob1hNTFBhcmVudCkge1xuICB2YXIgcGFyc2VUZXh0ID0geG1sLnBhcnNlVGV4dDtcblxuICAvL1RoZSBkb2N1bWVudCBvYmplY3QgaXMgYW4gZXNwZWNpYWwgb2JqZWN0IHRoYXQgaXQgbWF5IG1pc3Mgc29tZSBmdW5jdGlvbnMgb3IgYXR0cnMgZGVwZW5kaW5nIG9uIHRoZSBicm93c2VyLlxuICAvL1RvIHByZXZlbnQgdGhpcyBwcm9ibGVtIHdpdGggY3JlYXRlIHRoZSBKWE9OVHJlZSB1c2luZyB0aGUgcm9vdCBjaGlsZE5vZGUgd2hpY2ggaXMgYSBmdWxseSBmbGVzaGVkIG5vZGUgb24gYWxsIHN1cHBvcnRlZFxuICAvL2Jyb3dzZXJzLlxuICBpZihvWE1MUGFyZW50LmRvY3VtZW50RWxlbWVudCl7XG4gICAgcmV0dXJuIG5ldyB4bWwuSlhPTlRyZWUob1hNTFBhcmVudC5kb2N1bWVudEVsZW1lbnQpO1xuICB9XG5cbiAgaWYgKG9YTUxQYXJlbnQuaGFzQ2hpbGROb2RlcygpKSB7XG4gICAgdmFyIHNDb2xsZWN0ZWRUeHQgPSBcIlwiO1xuICAgIGZvciAodmFyIG9Ob2RlLCBzUHJvcCwgdkNvbnRlbnQsIG5JdGVtID0gMDsgbkl0ZW0gPCBvWE1MUGFyZW50LmNoaWxkTm9kZXMubGVuZ3RoOyBuSXRlbSsrKSB7XG4gICAgICBvTm9kZSA9IG9YTUxQYXJlbnQuY2hpbGROb2Rlcy5pdGVtKG5JdGVtKTtcbiAgICAgIC8qanNoaW50IGJpdHdpc2U6IGZhbHNlKi9cbiAgICAgIGlmICgob05vZGUubm9kZVR5cGUgLSAxIHwgMSkgPT09IDMpIHsgc0NvbGxlY3RlZFR4dCArPSBvTm9kZS5ub2RlVHlwZSA9PT0gMyA/IG9Ob2RlLm5vZGVWYWx1ZS50cmltKCkgOiBvTm9kZS5ub2RlVmFsdWU7IH1cbiAgICAgIGVsc2UgaWYgKG9Ob2RlLm5vZGVUeXBlID09PSAxICYmICFvTm9kZS5wcmVmaXgpIHtcbiAgICAgICAgc1Byb3AgPSB1dGlsaXRpZXMuZGVjYXBpdGFsaXplKG9Ob2RlLm5vZGVOYW1lKTtcbiAgICAgICAgdkNvbnRlbnQgPSBuZXcgeG1sLkpYT05UcmVlKG9Ob2RlKTtcbiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoc1Byb3ApKSB7XG4gICAgICAgICAgaWYgKHRoaXNbc1Byb3BdLmNvbnN0cnVjdG9yICE9PSBBcnJheSkgeyB0aGlzW3NQcm9wXSA9IFt0aGlzW3NQcm9wXV07IH1cbiAgICAgICAgICB0aGlzW3NQcm9wXS5wdXNoKHZDb250ZW50KTtcbiAgICAgICAgfSBlbHNlIHsgdGhpc1tzUHJvcF0gPSB2Q29udGVudDsgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc0NvbGxlY3RlZFR4dCkgeyB0aGlzLmtleVZhbHVlID0gcGFyc2VUZXh0KHNDb2xsZWN0ZWRUeHQpOyB9XG4gIH1cblxuICAvL0lFOCBTdHVwaWQgZml4XG4gIHZhciBoYXNBdHRyID0gdHlwZW9mIG9YTUxQYXJlbnQuaGFzQXR0cmlidXRlcyA9PT0gJ3VuZGVmaW5lZCc/IG9YTUxQYXJlbnQuYXR0cmlidXRlcy5sZW5ndGggPiAwOiBvWE1MUGFyZW50Lmhhc0F0dHJpYnV0ZXMoKTtcbiAgaWYgKGhhc0F0dHIpIHtcbiAgICB2YXIgb0F0dHJpYjtcbiAgICBmb3IgKHZhciBuQXR0cmliID0gMDsgbkF0dHJpYiA8IG9YTUxQYXJlbnQuYXR0cmlidXRlcy5sZW5ndGg7IG5BdHRyaWIrKykge1xuICAgICAgb0F0dHJpYiA9IG9YTUxQYXJlbnQuYXR0cmlidXRlcy5pdGVtKG5BdHRyaWIpO1xuICAgICAgdGhpc1tcIkBcIiArIHV0aWxpdGllcy5kZWNhcGl0YWxpemUob0F0dHJpYi5uYW1lKV0gPSBwYXJzZVRleHQob0F0dHJpYi52YWx1ZS50cmltKCkpO1xuICAgIH1cbiAgfVxufTtcblxueG1sLkpYT05UcmVlLnByb3RvdHlwZS5hdHRyID0gZnVuY3Rpb24oYXR0cikge1xuICByZXR1cm4gdGhpc1snQCcgKyB1dGlsaXRpZXMuZGVjYXBpdGFsaXplKGF0dHIpXTtcbn07XG5cbnhtbC50b0pYT05UcmVlID0gZnVuY3Rpb24gdG9KWE9OVHJlZSh4bWxTdHJpbmcpe1xuICB2YXIgeG1sRG9jID0geG1sLnN0clRvWE1MRG9jKHhtbFN0cmluZyk7XG4gIHJldHVybiBuZXcgeG1sLkpYT05UcmVlKHhtbERvYyk7XG59O1xuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBleHRyYWN0IHRoZSBrZXl2YWx1ZSBvZiBhIEpYT05UcmVlIG9ialxuICpcbiAqIEBwYXJhbSB4bWxPYmoge0pYT05UcmVlfVxuICogcmV0dXJuIHRoZSBrZXkgdmFsdWUgb3IgdW5kZWZpbmVkO1xuICovXG54bWwua2V5VmFsdWUgPSBmdW5jdGlvbiBnZXRLZXlWYWx1ZSh4bWxPYmopIHtcbiAgaWYoeG1sT2JqKXtcbiAgICByZXR1cm4geG1sT2JqLmtleVZhbHVlO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59O1xuXG54bWwuYXR0ciA9IGZ1bmN0aW9uIGdldEF0dHJWYWx1ZSh4bWxPYmosIGF0dHIpIHtcbiAgaWYoeG1sT2JqKSB7XG4gICAgcmV0dXJuIHhtbE9ialsnQCcgKyB1dGlsaXRpZXMuZGVjYXBpdGFsaXplKGF0dHIpXTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufTtcblxueG1sLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZVhNTChzdHIpIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC8mL2csICcmYW1wOycpXG4gICAgLnJlcGxhY2UoLzwvZywgJyZsdDsnKVxuICAgIC5yZXBsYWNlKC8+L2csICcmZ3Q7JylcbiAgICAucmVwbGFjZSgvXCIvZywgJyZxdW90OycpXG4gICAgLnJlcGxhY2UoLycvZywgJyZhcG9zOycpO1xufTtcblxueG1sLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZVhNTChzdHIpIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC8mYXBvczsvZywgXCInXCIpXG4gICAgLnJlcGxhY2UoLyZxdW90Oy9nLCAnXCInKVxuICAgIC5yZXBsYWNlKC8mZ3Q7L2csICc+JylcbiAgICAucmVwbGFjZSgvJmx0Oy9nLCAnPCcpXG4gICAgLnJlcGxhY2UoLyZhbXA7L2csICcmJyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHhtbDsiLCIndXNlIHN0cmljdCc7XG5cbnJlcXVpcmUoJy4vcGx1Z2luL2NvbXBvbmVudHMvYWRzLWxhYmVsXzQnKTtcbnJlcXVpcmUoJy4vcGx1Z2luL2NvbXBvbmVudHMvYmxhY2stcG9zdGVyXzQnKTtcblxudmFyIHZpZGVvSnNWQVNUID0gcmVxdWlyZSgnLi9wbHVnaW4vdmlkZW9qcy52YXN0LnZwYWlkJyk7XG5cbnZpZGVvanMucGx1Z2luKCd2YXN0Q2xpZW50JywgdmlkZW9Kc1ZBU1QpO1xuXG4iXX0= +},{"./plugin/components/ads-label_4":34,"./plugin/components/black-poster_4":36,"./plugin/videojs.vast.vpaid":37}]},{},[45]) +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlERkxBU0hDbGllbnQvanMvSVZQQUlEQWRVbml0LmpzIiwiYm93ZXJfY29tcG9uZW50cy9WUEFJREZMQVNIQ2xpZW50L2pzL1ZQQUlEQWRVbml0LmpzIiwiYm93ZXJfY29tcG9uZW50cy9WUEFJREZMQVNIQ2xpZW50L2pzL1ZQQUlERkxBU0hDbGllbnQuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlERkxBU0hDbGllbnQvanMvanNGbGFzaEJyaWRnZS5qcyIsImJvd2VyX2NvbXBvbmVudHMvVlBBSURGTEFTSENsaWVudC9qcy9qc0ZsYXNoQnJpZGdlUmVnaXN0cnkuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlERkxBU0hDbGllbnQvanMvcmVnaXN0cnkuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlERkxBU0hDbGllbnQvanMvdXRpbHMuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlESFRNTDVDbGllbnQvanMvSVZQQUlEQWRVbml0LmpzIiwiYm93ZXJfY29tcG9uZW50cy9WUEFJREhUTUw1Q2xpZW50L2pzL1ZQQUlEQWRVbml0LmpzIiwiYm93ZXJfY29tcG9uZW50cy9WUEFJREhUTUw1Q2xpZW50L2pzL1ZQQUlESFRNTDVDbGllbnQuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlESFRNTDVDbGllbnQvanMvc3Vic2NyaWJlci5qcyIsImJvd2VyX2NvbXBvbmVudHMvVlBBSURIVE1MNUNsaWVudC9qcy91dGlscy5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L0FkLmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvQ29tcGFuaW9uLmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvQ3JlYXRpdmUuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9JbkxpbmUuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9MaW5lYXIuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9NZWRpYUZpbGUuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9UcmFja2luZ0V2ZW50LmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvVkFTVENsaWVudC5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L1ZBU1RFcnJvci5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L1ZBU1RJbnRlZ3JhdG9yLmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvVkFTVFJlc3BvbnNlLmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvVkFTVFRyYWNrZXIuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9WaWRlb0NsaWNrcy5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L1dyYXBwZXIuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9wYXJzZXJzLmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvdmFzdFV0aWwuanMiLCJzcmMvc2NyaXB0cy9hZHMvdnBhaWQvVlBBSURBZFVuaXRXcmFwcGVyLmpzIiwic3JjL3NjcmlwdHMvYWRzL3ZwYWlkL1ZQQUlERmxhc2hUZWNoLmpzIiwic3JjL3NjcmlwdHMvYWRzL3ZwYWlkL1ZQQUlESFRNTDVUZWNoLmpzIiwic3JjL3NjcmlwdHMvYWRzL3ZwYWlkL1ZQQUlESW50ZWdyYXRvci5qcyIsInNyYy9zY3JpcHRzL3BsdWdpbi9jb21wb25lbnRzL2Fkcy1sYWJlbC5qcyIsInNyYy9zY3JpcHRzL3BsdWdpbi9jb21wb25lbnRzL2Fkcy1sYWJlbF80LmpzIiwic3JjL3NjcmlwdHMvcGx1Z2luL2NvbXBvbmVudHMvYmxhY2stcG9zdGVyLmpzIiwic3JjL3NjcmlwdHMvcGx1Z2luL2NvbXBvbmVudHMvYmxhY2stcG9zdGVyXzQuanMiLCJzcmMvc2NyaXB0cy9wbHVnaW4vdmlkZW9qcy52YXN0LnZwYWlkLmpzIiwic3JjL3NjcmlwdHMvdXRpbHMvYXN5bmMuanMiLCJzcmMvc2NyaXB0cy91dGlscy9kb20uanMiLCJzcmMvc2NyaXB0cy91dGlscy9odHRwLmpzIiwic3JjL3NjcmlwdHMvdXRpbHMvcGxheWVyVXRpbHMuanMiLCJzcmMvc2NyaXB0cy91dGlscy91cmxVdGlscy5qcyIsInNyYy9zY3JpcHRzL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMuanMiLCJzcmMvc2NyaXB0cy91dGlscy94bWwuanMiLCJzcmMvc2NyaXB0cy92aWRlb2pzXzQudmFzdC52cGFpZC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBOzs7Ozs7Ozs7Ozs7SUFHYTs7Ozs7Ozs7OzsyQ0FJMEQ7Z0JBQWxELDJFQUFxQixxQkFBNkI7Z0JBQXRCLGlFQUFXLHlCQUFXOzs7Ozs7OytCQUczRCxPQUFPLFFBQVEsVUFBVSxnQkFBMkc7Z0JBQTNGLHFFQUFlLEVBQUMsY0FBYSxFQUFiLGtCQUEyRTtnQkFBekQsd0VBQWtCLEVBQUMsV0FBVyxFQUFYLGtCQUFzQztnQkFBdEIsaUVBQVcseUJBQVc7Ozs7aUNBQ25JLE9BQU8sUUFBUSxVQUFnQztnQkFBdEIsaUVBQVcseUJBQVc7Ozs7a0NBRTFCO2dCQUF0QixpRUFBVyx5QkFBVzs7OztpQ0FDRDtnQkFBdEIsaUVBQVcseUJBQVc7Ozs7a0NBQ0M7Z0JBQXRCLGlFQUFXLHlCQUFXOzs7O21DQUNDO2dCQUF0QixpRUFBVyx5QkFBVzs7OzttQ0FDQTtnQkFBdEIsaUVBQVcseUJBQVc7Ozs7cUNBQ0U7Z0JBQXRCLGlFQUFXLHlCQUFXOzs7O2lDQUNKO2dCQUF0QixpRUFBVyx5QkFBVzs7Ozs7OztvQ0FHakIsVUFBVTs7O21DQUNYLFVBQVU7OztvQ0FDVCxVQUFVOzs7c0NBQ1IsVUFBVTs7OzRDQUNKLFVBQVU7OzsyQ0FDWCxVQUFVOzs7c0NBQ2YsVUFBVTs7O29DQUNaLGFBQW1DO2dCQUF0QixpRUFBVyx5QkFBVzs7OztvQ0FDbkMsVUFBVTs7O3dDQUNOLFVBQVU7OzttQ0FDZixVQUFVOzs7V0E3Qlo7OztBQWdDYixPQUFPLGNBQVAsQ0FBc0IsWUFBdEIsRUFBb0MsUUFBcEMsRUFBOEM7QUFDMUMsY0FBVSxLQUFWO0FBQ0Esa0JBQWMsS0FBZDtBQUNBLFdBQU8sQ0FD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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3UkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDck5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeExBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2aUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeFVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdE5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNySkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDellBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdFVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIid1c2Ugc3RyaWN0JztcblxuLy9zaW1wbGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIEFQSVxuZXhwb3J0IGNsYXNzIElWUEFJREFkVW5pdCB7XG5cbiAgICAvL2FsbCBtZXRob2RzIGJlbG93XG4gICAgLy9hcmUgYXN5bmMgbWV0aG9kc1xuICAgIGhhbmRzaGFrZVZlcnNpb24ocGxheWVyVlBBSURWZXJzaW9uID0gJzIuMCcsIGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7fVxuXG4gICAgLy9jcmVhdGl2ZURhdGEgaXMgYW4gb2JqZWN0IHRvIGJlIGNvbnNpc3RlbnQgd2l0aCBWUEFJREhUTUxcbiAgICBpbml0QWQgKHdpZHRoLCBoZWlnaHQsIHZpZXdNb2RlLCBkZXNpcmVkQml0cmF0ZSwgY3JlYXRpdmVEYXRhID0ge0FkUGFyYW1ldGVyczonJ30sIGVudmlyb25tZW50VmFycyA9IHtmbGFzaFZhcnM6ICcnfSwgY2FsbGJhY2sgPSB1bmRlZmluZWQpIHt9XG4gICAgcmVzaXplQWQod2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7fVxuXG4gICAgc3RhcnRBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge31cbiAgICBzdG9wQWQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHt9XG4gICAgcGF1c2VBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge31cbiAgICByZXN1bWVBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge31cbiAgICBleHBhbmRBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge31cbiAgICBjb2xsYXBzZUFkKGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7fVxuICAgIHNraXBBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge31cblxuICAgIC8vcHJvcGVydGllcyB0aGF0IHdpbGwgYmUgdHJlYXQgYXMgYXN5bmMgbWV0aG9kc1xuICAgIGdldEFkTGluZWFyKGNhbGxiYWNrKSB7fVxuICAgIGdldEFkV2lkdGgoY2FsbGJhY2spIHt9XG4gICAgZ2V0QWRIZWlnaHQoY2FsbGJhY2spIHt9XG4gICAgZ2V0QWRFeHBhbmRlZChjYWxsYmFjaykge31cbiAgICBnZXRBZFNraXBwYWJsZVN0YXRlKGNhbGxiYWNrKSB7fVxuICAgIGdldEFkUmVtYWluaW5nVGltZShjYWxsYmFjaykge31cbiAgICBnZXRBZER1cmF0aW9uKGNhbGxiYWNrKSB7fVxuICAgIHNldEFkVm9sdW1lKHNvdW5kVm9sdW1lLCBjYWxsYmFjayA9IHVuZGVmaW5lZCkge31cbiAgICBnZXRBZFZvbHVtZShjYWxsYmFjaykge31cbiAgICBnZXRBZENvbXBhbmlvbnMoY2FsbGJhY2spIHt9XG4gICAgZ2V0QWRJY29ucyhjYWxsYmFjaykge31cbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KElWUEFJREFkVW5pdCwgJ0VWRU5UUycsIHtcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICB2YWx1ZTogW1xuICAgICAgICAnQWRMb2FkZWQnLFxuICAgICAgICAnQWRTdGFydGVkJyxcbiAgICAgICAgJ0FkU3RvcHBlZCcsXG4gICAgICAgICdBZFNraXBwZWQnLFxuICAgICAgICAnQWRTa2lwcGFibGVTdGF0ZUNoYW5nZScsIC8vIFZQQUlEIDIuMCBuZXcgZXZlbnRcbiAgICAgICAgJ0FkU2l6ZUNoYW5nZScsIC8vIFZQQUlEIDIuMCBuZXcgZXZlbnRcbiAgICAgICAgJ0FkTGluZWFyQ2hhbmdlJyxcbiAgICAgICAgJ0FkRHVyYXRpb25DaGFuZ2UnLCAvLyBWUEFJRCAyLjAgbmV3IGV2ZW50XG4gICAgICAgICdBZEV4cGFuZGVkQ2hhbmdlJyxcbiAgICAgICAgJ0FkUmVtYWluaW5nVGltZUNoYW5nZScsIC8vIFtEZXByZWNhdGVkIGluIDIuMF0gYnV0IHdpbGwgYmUgc3RpbGwgZmlyZWQgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG4gICAgICAgICdBZFZvbHVtZUNoYW5nZScsXG4gICAgICAgICdBZEltcHJlc3Npb24nLFxuICAgICAgICAnQWRWaWRlb1N0YXJ0JyxcbiAgICAgICAgJ0FkVmlkZW9GaXJzdFF1YXJ0aWxlJyxcbiAgICAgICAgJ0FkVmlkZW9NaWRwb2ludCcsXG4gICAgICAgICdBZFZpZGVvVGhpcmRRdWFydGlsZScsXG4gICAgICAgICdBZFZpZGVvQ29tcGxldGUnLFxuICAgICAgICAnQWRDbGlja1RocnUnLFxuICAgICAgICAnQWRJbnRlcmFjdGlvbicsIC8vIFZQQUlEIDIuMCBuZXcgZXZlbnRcbiAgICAgICAgJ0FkVXNlckFjY2VwdEludml0YXRpb24nLFxuICAgICAgICAnQWRVc2VyTWluaW1pemUnLFxuICAgICAgICAnQWRVc2VyQ2xvc2UnLFxuICAgICAgICAnQWRQYXVzZWQnLFxuICAgICAgICAnQWRQbGF5aW5nJyxcbiAgICAgICAgJ0FkTG9nJyxcbiAgICAgICAgJ0FkRXJyb3InXG4gICAgXVxufSk7XG5cbiIsIid1c2Ugc3RyaWN0JztcblxubGV0IElWUEFJREFkVW5pdCA9IHJlcXVpcmUoJy4vSVZQQUlEQWRVbml0JykuSVZQQUlEQWRVbml0O1xubGV0IEFMTF9WUEFJRF9NRVRIT0RTID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoSVZQQUlEQWRVbml0LnByb3RvdHlwZSkuZmlsdGVyKGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuICAgIHJldHVybiBbJ2NvbnN0cnVjdG9yJ10uaW5kZXhPZihwcm9wZXJ0eSkgPT09IC0xO1xufSk7XG5cbmV4cG9ydCBjbGFzcyBWUEFJREFkVW5pdCBleHRlbmRzIElWUEFJREFkVW5pdCB7XG4gICAgY29uc3RydWN0b3IgKGZsYXNoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuX2Rlc3Ryb3llZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9mbGFzaCA9IGZsYXNoO1xuICAgIH1cblxuICAgIF9kZXN0cm95KCkge1xuICAgICAgICB0aGlzLl9kZXN0cm95ZWQgPSB0cnVlO1xuICAgICAgICBBTExfVlBBSURfTUVUSE9EUy5mb3JFYWNoKChtZXRob2ROYW1lKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9mbGFzaC5yZW1vdmVDYWxsYmFja0J5TWV0aG9kTmFtZShtZXRob2ROYW1lKTtcbiAgICAgICAgfSk7XG4gICAgICAgIElWUEFJREFkVW5pdC5FVkVOVFMuZm9yRWFjaCgoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2ZsYXNoLm9mZkV2ZW50KGV2ZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5fZmxhc2ggPSBudWxsO1xuICAgIH1cblxuICAgIGlzRGVzdHJveWVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rlc3Ryb3llZDtcbiAgICB9XG5cbiAgICBvbihldmVudE5hbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLm9uKGV2ZW50TmFtZSwgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIG9mZihldmVudE5hbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLm9mZihldmVudE5hbWUsIGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICAvL1ZQQUlEIGludGVyZmFjZVxuICAgIGhhbmRzaGFrZVZlcnNpb24ocGxheWVyVlBBSURWZXJzaW9uID0gJzIuMCcsIGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnaGFuZHNoYWtlVmVyc2lvbicsIFtwbGF5ZXJWUEFJRFZlcnNpb25dLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGluaXRBZCAod2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGRlc2lyZWRCaXRyYXRlLCBjcmVhdGl2ZURhdGEgPSB7QWRQYXJhbWV0ZXJzOiAnJ30sIGVudmlyb25tZW50VmFycyA9IHtmbGFzaFZhcnM6ICcnfSwgY2FsbGJhY2sgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy9yZXNpemUgZWxlbWVudCB0aGF0IGhhcyB0aGUgZmxhc2ggb2JqZWN0XG4gICAgICAgIHRoaXMuX2ZsYXNoLnNldFNpemUod2lkdGgsIGhlaWdodCk7XG4gICAgICAgIGNyZWF0aXZlRGF0YSA9IGNyZWF0aXZlRGF0YSB8fCB7QWRQYXJhbWV0ZXJzOiAnJ307XG4gICAgICAgIGVudmlyb25tZW50VmFycyA9IGVudmlyb25tZW50VmFycyB8fCB7Zmxhc2hWYXJzOiAnJ307XG5cbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdpbml0QWQnLCBbdGhpcy5fZmxhc2guZ2V0V2lkdGgoKSwgdGhpcy5fZmxhc2guZ2V0SGVpZ2h0KCksIHZpZXdNb2RlLCBkZXNpcmVkQml0cmF0ZSwgY3JlYXRpdmVEYXRhLkFkUGFyYW1ldGVycyB8fCAnJywgZW52aXJvbm1lbnRWYXJzLmZsYXNoVmFycyB8fCAnJ10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgcmVzaXplQWQod2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vcmVzaXplIGVsZW1lbnQgdGhhdCBoYXMgdGhlIGZsYXNoIG9iamVjdFxuICAgICAgICB0aGlzLl9mbGFzaC5zZXRTaXplKHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgICAgIC8vcmVzaXplIGFkIGluc2lkZSB0aGUgZmxhc2hcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdyZXNpemVBZCcsIFt0aGlzLl9mbGFzaC5nZXRXaWR0aCgpLCB0aGlzLl9mbGFzaC5nZXRIZWlnaHQoKSwgdmlld01vZGVdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIHN0YXJ0QWQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdzdGFydEFkJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgc3RvcEFkKGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnc3RvcEFkJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgcGF1c2VBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ3BhdXNlQWQnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICByZXN1bWVBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ3Jlc3VtZUFkJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgZXhwYW5kQWQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdleHBhbmRBZCcsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGNvbGxhcHNlQWQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdjb2xsYXBzZUFkJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgc2tpcEFkKGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnc2tpcEFkJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICAvL3Byb3BlcnRpZXMgdGhhdCB3aWxsIGJlIHRyZWF0IGFzIGFzeW5jIG1ldGhvZHNcbiAgICBnZXRBZExpbmVhcihjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2dldEFkTGluZWFyJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgZ2V0QWRXaWR0aChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2dldEFkV2lkdGgnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBnZXRBZEhlaWdodChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2dldEFkSGVpZ2h0JywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgZ2V0QWRFeHBhbmRlZChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2dldEFkRXhwYW5kZWQnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBnZXRBZFNraXBwYWJsZVN0YXRlKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnZ2V0QWRTa2lwcGFibGVTdGF0ZScsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGdldEFkUmVtYWluaW5nVGltZShjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2dldEFkUmVtYWluaW5nVGltZScsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGdldEFkRHVyYXRpb24oY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdnZXRBZER1cmF0aW9uJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgc2V0QWRWb2x1bWUodm9sdW1lLCBjYWxsYmFjayA9IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ3NldEFkVm9sdW1lJywgW3ZvbHVtZV0sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgZ2V0QWRWb2x1bWUoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdnZXRBZFZvbHVtZScsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGdldEFkQ29tcGFuaW9ucyhjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2dldEFkQ29tcGFuaW9ucycsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGdldEFkSWNvbnMoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdnZXRBZEljb25zJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG59XG5cbiIsIid1c2Ugc3RyaWN0JztcblxubGV0IEpTRmxhc2hCcmlkZ2UgPSByZXF1aXJlKCcuL2pzRmxhc2hCcmlkZ2UnKS5KU0ZsYXNoQnJpZGdlO1xubGV0IFZQQUlEQWRVbml0ID0gcmVxdWlyZSgnLi9WUEFJREFkVW5pdCcpLlZQQUlEQWRVbml0O1xuXG5sZXQgbm9vcCA9IHJlcXVpcmUoJy4vdXRpbHMnKS5ub29wO1xubGV0IGNhbGxiYWNrVGltZW91dCA9IHJlcXVpcmUoJy4vdXRpbHMnKS5jYWxsYmFja1RpbWVvdXQ7XG5sZXQgaXNQb3NpdGl2ZUludCA9IHJlcXVpcmUoJy4vdXRpbHMnKS5pc1Bvc2l0aXZlSW50O1xubGV0IGNyZWF0ZUVsZW1lbnRXaXRoSUQgPSByZXF1aXJlKCcuL3V0aWxzJykuY3JlYXRlRWxlbWVudFdpdGhJRDtcbmxldCB1bmlxdWVWUEFJRCA9IHJlcXVpcmUoJy4vdXRpbHMnKS51bmlxdWUoJ3ZwYWlkJyk7XG5cbmNvbnN0IEVSUk9SID0gJ2Vycm9yJztcbmNvbnN0IEZMQVNIX1ZFUlNJT04gPSAnMTAuMS4wJztcblxuY2xhc3MgVlBBSURGTEFTSENsaWVudCB7XG4gICAgY29uc3RydWN0b3IgKHZwYWlkUGFyZW50RWwsIGNhbGxiYWNrLCBzd2ZDb25maWcgPSB7ZGF0YTogJ1ZQQUlERmxhc2guc3dmJywgd2lkdGg6IDgwMCwgaGVpZ2h0OiA0MDB9LCBwYXJhbXMgPSB7IHdtb2RlOiAndHJhbnNwYXJlbnQnLCBzYWxpZ246ICd0bCcsIGFsaWduOiAnbGVmdCcsIGFsbG93U2NyaXB0QWNjZXNzOiAnYWx3YXlzJywgc2NhbGU6ICdub1NjYWxlJywgYWxsb3dGdWxsU2NyZWVuOiAndHJ1ZScsIHF1YWxpdHk6ICdoaWdoJ30sIHZwYWlkT3B0aW9ucyA9IHsgZGVidWc6IGZhbHNlLCB0aW1lb3V0OiAxMDAwMCB9KSB7XG5cbiAgICAgICAgaWYgKCFWUEFJREZMQVNIQ2xpZW50Lmhhc0V4dGVybmFsRGVwZW5kZW5jaWVzKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBvbkVycm9yKCdubyBzd2ZvYmplY3QgaW4gZ2xvYmFsIHNjb3BlLiBjaGVjazogaHR0cHM6Ly9naXRodWIuY29tL3N3Zm9iamVjdC9zd2ZvYmplY3Qgb3IgaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9zd2ZvYmplY3QvJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl92cGFpZFBhcmVudEVsID0gdnBhaWRQYXJlbnRFbDtcbiAgICAgICAgdGhpcy5fZmxhc2hJRCA9IHVuaXF1ZVZQQUlEKCk7XG4gICAgICAgIHRoaXMuX2Rlc3Ryb3llZCA9IGZhbHNlO1xuICAgICAgICBjYWxsYmFjayA9IGNhbGxiYWNrIHx8IG5vb3A7XG5cbiAgICAgICAgc3dmQ29uZmlnLndpZHRoID0gaXNQb3NpdGl2ZUludChzd2ZDb25maWcud2lkdGgsIDgwMCk7XG4gICAgICAgIHN3ZkNvbmZpZy5oZWlnaHQgPSBpc1Bvc2l0aXZlSW50KHN3ZkNvbmZpZy5oZWlnaHQsIDQwMCk7XG5cbiAgICAgICAgY3JlYXRlRWxlbWVudFdpdGhJRCh2cGFpZFBhcmVudEVsLCB0aGlzLl9mbGFzaElEKTtcblxuICAgICAgICBwYXJhbXMubW92aWUgPSBzd2ZDb25maWcuZGF0YTtcbiAgICAgICAgcGFyYW1zLkZsYXNoVmFycyA9IGBmbGFzaGlkPSR7dGhpcy5fZmxhc2hJRH0maGFuZGxlcj0ke0pTRmxhc2hCcmlkZ2UuVlBBSURfRkxBU0hfSEFORExFUn0mZGVidWc9JHt2cGFpZE9wdGlvbnMuZGVidWd9JnNhbGlnbj0ke3BhcmFtcy5zYWxpZ259YDtcblxuICAgICAgICBpZiAoIVZQQUlERkxBU0hDbGllbnQuaXNTdXBwb3J0ZWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIG9uRXJyb3IoJ3VzZXIgZG9uXFwndCBzdXBwb3J0IGZsYXNoIG9yIGRvZXNuXFwndCBoYXZlIHRoZSBtaW5pbXVtIHJlcXVpcmVkIHZlcnNpb24gb2YgZmxhc2ggJyArIEZMQVNIX1ZFUlNJT04pO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5lbCA9IHN3Zm9iamVjdC5jcmVhdGVTV0Yoc3dmQ29uZmlnLCBwYXJhbXMsIHRoaXMuX2ZsYXNoSUQpO1xuXG4gICAgICAgIGlmICghdGhpcy5lbCkge1xuICAgICAgICAgICAgcmV0dXJuIG9uRXJyb3IoICdzd2ZvYmplY3QgZmFpbGVkIHRvIGNyZWF0ZSBvYmplY3QgaW4gZWxlbWVudCcgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBoYW5kbGVyID0gY2FsbGJhY2tUaW1lb3V0KHZwYWlkT3B0aW9ucy50aW1lb3V0LFxuICAgICAgICAgICAgKGVyciwgZGF0YSkgPT4ge1xuICAgICAgICAgICAgICAgICRsb2FkUGVuZGVkQWRVbml0LmNhbGwodGhpcyk7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyLCBkYXRhKTtcbiAgICAgICAgICAgIH0sICgpID0+IHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayggJ3ZwYWlkIGZsYXNoIGxvYWQgdGltZW91dCAnICsgdnBhaWRPcHRpb25zLnRpbWVvdXQgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLl9mbGFzaCA9IG5ldyBKU0ZsYXNoQnJpZGdlKHRoaXMuZWwsIHN3ZkNvbmZpZy5kYXRhLCB0aGlzLl9mbGFzaElELCBzd2ZDb25maWcud2lkdGgsIHN3ZkNvbmZpZy5oZWlnaHQsIGhhbmRsZXIpO1xuXG4gICAgICAgIGZ1bmN0aW9uIG9uRXJyb3IoZXJyb3IpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKG5ldyBFcnJvcihlcnJvcikpO1xuICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgfVxuXG4gICAgZGVzdHJveSAoKSB7XG4gICAgICAgIHRoaXMuX2Rlc3Ryb3lBZFVuaXQoKTtcblxuICAgICAgICBpZiAodGhpcy5fZmxhc2gpIHtcbiAgICAgICAgICAgIHRoaXMuX2ZsYXNoLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHRoaXMuX2ZsYXNoID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVsID0gbnVsbDtcbiAgICAgICAgdGhpcy5fZGVzdHJveWVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpc0Rlc3Ryb3llZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZXN0cm95ZWQ7XG4gICAgfVxuXG4gICAgX2Rlc3Ryb3lBZFVuaXQoKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLl9sb2FkTGF0ZXI7XG5cbiAgICAgICAgaWYgKHRoaXMuX2FkVW5pdExvYWQpIHtcbiAgICAgICAgICAgIHRoaXMuX2FkVW5pdExvYWQgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5fZmxhc2gucmVtb3ZlQ2FsbGJhY2sodGhpcy5fYWRVbml0TG9hZCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fYWRVbml0KSB7XG4gICAgICAgICAgICB0aGlzLl9hZFVuaXQuX2Rlc3Ryb3koKTtcbiAgICAgICAgICAgIHRoaXMuX2FkVW5pdCA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBsb2FkQWRVbml0KGFkVVJMLCBjYWxsYmFjaykge1xuICAgICAgICAkdGhyb3dJZkRlc3Ryb3llZC5jYWxsKHRoaXMpO1xuXG4gICAgICAgIGlmICh0aGlzLl9hZFVuaXQpIHtcbiAgICAgICAgICAgIHRoaXMuX2Rlc3Ryb3lBZFVuaXQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl9mbGFzaC5pc1JlYWR5KCkpIHtcbiAgICAgICAgICAgIHRoaXMuX2FkVW5pdExvYWQgPSAoZXJyLCBtZXNzYWdlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYWRVbml0ID0gbmV3IFZQQUlEQWRVbml0KHRoaXMuX2ZsYXNoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5fYWRVbml0TG9hZCA9IG51bGw7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyLCB0aGlzLl9hZFVuaXQpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdsb2FkQWRVbml0JywgW2FkVVJMXSwgdGhpcy5fYWRVbml0TG9hZCk7XG4gICAgICAgIH1lbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2xvYWRMYXRlciA9IHt1cmw6IGFkVVJMLCBjYWxsYmFja307XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1bmxvYWRBZFVuaXQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgJHRocm93SWZEZXN0cm95ZWQuY2FsbCh0aGlzKTtcblxuICAgICAgICB0aGlzLl9kZXN0cm95QWRVbml0KCk7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgndW5sb2FkQWRVbml0JywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgZ2V0Rmxhc2hJRCgpIHtcbiAgICAgICAgJHRocm93SWZEZXN0cm95ZWQuY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZsYXNoLmdldEZsYXNoSUQoKTtcbiAgICB9XG4gICAgZ2V0Rmxhc2hVUkwoKSB7XG4gICAgICAgICR0aHJvd0lmRGVzdHJveWVkLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzLl9mbGFzaC5nZXRGbGFzaFVSTCgpO1xuICAgIH1cbn1cblxuc2V0U3RhdGljUHJvcGVydHkoJ2lzU3VwcG9ydGVkJywgKCkgPT4ge1xuICAgIHJldHVybiBWUEFJREZMQVNIQ2xpZW50Lmhhc0V4dGVybmFsRGVwZW5kZW5jaWVzKCkgJiYgc3dmb2JqZWN0Lmhhc0ZsYXNoUGxheWVyVmVyc2lvbihGTEFTSF9WRVJTSU9OKTtcbn0pO1xuXG5zZXRTdGF0aWNQcm9wZXJ0eSgnaGFzRXh0ZXJuYWxEZXBlbmRlbmNpZXMnLCAoKSA9PiB7XG4gICAgcmV0dXJuICEhd2luZG93LnN3Zm9iamVjdDtcbn0pO1xuXG5mdW5jdGlvbiAkdGhyb3dJZkRlc3Ryb3llZCgpIHtcbiAgICBpZih0aGlzLl9kZXN0cm95ZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IGVycm9yKCdWUEFJREZsYXNoVG9KUyBpcyBkZXN0cm95ZWQhJyk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiAkbG9hZFBlbmRlZEFkVW5pdCgpIHtcbiAgICBpZiAodGhpcy5fbG9hZExhdGVyKSB7XG4gICAgICAgIHRoaXMubG9hZEFkVW5pdCh0aGlzLl9sb2FkTGF0ZXIudXJsLCB0aGlzLl9sb2FkTGF0ZXIuY2FsbGJhY2spO1xuICAgICAgICBkZWxldGUgdGhpcy5fbG9hZExhdGVyO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gc2V0U3RhdGljUHJvcGVydHkocHJvcGVydHlOYW1lLCB2YWx1ZSkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShWUEFJREZMQVNIQ2xpZW50LCBwcm9wZXJ0eU5hbWUsIHtcbiAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICB2YWx1ZTogdmFsdWVcbiAgICB9KTtcbn1cblxud2luZG93LlZQQUlERkxBU0hDbGllbnQgPSBWUEFJREZMQVNIQ2xpZW50O1xubW9kdWxlLmV4cG9ydHMgPSBWUEFJREZMQVNIQ2xpZW50O1xuXG4iLCIndXNlIHN0cmljdCc7XG5cbmxldCB1bmlxdWUgPSByZXF1aXJlKCcuL3V0aWxzJykudW5pcXVlO1xubGV0IGlzUG9zaXRpdmVJbnQgPSByZXF1aXJlKCcuL3V0aWxzJykuaXNQb3NpdGl2ZUludDtcbmxldCBzdHJpbmdFbmRzV2l0aCA9IHJlcXVpcmUoJy4vdXRpbHMnKS5zdHJpbmdFbmRzV2l0aDtcbmxldCBTaW5nbGVWYWx1ZVJlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9yZWdpc3RyeScpLlNpbmdsZVZhbHVlUmVnaXN0cnk7XG5sZXQgTXVsdGlwbGVWYWx1ZXNSZWdpc3RyeSA9IHJlcXVpcmUoJy4vcmVnaXN0cnknKS5NdWx0aXBsZVZhbHVlc1JlZ2lzdHJ5O1xuY29uc3QgcmVnaXN0cnkgPSByZXF1aXJlKCcuL2pzRmxhc2hCcmlkZ2VSZWdpc3RyeScpO1xuY29uc3QgVlBBSURfRkxBU0hfSEFORExFUiA9ICd2cGFpZF92aWRlb19mbGFzaF9oYW5kbGVyJztcbmNvbnN0IEVSUk9SID0gJ0FkRXJyb3InO1xuXG5leHBvcnQgY2xhc3MgSlNGbGFzaEJyaWRnZSB7XG4gICAgY29uc3RydWN0b3IgKGVsLCBmbGFzaFVSTCwgZmxhc2hJRCwgd2lkdGgsIGhlaWdodCwgbG9hZEhhbmRTaGFrZSkge1xuICAgICAgICB0aGlzLl9lbCA9IGVsO1xuICAgICAgICB0aGlzLl9mbGFzaElEID0gZmxhc2hJRDtcbiAgICAgICAgdGhpcy5fZmxhc2hVUkwgPSBmbGFzaFVSTDtcbiAgICAgICAgdGhpcy5fd2lkdGggPSB3aWR0aDtcbiAgICAgICAgdGhpcy5faGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgICB0aGlzLl9oYW5kbGVycyA9IG5ldyBNdWx0aXBsZVZhbHVlc1JlZ2lzdHJ5KCk7XG4gICAgICAgIHRoaXMuX2NhbGxiYWNrcyA9IG5ldyBTaW5nbGVWYWx1ZVJlZ2lzdHJ5KCk7XG4gICAgICAgIHRoaXMuX3VuaXF1ZU1ldGhvZElkZW50aWZpZXIgPSB1bmlxdWUodGhpcy5fZmxhc2hJRCk7XG4gICAgICAgIHRoaXMuX3JlYWR5ID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX2hhbmRTaGFrZUhhbmRsZXIgPSBsb2FkSGFuZFNoYWtlO1xuXG4gICAgICAgIHJlZ2lzdHJ5LmFkZEluc3RhbmNlKHRoaXMuX2ZsYXNoSUQsIHRoaXMpO1xuICAgIH1cblxuICAgIG9uKGV2ZW50TmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5faGFuZGxlcnMuYWRkKGV2ZW50TmFtZSwgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIG9mZihldmVudE5hbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVycy5yZW1vdmUoZXZlbnROYW1lLCBjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgb2ZmRXZlbnQoZXZlbnROYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVycy5yZW1vdmVCeUtleShldmVudE5hbWUpO1xuICAgIH1cblxuICAgIG9mZkFsbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZXJzLnJlbW92ZUFsbCgpO1xuICAgIH1cblxuICAgIGNhbGxGbGFzaE1ldGhvZChtZXRob2ROYW1lLCBhcmdzID0gW10sIGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhciBjYWxsYmFja0lEID0gJyc7XG4gICAgICAgIC8vIGlmIG5vIGNhbGxiYWNrLCBzb21lIG1ldGhvZHMgdGhlIHJldHVybiBpcyB2b2lkIHNvIHRoZXkgZG9uJ3QgbmVlZCBjYWxsYmFja1xuICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgIGNhbGxiYWNrSUQgPSBgJHt0aGlzLl91bmlxdWVNZXRob2RJZGVudGlmaWVyKCl9XyR7bWV0aG9kTmFtZX1gO1xuICAgICAgICAgICAgdGhpcy5fY2FsbGJhY2tzLmFkZChjYWxsYmFja0lELCBjYWxsYmFjayk7XG4gICAgICAgIH1cblxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvL21ldGhvZHMgYXJlIGNyZWF0ZWQgYnkgRXh0ZXJuYWxJbnRlcmZhY2UuYWRkQ2FsbGJhY2sgaW4gYXMzIGNvZGUsIGlmIGZvciBzb21lIHJlYXNvbiBpdCBmYWlsZWRcbiAgICAgICAgICAgIC8vdGhpcyBjb2RlIHdpbGwgdGhyb3cgYW4gZXJyb3JcbiAgICAgICAgICAgIHRoaXMuX2VsW21ldGhvZE5hbWVdKFtjYWxsYmFja0lEXS5jb25jYXQoYXJncykpO1xuXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICRhc3luY0NhbGxiYWNrLmNhbGwodGhpcywgY2FsbGJhY2tJRCwgZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgLy9pZiB0aGVyZSBpc24ndCBhbnkgY2FsbGJhY2sgdG8gcmV0dXJuIGVycm9yIHVzZSBlcnJvciBldmVudCBoYW5kbGVyXG4gICAgICAgICAgICAgICAgdGhpcy5fdHJpZ2dlcihFUlJPUiwgZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZW1vdmVDYWxsYmFjayhjYWxsYmFjaykge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2FsbGJhY2tzLnJlbW92ZUJ5VmFsdWUoY2FsbGJhY2spO1xuICAgIH1cblxuICAgIHJlbW92ZUNhbGxiYWNrQnlNZXRob2ROYW1lKHN1ZmZpeCkge1xuICAgICAgICB0aGlzLl9jYWxsYmFja3MuZmlsdGVyS2V5cygoa2V5KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gc3RyaW5nRW5kc1dpdGgoa2V5LCBzdWZmaXgpO1xuICAgICAgICB9KS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrcy5yZW1vdmUoa2V5KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmVtb3ZlQWxsQ2FsbGJhY2tzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2FsbGJhY2tzLnJlbW92ZUFsbCgpO1xuICAgIH1cblxuICAgIF90cmlnZ2VyKGV2ZW50TmFtZSwgZXZlbnQpIHtcbiAgICAgICAgdGhpcy5faGFuZGxlcnMuZ2V0KGV2ZW50TmFtZSkuZm9yRWFjaCgoY2FsbGJhY2spID0+IHtcbiAgICAgICAgICAgIC8vY2xpY2tUaHJ1IGhhcyB0byBiZSBzeW5jLCBpZiBub3Qgd2lsbCBiZSBibG9jayBieSB0aGUgcG9wdXBibG9ja2VyXG4gICAgICAgICAgICBpZiAoZXZlbnROYW1lID09PSAnQWRDbGlja1RocnUnKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2hhbmRsZXJzLmdldChldmVudE5hbWUpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfY2FsbENhbGxiYWNrKG1ldGhvZE5hbWUsIGNhbGxiYWNrSUQsIGVyciwgcmVzdWx0KSB7XG5cbiAgICAgICAgbGV0IGNhbGxiYWNrID0gdGhpcy5fY2FsbGJhY2tzLmdldChjYWxsYmFja0lEKTtcblxuICAgICAgICAvL25vdCBhbGwgbWV0aG9kcyBjYWxsYmFjaydzIGFyZSBtYW5kYXRvcnlcbiAgICAgICAgLy9idXQgaWYgdGhlcmUgZXhpc3QgYW4gZXJyb3IsIGZpcmUgdGhlIGVycm9yIGV2ZW50XG4gICAgICAgIGlmICghY2FsbGJhY2spIHtcbiAgICAgICAgICAgIGlmIChlcnIgJiYgY2FsbGJhY2tJRCA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoRVJST1IsIGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAkYXN5bmNDYWxsYmFjay5jYWxsKHRoaXMsIGNhbGxiYWNrSUQsIGVyciwgcmVzdWx0KTtcblxuICAgIH1cblxuICAgIF9oYW5kU2hha2UoZXJyLCBkYXRhKSB7XG4gICAgICAgIHRoaXMuX3JlYWR5ID0gdHJ1ZTtcbiAgICAgICAgaWYgKHRoaXMuX2hhbmRTaGFrZUhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuX2hhbmRTaGFrZUhhbmRsZXIoZXJyLCBkYXRhKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9oYW5kU2hha2VIYW5kbGVyO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy9tZXRob2RzIGxpa2UgcHJvcGVydGllcyBzcGVjaWZpYyB0byB0aGlzIGltcGxlbWVudGF0aW9uIG9mIFZQQUlEXG4gICAgZ2V0U2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHt3aWR0aDogdGhpcy5fd2lkdGgsIGhlaWdodDogdGhpcy5faGVpZ2h0fTtcbiAgICB9XG4gICAgc2V0U2l6ZShuZXdXaWR0aCwgbmV3SGVpZ2h0KSB7XG4gICAgICAgIHRoaXMuX3dpZHRoID0gaXNQb3NpdGl2ZUludChuZXdXaWR0aCwgdGhpcy5fd2lkdGgpO1xuICAgICAgICB0aGlzLl9oZWlnaHQgPSBpc1Bvc2l0aXZlSW50KG5ld0hlaWdodCwgdGhpcy5faGVpZ2h0KTtcbiAgICAgICAgdGhpcy5fZWwuc2V0QXR0cmlidXRlKCd3aWR0aCcsIHRoaXMuX3dpZHRoKTtcbiAgICAgICAgdGhpcy5fZWwuc2V0QXR0cmlidXRlKCdoZWlnaHQnLCB0aGlzLl9oZWlnaHQpO1xuICAgIH1cbiAgICBnZXRXaWR0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3dpZHRoO1xuICAgIH1cbiAgICBzZXRXaWR0aChuZXdXaWR0aCkge1xuICAgICAgICB0aGlzLnNldFNpemUobmV3V2lkdGgsIHRoaXMuX2hlaWdodCk7XG4gICAgfVxuICAgIGdldEhlaWdodCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hlaWdodDtcbiAgICB9XG4gICAgc2V0SGVpZ2h0KG5ld0hlaWdodCkge1xuICAgICAgICB0aGlzLnNldFNpemUodGhpcy5fd2lkdGgsIG5ld0hlaWdodCk7XG4gICAgfVxuICAgIGdldEZsYXNoSUQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mbGFzaElEO1xuICAgIH1cbiAgICBnZXRGbGFzaFVSTCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZsYXNoVVJMO1xuICAgIH1cbiAgICBpc1JlYWR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVhZHk7XG4gICAgfVxuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMub2ZmQWxsKCk7XG4gICAgICAgIHRoaXMucmVtb3ZlQWxsQ2FsbGJhY2tzKCk7XG4gICAgICAgIHJlZ2lzdHJ5LnJlbW92ZUluc3RhbmNlQnlJRCh0aGlzLl9mbGFzaElEKTtcbiAgICAgICAgaWYgKHRoaXMuX2VsLnBhcmVudEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX2VsLnBhcmVudEVsZW1lbnQucmVtb3ZlQ2hpbGQodGhpcy5fZWwpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiAkYXN5bmNDYWxsYmFjayhjYWxsYmFja0lELCBlcnIsIHJlc3VsdCkge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBsZXQgY2FsbGJhY2sgPSB0aGlzLl9jYWxsYmFja3MuZ2V0KGNhbGxiYWNrSUQpO1xuICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrcy5yZW1vdmUoY2FsbGJhY2tJRCk7XG4gICAgICAgICAgICBjYWxsYmFjayhlcnIsIHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICB9LCAwKTtcbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEpTRmxhc2hCcmlkZ2UsICdWUEFJRF9GTEFTSF9IQU5ETEVSJywge1xuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgIHZhbHVlOiBWUEFJRF9GTEFTSF9IQU5ETEVSXG59KTtcblxuLyoqXG4gKiBFeHRlcm5hbCBpbnRlcmZhY2UgaGFuZGxlclxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBmbGFzaElEIGlkZW50aWZpZXIgb2YgdGhlIGZsYXNoIHdobyBjYWxsIHRoaXNcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlSUQgd2hhdCB0eXBlIG9mIG1lc3NhZ2UgaXMsIGNhbiBiZSAnZXZlbnQnIG9yICdjYWxsYmFjaydcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlTmFtZSBpZiB0aGUgdHlwZUlEIGlzIGEgZXZlbnQgdGhlIHR5cGVOYW1lIHdpbGwgYmUgdGhlIGV2ZW50TmFtZSwgaWYgaXMgYSBjYWxsYmFjayB0aGUgdHlwZUlEIGlzIHRoZSBtZXRob2ROYW1lIHRoYXQgaXMgcmVsYXRlZCB0aGlzIGNhbGxiYWNrXG4gKiBAcGFyYW0ge3N0cmluZ30gY2FsbGJhY2tJRCBvbmx5IGFwcGxpZXMgd2hlbiB0aGUgdHlwZUlEIGlzICdjYWxsYmFjaycsIGlkZW50aWZpZXIgb2YgdGhlIGNhbGxiYWNrIHRvIGNhbGxcbiAqIEBwYXJhbSB7b2JqZWN0fSBlcnJvciBlcnJvciBvYmplY3RcbiAqIEBwYXJhbSB7b2JqZWN0fSBkYXRhXG4gKi9cbndpbmRvd1tWUEFJRF9GTEFTSF9IQU5ETEVSXSA9IChmbGFzaElELCB0eXBlSUQsIHR5cGVOYW1lLCBjYWxsYmFja0lELCBlcnJvciwgZGF0YSkgPT4ge1xuICAgIGxldCBpbnN0YW5jZSA9IHJlZ2lzdHJ5LmdldEluc3RhbmNlQnlJRChmbGFzaElEKTtcbiAgICBpZiAoIWluc3RhbmNlKSByZXR1cm47XG4gICAgaWYgKHR5cGVOYW1lID09PSAnaGFuZFNoYWtlJykge1xuICAgICAgICBpbnN0YW5jZS5faGFuZFNoYWtlKGVycm9yLCBkYXRhKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodHlwZUlEICE9PSAnZXZlbnQnKSB7XG4gICAgICAgICAgICBpbnN0YW5jZS5fY2FsbENhbGxiYWNrKHR5cGVOYW1lLCBjYWxsYmFja0lELCBlcnJvciwgZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpbnN0YW5jZS5fdHJpZ2dlcih0eXBlTmFtZSwgZGF0YSk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG4iLCIndXNlIHN0cmljdCc7XG5cbmxldCBTaW5nbGVWYWx1ZVJlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9yZWdpc3RyeScpLlNpbmdsZVZhbHVlUmVnaXN0cnk7XG5sZXQgaW5zdGFuY2VzID0gbmV3IFNpbmdsZVZhbHVlUmVnaXN0cnkoKTtcblxuY29uc3QgSlNGbGFzaEJyaWRnZVJlZ2lzdHJ5ID0ge307XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoSlNGbGFzaEJyaWRnZVJlZ2lzdHJ5LCAnYWRkSW5zdGFuY2UnLCB7XG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIChpZCwgaW5zdGFuY2UpIHtcbiAgICAgICAgaW5zdGFuY2VzLmFkZChpZCwgaW5zdGFuY2UpO1xuICAgIH1cbn0pO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoSlNGbGFzaEJyaWRnZVJlZ2lzdHJ5LCAnZ2V0SW5zdGFuY2VCeUlEJywge1xuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoaWQpIHtcbiAgICAgICAgcmV0dXJuIGluc3RhbmNlcy5nZXQoaWQpO1xuICAgIH1cbn0pO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoSlNGbGFzaEJyaWRnZVJlZ2lzdHJ5LCAncmVtb3ZlSW5zdGFuY2VCeUlEJywge1xuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoaWQpIHtcbiAgICAgICAgcmV0dXJuIGluc3RhbmNlcy5yZW1vdmUoaWQpO1xuICAgIH1cbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEpTRmxhc2hCcmlkZ2VSZWdpc3RyeTtcblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnQgY2xhc3MgTXVsdGlwbGVWYWx1ZXNSZWdpc3RyeSB7XG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICB0aGlzLl9yZWdpc3RyaWVzID0ge307XG4gICAgfVxuICAgIGFkZCAoaWQsIHZhbHVlKSB7XG4gICAgICAgIGlmICghdGhpcy5fcmVnaXN0cmllc1tpZF0pIHtcbiAgICAgICAgICAgIHRoaXMuX3JlZ2lzdHJpZXNbaWRdID0gW107XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX3JlZ2lzdHJpZXNbaWRdLmluZGV4T2YodmFsdWUpID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5fcmVnaXN0cmllc1tpZF0ucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IChpZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVnaXN0cmllc1tpZF0gfHwgW107XG4gICAgfVxuICAgIGZpbHRlcktleXMgKGhhbmRsZXIpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuX3JlZ2lzdHJpZXMpLmZpbHRlcihoYW5kbGVyKTtcbiAgICB9XG4gICAgZmluZEJ5VmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXModGhpcy5fcmVnaXN0cmllcykuZmlsdGVyKChrZXkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9yZWdpc3RyaWVzW2tleV0uaW5kZXhPZih2YWx1ZSkgIT09IC0xO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4ga2V5cztcbiAgICB9XG4gICAgcmVtb3ZlKGtleSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9yZWdpc3RyaWVzW2tleV0pIHsgcmV0dXJuOyB9XG5cbiAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5fcmVnaXN0cmllc1trZXldLmluZGV4T2YodmFsdWUpO1xuXG4gICAgICAgIGlmIChpbmRleCA8IDApIHsgcmV0dXJuOyB9XG4gICAgICAgIHJldHVybiB0aGlzLl9yZWdpc3RyaWVzW2tleV0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICB9XG4gICAgcmVtb3ZlQnlLZXkgKGlkKSB7XG4gICAgICAgIGxldCBvbGQgPSB0aGlzLl9yZWdpc3RyaWVzW2lkXTtcbiAgICAgICAgZGVsZXRlIHRoaXMuX3JlZ2lzdHJpZXNbaWRdO1xuICAgICAgICByZXR1cm4gb2xkO1xuICAgIH1cbiAgICByZW1vdmVCeVZhbHVlICh2YWx1ZSkge1xuICAgICAgICBsZXQga2V5cyA9IHRoaXMuZmluZEJ5VmFsdWUodmFsdWUpO1xuICAgICAgICByZXR1cm4ga2V5cy5tYXAoKGtleSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVtb3ZlKGtleSwgdmFsdWUpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmVtb3ZlQWxsKCkge1xuICAgICAgICBsZXQgb2xkID0gdGhpcy5fcmVnaXN0cmllcztcbiAgICAgICAgdGhpcy5fcmVnaXN0cmllcyA9IHt9O1xuICAgICAgICByZXR1cm4gb2xkO1xuICAgIH1cbiAgICBzaXplKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5fcmVnaXN0cmllcykubGVuZ3RoO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNpbmdsZVZhbHVlUmVnaXN0cnkge1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgdGhpcy5fcmVnaXN0cmllcyA9IHt9O1xuICAgIH1cbiAgICBhZGQgKGlkLCB2YWx1ZSkge1xuICAgICAgICB0aGlzLl9yZWdpc3RyaWVzW2lkXSA9IHZhbHVlO1xuICAgIH1cbiAgICBnZXQgKGlkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZWdpc3RyaWVzW2lkXTtcbiAgICB9XG4gICAgZmlsdGVyS2V5cyAoaGFuZGxlcikge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5fcmVnaXN0cmllcykuZmlsdGVyKGhhbmRsZXIpO1xuICAgIH1cbiAgICBmaW5kQnlWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh0aGlzLl9yZWdpc3RyaWVzKS5maWx0ZXIoKGtleSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3JlZ2lzdHJpZXNba2V5XSA9PT0gdmFsdWU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBrZXlzO1xuICAgIH1cbiAgICByZW1vdmUgKGlkKSB7XG4gICAgICAgIGxldCBvbGQgPSB0aGlzLl9yZWdpc3RyaWVzW2lkXTtcbiAgICAgICAgZGVsZXRlIHRoaXMuX3JlZ2lzdHJpZXNbaWRdO1xuICAgICAgICByZXR1cm4gb2xkO1xuICAgIH1cbiAgICByZW1vdmVCeVZhbHVlICh2YWx1ZSkge1xuICAgICAgICBsZXQga2V5cyA9IHRoaXMuZmluZEJ5VmFsdWUodmFsdWUpO1xuICAgICAgICByZXR1cm4ga2V5cy5tYXAoKGtleSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVtb3ZlKGtleSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZW1vdmVBbGwoKSB7XG4gICAgICAgIGxldCBvbGQgPSB0aGlzLl9yZWdpc3RyaWVzO1xuICAgICAgICB0aGlzLl9yZWdpc3RyaWVzID0ge307XG4gICAgICAgIHJldHVybiBvbGQ7XG4gICAgfVxuICAgIHNpemUoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLl9yZWdpc3RyaWVzKS5sZW5ndGg7XG4gICAgfVxufVxuXG4iLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydCBmdW5jdGlvbiB1bmlxdWUocHJlZml4KSB7XG4gICAgbGV0IGNvdW50ID0gLTE7XG4gICAgcmV0dXJuIGYgPT4ge1xuICAgICAgICByZXR1cm4gYCR7cHJlZml4fV8keysrY291bnR9YDtcbiAgICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbm9vcCgpIHtcbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gY2FsbGJhY2tUaW1lb3V0KHRpbWVyLCBvblN1Y2Nlc3MsIG9uVGltZW91dCkge1xuXG4gICAgbGV0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcblxuICAgICAgICBvblN1Y2Nlc3MgPSBub29wO1xuICAgICAgICBvblRpbWVvdXQoKTtcblxuICAgIH0sIHRpbWVyKTtcblxuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgb25TdWNjZXNzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfTtcbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRWxlbWVudFdpdGhJRChwYXJlbnQsIGlkKSB7XG4gICAgdmFyIG5FbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIG5FbC5pZCA9IGlkO1xuICAgIHBhcmVudC5pbm5lckhUTUwgPSAnJztcbiAgICBwYXJlbnQuYXBwZW5kQ2hpbGQobkVsKTtcbiAgICByZXR1cm4gbkVsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNQb3NpdGl2ZUludChuZXdWYWwsIG9sZFZhbCkge1xuICAgIHJldHVybiAhaXNOYU4ocGFyc2VGbG9hdChuZXdWYWwpKSAmJiBpc0Zpbml0ZShuZXdWYWwpICYmIG5ld1ZhbCA+IDAgPyBuZXdWYWwgOiBvbGRWYWw7XG59XG5cbmxldCBlbmRzV2l0aCA9IChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKFN0cmluZy5wcm90b3R5cGUuZW5kc1dpdGgpIHJldHVybiBTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoO1xuICAgIHJldHVybiBmdW5jdGlvbiBlbmRzV2l0aCAoc2VhcmNoU3RyaW5nLCBwb3NpdGlvbikge1xuICAgICAgICB2YXIgc3ViamVjdFN0cmluZyA9IHRoaXMudG9TdHJpbmcoKTtcbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSB1bmRlZmluZWQgfHwgcG9zaXRpb24gPiBzdWJqZWN0U3RyaW5nLmxlbmd0aCkge1xuICAgICAgICAgICAgcG9zaXRpb24gPSBzdWJqZWN0U3RyaW5nLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBwb3NpdGlvbiAtPSBzZWFyY2hTdHJpbmcubGVuZ3RoO1xuICAgICAgICB2YXIgbGFzdEluZGV4ID0gc3ViamVjdFN0cmluZy5pbmRleE9mKHNlYXJjaFN0cmluZywgcG9zaXRpb24pO1xuICAgICAgICByZXR1cm4gbGFzdEluZGV4ICE9PSAtMSAmJiBsYXN0SW5kZXggPT09IHBvc2l0aW9uO1xuICAgIH1cbn0pKCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBzdHJpbmdFbmRzV2l0aChzdHJpbmcsIHNlYXJjaCkge1xuICAgIHJldHVybiBlbmRzV2l0aC5jYWxsKHN0cmluZywgc2VhcmNoKTtcbn1cblxuXG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBNRVRIT0RTID0gW1xuICAgICdoYW5kc2hha2VWZXJzaW9uJyxcbiAgICAnaW5pdEFkJyxcbiAgICAnc3RhcnRBZCcsXG4gICAgJ3N0b3BBZCcsXG4gICAgJ3NraXBBZCcsIC8vIFZQQUlEIDIuMCBuZXcgbWV0aG9kXG4gICAgJ3Jlc2l6ZUFkJyxcbiAgICAncGF1c2VBZCcsXG4gICAgJ3Jlc3VtZUFkJyxcbiAgICAnZXhwYW5kQWQnLFxuICAgICdjb2xsYXBzZUFkJyxcbiAgICAnc3Vic2NyaWJlJyxcbiAgICAndW5zdWJzY3JpYmUnXG5dO1xuXG52YXIgRVZFTlRTID0gW1xuICAgICdBZExvYWRlZCcsXG4gICAgJ0FkU3RhcnRlZCcsXG4gICAgJ0FkU3RvcHBlZCcsXG4gICAgJ0FkU2tpcHBlZCcsXG4gICAgJ0FkU2tpcHBhYmxlU3RhdGVDaGFuZ2UnLCAvLyBWUEFJRCAyLjAgbmV3IGV2ZW50XG4gICAgJ0FkU2l6ZUNoYW5nZScsIC8vIFZQQUlEIDIuMCBuZXcgZXZlbnRcbiAgICAnQWRMaW5lYXJDaGFuZ2UnLFxuICAgICdBZER1cmF0aW9uQ2hhbmdlJywgLy8gVlBBSUQgMi4wIG5ldyBldmVudFxuICAgICdBZEV4cGFuZGVkQ2hhbmdlJyxcbiAgICAnQWRSZW1haW5pbmdUaW1lQ2hhbmdlJywgLy8gW0RlcHJlY2F0ZWQgaW4gMi4wXSBidXQgd2lsbCBiZSBzdGlsbCBmaXJlZCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHlcbiAgICAnQWRWb2x1bWVDaGFuZ2UnLFxuICAgICdBZEltcHJlc3Npb24nLFxuICAgICdBZFZpZGVvU3RhcnQnLFxuICAgICdBZFZpZGVvRmlyc3RRdWFydGlsZScsXG4gICAgJ0FkVmlkZW9NaWRwb2ludCcsXG4gICAgJ0FkVmlkZW9UaGlyZFF1YXJ0aWxlJyxcbiAgICAnQWRWaWRlb0NvbXBsZXRlJyxcbiAgICAnQWRDbGlja1RocnUnLFxuICAgICdBZEludGVyYWN0aW9uJywgLy8gVlBBSUQgMi4wIG5ldyBldmVudFxuICAgICdBZFVzZXJBY2NlcHRJbnZpdGF0aW9uJyxcbiAgICAnQWRVc2VyTWluaW1pemUnLFxuICAgICdBZFVzZXJDbG9zZScsXG4gICAgJ0FkUGF1c2VkJyxcbiAgICAnQWRQbGF5aW5nJyxcbiAgICAnQWRMb2cnLFxuICAgICdBZEVycm9yJ1xuXTtcblxudmFyIEdFVFRFUlMgPSBbXG4gICAgJ2dldEFkTGluZWFyJyxcbiAgICAnZ2V0QWRXaWR0aCcsIC8vIFZQQUlEIDIuMCBuZXcgZ2V0dGVyXG4gICAgJ2dldEFkSGVpZ2h0JywgLy8gVlBBSUQgMi4wIG5ldyBnZXR0ZXJcbiAgICAnZ2V0QWRFeHBhbmRlZCcsXG4gICAgJ2dldEFkU2tpcHBhYmxlU3RhdGUnLCAvLyBWUEFJRCAyLjAgbmV3IGdldHRlclxuICAgICdnZXRBZFJlbWFpbmluZ1RpbWUnLFxuICAgICdnZXRBZER1cmF0aW9uJywgLy8gVlBBSUQgMi4wIG5ldyBnZXR0ZXJcbiAgICAnZ2V0QWRWb2x1bWUnLFxuICAgICdnZXRBZENvbXBhbmlvbnMnLCAvLyBWUEFJRCAyLjAgbmV3IGdldHRlclxuICAgICdnZXRBZEljb25zJyAvLyBWUEFJRCAyLjAgbmV3IGdldHRlclxuXTtcblxudmFyIFNFVFRFUlMgPSBbXG4gICAgJ3NldEFkVm9sdW1lJ1xuXTtcblxuXG4vKipcbiAqIFRoaXMgY2FsbGJhY2sgaXMgZGlzcGxheWVkIGFzIGdsb2JhbCBtZW1iZXIuIFRoZSBjYWxsYmFjayB1c2Ugbm9kZWpzIGVycm9yLWZpcnN0IGNhbGxiYWNrIHN0eWxlXG4gKiBAY2FsbGJhY2sgTm9kZVN0eWxlQ2FsbGJhY2tcbiAqIEBwYXJhbSB7c3RyaW5nfG51bGx9XG4gKiBAcGFyYW0ge3VuZGVmaW5lZHxvYmplY3R9XG4gKi9cblxuXG4vKipcbiAqIElWUEFJREFkVW5pdFxuICpcbiAqIEBjbGFzc1xuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBjcmVhdGl2ZVxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7SFRNTFZpZGVvRWxlbWVudH0gdmlkZW9cbiAqL1xuZnVuY3Rpb24gSVZQQUlEQWRVbml0KGNyZWF0aXZlLCBlbCwgdmlkZW8pIHt9XG5cblxuLyoqXG4gKiBoYW5kc2hha2VWZXJzaW9uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFZQQUlEVmVyc2lvblxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5oYW5kc2hha2VWZXJzaW9uID0gZnVuY3Rpb24gKFZQQUlEVmVyc2lvbiwgY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIGluaXRBZFxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSB3aWR0aFxuICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodFxuICogQHBhcmFtIHtzdHJpbmd9IHZpZXdNb2RlIGNhbiBiZSAnbm9ybWFsJywgJ3RodW1ibmFpbCcgb3IgJ2Z1bGxzY3JlZW4nXG4gKiBAcGFyYW0ge251bWJlcn0gZGVzaXJlZEJpdHJhdGUgaW5kaWNhdGVzIHRoZSBkZXNpcmVkIGJpdHJhdGUgaW4ga2Jwc1xuICogQHBhcmFtIHtvYmplY3R9IFtjcmVhdGl2ZURhdGFdIHVzZWQgZm9yIGFkZGl0aW9uYWwgaW5pdGlhbGl6YXRpb24gZGF0YVxuICogQHBhcmFtIHtvYmplY3R9IFtlbnZpcm9ubWVudFZhcnNdIHVzZWQgZm9yIHBhc3NpbmcgaW1wbGVtZW50YXRpb24tc3BlY2lmaWMgb2YganMgdmVyc2lvblxuICogQHBhcmFtIHtOb2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5pbml0QWQgPSBmdW5jdGlvbih3aWR0aCwgaGVpZ2h0LCB2aWV3TW9kZSwgZGVzaXJlZEJpdHJhdGUsIGNyZWF0aXZlRGF0YSwgZW52aXJvbm1lbnRWYXJzLCBjYWxsYmFjaykge307XG5cbi8qKlxuICogc3RhcnRBZFxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuc3RhcnRBZCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBzdG9wQWRcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLnN0b3BBZCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBza2lwQWRcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLnNraXBBZCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiByZXNpemVBZFxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUucmVzaXplQWQgPSBmdW5jdGlvbih3aWR0aCwgaGVpZ2h0LCB2aWV3TW9kZSwgY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIHBhdXNlQWRcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLnBhdXNlQWQgPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogcmVzdW1lQWRcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLnJlc3VtZUFkID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIGV4cGFuZEFkXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5leHBhbmRBZCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBjb2xsYXBzZUFkXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5jb2xsYXBzZUFkID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIHN1YnNjcmliZVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gaGFuZGxlclxuICogQHBhcmFtIHtvYmplY3R9IGNvbnRleHRcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5zdWJzY3JpYmUgPSBmdW5jdGlvbihldmVudCwgaGFuZGxlciwgY29udGV4dCkge307XG5cbi8qKlxuICogc3RhcnRBZFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtmdW5jdGlvbn0gaGFuZGxlclxuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLnVuc3Vic2NyaWJlID0gZnVuY3Rpb24oZXZlbnQsIGhhbmRsZXIpIHt9O1xuXG5cblxuLyoqXG4gKiBnZXRBZExpbmVhclxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuZ2V0QWRMaW5lYXIgPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogZ2V0QWRXaWR0aFxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuZ2V0QWRXaWR0aCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBnZXRBZEhlaWdodFxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuZ2V0QWRIZWlnaHQgPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogZ2V0QWRFeHBhbmRlZFxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuZ2V0QWRFeHBhbmRlZCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBnZXRBZFNraXBwYWJsZVN0YXRlXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5nZXRBZFNraXBwYWJsZVN0YXRlID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIGdldEFkUmVtYWluaW5nVGltZVxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuZ2V0QWRSZW1haW5pbmdUaW1lID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIGdldEFkRHVyYXRpb25cbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLmdldEFkRHVyYXRpb24gPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogZ2V0QWRWb2x1bWVcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLmdldEFkVm9sdW1lID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIGdldEFkQ29tcGFuaW9uc1xuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuZ2V0QWRDb21wYW5pb25zID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIGdldEFkSWNvbnNcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLmdldEFkSWNvbnMgPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogc2V0QWRWb2x1bWVcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gdm9sdW1lXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLnNldEFkVm9sdW1lID0gZnVuY3Rpb24odm9sdW1lLCBjYWxsYmFjaykge307XG5cbmFkZFN0YXRpY1RvSW50ZXJmYWNlKElWUEFJREFkVW5pdCwgJ01FVEhPRFMnLCBNRVRIT0RTKTtcbmFkZFN0YXRpY1RvSW50ZXJmYWNlKElWUEFJREFkVW5pdCwgJ0dFVFRFUlMnLCBHRVRURVJTKTtcbmFkZFN0YXRpY1RvSW50ZXJmYWNlKElWUEFJREFkVW5pdCwgJ1NFVFRFUlMnLCBTRVRURVJTKTtcbmFkZFN0YXRpY1RvSW50ZXJmYWNlKElWUEFJREFkVW5pdCwgJ0VWRU5UUycsICBFVkVOVFMpO1xuXG5cbnZhciBWUEFJRDFfTUVUSE9EUyA9IE1FVEhPRFMuZmlsdGVyKGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgIHJldHVybiBbJ3NraXBBZCddLmluZGV4T2YobWV0aG9kKSA9PT0gLTE7XG59KTtcblxuYWRkU3RhdGljVG9JbnRlcmZhY2UoSVZQQUlEQWRVbml0LCAnY2hlY2tWUEFJREludGVyZmFjZScsIGZ1bmN0aW9uIGNoZWNrVlBBSURJbnRlcmZhY2UgKGNyZWF0aXZlKSB7XG4gICAgdmFyIHJlc3VsdCA9IFZQQUlEMV9NRVRIT0RTLmV2ZXJ5KGZ1bmN0aW9uKGtleSkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIGNyZWF0aXZlW2tleV0gPT09ICdmdW5jdGlvbic7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IElWUEFJREFkVW5pdDtcblxuZnVuY3Rpb24gYWRkU3RhdGljVG9JbnRlcmZhY2UoSW50ZXJmYWNlLCBuYW1lLCB2YWx1ZSkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShJbnRlcmZhY2UsIG5hbWUsIHtcbiAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICB2YWx1ZTogdmFsdWVcbiAgICB9KTtcbn1cblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgSVZQQUlEQWRVbml0ID0gcmVxdWlyZSgnLi9JVlBBSURBZFVuaXQnKTtcbnZhciBTdWJzY3JpYmVyID0gcmVxdWlyZSgnLi9zdWJzY3JpYmVyJyk7XG52YXIgY2hlY2tWUEFJREludGVyZmFjZSA9IElWUEFJREFkVW5pdC5jaGVja1ZQQUlESW50ZXJmYWNlO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIE1FVEhPRFMgPSBJVlBBSURBZFVuaXQuTUVUSE9EUztcbnZhciBFUlJPUiA9ICdBZEVycm9yJztcbnZhciBBRF9DTElDSyA9ICdBZENsaWNrVGhydSc7XG52YXIgRklMVEVSRURfRVZFTlRTID0gSVZQQUlEQWRVbml0LkVWRU5UUy5maWx0ZXIoZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgcmV0dXJuIGV2ZW50ICE9IEFEX0NMSUNLO1xufSk7XG5cbi8qKlxuICogVGhpcyBjYWxsYmFjayBpcyBkaXNwbGF5ZWQgYXMgZ2xvYmFsIG1lbWJlci4gVGhlIGNhbGxiYWNrIHVzZSBub2RlanMgZXJyb3ItZmlyc3QgY2FsbGJhY2sgc3R5bGVcbiAqIEBjYWxsYmFjayBOb2RlU3R5bGVDYWxsYmFja1xuICogQHBhcmFtIHtzdHJpbmd8bnVsbH1cbiAqIEBwYXJhbSB7dW5kZWZpbmVkfG9iamVjdH1cbiAqL1xuXG5cbi8qKlxuICogVlBBSURBZFVuaXRcbiAqIEBjbGFzc1xuICpcbiAqIEBwYXJhbSBWUEFJRENyZWF0aXZlXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBbZWxdIHRoaXMgd2lsbCBiZSB1c2VkIGluIGluaXRBZCBlbnZpcm9ubWVudFZhcnMuc2xvdCBpZiBkZWZpbmVkXG4gKiBAcGFyYW0ge0hUTUxWaWRlb0VsZW1lbnR9IFt2aWRlb10gdGhpcyB3aWxsIGJlIHVzZWQgaW4gaW5pdEFkIGVudmlyb25tZW50VmFycy52aWRlb1Nsb3QgaWYgZGVmaW5lZFxuICovXG5mdW5jdGlvbiBWUEFJREFkVW5pdChWUEFJRENyZWF0aXZlLCBlbCwgdmlkZW8sIGlmcmFtZSkge1xuICAgIHRoaXMuX2lzVmFsaWQgPSBjaGVja1ZQQUlESW50ZXJmYWNlKFZQQUlEQ3JlYXRpdmUpO1xuICAgIGlmICh0aGlzLl9pc1ZhbGlkKSB7XG4gICAgICAgIHRoaXMuX2NyZWF0aXZlID0gVlBBSURDcmVhdGl2ZTtcbiAgICAgICAgdGhpcy5fZWwgPSBlbDtcbiAgICAgICAgdGhpcy5fdmlkZW9FbCA9IHZpZGVvO1xuICAgICAgICB0aGlzLl9pZnJhbWUgPSBpZnJhbWU7XG4gICAgICAgIHRoaXMuX3N1YnNjcmliZXJzID0gbmV3IFN1YnNjcmliZXIoKTtcbiAgICAgICAgJGFkZEV2ZW50c1N1YnNjcmliZXJzLmNhbGwodGhpcyk7XG4gICAgfVxufVxuXG5WUEFJREFkVW5pdC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKElWUEFJREFkVW5pdC5wcm90b3R5cGUpO1xuXG4vKipcbiAqIGlzVmFsaWRWUEFJREFkIHdpbGwgcmV0dXJuIGlmIHRoZSBWUEFJRENyZWF0aXZlIHBhc3NlZCBpbiBjb25zdHJ1Y3RvciBpcyB2YWxpZCBvciBub3RcbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5WUEFJREFkVW5pdC5wcm90b3R5cGUuaXNWYWxpZFZQQUlEQWQgPSBmdW5jdGlvbiBpc1ZhbGlkVlBBSURBZCgpIHtcbiAgICByZXR1cm4gdGhpcy5faXNWYWxpZDtcbn07XG5cbklWUEFJREFkVW5pdC5NRVRIT0RTLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgLy9OT1RFOiB0aGlzIG1ldGhvZHMgYXJndW1lbnRzIG9yZGVyIGFyZSBpbXBsZW1lbnRlZCBkaWZmZXJlbnRseSBmcm9tIHRoZSBzcGVjXG4gICAgdmFyIGlnbm9yZXMgPSBbXG4gICAgICAgICdzdWJzY3JpYmUnLFxuICAgICAgICAndW5zdWJzY3JpYmUnLFxuICAgICAgICAnaW5pdEFkJ1xuICAgIF07XG5cbiAgICBpZiAoaWdub3Jlcy5pbmRleE9mKG1ldGhvZCkgIT09IC0xKSByZXR1cm47XG5cbiAgICBWUEFJREFkVW5pdC5wcm90b3R5cGVbbWV0aG9kXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGFyaWF0eSA9IElWUEFJREFkVW5pdC5wcm90b3R5cGVbbWV0aG9kXS5sZW5ndGg7XG4gICAgICAgIC8vIFRPRE8gYXZvaWQgbGVha2luZyBhcmd1bWVudHNcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3BldGthYW50b25vdi9ibHVlYmlyZC93aWtpL09wdGltaXphdGlvbi1raWxsZXJzIzMyLWxlYWtpbmctYXJndW1lbnRzXG4gICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gKGFyaWF0eSA9PT0gYXJncy5sZW5ndGgpID8gYXJncy5wb3AoKSA6IHVuZGVmaW5lZDtcblxuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQsIGVycm9yID0gbnVsbDtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gdGhpcy5fY3JlYXRpdmVbbWV0aG9kXS5hcHBseSh0aGlzLl9jcmVhdGl2ZSwgYXJncyk7XG4gICAgICAgICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgICAgICAgICBlcnJvciA9IGU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhbGxPclRyaWdnZXJFdmVudChjYWxsYmFjaywgdGhpcy5fc3Vic2NyaWJlcnMsIGVycm9yLCByZXN1bHQpO1xuICAgICAgICB9LmJpbmQodGhpcyksIDApO1xuICAgIH07XG59KTtcblxuXG4vKipcbiAqIGluaXRBZCBjb25jcmVhdGUgaW1wbGVtZW50YXRpb25cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gd2lkdGhcbiAqIEBwYXJhbSB7bnVtYmVyfSBoZWlnaHRcbiAqIEBwYXJhbSB7c3RyaW5nfSB2aWV3TW9kZSBjYW4gYmUgJ25vcm1hbCcsICd0aHVtYm5haWwnIG9yICdmdWxsc2NyZWVuJ1xuICogQHBhcmFtIHtudW1iZXJ9IGRlc2lyZWRCaXRyYXRlIGluZGljYXRlcyB0aGUgZGVzaXJlZCBiaXRyYXRlIGluIGticHNcbiAqIEBwYXJhbSB7b2JqZWN0fSBbY3JlYXRpdmVEYXRhXSB1c2VkIGZvciBhZGRpdGlvbmFsIGluaXRpYWxpemF0aW9uIGRhdGFcbiAqIEBwYXJhbSB7b2JqZWN0fSBbZW52aXJvbm1lbnRWYXJzXSB1c2VkIGZvciBwYXNzaW5nIGltcGxlbWVudGF0aW9uLXNwZWNpZmljIG9mIGpzIHZlcnNpb24sIGlmIGVsICYgdmlkZW8gd2FzIHVzZWQgaW4gY29uc3RydWN0b3Igc2xvdCAmIHZpZGVvU2xvdCB3aWxsIGJlIGFkZGVkIHRvIHRoZSBvYmplY3RcbiAqIEBwYXJhbSB7Tm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cblZQQUlEQWRVbml0LnByb3RvdHlwZS5pbml0QWQgPSBmdW5jdGlvbiBpbml0QWQod2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGRlc2lyZWRCaXRyYXRlLCBjcmVhdGl2ZURhdGEsIGVudmlyb25tZW50VmFycywgY2FsbGJhY2spIHtcbiAgICBjcmVhdGl2ZURhdGEgPSBjcmVhdGl2ZURhdGEgfHwge307XG4gICAgZW52aXJvbm1lbnRWYXJzID0gdXRpbHMuZXh0ZW5kKHtcbiAgICAgICAgc2xvdDogdGhpcy5fZWwsXG4gICAgICAgIHZpZGVvU2xvdDogdGhpcy5fdmlkZW9FbFxuICAgIH0sIGVudmlyb25tZW50VmFycyB8fCB7fSk7XG5cbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGVycm9yO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRpdmUuaW5pdEFkKHdpZHRoLCBoZWlnaHQsIHZpZXdNb2RlLCBkZXNpcmVkQml0cmF0ZSwgY3JlYXRpdmVEYXRhLCBlbnZpcm9ubWVudFZhcnMpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBlcnJvciA9IGU7XG4gICAgICAgIH1cblxuICAgICAgICBjYWxsT3JUcmlnZ2VyRXZlbnQoY2FsbGJhY2ssIHRoaXMuX3N1YnNjcmliZXJzLCBlcnJvcik7XG4gICAgfS5iaW5kKHRoaXMpLCAwKTtcbn07XG5cbi8qKlxuICogc3Vic2NyaWJlXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBoYW5kbGVyXG4gKiBAcGFyYW0ge29iamVjdH0gY29udGV4dFxuICovXG5WUEFJREFkVW5pdC5wcm90b3R5cGUuc3Vic2NyaWJlID0gZnVuY3Rpb24gc3Vic2NyaWJlKGV2ZW50LCBoYW5kbGVyLCBjb250ZXh0KSB7XG4gICAgdGhpcy5fc3Vic2NyaWJlcnMuc3Vic2NyaWJlKGhhbmRsZXIsIGV2ZW50LCBjb250ZXh0KTtcbn07XG5cblxuLyoqXG4gKiB1bnN1YnNjcmliZVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gaGFuZGxlclxuICovXG5WUEFJREFkVW5pdC5wcm90b3R5cGUudW5zdWJzY3JpYmUgPSBmdW5jdGlvbiB1bnN1YnNjcmliZShldmVudCwgaGFuZGxlcikge1xuICAgIHRoaXMuX3N1YnNjcmliZXJzLnVuc3Vic2NyaWJlKGhhbmRsZXIsIGV2ZW50KTtcbn07XG5cbi8vYWxpYXNcblZQQUlEQWRVbml0LnByb3RvdHlwZS5vbiA9IFZQQUlEQWRVbml0LnByb3RvdHlwZS5zdWJzY3JpYmU7XG5WUEFJREFkVW5pdC5wcm90b3R5cGUub2ZmID0gVlBBSURBZFVuaXQucHJvdG90eXBlLnVuc3Vic2NyaWJlO1xuXG5JVlBBSURBZFVuaXQuR0VUVEVSUy5mb3JFYWNoKGZ1bmN0aW9uKGdldHRlcikge1xuICAgIFZQQUlEQWRVbml0LnByb3RvdHlwZVtnZXR0ZXJdID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICB2YXIgcmVzdWx0LCBlcnJvciA9IG51bGw7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRoaXMuX2NyZWF0aXZlW2dldHRlcl0oKTtcbiAgICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgICAgIGVycm9yID0gZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FsbE9yVHJpZ2dlckV2ZW50KGNhbGxiYWNrLCB0aGlzLl9zdWJzY3JpYmVycywgZXJyb3IsIHJlc3VsdCk7XG4gICAgICAgIH0uYmluZCh0aGlzKSwgMCk7XG4gICAgfTtcbn0pO1xuXG4vKipcbiAqIHNldEFkVm9sdW1lXG4gKlxuICogQHBhcmFtIHZvbHVtZVxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuVlBBSURBZFVuaXQucHJvdG90eXBlLnNldEFkVm9sdW1lID0gZnVuY3Rpb24gc2V0QWRWb2x1bWUodm9sdW1lLCBjYWxsYmFjaykge1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIHZhciByZXN1bHQsIGVycm9yID0gbnVsbDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0aXZlLnNldEFkVm9sdW1lKHZvbHVtZSk7XG4gICAgICAgICAgICByZXN1bHQgPSB0aGlzLl9jcmVhdGl2ZS5nZXRBZFZvbHVtZSgpO1xuICAgICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgICAgIGVycm9yID0gZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghZXJyb3IpIHtcbiAgICAgICAgICAgIGVycm9yID0gdXRpbHMudmFsaWRhdGUocmVzdWx0ID09PSB2b2x1bWUsICdmYWlsZWQgdG8gYXBwbHkgdm9sdW1lOiAnICsgdm9sdW1lKTtcbiAgICAgICAgfVxuICAgICAgICBjYWxsT3JUcmlnZ2VyRXZlbnQoY2FsbGJhY2ssIHRoaXMuX3N1YnNjcmliZXJzLCBlcnJvciwgcmVzdWx0KTtcbiAgICB9LmJpbmQodGhpcyksIDApO1xufTtcblxuVlBBSURBZFVuaXQucHJvdG90eXBlLl9kZXN0cm95ID0gZnVuY3Rpb24gZGVzdHJveSgpIHtcbiAgICB0aGlzLnN0b3BBZCgpO1xuICAgIHRoaXMuX3N1YnNjcmliZXJzLnVuc3Vic2NyaWJlQWxsKCk7XG59O1xuXG5mdW5jdGlvbiAkYWRkRXZlbnRzU3Vic2NyaWJlcnMoKSB7XG4gICAgLy8gc29tZSBhZHMgaW1wbGVtZW50XG4gICAgLy8gc28gdGhleSBvbmx5IGhhbmRsZSBvbmUgc3Vic2NyaWJlclxuICAgIC8vIHRvIGhhbmRsZSB0aGlzIHdlIGNyZWF0ZSBvdXIgb25lXG4gICAgRklMVEVSRURfRVZFTlRTLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuX2NyZWF0aXZlLnN1YnNjcmliZSgkdHJpZ2dlci5iaW5kKHRoaXMsIGV2ZW50KSwgZXZlbnQpO1xuICAgIH0uYmluZCh0aGlzKSk7XG5cbiAgICAvLyBtYXAgdGhlIGNsaWNrIGV2ZW50IHRvIGJlIGFuIG9iamVjdCBpbnN0ZWFkIG9mIGRlcGVuZGluZyBvZiB0aGUgb3JkZXIgb2YgdGhlIGFyZ3VtZW50c1xuICAgIC8vIGFuZCB0byBiZSBjb25zaXN0ZW50IHdpdGggdGhlIGZsYXNoXG4gICAgdGhpcy5fY3JlYXRpdmUuc3Vic2NyaWJlKCRjbGlja1RocnVIb29rLmJpbmQodGhpcyksIEFEX0NMSUNLKTtcblxuICAgIC8vIGJlY2F1c2Ugd2UgYXJlIGFkZGluZyB0aGUgZWxlbWVudCBpbnNpZGUgdGhlIGlmcmFtZVxuICAgIC8vIHRoZSB1c2VyIGlzIG5vdCBhYmxlIHRvIGNsaWNrIGluIHRoZSB2aWRlb1xuICAgIGlmICh0aGlzLl92aWRlb0VsKSB7XG4gICAgICAgIHZhciBkb2N1bWVudEVsZW1lbnQgPSB0aGlzLl9pZnJhbWUuY29udGVudERvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgICAgICAgdmFyIHZpZGVvRWwgPSB0aGlzLl92aWRlb0VsO1xuICAgICAgICBkb2N1bWVudEVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICBpZiAoZS50YXJnZXQgPT09IGRvY3VtZW50RWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHZpZGVvRWwuY2xpY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiAkY2xpY2tUaHJ1SG9vayh1cmwsIGlkLCBwbGF5ZXJIYW5kbGVzKSB7XG4gICAgdGhpcy5fc3Vic2NyaWJlcnMudHJpZ2dlclN5bmMoQURfQ0xJQ0ssIHt1cmw6IHVybCwgaWQ6IGlkLCBwbGF5ZXJIYW5kbGVzOiBwbGF5ZXJIYW5kbGVzfSk7XG59XG5cbmZ1bmN0aW9uICR0cmlnZ2VyKGV2ZW50KSB7XG4gICAgLy8gVE9ETyBhdm9pZCBsZWFraW5nIGFyZ3VtZW50c1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9wZXRrYWFudG9ub3YvYmx1ZWJpcmQvd2lraS9PcHRpbWl6YXRpb24ta2lsbGVycyMzMi1sZWFraW5nLWFyZ3VtZW50c1xuICAgIHRoaXMuX3N1YnNjcmliZXJzLnRyaWdnZXIoZXZlbnQsIEFycmF5LnByb3RvdHlwZS5zbGljZShhcmd1bWVudHMsIDEpKTtcbn1cblxuZnVuY3Rpb24gY2FsbE9yVHJpZ2dlckV2ZW50KGNhbGxiYWNrLCBzdWJzY3JpYmVycywgZXJyb3IsIHJlc3VsdCkge1xuICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICB9IGVsc2UgaWYgKGVycm9yKSB7XG4gICAgICAgIHN1YnNjcmliZXJzLnRyaWdnZXIoRVJST1IsIGVycm9yKTtcbiAgICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gVlBBSURBZFVuaXQ7XG5cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIHVuaXF1ZSA9IHV0aWxzLnVuaXF1ZSgndnBhaWRJZnJhbWUnKTtcbnZhciBWUEFJREFkVW5pdCA9IHJlcXVpcmUoJy4vVlBBSURBZFVuaXQnKTtcblxudmFyIGRlZmF1bHRUZW1wbGF0ZSA9ICc8IURPQ1RZUEUgaHRtbD48aHRtbCBsYW5nPVwiZW5cIj48aGVhZD48bWV0YSBjaGFyc2V0PVwiVVRGLThcIj48L2hlYWQ+PGJvZHkgc3R5bGU9XCJtYXJnaW46MDtwYWRkaW5nOjBcIj4nO1xuZGVmYXVsdFRlbXBsYXRlICs9ICc8c2NyaXB0IHR5cGU9XCJ0ZXh0L2phdmFzY3JpcHRcIiBzcmM9XCJ7e2lmcmFtZVVSTF9KU319XCI+PC9zY3JpcHQ+PHNjcmlwdD4nO1xuZGVmYXVsdFRlbXBsYXRlICs9ICdwYXJlbnQucG9zdE1lc3NhZ2UoXFwne1wiZXZlbnRcIjogXCJyZWFkeVwiLCBcImlkXCI6IFwie3tpZnJhbWVJRH19XCJ9XFwnLCB3aW5kb3cubG9jYXRpb24ub3JpZ2luKTsnO1xuZGVmYXVsdFRlbXBsYXRlICs9ICc8L3NjcmlwdD48ZGl2IGNsYXNzPVwiYWQtZWxlbWVudFwiPjwvZGl2PjwvYm9keT48L2h0bWw+JztcblxudmFyIEFEX1NUT1BQRUQgPSAnQWRTdG9wcGVkJztcblxuLyoqXG4gKiBUaGlzIGNhbGxiYWNrIGlzIGRpc3BsYXllZCBhcyBnbG9iYWwgbWVtYmVyLiBUaGUgY2FsbGJhY2sgdXNlIG5vZGVqcyBlcnJvci1maXJzdCBjYWxsYmFjayBzdHlsZVxuICogQGNhbGxiYWNrIE5vZGVTdHlsZUNhbGxiYWNrXG4gKiBAcGFyYW0ge3N0cmluZ3xudWxsfVxuICogQHBhcmFtIHt1bmRlZmluZWR8b2JqZWN0fVxuICovXG5cbi8qKlxuICogVlBBSURIVE1MNUNsaWVudFxuICogQGNsYXNzXG4gKlxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWwgdGhhdCB3aWxsIGNvbnRhaW4gdGhlIGlmcmFtZSB0byBsb2FkIGFkVW5pdCBhbmQgYSBlbCB0byBhZGQgdG8gYWRVbml0IHNsb3RcbiAqIEBwYXJhbSB7SFRNTFZpZGVvRWxlbWVudH0gdmlkZW8gZGVmYXVsdCB2aWRlbyBlbGVtZW50IHRvIGJlIHVzZWQgYnkgYWRVbml0XG4gKiBAcGFyYW0ge29iamVjdH0gW3RlbXBsYXRlQ29uZmlnXSB0ZW1wbGF0ZTogaHRtbCB0ZW1wbGF0ZSB0byBiZSB1c2VkIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQsIGV4dHJhT3B0aW9uczogdG8gYmUgdXNlZCB3aGVuIHJlbmRlcmluZyB0aGUgdGVtcGxhdGVcbiAqIEBwYXJhbSB7b2JqZWN0fSBbdnBhaWRPcHRpb25zXSB0aW1lb3V0OiB3aGVuIGxvYWRpbmcgYWRVbml0XG4gKi9cbmZ1bmN0aW9uIFZQQUlESFRNTDVDbGllbnQoZWwsIHZpZGVvLCB0ZW1wbGF0ZUNvbmZpZywgdnBhaWRPcHRpb25zKSB7XG4gICAgdGVtcGxhdGVDb25maWcgPSB0ZW1wbGF0ZUNvbmZpZyB8fCB7fTtcblxuICAgIHRoaXMuX2lkID0gdW5pcXVlKCk7XG4gICAgdGhpcy5fZGVzdHJveWVkID0gZmFsc2U7XG5cbiAgICB0aGlzLl9mcmFtZUNvbnRhaW5lciA9IHV0aWxzLmNyZWF0ZUVsZW1lbnRJbkVsKGVsLCAnZGl2Jyk7XG4gICAgdGhpcy5fdmlkZW9FbCA9IHZpZGVvO1xuICAgIHRoaXMuX3ZwYWlkT3B0aW9ucyA9IHZwYWlkT3B0aW9ucyB8fCB7dGltZW91dDogMTAwMDB9O1xuXG4gICAgdGhpcy5fdGVtcGxhdGVDb25maWcgPSB7XG4gICAgICAgIHRlbXBsYXRlOiB0ZW1wbGF0ZUNvbmZpZy50ZW1wbGF0ZSB8fCBkZWZhdWx0VGVtcGxhdGUsXG4gICAgICAgIGV4dHJhT3B0aW9uczogdGVtcGxhdGVDb25maWcuZXh0cmFPcHRpb25zIHx8IHt9XG4gICAgfTtcblxufVxuXG4vKipcbiAqIGRlc3Ryb3lcbiAqXG4gKi9cblZQQUlESFRNTDVDbGllbnQucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiBkZXN0cm95KCkge1xuICAgIGlmICh0aGlzLl9kZXN0cm95ZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9kZXN0cm95ZWQgPSB0cnVlO1xuICAgICR1bmxvYWRQcmV2aW91c0FkVW5pdC5jYWxsKHRoaXMpO1xufTtcblxuLyoqXG4gKiBpc0Rlc3Ryb3llZFxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cblZQQUlESFRNTDVDbGllbnQucHJvdG90eXBlLmlzRGVzdHJveWVkID0gZnVuY3Rpb24gaXNEZXN0cm95ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2Rlc3Ryb3llZDtcbn07XG5cbi8qKlxuICogbG9hZEFkVW5pdFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBhZFVSTCB1cmwgb2YgdGhlIGpzIG9mIHRoZSBhZFVuaXRcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cblZQQUlESFRNTDVDbGllbnQucHJvdG90eXBlLmxvYWRBZFVuaXQgPSBmdW5jdGlvbiBsb2FkQWRVbml0KGFkVVJMLCBjYWxsYmFjaykge1xuICAgICR0aHJvd0lmRGVzdHJveWVkLmNhbGwodGhpcyk7XG4gICAgJHVubG9hZFByZXZpb3VzQWRVbml0LmNhbGwodGhpcyk7XG5cbiAgICB2YXIgZnJhbWUgPSB1dGlscy5jcmVhdGVJZnJhbWVXaXRoQ29udGVudChcbiAgICAgICAgdGhpcy5fZnJhbWVDb250YWluZXIsXG4gICAgICAgIHRoaXMuX3RlbXBsYXRlQ29uZmlnLnRlbXBsYXRlLFxuICAgICAgICB1dGlscy5leHRlbmQoe1xuICAgICAgICAgICAgaWZyYW1lVVJMX0pTOiBhZFVSTCxcbiAgICAgICAgICAgIGlmcmFtZUlEOiB0aGlzLmdldElEKClcbiAgICAgICAgfSwgdGhpcy5fdGVtcGxhdGVDb25maWcuZXh0cmFPcHRpb25zKVxuICAgICk7XG4gICAgdGhpcy5fZnJhbWUgPSBmcmFtZTtcblxuICAgIHRoaXMuX29uTG9hZCA9IHV0aWxzLmNhbGxiYWNrVGltZW91dChcbiAgICAgICAgdGhpcy5fdnBhaWRPcHRpb25zLnRpbWVvdXQsXG4gICAgICAgIG9uTG9hZC5iaW5kKHRoaXMpLFxuICAgICAgICBvblRpbWVvdXQuYmluZCh0aGlzKVxuICAgICk7XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRoaXMuX29uTG9hZCk7XG5cbiAgICBmdW5jdGlvbiBvbkxvYWQgKGUpIHtcbiAgICAgICAgLypqc2hpbnQgdmFsaWR0aGlzOiBmYWxzZSAqL1xuICAgICAgICAvL2Rvbid0IGNsZWFyIHRpbWVvdXRcbiAgICAgICAgaWYgKGUub3JpZ2luICE9PSB3aW5kb3cubG9jYXRpb24ub3JpZ2luKSByZXR1cm47XG4gICAgICAgIHZhciByZXN1bHQgPSBKU09OLnBhcnNlKGUuZGF0YSk7XG5cbiAgICAgICAgLy9kb24ndCBjbGVhciB0aW1lb3V0XG4gICAgICAgIGlmIChyZXN1bHQuaWQgIT09IHRoaXMuZ2V0SUQoKSkgcmV0dXJuO1xuXG4gICAgICAgIHZhciBhZFVuaXQsIGVycm9yLCBjcmVhdGVBZDtcbiAgICAgICAgaWYgKCF0aGlzLl9mcmFtZS5jb250ZW50V2luZG93KSB7XG5cbiAgICAgICAgICAgIGVycm9yID0gJ3RoZSBpZnJhbWUgaXMgbm90IGFueW1vcmUgaW4gdGhlIERPTSB0cmVlJztcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY3JlYXRlQWQgPSB0aGlzLl9mcmFtZS5jb250ZW50V2luZG93LmdldFZQQUlEQWQ7XG4gICAgICAgICAgICBlcnJvciA9IHV0aWxzLnZhbGlkYXRlKHR5cGVvZiBjcmVhdGVBZCA9PT0gJ2Z1bmN0aW9uJywgJ3RoZSBhZCBkaWRuXFwndCByZXR1cm4gYSBmdW5jdGlvbiB0byBjcmVhdGUgYW4gYWQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghZXJyb3IpIHtcbiAgICAgICAgICAgIHZhciBhZEVsID0gdGhpcy5fZnJhbWUuY29udGVudFdpbmRvdy5kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuYWQtZWxlbWVudCcpO1xuICAgICAgICAgICAgYWRVbml0ID0gbmV3IFZQQUlEQWRVbml0KGNyZWF0ZUFkKCksIGFkRWwsIHRoaXMuX3ZpZGVvRWwsIHRoaXMuX2ZyYW1lKTtcbiAgICAgICAgICAgIGFkVW5pdC5zdWJzY3JpYmUoQURfU1RPUFBFRCwgJGFkRGVzdHJveWVkLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgZXJyb3IgPSB1dGlscy52YWxpZGF0ZShhZFVuaXQuaXNWYWxpZFZQQUlEQWQoKSwgJ3RoZSBhZGQgaXMgbm90IGZ1bGx5IGNvbXBsYWludCB3aXRoIFZQQUlEIHNwZWNpZmljYXRpb24nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2FkVW5pdCA9IGFkVW5pdDtcbiAgICAgICAgJGRlc3Ryb3lMb2FkTGlzdGVuZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgY2FsbGJhY2soZXJyb3IsIGVycm9yID8gbnVsbCA6IGFkVW5pdCk7XG5cbiAgICAgICAgLy9jbGVhciB0aW1lb3V0XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG9uVGltZW91dCgpIHtcbiAgICAgICAgY2FsbGJhY2soJ3RpbWVvdXQnLCBudWxsKTtcbiAgICB9XG59O1xuXG4vKipcbiAqIHVubG9hZEFkVW5pdFxuICpcbiAqL1xuVlBBSURIVE1MNUNsaWVudC5wcm90b3R5cGUudW5sb2FkQWRVbml0ID0gZnVuY3Rpb24gdW5sb2FkQWRVbml0KCkge1xuICAgICR1bmxvYWRQcmV2aW91c0FkVW5pdC5jYWxsKHRoaXMpO1xufTtcblxuLyoqXG4gKiBnZXRJRCB3aWxsIHJldHVybiB0aGUgdW5pcXVlIGlkXG4gKlxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5WUEFJREhUTUw1Q2xpZW50LnByb3RvdHlwZS5nZXRJRCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5faWQ7XG59O1xuXG5cbi8qKlxuICogJHJlbW92ZUVsXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGtleVxuICovXG5mdW5jdGlvbiAkcmVtb3ZlRWwoa2V5KSB7XG4gICAgdmFyIGVsID0gdGhpc1trZXldO1xuICAgIGlmIChlbCkge1xuICAgICAgICBlbC5yZW1vdmUoKTtcbiAgICAgICAgZGVsZXRlIHRoaXNba2V5XTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uICRhZERlc3Ryb3llZCgpIHtcbiAgICAkcmVtb3ZlQWRFbGVtZW50cy5jYWxsKHRoaXMpO1xuICAgIGRlbGV0ZSB0aGlzLl9hZFVuaXQ7XG59XG5cbmZ1bmN0aW9uICR1bmxvYWRQcmV2aW91c0FkVW5pdCgpIHtcbiAgICAkcmVtb3ZlQWRFbGVtZW50cy5jYWxsKHRoaXMpO1xuICAgICRkZXN0cm95QWRVbml0LmNhbGwodGhpcyk7XG59XG5cbmZ1bmN0aW9uICRyZW1vdmVBZEVsZW1lbnRzKCkge1xuICAgICRyZW1vdmVFbC5jYWxsKHRoaXMsICdfZnJhbWUnKTtcbiAgICAkZGVzdHJveUxvYWRMaXN0ZW5lci5jYWxsKHRoaXMpO1xufVxuXG4vKipcbiAqICRkZXN0cm95TG9hZExpc3RlbmVyXG4gKlxuICovXG5mdW5jdGlvbiAkZGVzdHJveUxvYWRMaXN0ZW5lcigpIHtcbiAgICBpZiAodGhpcy5fb25Mb2FkKSB7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdGhpcy5fb25Mb2FkKTtcbiAgICAgICAgdXRpbHMuY2xlYXJDYWxsYmFja1RpbWVvdXQodGhpcy5fb25Mb2FkKTtcbiAgICAgICAgZGVsZXRlIHRoaXMuX29uTG9hZDtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gJGRlc3Ryb3lBZFVuaXQoKSB7XG4gICAgaWYgKHRoaXMuX2FkVW5pdCkge1xuICAgICAgICB0aGlzLl9hZFVuaXQuc3RvcEFkKCk7XG4gICAgICAgIGRlbGV0ZSB0aGlzLl9hZFVuaXQ7XG4gICAgfVxufVxuXG4vKipcbiAqICR0aHJvd0lmRGVzdHJveWVkXG4gKlxuICovXG5mdW5jdGlvbiAkdGhyb3dJZkRlc3Ryb3llZCgpIHtcbiAgICBpZiAodGhpcy5fZGVzdHJveWVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvciAoJ1ZQQUlESFRNTDVDbGllbnQgYWxyZWFkeSBkZXN0cm95ZWQhJyk7XG4gICAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFZQQUlESFRNTDVDbGllbnQ7XG53aW5kb3cuVlBBSURIVE1MNUNsaWVudCA9IFZQQUlESFRNTDVDbGllbnQ7XG5cbiIsIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gU3Vic2NyaWJlcigpIHtcbiAgICB0aGlzLl9zdWJzY3JpYmVycyA9IHt9O1xufVxuXG5TdWJzY3JpYmVyLnByb3RvdHlwZS5zdWJzY3JpYmUgPSBmdW5jdGlvbiBzdWJzY3JpYmUoaGFuZGxlciwgZXZlbnROYW1lLCBjb250ZXh0KSB7XG4gICAgdGhpcy5nZXQoZXZlbnROYW1lKS5wdXNoKHtoYW5kbGVyOiBoYW5kbGVyLCBjb250ZXh0OiBjb250ZXh0fSk7XG59O1xuXG5TdWJzY3JpYmVyLnByb3RvdHlwZS51bnN1YnNjcmliZSA9IGZ1bmN0aW9uIHVuc3Vic2NyaWJlKGhhbmRsZXIsIGV2ZW50TmFtZSkge1xuICAgIHRoaXMuX3N1YnNjcmliZXJzW2V2ZW50TmFtZV0gPSB0aGlzLmdldChldmVudE5hbWUpLmZpbHRlcihmdW5jdGlvbiAoc3Vic2NyaWJlcikge1xuICAgICAgICByZXR1cm4gaGFuZGxlciA9PT0gc3Vic2NyaWJlci5oYW5kbGVyO1xuICAgIH0pO1xufTtcblxuU3Vic2NyaWJlci5wcm90b3R5cGUudW5zdWJzY3JpYmVBbGwgPSBmdW5jdGlvbiB1bnN1YnNjcmliZUFsbCgpIHtcbiAgICB0aGlzLl9zdWJzY3JpYmVycyA9IHt9O1xufTtcblxuU3Vic2NyaWJlci5wcm90b3R5cGUudHJpZ2dlciA9IGZ1bmN0aW9uKGV2ZW50TmFtZSwgZGF0YSkge1xuICAgIHZhciB0aGF0ID0gdGhpcztcbiAgICB0aGF0LmdldChldmVudE5hbWUpLmZvckVhY2goZnVuY3Rpb24gKHN1YnNjcmliZXIpIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAodGhhdC5nZXQoZXZlbnROYW1lKSkge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuaGFuZGxlci5jYWxsKHN1YnNjcmliZXIuY29udGV4dCwgZGF0YSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIDApO1xuICAgIH0pO1xufTtcblxuU3Vic2NyaWJlci5wcm90b3R5cGUudHJpZ2dlclN5bmMgPSBmdW5jdGlvbihldmVudE5hbWUsIGRhdGEpIHtcbiAgICB0aGlzLmdldChldmVudE5hbWUpLmZvckVhY2goZnVuY3Rpb24gKHN1YnNjcmliZXIpIHtcbiAgICAgICAgc3Vic2NyaWJlci5oYW5kbGVyLmNhbGwoc3Vic2NyaWJlci5jb250ZXh0LCBkYXRhKTtcbiAgICB9KTtcbn07XG5cblN1YnNjcmliZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIGdldChldmVudE5hbWUpIHtcbiAgICBpZiAoIXRoaXMuX3N1YnNjcmliZXJzW2V2ZW50TmFtZV0pIHtcbiAgICAgICAgdGhpcy5fc3Vic2NyaWJlcnNbZXZlbnROYW1lXSA9IFtdO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc3Vic2NyaWJlcnNbZXZlbnROYW1lXTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gU3Vic2NyaWJlcjtcblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIG5vb3AgYSBlbXB0eSBmdW5jdGlvblxuICovXG5mdW5jdGlvbiBub29wKCkge31cblxuLyoqXG4gKiB2YWxpZGF0ZSBpZiBpcyBub3QgdmFsaWRhdGUgd2lsbCByZXR1cm4gYW4gRXJyb3Igd2l0aCB0aGUgbWVzc2FnZVxuICpcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNWYWxpZFxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2VcbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGUoaXNWYWxpZCwgbWVzc2FnZSkge1xuICAgIHJldHVybiBpc1ZhbGlkID8gbnVsbCA6IG5ldyBFcnJvcihtZXNzYWdlKTtcbn1cblxudmFyIHRpbWVvdXRzID0ge307XG4vKipcbiAqIGNsZWFyQ2FsbGJhY2tUaW1lb3V0XG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gZnVuYyBoYW5kbGVyIHRvIHJlbW92ZVxuICovXG5mdW5jdGlvbiBjbGVhckNhbGxiYWNrVGltZW91dChmdW5jKSB7XG4gICAgdmFyIHRpbWVvdXQgPSB0aW1lb3V0c1tmdW5jXTtcbiAgICBpZiAodGltZW91dCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgIGRlbGV0ZSB0aW1lb3V0c1tmdW5jXTtcbiAgICB9XG59XG5cbi8qKlxuICogY2FsbGJhY2tUaW1lb3V0IGlmIHRoZSBvblN1Y2Nlc3MgaXMgbm90IGNhbGxlZCBhbmQgcmV0dXJucyB0cnVlIGluIHRoZSB0aW1lbGltaXQgdGhlbiBvblRpbWVvdXQgd2lsbCBiZSBjYWxsZWRcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gdGltZXJcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IG9uU3VjY2Vzc1xuICogQHBhcmFtIHtmdW5jdGlvbn0gb25UaW1lb3V0XG4gKi9cbmZ1bmN0aW9uIGNhbGxiYWNrVGltZW91dCh0aW1lciwgb25TdWNjZXNzLCBvblRpbWVvdXQpIHtcbiAgICB2YXIgY2FsbGJhY2ssIHRpbWVvdXQ7XG5cbiAgICB0aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIG9uU3VjY2VzcyA9IG5vb3A7XG4gICAgICAgIGRlbGV0ZSB0aW1lb3V0W2NhbGxiYWNrXTtcbiAgICAgICAgb25UaW1lb3V0KCk7XG4gICAgfSwgdGltZXIpO1xuXG4gICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIFRPRE8gYXZvaWQgbGVha2luZyBhcmd1bWVudHNcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3BldGthYW50b25vdi9ibHVlYmlyZC93aWtpL09wdGltaXphdGlvbi1raWxsZXJzIzMyLWxlYWtpbmctYXJndW1lbnRzXG4gICAgICAgIGlmIChvblN1Y2Nlc3MuYXBwbHkodGhpcywgYXJndW1lbnRzKSkge1xuICAgICAgICAgICAgY2xlYXJDYWxsYmFja1RpbWVvdXQoY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHRpbWVvdXRzW2NhbGxiYWNrXSA9IHRpbWVvdXQ7XG5cbiAgICByZXR1cm4gY2FsbGJhY2s7XG59XG5cblxuLyoqXG4gKiBjcmVhdGVFbGVtZW50SW5FbFxuICpcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHBhcmVudFxuICogQHBhcmFtIHtzdHJpbmd9IHRhZ05hbWVcbiAqIEBwYXJhbSB7c3RyaW5nfSBpZFxuICovXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50SW5FbChwYXJlbnQsIHRhZ05hbWUsIGlkKSB7XG4gICAgdmFyIG5FbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSk7XG4gICAgaWYgKGlkKSBuRWwuaWQgPSBpZDtcbiAgICBwYXJlbnQuYXBwZW5kQ2hpbGQobkVsKTtcbiAgICByZXR1cm4gbkVsO1xufVxuXG4vKipcbiAqIGNyZWF0ZUlmcmFtZVdpdGhDb250ZW50XG4gKlxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gcGFyZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gdGVtcGxhdGUgc2ltcGxlIHRlbXBsYXRlIHVzaW5nIHt7dmFyfX1cbiAqIEBwYXJhbSB7b2JqZWN0fSBkYXRhXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUlmcmFtZVdpdGhDb250ZW50KHBhcmVudCwgdGVtcGxhdGUsIGRhdGEpIHtcbiAgICB2YXIgaWZyYW1lID0gY3JlYXRlSWZyYW1lKHBhcmVudCk7XG4gICAgaWYgKCFzZXRJZnJhbWVDb250ZW50KGlmcmFtZSwgc2ltcGxlVGVtcGxhdGUodGVtcGxhdGUsIGRhdGEpKSkgcmV0dXJuO1xuICAgIHJldHVybiBpZnJhbWU7XG59XG5cbi8qKlxuICogY3JlYXRlSWZyYW1lXG4gKlxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gcGFyZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gdXJsXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUlmcmFtZShwYXJlbnQsIHVybCkge1xuICAgIHZhciBuRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICBuRWwuc3JjID0gdXJsIHx8ICdhYm91dDpibGFuayc7XG4gICAgbkVsLm1hcmdpbldpZHRoID0gJzAnO1xuICAgIG5FbC5tYXJnaW5IZWlnaHQgPSAnMCc7XG4gICAgbkVsLmZyYW1lQm9yZGVyID0gJzAnO1xuICAgIG5FbC53aWR0aCA9ICcxMDAlJztcbiAgICBuRWwuaGVpZ2h0ID0gJzEwMCUnO1xuICAgIG5FbC5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgbkVsLnN0eWxlLmxlZnQgPSAnMCc7XG4gICAgbkVsLnN0eWxlLnRvcCA9ICcwJztcbiAgICBuRWwuc3R5bGUubWFyZ2luID0gJzBweCc7XG4gICAgbkVsLnN0eWxlLnBhZGRpbmcgPSAnMHB4JztcbiAgICBuRWwuc3R5bGUuYm9yZGVyID0gJ25vbmUnO1xuICAgIG5FbC5zZXRBdHRyaWJ1dGUoJ1NDUk9MTElORycsJ05PJyk7XG4gICAgcGFyZW50LmlubmVySFRNTCA9ICcnO1xuICAgIHBhcmVudC5hcHBlbmRDaGlsZChuRWwpO1xuICAgIHJldHVybiBuRWw7XG59XG5cbi8qKlxuICogc2ltcGxlVGVtcGxhdGVcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGVtcGxhdGVcbiAqIEBwYXJhbSB7b2JqZWN0fSBkYXRhXG4gKi9cbmZ1bmN0aW9uIHNpbXBsZVRlbXBsYXRlKHRlbXBsYXRlLCBkYXRhKSB7XG4gICAgT2JqZWN0LmtleXMoZGF0YSkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIHZhciB2YWx1ZSA9ICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSA/IEpTT04uc3RyaW5naWZ5KGRhdGFba2V5XSkgOiBkYXRhW2tleV07XG4gICAgICAgIHRlbXBsYXRlID0gdGVtcGxhdGUucmVwbGFjZShuZXcgUmVnRXhwKCd7eycgKyBrZXkgKyAnfX0nLCAnZycpLCB2YWx1ZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRlbXBsYXRlO1xufVxuXG4vKipcbiAqIHNldElmcmFtZUNvbnRlbnRcbiAqXG4gKiBAcGFyYW0ge0hUTUxJZnJhbWVFbGVtZW50fSBpZnJhbWVFbFxuICogQHBhcmFtIGNvbnRlbnRcbiAqL1xuZnVuY3Rpb24gc2V0SWZyYW1lQ29udGVudChpZnJhbWVFbCwgY29udGVudCkge1xuICAgIHZhciBpZnJhbWVEb2MgPSBpZnJhbWVFbC5jb250ZW50V2luZG93ICYmIGlmcmFtZUVsLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnQ7XG4gICAgaWYgKCFpZnJhbWVEb2MpIHJldHVybiBmYWxzZTtcblxuICAgIGlmcmFtZURvYy53cml0ZShjb250ZW50KTtcblxuICAgIHJldHVybiB0cnVlO1xufVxuXG5cbi8qKlxuICogZXh0ZW5kIG9iamVjdCB3aXRoIGtleXMgZnJvbSBhbm90aGVyIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSB0b0V4dGVuZFxuICogQHBhcmFtIHtvYmplY3R9IGZyb21Tb3VyY2VcbiAqL1xuZnVuY3Rpb24gZXh0ZW5kKHRvRXh0ZW5kLCBmcm9tU291cmNlKSB7XG4gICAgT2JqZWN0LmtleXMoZnJvbVNvdXJjZSkuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgdG9FeHRlbmRba2V5XSA9IGZyb21Tb3VyY2Vba2V5XTtcbiAgICB9KTtcbiAgICByZXR1cm4gdG9FeHRlbmQ7XG59XG5cblxuLyoqXG4gKiB1bmlxdWUgd2lsbCBjcmVhdGUgYSB1bmlxdWUgc3RyaW5nIGV2ZXJ5dGltZSBpcyBjYWxsZWQsIHNlcXVlbnRpYWxseSBhbmQgcHJlZml4ZWRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJlZml4XG4gKi9cbmZ1bmN0aW9uIHVuaXF1ZShwcmVmaXgpIHtcbiAgICB2YXIgY291bnQgPSAtMTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gcHJlZml4ICsgJ18nICsgKCsrY291bnQpO1xuICAgIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIG5vb3A6IG5vb3AsXG4gICAgdmFsaWRhdGU6IHZhbGlkYXRlLFxuICAgIGNsZWFyQ2FsbGJhY2tUaW1lb3V0OiBjbGVhckNhbGxiYWNrVGltZW91dCxcbiAgICBjYWxsYmFja1RpbWVvdXQ6IGNhbGxiYWNrVGltZW91dCxcbiAgICBjcmVhdGVFbGVtZW50SW5FbDogY3JlYXRlRWxlbWVudEluRWwsXG4gICAgY3JlYXRlSWZyYW1lV2l0aENvbnRlbnQ6IGNyZWF0ZUlmcmFtZVdpdGhDb250ZW50LFxuICAgIGNyZWF0ZUlmcmFtZTogY3JlYXRlSWZyYW1lLFxuICAgIHNpbXBsZVRlbXBsYXRlOiBzaW1wbGVUZW1wbGF0ZSxcbiAgICBzZXRJZnJhbWVDb250ZW50OiBzZXRJZnJhbWVDb250ZW50LFxuICAgIGV4dGVuZDogZXh0ZW5kLFxuICAgIHVuaXF1ZTogdW5pcXVlXG59O1xuXG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBJbkxpbmUgPSByZXF1aXJlKCcuL0luTGluZScpO1xudmFyIFdyYXBwZXIgPSByZXF1aXJlKCcuL1dyYXBwZXInKTtcblxuZnVuY3Rpb24gQWQoYWRKVHJlZSkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQWQpKSB7XG4gICAgcmV0dXJuIG5ldyBBZChhZEpUcmVlKTtcbiAgfVxuICB0aGlzLmluaXRpYWxpemUoYWRKVHJlZSk7XG59XG5cbkFkLnByb3RvdHlwZS5pbml0aWFsaXplID0gZnVuY3Rpb24oYWRKVHJlZSkge1xuICB0aGlzLmlkID0gYWRKVHJlZS5hdHRyKCdpZCcpO1xuICB0aGlzLnNlcXVlbmNlID0gYWRKVHJlZS5hdHRyKCdzZXF1ZW5jZScpO1xuXG4gIGlmKGFkSlRyZWUuaW5MaW5lKSB7XG4gICAgdGhpcy5pbkxpbmUgPSBuZXcgSW5MaW5lKGFkSlRyZWUuaW5MaW5lKTtcbiAgfVxuXG4gIGlmKGFkSlRyZWUud3JhcHBlcil7XG4gICAgdGhpcy53cmFwcGVyID0gbmV3IFdyYXBwZXIoYWRKVHJlZS53cmFwcGVyKTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBBZDsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBUcmFja2luZ0V2ZW50ID0gcmVxdWlyZSgnLi9UcmFja2luZ0V2ZW50Jyk7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbnZhciB4bWwgPSByZXF1aXJlKCcuLi8uLi91dGlscy94bWwnKTtcblxuXG5mdW5jdGlvbiBDb21wYW5pb24oY29tcGFuaW9uSlRyZWUpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIENvbXBhbmlvbikpIHtcbiAgICByZXR1cm4gbmV3IENvbXBhbmlvbihjb21wYW5pb25KVHJlZSk7XG4gIH1cblxuICAvL1JlcXVpcmVkIEVsZW1lbnRzXG4gIHRoaXMuY3JlYXRpdmVUeXBlID0geG1sLmF0dHIoY29tcGFuaW9uSlRyZWUuc3RhdGljUmVzb3VyY2UsICdjcmVhdGl2ZVR5cGUnKTtcbiAgdGhpcy5zdGF0aWNSZXNvdXJjZSA9IHhtbC5rZXlWYWx1ZShjb21wYW5pb25KVHJlZS5zdGF0aWNSZXNvdXJjZSk7XG5cbiAgLy8gV2VpcmQgYnVnIHdoZW4gdGhlIEpYT04gdHJlZSBpcyBidWlsdCBpdCBkb2Vzbid0IGhhbmRsZSBjYXNpbmcgcHJvcGVybHkgaW4gdGhpcyBzaXR1YXRpb24uLi5cbiAgdmFyIGh0bWxSZXNvdXJjZSA9IG51bGw7XG4gIGlmICh4bWwua2V5VmFsdWUoY29tcGFuaW9uSlRyZWUuSFRNTFJlc291cmNlKSkge1xuICAgIGh0bWxSZXNvdXJjZSA9IHhtbC5rZXlWYWx1ZShjb21wYW5pb25KVHJlZS5IVE1MUmVzb3VyY2UpO1xuICB9IGVsc2UgaWYgKHhtbC5rZXlWYWx1ZShjb21wYW5pb25KVHJlZS5oVE1MUmVzb3VyY2UpKSB7XG4gICAgaHRtbFJlc291cmNlID0geG1sLmtleVZhbHVlKGNvbXBhbmlvbkpUcmVlLmhUTUxSZXNvdXJjZSk7XG4gIH1cbiAgdGhpcy5odG1sUmVzb3VyY2UgPSBodG1sUmVzb3VyY2U7XG5cbiAgdmFyIGlmcmFtZVJlc291cmNlID0gbnVsbDtcbiAgaWYgKHhtbC5rZXlWYWx1ZShjb21wYW5pb25KVHJlZS5JRnJhbWVSZXNvdXJjZSkpIHtcbiAgICBpZnJhbWVSZXNvdXJjZSA9IHhtbC5rZXlWYWx1ZShjb21wYW5pb25KVHJlZS5JRnJhbWVSZXNvdXJjZSk7XG4gIH0gZWxzZSBpZiAoeG1sLmtleVZhbHVlKGNvbXBhbmlvbkpUcmVlLmlGcmFtZXJlc291cmNlKSkge1xuICAgIGlmcmFtZVJlc291cmNlID0geG1sLmtleVZhbHVlKGNvbXBhbmlvbkpUcmVlLmlGcmFtZXJlc291cmNlKTtcbiAgfVxuICB0aGlzLmlmcmFtZVJlc291cmNlID0gaWZyYW1lUmVzb3VyY2U7XG5cbiAgLy9PcHRpb25hbCBmaWVsZHNcbiAgdGhpcy5pZCA9IHhtbC5hdHRyKGNvbXBhbmlvbkpUcmVlLCAnaWQnKTtcbiAgdGhpcy53aWR0aCA9IHhtbC5hdHRyKGNvbXBhbmlvbkpUcmVlLCAnd2lkdGgnKTtcbiAgdGhpcy5oZWlnaHQgPSB4bWwuYXR0cihjb21wYW5pb25KVHJlZSwgJ2hlaWdodCcpO1xuICB0aGlzLmV4cGFuZGVkV2lkdGggPSB4bWwuYXR0cihjb21wYW5pb25KVHJlZSwgJ2V4cGFuZGVkV2lkdGgnKTtcbiAgdGhpcy5leHBhbmRlZEhlaWdodCA9IHhtbC5hdHRyKGNvbXBhbmlvbkpUcmVlLCAnZXhwYW5kZWRIZWlnaHQnKTtcbiAgdGhpcy5zY2FsYWJsZSA9IHhtbC5hdHRyKGNvbXBhbmlvbkpUcmVlLCAnc2NhbGFibGUnKTtcbiAgdGhpcy5tYWludGFpbkFzcGVjdFJhdGlvID0geG1sLmF0dHIoY29tcGFuaW9uSlRyZWUsICdtYWludGFpbkFzcGVjdFJhdGlvJyk7XG4gIHRoaXMubWluU3VnZ2VzdGVkRHVyYXRpb24gPSB4bWwuYXR0cihjb21wYW5pb25KVHJlZSwgJ21pblN1Z2dlc3RlZER1cmF0aW9uJyk7XG4gIHRoaXMuYXBpRnJhbWV3b3JrID0geG1sLmF0dHIoY29tcGFuaW9uSlRyZWUsICdhcGlGcmFtZXdvcmsnKTtcbiAgdGhpcy5jb21wYW5pb25DbGlja1Rocm91Z2ggPSB4bWwua2V5VmFsdWUoY29tcGFuaW9uSlRyZWUuY29tcGFuaW9uQ2xpY2tUaHJvdWdoKTtcbiAgdGhpcy50cmFja2luZ0V2ZW50cyA9IHBhcnNlVHJhY2tpbmdFdmVudHMoY29tcGFuaW9uSlRyZWUudHJhY2tpbmdFdmVudHMgJiYgY29tcGFuaW9uSlRyZWUudHJhY2tpbmdFdmVudHMudHJhY2tpbmcpO1xuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gcGFyc2VUcmFja2luZ0V2ZW50cyh0cmFja2luZ0V2ZW50cykge1xuICAgIHZhciB0cmFja2luZ3MgPSBbXTtcbiAgICBpZiAodXRpbGl0aWVzLmlzRGVmaW5lZCh0cmFja2luZ0V2ZW50cykpIHtcbiAgICAgIHRyYWNraW5nRXZlbnRzID0gdXRpbGl0aWVzLmlzQXJyYXkodHJhY2tpbmdFdmVudHMpID8gdHJhY2tpbmdFdmVudHMgOiBbdHJhY2tpbmdFdmVudHNdO1xuICAgICAgdHJhY2tpbmdFdmVudHMuZm9yRWFjaChmdW5jdGlvbiAodHJhY2tpbmdEYXRhKSB7XG4gICAgICAgIHRyYWNraW5ncy5wdXNoKG5ldyBUcmFja2luZ0V2ZW50KHRyYWNraW5nRGF0YSkpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0cmFja2luZ3M7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBDb21wYW5pb247IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgTGluZWFyID0gcmVxdWlyZSgnLi9MaW5lYXInKTtcbnZhciBDb21wYW5pb24gPSByZXF1aXJlKCcuL0NvbXBhbmlvbicpO1xudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxuZnVuY3Rpb24gQ3JlYXRpdmUoY3JlYXRpdmVKVHJlZSkge1xuICBpZighKHRoaXMgaW5zdGFuY2VvZiBDcmVhdGl2ZSkpIHtcbiAgICByZXR1cm4gbmV3IENyZWF0aXZlKGNyZWF0aXZlSlRyZWUpO1xuICB9XG5cbiAgdGhpcy5pZCA9IGNyZWF0aXZlSlRyZWUuYXR0cignaWQnKTtcbiAgdGhpcy5zZXF1ZW5jZSA9IGNyZWF0aXZlSlRyZWUuYXR0cignc2VxdWVuY2UnKTtcbiAgdGhpcy5hZElkID0gY3JlYXRpdmVKVHJlZS5hdHRyKCdhZElkJyk7XG4gIHRoaXMuYXBpRnJhbWV3b3JrID0gY3JlYXRpdmVKVHJlZS5hdHRyKCdhcGlGcmFtZXdvcmsnKTtcblxuICBpZihjcmVhdGl2ZUpUcmVlLmxpbmVhcikge1xuICAgIHRoaXMubGluZWFyID0gbmV3IExpbmVhcihjcmVhdGl2ZUpUcmVlLmxpbmVhcik7XG4gIH1cblxuICBpZiAoY3JlYXRpdmVKVHJlZS5jb21wYW5pb25BZHMpIHtcbiAgICB2YXIgY29tcGFuaW9ucyA9IFtdO1xuICAgIHZhciBjb21wYW5pb25BZHMgPSBjcmVhdGl2ZUpUcmVlLmNvbXBhbmlvbkFkcyAmJiBjcmVhdGl2ZUpUcmVlLmNvbXBhbmlvbkFkcy5jb21wYW5pb247XG4gICAgY29tcGFuaW9uQWRzID0gdXRpbGl0aWVzLmlzQXJyYXkoY29tcGFuaW9uQWRzKSA/IGNvbXBhbmlvbkFkcyA6IFtjb21wYW5pb25BZHNdO1xuICAgIGNvbXBhbmlvbkFkcy5mb3JFYWNoKGZ1bmN0aW9uIChjb21wYW5pb25EYXRhKSB7XG4gICAgICBjb21wYW5pb25zLnB1c2gobmV3IENvbXBhbmlvbihjb21wYW5pb25EYXRhKSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbXBhbmlvbkFkcyA9IGNvbXBhbmlvbnM7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBDcmVhdGl2ZTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciB2YXN0VXRpbCA9IHJlcXVpcmUoJy4vdmFzdFV0aWwnKTtcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcbnZhciB4bWwgPSByZXF1aXJlKCcuLi8uLi91dGlscy94bWwnKTtcblxuZnVuY3Rpb24gSW5MaW5lKGlubGluZUpUcmVlKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBJbkxpbmUpKSB7XG4gICAgcmV0dXJuIG5ldyBJbkxpbmUoaW5saW5lSlRyZWUpO1xuICB9XG5cbiAgLy9SZXF1aXJlZCBGaWVsZHNcbiAgdGhpcy5hZFRpdGxlID0geG1sLmtleVZhbHVlKGlubGluZUpUcmVlLmFkVGl0bGUpO1xuICB0aGlzLmFkU3lzdGVtID0geG1sLmtleVZhbHVlKGlubGluZUpUcmVlLmFkU3lzdGVtKTtcbiAgdGhpcy5pbXByZXNzaW9ucyA9IHZhc3RVdGlsLnBhcnNlSW1wcmVzc2lvbnMoaW5saW5lSlRyZWUuaW1wcmVzc2lvbik7XG4gIHRoaXMuY3JlYXRpdmVzID0gdmFzdFV0aWwucGFyc2VDcmVhdGl2ZXMoaW5saW5lSlRyZWUuY3JlYXRpdmVzKTtcblxuICAvL09wdGlvbmFsIEZpZWxkc1xuICB0aGlzLmRlc2NyaXB0aW9uID0geG1sLmtleVZhbHVlKGlubGluZUpUcmVlLmRlc2NyaXB0aW9uKTtcbiAgdGhpcy5hZHZlcnRpc2VyID0geG1sLmtleVZhbHVlKGlubGluZUpUcmVlLmFkdmVydGlzZXIpO1xuICB0aGlzLnN1cnZleXMgPSBwYXJzZVN1cnZleXMoaW5saW5lSlRyZWUuc3VydmV5KTtcbiAgdGhpcy5lcnJvciA9IHhtbC5rZXlWYWx1ZShpbmxpbmVKVHJlZS5lcnJvcik7XG4gIHRoaXMucHJpY2luZyA9IHhtbC5rZXlWYWx1ZShpbmxpbmVKVHJlZS5wcmljaW5nKTtcbiAgdGhpcy5leHRlbnNpb25zID0gaW5saW5lSlRyZWUuZXh0ZW5zaW9ucztcblxuICAvKioqIExvY2FsIEZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIHBhcnNlU3VydmV5cyhpbmxpbmVTdXJ2ZXlzKSB7XG4gICAgaWYgKGlubGluZVN1cnZleXMpIHtcbiAgICAgIHJldHVybiB1dGlsaXRpZXMudHJhbnNmb3JtQXJyYXkodXRpbGl0aWVzLmlzQXJyYXkoaW5saW5lU3VydmV5cykgPyBpbmxpbmVTdXJ2ZXlzIDogW2lubGluZVN1cnZleXNdLCBmdW5jdGlvbiAoc3VydmV5KSB7XG4gICAgICAgIGlmKHV0aWxpdGllcy5pc05vdEVtcHR5U3RyaW5nKHN1cnZleS5rZXlWYWx1ZSkpe1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB1cmk6IHN1cnZleS5rZXlWYWx1ZSxcbiAgICAgICAgICAgIHR5cGU6IHN1cnZleS5hdHRyKCd0eXBlJylcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gW107XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBJbkxpbmU7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHJhY2tpbmdFdmVudCA9IHJlcXVpcmUoJy4vVHJhY2tpbmdFdmVudCcpO1xudmFyIE1lZGlhRmlsZSA9IHJlcXVpcmUoJy4vTWVkaWFGaWxlJyk7XG52YXIgVmlkZW9DbGlja3MgPSByZXF1aXJlKCcuL1ZpZGVvQ2xpY2tzJyk7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG52YXIgcGFyc2VycyA9IHJlcXVpcmUoJy4vcGFyc2VycycpO1xuXG52YXIgeG1sID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMveG1sJyk7XG5cblxuZnVuY3Rpb24gTGluZWFyKGxpbmVhckpUcmVlKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBMaW5lYXIpKSB7XG4gICAgcmV0dXJuIG5ldyBMaW5lYXIobGluZWFySlRyZWUpO1xuICB9XG5cbiAgLy9SZXF1aXJlZCBFbGVtZW50c1xuICB0aGlzLmR1cmF0aW9uID0gcGFyc2Vycy5kdXJhdGlvbih4bWwua2V5VmFsdWUobGluZWFySlRyZWUuZHVyYXRpb24pKTtcbiAgdGhpcy5tZWRpYUZpbGVzID0gcGFyc2VNZWRpYUZpbGVzKGxpbmVhckpUcmVlLm1lZGlhRmlsZXMgJiYgbGluZWFySlRyZWUubWVkaWFGaWxlcy5tZWRpYUZpbGUpO1xuXG4gIC8vT3B0aW9uYWwgZmllbGRzXG4gIHRoaXMudHJhY2tpbmdFdmVudHMgPSBwYXJzZVRyYWNraW5nRXZlbnRzKGxpbmVhckpUcmVlLnRyYWNraW5nRXZlbnRzICYmIGxpbmVhckpUcmVlLnRyYWNraW5nRXZlbnRzLnRyYWNraW5nLCB0aGlzLmR1cmF0aW9uKTtcbiAgdGhpcy5za2lwb2Zmc2V0ID0gcGFyc2Vycy5vZmZzZXQoeG1sLmF0dHIobGluZWFySlRyZWUsICdza2lwb2Zmc2V0JyksIHRoaXMuZHVyYXRpb24pO1xuXG4gIGlmIChsaW5lYXJKVHJlZS52aWRlb0NsaWNrcykge1xuICAgIHRoaXMudmlkZW9DbGlja3MgPSBuZXcgVmlkZW9DbGlja3MobGluZWFySlRyZWUudmlkZW9DbGlja3MpO1xuICB9XG5cbiAgaWYobGluZWFySlRyZWUuYWRQYXJhbWV0ZXJzKSB7XG4gICAgdGhpcy5hZFBhcmFtZXRlcnMgPSB4bWwua2V5VmFsdWUobGluZWFySlRyZWUuYWRQYXJhbWV0ZXJzKTtcblxuICAgIGlmKHhtbC5hdHRyKGxpbmVhckpUcmVlLmFkUGFyYW1ldGVycywgJ3htbEVuY29kZWQnKSl7XG4gICAgICB0aGlzLmFkUGFyYW1ldGVycyA9IHhtbC5kZWNvZGUodGhpcy5hZFBhcmFtZXRlcnMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gcGFyc2VUcmFja2luZ0V2ZW50cyh0cmFja2luZ0V2ZW50cywgZHVyYXRpb24pIHtcbiAgICB2YXIgdHJhY2tpbmdzID0gW107XG4gICAgaWYgKHV0aWxpdGllcy5pc0RlZmluZWQodHJhY2tpbmdFdmVudHMpKSB7XG4gICAgICB0cmFja2luZ0V2ZW50cyA9IHV0aWxpdGllcy5pc0FycmF5KHRyYWNraW5nRXZlbnRzKSA/IHRyYWNraW5nRXZlbnRzIDogW3RyYWNraW5nRXZlbnRzXTtcbiAgICAgIHRyYWNraW5nRXZlbnRzLmZvckVhY2goZnVuY3Rpb24gKHRyYWNraW5nRGF0YSkge1xuICAgICAgICB0cmFja2luZ3MucHVzaChuZXcgVHJhY2tpbmdFdmVudCh0cmFja2luZ0RhdGEsIGR1cmF0aW9uKSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRyYWNraW5ncztcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlTWVkaWFGaWxlcyhtZWRpYUZpbGVzSnhvblRyZWUpIHtcbiAgICB2YXIgbWVkaWFGaWxlcyA9IFtdO1xuICAgIGlmICh1dGlsaXRpZXMuaXNEZWZpbmVkKG1lZGlhRmlsZXNKeG9uVHJlZSkpIHtcbiAgICAgIG1lZGlhRmlsZXNKeG9uVHJlZSA9IHV0aWxpdGllcy5pc0FycmF5KG1lZGlhRmlsZXNKeG9uVHJlZSkgPyBtZWRpYUZpbGVzSnhvblRyZWUgOiBbbWVkaWFGaWxlc0p4b25UcmVlXTtcblxuICAgICAgbWVkaWFGaWxlc0p4b25UcmVlLmZvckVhY2goZnVuY3Rpb24gKG1mRGF0YSkge1xuICAgICAgICBtZWRpYUZpbGVzLnB1c2gobmV3IE1lZGlhRmlsZShtZkRhdGEpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gbWVkaWFGaWxlcztcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IExpbmVhcjsiLCIndXNlIHN0cmljdCc7XG5cbnZhciB4bWwgPSByZXF1aXJlKCcuLi8uLi91dGlscy94bWwnKTtcblxudmFyIGF0dHJpYnV0ZXNMaXN0ID0gW1xuICAvL1JlcXVpcmVkIGF0dHJpYnV0ZXNcbiAgJ2RlbGl2ZXJ5JyxcbiAgJ3R5cGUnLFxuICAnd2lkdGgnLFxuICAnaGVpZ2h0JyxcbiAgLy9PcHRpb25hbCBhdHRyaWJ1dGVzXG4gICdjb2RlYycsXG4gICdpZCcsXG4gICdiaXRyYXRlJyxcbiAgJ21pbkJpdHJhdGUnLFxuICAnbWF4Qml0cmF0ZScsXG4gICdzY2FsYWJsZScsXG4gICdtYWludGFpbkFzcGVjdFJhdGlvJyxcbiAgJ2FwaUZyYW1ld29yaydcbl07XG5cbmZ1bmN0aW9uIE1lZGlhRmlsZShtZWRpYUZpbGVKVHJlZSkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgTWVkaWFGaWxlKSkge1xuICAgIHJldHVybiBuZXcgTWVkaWFGaWxlKG1lZGlhRmlsZUpUcmVlKTtcbiAgfVxuXG4gIC8vUmVxdWlyZWQgYXR0cmlidXRlc1xuICB0aGlzLnNyYyA9IHhtbC5rZXlWYWx1ZShtZWRpYUZpbGVKVHJlZSk7XG5cbiAgZm9yKHZhciB4PTA7IHg8YXR0cmlidXRlc0xpc3QubGVuZ3RoOyB4KyspIHtcbiAgICB2YXIgYXR0cmlidXRlID0gYXR0cmlidXRlc0xpc3RbeF07XG4gICAgdGhpc1thdHRyaWJ1dGVdID0gbWVkaWFGaWxlSlRyZWUuYXR0cihhdHRyaWJ1dGUpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gTWVkaWFGaWxlOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIHBhcnNlcnMgPSByZXF1aXJlKCcuL3BhcnNlcnMnKTtcblxudmFyIHhtbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3htbCcpO1xuXG5mdW5jdGlvbiBUcmFja2luZ0V2ZW50KHRyYWNraW5nSlRyZWUsIGR1cmF0aW9uKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBUcmFja2luZ0V2ZW50KSkge1xuICAgIHJldHVybiBuZXcgVHJhY2tpbmdFdmVudCh0cmFja2luZ0pUcmVlLCBkdXJhdGlvbik7XG4gIH1cblxuICB0aGlzLm5hbWUgPSB0cmFja2luZ0pUcmVlLmF0dHIoJ2V2ZW50Jyk7XG4gIHRoaXMudXJpID0geG1sLmtleVZhbHVlKHRyYWNraW5nSlRyZWUpO1xuXG4gIGlmKCdwcm9ncmVzcycgPT09IHRoaXMubmFtZSkge1xuICAgIHRoaXMub2Zmc2V0ID0gcGFyc2Vycy5vZmZzZXQodHJhY2tpbmdKVHJlZS5hdHRyKCdvZmZzZXQnKSwgZHVyYXRpb24pO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gVHJhY2tpbmdFdmVudDsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBBZCA9IHJlcXVpcmUoJy4vQWQnKTtcbnZhciBWQVNURXJyb3IgPSByZXF1aXJlKCcuL1ZBU1RFcnJvcicpO1xudmFyIFZBU1RSZXNwb25zZSA9IHJlcXVpcmUoJy4vVkFTVFJlc3BvbnNlJyk7XG52YXIgdmFzdFV0aWwgPSByZXF1aXJlKCcuL3Zhc3RVdGlsJyk7XG5cbnZhciBhc3luYyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL2FzeW5jJyk7XG52YXIgaHR0cCA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL2h0dHAnKS5odHRwO1xudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcbnZhciB4bWwgPSByZXF1aXJlKCcuLi8uLi91dGlscy94bWwnKTtcblxuZnVuY3Rpb24gVkFTVENsaWVudChvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBWQVNUQ2xpZW50KSkge1xuICAgIHJldHVybiBuZXcgVkFTVENsaWVudChvcHRpb25zKTtcbiAgfVxuICB2YXIgZGVmYXVsdE9wdGlvbnMgPSB7XG4gICAgV1JBUFBFUl9MSU1JVDogNVxuICB9O1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICB0aGlzLnNldHRpbmdzID0gdXRpbGl0aWVzLmV4dGVuZCh7fSwgb3B0aW9ucywgZGVmYXVsdE9wdGlvbnMpO1xuICB0aGlzLmVycm9yVVJMTWFjcm9zID0gW107XG59XG5cblZBU1RDbGllbnQucHJvdG90eXBlLmdldFZBU1RSZXNwb25zZSA9IGZ1bmN0aW9uIGdldFZBU1RSZXNwb25zZShhZFRhZ1VybCwgY2FsbGJhY2spIHtcbiAgdmFyIHRoYXQgPSB0aGlzO1xuXG4gIHZhciBlcnJvciA9IHNhbml0eUNoZWNrKGFkVGFnVXJsLCBjYWxsYmFjayk7XG4gIGlmIChlcnJvcikge1xuICAgIGlmICh1dGlsaXRpZXMuaXNGdW5jdGlvbihjYWxsYmFjaykpIHtcbiAgICAgIHJldHVybiBjYWxsYmFjayhlcnJvcik7XG4gICAgfVxuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgYXN5bmMud2F0ZXJmYWxsKFtcbiAgICAgIHRoaXMuX2dldFZBU1RBZC5iaW5kKHRoaXMsIGFkVGFnVXJsKSxcbiAgICAgIGJ1aWxkVkFTVFJlc3BvbnNlXG4gICAgXSxcbiAgICBjYWxsYmFjayk7XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBidWlsZFZBU1RSZXNwb25zZShhZHNDaGFpbiwgY2IpIHtcbiAgICB0cnkge1xuICAgICAgdmFyIHJlc3BvbnNlID0gdGhhdC5fYnVpbGRWQVNUUmVzcG9uc2UoYWRzQ2hhaW4pO1xuICAgICAgY2IobnVsbCwgcmVzcG9uc2UpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNiKGUpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNhbml0eUNoZWNrKGFkVGFnVXJsLCBjYikge1xuICAgIGlmICghYWRUYWdVcmwpIHtcbiAgICAgIHJldHVybiBuZXcgVkFTVEVycm9yKCdvbiBWQVNUQ2xpZW50LmdldFZBU1RSZXNwb25zZSwgbWlzc2luZyBhZCB0YWcgVVJMJyk7XG4gICAgfVxuXG4gICAgaWYgKCF1dGlsaXRpZXMuaXNGdW5jdGlvbihjYikpIHtcbiAgICAgIHJldHVybiBuZXcgVkFTVEVycm9yKCdvbiBWQVNUQ2xpZW50LmdldFZBU1RSZXNwb25zZSwgbWlzc2luZyBjYWxsYmFjayBmdW5jdGlvbicpO1xuICAgIH1cbiAgfVxufTtcblxuVkFTVENsaWVudC5wcm90b3R5cGUuX2dldFZBU1RBZCA9IGZ1bmN0aW9uIChhZFRhZ1VybCwgY2FsbGJhY2spIHtcbiAgdmFyIHRoYXQgPSB0aGlzO1xuXG4gIGdldEFkV2F0ZXJmYWxsKGFkVGFnVXJsLCBmdW5jdGlvbiAoZXJyb3IsIHZhc3RUcmVlKSB7XG4gICAgdmFyIHdhdGVyZmFsbEFkcyA9IHZhc3RUcmVlICYmIHV0aWxpdGllcy5pc0FycmF5KHZhc3RUcmVlLmFkcykgPyB2YXN0VHJlZS5hZHMgOiBudWxsO1xuICAgIGlmIChlcnJvcikge1xuICAgICAgdGhhdC5fdHJhY2tFcnJvcihlcnJvciwgd2F0ZXJmYWxsQWRzKTtcbiAgICAgIHJldHVybiBjYWxsYmFjayhlcnJvciwgd2F0ZXJmYWxsQWRzKTtcbiAgICB9XG5cbiAgICBnZXRBZCh3YXRlcmZhbGxBZHMuc2hpZnQoKSwgW10sIHdhdGVyZmFsbEhhbmRsZXIpO1xuXG4gICAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqL1xuICAgIGZ1bmN0aW9uIHdhdGVyZmFsbEhhbmRsZXIoZXJyb3IsIGFkQ2hhaW4pIHtcbiAgICAgIGlmIChlcnJvcikge1xuICAgICAgICB0aGF0Ll90cmFja0Vycm9yKGVycm9yLCBhZENoYWluKTtcbiAgICAgICAgaWYgKHdhdGVyZmFsbEFkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgZ2V0QWQod2F0ZXJmYWxsQWRzLnNoaWZ0KCksW10sIHdhdGVyZmFsbEhhbmRsZXIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNhbGxiYWNrKGVycm9yLCBhZENoYWluKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FsbGJhY2sobnVsbCwgYWRDaGFpbik7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICAvKioqIExvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIGdldEFkV2F0ZXJmYWxsKGFkVGFnVXJsLCBjYWxsYmFjaykge1xuICAgIHZhciByZXF1ZXN0VmFzdFhNTCA9IHRoYXQuX3JlcXVlc3RWQVNUWG1sLmJpbmQodGhhdCwgYWRUYWdVcmwpO1xuICAgIGFzeW5jLndhdGVyZmFsbChbXG4gICAgICByZXF1ZXN0VmFzdFhNTCxcbiAgICAgIGJ1aWxkVmFzdFdhdGVyZmFsbFxuICAgIF0sIGNhbGxiYWNrKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGJ1aWxkVmFzdFdhdGVyZmFsbCh4bWxTdHIsIGNhbGxiYWNrKSB7XG4gICAgdmFyIHZhc3RUcmVlO1xuICAgIHRyeSB7XG4gICAgICB2YXN0VHJlZSA9IHhtbC50b0pYT05UcmVlKHhtbFN0cik7XG5cbiAgICAgIGlmKHV0aWxpdGllcy5pc0FycmF5KHZhc3RUcmVlLmFkKSkge1xuICAgICAgICB2YXN0VHJlZS5hZHMgPSB2YXN0VHJlZS5hZDtcbiAgICAgIH0gZWxzZSBpZih2YXN0VHJlZS5hZCl7XG4gICAgICAgIHZhc3RUcmVlLmFkcyA9IFt2YXN0VHJlZS5hZF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXN0VHJlZS5hZHMgPSBbXTtcbiAgICAgIH1cbiAgICAgIGNhbGxiYWNrKHZhbGlkYXRlVkFTVFRyZWUodmFzdFRyZWUpLCB2YXN0VHJlZSk7XG5cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjYWxsYmFjayhuZXcgVkFTVEVycm9yKFwib24gVkFTVENsaWVudC5nZXRWQVNUQWQuYnVpbGRWYXN0V2F0ZXJmYWxsLCBlcnJvciBwYXJzaW5nIHhtbFwiLCAxMDApLCBudWxsKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB2YWxpZGF0ZVZBU1RUcmVlKHZhc3RUcmVlKSB7XG4gICAgdmFyIHZhc3RWZXJzaW9uID0geG1sLmF0dHIodmFzdFRyZWUsICd2ZXJzaW9uJyk7XG5cbiAgICBpZiAoIXZhc3RUcmVlLmFkKSB7XG4gICAgICByZXR1cm4gbmV3IFZBU1RFcnJvcignb24gVkFTVENsaWVudC5nZXRWQVNUQWQudmFsaWRhdGVWQVNUVHJlZSwgbm8gQWQgaW4gVkFTVCB0cmVlJywgMzAzKTtcbiAgICB9XG5cbiAgICBpZiAodmFzdFZlcnNpb24gJiYgKHZhc3RWZXJzaW9uICE9IDMgJiYgdmFzdFZlcnNpb24gIT0gMikpIHtcbiAgICAgIHJldHVybiBuZXcgVkFTVEVycm9yKCdvbiBWQVNUQ2xpZW50LmdldFZBU1RBZC52YWxpZGF0ZVZBU1RUcmVlLCBub3Qgc3VwcG9ydGVkIFZBU1QgdmVyc2lvbiBcIicgKyB2YXN0VmVyc2lvbiArICdcIicsIDEwMik7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRBZChhZFRhZ1VybCwgYWRDaGFpbiwgY2FsbGJhY2spIHtcbiAgICBpZiAoYWRDaGFpbi5sZW5ndGggPj0gdGhhdC5XUkFQUEVSX0xJTUlUKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2sobmV3IFZBU1RFcnJvcihcIm9uIFZBU1RDbGllbnQuZ2V0VkFTVEFkLmdldEFkLCBwbGF5ZXJzIHdyYXBwZXIgbGltaXQgcmVhY2hlZCAodGhlIGxpbWl0IGlzIFwiICsgdGhhdC5XUkFQUEVSX0xJTUlUICsgXCIpXCIsIDMwMiksIGFkQ2hhaW4pO1xuICAgIH1cblxuICAgIGFzeW5jLndhdGVyZmFsbChbXG4gICAgICBmdW5jdGlvbiAobmV4dCkge1xuICAgICAgICBpZiAodXRpbGl0aWVzLmlzU3RyaW5nKGFkVGFnVXJsKSkge1xuICAgICAgICAgIHJlcXVlc3RWQVNUQWQoYWRUYWdVcmwsIG5leHQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5leHQobnVsbCwgYWRUYWdVcmwpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgYnVpbGRBZFxuICAgIF0sIGZ1bmN0aW9uIChlcnJvciwgYWQpIHtcbiAgICAgIGlmIChhZCkge1xuICAgICAgICBhZENoYWluLnB1c2goYWQpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycm9yLCBhZENoYWluKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFkLndyYXBwZXIpIHtcbiAgICAgICAgcmV0dXJuIGdldEFkKGFkLndyYXBwZXIuVkFTVEFkVGFnVVJJLCBhZENoYWluLCBjYWxsYmFjayk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBhZENoYWluKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGJ1aWxkQWQoYWRKeG9uVHJlZSwgY2FsbGJhY2spIHtcbiAgICB0cnkge1xuICAgICAgdmFyIGFkID0gbmV3IEFkKGFkSnhvblRyZWUpO1xuICAgICAgY2FsbGJhY2sodmFsaWRhdGVBZChhZCksIGFkKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjYWxsYmFjayhuZXcgVkFTVEVycm9yKCdvbiBWQVNUQ2xpZW50LmdldFZBU1RBZC5idWlsZEFkLCBlcnJvciBwYXJzaW5nIHhtbCcsIDEwMCksIG51bGwpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHZhbGlkYXRlQWQoYWQpIHtcbiAgICB2YXIgd3JhcHBlciA9IGFkLndyYXBwZXI7XG4gICAgdmFyIGluTGluZSA9IGFkLmluTGluZTtcbiAgICB2YXIgZXJyTXNnUHJlZml4ID0gJ29uIFZBU1RDbGllbnQuZ2V0VkFTVEFkLnZhbGlkYXRlQWQsICc7XG5cbiAgICBpZiAoaW5MaW5lICYmIHdyYXBwZXIpIHtcbiAgICAgIHJldHVybiBuZXcgVkFTVEVycm9yKGVyck1zZ1ByZWZpeCArXCJJbkxpbmUgYW5kIFdyYXBwZXIgYm90aCBmb3VuZCBvbiB0aGUgc2FtZSBBZFwiLCAxMDEpO1xuICAgIH1cblxuICAgIGlmICghaW5MaW5lICYmICF3cmFwcGVyKSB7XG4gICAgICByZXR1cm4gbmV3IFZBU1RFcnJvcihlcnJNc2dQcmVmaXggKyBcIm5vciB3cmFwcGVyIG5vciBpbmxpbmUgZWxlbWVudHMgZm91bmQgb24gdGhlIEFkXCIsIDEwMSk7XG4gICAgfVxuXG4gICAgaWYgKGluTGluZSAmJiBpbkxpbmUuY3JlYXRpdmVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIG5ldyBWQVNURXJyb3IoZXJyTXNnUHJlZml4ICsgXCJtaXNzaW5nIGNyZWF0aXZlIGluIEluTGluZSBlbGVtZW50XCIsIDEwMSk7XG4gICAgfVxuXG4gICAgaWYgKHdyYXBwZXIgJiYgIXdyYXBwZXIuVkFTVEFkVGFnVVJJKSB7XG4gICAgICByZXR1cm4gbmV3IFZBU1RFcnJvcihlcnJNc2dQcmVmaXggKyBcIm1pc3NpbmcgJ1ZBU1RBZFRhZ1VSSScgaW4gd3JhcHBlclwiLCAxMDEpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlcXVlc3RWQVNUQWQoYWRUYWdVcmwsIGNhbGxiYWNrKSB7XG4gICAgdGhhdC5fcmVxdWVzdFZBU1RYbWwoYWRUYWdVcmwsIGZ1bmN0aW9uIChlcnJvciwgeG1sU3RyKSB7XG4gICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycm9yKTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIHZhciB2YXN0VHJlZSA9IHhtbC50b0pYT05UcmVlKHhtbFN0cik7XG4gICAgICAgIGNhbGxiYWNrKHZhbGlkYXRlVkFTVFRyZWUodmFzdFRyZWUpLCB2YXN0VHJlZS5hZCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhbGxiYWNrKG5ldyBWQVNURXJyb3IoXCJvbiBWQVNUQ2xpZW50LmdldFZBU1RBZC5yZXF1ZXN0VkFTVEFkLCBlcnJvciBwYXJzaW5nIHhtbFwiLCAxMDApKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufTtcblxuVkFTVENsaWVudC5wcm90b3R5cGUuX3JlcXVlc3RWQVNUWG1sID0gZnVuY3Rpb24gcmVxdWVzdFZBU1RYbWwoYWRUYWdVcmwsIGNhbGxiYWNrKSB7XG4gIHRyeSB7XG4gICAgaWYgKHV0aWxpdGllcy5pc0Z1bmN0aW9uKGFkVGFnVXJsKSkge1xuICAgICAgYWRUYWdVcmwocmVxdWVzdEhhbmRsZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBodHRwLmdldChhZFRhZ1VybCwgcmVxdWVzdEhhbmRsZXIsIHtcbiAgICAgICAgd2l0aENyZWRlbnRpYWxzOiB0cnVlXG4gICAgICB9KTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjYWxsYmFjayhlKTtcbiAgfVxuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gcmVxdWVzdEhhbmRsZXIoZXJyb3IsIHJlc3BvbnNlLCBzdGF0dXMpIHtcbiAgICBpZiAoZXJyb3IpIHtcbiAgICAgIHZhciBlcnJNc2cgPSB1dGlsaXRpZXMuaXNEZWZpbmVkKHN0YXR1cykgP1xuICAgICAgXCJvbiBWQVNUQ2xpZW50LnJlcXVlc3RWYXN0WE1MLCBIVFRQIHJlcXVlc3QgZXJyb3Igd2l0aCBzdGF0dXMgJ1wiICsgc3RhdHVzICsgXCInXCIgOlxuICAgICAgICBcIm9uIFZBU1RDbGllbnQucmVxdWVzdFZhc3RYTUwsIEVycm9yIGdldHRpbmcgdGhlIHRoZSBWQVNUIFhNTCB3aXRoIGhlIHBhc3NlZCBhZFRhZ1hNTCBmblwiO1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBWQVNURXJyb3IoZXJyTXNnLCAzMDEpLCBudWxsKTtcbiAgICB9XG5cbiAgICBjYWxsYmFjayhudWxsLCByZXNwb25zZSk7XG4gIH1cbn07XG5cblZBU1RDbGllbnQucHJvdG90eXBlLl9idWlsZFZBU1RSZXNwb25zZSA9IGZ1bmN0aW9uIGJ1aWxkVkFTVFJlc3BvbnNlKGFkc0NoYWluKSB7XG4gIHZhciByZXNwb25zZSA9IG5ldyBWQVNUUmVzcG9uc2UoKTtcbiAgYWRkQWRzVG9SZXNwb25zZShyZXNwb25zZSwgYWRzQ2hhaW4pO1xuICB2YWxpZGF0ZVJlc3BvbnNlKHJlc3BvbnNlKTtcblxuICByZXR1cm4gcmVzcG9uc2U7XG5cbiAgLy8qKiogTG9jYWwgZnVuY3Rpb24gKioqKlxuICBmdW5jdGlvbiBhZGRBZHNUb1Jlc3BvbnNlKHJlc3BvbnNlLCBhZHMpIHtcbiAgICBhZHMuZm9yRWFjaChmdW5jdGlvbiAoYWQpIHtcbiAgICAgIHJlc3BvbnNlLmFkZEFkKGFkKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHZhbGlkYXRlUmVzcG9uc2UocmVzcG9uc2UpIHtcbiAgICB2YXIgcHJvZ3Jlc3NFdmVudHMgPSByZXNwb25zZS50cmFja2luZ0V2ZW50cy5wcm9ncmVzcztcblxuICAgIGlmICghcmVzcG9uc2UuaGFzTGluZWFyKCkpIHtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoXCJvbiBWQVNUQ2xpZW50Ll9idWlsZFZBU1RSZXNwb25zZSwgUmVjZWl2ZWQgYW4gQWQgdHlwZSB0aGF0IGlzIG5vdCBzdXBwb3J0ZWRcIiwgMjAwKTtcbiAgICB9XG5cbiAgICBpZiAocmVzcG9uc2UuZHVyYXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcihcIm9uIFZBU1RDbGllbnQuX2J1aWxkVkFTVFJlc3BvbnNlLCBNaXNzaW5nIGR1cmF0aW9uIGZpZWxkIGluIFZBU1QgcmVzcG9uc2VcIiwgMTAxKTtcbiAgICB9XG5cbiAgICBpZiAocHJvZ3Jlc3NFdmVudHMpIHtcbiAgICAgIHByb2dyZXNzRXZlbnRzLmZvckVhY2goZnVuY3Rpb24gKHByb2dyZXNzRXZlbnQpIHtcbiAgICAgICAgaWYgKCF1dGlsaXRpZXMuaXNOdW1iZXIocHJvZ3Jlc3NFdmVudC5vZmZzZXQpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcihcIm9uIFZBU1RDbGllbnQuX2J1aWxkVkFTVFJlc3BvbnNlLCBtaXNzaW5nIG9yIHdyb25nIG9mZnNldCBhdHRyaWJ1dGUgb24gcHJvZ3Jlc3MgdHJhY2tpbmcgZXZlbnRcIiwgMTAxKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG59O1xuXG5WQVNUQ2xpZW50LnByb3RvdHlwZS5fdHJhY2tFcnJvciA9IGZ1bmN0aW9uIChlcnJvciwgYWRDaGFpbikge1xuICBpZiAoIXV0aWxpdGllcy5pc0FycmF5KGFkQ2hhaW4pIHx8IGFkQ2hhaW4ubGVuZ3RoID09PSAwKSB7IC8vVGhlcmUgaXMgbm90aGluZyB0byB0cmFja1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBlcnJvclVSTE1hY3JvcyA9IFtdO1xuICBhZENoYWluLmZvckVhY2goYWRkRXJyb3JVcmxNYWNyb3MpO1xuICB2YXN0VXRpbC50cmFjayhlcnJvclVSTE1hY3Jvcywge0VSUk9SQ09ERTogZXJyb3IuY29kZSB8fCA5MDB9KTsgIC8vOTAwIDw9PSBVbmRlZmluZWQgZXJyb3JcblxuICAvKioqIExvY2FsIGZ1bmN0aW9ucyAgKioqL1xuICBmdW5jdGlvbiBhZGRFcnJvclVybE1hY3JvcyhhZCkge1xuICAgIGlmIChhZC53cmFwcGVyICYmIGFkLndyYXBwZXIuZXJyb3IpIHtcbiAgICAgIGVycm9yVVJMTWFjcm9zLnB1c2goYWQud3JhcHBlci5lcnJvcik7XG4gICAgfVxuXG4gICAgaWYgKGFkLmluTGluZSAmJiBhZC5pbkxpbmUuZXJyb3IpIHtcbiAgICAgIGVycm9yVVJMTWFjcm9zLnB1c2goYWQuaW5MaW5lLmVycm9yKTtcbiAgICB9XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gVkFTVENsaWVudDtcbiIsIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gVkFTVEVycm9yKG1lc3NhZ2UsIGNvZGUpIHtcbiAgdGhpcy5tZXNzYWdlID0gJ1ZBU1QgRXJyb3I6ICcgKyAobWVzc2FnZSB8fCAnJyk7XG4gIGlmIChjb2RlKSB7XG4gICAgdGhpcy5jb2RlID0gY29kZTtcbiAgfVxufVxuXG5WQVNURXJyb3IucHJvdG90eXBlID0gbmV3IEVycm9yKCk7XG5WQVNURXJyb3IucHJvdG90eXBlLm5hbWUgPSBcIlZBU1QgRXJyb3JcIjtcblxubW9kdWxlLmV4cG9ydHMgPSBWQVNURXJyb3I7IiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIElubmVyIGhlbHBlciBjbGFzcyB0aGF0IGRlYWxzIHdpdGggdGhlIGxvZ2ljIG9mIHRoZSBpbmRpdmlkdWFsIHN0ZXBzIG5lZWRlZCB0byBzZXR1cCBhbiBhZCBpbiB0aGUgcGxheWVyLlxuICpcbiAqIEBwYXJhbSBwbGF5ZXIge29iamVjdH0gaW5zdGFuY2Ugb2YgdGhlIHBsYXllciB0aGF0IHdpbGwgcGxheSB0aGUgYWQuIEl0IGFzc3VtZXMgdGhhdCB0aGUgdmlkZW9qcy1jb250cmliLWFkcyBwbHVnaW5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgaGFzIGJlZW4gaW5pdGlhbGl6ZWQgd2hlbiB5b3UgdXNlIGl0cyB1dGlsaXR5IGZ1bmN0aW9ucy5cbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuXG52YXIgVkFTVFJlc3BvbnNlID0gcmVxdWlyZSgnLi9WQVNUUmVzcG9uc2UnKTtcbnZhciBWQVNURXJyb3IgPSByZXF1aXJlKCcuL1ZBU1RFcnJvcicpO1xudmFyIFZBU1RUcmFja2VyID0gcmVxdWlyZSgnLi9WQVNUVHJhY2tlcicpO1xudmFyIHZhc3RVdGlsID0gcmVxdWlyZSgnLi92YXN0VXRpbCcpO1xuXG52YXIgYXN5bmMgPSByZXF1aXJlKCcuLi8uLi91dGlscy9hc3luYycpO1xudmFyIGRvbSA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL2RvbScpO1xudmFyIHBsYXllclV0aWxzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvcGxheWVyVXRpbHMnKTtcbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbmZ1bmN0aW9uIFZBU1RJbnRlZ3JhdG9yKHBsYXllcikge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVkFTVEludGVncmF0b3IpKSB7XG4gICAgcmV0dXJuIG5ldyBWQVNUSW50ZWdyYXRvcihwbGF5ZXIpO1xuICB9XG5cbiAgdGhpcy5wbGF5ZXIgPSBwbGF5ZXI7XG59XG5cblZBU1RJbnRlZ3JhdG9yLnByb3RvdHlwZS5wbGF5QWQgPSBmdW5jdGlvbiBwbGF5QWQodmFzdFJlc3BvbnNlLCBjYWxsYmFjaykge1xuICB2YXIgdGhhdCA9IHRoaXM7XG4gIGNhbGxiYWNrID0gY2FsbGJhY2sgfHwgdXRpbGl0aWVzLm5vb3A7XG5cbiAgaWYgKCEodmFzdFJlc3BvbnNlIGluc3RhbmNlb2YgVkFTVFJlc3BvbnNlKSkge1xuICAgIHJldHVybiBjYWxsYmFjayhuZXcgVkFTVEVycm9yKCdPbiBWQVNUSW50ZWdyYXRvciwgbWlzc2luZyByZXF1aXJlZCBWQVNUUmVzcG9uc2UnKSk7XG4gIH1cblxuICBhc3luYy53YXRlcmZhbGwoW1xuICAgIGZ1bmN0aW9uIChuZXh0KSB7XG4gICAgICBuZXh0KG51bGwsIHZhc3RSZXNwb25zZSk7XG4gICAgfSxcbiAgICB0aGlzLl9zZWxlY3RBZFNvdXJjZS5iaW5kKHRoaXMpLFxuICAgIHRoaXMuX2NyZWF0ZVZBU1RUcmFja2VyLmJpbmQodGhpcyksXG4gICAgdGhpcy5fYWRkQ2xpY2tUaHJvdWdoLmJpbmQodGhpcyksXG4gICAgdGhpcy5fYWRkU2tpcEJ1dHRvbi5iaW5kKHRoaXMpLFxuICAgIHRoaXMuX3NldHVwRXZlbnRzLmJpbmQodGhpcyksXG4gICAgdGhpcy5fcGxheVNlbGVjdGVkQWQuYmluZCh0aGlzKVxuICBdLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3BvbnNlKSB7XG4gICAgaWYgKGVycm9yICYmIHJlc3BvbnNlKSB7XG4gICAgICB0aGF0Ll90cmFja0Vycm9yKGVycm9yLCByZXNwb25zZSk7XG4gICAgfVxuICAgIGNhbGxiYWNrKGVycm9yLCByZXNwb25zZSk7XG4gIH0pO1xuXG4gIHRoaXMuX2FkVW5pdCA9IHtcbiAgICBfc3JjOiBudWxsLFxuICAgIHR5cGU6ICdWQVNUJyxcbiAgICBwYXVzZUFkOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGF0LnBsYXllci5wYXVzZSh0cnVlKTtcbiAgICB9LFxuXG4gICAgcmVzdW1lQWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoYXQucGxheWVyLnBsYXkodHJ1ZSk7XG4gICAgfSxcblxuICAgIGlzUGF1c2VkOiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gdGhhdC5wbGF5ZXIucGF1c2VkKHRydWUpO1xuICAgIH0sXG5cbiAgICBnZXRTcmM6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiB0aGlzLl9zcmM7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiB0aGlzLl9hZFVuaXQ7XG59O1xuXG5WQVNUSW50ZWdyYXRvci5wcm90b3R5cGUuX3NlbGVjdEFkU291cmNlID0gZnVuY3Rpb24gc2VsZWN0QWRTb3VyY2UocmVzcG9uc2UsIGNhbGxiYWNrKSB7XG4gIHZhciBzb3VyY2U7XG5cbiAgdmFyIHBsYXllcldpZHRoID0gZG9tLmdldERpbWVuc2lvbih0aGlzLnBsYXllci5lbCgpKS53aWR0aDtcbiAgcmVzcG9uc2UubWVkaWFGaWxlcy5zb3J0KGZ1bmN0aW9uIGNvbXBhcmVUbyhhLCBiKSB7XG4gICAgdmFyIGRlbHRhQSA9IE1hdGguYWJzKHBsYXllcldpZHRoIC0gYS53aWR0aCk7XG4gICAgdmFyIGRlbHRhQiA9IE1hdGguYWJzKHBsYXllcldpZHRoIC0gYi53aWR0aCk7XG4gICAgcmV0dXJuIGRlbHRhQSAtIGRlbHRhQjtcbiAgfSk7XG5cbiAgc291cmNlID0gdGhpcy5wbGF5ZXIuc2VsZWN0U291cmNlKHJlc3BvbnNlLm1lZGlhRmlsZXMpLnNvdXJjZTtcblxuICBpZiAoc291cmNlKSB7XG4gICAgaWYgKHRoaXMuX2FkVW5pdCkge1xuICAgICAgdGhpcy5fYWRVbml0Ll9zcmMgPSBzb3VyY2U7XG4gICAgfVxuICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBzb3VyY2UsIHJlc3BvbnNlKTtcbiAgfVxuXG4gIC8vIGNvZGUgNDAzIDw9PSBDb3VsZG4ndCBmaW5kIE1lZGlhRmlsZSB0aGF0IGlzIHN1cHBvcnRlZCBieSB0aGlzIHZpZGVvIHBsYXllclxuICBjYWxsYmFjayhuZXcgVkFTVEVycm9yKFwiQ291bGQgbm90IGZpbmQgQWQgbWVkaWFmaWxlIHN1cHBvcnRlZCBieSB0aGlzIHBsYXllclwiLCA0MDMpLCByZXNwb25zZSk7XG59O1xuXG5WQVNUSW50ZWdyYXRvci5wcm90b3R5cGUuX2NyZWF0ZVZBU1RUcmFja2VyID0gZnVuY3Rpb24gY3JlYXRlVkFTVFRyYWNrZXIoYWRNZWRpYUZpbGUsIHJlc3BvbnNlLCBjYWxsYmFjaykge1xuICB0cnkge1xuICAgIGNhbGxiYWNrKG51bGwsIGFkTWVkaWFGaWxlLCBuZXcgVkFTVFRyYWNrZXIoYWRNZWRpYUZpbGUuc3JjLCByZXNwb25zZSksIHJlc3BvbnNlKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNhbGxiYWNrKGUsIHJlc3BvbnNlKTtcbiAgfVxufTtcblxuVkFTVEludGVncmF0b3IucHJvdG90eXBlLl9zZXR1cEV2ZW50cyA9IGZ1bmN0aW9uIHNldHVwRXZlbnRzKGFkTWVkaWFGaWxlLCB0cmFja2VyLCByZXNwb25zZSwgY2FsbGJhY2spIHtcbiAgdmFyIHByZXZpb3VzbHlNdXRlZDtcbiAgdmFyIHBsYXllciA9IHRoaXMucGxheWVyO1xuICBwbGF5ZXIub24oJ2Z1bGxzY3JlZW5jaGFuZ2UnLCB0cmFja0Z1bGxzY3JlZW5DaGFuZ2UpO1xuICBwbGF5ZXIub24oJ3Zhc3QuYWRTdGFydCcsIHRyYWNrSW1wcmVzc2lvbnMpO1xuICBwbGF5ZXIub24oJ3BhdXNlJywgdHJhY2tQYXVzZSk7XG4gIHBsYXllci5vbigndGltZXVwZGF0ZScsIHRyYWNrUHJvZ3Jlc3MpO1xuICBwbGF5ZXIub24oJ3ZvbHVtZWNoYW5nZScsIHRyYWNrVm9sdW1lQ2hhbmdlKTtcblxuICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWyd2YXN0LmFkRW5kJywgJ3Zhc3QuYWRzQ2FuY2VsJ10sIHVuYmluZEV2ZW50cyk7XG4gIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3Zhc3QuYWRFbmQnLCAndmFzdC5hZHNDYW5jZWwnLCAndmFzdC5hZFNraXAnXSwgZnVuY3Rpb24oZXZ0KXtcbiAgICBpZihldnQudHlwZSA9PT0gJ3Zhc3QuYWRFbmQnKXtcbiAgICAgIHRyYWNrZXIudHJhY2tDb21wbGV0ZSgpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGFkTWVkaWFGaWxlLCByZXNwb25zZSk7XG5cbiAgLyoqKiBMb2NhbCBGdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiB1bmJpbmRFdmVudHMoKSB7XG4gICAgcGxheWVyLm9mZignZnVsbHNjcmVlbmNoYW5nZScsIHRyYWNrRnVsbHNjcmVlbkNoYW5nZSk7XG4gICAgcGxheWVyLm9mZigndmFzdC5hZFN0YXJ0JywgdHJhY2tJbXByZXNzaW9ucyk7XG4gICAgcGxheWVyLm9mZigncGF1c2UnLCB0cmFja1BhdXNlKTtcbiAgICBwbGF5ZXIub2ZmKCd0aW1ldXBkYXRlJywgdHJhY2tQcm9ncmVzcyk7XG4gICAgcGxheWVyLm9mZigndm9sdW1lY2hhbmdlJywgdHJhY2tWb2x1bWVDaGFuZ2UpO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJhY2tGdWxsc2NyZWVuQ2hhbmdlKCkge1xuICAgIGlmIChwbGF5ZXIuaXNGdWxsc2NyZWVuKCkpIHtcbiAgICAgIHRyYWNrZXIudHJhY2tGdWxsc2NyZWVuKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRyYWNrZXIudHJhY2tFeGl0RnVsbHNjcmVlbigpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYWNrUGF1c2UoKSB7XG4gICAgLy9OT1RFOiB3aGVuZXZlciBhIHZpZGVvIGVuZHMgdGhlIHZpZGVvIEVsZW1lbnQgdHJpZ2dlcnMgYSAncGF1c2UnIGV2ZW50IGJlZm9yZSB0aGUgJ2VuZGVkJyBldmVudC5cbiAgICAvLyAgICAgIFdlIHNob3VsZCBub3QgdHJhY2sgdGhpcyBwYXVzZSBldmVudCBiZWNhdXNlIGl0IG1ha2VzIHRoZSBWQVNUIHRyYWNraW5nIGNvbmZ1c2luZyBhZ2FpbiB3ZSB1c2UgYVxuICAgIC8vICAgICAgVGhyZXNob2xkIG9mIDIgc2Vjb25kcyB0byBwcmV2ZW50IGZhbHNlIHBvc2l0aXZlcyBvbiBJT1MuXG4gICAgaWYgKE1hdGguYWJzKHBsYXllci5kdXJhdGlvbigpIC0gcGxheWVyLmN1cnJlbnRUaW1lKCkpIDwgMikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyYWNrZXIudHJhY2tQYXVzZSgpO1xuICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3BsYXknLCAndmFzdC5hZEVuZCcsICd2YXN0LmFkc0NhbmNlbCddLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICBpZihldnQudHlwZSA9PT0gJ3BsYXknKXtcbiAgICAgICAgdHJhY2tlci50cmFja1Jlc3VtZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJhY2tQcm9ncmVzcygpIHtcbiAgICB2YXIgY3VycmVudFRpbWVJbk1zID0gcGxheWVyLmN1cnJlbnRUaW1lKCkgKiAxMDAwO1xuICAgIHRyYWNrZXIudHJhY2tQcm9ncmVzcyhjdXJyZW50VGltZUluTXMpO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJhY2tJbXByZXNzaW9ucygpIHtcbiAgICB0cmFja2VyLnRyYWNrSW1wcmVzc2lvbnMoKTtcbiAgICB0cmFja2VyLnRyYWNrQ3JlYXRpdmVWaWV3KCk7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFja1ZvbHVtZUNoYW5nZSgpIHtcbiAgICB2YXIgbXV0ZWQgPSBwbGF5ZXIubXV0ZWQoKTtcbiAgICBpZiAobXV0ZWQpIHtcbiAgICAgIHRyYWNrZXIudHJhY2tNdXRlKCk7XG4gICAgfSBlbHNlIGlmIChwcmV2aW91c2x5TXV0ZWQpIHtcbiAgICAgIHRyYWNrZXIudHJhY2tVbm11dGUoKTtcbiAgICB9XG4gICAgcHJldmlvdXNseU11dGVkID0gbXV0ZWQ7XG4gIH1cbn07XG5cblZBU1RJbnRlZ3JhdG9yLnByb3RvdHlwZS5fYWRkU2tpcEJ1dHRvbiA9IGZ1bmN0aW9uIGFkZFNraXBCdXR0b24oc291cmNlLCB0cmFja2VyLCByZXNwb25zZSwgY2FsbGJhY2spIHtcbiAgdmFyIHNraXBPZmZzZXRJblNlYztcbiAgdmFyIHRoYXQgPSB0aGlzO1xuXG4gIGlmICh1dGlsaXRpZXMuaXNOdW1iZXIocmVzcG9uc2Uuc2tpcG9mZnNldCkpIHtcbiAgICBza2lwT2Zmc2V0SW5TZWMgPSByZXNwb25zZS5za2lwb2Zmc2V0IC8gMTAwMDtcbiAgICBhZGRTa2lwQnV0dG9uVG9QbGF5ZXIodGhpcy5wbGF5ZXIsIHNraXBPZmZzZXRJblNlYyk7XG4gIH1cbiAgY2FsbGJhY2sobnVsbCwgc291cmNlLCB0cmFja2VyLCByZXNwb25zZSk7XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbiAqKiovXG4gIGZ1bmN0aW9uIGFkZFNraXBCdXR0b25Ub1BsYXllcihwbGF5ZXIsIHNraXBPZmZzZXQpIHtcbiAgICB2YXIgc2tpcEJ1dHRvbiA9IGNyZWF0ZVNraXBCdXR0b24ocGxheWVyKTtcbiAgICB2YXIgdXBkYXRlU2tpcEJ1dHRvbiA9IHVwZGF0ZVNraXBCdXR0b25TdGF0ZS5iaW5kKHRoYXQsIHNraXBCdXR0b24sIHNraXBPZmZzZXQsIHBsYXllcik7XG5cbiAgICBwbGF5ZXIuZWwoKS5hcHBlbmRDaGlsZChza2lwQnV0dG9uKTtcbiAgICBwbGF5ZXIub24oJ3RpbWV1cGRhdGUnLCB1cGRhdGVTa2lwQnV0dG9uKTtcblxuICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3Zhc3QuYWRFbmQnLCAndmFzdC5hZHNDYW5jZWwnXSwgcmVtb3ZlU2tpcEJ1dHRvbik7XG5cbiAgICBmdW5jdGlvbiByZW1vdmVTa2lwQnV0dG9uKCkge1xuICAgICAgcGxheWVyLm9mZigndGltZXVwZGF0ZScsIHVwZGF0ZVNraXBCdXR0b24pO1xuICAgICAgZG9tLnJlbW92ZShza2lwQnV0dG9uKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVTa2lwQnV0dG9uKHBsYXllcikge1xuICAgIHZhciBza2lwQnV0dG9uID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgZG9tLmFkZENsYXNzKHNraXBCdXR0b24sIFwidmFzdC1za2lwLWJ1dHRvblwiKTtcblxuICAgIHNraXBCdXR0b24ub25jbGljayA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICBpZiAoZG9tLmhhc0NsYXNzKHNraXBCdXR0b24sICdlbmFibGVkJykpIHtcbiAgICAgICAgdHJhY2tlci50cmFja1NraXAoKTtcbiAgICAgICAgcGxheWVyLnRyaWdnZXIoJ3Zhc3QuYWRTa2lwJyk7XG4gICAgICB9XG5cbiAgICAgIC8vV2UgcHJldmVudCBldmVudCBwcm9wYWdhdGlvbiB0byBhdm9pZCBwcm9ibGVtcyB3aXRoIHRoZSBjbGlja1Rocm91Z2ggYW5kIHNvIG9uXG4gICAgICBpZiAod2luZG93LkV2ZW50LnByb3RvdHlwZS5zdG9wUHJvcGFnYXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gc2tpcEJ1dHRvbjtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZVNraXBCdXR0b25TdGF0ZShza2lwQnV0dG9uLCBza2lwT2Zmc2V0LCBwbGF5ZXIpIHtcbiAgICB2YXIgdGltZUxlZnQgPSBNYXRoLmNlaWwoc2tpcE9mZnNldCAtIHBsYXllci5jdXJyZW50VGltZSgpKTtcbiAgICBpZiAodGltZUxlZnQgPiAwKSB7XG4gICAgICBza2lwQnV0dG9uLmlubmVySFRNTCA9IFwiU2tpcCBpbiBcIiArIHV0aWxpdGllcy50b0ZpeGVkRGlnaXRzKHRpbWVMZWZ0LCAyKSArIFwiLi4uXCI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghZG9tLmhhc0NsYXNzKHNraXBCdXR0b24sICdlbmFibGVkJykpIHtcbiAgICAgICAgZG9tLmFkZENsYXNzKHNraXBCdXR0b24sICdlbmFibGVkJyk7XG4gICAgICAgIHNraXBCdXR0b24uaW5uZXJIVE1MID0gXCJTa2lwIGFkXCI7XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG5WQVNUSW50ZWdyYXRvci5wcm90b3R5cGUuX2FkZENsaWNrVGhyb3VnaCA9IGZ1bmN0aW9uIGFkZENsaWNrVGhyb3VnaChtZWRpYUZpbGUsIHRyYWNrZXIsIHJlc3BvbnNlLCBjYWxsYmFjaykge1xuICB2YXIgcGxheWVyID0gdGhpcy5wbGF5ZXI7XG4gIHZhciBibG9ja2VyID0gY3JlYXRlQ2xpY2tUaHJvdWdoQmxvY2tlcihwbGF5ZXIsIHRyYWNrZXIsIHJlc3BvbnNlKTtcbiAgdmFyIHVwZGF0ZUJsb2NrZXIgPSB1cGRhdGVCbG9ja2VyVVJMLmJpbmQodGhpcywgYmxvY2tlciwgcmVzcG9uc2UsIHBsYXllcik7XG5cbiAgcGxheWVyLmVsKCkuaW5zZXJ0QmVmb3JlKGJsb2NrZXIsIHBsYXllci5jb250cm9sQmFyLmVsKCkpO1xuICBwbGF5ZXIub24oJ3RpbWV1cGRhdGUnLCB1cGRhdGVCbG9ja2VyKTtcbiAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsndmFzdC5hZEVuZCcsICd2YXN0LmFkc0NhbmNlbCddLCByZW1vdmVCbG9ja2VyKTtcblxuICByZXR1cm4gY2FsbGJhY2sobnVsbCwgbWVkaWFGaWxlLCB0cmFja2VyLCByZXNwb25zZSk7XG5cbiAgLyoqKiBMb2NhbCBGdW5jdGlvbnMgKioqL1xuXG4gIGZ1bmN0aW9uIGNyZWF0ZUNsaWNrVGhyb3VnaEJsb2NrZXIocGxheWVyLCB0cmFja2VyLCByZXNwb25zZSkge1xuICAgIHZhciBibG9ja2VyID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJhXCIpO1xuICAgIHZhciBjbGlja1Rocm91Z2hNYWNybyA9IHJlc3BvbnNlLmNsaWNrVGhyb3VnaDtcblxuICAgIGRvbS5hZGRDbGFzcyhibG9ja2VyLCAndmFzdC1ibG9ja2VyJyk7XG4gICAgYmxvY2tlci5ocmVmID0gZ2VuZXJhdGVDbGlja1Rocm91Z2hVUkwoY2xpY2tUaHJvdWdoTWFjcm8sIHBsYXllcik7XG5cbiAgICBpZiAodXRpbGl0aWVzLmlzU3RyaW5nKGNsaWNrVGhyb3VnaE1hY3JvKSkge1xuICAgICAgYmxvY2tlci50YXJnZXQgPSBcIl9ibGFua1wiO1xuICAgIH1cblxuICAgIGJsb2NrZXIub25jbGljayA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICBpZiAocGxheWVyLnBhdXNlZCgpKSB7XG4gICAgICAgIHBsYXllci5wbGF5KCk7XG5cbiAgICAgICAgLy9XZSBwcmV2ZW50IGV2ZW50IHByb3BhZ2F0aW9uIHRvIGF2b2lkIHByb2JsZW1zIHdpdGggdGhlIHBsYXllcidzIG5vcm1hbCBwYXVzZSBtZWNoYW5pc21cbiAgICAgICAgaWYgKHdpbmRvdy5FdmVudC5wcm90b3R5cGUuc3RvcFByb3BhZ2F0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgcGxheWVyLnBhdXNlKCk7XG4gICAgICB0cmFja2VyLnRyYWNrQ2xpY2soKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGJsb2NrZXI7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVCbG9ja2VyVVJMKGJsb2NrZXIsIHJlc3BvbnNlLCBwbGF5ZXIpIHtcbiAgICBibG9ja2VyLmhyZWYgPSBnZW5lcmF0ZUNsaWNrVGhyb3VnaFVSTChyZXNwb25zZS5jbGlja1Rocm91Z2gsIHBsYXllcik7XG4gIH1cblxuICBmdW5jdGlvbiBnZW5lcmF0ZUNsaWNrVGhyb3VnaFVSTChjbGlja1Rocm91Z2hNYWNybywgcGxheWVyKSB7XG4gICAgdmFyIHZhcmlhYmxlcyA9IHtcbiAgICAgIEFTU0VUVVJJOiBtZWRpYUZpbGUuc3JjLFxuICAgICAgQ09OVEVOVFBMQVlIRUFEOiB2YXN0VXRpbC5mb3JtYXRQcm9ncmVzcyhwbGF5ZXIuY3VycmVudFRpbWUoKSAqIDEwMDApXG4gICAgfTtcblxuICAgIHJldHVybiBjbGlja1Rocm91Z2hNYWNybyA/IHZhc3RVdGlsLnBhcnNlVVJMTWFjcm8oY2xpY2tUaHJvdWdoTWFjcm8sIHZhcmlhYmxlcykgOiAnIyc7XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVCbG9ja2VyKCkge1xuICAgIHBsYXllci5vZmYoJ3RpbWV1cGRhdGUnLCB1cGRhdGVCbG9ja2VyKTtcbiAgICBkb20ucmVtb3ZlKGJsb2NrZXIpO1xuICB9XG59O1xuXG5WQVNUSW50ZWdyYXRvci5wcm90b3R5cGUuX3BsYXlTZWxlY3RlZEFkID0gZnVuY3Rpb24gcGxheVNlbGVjdGVkQWQoc291cmNlLCByZXNwb25zZSwgY2FsbGJhY2spIHtcbiAgdmFyIHBsYXllciA9IHRoaXMucGxheWVyO1xuXG4gIHBsYXllci5wcmVsb2FkKFwiYXV0b1wiKTsgLy93aXRob3V0IHByZWxvYWQ9YXV0byB0aGUgZHVyYXRpb25jaGFuZ2UgZXZlbnQgaXMgbmV2ZXIgZmlyZWRcbiAgcGxheWVyLnNyYyhzb3VyY2UpO1xuXG4gIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ2R1cmF0aW9uY2hhbmdlJywgJ2Vycm9yJywgJ3Zhc3QuYWRzQ2FuY2VsJ10sIGZ1bmN0aW9uIChldnQpIHtcbiAgICBpZiAoZXZ0LnR5cGUgPT09ICdkdXJhdGlvbmNoYW5nZScpIHtcbiAgICAgIHBsYXlBZCgpO1xuICAgIH0gZWxzZSBpZihldnQudHlwZSA9PT0gJ2Vycm9yJykge1xuICAgICAgY2FsbGJhY2sobmV3IFZBU1RFcnJvcihcIm9uIFZBU1RJbnRlZ3JhdG9yLCBQbGF5ZXIgaXMgdW5hYmxlIHRvIHBsYXkgdGhlIEFkXCIsIDQwMCksIHJlc3BvbnNlKTtcbiAgICB9XG4gICAgLy9OT1RFOiBJZiB0aGUgYWRzIGdldCBjYW5jZWxlZCB3ZSBkbyBub3RoaW5nL1xuICB9KTtcblxuICAvKioqKiBsb2NhbCBmdW5jdGlvbnMgKioqKioqL1xuICBmdW5jdGlvbiBwbGF5QWQoKSB7XG4gICAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsncGxheWluZycsICd2YXN0LmFkc0NhbmNlbCddLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICBpZihldnQudHlwZSA9PT0gJ3Zhc3QuYWRzQ2FuY2VsJyl7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgcGxheWVyLnRyaWdnZXIoJ3Zhc3QuYWRTdGFydCcpO1xuXG4gICAgICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWydlbmRlZCcsICd2YXN0LmFkc0NhbmNlbCcsICd2YXN0LmFkU2tpcCddLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIGlmKGV2dC50eXBlID09PSAnZW5kZWQnIHx8IGV2dC50eXBlID09PSAndmFzdC5hZFNraXAnKXtcbiAgICAgICAgICBjYWxsYmFjayhudWxsLCByZXNwb25zZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy9OT1RFOiBpZiB0aGUgYWRzIGdldCBjYW5jZWwgd2UgZG8gbm90aGluZ1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgcGxheWVyLnBsYXkoKTtcbiAgfVxufTtcblxuVkFTVEludGVncmF0b3IucHJvdG90eXBlLl90cmFja0Vycm9yID0gZnVuY3Rpb24gdHJhY2tFcnJvcihlcnJvciwgcmVzcG9uc2UpIHtcbiAgdmFzdFV0aWwudHJhY2socmVzcG9uc2UuZXJyb3JVUkxNYWNyb3MsIHtFUlJPUkNPREU6IGVycm9yLmNvZGUgfHwgOTAwfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZBU1RJbnRlZ3JhdG9yOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIEFkID0gcmVxdWlyZSgnLi9BZCcpO1xudmFyIFZpZGVvQ2xpY2tzID0gcmVxdWlyZSgnLi9WaWRlb0NsaWNrcycpO1xudmFyIExpbmVhciA9IHJlcXVpcmUoJy4vTGluZWFyJyk7XG52YXIgSW5MaW5lID0gcmVxdWlyZSgnLi9JbkxpbmUnKTtcbnZhciBXcmFwcGVyID0gcmVxdWlyZSgnLi9XcmFwcGVyJyk7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG52YXIgeG1sID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMveG1sJyk7XG5cbndpbmRvdy5JbkxpbmVfX0EgPSBJbkxpbmU7XG5mdW5jdGlvbiBWQVNUUmVzcG9uc2UoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBWQVNUUmVzcG9uc2UpKSB7XG4gICAgcmV0dXJuIG5ldyBWQVNUUmVzcG9uc2UoKTtcbiAgfVxuXG4gIHRoaXMuX2xpbmVhckFkZGVkID0gZmFsc2U7XG4gIHRoaXMuYWRzID0gW107XG4gIHRoaXMuZXJyb3JVUkxNYWNyb3MgPSBbXTtcbiAgdGhpcy5pbXByZXNzaW9ucyA9IFtdO1xuICB0aGlzLmNsaWNrVHJhY2tpbmdzID0gW107XG4gIHRoaXMuY3VzdG9tQ2xpY2tzID0gW107XG4gIHRoaXMudHJhY2tpbmdFdmVudHMgPSB7fTtcbiAgdGhpcy5tZWRpYUZpbGVzID0gW107XG4gIHRoaXMuY2xpY2tUaHJvdWdoID0gdW5kZWZpbmVkO1xuICB0aGlzLmFkVGl0bGUgPSAnJztcbiAgdGhpcy5kdXJhdGlvbiA9IHVuZGVmaW5lZDtcbiAgdGhpcy5za2lwb2Zmc2V0ID0gdW5kZWZpbmVkO1xufVxuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLmFkZEFkID0gZnVuY3Rpb24gKGFkKSB7XG4gIHZhciBpbkxpbmUsIHdyYXBwZXI7XG4gIGlmIChhZCBpbnN0YW5jZW9mIEFkKSB7XG4gICAgaW5MaW5lID0gYWQuaW5MaW5lO1xuICAgIHdyYXBwZXIgPSBhZC53cmFwcGVyO1xuXG4gICAgdGhpcy5hZHMucHVzaChhZCk7XG5cbiAgICBpZiAoaW5MaW5lKSB7XG4gICAgICB0aGlzLl9hZGRJbkxpbmUoaW5MaW5lKTtcbiAgICB9XG5cbiAgICBpZiAod3JhcHBlcikge1xuICAgICAgdGhpcy5fYWRkV3JhcHBlcih3cmFwcGVyKTtcbiAgICB9XG4gIH1cbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZEVycm9yVHJhY2tVcmwgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgdmFyIGVycm9yVVJMID0gZXJyb3IgaW5zdGFuY2VvZiB4bWwuSlhPTlRyZWUgPyB4bWwua2V5VmFsdWUoZXJyb3IpIDogZXJyb3I7XG4gIGlmIChlcnJvclVSTCkge1xuICAgIHRoaXMuZXJyb3JVUkxNYWNyb3MucHVzaChlcnJvclVSTCk7XG4gIH1cbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZEltcHJlc3Npb25zID0gZnVuY3Rpb24gKGltcHJlc3Npb25zKSB7XG4gIHV0aWxpdGllcy5pc0FycmF5KGltcHJlc3Npb25zKSAmJiBhcHBlbmRUb0FycmF5KHRoaXMuaW1wcmVzc2lvbnMsIGltcHJlc3Npb25zKTtcbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZENsaWNrVGhyb3VnaCA9IGZ1bmN0aW9uIChjbGlja1Rocm91Z2gpIHtcbiAgaWYgKHV0aWxpdGllcy5pc05vdEVtcHR5U3RyaW5nKGNsaWNrVGhyb3VnaCkpIHtcbiAgICB0aGlzLmNsaWNrVGhyb3VnaCA9IGNsaWNrVGhyb3VnaDtcbiAgfVxufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkQ2xpY2tUcmFja2luZ3MgPSBmdW5jdGlvbiAoY2xpY2tUcmFja2luZ3MpIHtcbiAgdXRpbGl0aWVzLmlzQXJyYXkoY2xpY2tUcmFja2luZ3MpICYmIGFwcGVuZFRvQXJyYXkodGhpcy5jbGlja1RyYWNraW5ncywgY2xpY2tUcmFja2luZ3MpO1xufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkQ3VzdG9tQ2xpY2tzID0gZnVuY3Rpb24gKGN1c3RvbUNsaWNrcykge1xuICB1dGlsaXRpZXMuaXNBcnJheShjdXN0b21DbGlja3MpICYmIGFwcGVuZFRvQXJyYXkodGhpcy5jdXN0b21DbGlja3MsIGN1c3RvbUNsaWNrcyk7XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRUcmFja2luZ0V2ZW50cyA9IGZ1bmN0aW9uICh0cmFja2luZ0V2ZW50cykge1xuICB2YXIgZXZlbnRzTWFwID0gdGhpcy50cmFja2luZ0V2ZW50cztcblxuICBpZiAodHJhY2tpbmdFdmVudHMpIHtcbiAgICB0cmFja2luZ0V2ZW50cyA9IHV0aWxpdGllcy5pc0FycmF5KHRyYWNraW5nRXZlbnRzKSA/IHRyYWNraW5nRXZlbnRzIDogW3RyYWNraW5nRXZlbnRzXTtcbiAgICB0cmFja2luZ0V2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uICh0cmFja2luZ0V2ZW50KSB7XG4gICAgICBpZiAoIWV2ZW50c01hcFt0cmFja2luZ0V2ZW50Lm5hbWVdKSB7XG4gICAgICAgIGV2ZW50c01hcFt0cmFja2luZ0V2ZW50Lm5hbWVdID0gW107XG4gICAgICB9XG4gICAgICBldmVudHNNYXBbdHJhY2tpbmdFdmVudC5uYW1lXS5wdXNoKHRyYWNraW5nRXZlbnQpO1xuICAgIH0pO1xuICB9XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRUaXRsZSA9IGZ1bmN0aW9uICh0aXRsZSkge1xuICBpZiAodXRpbGl0aWVzLmlzTm90RW1wdHlTdHJpbmcodGl0bGUpKSB7XG4gICAgdGhpcy5hZFRpdGxlID0gdGl0bGU7XG4gIH1cbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZER1cmF0aW9uID0gZnVuY3Rpb24gKGR1cmF0aW9uKSB7XG4gIGlmICh1dGlsaXRpZXMuaXNOdW1iZXIoZHVyYXRpb24pKSB7XG4gICAgdGhpcy5kdXJhdGlvbiA9IGR1cmF0aW9uO1xuICB9XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRWaWRlb0NsaWNrcyA9IGZ1bmN0aW9uICh2aWRlb0NsaWNrcykge1xuICBpZiAodmlkZW9DbGlja3MgaW5zdGFuY2VvZiBWaWRlb0NsaWNrcykge1xuICAgIHRoaXMuX2FkZENsaWNrVGhyb3VnaCh2aWRlb0NsaWNrcy5jbGlja1Rocm91Z2gpO1xuICAgIHRoaXMuX2FkZENsaWNrVHJhY2tpbmdzKHZpZGVvQ2xpY2tzLmNsaWNrVHJhY2tpbmdzKTtcbiAgICB0aGlzLl9hZGRDdXN0b21DbGlja3ModmlkZW9DbGlja3MuY3VzdG9tQ2xpY2tzKTtcbiAgfVxufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkTWVkaWFGaWxlcyA9IGZ1bmN0aW9uIChtZWRpYUZpbGVzKSB7XG4gIHV0aWxpdGllcy5pc0FycmF5KG1lZGlhRmlsZXMpICYmIGFwcGVuZFRvQXJyYXkodGhpcy5tZWRpYUZpbGVzLCBtZWRpYUZpbGVzKTtcbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZFNraXBvZmZzZXQgPSBmdW5jdGlvbiAob2Zmc2V0KSB7XG4gIGlmIChvZmZzZXQpIHtcbiAgICB0aGlzLnNraXBvZmZzZXQgPSBvZmZzZXQ7XG4gIH1cbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZEFkUGFyYW1ldGVycyA9IGZ1bmN0aW9uIChhZFBhcmFtZXRlcnMpIHtcbiAgaWYgKGFkUGFyYW1ldGVycykge1xuICAgIHRoaXMuYWRQYXJhbWV0ZXJzID0gYWRQYXJhbWV0ZXJzO1xuICB9XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRMaW5lYXIgPSBmdW5jdGlvbiAobGluZWFyKSB7XG4gIGlmIChsaW5lYXIgaW5zdGFuY2VvZiBMaW5lYXIpIHtcbiAgICB0aGlzLl9hZGREdXJhdGlvbihsaW5lYXIuZHVyYXRpb24pO1xuICAgIHRoaXMuX2FkZFRyYWNraW5nRXZlbnRzKGxpbmVhci50cmFja2luZ0V2ZW50cyk7XG4gICAgdGhpcy5fYWRkVmlkZW9DbGlja3MobGluZWFyLnZpZGVvQ2xpY2tzKTtcbiAgICB0aGlzLl9hZGRNZWRpYUZpbGVzKGxpbmVhci5tZWRpYUZpbGVzKTtcbiAgICB0aGlzLl9hZGRTa2lwb2Zmc2V0KGxpbmVhci5za2lwb2Zmc2V0KTtcbiAgICB0aGlzLl9hZGRBZFBhcmFtZXRlcnMobGluZWFyLmFkUGFyYW1ldGVycyk7XG4gICAgdGhpcy5fbGluZWFyQWRkZWQgPSB0cnVlO1xuICB9XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRJbkxpbmUgPSBmdW5jdGlvbiAoaW5MaW5lKSB7XG4gIHZhciB0aGF0ID0gdGhpcztcblxuICBpZiAoaW5MaW5lIGluc3RhbmNlb2YgSW5MaW5lKSB7XG4gICAgdGhpcy5fYWRkVGl0bGUoaW5MaW5lLmFkVGl0bGUpO1xuICAgIHRoaXMuX2FkZEVycm9yVHJhY2tVcmwoaW5MaW5lLmVycm9yKTtcbiAgICB0aGlzLl9hZGRJbXByZXNzaW9ucyhpbkxpbmUuaW1wcmVzc2lvbnMpO1xuXG4gICAgaW5MaW5lLmNyZWF0aXZlcy5mb3JFYWNoKGZ1bmN0aW9uIChjcmVhdGl2ZSkge1xuICAgICAgaWYgKGNyZWF0aXZlLmxpbmVhcikge1xuICAgICAgICB0aGF0Ll9hZGRMaW5lYXIoY3JlYXRpdmUubGluZWFyKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkV3JhcHBlciA9IGZ1bmN0aW9uICh3cmFwcGVyKSB7XG4gIHZhciB0aGF0ID0gdGhpcztcblxuICBpZiAod3JhcHBlciBpbnN0YW5jZW9mIFdyYXBwZXIpIHtcbiAgICB0aGlzLl9hZGRFcnJvclRyYWNrVXJsKHdyYXBwZXIuZXJyb3IpO1xuICAgIHRoaXMuX2FkZEltcHJlc3Npb25zKHdyYXBwZXIuaW1wcmVzc2lvbnMpO1xuXG4gICAgd3JhcHBlci5jcmVhdGl2ZXMuZm9yRWFjaChmdW5jdGlvbiAoY3JlYXRpdmUpIHtcbiAgICAgIHZhciBsaW5lYXIgPSBjcmVhdGl2ZS5saW5lYXI7XG4gICAgICBpZiAobGluZWFyKSB7XG4gICAgICAgIHRoYXQuX2FkZFZpZGVvQ2xpY2tzKGxpbmVhci52aWRlb0NsaWNrcyk7XG4gICAgICAgIHRoYXQuY2xpY2tUaHJvdWdoID0gdW5kZWZpbmVkOy8vV2UgZW5zdXJlIHRoYXQgbm8gY2xpY2tUaHJvdWdoIGhhcyBiZWVuIGFkZGVkXG4gICAgICAgIHRoYXQuX2FkZFRyYWNraW5nRXZlbnRzKGxpbmVhci50cmFja2luZ0V2ZW50cyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuaGFzTGluZWFyID0gZnVuY3Rpb24oKXtcbiAgcmV0dXJuIHRoaXMuX2xpbmVhckFkZGVkO1xufTtcblxuZnVuY3Rpb24gYXBwZW5kVG9BcnJheShhcnJheSwgaXRlbXMpIHtcbiAgaXRlbXMuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xuICAgIGFycmF5LnB1c2goaXRlbSk7XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFZBU1RSZXNwb25zZTtcblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVkFTVEVycm9yID0gcmVxdWlyZSgnLi9WQVNURXJyb3InKTtcbnZhciBWQVNUUmVzcG9uc2UgPSByZXF1aXJlKCcuL1ZBU1RSZXNwb25zZScpO1xudmFyIHZhc3RVdGlsID0gcmVxdWlyZSgnLi92YXN0VXRpbCcpO1xudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxuZnVuY3Rpb24gVkFTVFRyYWNrZXIoYXNzZXRVUkksIHZhc3RSZXNwb25zZSkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVkFTVFRyYWNrZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBWQVNUVHJhY2tlcihhc3NldFVSSSwgdmFzdFJlc3BvbnNlKTtcbiAgfVxuXG4gIHRoaXMuc2FuaXR5Q2hlY2soYXNzZXRVUkksIHZhc3RSZXNwb25zZSk7XG4gIHRoaXMuaW5pdGlhbGl6ZShhc3NldFVSSSwgdmFzdFJlc3BvbnNlKTtcblxufVxuXG5WQVNUVHJhY2tlci5wcm90b3R5cGUuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKGFzc2V0VVJJLCB2YXN0UmVzcG9uc2UpIHtcbiAgdGhpcy5yZXNwb25zZSA9IHZhc3RSZXNwb25zZTtcbiAgdGhpcy5hc3NldFVSSSA9IGFzc2V0VVJJO1xuICB0aGlzLnByb2dyZXNzID0gMDtcbiAgdGhpcy5xdWFydGlsZXMgPSB7XG4gICAgZmlyc3RRdWFydGlsZToge3RyYWNrZWQ6IGZhbHNlLCB0aW1lOiBNYXRoLnJvdW5kKDI1ICogdmFzdFJlc3BvbnNlLmR1cmF0aW9uKSAvIDEwMH0sXG4gICAgbWlkcG9pbnQ6IHt0cmFja2VkOiBmYWxzZSwgdGltZTogTWF0aC5yb3VuZCg1MCAqIHZhc3RSZXNwb25zZS5kdXJhdGlvbikgLyAxMDB9LFxuICAgIHRoaXJkUXVhcnRpbGU6IHt0cmFja2VkOiBmYWxzZSwgdGltZTogTWF0aC5yb3VuZCg3NSAqIHZhc3RSZXNwb25zZS5kdXJhdGlvbikgLyAxMDB9XG4gIH07XG59O1xuXG5WQVNUVHJhY2tlci5wcm90b3R5cGUuc2FuaXR5Q2hlY2sgPSBmdW5jdGlvbihhc3NldFVSSSwgdmFzdFJlc3BvbnNlKSB7XG4gIGlmICghdXRpbGl0aWVzLmlzU3RyaW5nKGFzc2V0VVJJKSB8fCB1dGlsaXRpZXMuaXNFbXB0eVN0cmluZyhhc3NldFVSSSkpIHtcbiAgICB0aHJvdyBuZXcgVkFTVEVycm9yKCdvbiBWQVNUVHJhY2tlciBjb25zdHJ1Y3RvciwgbWlzc2luZyByZXF1aXJlZCB0aGUgVVJJIG9mIHRoZSBhZCBhc3NldCBiZWluZyBwbGF5ZWQnKTtcbiAgfVxuXG4gIGlmICghKHZhc3RSZXNwb25zZSBpbnN0YW5jZW9mIFZBU1RSZXNwb25zZSkpIHtcbiAgICB0aHJvdyBuZXcgVkFTVEVycm9yKCdvbiBWQVNUVHJhY2tlciBjb25zdHJ1Y3RvciwgbWlzc2luZyByZXF1aXJlZCBWQVNUIHJlc3BvbnNlJyk7XG4gIH1cbn07XG5cblZBU1RUcmFja2VyLnByb3RvdHlwZS50cmFja1VSTHMgPSBmdW5jdGlvbiB0cmFja1VSTHModXJscywgdmFyaWFibGVzKSB7XG4gIGlmICh1dGlsaXRpZXMuaXNBcnJheSh1cmxzKSAmJiB1cmxzLmxlbmd0aCA+IDApIHtcbiAgICB2YXJpYWJsZXMgPSB1dGlsaXRpZXMuZXh0ZW5kKHtcbiAgICAgIEFTU0VUVVJJOiB0aGlzLmFzc2V0VVJJLFxuICAgICAgQ09OVEVOVFBMQVlIRUFEOiB2YXN0VXRpbC5mb3JtYXRQcm9ncmVzcyh0aGlzLnByb2dyZXNzKVxuICAgIH0sIHZhcmlhYmxlcyB8fCB7fSk7XG5cbiAgICB2YXN0VXRpbC50cmFjayh1cmxzLCB2YXJpYWJsZXMpO1xuICB9XG59O1xuXG5WQVNUVHJhY2tlci5wcm90b3R5cGUudHJhY2tFdmVudCA9IGZ1bmN0aW9uIHRyYWNrRXZlbnQoZXZlbnROYW1lLCB0cmFja09uY2UpIHtcbiAgdGhpcy50cmFja1VSTHMoZ2V0RXZlbnRVcmlzKHRoaXMucmVzcG9uc2UudHJhY2tpbmdFdmVudHNbZXZlbnROYW1lXSkpO1xuICBpZiAodHJhY2tPbmNlKSB7XG4gICAgdGhpcy5yZXNwb25zZS50cmFja2luZ0V2ZW50c1tldmVudE5hbWVdID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbiAqKiovXG4gIGZ1bmN0aW9uIGdldEV2ZW50VXJpcyh0cmFja2luZ0V2ZW50cykge1xuICAgIHZhciB1cmlzO1xuXG4gICAgaWYgKHRyYWNraW5nRXZlbnRzKSB7XG4gICAgICB1cmlzID0gW107XG4gICAgICB0cmFja2luZ0V2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICB1cmlzLnB1c2goZXZlbnQudXJpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdXJpcztcbiAgfVxufTtcblxuVkFTVFRyYWNrZXIucHJvdG90eXBlLnRyYWNrUHJvZ3Jlc3MgPSBmdW5jdGlvbiB0cmFja1Byb2dyZXNzKG5ld1Byb2dyZXNzSW5Ncykge1xuICB2YXIgdGhhdCA9IHRoaXM7XG4gIHZhciBldmVudHMgPSBbXTtcbiAgdmFyIE9OQ0UgPSB0cnVlO1xuICB2YXIgQUxXQVlTID0gZmFsc2U7XG4gIHZhciB0cmFja2luZ0V2ZW50cyA9IHRoaXMucmVzcG9uc2UudHJhY2tpbmdFdmVudHM7XG5cbiAgaWYgKHV0aWxpdGllcy5pc051bWJlcihuZXdQcm9ncmVzc0luTXMpKSB7XG4gICAgYWRkVHJhY2tFdmVudCgnc3RhcnQnLCBPTkNFLCBuZXdQcm9ncmVzc0luTXMgPiAwKTtcbiAgICBhZGRUcmFja0V2ZW50KCdyZXdpbmQnLCBBTFdBWVMsIGhhc1Jld291bmQodGhpcy5wcm9ncmVzcywgbmV3UHJvZ3Jlc3NJbk1zKSk7XG4gICAgYWRkUXVhcnRpbGVFdmVudHMobmV3UHJvZ3Jlc3NJbk1zKTtcbiAgICB0cmFja1Byb2dyZXNzRXZlbnRzKG5ld1Byb2dyZXNzSW5Ncyk7XG4gICAgdHJhY2tFdmVudHMoKTtcbiAgICB0aGlzLnByb2dyZXNzID0gbmV3UHJvZ3Jlc3NJbk1zO1xuICB9XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbiAqKiovXG4gIGZ1bmN0aW9uIGhhc1Jld291bmQoY3VycmVudFByb2dyZXNzLCBuZXdQcm9ncmVzcykge1xuICAgIHZhciBSRVdJTkRfVEhSRVNIT0xEID0gMzAwMDsgLy9JT1MgdmlkZW8gY2xvY2sgaXMgdmVyeSB1bnJlbGlhYmxlIGFuZCB3ZSBuZWVkIGEgMyBzZWNvbmRzIHRocmVzaG9sZCB0byBlbnN1cmUgdGhhdCB0aGVyZSB3YXMgYSByZXdpbmQgYW4gdGhhdCBpdCB3YXMgb24gcHVycG9zZS5cbiAgICByZXR1cm4gY3VycmVudFByb2dyZXNzID4gbmV3UHJvZ3Jlc3NJbk1zICYmIE1hdGguYWJzKG5ld1Byb2dyZXNzIC0gY3VycmVudFByb2dyZXNzKSA+IFJFV0lORF9USFJFU0hPTEQ7XG4gIH1cblxuICBmdW5jdGlvbiBhZGRUcmFja0V2ZW50KGV2ZW50TmFtZSwgdHJhY2tPbmNlLCBjYW5CZUFkZGVkKSB7XG4gICAgaWYgKHRyYWNraW5nRXZlbnRzW2V2ZW50TmFtZV0gJiYgY2FuQmVBZGRlZCkge1xuICAgICAgZXZlbnRzLnB1c2goe1xuICAgICAgICBuYW1lOiBldmVudE5hbWUsXG4gICAgICAgIHRyYWNrT25jZTogISF0cmFja09uY2VcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZFF1YXJ0aWxlRXZlbnRzKHByb2dyZXNzKSB7XG4gICAgdmFyIHF1YXJ0aWxlcyA9IHRoYXQucXVhcnRpbGVzO1xuICAgIHZhciBmaXJzdFF1YXJ0aWxlID0gdGhhdC5xdWFydGlsZXMuZmlyc3RRdWFydGlsZTtcbiAgICB2YXIgbWlkcG9pbnQgPSB0aGF0LnF1YXJ0aWxlcy5taWRwb2ludDtcbiAgICB2YXIgdGhpcmRRdWFydGlsZSA9IHRoYXQucXVhcnRpbGVzLnRoaXJkUXVhcnRpbGU7XG5cbiAgICBpZiAoIWZpcnN0UXVhcnRpbGUudHJhY2tlZCkge1xuICAgICAgdHJhY2tRdWFydGlsZSgnZmlyc3RRdWFydGlsZScsIHByb2dyZXNzKTtcbiAgICB9IGVsc2UgaWYgKCFtaWRwb2ludC50cmFja2VkKSB7XG4gICAgICB0cmFja1F1YXJ0aWxlKCdtaWRwb2ludCcsIHByb2dyZXNzKTtcbiAgICB9IGVsc2UgaWYgKCF0aGlyZFF1YXJ0aWxlLnRyYWNrZWQpe1xuICAgICAgdHJhY2tRdWFydGlsZSgndGhpcmRRdWFydGlsZScsIHByb2dyZXNzKTtcbiAgICB9XG5cbiAgICAvKioqIExvY2FsIGZ1bmN0aW9uICoqKi9cbiAgICBmdW5jdGlvbiB0cmFja1F1YXJ0aWxlKHF1YXJ0aWxlTmFtZSwgcHJvZ3Jlc3Mpe1xuICAgICAgdmFyIHF1YXJ0aWxlID0gcXVhcnRpbGVzW3F1YXJ0aWxlTmFtZV07XG4gICAgICBpZihjYW5CZVRyYWNrZWQocXVhcnRpbGUsIHByb2dyZXNzKSl7XG4gICAgICAgIHF1YXJ0aWxlLnRyYWNrZWQgPSB0cnVlO1xuICAgICAgICBhZGRUcmFja0V2ZW50KHF1YXJ0aWxlTmFtZSwgT05DRSwgdHJ1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gY2FuQmVUcmFja2VkKHF1YXJ0aWxlLCBwcm9ncmVzcykge1xuICAgIHZhciBxdWFydGlsZVRpbWUgPSBxdWFydGlsZS50aW1lO1xuICAgIC8vV2Ugb25seSBmaXJlIHRoZSBxdWFydGlsZSBldmVudCBpZiB0aGUgcHJvZ3Jlc3MgaXMgYmlnZ2VyIHRoYW4gdGhlIHF1YXJ0aWxlIHRpbWUgYnkgNSBzZWNvbmRzIGF0IG1vc3QuXG4gICAgcmV0dXJuIHByb2dyZXNzID49IHF1YXJ0aWxlVGltZSAmJiBwcm9ncmVzcyA8PSAocXVhcnRpbGVUaW1lICsgNTAwMCk7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFja1Byb2dyZXNzRXZlbnRzKHByb2dyZXNzKSB7XG4gICAgaWYgKCF1dGlsaXRpZXMuaXNBcnJheSh0cmFja2luZ0V2ZW50cy5wcm9ncmVzcykpIHtcbiAgICAgIHJldHVybjsgLy9Ob3RoaW5nIHRvIHRyYWNrXG4gICAgfVxuXG4gICAgdmFyIHBlbmRpbmdQcm9ncmVzc0V2dHMgPSBbXTtcblxuICAgIHRyYWNraW5nRXZlbnRzLnByb2dyZXNzLmZvckVhY2goZnVuY3Rpb24gKGV2dCkge1xuICAgICAgaWYgKGV2dC5vZmZzZXQgPD0gcHJvZ3Jlc3MpIHtcbiAgICAgICAgdGhhdC50cmFja1VSTHMoW2V2dC51cmldKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBlbmRpbmdQcm9ncmVzc0V2dHMucHVzaChldnQpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRyYWNraW5nRXZlbnRzLnByb2dyZXNzID0gcGVuZGluZ1Byb2dyZXNzRXZ0cztcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYWNrRXZlbnRzKCkge1xuICAgIGV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgdGhhdC50cmFja0V2ZW50KGV2ZW50Lm5hbWUsIGV2ZW50LnRyYWNrT25jZSk7XG4gICAgfSk7XG4gIH1cbn07XG5cbltcbiAgJ3Jld2luZCcsXG4gICdmdWxsc2NyZWVuJyxcbiAgJ2V4aXRGdWxsc2NyZWVuJyxcbiAgJ3BhdXNlJyxcbiAgJ3Jlc3VtZScsXG4gICdtdXRlJyxcbiAgJ3VubXV0ZScsXG4gICdhY2NlcHRJbnZpdGF0aW9uJyxcbiAgJ2FjY2VwdEludml0YXRpb25MaW5lYXInLFxuICAnY29sbGFwc2UnLFxuICAnZXhwYW5kJ1xuXS5mb3JFYWNoKGZ1bmN0aW9uIChldmVudE5hbWUpIHtcbiAgICBWQVNUVHJhY2tlci5wcm90b3R5cGVbJ3RyYWNrJyArIHV0aWxpdGllcy5jYXBpdGFsaXplKGV2ZW50TmFtZSldID0gZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy50cmFja0V2ZW50KGV2ZW50TmFtZSk7XG4gICAgfTtcbiAgfSk7XG5cbltcbiAgJ3N0YXJ0JyxcbiAgJ3NraXAnLFxuICAnY2xvc2UnLFxuICAnY2xvc2VMaW5lYXInXG5dLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xuICAgIFZBU1RUcmFja2VyLnByb3RvdHlwZVsndHJhY2snICsgdXRpbGl0aWVzLmNhcGl0YWxpemUoZXZlbnROYW1lKV0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLnRyYWNrRXZlbnQoZXZlbnROYW1lLCB0cnVlKTtcbiAgICB9O1xuICB9KTtcblxuW1xuICAnZmlyc3RRdWFydGlsZScsXG4gICdtaWRwb2ludCcsXG4gICd0aGlyZFF1YXJ0aWxlJ1xuXS5mb3JFYWNoKGZ1bmN0aW9uIChxdWFydGlsZSkge1xuICAgIFZBU1RUcmFja2VyLnByb3RvdHlwZVsndHJhY2snICsgdXRpbGl0aWVzLmNhcGl0YWxpemUocXVhcnRpbGUpXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMucXVhcnRpbGVzW3F1YXJ0aWxlXS50cmFja2VkID0gdHJ1ZTtcbiAgICAgIHRoaXMudHJhY2tFdmVudChxdWFydGlsZSwgdHJ1ZSk7XG4gICAgfTtcbiAgfSk7XG5cblZBU1RUcmFja2VyLnByb3RvdHlwZS50cmFja0NvbXBsZXRlID0gZnVuY3Rpb24gKCkge1xuICBpZih0aGlzLnF1YXJ0aWxlcy50aGlyZFF1YXJ0aWxlLnRyYWNrZWQpe1xuICAgIHRoaXMudHJhY2tFdmVudCgnY29tcGxldGUnLCB0cnVlKTtcbiAgfVxufTtcblxuVkFTVFRyYWNrZXIucHJvdG90eXBlLnRyYWNrRXJyb3JXaXRoQ29kZSA9IGZ1bmN0aW9uIHRyYWNrRXJyb3JXaXRoQ29kZShlcnJvcmNvZGUpIHtcbiAgaWYgKHV0aWxpdGllcy5pc051bWJlcihlcnJvcmNvZGUpKSB7XG4gICAgdGhpcy50cmFja1VSTHModGhpcy5yZXNwb25zZS5lcnJvclVSTE1hY3Jvcywge0VSUk9SQ09ERTogZXJyb3Jjb2RlfSk7XG4gIH1cbn07XG5cblZBU1RUcmFja2VyLnByb3RvdHlwZS50cmFja0ltcHJlc3Npb25zID0gZnVuY3Rpb24gdHJhY2tJbXByZXNzaW9ucygpIHtcbiAgdGhpcy50cmFja1VSTHModGhpcy5yZXNwb25zZS5pbXByZXNzaW9ucyk7XG59O1xuXG5WQVNUVHJhY2tlci5wcm90b3R5cGUudHJhY2tDcmVhdGl2ZVZpZXcgPSBmdW5jdGlvbiB0cmFja0NyZWF0aXZlVmlldygpIHtcbiAgdGhpcy50cmFja0V2ZW50KCdjcmVhdGl2ZVZpZXcnKTtcbn07XG5cblZBU1RUcmFja2VyLnByb3RvdHlwZS50cmFja0NsaWNrID0gZnVuY3Rpb24gdHJhY2tDbGljaygpIHtcbiAgdGhpcy50cmFja1VSTHModGhpcy5yZXNwb25zZS5jbGlja1RyYWNraW5ncyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZBU1RUcmFja2VyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucycpO1xudmFyIHhtbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3htbCcpO1xuXG5mdW5jdGlvbiBWaWRlb0NsaWNrcyh2aWRlb0NsaWNrSlRyZWUpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFZpZGVvQ2xpY2tzKSkge1xuICAgIHJldHVybiBuZXcgVmlkZW9DbGlja3ModmlkZW9DbGlja0pUcmVlKTtcbiAgfVxuXG4gIHRoaXMuY2xpY2tUaHJvdWdoID0geG1sLmtleVZhbHVlKHZpZGVvQ2xpY2tKVHJlZS5jbGlja1Rocm91Z2gpO1xuICB0aGlzLmNsaWNrVHJhY2tpbmdzID0gcGFyc2VDbGlja1RyYWNraW5ncyh2aWRlb0NsaWNrSlRyZWUuY2xpY2tUcmFja2luZyk7XG4gIHRoaXMuY3VzdG9tQ2xpY2tzID0gcGFyc2VDbGlja1RyYWNraW5ncyh2aWRlb0NsaWNrSlRyZWUuY3VzdG9tQ2xpY2spO1xuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gcGFyc2VDbGlja1RyYWNraW5ncyh0cmFja2luZ0RhdGEpIHtcbiAgICB2YXIgY2xpY2tUcmFja2luZ3MgPSBbXTtcbiAgICBpZiAodHJhY2tpbmdEYXRhKSB7XG4gICAgICB0cmFja2luZ0RhdGEgPSB1dGlsaXRpZXMuaXNBcnJheSh0cmFja2luZ0RhdGEpID8gdHJhY2tpbmdEYXRhIDogW3RyYWNraW5nRGF0YV07XG4gICAgICB0cmFja2luZ0RhdGEuZm9yRWFjaChmdW5jdGlvbiAoY2xpY2tUcmFja2luZ0RhdGEpIHtcbiAgICAgICAgY2xpY2tUcmFja2luZ3MucHVzaCh4bWwua2V5VmFsdWUoY2xpY2tUcmFja2luZ0RhdGEpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gY2xpY2tUcmFja2luZ3M7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBWaWRlb0NsaWNrczsiLCIndXNlIHN0cmljdCc7XG5cbnZhciB2YXN0VXRpbCA9IHJlcXVpcmUoJy4vdmFzdFV0aWwnKTtcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcbnZhciB4bWwgPSByZXF1aXJlKCcuLi8uLi91dGlscy94bWwnKTtcblxuZnVuY3Rpb24gV3JhcHBlcih3cmFwcGVySlRyZWUpIHtcbiAgaWYoISh0aGlzIGluc3RhbmNlb2YgV3JhcHBlcikpIHtcbiAgICByZXR1cm4gbmV3IFdyYXBwZXIod3JhcHBlckpUcmVlKTtcbiAgfVxuXG4gIC8vUmVxdWlyZWQgZWxlbWVudHNcbiAgdGhpcy5hZFN5c3RlbSA9IHhtbC5rZXlWYWx1ZSh3cmFwcGVySlRyZWUuYWRTeXN0ZW0pO1xuICB0aGlzLmltcHJlc3Npb25zID0gdmFzdFV0aWwucGFyc2VJbXByZXNzaW9ucyh3cmFwcGVySlRyZWUuaW1wcmVzc2lvbik7XG4gIHRoaXMuVkFTVEFkVGFnVVJJID0geG1sLmtleVZhbHVlKHdyYXBwZXJKVHJlZS52QVNUQWRUYWdVUkkpO1xuXG4gIC8vT3B0aW9uYWwgZWxlbWVudHNcbiAgdGhpcy5jcmVhdGl2ZXMgPSB2YXN0VXRpbC5wYXJzZUNyZWF0aXZlcyh3cmFwcGVySlRyZWUuY3JlYXRpdmVzKTtcbiAgdGhpcy5lcnJvciA9IHhtbC5rZXlWYWx1ZSh3cmFwcGVySlRyZWUuZXJyb3IpO1xuICB0aGlzLmV4dGVuc2lvbnMgPSB3cmFwcGVySlRyZWUuZXh0ZW5zaW9ucztcblxuICAvL09wdGlvbmFsIGF0dHJzXG4gIHRoaXMuZm9sbG93QWRkaXRpb25hbFdyYXBwZXJzID0gdXRpbGl0aWVzLmlzRGVmaW5lZCh4bWwuYXR0cih3cmFwcGVySlRyZWUsICdmb2xsb3dBZGRpdGlvbmFsV3JhcHBlcnMnKSk/IHhtbC5hdHRyKHdyYXBwZXJKVHJlZSwgJ2ZvbGxvd0FkZGl0aW9uYWxXcmFwcGVycycpOiB0cnVlO1xuICB0aGlzLmFsbG93TXVsdGlwbGVBZHMgPSB4bWwuYXR0cih3cmFwcGVySlRyZWUsICdhbGxvd011bHRpcGxlQWRzJyk7XG4gIHRoaXMuZmFsbGJhY2tPbk5vQWQgPSB4bWwuYXR0cih3cmFwcGVySlRyZWUsICdmYWxsYmFja09uTm9BZCcpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFdyYXBwZXI7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucycpO1xuXG52YXIgZHVyYXRpb25SZWdleCA9IC8oXFxkXFxkKTooXFxkXFxkKTooXFxkXFxkKShcXC4oXFxkXFxkXFxkKSk/LztcblxudmFyIHBhcnNlcnMgPSB7XG5cbiAgZHVyYXRpb246IGZ1bmN0aW9uIHBhcnNlRHVyYXRpb24oZHVyYXRpb25TdHIpIHtcblxuICAgIHZhciBtYXRjaCwgZHVyYXRpb25Jbk1zO1xuXG4gICAgaWYgKHV0aWxpdGllcy5pc1N0cmluZyhkdXJhdGlvblN0cikpIHtcbiAgICAgIG1hdGNoID0gZHVyYXRpb25TdHIubWF0Y2goZHVyYXRpb25SZWdleCk7XG4gICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgZHVyYXRpb25Jbk1zID0gcGFyc2VIb3Vyc1RvTXMobWF0Y2hbMV0pICsgcGFyc2VNaW5Ub01zKG1hdGNoWzJdKSArIHBhcnNlU2VjVG9NcyhtYXRjaFszXSkgKyBwYXJzZUludChtYXRjaFs1XSB8fCAwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gaXNOYU4oZHVyYXRpb25Jbk1zKSA/IG51bGwgOiBkdXJhdGlvbkluTXM7XG5cbiAgICAvKioqIGxvY2FsIGZ1bmN0aW9ucyAqKiovXG4gICAgZnVuY3Rpb24gcGFyc2VIb3Vyc1RvTXMoaG91clN0cikge1xuICAgICAgcmV0dXJuIHBhcnNlSW50KGhvdXJTdHIsIDEwKSAqIDYwICogNjAgKiAxMDAwO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlTWluVG9NcyhtaW5TdHIpIHtcbiAgICAgIHJldHVybiBwYXJzZUludChtaW5TdHIsIDEwKSAqIDYwICogMTAwMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZVNlY1RvTXMoc2VjU3RyKSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQoc2VjU3RyLCAxMCkgKiAxMDAwO1xuICAgIH1cbiAgfSxcblxuICBvZmZzZXQ6IGZ1bmN0aW9uIHBhcnNlT2Zmc2V0KG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICBpZihpc1BlcmNlbnRhZ2Uob2Zmc2V0KSl7XG4gICAgICByZXR1cm4gY2FsY3VsYXRlUGVyY2VudGFnZShvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIHBhcnNlcnMuZHVyYXRpb24ob2Zmc2V0KTtcblxuICAgIC8qKiogTG9jYWwgZnVuY3Rpb24gKioqL1xuICAgIGZ1bmN0aW9uIGlzUGVyY2VudGFnZShvZmZzZXQpIHtcbiAgICAgIHZhciBwZXJjZW50YWdlUmVnZXggPSAvXlxcZCsoXFwuXFxkKyk/JSQvZztcbiAgICAgIHJldHVybiBwZXJjZW50YWdlUmVnZXgudGVzdChvZmZzZXQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNhbGN1bGF0ZVBlcmNlbnRhZ2UocGVyY2VudFN0ciwgZHVyYXRpb24pIHtcbiAgICAgIGlmKGR1cmF0aW9uKSB7XG4gICAgICAgIHJldHVybiBjYWxjUGVyY2VudChkdXJhdGlvbiwgcGFyc2VGbG9hdChwZXJjZW50U3RyLnJlcGxhY2UoJyUnLCAnJykpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNhbGNQZXJjZW50KHF1YW50aXR5LCBwZXJjZW50KXtcbiAgICAgIHJldHVybiBxdWFudGl0eSAqIHBlcmNlbnQgLyAxMDA7XG4gICAgfVxuICB9XG5cbn07XG5cblxubW9kdWxlLmV4cG9ydHMgPSBwYXJzZXJzOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIENyZWF0aXZlID0gcmVxdWlyZSgnLi9DcmVhdGl2ZScpO1xudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxudmFyIHZhc3RVdGlsID0ge1xuXG4gIHRyYWNrOiBmdW5jdGlvbiB0cmFjayhVUkxNYWNyb3MsIHZhcmlhYmxlcykge1xuICAgIHZhciBzb3VyY2VzID0gdmFzdFV0aWwucGFyc2VVUkxNYWNyb3MoVVJMTWFjcm9zLCB2YXJpYWJsZXMpO1xuICAgIHZhciB0cmFja0ltZ3MgPSBbXTtcbiAgICBzb3VyY2VzLmZvckVhY2goZnVuY3Rpb24gKHNyYykge1xuICAgICAgdmFyIGltZyA9IG5ldyBJbWFnZSgpO1xuICAgICAgaW1nLnNyYyA9IHNyYztcbiAgICAgIHRyYWNrSW1ncy5wdXNoKGltZyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRyYWNrSW1ncztcbiAgfSxcblxuICBwYXJzZVVSTE1hY3JvczogZnVuY3Rpb24gcGFyc2VNYWNyb3MoVVJMTWFjcm9zLCB2YXJpYWJsZXMpIHtcbiAgICB2YXIgcGFyc2VkVVJMcyA9IFtdO1xuXG4gICAgdmFyaWFibGVzID0gdmFyaWFibGVzIHx8IHt9O1xuXG4gICAgaWYgKCEodmFyaWFibGVzW1wiQ0FDSEVCVVNUSU5HXCJdKSkge1xuICAgICAgdmFyaWFibGVzW1wiQ0FDSEVCVVNUSU5HXCJdID0gTWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpICogMS4wZSsxMCk7XG4gICAgfVxuXG4gICAgVVJMTWFjcm9zLmZvckVhY2goZnVuY3Rpb24gKFVSTE1hY3JvKSB7XG4gICAgICBwYXJzZWRVUkxzLnB1c2godmFzdFV0aWwuX3BhcnNlVVJMTWFjcm8oVVJMTWFjcm8sIHZhcmlhYmxlcykpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHBhcnNlZFVSTHM7XG4gIH0sXG5cbiAgcGFyc2VVUkxNYWNybzogZnVuY3Rpb24gcGFyc2VNYWNybyhVUkxNYWNybywgdmFyaWFibGVzKSB7XG4gICAgdmFyaWFibGVzID0gdmFyaWFibGVzIHx8IHt9O1xuXG4gICAgaWYgKCEodmFyaWFibGVzW1wiQ0FDSEVCVVNUSU5HXCJdKSkge1xuICAgICAgdmFyaWFibGVzW1wiQ0FDSEVCVVNUSU5HXCJdID0gTWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpICogMS4wZSsxMCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhc3RVdGlsLl9wYXJzZVVSTE1hY3JvKFVSTE1hY3JvLCB2YXJpYWJsZXMpO1xuICB9LFxuXG4gIF9wYXJzZVVSTE1hY3JvOiBmdW5jdGlvbiBwYXJzZU1hY3JvKFVSTE1hY3JvLCB2YXJpYWJsZXMpIHtcbiAgICB2YXJpYWJsZXMgPSB2YXJpYWJsZXMgfHwge307XG5cbiAgICB1dGlsaXRpZXMuZm9yRWFjaCh2YXJpYWJsZXMsIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICBVUkxNYWNybyA9IFVSTE1hY3JvLnJlcGxhY2UobmV3IFJlZ0V4cChcIlxcXFxbXCIgKyBrZXkgKyBcIlxcXFxcXF1cIiwgJ2dtJyksIHZhbHVlKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBVUkxNYWNybztcbiAgfSxcblxuICBwYXJzZUR1cmF0aW9uOiBmdW5jdGlvbiBwYXJzZUR1cmF0aW9uKGR1cmF0aW9uU3RyKSB7XG4gICAgdmFyIGR1cmF0aW9uUmVnZXggPSAvKFxcZFxcZCk6KFxcZFxcZCk6KFxcZFxcZCkoXFwuKFxcZFxcZFxcZCkpPy87XG4gICAgdmFyIG1hdGNoLCBkdXJhdGlvbkluTXM7XG5cbiAgICBpZiAodXRpbGl0aWVzLmlzU3RyaW5nKGR1cmF0aW9uU3RyKSkge1xuICAgICAgbWF0Y2ggPSBkdXJhdGlvblN0ci5tYXRjaChkdXJhdGlvblJlZ2V4KTtcbiAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICBkdXJhdGlvbkluTXMgPSBwYXJzZUhvdXJzVG9NcyhtYXRjaFsxXSkgKyBwYXJzZU1pblRvTXMobWF0Y2hbMl0pICsgcGFyc2VTZWNUb01zKG1hdGNoWzNdKSArIHBhcnNlSW50KG1hdGNoWzVdIHx8IDApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBpc05hTihkdXJhdGlvbkluTXMpID8gbnVsbCA6IGR1cmF0aW9uSW5NcztcblxuICAgIC8qKiogbG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgICBmdW5jdGlvbiBwYXJzZUhvdXJzVG9Ncyhob3VyU3RyKSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQoaG91clN0ciwgMTApICogNjAgKiA2MCAqIDEwMDA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VNaW5Ub01zKG1pblN0cikge1xuICAgICAgcmV0dXJuIHBhcnNlSW50KG1pblN0ciwgMTApICogNjAgKiAxMDAwO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlU2VjVG9NcyhzZWNTdHIpIHtcbiAgICAgIHJldHVybiBwYXJzZUludChzZWNTdHIsIDEwKSAqIDEwMDA7XG4gICAgfVxuICB9LFxuXG4gIHBhcnNlSW1wcmVzc2lvbnM6IGZ1bmN0aW9uIHBhcnNlSW1wcmVzc2lvbnMoaW1wcmVzc2lvbnMpIHtcbiAgICBpZiAoaW1wcmVzc2lvbnMpIHtcbiAgICAgIGltcHJlc3Npb25zID0gdXRpbGl0aWVzLmlzQXJyYXkoaW1wcmVzc2lvbnMpID8gaW1wcmVzc2lvbnMgOiBbaW1wcmVzc2lvbnNdO1xuICAgICAgcmV0dXJuIHV0aWxpdGllcy50cmFuc2Zvcm1BcnJheShpbXByZXNzaW9ucywgZnVuY3Rpb24gKGltcHJlc3Npb24pIHtcbiAgICAgICAgaWYgKHV0aWxpdGllcy5pc05vdEVtcHR5U3RyaW5nKGltcHJlc3Npb24ua2V5VmFsdWUpKSB7XG4gICAgICAgICAgcmV0dXJuIGltcHJlc3Npb24ua2V5VmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gW107XG4gIH0sXG5cbiAgcGFyc2VDcmVhdGl2ZXM6IGZ1bmN0aW9uIHBhcnNlQ3JlYXRpdmVzKGNyZWF0aXZlc0pUcmVlKSB7XG4gICAgdmFyIGNyZWF0aXZlcyA9IFtdO1xuICAgIHZhciBjcmVhdGl2ZXNEYXRhO1xuICAgIGlmICh1dGlsaXRpZXMuaXNEZWZpbmVkKGNyZWF0aXZlc0pUcmVlKSAmJiB1dGlsaXRpZXMuaXNEZWZpbmVkKGNyZWF0aXZlc0pUcmVlLmNyZWF0aXZlKSkge1xuICAgICAgY3JlYXRpdmVzRGF0YSA9IHV0aWxpdGllcy5pc0FycmF5KGNyZWF0aXZlc0pUcmVlLmNyZWF0aXZlKSA/IGNyZWF0aXZlc0pUcmVlLmNyZWF0aXZlIDogW2NyZWF0aXZlc0pUcmVlLmNyZWF0aXZlXTtcbiAgICAgIGNyZWF0aXZlc0RhdGEuZm9yRWFjaChmdW5jdGlvbiAoY3JlYXRpdmUpIHtcbiAgICAgICAgY3JlYXRpdmVzLnB1c2gobmV3IENyZWF0aXZlKGNyZWF0aXZlKSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGNyZWF0aXZlcztcbiAgfSxcblxuICAvL1dlIGFzc3VtZSB0aGF0IHRoZSBwcm9ncmVzcyBpcyBnb2luZyB0byBhcnJpdmUgaW4gbWlsbGlzZWNvbmRzXG4gIGZvcm1hdFByb2dyZXNzOiBmdW5jdGlvbiBmb3JtYXRQcm9ncmVzcyhwcm9ncmVzcykge1xuICAgIHZhciBob3VycywgbWludXRlcywgc2Vjb25kcywgbWlsbGlzZWNvbmRzO1xuICAgIGhvdXJzID0gcHJvZ3Jlc3MgLyAoNjAgKiA2MCAqIDEwMDApO1xuICAgIGhvdXJzID0gTWF0aC5mbG9vcihob3Vycyk7XG4gICAgbWludXRlcyA9IChwcm9ncmVzcyAvICg2MCAqIDEwMDApKSAlIDYwO1xuICAgIG1pbnV0ZXMgPSBNYXRoLmZsb29yKG1pbnV0ZXMpO1xuICAgIHNlY29uZHMgPSAocHJvZ3Jlc3MgLyAxMDAwKSAlIDYwO1xuICAgIHNlY29uZHMgPSBNYXRoLmZsb29yKHNlY29uZHMpO1xuICAgIG1pbGxpc2Vjb25kcyA9IHByb2dyZXNzICUgMTAwMDtcbiAgICByZXR1cm4gdXRpbGl0aWVzLnRvRml4ZWREaWdpdHMoaG91cnMsIDIpICsgJzonICsgdXRpbGl0aWVzLnRvRml4ZWREaWdpdHMobWludXRlcywgMikgKyAnOicgKyB1dGlsaXRpZXMudG9GaXhlZERpZ2l0cyhzZWNvbmRzLCAyKSArICcuJyArIHV0aWxpdGllcy50b0ZpeGVkRGlnaXRzKG1pbGxpc2Vjb25kcywgMyk7XG4gIH0sXG5cbiAgcGFyc2VPZmZzZXQ6ICAgZnVuY3Rpb24gcGFyc2VPZmZzZXQob2Zmc2V0LCBkdXJhdGlvbikge1xuICAgIGlmKGlzUGVyY2VudGFnZShvZmZzZXQpKXtcbiAgICAgIHJldHVybiBjYWxjdWxhdGVQZXJjZW50YWdlKG9mZnNldCwgZHVyYXRpb24pO1xuICAgIH1cbiAgICByZXR1cm4gdmFzdFV0aWwucGFyc2VEdXJhdGlvbihvZmZzZXQpO1xuXG4gICAgLyoqKiBMb2NhbCBmdW5jdGlvbiAqKiovXG4gICAgZnVuY3Rpb24gaXNQZXJjZW50YWdlKG9mZnNldCkge1xuICAgICAgdmFyIHBlcmNlbnRhZ2VSZWdleCA9IC9eXFxkKyhcXC5cXGQrKT8lJC9nO1xuICAgICAgcmV0dXJuIHBlcmNlbnRhZ2VSZWdleC50ZXN0KG9mZnNldCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FsY3VsYXRlUGVyY2VudGFnZShwZXJjZW50U3RyLCBkdXJhdGlvbikge1xuICAgICAgaWYoZHVyYXRpb24pIHtcbiAgICAgICAgcmV0dXJuIGNhbGNQZXJjZW50KGR1cmF0aW9uLCBwYXJzZUZsb2F0KHBlcmNlbnRTdHIucmVwbGFjZSgnJScsICcnKSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FsY1BlcmNlbnQocXVhbnRpdHksIHBlcmNlbnQpe1xuICAgICAgcmV0dXJuIHF1YW50aXR5ICogcGVyY2VudCAvIDEwMDtcbiAgICB9XG4gIH0sXG5cbiAgaXNWUEFJRDogZnVuY3Rpb24gaXNWUEFJRE1lZGlhRmlsZShtZWRpYUZpbGUpIHtcbiAgICByZXR1cm4gISFtZWRpYUZpbGUgJiYgbWVkaWFGaWxlLmFwaUZyYW1ld29yayA9PT0gJ1ZQQUlEJztcbiAgfVxufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IHZhc3RVdGlsOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIFZBU1RFcnJvciA9IHJlcXVpcmUoJy4uL3Zhc3QvVkFTVEVycm9yJyk7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbmZ1bmN0aW9uIFZQQUlEQWRVbml0V3JhcHBlcih2cGFpZEFkVW5pdCwgb3B0cykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVlBBSURBZFVuaXRXcmFwcGVyKSkge1xuICAgIHJldHVybiBuZXcgVlBBSURBZFVuaXRXcmFwcGVyKHZwYWlkQWRVbml0LCBvcHRzKTtcbiAgfVxuICBzYW5pdHlDaGVjayh2cGFpZEFkVW5pdCwgb3B0cyk7XG5cbiAgdGhpcy5vcHRpb25zID0gdXRpbGl0aWVzLmV4dGVuZCh7fSwgb3B0cyk7XG5cbiAgdGhpcy5fYWRVbml0ID0gdnBhaWRBZFVuaXQ7XG5cbiAgLyoqKiBMb2NhbCBGdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBzYW5pdHlDaGVjayhhZFVuaXQsIG9wdHMpIHtcbiAgICBpZiAoIWFkVW5pdCB8fCAhVlBBSURBZFVuaXRXcmFwcGVyLmNoZWNrVlBBSURJbnRlcmZhY2UoYWRVbml0KSkge1xuICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcignb24gVlBBSURBZFVuaXRXcmFwcGVyLCB0aGUgcGFzc2VkIFZQQUlEIGFkVW5pdCBkb2VzIG5vdCBmdWxseSBpbXBsZW1lbnQgdGhlIFZQQUlEIGludGVyZmFjZScpO1xuICAgIH1cblxuICAgIGlmICghdXRpbGl0aWVzLmlzT2JqZWN0KG9wdHMpKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFwib24gVlBBSURBZFVuaXRXcmFwcGVyLCBleHBlY3RlZCBvcHRpb25zIGhhc2ggIGJ1dCBnb3QgJ1wiICsgb3B0cyArIFwiJ1wiKTtcbiAgICB9XG5cbiAgICBpZiAoIShcInJlc3BvbnNlVGltZW91dFwiIGluIG9wdHMpIHx8ICF1dGlsaXRpZXMuaXNOdW1iZXIob3B0cy5yZXNwb25zZVRpbWVvdXQpICl7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFwib24gVlBBSURBZFVuaXRXcmFwcGVyLCBleHBlY3RlZCByZXNwb25zZVRpbWVvdXQgaW4gb3B0aW9uc1wiKTtcbiAgICB9XG4gIH1cbn1cblxuVlBBSURBZFVuaXRXcmFwcGVyLmNoZWNrVlBBSURJbnRlcmZhY2UgPSBmdW5jdGlvbiBjaGVja1ZQQUlESW50ZXJmYWNlKFZQQUlEQWRVbml0KSB7XG4gIC8vTk9URTogc2tpcEFkIGlzIG5vdCBwYXJ0IG9mIHRoZSBtZXRob2QgbGlzdCBiZWNhdXNlIGl0IG9ubHkgYXBwZWFycyBpbiBWUEFJRCAyLjAgYW5kIHdlIHN1cHBvcnQgVlBBSUQgMS4wXG4gIHZhciBWUEFJREludGVyZmFjZU1ldGhvZHMgPSBbXG4gICAgJ2hhbmRzaGFrZVZlcnNpb24nLCAnaW5pdEFkJywgJ3N0YXJ0QWQnLCAnc3RvcEFkJywgJ3Jlc2l6ZUFkJywgJ3BhdXNlQWQnLCAnZXhwYW5kQWQnLCAnY29sbGFwc2VBZCdcbiAgXTtcblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gVlBBSURJbnRlcmZhY2VNZXRob2RzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgaWYgKCFWUEFJREFkVW5pdCB8fCAhdXRpbGl0aWVzLmlzRnVuY3Rpb24oVlBBSURBZFVuaXRbVlBBSURJbnRlcmZhY2VNZXRob2RzW2ldXSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuXG4gIHJldHVybiBjYW5TdWJzY3JpYmVUb0V2ZW50cyhWUEFJREFkVW5pdCkgJiYgY2FuVW5zdWJzY3JpYmVGcm9tRXZlbnRzKFZQQUlEQWRVbml0KTtcblxuICAvKioqIExvY2FsIEZ1bmN0aW9ucyAqKiovXG5cbiAgZnVuY3Rpb24gY2FuU3Vic2NyaWJlVG9FdmVudHMoYWRVbml0KSB7XG4gICAgcmV0dXJuIHV0aWxpdGllcy5pc0Z1bmN0aW9uKGFkVW5pdC5zdWJzY3JpYmUpIHx8IHV0aWxpdGllcy5pc0Z1bmN0aW9uKGFkVW5pdC5hZGRFdmVudExpc3RlbmVyKSB8fCB1dGlsaXRpZXMuaXNGdW5jdGlvbihhZFVuaXQub24pO1xuICB9XG5cbiAgZnVuY3Rpb24gY2FuVW5zdWJzY3JpYmVGcm9tRXZlbnRzKGFkVW5pdCkge1xuICAgIHJldHVybiB1dGlsaXRpZXMuaXNGdW5jdGlvbihhZFVuaXQudW5zdWJzY3JpYmUpIHx8IHV0aWxpdGllcy5pc0Z1bmN0aW9uKGFkVW5pdC5yZW1vdmVFdmVudExpc3RlbmVyKSB8fCB1dGlsaXRpZXMuaXNGdW5jdGlvbihhZFVuaXQub2ZmKTtcblxuICB9XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLmFkVW5pdEFzeW5jQ2FsbCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGFyZ3MgPSB1dGlsaXRpZXMuYXJyYXlMaWtlT2JqVG9BcnJheShhcmd1bWVudHMpO1xuICB2YXIgbWV0aG9kID0gYXJncy5zaGlmdCgpO1xuICB2YXIgY2IgPSBhcmdzLnBvcCgpO1xuICB2YXIgdGltZW91dElkO1xuXG4gIHNhbml0eUNoZWNrKG1ldGhvZCwgY2IsIHRoaXMuX2FkVW5pdCk7XG4gIGFyZ3MucHVzaCh3cmFwQ2FsbGJhY2soKSk7XG5cbiAgdGhpcy5fYWRVbml0W21ldGhvZF0uYXBwbHkodGhpcy5fYWRVbml0LCBhcmdzKTtcbiAgdGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgdGltZW91dElkID0gbnVsbDtcbiAgICBjYihuZXcgVkFTVEVycm9yKFwib24gVlBBSURBZFVuaXRXcmFwcGVyLCB0aW1lb3V0IHdoaWxlIHdhaXRpbmcgZm9yIGEgcmVzcG9uc2Ugb24gY2FsbCAnXCIgKyBtZXRob2QgKyBcIidcIikpO1xuICAgIGNiID0gdXRpbGl0aWVzLm5vb3A7XG4gIH0sIHRoaXMub3B0aW9ucy5yZXNwb25zZVRpbWVvdXQpO1xuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gc2FuaXR5Q2hlY2sobWV0aG9kLCBjYiwgYWRVbml0KSB7XG4gICAgaWYgKCF1dGlsaXRpZXMuaXNTdHJpbmcobWV0aG9kKSB8fCAhdXRpbGl0aWVzLmlzRnVuY3Rpb24oYWRVbml0W21ldGhvZF0pKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFwib24gVlBBSURBZFVuaXRXcmFwcGVyLmFkVW5pdEFzeW5jQ2FsbCwgaW52YWxpZCBtZXRob2QgbmFtZVwiKTtcbiAgICB9XG5cbiAgICBpZiAoIXV0aWxpdGllcy5pc0Z1bmN0aW9uKGNiKSkge1xuICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcihcIm9uIFZQQUlEQWRVbml0V3JhcHBlci5hZFVuaXRBc3luY0NhbGwsIG1pc3NpbmcgY2FsbGJhY2tcIik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gd3JhcENhbGxiYWNrKCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAodGltZW91dElkKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgfVxuICAgICAgY2IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuICB9XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLm9uID0gZnVuY3Rpb24gKGV2dE5hbWUsIGhhbmRsZXIpIHtcbiAgdmFyIGFkZEV2ZW50TGlzdGVuZXIgPSB0aGlzLl9hZFVuaXQuYWRkRXZlbnRMaXN0ZW5lciB8fCB0aGlzLl9hZFVuaXQuc3Vic2NyaWJlIHx8IHRoaXMuX2FkVW5pdC5vbjtcbiAgYWRkRXZlbnRMaXN0ZW5lci5jYWxsKHRoaXMuX2FkVW5pdCwgZXZ0TmFtZSwgaGFuZGxlcik7XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIChldnROYW1lLCBoYW5kbGVyKSB7XG4gIHZhciByZW1vdmVFdmVudExpc3RlbmVyID0gdGhpcy5fYWRVbml0LnJlbW92ZUV2ZW50TGlzdGVuZXIgfHwgdGhpcy5fYWRVbml0LnVuc3Vic2NyaWJlIHx8IHRoaXMuX2FkVW5pdC5vZmY7XG4gIHJlbW92ZUV2ZW50TGlzdGVuZXIuY2FsbCh0aGlzLl9hZFVuaXQsIGV2dE5hbWUsIGhhbmRsZXIpO1xufTtcblxuVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZS53YWl0Rm9yRXZlbnQgPSBmdW5jdGlvbiAoZXZ0TmFtZSwgY2IsIGNvbnRleHQpIHtcbiAgdmFyIHRpbWVvdXRJZDtcbiAgc2FuaXR5Q2hlY2soZXZ0TmFtZSwgY2IpO1xuICBjb250ZXh0ID0gY29udGV4dCB8fCBudWxsO1xuXG4gIHRoaXMub24oZXZ0TmFtZSwgcmVzcG9uc2VMaXN0ZW5lcik7XG5cbiAgdGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgY2IobmV3IFZBU1RFcnJvcihcIm9uIFZQQUlEQWRVbml0V3JhcHBlci53YWl0Rm9yRXZlbnQsIHRpbWVvdXQgd2hpbGUgd2FpdGluZyBmb3IgZXZlbnQgJ1wiICsgZXZ0TmFtZSArIFwiJ1wiKSk7XG4gICAgdGltZW91dElkID0gbnVsbDtcbiAgICBjYiA9IHV0aWxpdGllcy5ub29wO1xuICB9LCB0aGlzLm9wdGlvbnMucmVzcG9uc2VUaW1lb3V0KTtcblxuICAvKioqIExvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIHNhbml0eUNoZWNrKGV2dE5hbWUsIGNiKSB7XG4gICAgaWYgKCF1dGlsaXRpZXMuaXNTdHJpbmcoZXZ0TmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoXCJvbiBWUEFJREFkVW5pdFdyYXBwZXIud2FpdEZvckV2ZW50LCBtaXNzaW5nIGV2dCBuYW1lXCIpO1xuICAgIH1cblxuICAgIGlmICghdXRpbGl0aWVzLmlzRnVuY3Rpb24oY2IpKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFwib24gVlBBSURBZFVuaXRXcmFwcGVyLndhaXRGb3JFdmVudCwgbWlzc2luZyBjYWxsYmFja1wiKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZXNwb25zZUxpc3RlbmVyKCkge1xuICAgIHZhciBhcmdzID0gdXRpbGl0aWVzLmFycmF5TGlrZU9ialRvQXJyYXkoYXJndW1lbnRzKTtcblxuICAgIGlmICh0aW1lb3V0SWQpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgdGltZW91dElkID0gbnVsbDtcbiAgICB9XG5cbiAgICBhcmdzLnVuc2hpZnQobnVsbCk7XG4gICAgY2IuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gIH1cbn07XG5cbi8vIFZQQUlEIE1FVEhPRFNcblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUuaGFuZHNoYWtlVmVyc2lvbiA9IGZ1bmN0aW9uICh2ZXJzaW9uLCBjYikge1xuICB0aGlzLmFkVW5pdEFzeW5jQ2FsbCgnaGFuZHNoYWtlVmVyc2lvbicsIHZlcnNpb24sIGNiKTtcbn07XG5cbi8qIGpzaGludCBtYXhwYXJhbXM6NiAqL1xuVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZS5pbml0QWQgPSBmdW5jdGlvbiAod2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGRlc2lyZWRCaXRyYXRlLCBhZFVuaXREYXRhLCBjYikge1xuICB0aGlzLndhaXRGb3JFdmVudCgnQWRMb2FkZWQnLCBjYik7XG4gIHRoaXMuX2FkVW5pdC5pbml0QWQod2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGRlc2lyZWRCaXRyYXRlLCBhZFVuaXREYXRhKTtcbn07XG5cblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUucmVzaXplQWQgPSBmdW5jdGlvbiAod2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGNiKSB7XG4gIC8vIE5PVEU6IEFkU2l6ZUNoYW5nZSBldmVudCBpcyBvbmx5IHN1cHBvcnRlZCBvbiBWUEFJRCAyLjAgc28gZm9yIHRoZSBtb21lbnQgd2UgYXJlIG5vdCBnb2luZyB0byB1c2UgaXRcbiAgLy8gYW5kIHdpbGwgYXNzdW1lIHRoYXQgZXZlcnl0aGluZyBpcyBmaW5lIGFmdGVyIHRoZSBhc3luYyBjYWxsXG4gIHRoaXMuYWRVbml0QXN5bmNDYWxsKCdyZXNpemVBZCcsIHdpZHRoLCBoZWlnaHQsIHZpZXdNb2RlLCBjYik7XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLnN0YXJ0QWQgPSBmdW5jdGlvbiAoY2IpIHtcbiAgdGhpcy53YWl0Rm9yRXZlbnQoJ0FkU3RhcnRlZCcsIGNiKTtcbiAgdGhpcy5fYWRVbml0LnN0YXJ0QWQoKTtcbn07XG5cblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUuc3RvcEFkID0gZnVuY3Rpb24gKGNiKSB7XG4gIHRoaXMud2FpdEZvckV2ZW50KCdBZFN0b3BwZWQnLCBjYik7XG4gIHRoaXMuX2FkVW5pdC5zdG9wQWQoKTtcbn07XG5cblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUucGF1c2VBZCA9IGZ1bmN0aW9uIChjYikge1xuICB0aGlzLndhaXRGb3JFdmVudCgnQWRQYXVzZWQnLCBjYik7XG4gIHRoaXMuX2FkVW5pdC5wYXVzZUFkKCk7XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLnJlc3VtZUFkID0gZnVuY3Rpb24gKGNiKSB7XG4gIHRoaXMud2FpdEZvckV2ZW50KCdBZFBsYXlpbmcnLCBjYik7XG4gIHRoaXMuX2FkVW5pdC5yZXN1bWVBZCgpO1xufTtcblxuVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZS5leHBhbmRBZCA9IGZ1bmN0aW9uIChjYikge1xuICB0aGlzLndhaXRGb3JFdmVudCgnQWRFeHBhbmRlZENoYW5nZScsIGNiKTtcbiAgdGhpcy5fYWRVbml0LmV4cGFuZEFkKCk7XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLmNvbGxhcHNlQWQgPSBmdW5jdGlvbiAoY2IpIHtcbiAgdGhpcy53YWl0Rm9yRXZlbnQoJ0FkRXhwYW5kZWRDaGFuZ2UnLCBjYik7XG4gIHRoaXMuX2FkVW5pdC5jb2xsYXBzZUFkKCk7XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLnNraXBBZCA9IGZ1bmN0aW9uIChjYikge1xuICB0aGlzLndhaXRGb3JFdmVudCgnQWRTa2lwcGVkJywgY2IpO1xuICB0aGlzLl9hZFVuaXQuc2tpcEFkKCk7XG59O1xuXG4vL1ZQQUlEIHByb3BlcnR5IGdldHRlcnNcbltcbiAgJ2FkTGluZWFyJyxcbiAgJ2FkV2lkdGgnLFxuICAnYWRIZWlnaHQnLFxuICAnYWRFeHBhbmRlZCcsXG4gICdhZFNraXBwYWJsZVN0YXRlJyxcbiAgJ2FkUmVtYWluaW5nVGltZScsXG4gICdhZER1cmF0aW9uJyxcbiAgJ2FkVm9sdW1lJyxcbiAgJ2FkQ29tcGFuaW9ucycsXG4gICdhZEljb25zJ1xuXS5mb3JFYWNoKGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuICB2YXIgZ2V0dGVyTmFtZSA9ICdnZXQnICsgdXRpbGl0aWVzLmNhcGl0YWxpemUocHJvcGVydHkpO1xuXG4gIFZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGVbZ2V0dGVyTmFtZV0gPSBmdW5jdGlvbiAoY2IpIHtcbiAgICB0aGlzLmFkVW5pdEFzeW5jQ2FsbChnZXR0ZXJOYW1lLCBjYik7XG4gIH07XG59KTtcblxuLy9WUEFJRCBwcm9wZXJ0eSBzZXR0ZXJzXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLnNldEFkVm9sdW1lID0gZnVuY3Rpb24odm9sdW1lLCBjYil7XG4gIHRoaXMuYWRVbml0QXN5bmNDYWxsKCdzZXRBZFZvbHVtZScsdm9sdW1lLCBjYik7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZQQUlEQWRVbml0V3JhcHBlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFZBU1RFcnJvciA9IHJlcXVpcmUoJy4uL3Zhc3QvVkFTVEVycm9yJyk7XG5cbnZhciBWUEFJREZMQVNIQ2xpZW50ID0gcmVxdWlyZSgnVlBBSURGTEFTSENsaWVudC9qcy9WUEFJREZMQVNIQ2xpZW50Jyk7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG52YXIgZG9tID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvZG9tJyk7XG5cbmZ1bmN0aW9uIFZQQUlERmxhc2hUZWNoKG1lZGlhRmlsZSwgc2V0dGluZ3MpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFZQQUlERmxhc2hUZWNoKSkge1xuICAgIHJldHVybiBuZXcgVlBBSURGbGFzaFRlY2gobWVkaWFGaWxlKTtcbiAgfVxuICBzYW5pdHlDaGVjayhtZWRpYUZpbGUpO1xuICB0aGlzLm5hbWUgPSAndnBhaWQtZmxhc2gnO1xuICB0aGlzLm1lZGlhRmlsZSA9IG1lZGlhRmlsZTtcbiAgdGhpcy5jb250YWluZXJFbCA9IG51bGw7XG4gIHRoaXMudnBhaWRGbGFzaENsaWVudCA9IG51bGw7XG4gIHRoaXMuc2V0dGluZ3MgPSBzZXR0aW5ncztcblxuICAvKioqIGxvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIHNhbml0eUNoZWNrKG1lZGlhRmlsZSkge1xuICAgIGlmICghbWVkaWFGaWxlIHx8ICF1dGlsaXRpZXMuaXNTdHJpbmcobWVkaWFGaWxlLnNyYykpIHtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoJ29uIFZQQUlERmxhc2hUZWNoLCBpbnZhbGlkIE1lZGlhRmlsZScpO1xuICAgIH1cbiAgfVxufVxuXG5WUEFJREZsYXNoVGVjaC5WUEFJREZMQVNIQ2xpZW50ID0gVlBBSURGTEFTSENsaWVudDtcblxuVlBBSURGbGFzaFRlY2guc3VwcG9ydHMgPSBmdW5jdGlvbiAodHlwZSkge1xuICByZXR1cm4gdHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3gtc2hvY2t3YXZlLWZsYXNoJyAmJiBWUEFJREZsYXNoVGVjaC5WUEFJREZMQVNIQ2xpZW50LmlzU3VwcG9ydGVkKCk7XG59O1xuXG5WUEFJREZsYXNoVGVjaC5wcm90b3R5cGUubG9hZEFkVW5pdCA9IGZ1bmN0aW9uIGxvYWRGbGFzaENyZWF0aXZlKGNvbnRhaW5lckVsLCBvYmplY3RFbCwgY2FsbGJhY2spIHtcbiAgdmFyIHRoYXQgPSB0aGlzO1xuICB2YXIgZmxhc2hDbGllbnRPcHRzID0gdGhpcy5zZXR0aW5ncyAmJiB0aGlzLnNldHRpbmdzLnZwYWlkRmxhc2hMb2FkZXJQYXRoID8ge2RhdGE6IHRoaXMuc2V0dGluZ3MudnBhaWRGbGFzaExvYWRlclBhdGh9IDogdW5kZWZpbmVkO1xuICBzYW5pdHlDaGVjayhjb250YWluZXJFbCwgY2FsbGJhY2spO1xuXG4gIHRoaXMuY29udGFpbmVyRWwgPSBjb250YWluZXJFbDtcbiAgdGhpcy52cGFpZEZsYXNoQ2xpZW50ID0gbmV3IFZQQUlERmxhc2hUZWNoLlZQQUlERkxBU0hDbGllbnQoY29udGFpbmVyRWwsIGZ1bmN0aW9uIChlcnJvcikge1xuICAgIGlmIChlcnJvcikge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycm9yKTtcbiAgICB9XG5cbiAgICB0aGF0LnZwYWlkRmxhc2hDbGllbnQubG9hZEFkVW5pdCh0aGF0Lm1lZGlhRmlsZS5zcmMsIGNhbGxiYWNrKTtcbiAgfSwgZmxhc2hDbGllbnRPcHRzKTtcblxuICAvKioqIExvY2FsIEZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIHNhbml0eUNoZWNrKGNvbnRhaW5lciwgY2IpIHtcblxuICAgIGlmICghZG9tLmlzRG9tRWxlbWVudChjb250YWluZXIpKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKCdvbiBWUEFJREZsYXNoVGVjaC5sb2FkQWRVbml0LCBpbnZhbGlkIGRvbSBjb250YWluZXIgZWxlbWVudCcpO1xuICAgIH1cblxuICAgIGlmICghdXRpbGl0aWVzLmlzRnVuY3Rpb24oY2IpKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKCdvbiBWUEFJREZsYXNoVGVjaC5sb2FkQWRVbml0LCBtaXNzaW5nIHZhbGlkIGNhbGxiYWNrJyk7XG4gICAgfVxuICB9XG59O1xuXG5WUEFJREZsYXNoVGVjaC5wcm90b3R5cGUudW5sb2FkQWRVbml0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy52cGFpZEZsYXNoQ2xpZW50KSB7XG4gICAgdHJ5e1xuICAgICAgdGhpcy52cGFpZEZsYXNoQ2xpZW50LmRlc3Ryb3koKTtcbiAgICB9IGNhdGNoKGUpe1xuICAgICAgaWYoY29uc29sZSAmJiB1dGlsaXRpZXMuaXNGdW5jdGlvbihjb25zb2xlLmxvZykpe1xuICAgICAgICBjb25zb2xlLmxvZygnVkFTVCBFUlJPUjogdHJ5aW5nIHRvIHVubG9hZCB0aGUgVlBBSUQgYWR1bml0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMudnBhaWRGbGFzaENsaWVudCA9IG51bGw7XG4gIH1cblxuICBpZiAodGhpcy5jb250YWluZXJFbCkge1xuICAgIGRvbS5yZW1vdmUodGhpcy5jb250YWluZXJFbCk7XG4gICAgdGhpcy5jb250YWluZXJFbCA9IG51bGw7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gVlBBSURGbGFzaFRlY2g7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVkFTVEVycm9yID0gcmVxdWlyZSgnLi4vdmFzdC9WQVNURXJyb3InKTtcblxudmFyIFZQQUlESFRNTDVDbGllbnQgPSByZXF1aXJlKCdWUEFJREhUTUw1Q2xpZW50L2pzL1ZQQUlESFRNTDVDbGllbnQnKTtcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcbnZhciBkb20gPSByZXF1aXJlKCcuLi8uLi91dGlscy9kb20nKTtcblxuZnVuY3Rpb24gVlBBSURIVE1MNVRlY2gobWVkaWFGaWxlKSB7XG5cbiAgaWYoISh0aGlzIGluc3RhbmNlb2YgVlBBSURIVE1MNVRlY2gpKSB7XG4gICAgcmV0dXJuIG5ldyBWUEFJREhUTUw1VGVjaChtZWRpYUZpbGUpO1xuICB9XG5cbiAgc2FuaXR5Q2hlY2sobWVkaWFGaWxlKTtcblxuICB0aGlzLm5hbWUgPSAndnBhaWQtaHRtbDUnO1xuICB0aGlzLmNvbnRhaW5lckVsID0gbnVsbDtcbiAgdGhpcy52aWRlb0VsID0gbnVsbDtcbiAgdGhpcy52cGFpZEhUTUxDbGllbnQgPSBudWxsO1xuXG4gIHRoaXMubWVkaWFGaWxlID0gbWVkaWFGaWxlO1xuXG4gIGZ1bmN0aW9uIHNhbml0eUNoZWNrKG1lZGlhRmlsZSkge1xuICAgICAgaWYgKCFtZWRpYUZpbGUgfHwgIXV0aWxpdGllcy5pc1N0cmluZyhtZWRpYUZpbGUuc3JjKSkge1xuICAgICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFZQQUlESFRNTDVUZWNoLklOVkFMSURfTUVESUFfRklMRSk7XG4gICAgICB9XG4gIH1cbn1cblxuVlBBSURIVE1MNVRlY2guVlBBSURIVE1MNUNsaWVudCA9IFZQQUlESFRNTDVDbGllbnQ7XG5cblZQQUlESFRNTDVUZWNoLnN1cHBvcnRzID0gZnVuY3Rpb24gKHR5cGUpIHtcbiAgcmV0dXJuICF1dGlsaXRpZXMuaXNPbGRJRSgpICYmIHR5cGUgPT09ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0Jztcbn07XG5cblZQQUlESFRNTDVUZWNoLnByb3RvdHlwZS5sb2FkQWRVbml0ID0gZnVuY3Rpb24gbG9hZEFkVW5pdChjb250YWluZXJFbCwgdmlkZW9FbCwgY2FsbGJhY2spIHtcbiAgc2FuaXR5Q2hlY2soY29udGFpbmVyRWwsIHZpZGVvRWwsIGNhbGxiYWNrKTtcblxuICB0aGlzLmNvbnRhaW5lckVsID0gY29udGFpbmVyRWw7XG4gIHRoaXMudmlkZW9FbCA9IHZpZGVvRWw7XG4gIHRoaXMudnBhaWRIVE1MQ2xpZW50ID0gbmV3IFZQQUlESFRNTDVUZWNoLlZQQUlESFRNTDVDbGllbnQoY29udGFpbmVyRWwsIHZpZGVvRWwsIHt9KTtcbiAgdGhpcy52cGFpZEhUTUxDbGllbnQubG9hZEFkVW5pdCh0aGlzLm1lZGlhRmlsZS5zcmMsIGNhbGxiYWNrKTtcblxuICBmdW5jdGlvbiBzYW5pdHlDaGVjayhjb250YWluZXIsIHZpZGVvLCBjYikge1xuICAgIGlmICghZG9tLmlzRG9tRWxlbWVudChjb250YWluZXIpKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFZQQUlESFRNTDVUZWNoLklOVkFMSURfRE9NX0NPTlRBSU5FUl9FTCk7XG4gICAgfVxuXG4gICAgaWYgKCFkb20uaXNEb21FbGVtZW50KHZpZGVvKSB8fCB2aWRlby50YWdOYW1lLnRvTG93ZXJDYXNlKCkgIT09ICd2aWRlbycpIHtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoVlBBSURIVE1MNVRlY2guSU5WQUxJRF9ET01fQ09OVEFJTkVSX0VMKTtcbiAgICB9XG5cbiAgICBpZiAoIXV0aWxpdGllcy5pc0Z1bmN0aW9uKGNiKSkge1xuICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcihWUEFJREhUTUw1VGVjaC5NSVNTSU5HX0NBTExCQUNLKTtcbiAgICB9XG4gIH1cbn07XG5cblZQQUlESFRNTDVUZWNoLnByb3RvdHlwZS51bmxvYWRBZFVuaXQgPSBmdW5jdGlvbiB1bmxvYWRBZFVuaXQoKSB7XG4gIGlmICh0aGlzLnZwYWlkSFRNTENsaWVudCkge1xuICAgIHRyeSB7XG4gICAgICB0aGlzLnZwYWlkSFRNTENsaWVudC5kZXN0cm95KCk7XG4gICAgfSBjYXRjaChlKSB7XG4gICAgICBpZiAoY29uc29sZSAmJiB1dGlsaXRpZXMuaXNGdW5jdGlvbihjb25zb2xlLmxvZykpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1ZBU1QgRVJST1I6IHRyeWluZyB0byB1bmxvYWQgdGhlIFZQQUlEIGFkdW5pdCcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMudnBhaWRIVE1MQ2xpZW50ID0gbnVsbDtcbiAgfVxuXG4gIGlmICh0aGlzLmNvbnRhaW5lckVsKSB7XG4gICAgZG9tLnJlbW92ZSh0aGlzLmNvbnRhaW5lckVsKTtcbiAgICB0aGlzLmNvbnRhaW5lckVsID0gbnVsbDtcbiAgfVxufTtcblxudmFyIFBSRUZJWCA9ICdvbiBWUEFJREhUTUw1VGVjaCc7XG5WUEFJREhUTUw1VGVjaC5JTlZBTElEX01FRElBX0ZJTEUgPSBQUkVGSVggKyAnLCBpbnZhbGlkIE1lZGlhRmlsZSc7XG5WUEFJREhUTUw1VGVjaC5JTlZBTElEX0RPTV9DT05UQUlORVJfRUwgPSBQUkVGSVggKyAnLCBpbnZhbGlkIGNvbnRhaW5lciBIdG1sRWxlbWVudCc7XG5WUEFJREhUTUw1VGVjaC5JTlZBTElEX0RPTV9WSURFT19FTCA9IFBSRUZJWCArICcsIGludmFsaWQgSFRNTFZpZGVvRWxlbWVudCc7XG5WUEFJREhUTUw1VGVjaC5NSVNTSU5HX0NBTExCQUNLID0gUFJFRklYICsgJywgbWlzc2luZyB2YWxpZCBjYWxsYmFjayc7XG5cbm1vZHVsZS5leHBvcnRzID0gVlBBSURIVE1MNVRlY2g7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVkFTVEVycm9yID0gcmVxdWlyZSgnLi4vdmFzdC9WQVNURXJyb3InKTtcbnZhciBWQVNUUmVzcG9uc2UgPSByZXF1aXJlKCcuLi92YXN0L1ZBU1RSZXNwb25zZScpO1xudmFyIFZBU1RUcmFja2VyID0gcmVxdWlyZSgnLi4vdmFzdC9WQVNUVHJhY2tlcicpO1xudmFyIHZhc3RVdGlsID0gcmVxdWlyZSgnLi4vdmFzdC92YXN0VXRpbCcpO1xuXG52YXIgVlBBSURBZFVuaXRXcmFwcGVyID0gcmVxdWlyZSgnLi9WUEFJREFkVW5pdFdyYXBwZXInKTtcbnZhciBWUEFJREhUTUw1VGVjaCA9IHJlcXVpcmUoJy4vVlBBSURIVE1MNVRlY2gnKTtcbnZhciBWUEFJREZsYXNoVGVjaCA9IHJlcXVpcmUoJy4vVlBBSURGbGFzaFRlY2gnKTtcblxudmFyIGFzeW5jID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvYXN5bmMnKTtcbnZhciBkb20gPSByZXF1aXJlKCcuLi8uLi91dGlscy9kb20nKTtcbnZhciBwbGF5ZXJVdGlscyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3BsYXllclV0aWxzJyk7XG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucycpO1xuXG5mdW5jdGlvbiBWUEFJREludGVncmF0b3IocGxheWVyLCBzZXR0aW5ncykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVlBBSURJbnRlZ3JhdG9yKSkge1xuICAgIHJldHVybiBuZXcgVlBBSURJbnRlZ3JhdG9yKHBsYXllcik7XG4gIH1cblxuICB0aGlzLlZJRVdfTU9ERSA9IHtcbiAgICBOT1JNQUw6ICdub3JtYWwnLFxuICAgIEZVTExTQ1JFRU46IFwiZnVsbHNjcmVlblwiLFxuICAgIFRIVU1CTkFJTDogXCJ0aHVtYm5haWxcIlxuICB9O1xuICB0aGlzLnBsYXllciA9IHBsYXllcjtcbiAgdGhpcy5jb250YWluZXJFbCA9IGNyZWF0ZVZQQUlEQ29udGFpbmVyRWwocGxheWVyKTtcbiAgdGhpcy5vcHRpb25zID0ge1xuICAgIHJlc3BvbnNlVGltZW91dDogNTAwMCxcbiAgICBWUEFJRF9WRVJTSU9OOiAnMi4wJ1xuICB9O1xuICB0aGlzLnNldHRpbmdzID0gc2V0dGluZ3M7XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqL1xuXG4gIGZ1bmN0aW9uIGNyZWF0ZVZQQUlEQ29udGFpbmVyRWwoKSB7XG4gICAgdmFyIGNvbnRhaW5lckVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZG9tLmFkZENsYXNzKGNvbnRhaW5lckVsLCAnVlBBSUQtY29udGFpbmVyJyk7XG4gICAgcGxheWVyLmVsKCkuaW5zZXJ0QmVmb3JlKGNvbnRhaW5lckVsLCBwbGF5ZXIuY29udHJvbEJhci5lbCgpKTtcbiAgICByZXR1cm4gY29udGFpbmVyRWw7XG5cbiAgfVxufVxuXG4vL0xpc3Qgb2Ygc3VwcG9ydGVkIFZQQUlEIHRlY2hub2xvZ2llc1xuVlBBSURJbnRlZ3JhdG9yLnRlY2hzID0gW1xuICBWUEFJREZsYXNoVGVjaCxcbiAgVlBBSURIVE1MNVRlY2hcbl07XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUucGxheUFkID0gZnVuY3Rpb24gcGxheVZQYWlkQWQodmFzdFJlc3BvbnNlLCBjYWxsYmFjaykge1xuICB2YXIgdGhhdCA9IHRoaXM7XG4gIHZhciB0ZWNoO1xuICB2YXIgcGxheWVyID0gdGhpcy5wbGF5ZXI7XG5cbiAgY2FsbGJhY2sgPSBjYWxsYmFjayB8fCB1dGlsaXRpZXMubm9vcDtcbiAgaWYgKCEodmFzdFJlc3BvbnNlIGluc3RhbmNlb2YgVkFTVFJlc3BvbnNlKSkge1xuICAgIHJldHVybiBjYWxsYmFjayhuZXcgVkFTVEVycm9yKCdvbiBWQVNUSW50ZWdyYXRvci5wbGF5QWQsIG1pc3NpbmcgcmVxdWlyZWQgVkFTVFJlc3BvbnNlJykpO1xuICB9XG5cbiAgdGVjaCA9IHRoaXMuX2ZpbmRTdXBwb3J0ZWRUZWNoKHZhc3RSZXNwb25zZSwgdGhpcy5zZXR0aW5ncyk7XG4gIGRvbS5hZGRDbGFzcyhwbGF5ZXIuZWwoKSwgJ3Zqcy12cGFpZC1hZCcpO1xuXG4gIHBsYXllci5vbigndmFzdC5hZHNDYW5jZWwnLCB0cmlnZ2VyVnBhaWRBZEVuZCk7XG4gIHBsYXllci5vbmUoJ3ZwYWlkLmFkRW5kJywgZnVuY3Rpb24oKXtcbiAgICBwbGF5ZXIub2ZmKCd2YXN0LmFkc0NhbmNlbCcsIHRyaWdnZXJWcGFpZEFkRW5kKTtcbiAgICByZW1vdmVBZFVuaXQoKTtcbiAgfSk7XG5cbiAgaWYgKHRlY2gpIHtcbiAgICBhc3luYy53YXRlcmZhbGwoW1xuICAgICAgZnVuY3Rpb24gKG5leHQpIHtcbiAgICAgICAgbmV4dChudWxsLCB0ZWNoLCB2YXN0UmVzcG9uc2UpO1xuICAgICAgfSxcbiAgICAgIHRoaXMuX2xvYWRBZFVuaXQuYmluZCh0aGlzKSxcbiAgICAgIHRoaXMuX3BsYXlBZFVuaXQuYmluZCh0aGlzKSxcbiAgICAgIHRoaXMuX2ZpbmlzaFBsYXlpbmcuYmluZCh0aGlzKVxuXG4gICAgXSwgZnVuY3Rpb24gKGVycm9yLCBhZFVuaXQsIHZhc3RSZXNwb25zZSkge1xuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIHRoYXQuX3RyYWNrRXJyb3IodmFzdFJlc3BvbnNlKTtcbiAgICAgIH1cbiAgICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5hZEVuZCcpO1xuICAgICAgY2FsbGJhY2soZXJyb3IsIHZhc3RSZXNwb25zZSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLl9hZFVuaXQgPSB7XG4gICAgICBfcGF1c2VkOiB0cnVlLFxuICAgICAgdHlwZTogJ1ZQQUlEJyxcbiAgICAgIHBhdXNlQWQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQucGF1c2VBZCcpO1xuICAgICAgICBwbGF5ZXIucGF1c2UodHJ1ZSk7Ly93ZSBtYWtlIHN1cmUgdGhhdCB0aGUgdmlkZW8gY29udGVudCBnZXRzIHN0b3BwZWQuXG4gICAgICB9LFxuICAgICAgcmVzdW1lQWQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5yZXN1bWVBZCcpO1xuICAgICAgfSxcbiAgICAgIGlzUGF1c2VkOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhdXNlZDtcbiAgICAgIH0sXG4gICAgICBnZXRTcmM6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGVjaC5tZWRpYUZpbGU7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLl9hZFVuaXQ7XG4gIH1cblxuICBjYWxsYmFjayhuZXcgVkFTVEVycm9yKCdvbiBWUEFJREludGVncmF0b3IucGxheUFkLCBjb3VsZCBub3QgZmluZCBhIHN1cHBvcnRlZCBtZWRpYUZpbGUnKSk7XG5cbiAgcmV0dXJuIG51bGw7XG4gIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gdHJpZ2dlclZwYWlkQWRFbmQoKXtcbiAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuYWRFbmQnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbW92ZUFkVW5pdCgpIHtcbiAgICBpZiAodGVjaCkge1xuICAgICAgdGVjaC51bmxvYWRBZFVuaXQoKTtcbiAgICB9XG4gICAgZG9tLnJlbW92ZUNsYXNzKHBsYXllci5lbCgpLCAndmpzLXZwYWlkLWFkJyk7XG4gIH1cbn07XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUuX2ZpbmRTdXBwb3J0ZWRUZWNoID0gZnVuY3Rpb24gKHZhc3RSZXNwb25zZSwgc2V0dGluZ3MpIHtcbiAgaWYgKCEodmFzdFJlc3BvbnNlIGluc3RhbmNlb2YgVkFTVFJlc3BvbnNlKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdmFyIHZwYWlkTWVkaWFGaWxlcyA9IHZhc3RSZXNwb25zZS5tZWRpYUZpbGVzLmZpbHRlcih2YXN0VXRpbC5pc1ZQQUlEKTtcbiAgdmFyIGksIGxlbiwgbWVkaWFGaWxlLCBWUEFJRFRlY2g7XG5cbiAgZm9yIChpID0gMCwgbGVuID0gdnBhaWRNZWRpYUZpbGVzLmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKSB7XG4gICAgbWVkaWFGaWxlID0gdnBhaWRNZWRpYUZpbGVzW2ldO1xuICAgIFZQQUlEVGVjaCA9IGZpbmRTdXBwb3J0ZWRUZWNoKG1lZGlhRmlsZSk7XG4gICAgaWYgKFZQQUlEVGVjaCkge1xuICAgICAgcmV0dXJuIG5ldyBWUEFJRFRlY2gobWVkaWFGaWxlLCBzZXR0aW5ncyk7XG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsO1xuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gZmluZFN1cHBvcnRlZFRlY2gobWVkaWFmaWxlKSB7XG4gICAgdmFyIHR5cGUgPSBtZWRpYWZpbGUudHlwZTtcbiAgICB2YXIgaSwgbGVuLCBWUEFJRFRlY2g7XG4gICAgZm9yIChpID0gMCwgbGVuID0gVlBBSURJbnRlZ3JhdG9yLnRlY2hzLmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKSB7XG4gICAgICBWUEFJRFRlY2ggPSBWUEFJREludGVncmF0b3IudGVjaHNbaV07XG4gICAgICBpZiAoVlBBSURUZWNoLnN1cHBvcnRzKHR5cGUpKSB7XG4gICAgICAgIHJldHVybiBWUEFJRFRlY2g7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG59O1xuXG5WUEFJREludGVncmF0b3IucHJvdG90eXBlLl9jcmVhdGVWUEFJREFkVW5pdFdyYXBwZXIgPSBmdW5jdGlvbihhZFVuaXQsIHNyYywgcmVzcG9uc2VUaW1lb3V0KSB7XG4gIHJldHVybiBuZXcgVlBBSURBZFVuaXRXcmFwcGVyKGFkVW5pdCwge3NyYzogc3JjLCByZXNwb25zZVRpbWVvdXQ6IHJlc3BvbnNlVGltZW91dH0pO1xufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5fbG9hZEFkVW5pdCA9IGZ1bmN0aW9uICh0ZWNoLCB2YXN0UmVzcG9uc2UsIG5leHQpIHtcbiAgdmFyIHRoYXQgPSB0aGlzO1xuICB2YXIgcGxheWVyID0gdGhpcy5wbGF5ZXI7XG4gIHZhciB2anNUZWNoRWwgPSBwbGF5ZXIuZWwoKS5xdWVyeVNlbGVjdG9yKCcudmpzLXRlY2gnKTtcbiAgdmFyIHJlc3BvbnNlVGltZW91dCA9IHRoaXMuc2V0dGluZ3MucmVzcG9uc2VUaW1lb3V0IHx8IHRoaXMub3B0aW9ucy5yZXNwb25zZVRpbWVvdXQ7XG4gIHRlY2gubG9hZEFkVW5pdCh0aGlzLmNvbnRhaW5lckVsLCB2anNUZWNoRWwsIGZ1bmN0aW9uIChlcnJvciwgYWRVbml0KSB7XG4gICAgaWYgKGVycm9yKSB7XG4gICAgICByZXR1cm4gbmV4dChlcnJvciwgYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICB2YXIgV3JhcHBlZEFkVW5pdCA9IHRoYXQuX2NyZWF0ZVZQQUlEQWRVbml0V3JhcHBlcihhZFVuaXQsIHRlY2gubWVkaWFGaWxlLnNyYywgcmVzcG9uc2VUaW1lb3V0KTtcbiAgICAgIHZhciB0ZWNoQ2xhc3MgPSAndmpzLScgKyB0ZWNoLm5hbWUgKyAnLWFkJztcbiAgICAgIGRvbS5hZGRDbGFzcyhwbGF5ZXIuZWwoKSwgdGVjaENsYXNzKTtcbiAgICAgIHBsYXllci5vbmUoJ3ZwYWlkLmFkRW5kJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGRvbS5yZW1vdmVDbGFzcyhwbGF5ZXIuZWwoKSx0ZWNoQ2xhc3MpO1xuICAgICAgfSk7XG4gICAgICBuZXh0KG51bGwsIFdyYXBwZWRBZFVuaXQsIHZhc3RSZXNwb25zZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbmV4dChlLCBhZFVuaXQsIHZhc3RSZXNwb25zZSk7XG4gICAgfVxuICB9KTtcbn07XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUuX3BsYXlBZFVuaXQgPSBmdW5jdGlvbiAoYWRVbml0LCB2YXN0UmVzcG9uc2UsIGNhbGxiYWNrKSB7XG4gIGFzeW5jLndhdGVyZmFsbChbXG4gICAgZnVuY3Rpb24gKG5leHQpIHtcbiAgICAgIG5leHQobnVsbCwgYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuICAgIH0sXG4gICAgdGhpcy5faGFuZHNoYWtlLmJpbmQodGhpcyksXG4gICAgdGhpcy5faW5pdEFkLmJpbmQodGhpcyksXG4gICAgdGhpcy5fc2V0dXBFdmVudHMuYmluZCh0aGlzKSxcbiAgICB0aGlzLl9hZGRTa2lwQnV0dG9uLmJpbmQodGhpcyksXG4gICAgdGhpcy5fbGlua1BsYXllckNvbnRyb2xzLmJpbmQodGhpcyksXG4gICAgdGhpcy5fc3RhcnRBZC5iaW5kKHRoaXMpXG4gIF0sIGNhbGxiYWNrKTtcbn07XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUuX2hhbmRzaGFrZSA9IGZ1bmN0aW9uIGhhbmRzaGFrZShhZFVuaXQsIHZhc3RSZXNwb25zZSwgbmV4dCkge1xuICBhZFVuaXQuaGFuZHNoYWtlVmVyc2lvbih0aGlzLm9wdGlvbnMuVlBBSURfVkVSU0lPTiwgZnVuY3Rpb24gKGVycm9yLCB2ZXJzaW9uKSB7XG4gICAgaWYgKGVycm9yKSB7XG4gICAgICByZXR1cm4gbmV4dChlcnJvciwgYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuICAgIH1cblxuICAgIGlmICh2ZXJzaW9uICYmIGlzU3VwcG9ydGVkVmVyc2lvbih2ZXJzaW9uKSkge1xuICAgICAgcmV0dXJuIG5leHQobnVsbCwgYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXh0KG5ldyBWQVNURXJyb3IoJ29uIFZQQUlESW50ZWdyYXRvci5faGFuZHNoYWtlLCB1bnN1cHBvcnRlZCB2ZXJzaW9uIFwiJyArIHZlcnNpb24gKyAnXCInKSwgYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuICB9KTtcblxuICBmdW5jdGlvbiBpc1N1cHBvcnRlZFZlcnNpb24odmVyc2lvbikge1xuICAgIHZhciBtYWpvck51bSA9IG1ham9yKHZlcnNpb24pO1xuICAgIHJldHVybiBtYWpvck51bSA+PSAxICYmIG1ham9yTnVtIDw9IDI7XG4gIH1cblxuICBmdW5jdGlvbiBtYWpvcih2ZXJzaW9uKSB7XG4gICAgdmFyIHBhcnRzID0gdmVyc2lvbi5zcGxpdCgnLicpO1xuICAgIHJldHVybiBwYXJzZUludChwYXJ0c1swXSwgMTApO1xuICB9XG59O1xuXG5WUEFJREludGVncmF0b3IucHJvdG90eXBlLl9pbml0QWQgPSBmdW5jdGlvbiAoYWRVbml0LCB2YXN0UmVzcG9uc2UsIG5leHQpIHtcbiAgdmFyIHRlY2ggPSB0aGlzLnBsYXllci5lbCgpLnF1ZXJ5U2VsZWN0b3IoJy52anMtdGVjaCcpO1xuICB2YXIgZGltZW5zaW9uID0gZG9tLmdldERpbWVuc2lvbih0ZWNoKTtcbiAgYWRVbml0LmluaXRBZChkaW1lbnNpb24ud2lkdGgsIGRpbWVuc2lvbi5oZWlnaHQsIHRoaXMuVklFV19NT0RFLk5PUk1BTCwgLTEsIHtBZFBhcmFtZXRlcnM6IHZhc3RSZXNwb25zZS5hZFBhcmFtZXRlcnMgfHwgJyd9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICBuZXh0KGVycm9yLCBhZFVuaXQsIHZhc3RSZXNwb25zZSk7XG4gIH0pO1xufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5fY3JlYXRlVkFTVFRyYWNrZXIgPSBmdW5jdGlvbihhZFVuaXRTcmMsIHZhc3RSZXNwb25zZSkge1xuICByZXR1cm4gbmV3IFZBU1RUcmFja2VyKGFkVW5pdFNyYywgdmFzdFJlc3BvbnNlKTtcbn07XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUuX3NldHVwRXZlbnRzID0gZnVuY3Rpb24gKGFkVW5pdCwgdmFzdFJlc3BvbnNlLCBuZXh0KSB7XG4gIHZhciBhZFVuaXRTcmMgPSBhZFVuaXQub3B0aW9ucy5zcmM7XG4gIHZhciB0cmFja2VyID0gdGhpcy5fY3JlYXRlVkFTVFRyYWNrZXIoYWRVbml0U3JjLCB2YXN0UmVzcG9uc2UpO1xuICB2YXIgcGxheWVyID0gdGhpcy5wbGF5ZXI7XG4gIHZhciB0aGF0ID0gdGhpcztcblxuICBhZFVuaXQub24oJ0FkU2tpcHBlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuQWRTa2lwcGVkJyk7XG4gICAgdHJhY2tlci50cmFja1NraXAoKTtcbiAgfSk7XG5cbiAgYWRVbml0Lm9uKCdBZEltcHJlc3Npb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkSW1wcmVzc2lvbicpO1xuICAgIHRyYWNrZXIudHJhY2tJbXByZXNzaW9ucygpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkU3RhcnRlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuQWRTdGFydGVkJyk7XG4gICAgdHJhY2tlci50cmFja0NyZWF0aXZlVmlldygpO1xuICAgIG5vdGlmeVBsYXlUb1BsYXllcigpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkVmlkZW9TdGFydCcsIGZ1bmN0aW9uICgpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuQWRWaWRlb1N0YXJ0Jyk7XG4gICAgdHJhY2tlci50cmFja1N0YXJ0KCk7XG4gICAgbm90aWZ5UGxheVRvUGxheWVyKCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRQbGF5aW5nJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFBsYXlpbmcnKTtcbiAgICB0cmFja2VyLnRyYWNrUmVzdW1lKCk7XG4gICAgbm90aWZ5UGxheVRvUGxheWVyKCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRQYXVzZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkUGF1c2VkJyk7XG4gICAgdHJhY2tlci50cmFja1BhdXNlKCk7XG4gICAgbm90aWZ5UGF1c2VUb1BsYXllcigpO1xuICB9KTtcblxuICBmdW5jdGlvbiBub3RpZnlQbGF5VG9QbGF5ZXIoKXtcbiAgICBpZih0aGF0Ll9hZFVuaXQgJiYgdGhhdC5fYWRVbml0LmlzUGF1c2VkKCkpe1xuICAgICAgdGhhdC5fYWRVbml0Ll9wYXVzZWQgPSBmYWxzZTtcbiAgICB9XG4gICAgcGxheWVyLnRyaWdnZXIoJ3BsYXknKTtcblxuICB9XG5cbiAgZnVuY3Rpb24gbm90aWZ5UGF1c2VUb1BsYXllcigpIHtcbiAgICBpZih0aGF0Ll9hZFVuaXQpe1xuICAgICAgdGhhdC5fYWRVbml0Ll9wYXVzZWQgPSB0cnVlO1xuICAgIH1cbiAgICBwbGF5ZXIudHJpZ2dlcigncGF1c2UnKTtcbiAgfVxuXG4gIGFkVW5pdC5vbignQWRWaWRlb0ZpcnN0UXVhcnRpbGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkVmlkZW9GaXJzdFF1YXJ0aWxlJyk7XG4gICAgdHJhY2tlci50cmFja0ZpcnN0UXVhcnRpbGUoKTtcbiAgfSk7XG5cbiAgYWRVbml0Lm9uKCdBZFZpZGVvTWlkcG9pbnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkVmlkZW9NaWRwb2ludCcpO1xuICAgIHRyYWNrZXIudHJhY2tNaWRwb2ludCgpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkVmlkZW9UaGlyZFF1YXJ0aWxlJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFZpZGVvVGhpcmRRdWFydGlsZScpO1xuICAgIHRyYWNrZXIudHJhY2tUaGlyZFF1YXJ0aWxlKCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRWaWRlb0NvbXBsZXRlJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFZpZGVvQ29tcGxldGUnKTtcbiAgICB0cmFja2VyLnRyYWNrQ29tcGxldGUoKTtcbiAgfSk7XG5cbiAgYWRVbml0Lm9uKCdBZENsaWNrVGhydScsIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkQ2xpY2tUaHJ1Jyk7XG4gICAgdmFyIHVybCA9IGRhdGEudXJsO1xuICAgIHZhciBwbGF5ZXJIYW5kbGVzID0gZGF0YS5wbGF5ZXJIYW5kbGVzO1xuICAgIHZhciBjbGlja1RocnVVcmwgPSB1dGlsaXRpZXMuaXNOb3RFbXB0eVN0cmluZyh1cmwpID8gdXJsIDogZ2VuZXJhdGVDbGlja1Rocm91Z2hVUkwodmFzdFJlc3BvbnNlLmNsaWNrVGhyb3VnaCk7XG5cbiAgICB0cmFja2VyLnRyYWNrQ2xpY2soKTtcbiAgICBpZiAocGxheWVySGFuZGxlcyAmJiBjbGlja1RocnVVcmwpIHtcbiAgICAgIHdpbmRvdy5vcGVuKGNsaWNrVGhydVVybCwgJ19ibGFuaycpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdlbmVyYXRlQ2xpY2tUaHJvdWdoVVJMKGNsaWNrVGhyb3VnaE1hY3JvKSB7XG4gICAgICB2YXIgdmFyaWFibGVzID0ge1xuICAgICAgICBBU1NFVFVSSTogYWRVbml0Lm9wdGlvbnMuc3JjLFxuICAgICAgICBDT05URU5UUExBWUhFQUQ6IDAgLy9JbiBWUEFJRCB0aGVyZSBpcyBubyBtZXRob2QgdG8ga25vdyB0aGUgY3VycmVudCB0aW1lIGZyb20gdGhlIGFkVW5pdFxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIGNsaWNrVGhyb3VnaE1hY3JvID8gdmFzdFV0aWwucGFyc2VVUkxNYWNybyhjbGlja1Rocm91Z2hNYWNybywgdmFyaWFibGVzKSA6IG51bGw7XG4gICAgfVxuICB9KTtcblxuICBhZFVuaXQub24oJ0FkVXNlckFjY2VwdEludml0YXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkVXNlckFjY2VwdEludml0YXRpb24nKTtcbiAgICB0cmFja2VyLnRyYWNrQWNjZXB0SW52aXRhdGlvbigpO1xuICAgIHRyYWNrZXIudHJhY2tBY2NlcHRJbnZpdGF0aW9uTGluZWFyKCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRVc2VyQ2xvc2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkVXNlckNsb3NlJyk7XG4gICAgdHJhY2tlci50cmFja0Nsb3NlKCk7XG4gICAgdHJhY2tlci50cmFja0Nsb3NlTGluZWFyKCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRVc2VyTWluaW1pemUnLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkVXNlck1pbmltaXplJyk7XG4gICAgdHJhY2tlci50cmFja0NvbGxhcHNlKCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRFcnJvcicsIGZ1bmN0aW9uICgpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuQWRFcnJvcicpO1xuICAgIC8vTk9URTogd2UgdHJhY2sgZXJyb3JzIGNvZGUgOTAxLCBhcyBub3RlZCBpbiBWQVNUIDMuMFxuICAgIHRyYWNrZXIudHJhY2tFcnJvcldpdGhDb2RlKDkwMSk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRWb2x1bWVDaGFuZ2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkVm9sdW1lQ2hhbmdlJyk7XG4gICAgdmFyIGxhc3RWb2x1bWUgPSBwbGF5ZXIudm9sdW1lKCk7XG4gICAgYWRVbml0LmdldEFkVm9sdW1lKGZ1bmN0aW9uIChlcnJvciwgY3VycmVudFZvbHVtZSkge1xuICAgICAgaWYgKGN1cnJlbnRWb2x1bWUgPT09IDAgJiYgbGFzdFZvbHVtZSA+IDApIHtcbiAgICAgICAgdHJhY2tlci50cmFja011dGUoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGN1cnJlbnRWb2x1bWUgPiAwICYmIGxhc3RWb2x1bWUgPT09IDApIHtcbiAgICAgICAgdHJhY2tlci50cmFja1VubXV0ZSgpO1xuICAgICAgfVxuXG4gICAgICBwbGF5ZXIudm9sdW1lKGN1cnJlbnRWb2x1bWUpO1xuICAgIH0pO1xuICB9KTtcblxuICB2YXIgdXBkYXRlVmlld1NpemUgPSByZXNpemVBZC5iaW5kKHRoaXMsIHBsYXllciwgYWRVbml0LCB0aGlzLlZJRVdfTU9ERSk7XG4gIHZhciB1cGRhdGVWaWV3U2l6ZVRocm90dGxlZCA9IHV0aWxpdGllcy50aHJvdHRsZSh1cGRhdGVWaWV3U2l6ZSwgMTAwKTtcbiAgdmFyIGF1dG9SZXNpemUgPSB0aGlzLnNldHRpbmdzLmF1dG9SZXNpemU7XG5cbiAgaWYgKGF1dG9SZXNpemUpIHtcbiAgICBkb20uYWRkRXZlbnRMaXN0ZW5lcih3aW5kb3csICdyZXNpemUnLCB1cGRhdGVWaWV3U2l6ZVRocm90dGxlZCk7XG4gICAgZG9tLmFkZEV2ZW50TGlzdGVuZXIod2luZG93LCAnb3JpZW50YXRpb25jaGFuZ2UnLCB1cGRhdGVWaWV3U2l6ZVRocm90dGxlZCk7XG4gIH1cblxuICBwbGF5ZXIub24oJ3Zhc3QucmVzaXplJywgdXBkYXRlVmlld1NpemUpO1xuICBwbGF5ZXIub24oJ3ZwYWlkLnBhdXNlQWQnLCBwYXVzZUFkVW5pdCk7XG4gIHBsYXllci5vbigndnBhaWQucmVzdW1lQWQnLCByZXN1bWVBZFVuaXQpO1xuXG4gIHBsYXllci5vbmUoJ3ZwYWlkLmFkRW5kJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci5vZmYoJ3Zhc3QucmVzaXplJywgdXBkYXRlVmlld1NpemUpO1xuICAgIHBsYXllci5vZmYoJ3ZwYWlkLnBhdXNlQWQnLCBwYXVzZUFkVW5pdCk7XG4gICAgcGxheWVyLm9mZigndnBhaWQucmVzdW1lQWQnLCByZXN1bWVBZFVuaXQpO1xuXG4gICAgaWYgKGF1dG9SZXNpemUpIHtcbiAgICAgIGRvbS5yZW1vdmVFdmVudExpc3RlbmVyKHdpbmRvdywgJ3Jlc2l6ZScsIHVwZGF0ZVZpZXdTaXplVGhyb3R0bGVkKTtcbiAgICAgIGRvbS5yZW1vdmVFdmVudExpc3RlbmVyKHdpbmRvdywgJ29yaWVudGF0aW9uY2hhbmdlJywgdXBkYXRlVmlld1NpemVUaHJvdHRsZWQpO1xuICAgIH1cbiAgfSk7XG5cbiAgbmV4dChudWxsLCBhZFVuaXQsIHZhc3RSZXNwb25zZSk7XG5cbiAgLyoqKiBMb2NhbCBGdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBwYXVzZUFkVW5pdCgpIHtcbiAgICBhZFVuaXQucGF1c2VBZCh1dGlsaXRpZXMubm9vcCk7XG4gIH1cblxuICBmdW5jdGlvbiByZXN1bWVBZFVuaXQoKSB7XG4gICAgYWRVbml0LnJlc3VtZUFkKHV0aWxpdGllcy5ub29wKTtcbiAgfVxufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5fYWRkU2tpcEJ1dHRvbiA9IGZ1bmN0aW9uIChhZFVuaXQsIHZhc3RSZXNwb25zZSwgbmV4dCkge1xuICB2YXIgc2tpcEJ1dHRvbjtcbiAgdmFyIHBsYXllciA9IHRoaXMucGxheWVyO1xuXG4gIGFkVW5pdC5vbignQWRTa2lwcGFibGVTdGF0ZUNoYW5nZScsIHVwZGF0ZVNraXBCdXR0b25TdGF0ZSk7XG5cbiAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsndmFzdC5hZEVuZCcsICd2YXN0LmFkc0NhbmNlbCddLCByZW1vdmVTa2lwQnV0dG9uKTtcblxuICBuZXh0KG51bGwsIGFkVW5pdCwgdmFzdFJlc3BvbnNlKTtcblxuICAvKioqIExvY2FsIGZ1bmN0aW9uICoqKi9cbiAgZnVuY3Rpb24gdXBkYXRlU2tpcEJ1dHRvblN0YXRlKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFNraXBwYWJsZVN0YXRlQ2hhbmdlJyk7XG4gICAgYWRVbml0LmdldEFkU2tpcHBhYmxlU3RhdGUoZnVuY3Rpb24gKGVycm9yLCBpc1NraXBwYWJsZSkge1xuICAgICAgaWYgKGlzU2tpcHBhYmxlKSB7XG4gICAgICAgIGlmICghc2tpcEJ1dHRvbikge1xuICAgICAgICAgIGFkZFNraXBCdXR0b24ocGxheWVyKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVtb3ZlU2tpcEJ1dHRvbihwbGF5ZXIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gYWRkU2tpcEJ1dHRvbihwbGF5ZXIpIHtcbiAgICBza2lwQnV0dG9uID0gY3JlYXRlU2tpcEJ1dHRvbihwbGF5ZXIpO1xuICAgIHBsYXllci5lbCgpLmFwcGVuZENoaWxkKHNraXBCdXR0b24pO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVtb3ZlU2tpcEJ1dHRvbigpIHtcbiAgICBkb20ucmVtb3ZlKHNraXBCdXR0b24pO1xuICAgIHNraXBCdXR0b24gPSBudWxsO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlU2tpcEJ1dHRvbigpIHtcbiAgICB2YXIgc2tpcEJ1dHRvbiA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgIGRvbS5hZGRDbGFzcyhza2lwQnV0dG9uLCBcInZhc3Qtc2tpcC1idXR0b25cIik7XG4gICAgZG9tLmFkZENsYXNzKHNraXBCdXR0b24sIFwiZW5hYmxlZFwiKTtcbiAgICBza2lwQnV0dG9uLmlubmVySFRNTCA9IFwiU2tpcCBhZFwiO1xuXG4gICAgc2tpcEJ1dHRvbi5vbmNsaWNrID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgIGFkVW5pdC5za2lwQWQodXRpbGl0aWVzLm5vb3ApOy8vV2Ugc2tpcCB0aGUgYWRVbml0XG5cbiAgICAgIC8vV2UgcHJldmVudCBldmVudCBwcm9wYWdhdGlvbiB0byBhdm9pZCBwcm9ibGVtcyB3aXRoIHRoZSBjbGlja1Rocm91Z2ggYW5kIHNvIG9uXG4gICAgICBpZiAod2luZG93LkV2ZW50LnByb3RvdHlwZS5zdG9wUHJvcGFnYXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gc2tpcEJ1dHRvbjtcbiAgfVxufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5fbGlua1BsYXllckNvbnRyb2xzID0gZnVuY3Rpb24gKGFkVW5pdCwgdmFzdFJlc3BvbnNlLCBuZXh0KSB7XG4gIHZhciB0aGF0ID0gdGhpcztcbiAgbGlua1ZvbHVtZUNvbnRyb2wodGhpcy5wbGF5ZXIsIGFkVW5pdCk7XG4gIGxpbmtGdWxsU2NyZWVuQ29udHJvbCh0aGlzLnBsYXllciwgYWRVbml0LCB0aGlzLlZJRVdfTU9ERSk7XG5cbiAgbmV4dChudWxsLCBhZFVuaXQsIHZhc3RSZXNwb25zZSk7XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBsaW5rVm9sdW1lQ29udHJvbChwbGF5ZXIsIGFkVW5pdCkge1xuICAgIHBsYXllci5vbigndm9sdW1lY2hhbmdlJywgdXBkYXRlQWRVbml0Vm9sdW1lKTtcbiAgICBhZFVuaXQub24oJ0FkVm9sdW1lQ2hhbmdlJywgdXBkYXRlUGxheWVyVm9sdW1lKTtcblxuICAgIHBsYXllci5vbmUoJ3ZwYWlkLmFkRW5kJywgZnVuY3Rpb24gKCkge1xuICAgICAgcGxheWVyLm9mZigndm9sdW1lY2hhbmdlJywgdXBkYXRlQWRVbml0Vm9sdW1lKTtcbiAgICB9KTtcblxuXG4gICAgLyoqKiBsb2NhbCBmdW5jdGlvbnMgKioqL1xuICAgIGZ1bmN0aW9uIHVwZGF0ZUFkVW5pdFZvbHVtZSgpIHtcbiAgICAgIHZhciB2b2wgPSBwbGF5ZXIubXV0ZWQoKSA/IDAgOiBwbGF5ZXIudm9sdW1lKCk7XG4gICAgICBhZFVuaXQuc2V0QWRWb2x1bWUodm9sLCBsb2dFcnJvcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdXBkYXRlUGxheWVyVm9sdW1lKCkge1xuICAgICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkVm9sdW1lQ2hhbmdlJyk7XG4gICAgICBhZFVuaXQuZ2V0QWRWb2x1bWUoZnVuY3Rpb24gKGVycm9yLCB2b2wpIHtcbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgbG9nRXJyb3IoZXJyb3IpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBsYXllci52b2x1bWUodm9sKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gbGlua0Z1bGxTY3JlZW5Db250cm9sKHBsYXllciwgYWRVbml0LCBWSUVXX01PREUpIHtcbiAgICB2YXIgdXBkYXRlVmlld1NpemUgPSByZXNpemVBZC5iaW5kKHRoYXQsIHBsYXllciwgYWRVbml0LCBWSUVXX01PREUpO1xuXG4gICAgcGxheWVyLm9uKCdmdWxsc2NyZWVuY2hhbmdlJywgdXBkYXRlVmlld1NpemUpO1xuXG4gICAgcGxheWVyLm9uZSgndnBhaWQuYWRFbmQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBwbGF5ZXIub2ZmKCdmdWxsc2NyZWVuY2hhbmdlJywgdXBkYXRlVmlld1NpemUpO1xuICAgIH0pO1xuICB9XG59O1xuXG5WUEFJREludGVncmF0b3IucHJvdG90eXBlLl9zdGFydEFkID0gZnVuY3Rpb24gKGFkVW5pdCwgdmFzdFJlc3BvbnNlLCBuZXh0KSB7XG4gIHZhciBwbGF5ZXIgPSB0aGlzLnBsYXllcjtcblxuICBhZFVuaXQuc3RhcnRBZChmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICBpZiAoIWVycm9yKSB7XG4gICAgICBwbGF5ZXIudHJpZ2dlcigndmFzdC5hZFN0YXJ0Jyk7XG4gICAgfVxuICAgIG5leHQoZXJyb3IsIGFkVW5pdCwgdmFzdFJlc3BvbnNlKTtcbiAgfSk7XG59O1xuXG5WUEFJREludGVncmF0b3IucHJvdG90eXBlLl9maW5pc2hQbGF5aW5nID0gZnVuY3Rpb24gKGFkVW5pdCwgdmFzdFJlc3BvbnNlLCBuZXh0KSB7XG4gIHZhciBwbGF5ZXIgPSB0aGlzLnBsYXllcjtcbiAgYWRVbml0Lm9uKCdBZFN0b3BwZWQnLCBmdW5jdGlvbiAoKSB7XG4gICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuQWRTdG9wcGVkJyk7XG4gICBmaW5pc2hQbGF5aW5nQWQobnVsbCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRFcnJvcicsIGZ1bmN0aW9uIChlcnJvcikge1xuICAgIHZhciBlcnJNc2cgPSBlcnJvcj8gZXJyb3IubWVzc2FnZSA6ICdvbiBWUEFJREludGVncmF0b3IsIGVycm9yIHdoaWxlIHdhaXRpbmcgZm9yIHRoZSBhZFVuaXQgdG8gZmluaXNoIHBsYXlpbmcnO1xuICAgIGZpbmlzaFBsYXlpbmdBZChuZXcgVkFTVEVycm9yKGVyck1zZykpO1xuICB9KTtcblxuICAvKioqIGxvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIGZpbmlzaFBsYXlpbmdBZChlcnJvcikge1xuICAgIG5leHQoZXJyb3IsIGFkVW5pdCwgdmFzdFJlc3BvbnNlKTtcbiAgfVxufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5fdHJhY2tFcnJvciA9IGZ1bmN0aW9uIHRyYWNrRXJyb3IocmVzcG9uc2UpIHtcbiAgdmFzdFV0aWwudHJhY2socmVzcG9uc2UuZXJyb3JVUkxNYWNyb3MsIHtFUlJPUkNPREU6IDkwMX0pO1xufTtcblxuZnVuY3Rpb24gcmVzaXplQWQocGxheWVyLCBhZFVuaXQsIFZJRVdfTU9ERSkge1xuICB2YXIgdGVjaCA9IHBsYXllci5lbCgpLnF1ZXJ5U2VsZWN0b3IoJy52anMtdGVjaCcpO1xuICB2YXIgZGltZW5zaW9uID0gZG9tLmdldERpbWVuc2lvbih0ZWNoKTtcbiAgdmFyIE1PREUgPSBwbGF5ZXIuaXNGdWxsc2NyZWVuKCkgPyBWSUVXX01PREUuRlVMTFNDUkVFTiA6IFZJRVdfTU9ERS5OT1JNQUw7XG4gIGFkVW5pdC5yZXNpemVBZChkaW1lbnNpb24ud2lkdGgsIGRpbWVuc2lvbi5oZWlnaHQsIE1PREUsIGxvZ0Vycm9yKTtcbn1cblxuZnVuY3Rpb24gbG9nRXJyb3IoZXJyb3IpIHtcbiAgaWYgKGVycm9yICYmIGNvbnNvbGUgJiYgY29uc29sZS5sb2cpIHtcbiAgICBjb25zb2xlLmxvZygnRVJST1I6ICcgKyBlcnJvci5tZXNzYWdlLCBlcnJvcik7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBWUEFJREludGVncmF0b3I7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZG9tID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvZG9tJyk7XG5cbnZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG5lbGVtZW50LmNsYXNzTmFtZSA9ICd2anMtYWRzLWxhYmVsIHZqcy1jb250cm9sIHZqcy1sYWJlbC1oaWRkZW4nO1xuZWxlbWVudC5pbm5lckhUTUwgPSAnQWR2ZXJ0aXNlbWVudCc7XG5cbnZhciBBZHNMYWJlbEZhY3RvcnkgPSBmdW5jdGlvbihiYXNlQ29tcG9uZW50KSB7XG4gIHJldHVybiB7XG4gICAgLyoqIEBjb25zdHJ1Y3RvciAqL1xuICAgIGluaXQ6IGZ1bmN0aW9uIGluaXQocGxheWVyLCBvcHRpb25zKSB7XG4gICAgICBvcHRpb25zLmVsID0gZWxlbWVudDtcbiAgICAgIGJhc2VDb21wb25lbnQuY2FsbCh0aGlzLCBwbGF5ZXIsIG9wdGlvbnMpO1xuXG4gICAgICAvLyBXZSBhc3luY2hyb25vdXNseSByZXBvc2l0aW9uIHRoZSBhZHMgbGFiZWwgZWxlbWVudFxuICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjdXJyZW50VGltZUNvbXAgPSBwbGF5ZXIuY29udHJvbEJhciAmJiggcGxheWVyLmNvbnRyb2xCYXIuZ2V0Q2hpbGQoXCJ0aW1lckNvbnRyb2xzXCIpIHx8IHBsYXllci5jb250cm9sQmFyLmdldENoaWxkKFwiY3VycmVudFRpbWVEaXNwbGF5XCIpICk7XG4gICAgICAgIGlmKGN1cnJlbnRUaW1lQ29tcCkge1xuICAgICAgICAgIHBsYXllci5jb250cm9sQmFyLmVsKCkuaW5zZXJ0QmVmb3JlKGVsZW1lbnQsIGN1cnJlbnRUaW1lQ29tcC5lbCgpKTtcbiAgICAgICAgfVxuICAgICAgICBkb20ucmVtb3ZlQ2xhc3MoZWxlbWVudCwgJ3Zqcy1sYWJlbC1oaWRkZW4nKTtcbiAgICAgIH0sIDApO1xuICAgIH0sXG5cbiAgICBlbDogZnVuY3Rpb24gZ2V0RWxlbWVudCgpIHtcbiAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH1cbiAgfTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gQWRzTGFiZWxGYWN0b3J5OyIsIid1c2Ugc3RyaWN0JztcblxudmFyIGJhc2VWaWRlb0pzQ29tcG9uZW50ID0gdmlkZW9qcy5Db21wb25lbnQ7XG5cbnZhciBBZHNMYWJlbCA9IHJlcXVpcmUoJy4vYWRzLWxhYmVsJykoYmFzZVZpZGVvSnNDb21wb25lbnQpO1xuXG52aWRlb2pzLkFkc0xhYmVsID0gdmlkZW9qcy5Db21wb25lbnQuZXh0ZW5kKEFkc0xhYmVsKTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBUaGUgY29tcG9uZW50IHRoYXQgc2hvd3MgYSBibGFjayBzY3JlZW4gdW50aWwgdGhlIGFkcyBwbHVnaW4gaGFzIGRlY2lkZWQgaWYgaXQgY2FuIG9yIGl0IGNhbiBub3QgcGxheSB0aGUgYWQuXG4gKlxuICogTm90ZTogSW4gY2FzZSB5b3Ugd29uZGVyIHdoeSBpbnN0ZWFkIG9mIHRoaXMgYmxhY2sgcG9zdGVyIHdlIGRvbid0IGp1c3Qgc2hvdyB0aGUgc3Bpbm5lciBsb2FkZXIuXG4gKiAgICAgICBJT1MgZGV2aWNlcyBkbyBub3Qgd29yayB3ZWxsIHdpdGggYW5pbWF0aW9ucyBhbmQgdGhlIGJyb3dzZXIgY2hyYXNoZXMgZnJvbSB0aW1lIHRvIHRpbWUgVGhhdCBpcyB3aHkgd2UgY2hvc2UgdG9cbiAqICAgICAgIGhhdmUgYSBzZWNvbmRhcnkgYmxhY2sgcG9zdGVyLlxuICpcbiAqICAgICAgIEl0IGFsc28gbWFrZXMgaXQgbXVjaCBtb3JlIGVhc2llciBmb3IgdGhlIHVzZXJzIG9mIHRoZSBwbHVnaW4gc2luY2UgaXQgZG9lcyBub3QgY2hhbmdlIHRoZSBkZWZhdWx0IGJlaGF2aW91ciBvZiB0aGVcbiAqICAgICAgIHNwaW5uZXIgYW5kIHRoZSBwbGF5ZXIgd29ya3MgdGhlIHNhbWUgd2F5IHdpdGggYW5kIHdpdGhvdXQgdGhlIHBsdWdpbi5cbiAqXG4gKiBAcGFyYW0ge3Zqcy5QbGF5ZXJ8T2JqZWN0fSBwbGF5ZXJcbiAqIEBwYXJhbSB7T2JqZWN0PX0gb3B0aW9uc1xuICogQGNvbnN0cnVjdG9yXG4gKi9cbnZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG5cbnZhciBCbGFja1Bvc3RlckZhY3RvcnkgPSBmdW5jdGlvbihiYXNlQ29tcG9uZW50KSB7XG4gIHJldHVybiB7XG4gICAgLyoqIEBjb25zdHJ1Y3RvciAqL1xuICAgIGluaXQ6IGZ1bmN0aW9uIGluaXQocGxheWVyLCBvcHRpb25zKSB7XG4gICAgICBvcHRpb25zLmVsID0gZWxlbWVudDtcbiAgICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gJ3Zqcy1ibGFjay1wb3N0ZXInO1xuICAgICAgYmFzZUNvbXBvbmVudC5jYWxsKHRoaXMsIHBsYXllciwgb3B0aW9ucyk7XG5cbiAgICAgIHZhciBwb3N0ZXJJbWcgPSBwbGF5ZXIuZ2V0Q2hpbGQoJ3Bvc3RlckltYWdlJyk7XG5cbiAgICAgIC8vV2UgbmVlZCB0byBkbyBpdCBhc3luY2hyb25vdXNseSB0byBiZSBzdXJlIHRoYXQgdGhlIGJsYWNrIHBvc3RlciBlbCBpcyBvbiB0aGUgZG9tLlxuICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgaWYocG9zdGVySW1nICYmIHBsYXllciAmJiBwbGF5ZXIuZWwoKSkge1xuICAgICAgICAgIHBsYXllci5lbCgpLmluc2VydEJlZm9yZShlbGVtZW50LCBwb3N0ZXJJbWcuZWwoKSk7XG4gICAgICAgIH1cbiAgICAgIH0sIDApO1xuICAgIH0sXG4gICAgZWw6IGZ1bmN0aW9uIGdldEVsZW1lbnQoKSB7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEJsYWNrUG9zdGVyRmFjdG9yeTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBiYXNlVmlkZW9Kc0NvbXBvbmVudCA9IHZpZGVvanMuQ29tcG9uZW50O1xuXG52YXIgQmxhY2tQb3N0ZXIgPSByZXF1aXJlKCcuL2JsYWNrLXBvc3RlcicpKGJhc2VWaWRlb0pzQ29tcG9uZW50KTtcblxudmlkZW9qcy5CbGFja1Bvc3RlciA9IHZpZGVvanMuQ29tcG9uZW50LmV4dGVuZChCbGFja1Bvc3Rlcik7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBWQVNUQ2xpZW50ID0gcmVxdWlyZSgnLi4vYWRzL3Zhc3QvVkFTVENsaWVudCcpO1xudmFyIFZBU1RFcnJvciA9IHJlcXVpcmUoJy4uL2Fkcy92YXN0L1ZBU1RFcnJvcicpO1xudmFyIHZhc3RVdGlsID0gcmVxdWlyZSgnLi4vYWRzL3Zhc3QvdmFzdFV0aWwnKTtcblxudmFyIFZBU1RJbnRlZ3JhdG9yID0gcmVxdWlyZSgnLi4vYWRzL3Zhc3QvVkFTVEludGVncmF0b3InKTtcbnZhciBWUEFJREludGVncmF0b3IgPSByZXF1aXJlKCcuLi9hZHMvdnBhaWQvVlBBSURJbnRlZ3JhdG9yJyk7XG5cbnZhciBhc3luYyA9IHJlcXVpcmUoJy4uL3V0aWxzL2FzeW5jJyk7XG52YXIgZG9tID0gcmVxdWlyZSgnLi4vdXRpbHMvZG9tJyk7XG52YXIgcGxheWVyVXRpbHMgPSByZXF1aXJlKCcuLi91dGlscy9wbGF5ZXJVdGlscycpO1xudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBWQVNUUGx1Z2luKG9wdGlvbnMpIHtcbiAgdmFyIHNuYXBzaG90O1xuICB2YXIgcGxheWVyID0gdGhpcztcbiAgdmFyIHZhc3QgPSBuZXcgVkFTVENsaWVudCgpO1xuICB2YXIgYWRzQ2FuY2VsZWQgPSBmYWxzZTtcbiAgdmFyIGRlZmF1bHRPcHRzID0ge1xuICAgIC8vIG1heGltdW0gYW1vdW50IG9mIHRpbWUgaW4gbXMgdG8gd2FpdCB0byByZWNlaXZlIGBhZHNyZWFkeWAgZnJvbSB0aGUgYWRcbiAgICAvLyBpbXBsZW1lbnRhdGlvbiBhZnRlciBwbGF5IGhhcyBiZWVuIHJlcXVlc3RlZC4gQWQgaW1wbGVtZW50YXRpb25zIGFyZVxuICAgIC8vIGV4cGVjdGVkIHRvIGxvYWQgYW55IGR5bmFtaWMgbGlicmFyaWVzIGFuZCBtYWtlIGFueSByZXF1ZXN0cyB0byBkZXRlcm1pbmVcbiAgICAvLyBhZCBwb2xpY2llcyBmb3IgYSB2aWRlbyBkdXJpbmcgdGhpcyB0aW1lLlxuICAgIHRpbWVvdXQ6IDUwMCxcblxuICAgIC8vVE9ETzpmaW5pc2ggdGhpcyBJT1MgRklYXG4gICAgLy9XaGVuZXZlciB5b3UgcGxheSBhbiBhZGQgb24gSU9TLCB0aGUgbmF0aXZlIHBsYXllciBraWNrcyBpbiBhbmQgd2UgbG9vc2UgY29udHJvbCBvZiBpdC4gT24gdmVyeSBoZWF2eSBwYWdlcyB0aGUgJ3BsYXknIGV2ZW50XG4gICAgLy8gTWF5IG9jY3VyIGFmdGVyIHRoZSB2aWRlbyBjb250ZW50IGhhcyBhbHJlYWR5IHN0YXJ0ZWQuIFRoaXMgaXMgd3JvbmcgaWYgeW91IHdhbnQgdG8gcGxheSBhIHByZXJvbGwgYWQgdGhhdCBuZWVkcyB0byBoYXBwZW4gYmVmb3JlIHRoZSB1c2VyXG4gICAgLy8gc3RhcnRzIHdhdGNoaW5nIHRoZSBjb250ZW50LiBUbyBwcmV2ZW50IHRoaXMgdXNlY1xuICAgIGlvc1ByZXJvbGxDYW5jZWxUaW1lb3V0OiAyMDAwLFxuXG4gICAgLy8gbWF4aW11biBhbW91bnQgb2YgdGltZSBmb3IgdGhlIGFkIHRvIGFjdHVhbGx5IHN0YXJ0IHBsYXlpbmcuIElmIHRoaXMgdGltZW91dCBnZXRzXG4gICAgLy8gdHJpZ2dlcmVkIHRoZSBhZHMgd2lsbCBiZSBjYW5jZWxsZWRcbiAgICBhZENhbmNlbFRpbWVvdXQ6IDMwMDAsXG5cbiAgICAvLyBCb29sZWFuIGZsYWcgdGhhdCBjb25maWd1cmVzIHRoZSBwbGF5ZXIgdG8gcGxheSBhIG5ldyBhZCBiZWZvcmUgdGhlIHVzZXIgc2VlcyB0aGUgdmlkZW8gYWdhaW5cbiAgICAvLyB0aGUgY3VycmVudCB2aWRlb1xuICAgIHBsYXlBZEFsd2F5czogZmFsc2UsXG5cbiAgICAvLyBGbGFnIHRvIGVuYWJsZSBvciBkaXNhYmxlIHRoZSBhZHMgYnkgZGVmYXVsdC5cbiAgICBhZHNFbmFibGVkOiB0cnVlLFxuXG4gICAgLy8gQm9vbGVhbiBmbGFnIHRvIGVuYWJsZSBvciBkaXNhYmxlIHRoZSByZXNpemUgd2l0aCB3aW5kb3cucmVzaXplIG9yIG9yaWVudGF0aW9uY2hhbmdlXG4gICAgYXV0b1Jlc2l6ZTogdHJ1ZSxcblxuICAgIC8vIFBhdGggdG8gdGhlIFZQQUlEIGZsYXNoIGFkJ3MgbG9hZGVyXG4gICAgdnBhaWRGbGFzaExvYWRlclBhdGg6ICcvVlBBSURGbGFzaC5zd2YnXG4gIH07XG5cbiAgdmFyIHNldHRpbmdzID0gdXRpbGl0aWVzLmV4dGVuZCh7fSwgZGVmYXVsdE9wdHMsIG9wdGlvbnMgfHwge30pO1xuXG4gIGlmKHV0aWxpdGllcy5pc1VuZGVmaW5lZChzZXR0aW5ncy5hZFRhZ1VybCkgJiYgdXRpbGl0aWVzLmlzRGVmaW5lZChzZXR0aW5ncy51cmwpKXtcbiAgICBzZXR0aW5ncy5hZFRhZ1VybCA9IHNldHRpbmdzLnVybDtcbiAgfVxuXG4gIGlmICh1dGlsaXRpZXMuaXNTdHJpbmcoc2V0dGluZ3MuYWRUYWdVcmwpKSB7XG4gICAgc2V0dGluZ3MuYWRUYWdVcmwgPSB1dGlsaXRpZXMuZWNob0ZuKHNldHRpbmdzLmFkVGFnVXJsKTtcbiAgfVxuXG4gIGlmICh1dGlsaXRpZXMuaXNEZWZpbmVkKHNldHRpbmdzLmFkVGFnWE1MKSAmJiAhdXRpbGl0aWVzLmlzRnVuY3Rpb24oc2V0dGluZ3MuYWRUYWdYTUwpKSB7XG4gICAgcmV0dXJuIHRyYWNrQWRFcnJvcihuZXcgVkFTVEVycm9yKCdvbiBWaWRlb0pTIFZBU1QgcGx1Z2luLCB0aGUgcGFzc2VkIGFkVGFnWE1MIG9wdGlvbiBkb2VzIG5vdCBjb250YWluIGEgZnVuY3Rpb24nKSk7XG4gIH1cblxuICBpZiAoIXV0aWxpdGllcy5pc0RlZmluZWQoc2V0dGluZ3MuYWRUYWdVcmwpICYmICF1dGlsaXRpZXMuaXNGdW5jdGlvbihzZXR0aW5ncy5hZFRhZ1hNTCkpIHtcbiAgICByZXR1cm4gdHJhY2tBZEVycm9yKG5ldyBWQVNURXJyb3IoJ29uIFZpZGVvSlMgVkFTVCBwbHVnaW4sIG1pc3NpbmcgYWRUYWdVcmwgb24gb3B0aW9ucyBvYmplY3QnKSk7XG4gIH1cblxuICBwbGF5ZXJVdGlscy5wcmVwYXJlRm9yQWRzKHBsYXllcik7XG5cbiAgaWYgKHNldHRpbmdzLnBsYXlBZEFsd2F5cykge1xuICAgIC8vIE5vIG1hdHRlciB3aGF0IGhhcHBlbnMgd2UgcGxheSBhIG5ldyBhZCBiZWZvcmUgdGhlIHVzZXIgc2VlcyB0aGUgdmlkZW8gYWdhaW4uXG4gICAgcGxheWVyLm9uKCd2YXN0LmNvbnRlbnRFbmQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcGxheWVyLnRyaWdnZXIoJ3Zhc3QucmVzZXQnKTtcbiAgICAgIH0sIDApO1xuICAgIH0pO1xuICB9XG5cbiAgcGxheWVyLm9uKCd2YXN0LmZpcnN0UGxheScsIHRyeVRvUGxheVByZXJvbGxBZCk7XG5cbiAgcGxheWVyLm9uKCd2YXN0LnJlc2V0JywgZnVuY3Rpb24gKCkge1xuICAgIC8vSWYgd2UgYXJlIHJlc2V0aW5nIHRoZSBwbHVnaW4sIHdlIGRvbid0IHdhbnQgdG8gcmVzdG9yZSB0aGUgY29udGVudFxuICAgIHNuYXBzaG90ID0gbnVsbDtcbiAgICBjYW5jZWxBZHMoKTtcbiAgfSk7XG5cbiAgcGxheWVyLnZhc3QgPSB7XG4gICAgaXNFbmFibGVkOiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gc2V0dGluZ3MuYWRzRW5hYmxlZDtcbiAgICB9LFxuXG4gICAgZW5hYmxlOiBmdW5jdGlvbiAoKSB7XG4gICAgICBzZXR0aW5ncy5hZHNFbmFibGVkID0gdHJ1ZTtcbiAgICB9LFxuXG4gICAgZGlzYWJsZTogZnVuY3Rpb24gKCkge1xuICAgICAgc2V0dGluZ3MuYWRzRW5hYmxlZCA9IGZhbHNlO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gcGxheWVyLnZhc3Q7XG5cbiAgLyoqKiogTG9jYWwgZnVuY3Rpb25zICoqKiovXG4gIGZ1bmN0aW9uIHRyeVRvUGxheVByZXJvbGxBZCgpIHtcbiAgICAvL1dlIHJlbW92ZSB0aGUgcG9zdGVyIHRvIHByZXZlbnQgZmxpY2tlcmluZyB3aGVuZXZlciB0aGUgY29udGVudCBzdGFydHMgcGxheWluZ1xuICAgIHBsYXllclV0aWxzLnJlbW92ZU5hdGl2ZVBvc3RlcihwbGF5ZXIpO1xuXG4gICAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsndmFzdC5hZHNDYW5jZWwnLCAndmFzdC5hZEVuZCddLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZW1vdmVBZFVuaXQoKTtcbiAgICAgIHJlc3RvcmVWaWRlb0NvbnRlbnQoKTtcbiAgICB9KTtcblxuICAgIGFzeW5jLndhdGVyZmFsbChbXG4gICAgICBjaGVja0Fkc0VuYWJsZWQsXG4gICAgICBwcmVwYXJlUGxheWVyRm9yQWQsXG4gICAgICBzdGFydEFkQ2FuY2VsVGltZW91dCxcbiAgICAgIHBsYXlQcmVyb2xsQWRcbiAgICBdLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3BvbnNlKSB7XG4gICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgdHJhY2tBZEVycm9yKGVycm9yLCByZXNwb25zZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwbGF5ZXIudHJpZ2dlcigndmFzdC5hZEVuZCcpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqL1xuXG4gICAgZnVuY3Rpb24gcmVtb3ZlQWRVbml0KCkge1xuICAgICAgaWYgKHBsYXllci52YXN0ICYmIHBsYXllci52YXN0LmFkVW5pdCkge1xuICAgICAgICBwbGF5ZXIudmFzdC5hZFVuaXQgPSBudWxsOyAvL1dlIHJlbW92ZSB0aGUgYWRVbml0XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVzdG9yZVZpZGVvQ29udGVudCgpIHtcbiAgICAgIHNldHVwQ29udGVudEV2ZW50cygpO1xuICAgICAgaWYgKHNuYXBzaG90KSB7XG4gICAgICAgIHBsYXllclV0aWxzLnJlc3RvcmVQbGF5ZXJTbmFwc2hvdChwbGF5ZXIsIHNuYXBzaG90KTtcbiAgICAgICAgc25hcHNob3QgPSBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNldHVwQ29udGVudEV2ZW50cygpIHtcbiAgICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3BsYXlpbmcnLCAndmFzdC5yZXNldCcsICd2YXN0LmZpcnN0UGxheSddLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIGlmIChldnQudHlwZSAhPT0gJ3BsYXlpbmcnKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcGxheWVyLnRyaWdnZXIoJ3Zhc3QuY29udGVudFN0YXJ0Jyk7XG5cbiAgICAgICAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsnZW5kZWQnLCAndmFzdC5yZXNldCcsICd2YXN0LmZpcnN0UGxheSddLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgICAgaWYgKGV2dC50eXBlID09PSAnZW5kZWQnKSB7XG4gICAgICAgICAgICBwbGF5ZXIudHJpZ2dlcigndmFzdC5jb250ZW50RW5kJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNoZWNrQWRzRW5hYmxlZChuZXh0KSB7XG4gICAgICBpZiAoc2V0dGluZ3MuYWRzRW5hYmxlZCkge1xuICAgICAgICByZXR1cm4gbmV4dChudWxsKTtcbiAgICAgIH1cbiAgICAgIG5leHQobmV3IFZBU1RFcnJvcignQWRzIGFyZSBub3QgZW5hYmxlZCcpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmVwYXJlUGxheWVyRm9yQWQobmV4dCkge1xuICAgICAgaWYgKGNhblBsYXlQcmVyb2xsQWQoKSkge1xuICAgICAgICBzbmFwc2hvdCA9IHBsYXllclV0aWxzLmdldFBsYXllclNuYXBzaG90KHBsYXllcik7XG4gICAgICAgIHBsYXllci5wYXVzZSgpO1xuICAgICAgICBhZGRTcGlubmVySWNvbigpO1xuXG4gICAgICAgIGlmKHBsYXllci5wYXVzZWQoKSkge1xuICAgICAgICAgIG5leHQobnVsbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsncGxheWluZyddLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHBsYXllci5wYXVzZSgpO1xuICAgICAgICAgICAgbmV4dChudWxsKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV4dChuZXcgVkFTVEVycm9yKCd2aWRlbyBjb250ZW50IGhhcyBiZWVuIHBsYXlpbmcgYmVmb3JlIHByZXJvbGwgYWQnKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FuUGxheVByZXJvbGxBZCgpIHtcbiAgICAgIHJldHVybiAhdXRpbGl0aWVzLmlzSVBob25lKCkgfHwgcGxheWVyLmN1cnJlbnRUaW1lKCkgPD0gc2V0dGluZ3MuaW9zUHJlcm9sbENhbmNlbFRpbWVvdXQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc3RhcnRBZENhbmNlbFRpbWVvdXQobmV4dCkge1xuICAgICAgdmFyIGFkQ2FuY2VsVGltZW91dElkO1xuICAgICAgYWRzQ2FuY2VsZWQgPSBmYWxzZTtcblxuICAgICAgYWRDYW5jZWxUaW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdHJhY2tBZEVycm9yKG5ldyBWQVNURXJyb3IoJ3RpbWVvdXQgd2hpbGUgd2FpdGluZyBmb3IgdGhlIHZpZGVvIHRvIHN0YXJ0IHBsYXlpbmcnLCA0MDIpKTtcbiAgICAgIH0sIHNldHRpbmdzLmFkQ2FuY2VsVGltZW91dCk7XG5cbiAgICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3Zhc3QuYWRTdGFydCcsICd2YXN0LmFkc0NhbmNlbCddLCBjbGVhckFkQ2FuY2VsVGltZW91dCk7XG5cbiAgICAgIC8qKiogbG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgICAgIGZ1bmN0aW9uIGNsZWFyQWRDYW5jZWxUaW1lb3V0KCkge1xuICAgICAgICBpZiAoYWRDYW5jZWxUaW1lb3V0SWQpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQoYWRDYW5jZWxUaW1lb3V0SWQpO1xuICAgICAgICAgIGFkQ2FuY2VsVGltZW91dElkID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBuZXh0KG51bGwpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkZFNwaW5uZXJJY29uKCkge1xuICAgICAgZG9tLmFkZENsYXNzKHBsYXllci5lbCgpLCAndmpzLXZhc3QtYWQtbG9hZGluZycpO1xuICAgICAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsndmFzdC5hZFN0YXJ0JywgJ3Zhc3QuYWRzQ2FuY2VsJ10sIHJlbW92ZVNwaW5uZXJJY29uKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZW1vdmVTcGlubmVySWNvbigpIHtcbiAgICAgIC8vSU1QT1JUQU5UIE5PVEU6IFdlIHJlbW92ZSB0aGUgc3Bpbm5lckljb24gYXN5bmNocm9ub3VzbHkgdG8gZ2l2ZSB0aW1lIHRvIHRoZSBicm93c2VyIHRvIHN0YXJ0IHRoZSB2aWRlby5cbiAgICAgIC8vIElmIHdlIHJlbW92ZSBpdCBzeW5jaHJvbm91c2x5IHdlIHNlZSBhIGZsYXNoIG9mIHRoZSBjb250ZW50IHZpZGVvIGJlZm9yZSB0aGUgYWQgc3RhcnRzIHBsYXlpbmcuXG4gICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZG9tLnJlbW92ZUNsYXNzKHBsYXllci5lbCgpLCAndmpzLXZhc3QtYWQtbG9hZGluZycpO1xuICAgICAgfSwgMTAwKTtcbiAgICB9XG5cbiAgfVxuXG4gIGZ1bmN0aW9uIGNhbmNlbEFkcygpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcigndmFzdC5hZHNDYW5jZWwnKTtcbiAgICBhZHNDYW5jZWxlZCA9IHRydWU7XG4gIH1cblxuICBmdW5jdGlvbiBwbGF5UHJlcm9sbEFkKGNhbGxiYWNrKSB7XG4gICAgYXN5bmMud2F0ZXJmYWxsKFtcbiAgICAgIGdldFZhc3RSZXNwb25zZSxcbiAgICAgIHBsYXlBZFxuICAgIF0sIGNhbGxiYWNrKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldFZhc3RSZXNwb25zZShjYWxsYmFjaykge1xuICAgIHZhc3QuZ2V0VkFTVFJlc3BvbnNlKHNldHRpbmdzLmFkVGFnVXJsID8gc2V0dGluZ3MuYWRUYWdVcmwoKSA6IHNldHRpbmdzLmFkVGFnWE1MLCBjYWxsYmFjayk7XG4gIH1cblxuICBmdW5jdGlvbiBwbGF5QWQodmFzdFJlc3BvbnNlLCBjYWxsYmFjaykge1xuICAgIC8vVE9ETzogRmluZCBhIGJldHRlciB3YXkgdG8gc3RvcCB0aGUgcGxheS4gVGhlICdwbGF5UHJlcm9sbFdhdGVyZmFsbCcgZW5kcyBpbiBhbiBpbmNvbnNpc3RlbnQgc2l0dWF0aW9uXG4gICAgLy9JZiB0aGUgc3RhdGUgaXMgbm90ICdwcmVyb2xsPycgaXQgbWVhbnMgdGhlIGFkcyB3ZXJlIGNhbmNlbGVkIHRoZXJlZm9yZSwgd2UgYnJlYWsgdGhlIHdhdGVyZmFsbFxuICAgIGlmIChhZHNDYW5jZWxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBhZEludGVncmF0b3IgPSBpc1ZQQUlEKHZhc3RSZXNwb25zZSkgPyBuZXcgVlBBSURJbnRlZ3JhdG9yKHBsYXllciwgc2V0dGluZ3MpIDogbmV3IFZBU1RJbnRlZ3JhdG9yKHBsYXllcik7XG4gICAgdmFyIGFkRmluaXNoZWQgPSBmYWxzZTtcblxuICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3Zhc3QuYWRTdGFydCcsICd2YXN0LmFkc0NhbmNlbCddLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICBpZiAoZXZ0LnR5cGUgPT09ICd2YXN0LmFkU3RhcnQnKSB7XG4gICAgICAgIGFkZEFkc0xhYmVsKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWyd2YXN0LmFkRW5kJywgJ3Zhc3QuYWRzQ2FuY2VsJ10sIHJlbW92ZUFkc0xhYmVsKTtcblxuICAgIGlmICh1dGlsaXRpZXMuaXNJRGV2aWNlKCkpIHtcbiAgICAgIHByZXZlbnRNYW51YWxQcm9ncmVzcygpO1xuICAgIH1cblxuICAgIHBsYXllci52YXN0LnZhc3RSZXNwb25zZSA9IHZhc3RSZXNwb25zZTtcbiAgICBwbGF5ZXIudmFzdC5hZFVuaXQgPSBhZEludGVncmF0b3IucGxheUFkKHZhc3RSZXNwb25zZSwgY2FsbGJhY2spO1xuXG4gICAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqKi9cbiAgICBmdW5jdGlvbiBhZGRBZHNMYWJlbCgpIHtcbiAgICAgIGlmIChhZEZpbmlzaGVkIHx8IHBsYXllci5jb250cm9sQmFyLmdldENoaWxkKCdBZHNMYWJlbCcpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgcGxheWVyLmNvbnRyb2xCYXIuYWRkQ2hpbGQoJ0Fkc0xhYmVsJyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVtb3ZlQWRzTGFiZWwoKSB7XG4gICAgICBwbGF5ZXIuY29udHJvbEJhci5yZW1vdmVDaGlsZCgnQWRzTGFiZWwnKTtcbiAgICAgIGFkRmluaXNoZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByZXZlbnRNYW51YWxQcm9ncmVzcygpIHtcbiAgICAgIC8vSU9TIHZpZGVvIGNsb2NrIGlzIHZlcnkgdW5yZWxpYWJsZSBhbmQgd2UgbmVlZCBhIDMgc2Vjb25kcyB0aHJlc2hvbGQgdG8gZW5zdXJlIHRoYXQgdGhlIHVzZXIgZm9yd2FyZGVkL3Jld291bmQgdGhlIGFkXG4gICAgICB2YXIgUFJPR1JFU1NfVEhSRVNIT0xEID0gMztcbiAgICAgIHZhciBwcmV2aW91c1RpbWUgPSAwO1xuICAgICAgdmFyIHNraXBhZF9hdHRlbXB0cyA9IDA7XG5cbiAgICAgIHBsYXllci5vbigndGltZXVwZGF0ZScsIGFkVGltZXVwZGF0ZUhhbmRsZXIpO1xuICAgICAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsndmFzdC5hZEVuZCcsICd2YXN0LmFkc0NhbmNlbCcsICd2YXN0LmFkRXJyb3InXSwgc3RvcFByZXZlbnRNYW51YWxQcm9ncmVzcyk7XG5cbiAgICAgIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgICAgIGZ1bmN0aW9uIGFkVGltZXVwZGF0ZUhhbmRsZXIoKSB7XG4gICAgICAgIHZhciBjdXJyZW50VGltZSA9IHBsYXllci5jdXJyZW50VGltZSgpO1xuICAgICAgICB2YXIgcHJvZ3Jlc3NEZWx0YSA9IE1hdGguYWJzKGN1cnJlbnRUaW1lIC0gcHJldmlvdXNUaW1lKTtcblxuICAgICAgICBpZiAocHJvZ3Jlc3NEZWx0YSA+IFBST0dSRVNTX1RIUkVTSE9MRCkge1xuICAgICAgICAgIHNraXBhZF9hdHRlbXB0cyArPSAxO1xuICAgICAgICAgIGlmIChza2lwYWRfYXR0ZW1wdHMgPj0gMikge1xuICAgICAgICAgICAgcGxheWVyLnBhdXNlKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHBsYXllci5jdXJyZW50VGltZShwcmV2aW91c1RpbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHByZXZpb3VzVGltZSA9IGN1cnJlbnRUaW1lO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIHN0b3BQcmV2ZW50TWFudWFsUHJvZ3Jlc3MoKSB7XG4gICAgICAgIHBsYXllci5vZmYoJ3RpbWV1cGRhdGUnLCBhZFRpbWV1cGRhdGVIYW5kbGVyKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB0cmFja0FkRXJyb3IoZXJyb3IsIHZhc3RSZXNwb25zZSkge1xuICAgIHBsYXllci50cmlnZ2VyKHt0eXBlOiAndmFzdC5hZEVycm9yJywgZXJyb3I6IGVycm9yfSk7XG4gICAgY2FuY2VsQWRzKCk7XG4gICAgaWYgKGNvbnNvbGUgJiYgY29uc29sZS5sb2cpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdBRCBFUlJPUjonLCBlcnJvci5tZXNzYWdlLCBlcnJvciwgdmFzdFJlc3BvbnNlKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpc1ZQQUlEKHZhc3RSZXNwb25zZSkge1xuICAgIHZhciBpLCBsZW47XG4gICAgdmFyIG1lZGlhRmlsZXMgPSB2YXN0UmVzcG9uc2UubWVkaWFGaWxlcztcbiAgICBmb3IgKGkgPSAwLCBsZW4gPSBtZWRpYUZpbGVzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBpZiAodmFzdFV0aWwuaXNWUEFJRChtZWRpYUZpbGVzW2ldKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59OyIsIi8vU21hbGwgc3Vic2V0IG9mIGFzeW5jXG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxudmFyIGFzeW5jID0ge307XG5cbmFzeW5jLnNldEltbWVkaWF0ZSA9IGZ1bmN0aW9uIChmbikge1xuICBzZXRUaW1lb3V0KGZuLCAwKTtcbn07XG5cbmFzeW5jLml0ZXJhdG9yID0gZnVuY3Rpb24gKHRhc2tzKSB7XG4gIHZhciBtYWtlQ2FsbGJhY2sgPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICB2YXIgZm4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAodGFza3MubGVuZ3RoKSB7XG4gICAgICAgIHRhc2tzW2luZGV4XS5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZuLm5leHQoKTtcbiAgICB9O1xuICAgIGZuLm5leHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gKGluZGV4IDwgdGFza3MubGVuZ3RoIC0gMSkgPyBtYWtlQ2FsbGJhY2soaW5kZXggKyAxKSA6IG51bGw7XG4gICAgfTtcbiAgICByZXR1cm4gZm47XG4gIH07XG4gIHJldHVybiBtYWtlQ2FsbGJhY2soMCk7XG59O1xuXG5cbmFzeW5jLndhdGVyZmFsbCA9IGZ1bmN0aW9uICh0YXNrcywgY2FsbGJhY2spIHtcbiAgY2FsbGJhY2sgPSBjYWxsYmFjayB8fCBmdW5jdGlvbiAoKSB7IH07XG4gIGlmICghdXRpbGl0aWVzLmlzQXJyYXkodGFza3MpKSB7XG4gICAgdmFyIGVyciA9IG5ldyBFcnJvcignRmlyc3QgYXJndW1lbnQgdG8gd2F0ZXJmYWxsIG11c3QgYmUgYW4gYXJyYXkgb2YgZnVuY3Rpb25zJyk7XG4gICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gIH1cbiAgaWYgKCF0YXNrcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgfVxuICB2YXIgd3JhcEl0ZXJhdG9yID0gZnVuY3Rpb24gKGl0ZXJhdG9yKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgY2FsbGJhY2suYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICAgICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICB2YXIgbmV4dCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgaWYgKG5leHQpIHtcbiAgICAgICAgICBhcmdzLnB1c2god3JhcEl0ZXJhdG9yKG5leHQpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBhcmdzLnB1c2goY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGFzeW5jLnNldEltbWVkaWF0ZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaXRlcmF0b3IuYXBwbHkobnVsbCwgYXJncyk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH07XG4gIH07XG4gIHdyYXBJdGVyYXRvcihhc3luYy5pdGVyYXRvcih0YXNrcykpKCk7XG59O1xuXG5hc3luYy53aGVuID0gZnVuY3Rpb24gKGNvbmRpdGlvbiwgY2FsbGJhY2spIHtcbiAgaWYgKCF1dGlsaXRpZXMuaXNGdW5jdGlvbihjYWxsYmFjaykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJhc3luYy53aGVuIGVycm9yOiBtaXNzaW5nIGNhbGxiYWNrIGFyZ3VtZW50XCIpO1xuICB9XG5cbiAgdmFyIGlzQWxsb3dlZCA9IHV0aWxpdGllcy5pc0Z1bmN0aW9uKGNvbmRpdGlvbikgPyBjb25kaXRpb24gOiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICEhY29uZGl0aW9uO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGFyZ3MgPSB1dGlsaXRpZXMuYXJyYXlMaWtlT2JqVG9BcnJheShhcmd1bWVudHMpO1xuICAgIHZhciBuZXh0ID0gYXJncy5wb3AoKTtcblxuICAgIGlmIChpc0FsbG93ZWQuYXBwbHkobnVsbCwgYXJncykpIHtcbiAgICAgIHJldHVybiBjYWxsYmFjay5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIGFyZ3MudW5zaGlmdChudWxsKTtcbiAgICByZXR1cm4gbmV4dC5hcHBseShudWxsLCBhcmdzKTtcbiAgfTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gYXN5bmM7XG5cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4vdXRpbGl0eUZ1bmN0aW9ucycpO1xuXG52YXIgZG9tID0ge307XG5cbmRvbS5pc1Zpc2libGUgPSBmdW5jdGlvbiBpc1Zpc2libGUoZWwpIHtcbiAgdmFyIHN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWwpO1xuICByZXR1cm4gc3R5bGUudmlzaWJpbGl0eSAhPT0gJ2hpZGRlbic7XG59O1xuXG5kb20uaXNIaWRkZW4gPSBmdW5jdGlvbiBpc0hpZGRlbihlbCkge1xuICB2YXIgc3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbCk7XG4gIHJldHVybiBzdHlsZS5kaXNwbGF5ID09PSAnbm9uZSc7XG59O1xuXG5kb20uaXNTaG93biA9IGZ1bmN0aW9uIGlzU2hvd24oZWwpIHtcbiAgcmV0dXJuICFkb20uaXNIaWRkZW4oZWwpO1xufTtcblxuZG9tLmhpZGUgPSBmdW5jdGlvbiBoaWRlKGVsKSB7XG4gIGVsLl9fcHJldl9zdHlsZV9kaXNwbGF5XyA9IGVsLnN0eWxlLmRpc3BsYXk7XG4gIGVsLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG59O1xuXG5kb20uc2hvdyA9IGZ1bmN0aW9uIHNob3coZWwpIHtcbiAgaWYgKGRvbS5pc0hpZGRlbihlbCkpIHtcbiAgICBlbC5zdHlsZS5kaXNwbGF5ID0gZWwuX19wcmV2X3N0eWxlX2Rpc3BsYXlfO1xuICB9XG4gIGVsLl9fcHJldl9zdHlsZV9kaXNwbGF5XyA9IHVuZGVmaW5lZDtcbn07XG5cbmRvbS5oYXNDbGFzcyA9IGZ1bmN0aW9uIGhhc0NsYXNzKGVsLCBjc3NDbGFzcykge1xuICB2YXIgY2xhc3NlcywgaSwgbGVuO1xuXG4gIGlmICh1dGlsaXRpZXMuaXNOb3RFbXB0eVN0cmluZyhjc3NDbGFzcykpIHtcbiAgICBpZiAoZWwuY2xhc3NMaXN0KSB7XG4gICAgICByZXR1cm4gZWwuY2xhc3NMaXN0LmNvbnRhaW5zKGNzc0NsYXNzKTtcbiAgICB9XG5cbiAgICBjbGFzc2VzID0gdXRpbGl0aWVzLmlzU3RyaW5nKGVsLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSkgPyBlbC5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykuc3BsaXQoL1xccysvKSA6IFtdO1xuICAgIGNzc0NsYXNzID0gKGNzc0NsYXNzIHx8ICcnKTtcblxuICAgIGZvciAoaSA9IDAsIGxlbiA9IGNsYXNzZXMubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgIGlmIChjbGFzc2VzW2ldID09PSBjc3NDbGFzcykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuZG9tLmFkZENsYXNzID0gZnVuY3Rpb24gKGVsLCBjc3NDbGFzcykge1xuICB2YXIgY2xhc3NlcztcblxuICBpZiAodXRpbGl0aWVzLmlzTm90RW1wdHlTdHJpbmcoY3NzQ2xhc3MpKSB7XG4gICAgaWYgKGVsLmNsYXNzTGlzdCkge1xuICAgICAgcmV0dXJuIGVsLmNsYXNzTGlzdC5hZGQoY3NzQ2xhc3MpO1xuICAgIH1cblxuICAgIGNsYXNzZXMgPSB1dGlsaXRpZXMuaXNTdHJpbmcoZWwuZ2V0QXR0cmlidXRlKCdjbGFzcycpKSA/IGVsLmdldEF0dHJpYnV0ZSgnY2xhc3MnKS5zcGxpdCgvXFxzKy8pIDogW107XG4gICAgaWYgKHV0aWxpdGllcy5pc1N0cmluZyhjc3NDbGFzcykgJiYgdXRpbGl0aWVzLmlzTm90RW1wdHlTdHJpbmcoY3NzQ2xhc3MucmVwbGFjZSgvXFxzKy8sICcnKSkpIHtcbiAgICAgIGNsYXNzZXMucHVzaChjc3NDbGFzcyk7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgY2xhc3Nlcy5qb2luKCcgJykpO1xuICAgIH1cbiAgfVxufTtcblxuZG9tLnJlbW92ZUNsYXNzID0gZnVuY3Rpb24gKGVsLCBjc3NDbGFzcykge1xuICB2YXIgY2xhc3NlcztcblxuICBpZiAodXRpbGl0aWVzLmlzTm90RW1wdHlTdHJpbmcoY3NzQ2xhc3MpKSB7XG4gICAgaWYgKGVsLmNsYXNzTGlzdCkge1xuICAgICAgcmV0dXJuIGVsLmNsYXNzTGlzdC5yZW1vdmUoY3NzQ2xhc3MpO1xuICAgIH1cblxuICAgIGNsYXNzZXMgPSB1dGlsaXRpZXMuaXNTdHJpbmcoZWwuZ2V0QXR0cmlidXRlKCdjbGFzcycpKSA/IGVsLmdldEF0dHJpYnV0ZSgnY2xhc3MnKS5zcGxpdCgvXFxzKy8pIDogW107XG4gICAgdmFyIG5ld0NsYXNzZXMgPSBbXTtcbiAgICB2YXIgaSwgbGVuO1xuICAgIGlmICh1dGlsaXRpZXMuaXNTdHJpbmcoY3NzQ2xhc3MpICYmIHV0aWxpdGllcy5pc05vdEVtcHR5U3RyaW5nKGNzc0NsYXNzLnJlcGxhY2UoL1xccysvLCAnJykpKSB7XG5cbiAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGNsYXNzZXMubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgICAgaWYgKGNzc0NsYXNzICE9PSBjbGFzc2VzW2ldKSB7XG4gICAgICAgICAgbmV3Q2xhc3Nlcy5wdXNoKGNsYXNzZXNbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgbmV3Q2xhc3Nlcy5qb2luKCcgJykpO1xuICAgIH1cbiAgfVxufTtcblxuZG9tLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRFdmVudExpc3RlbmVyKGVsLCB0eXBlLCBoYW5kbGVyKSB7XG4gIGlmKHV0aWxpdGllcy5pc0FycmF5KGVsKSl7XG4gICAgdXRpbGl0aWVzLmZvckVhY2goZWwsIGZ1bmN0aW9uKGUpIHtcbiAgICAgIGRvbS5hZGRFdmVudExpc3RlbmVyKGUsIHR5cGUsIGhhbmRsZXIpO1xuICAgIH0pO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmKHV0aWxpdGllcy5pc0FycmF5KHR5cGUpKXtcbiAgICB1dGlsaXRpZXMuZm9yRWFjaCh0eXBlLCBmdW5jdGlvbih0KSB7XG4gICAgICBkb20uYWRkRXZlbnRMaXN0ZW5lcihlbCwgdCwgaGFuZGxlcik7XG4gICAgfSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGVsLmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICBlbC5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGhhbmRsZXIsIGZhbHNlKTtcbiAgfSBlbHNlIGlmIChlbC5hdHRhY2hFdmVudCkge1xuICAgIC8vIFdBUk5JTkchISEgdGhpcyBpcyBhIHZlcnkgbmFpdmUgaW1wbGVtZW50YXRpb24gIVxuICAgIC8vIHRoZSBldmVudCBvYmplY3QgdGhhdCBzaG91bGQgYmUgcGFzc2VkIHRvIHRoZSBoYW5kbGVyXG4gICAgLy8gd291bGQgbm90IGJlIHRoZXJlIGZvciBJRThcbiAgICAvLyB3ZSBzaG91bGQgdXNlIFwid2luZG93LmV2ZW50XCIgYW5kIHRoZW4gXCJldmVudC5zcmNFbGVtZW50XCJcbiAgICAvLyBpbnN0ZWFkIG9mIFwiZXZlbnQudGFyZ2V0XCJcbiAgICBlbC5hdHRhY2hFdmVudChcIm9uXCIgKyB0eXBlLCBoYW5kbGVyKTtcbiAgfVxufTtcblxuZG9tLnJlbW92ZUV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiByZW1vdmVFdmVudExpc3RlbmVyKGVsLCB0eXBlLCBoYW5kbGVyKSB7XG4gIGlmKHV0aWxpdGllcy5pc0FycmF5KGVsKSl7XG4gICAgdXRpbGl0aWVzLmZvckVhY2goZWwsIGZ1bmN0aW9uKGUpIHtcbiAgICAgIGRvbS5yZW1vdmVFdmVudExpc3RlbmVyKGUsIHR5cGUsIGhhbmRsZXIpO1xuICAgIH0pO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmKHV0aWxpdGllcy5pc0FycmF5KHR5cGUpKXtcbiAgICB1dGlsaXRpZXMuZm9yRWFjaCh0eXBlLCBmdW5jdGlvbih0KSB7XG4gICAgICBkb20ucmVtb3ZlRXZlbnRMaXN0ZW5lcihlbCwgdCwgaGFuZGxlcik7XG4gICAgfSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIpIHtcbiAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGhhbmRsZXIsIGZhbHNlKTtcbiAgfSBlbHNlIGlmIChlbC5kZXRhY2hFdmVudCkge1xuICAgIGVsLmRldGFjaEV2ZW50KFwib25cIiArIHR5cGUsIGhhbmRsZXIpO1xuICB9IGVsc2Uge1xuICAgIGVsW1wib25cIiArIHR5cGVdID0gbnVsbDtcbiAgfVxufTtcblxuZG9tLmRpc3BhdGNoRXZlbnQgPSBmdW5jdGlvbiBkaXNwYXRjaEV2ZW50KGVsLCBldmVudCkge1xuICBpZiAoZWwuZGlzcGF0Y2hFdmVudCkge1xuICAgIGVsLmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICB9IGVsc2Uge1xuICAgIGVsLmZpcmVFdmVudChcIm9uXCIgKyBldmVudC5ldmVudFR5cGUsIGV2ZW50KTtcbiAgfVxufTtcblxuZG9tLmlzRGVzY2VuZGFudCA9IGZ1bmN0aW9uIGlzRGVzY2VuZGFudChwYXJlbnQsIGNoaWxkKSB7XG4gIHZhciBub2RlID0gY2hpbGQucGFyZW50Tm9kZTtcbiAgd2hpbGUgKG5vZGUgIT09IG51bGwpIHtcbiAgICBpZiAobm9kZSA9PT0gcGFyZW50KSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59O1xuXG5kb20uZ2V0VGV4dENvbnRlbnQgPSBmdW5jdGlvbiBnZXRUZXh0Q29udGVudChlbCl7XG4gIHJldHVybiBlbC50ZXh0Q29udGVudCB8fCBlbC50ZXh0O1xufTtcblxuZG9tLnByZXBlbmRDaGlsZCA9IGZ1bmN0aW9uIHByZXBlbmRDaGlsZChwYXJlbnQsIGNoaWxkKSB7XG4gIGlmKGNoaWxkLnBhcmVudE5vZGUpe1xuICAgIGNoaWxkLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoY2hpbGQpO1xuICB9XG4gIHJldHVybiBwYXJlbnQuaW5zZXJ0QmVmb3JlKGNoaWxkLCBwYXJlbnQuZmlyc3RDaGlsZCk7XG59O1xuXG5kb20ucmVtb3ZlID0gZnVuY3Rpb24gcmVtb3ZlTm9kZShub2RlKXtcbiAgaWYobm9kZSAmJiBub2RlLnBhcmVudE5vZGUpe1xuICAgIG5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChub2RlKTtcbiAgfVxufTtcblxuZG9tLmlzRG9tRWxlbWVudCA9IGZ1bmN0aW9uIGlzRG9tRWxlbWVudChvKSB7XG4gIHJldHVybiBvIGluc3RhbmNlb2YgRWxlbWVudDtcbn07XG5cbmRvbS5jbGljayA9IGZ1bmN0aW9uKGVsLCBoYW5kbGVyKSB7XG4gIGRvbS5hZGRFdmVudExpc3RlbmVyKGVsLCAnY2xpY2snLCBoYW5kbGVyKTtcbn07XG5cbmRvbS5vbmNlID0gZnVuY3Rpb24oZWwsIHR5cGUsIGhhbmRsZXIpIHtcbiAgZnVuY3Rpb24gaGFuZGxlcldyYXAoKSB7XG4gICAgaGFuZGxlci5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuICAgIGRvbS5yZW1vdmVFdmVudExpc3RlbmVyKGVsLCB0eXBlLCBoYW5kbGVyV3JhcCk7XG4gIH1cblxuICBkb20uYWRkRXZlbnRMaXN0ZW5lcihlbCwgdHlwZSwgaGFuZGxlcldyYXApO1xufTtcblxuLy9Ob3RlOiB0aGVyZSBpcyBubyBnZXRCb3VuZGluZ0NsaWVudFJlY3Qgb24gaVBhZCBzbyB3ZSBuZWVkIGEgZmFsbGJhY2tcbmRvbS5nZXREaW1lbnNpb24gPSBmdW5jdGlvbiBnZXREaW1lbnNpb24oZWxlbWVudCkge1xuICB2YXIgcmVjdDtcblxuICAvL09uIElFOSBhbmQgYmVsb3cgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IGRvZXMgbm90IHdvcmsgY29uc2lzdGVudGx5XG4gIGlmKCF1dGlsaXRpZXMuaXNPbGRJRSgpICYmIGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KSB7XG4gICAgcmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHdpZHRoOiByZWN0LndpZHRoLFxuICAgICAgaGVpZ2h0OiByZWN0LmhlaWdodFxuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHdpZHRoOiBlbGVtZW50Lm9mZnNldFdpZHRoLFxuICAgIGhlaWdodDogZWxlbWVudC5vZmZzZXRIZWlnaHRcbiAgfTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZG9tOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIHVybFV0aWxzID0gcmVxdWlyZSgnLi91cmxVdGlscycpO1xudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4vdXRpbGl0eUZ1bmN0aW9ucycpO1xuXG5mdW5jdGlvbiBIdHRwUmVxdWVzdEVycm9yKG1lc3NhZ2UpIHtcbiAgdGhpcy5tZXNzYWdlID0gJ0h0dHBSZXF1ZXN0IEVycm9yOiAnICsgKG1lc3NhZ2UgfHwgJycpO1xufVxuSHR0cFJlcXVlc3RFcnJvci5wcm90b3R5cGUgPSBuZXcgRXJyb3IoKTtcbkh0dHBSZXF1ZXN0RXJyb3IucHJvdG90eXBlLm5hbWUgPSBcIkh0dHBSZXF1ZXN0IEVycm9yXCI7XG5cbmZ1bmN0aW9uIEh0dHBSZXF1ZXN0KGNyZWF0ZVhocikge1xuICBpZiAoIXV0aWxpdGllcy5pc0Z1bmN0aW9uKGNyZWF0ZVhocikpIHtcbiAgICB0aHJvdyBuZXcgSHR0cFJlcXVlc3RFcnJvcignTWlzc2luZyBYTUxIdHRwUmVxdWVzdCBmYWN0b3J5IG1ldGhvZCcpO1xuICB9XG5cbiAgdGhpcy5jcmVhdGVYaHIgPSBjcmVhdGVYaHI7XG59XG5cbkh0dHBSZXF1ZXN0LnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAobWV0aG9kLCB1cmwsIGNhbGxiYWNrLCBvcHRpb25zKSB7XG4gIHNhbml0eUNoZWNrKHVybCwgY2FsbGJhY2ssIG9wdGlvbnMpO1xuICB2YXIgdGltZW91dCwgdGltZW91dElkO1xuICB2YXIgeGhyID0gdGhpcy5jcmVhdGVYaHIoKTtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHRpbWVvdXQgPSB1dGlsaXRpZXMuaXNOdW1iZXIob3B0aW9ucy50aW1lb3V0KSA/IG9wdGlvbnMudGltZW91dCA6IDA7XG5cbiAgeGhyLm9wZW4obWV0aG9kLCB1cmxVdGlscy51cmxQYXJ0cyh1cmwpLmhyZWYsIHRydWUpO1xuXG4gIGlmIChvcHRpb25zLmhlYWRlcnMpIHtcbiAgICBzZXRIZWFkZXJzKHhociwgb3B0aW9ucy5oZWFkZXJzKTtcbiAgfVxuXG4gIGlmIChvcHRpb25zLndpdGhDcmVkZW50aWFscykge1xuICAgIHhoci53aXRoQ3JlZGVudGlhbHMgPSB0cnVlO1xuICB9XG5cbiAgeGhyLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc3RhdHVzVGV4dCwgcmVzcG9uc2UsIHN0YXR1cztcblxuICAgIC8qKlxuICAgICAqIFRoZSBvbmx5IHdheSB0byBkbyBhIHNlY3VyZSByZXF1ZXN0IG9uIElFOCBhbmQgSUU5IGlzIHdpdGggdGhlIFhEb21haW5SZXF1ZXN0IG9iamVjdC4gVW5mb3J0dW5hdGVseSwgbWljcm9zb2Z0IGlzXG4gICAgICogc28gbmljZSB0aGF0IGRlY2lkZWQgdGhhdCB0aGUgc3RhdHVzIHByb3BlcnR5IGFuZCB0aGUgJ2dldEFsbFJlc3BvbnNlSGVhZGVycycgbWV0aG9kIHdoZXJlIG5vdCBuZWVkZWQgc28gd2UgaGF2ZSB0b1xuICAgICAqIGZha2UgdGhlbS4gSWYgdGhlIHJlcXVlc3QgZ2V0cyBkb25lIHdpdGggYW4gWERvbWFpblJlcXVlc3QgaW5zdGFuY2UsIHdlIHdpbGwgYXNzdW1lIHRoYXQgdGhlcmUgYXJlIG5vIGhlYWRlcnMgYW5kXG4gICAgICogdGhlIHN0YXR1cyB3aWxsIGFsd2F5cyBiZSAyMDAuIElmIHlvdSBkb24ndCBsaWtlIGl0LCBETyBOT1QgVVNFIEFOQ0lFTlQgQlJPV1NFUlMhISFcbiAgICAgKlxuICAgICAqIEZvciBtb3IgaW5mbyBnbyB0bzogaHR0cHM6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9jYzI4ODA2MCh2PXZzLjg1KS5hc3B4XG4gICAgICovXG4gICAgaWYgKCF4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKSB7XG4gICAgICB4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKCF4aHIuc3RhdHVzKSB7XG4gICAgICB4aHIuc3RhdHVzID0gMjAwO1xuICAgIH1cblxuICAgIGlmICh1dGlsaXRpZXMuaXNEZWZpbmVkKHRpbWVvdXRJZCkpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgdGltZW91dElkID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHN0YXR1c1RleHQgPSB4aHIuc3RhdHVzVGV4dCB8fCAnJztcblxuICAgIC8vIHJlc3BvbnNlVGV4dCBpcyB0aGUgb2xkLXNjaG9vbCB3YXkgb2YgcmV0cmlldmluZyByZXNwb25zZSAoc3VwcG9ydGVkIGJ5IElFOCAmIDkpXG4gICAgLy8gcmVzcG9uc2UvcmVzcG9uc2VUeXBlIHByb3BlcnRpZXMgd2VyZSBpbnRyb2R1Y2VkIGluIFhIUiBMZXZlbDIgc3BlYyAoc3VwcG9ydGVkIGJ5IElFMTApXG4gICAgcmVzcG9uc2UgPSAoJ3Jlc3BvbnNlJyBpbiB4aHIpID8geGhyLnJlc3BvbnNlIDogeGhyLnJlc3BvbnNlVGV4dDtcblxuICAgIC8vIG5vcm1hbGl6ZSBJRTkgYnVnIChodHRwOi8vYnVncy5qcXVlcnkuY29tL3RpY2tldC8xNDUwKVxuICAgIHN0YXR1cyA9IHhoci5zdGF0dXMgPT09IDEyMjMgPyAyMDQgOiB4aHIuc3RhdHVzO1xuXG4gICAgY2FsbGJhY2soXG4gICAgICBzdGF0dXMsXG4gICAgICByZXNwb25zZSxcbiAgICAgIHhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSxcbiAgICAgIHN0YXR1c1RleHQpO1xuICB9O1xuXG4gIHhoci5vbmVycm9yID0gcmVxdWVzdEVycm9yO1xuICB4aHIub25hYm9ydCA9IHJlcXVlc3RFcnJvcjtcblxuICB4aHIuc2VuZCgpO1xuXG4gIGlmICh0aW1lb3V0ID4gMCkge1xuICAgIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgeGhyICYmIHhoci5hYm9ydCgpO1xuICAgIH0sIHRpbWVvdXQpO1xuICB9XG5cbiAgZnVuY3Rpb24gc2FuaXR5Q2hlY2sodXJsLCBjYWxsYmFjaywgb3B0aW9ucykge1xuICAgIGlmICghdXRpbGl0aWVzLmlzU3RyaW5nKHVybCkgfHwgdXRpbGl0aWVzLmlzRW1wdHlTdHJpbmcodXJsKSkge1xuICAgICAgdGhyb3cgbmV3IEh0dHBSZXF1ZXN0RXJyb3IoXCJJbnZhbGlkIHVybCAnXCIgKyB1cmwgKyBcIidcIik7XG4gICAgfVxuXG4gICAgaWYgKCF1dGlsaXRpZXMuaXNGdW5jdGlvbihjYWxsYmFjaykpIHtcbiAgICAgIHRocm93IG5ldyBIdHRwUmVxdWVzdEVycm9yKFwiSW52YWxpZCBoYW5kbGVyICdcIiArIGNhbGxiYWNrICsgXCInIGZvciB0aGUgaHR0cCByZXF1ZXN0XCIpO1xuICAgIH1cblxuICAgIGlmICh1dGlsaXRpZXMuaXNEZWZpbmVkKG9wdGlvbnMpICYmICF1dGlsaXRpZXMuaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgIHRocm93IG5ldyBIdHRwUmVxdWVzdEVycm9yKFwiSW52YWxpZCBvcHRpb25zIG1hcCAnXCIgKyBvcHRpb25zICsgXCInXCIpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNldEhlYWRlcnMoeGhyLCBoZWFkZXJzKSB7XG4gICAgdXRpbGl0aWVzLmZvckVhY2goaGVhZGVycywgZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcbiAgICAgIGlmICh1dGlsaXRpZXMuaXNEZWZpbmVkKHZhbHVlKSkge1xuICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihrZXksIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlcXVlc3RFcnJvcigpIHtcbiAgICBjYWxsYmFjaygtMSwgbnVsbCwgbnVsbCwgJycpO1xuICB9XG59O1xuXG5IdHRwUmVxdWVzdC5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKHVybCwgY2FsbGJhY2ssIG9wdGlvbnMpIHtcbiAgdGhpcy5ydW4oJ0dFVCcsIHVybCwgcHJvY2Vzc1Jlc3BvbnNlLCBvcHRpb25zKTtcblxuICBmdW5jdGlvbiBwcm9jZXNzUmVzcG9uc2Uoc3RhdHVzLCByZXNwb25zZSwgaGVhZGVyc1N0cmluZywgc3RhdHVzVGV4dCkge1xuICAgIGlmIChpc1N1Y2Nlc3Moc3RhdHVzKSkge1xuICAgICAgY2FsbGJhY2sobnVsbCwgcmVzcG9uc2UsIHN0YXR1cywgaGVhZGVyc1N0cmluZywgc3RhdHVzVGV4dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNhbGxiYWNrKG5ldyBIdHRwUmVxdWVzdEVycm9yKHN0YXR1c1RleHQpLCByZXNwb25zZSwgc3RhdHVzLCBoZWFkZXJzU3RyaW5nLCBzdGF0dXNUZXh0KTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpc1N1Y2Nlc3Moc3RhdHVzKSB7XG4gICAgcmV0dXJuIDIwMCA8PSBzdGF0dXMgJiYgc3RhdHVzIDwgMzAwO1xuICB9XG59O1xuXG5mdW5jdGlvbiBjcmVhdGVYaHIoKSB7XG4gIHZhciB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgaWYgKCEoXCJ3aXRoQ3JlZGVudGlhbHNcIiBpbiB4aHIpKSB7XG4gICAgLy8gWERvbWFpblJlcXVlc3QgZm9yIElFLlxuICAgIHhociA9IG5ldyBYRG9tYWluUmVxdWVzdCgpO1xuICB9XG4gIHJldHVybiB4aHI7XG59XG5cbnZhciBodHRwID0gbmV3IEh0dHBSZXF1ZXN0KGNyZWF0ZVhocik7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBodHRwOiBodHRwLFxuICBIdHRwUmVxdWVzdDogSHR0cFJlcXVlc3QsXG4gIEh0dHBSZXF1ZXN0RXJyb3I6IEh0dHBSZXF1ZXN0RXJyb3IsXG4gIGNyZWF0ZVhocjogY3JlYXRlWGhyXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZG9tID0gcmVxdWlyZSgnLi9kb20nKTtcbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxudmFyIHBsYXllclV0aWxzID0ge307XG5cbi8qKlxuICogUmV0dXJucyBhbiBvYmplY3QgdGhhdCBjYXB0dXJlcyB0aGUgcG9ydGlvbnMgb2YgcGxheWVyIHN0YXRlIHJlbGV2YW50IHRvXG4gKiB2aWRlbyBwbGF5YmFjay4gVGhlIHJlc3VsdCBvZiB0aGlzIGZ1bmN0aW9uIGNhbiBiZSBwYXNzZWQgdG9cbiAqIHJlc3RvcmVQbGF5ZXJTbmFwc2hvdCB3aXRoIGEgcGxheWVyIHRvIHJldHVybiB0aGUgcGxheWVyIHRvIHRoZSBzdGF0ZSBpdFxuICogd2FzIGluIHdoZW4gdGhpcyBmdW5jdGlvbiB3YXMgaW52b2tlZC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBwbGF5ZXIgVGhlIHZpZGVvanMgcGxheWVyIG9iamVjdFxuICovXG5wbGF5ZXJVdGlscy5nZXRQbGF5ZXJTbmFwc2hvdCA9IGZ1bmN0aW9uIGdldFBsYXllclNuYXBzaG90KHBsYXllcikge1xuICB2YXIgdGVjaCA9IHBsYXllci5lbCgpLnF1ZXJ5U2VsZWN0b3IoJy52anMtdGVjaCcpO1xuXG4gIHZhciBzbmFwc2hvdCA9IHtcbiAgICBlbmRlZDogcGxheWVyLmVuZGVkKCksXG4gICAgc3JjOiBwbGF5ZXIuY3VycmVudFNyYygpLFxuICAgIGN1cnJlbnRUaW1lOiBwbGF5ZXIuY3VycmVudFRpbWUoKSxcbiAgICB0eXBlOiBwbGF5ZXIuY3VycmVudFR5cGUoKSxcbiAgICBwbGF5aW5nOiAhcGxheWVyLnBhdXNlZCgpLFxuICAgIHN1cHByZXNzZWRUcmFja3M6IGdldFN1cHByZXNzZWRUcmFja3MocGxheWVyKVxuICB9O1xuXG4gIGlmICh0ZWNoKSB7XG4gICAgc25hcHNob3QubmF0aXZlUG9zdGVyID0gdGVjaC5wb3N0ZXI7XG4gICAgc25hcHNob3Quc3R5bGUgPSB0ZWNoLmdldEF0dHJpYnV0ZSgnc3R5bGUnKTtcbiAgfVxuICByZXR1cm4gc25hcHNob3Q7XG5cbiAgLyoqKiogTG9jYWwgRnVuY3Rpb25zICoqKiovXG4gIGZ1bmN0aW9uIGdldFN1cHByZXNzZWRUcmFja3MocGxheWVyKSB7XG4gICAgdmFyIHRyYWNrcyA9IHBsYXllci5yZW1vdGVUZXh0VHJhY2tzID8gcGxheWVyLnJlbW90ZVRleHRUcmFja3MoKSA6IFtdO1xuXG4gICAgaWYgKHRyYWNrcyAmJiB1dGlsaXRpZXMuaXNBcnJheSh0cmFja3MudHJhY2tzXykpIHtcbiAgICAgIHRyYWNrcyA9IHRyYWNrcy50cmFja3NfO1xuICAgIH1cblxuICAgIGlmICghdXRpbGl0aWVzLmlzQXJyYXkodHJhY2tzKSkge1xuICAgICAgdHJhY2tzID0gW107XG4gICAgfVxuXG4gICAgdmFyIHN1cHByZXNzZWRUcmFja3MgPSBbXTtcbiAgICB0cmFja3MuZm9yRWFjaChmdW5jdGlvbiAodHJhY2spIHtcbiAgICAgIHN1cHByZXNzZWRUcmFja3MucHVzaCh7XG4gICAgICAgIHRyYWNrOiB0cmFjayxcbiAgICAgICAgbW9kZTogdHJhY2subW9kZVxuICAgICAgfSk7XG4gICAgICB0cmFjay5tb2RlID0gJ2Rpc2FibGVkJztcbiAgICB9KTtcblxuICAgIHJldHVybiBzdXBwcmVzc2VkVHJhY2tzO1xuICB9XG59O1xuXG4vKipcbiAqIEF0dGVtcHRzIHRvIG1vZGlmeSB0aGUgc3BlY2lmaWVkIHBsYXllciBzbyB0aGF0IGl0cyBzdGF0ZSBpcyBlcXVpdmFsZW50IHRvXG4gKiB0aGUgc3RhdGUgb2YgdGhlIHNuYXBzaG90LlxuICogQHBhcmFtIHtvYmplY3R9IHNuYXBzaG90IC0gdGhlIHBsYXllciBzdGF0ZSB0byBhcHBseVxuICovXG5wbGF5ZXJVdGlscy5yZXN0b3JlUGxheWVyU25hcHNob3QgPSBmdW5jdGlvbiByZXN0b3JlUGxheWVyU25hcHNob3QocGxheWVyLCBzbmFwc2hvdCkge1xuICB2YXIgdGVjaCA9IHBsYXllci5lbCgpLnF1ZXJ5U2VsZWN0b3IoJy52anMtdGVjaCcpO1xuICB2YXIgYXR0ZW1wdHMgPSAyMDsgLy8gdGhlIG51bWJlciBvZiByZW1haW5pbmcgYXR0ZW1wdHMgdG8gcmVzdG9yZSB0aGUgc25hcHNob3RcblxuICBpZiAoc25hcHNob3QubmF0aXZlUG9zdGVyKSB7XG4gICAgdGVjaC5wb3N0ZXIgPSBzbmFwc2hvdC5uYXRpdmVQb3N0ZXI7XG4gIH1cblxuICBpZiAoJ3N0eWxlJyBpbiBzbmFwc2hvdCkge1xuICAgIC8vIG92ZXJ3cml0ZSBhbGwgY3NzIHN0eWxlIHByb3BlcnRpZXMgdG8gcmVzdG9yZSBzdGF0ZSBwcmVjaXNlbHlcbiAgICB0ZWNoLnNldEF0dHJpYnV0ZSgnc3R5bGUnLCBzbmFwc2hvdC5zdHlsZSB8fCAnJyk7XG4gIH1cblxuICBpZiAoaGFzU3JjQ2hhbmdlZChwbGF5ZXIsIHNuYXBzaG90KSkge1xuXG4gICAgLy8gb24gaW9zNywgZmlkZGxpbmcgd2l0aCB0ZXh0VHJhY2tzIHRvbyBlYXJseSB3aWxsIGNhdXNlIHNhZmFyaSB0byBjcmFzaFxuICAgIHBsYXllci5vbmUoJ2NvbnRlbnRsb2FkZWRtZXRhZGF0YScsIHJlc3RvcmVUcmFja3MpO1xuXG4gICAgcGxheWVyLm9uZSgnY2FucGxheScsIHRyeVRvUmVzdW1lKTtcbiAgICBlbnN1cmVDYW5wbGF5RXZ0R2V0c0ZpcmVkKCk7XG5cbiAgICAvLyBpZiB0aGUgc3JjIGNoYW5nZWQgZm9yIGFkIHBsYXliYWNrLCByZXNldCBpdFxuICAgIHBsYXllci5zcmMoe3NyYzogc25hcHNob3Quc3JjLCB0eXBlOiBzbmFwc2hvdC50eXBlfSk7XG5cbiAgICAvLyBzYWZhcmkgcmVxdWlyZXMgYSBjYWxsIHRvIGBsb2FkYCB0byBwaWNrIHVwIGEgY2hhbmdlZCBzb3VyY2VcbiAgICBwbGF5ZXIubG9hZCgpO1xuXG4gIH0gZWxzZSB7XG4gICAgcmVzdG9yZVRyYWNrcygpO1xuXG4gICAgaWYgKHNuYXBzaG90LnBsYXlpbmcpIHtcbiAgICAgIHBsYXllci5wbGF5KCk7XG4gICAgfVxuICB9XG5cbiAgLyoqKiBMb2NhbCBGdW5jdGlvbnMgKioqL1xuXG4gIC8qKlxuICAgKiBTb21ldGltZXMgZmlyZWZveCBkb2VzIG5vdCB0cmlnZ2VyIHRoZSAnY2FucGxheScgZXZ0LlxuICAgKiBUaGlzIGNvZGUgZW5zdXJlIHRoYXQgaXQgYWx3YXlzIGdldHMgdHJpZ2dlcmVkIHRyaWdnZXJlZC5cbiAgICovXG4gIGZ1bmN0aW9uIGVuc3VyZUNhbnBsYXlFdnRHZXRzRmlyZWQoKSB7XG4gICAgdmFyIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICBwbGF5ZXIudHJpZ2dlcignY2FucGxheScpO1xuICAgIH0sIDEwMDApO1xuXG4gICAgcGxheWVyLm9uZSgnY2FucGxheScsIGZ1bmN0aW9uKCl7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgcGxheWVyIG5lZWRzIHRvIGJlIHJlc3RvcmVkIHRvIGl0cyBzdGF0ZVxuICAgKiBiZWZvcmUgYWQgcGxheWJhY2sgYmVnYW4uIFdpdGggYSBjdXN0b20gYWQgZGlzcGxheSBvciBidXJuZWQtaW5cbiAgICogYWRzLCB0aGUgY29udGVudCBwbGF5ZXIgc3RhdGUgaGFzbid0IGJlZW4gbW9kaWZpZWQgYW5kIHNvIG5vXG4gICAqIHJlc3RvcmF0aW9uIGlzIHJlcXVpcmVkXG4gICAqL1xuICBmdW5jdGlvbiBoYXNTcmNDaGFuZ2VkKHBsYXllciwgc25hcHNob3QpIHtcbiAgICBpZiAocGxheWVyLnNyYygpKSB7XG4gICAgICByZXR1cm4gcGxheWVyLnNyYygpICE9PSBzbmFwc2hvdC5zcmM7XG4gICAgfVxuICAgIC8vIHRoZSBwbGF5ZXIgd2FzIGNvbmZpZ3VyZWQgdGhyb3VnaCBzb3VyY2UgZWxlbWVudCBjaGlsZHJlblxuICAgIHJldHVybiBwbGF5ZXIuY3VycmVudFNyYygpICE9PSBzbmFwc2hvdC5zcmM7XG4gIH1cblxuICBmdW5jdGlvbiByZXN0b3JlVHJhY2tzKCkge1xuICAgIHZhciBzdXBwcmVzc2VkVHJhY2tzID0gc25hcHNob3Quc3VwcHJlc3NlZFRyYWNrcztcbiAgICBzdXBwcmVzc2VkVHJhY2tzLmZvckVhY2goZnVuY3Rpb24gKHRyYWNrU25hcHNob3QpIHtcbiAgICAgIHRyYWNrU25hcHNob3QudHJhY2subW9kZSA9IHRyYWNrU25hcHNob3QubW9kZTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmUgaWYgdGhlIHZpZGVvIGVsZW1lbnQgaGFzIGxvYWRlZCBlbm91Z2ggb2YgdGhlIHNuYXBzaG90IHNvdXJjZVxuICAgKiB0byBiZSByZWFkeSB0byBhcHBseSB0aGUgcmVzdCBvZiB0aGUgc3RhdGVcbiAgICovXG4gIGZ1bmN0aW9uIHRyeVRvUmVzdW1lKCkge1xuXG4gICAgLy8gaWYgc29tZSBwZXJpb2Qgb2YgdGhlIHZpZGVvIGlzIHNlZWthYmxlLCByZXN1bWUgcGxheWJhY2tcbiAgICAvLyBvdGhlcndpc2UgZGVsYXkgYSBiaXQgYW5kIHRoZW4gY2hlY2sgYWdhaW4gdW5sZXNzIHdlJ3JlIG91dCBvZiBhdHRlbXB0c1xuXG4gICAgaWYgKCFwbGF5ZXJVdGlscy5pc1JlYWR5VG9SZXN1bWUocGxheWVyKSAmJiBhdHRlbXB0cy0tKSB7XG4gICAgICBzZXRUaW1lb3V0KHRyeVRvUmVzdW1lLCA1MCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmKHBsYXllci5jdXJyZW50VGltZSgpICE9PSBzbmFwc2hvdC5jdXJyZW50VGltZSkge1xuICAgICAgICAgIGlmIChzbmFwc2hvdC5wbGF5aW5nKSB7IC8vIGlmIG5lZWRlZCByZXN0b3JlIHBsYXlpbmcgc3RhdHVzIGFmdGVyIHNlZWsgY29tcGxldGVzXG4gICAgICAgICAgICBwbGF5ZXIub25lKCdzZWVrZWQnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgcGxheWVyLnBsYXkoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBwbGF5ZXIuY3VycmVudFRpbWUoc25hcHNob3QuY3VycmVudFRpbWUpO1xuXG4gICAgICAgIH0gZWxzZSBpZiAoc25hcHNob3QucGxheWluZykge1xuICAgICAgICAgIC8vIGlmIG5lZWRlZCBhbmQgbm8gc2VlayBoYXMgYmVlbiBwZXJmb3JtZWQsIHJlc3RvcmUgcGxheWluZyBzdGF0dXMgaW1tZWRpYXRlbHlcbiAgICAgICAgICBwbGF5ZXIucGxheSgpO1xuICAgICAgICB9XG5cbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdmlkZW9qcy5sb2cud2FybignRmFpbGVkIHRvIHJlc3VtZSB0aGUgY29udGVudCBhZnRlciBhbiBhZHZlcnRpc2VtZW50JywgZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG5wbGF5ZXJVdGlscy5pc1JlYWR5VG9SZXN1bWUgPSBmdW5jdGlvbiAocGxheWVyKSB7XG5cbiAgaWYgKHBsYXllci5yZWFkeVN0YXRlKCkgPiAxKSB7XG4gICAgLy8gc29tZSBicm93c2VycyBhbmQgbWVkaWEgYXJlbid0IFwic2Vla2FibGVcIi5cbiAgICAvLyByZWFkeVN0YXRlIGdyZWF0ZXIgdGhhbiAxIGFsbG93cyBmb3Igc2Vla2luZyB3aXRob3V0IGV4Y2VwdGlvbnNcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChwbGF5ZXIuc2Vla2FibGUoKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gaWYgdGhlIHBsYXllciBkb2Vzbid0IGV4cG9zZSB0aGUgc2Vla2FibGUgdGltZSByYW5nZXMsIHRyeSB0b1xuICAgIC8vIHJlc3VtZSBwbGF5YmFjayBpbW1lZGlhdGVseVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKHBsYXllci5zZWVrYWJsZSgpLmxlbmd0aCA+IDApIHtcbiAgICAvLyBpZiBzb21lIHBlcmlvZCBvZiB0aGUgdmlkZW8gaXMgc2Vla2FibGUsIHJlc3VtZSBwbGF5YmFja1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIHByZXBhcmVzIHRoZSBwbGF5ZXIgdG8gZGlzcGxheSBhZHMuXG4gKiBBZGRpbmcgY29udmVuaWVuY2UgZXZlbnRzIGxpa2UgdGhlICd2YXN0LmZpcnNQbGF5JyB0aGF0IGdldHMgZmlyZWQgd2hlbiB0aGUgdmlkZW8gaXMgZmlyc3QgcGxheWVkXG4gKiBhbmQgYWRzIHRoZSBibGFja1Bvc3RlciB0byB0aGUgcGxheWVyIHRvIHByZXZlbnQgY29udGVudCBmcm9tIGJlaW5nIGRpc3BsYXllZCBiZWZvcmUgdGhlIHByZXJvbGwgYWQuXG4gKlxuICogQHBhcmFtIHBsYXllclxuICovXG5wbGF5ZXJVdGlscy5wcmVwYXJlRm9yQWRzID0gZnVuY3Rpb24gKHBsYXllcikge1xuICB2YXIgYmxhY2tQb3N0ZXIgPSBwbGF5ZXIuYWRkQ2hpbGQoJ2JsYWNrUG9zdGVyJyk7XG4gIHZhciBfZmlyc3RQbGF5ID0gdHJ1ZTtcbiAgdmFyIHZvbHVtZVNuYXBzaG90O1xuXG5cbiAgbW9ua2V5UGF0Y2hQbGF5ZXJBcGkoKTtcblxuICBwbGF5ZXIub24oJ3BsYXknLCB0cnlUb1RyaWdnZXJGaXJzdFBsYXkpO1xuICBwbGF5ZXIub24oJ3Zhc3QucmVzZXQnLCByZXNldEZpcnN0UGxheSk7Ly9FdmVyeSB0aW1lIHdlIGNoYW5nZSB0aGUgc291cmNlcyB3ZSByZXNldCB0aGUgZmlyc3QgcGxheS5cbiAgcGxheWVyLm9uKCd2YXN0LmZpcnN0UGxheScsIHJlc3RvcmVDb250ZW50Vm9sdW1lKTtcbiAgcGxheWVyLm9uKCdlcnJvcicsIGhpZGVCbGFja1Bvc3Rlcik7Ly9JZiB0aGVyZSBpcyBhbiBlcnJvciBpbiB0aGUgcGxheWVyIHdlIHJlbW92ZSB0aGUgYmxhY2twb3N0ZXIgdG8gc2hvdyB0aGUgZXJyIG1zZ1xuICBwbGF5ZXIub24oJ3Zhc3QuYWRTdGFydCcsIGhpZGVCbGFja1Bvc3Rlcik7XG4gIHBsYXllci5vbigndmFzdC5hZHNDYW5jZWwnLCBoaWRlQmxhY2tQb3N0ZXIpO1xuICBwbGF5ZXIub24oJ3Zhc3QuYWRFcnJvcicsIGhpZGVCbGFja1Bvc3Rlcik7XG4gIHBsYXllci5vbigndmFzdC5hZFN0YXJ0JywgYWRkU3R5bGVzKTtcbiAgcGxheWVyLm9uKCd2YXN0LmFkRW5kJywgcmVtb3ZlU3R5bGVzKTtcbiAgcGxheWVyLm9uKCd2YXN0LmFkc0NhbmNlbCcsIHJlbW92ZVN0eWxlcyk7XG5cbiAgLyoqKiBMb2NhbCBGdW5jdGlvbnMgKioqL1xuXG4gIC8qKlxuICAgV2hhdCB0aGlzIGZ1bmN0aW9uIGRvZXMgaXMgdWdseSBhbmQgaG9ycmlibGUgYW5kIEkgc2hvdWxkIHRoaW5rIHR3aWNlIGJlZm9yZSBjYWxsaW5nIG15c2VsZiBhIGdvb2QgZGV2ZWxvcGVyLiBXaXRoIHRoYXQgc2FpZCxcbiAgIGl0IGlzIHRoZSBiZXN0IHNvbHV0aW9uIEkgY291bGQgZmluZCB0byBtdXRlIHRoZSB2aWRlbyB1bnRpbCB0aGUgJ3BsYXknIGV2ZW50IGhhcHBlbnMgKG9uIG1vYmlsZSBkZXZpY2VzKSBhbmQgdGhlIHBsdWdpbiBjYW4gZGVjaWRlIHdoZXRoZXJcbiAgIHRvIHBsYXkgdGhlIGFkIG9yIG5vdC5cblxuICAgV2UgYWxzbyBuZWVkIHRoaXMgbW9ua2V5cGF0Y2ggdG8gYmUgYWJsZSB0byBwYXVzZSBhbmQgcmVzdW1lIGFuIGFkIHVzaW5nIHRoZSBwbGF5ZXIncyBBUElcblxuICAgSWYgeW91IGhhdmUgYSBiZXR0ZXIgc29sdXRpb24gcGxlYXNlIGRvIHRlbGwgbWUuXG4gICAqL1xuICBmdW5jdGlvbiBtb25rZXlQYXRjaFBsYXllckFwaSgpIHtcblxuICAgIC8qKlxuICAgICAqIE1vbmtleSBwYXRjaCBuZWVkZWQgdG8gaGFuZGxlIGZpcnN0UGxheSBhbmQgcmVzdW1lIG9mIHBsYXlpbmcgYWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY2FsbE9yaWdQbGF5IG5lY2Vzc2FyeSBmbGFnIHRvIHByZXZlbnQgaW5maW5pdGUgbG9vcCB3aGVuIHlvdSBhcmUgcmVzdG9yaW5nIGEgVkFTVCBhZC5cbiAgICAgKiBAcmV0dXJucyB7cGxheWVyfVxuICAgICAqL1xuICAgIHZhciBvcmlnUGxheSA9IHBsYXllci5wbGF5O1xuICAgIHBsYXllci5wbGF5ID0gZnVuY3Rpb24gKGNhbGxPcmlnUGxheSkge1xuICAgICAgdmFyIHRoYXQgPSB0aGlzO1xuXG4gICAgICBpZiAoaXNGaXJzdFBsYXkoKSkge1xuICAgICAgICBmaXJzdFBsYXkoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VtZShjYWxsT3JpZ1BsYXkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcblxuICAgICAgLyoqKiBsb2NhbCBmdW5jdGlvbnMgKioqL1xuICAgICAgZnVuY3Rpb24gZmlyc3RQbGF5KCkge1xuICAgICAgICBpZiAoIXV0aWxpdGllcy5pc0lQaG9uZSgpKSB7XG4gICAgICAgICAgdm9sdW1lU25hcHNob3QgPSBzYXZlVm9sdW1lU25hcHNob3QoKTtcbiAgICAgICAgICBwbGF5ZXIubXV0ZWQodHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBvcmlnUGxheS5hcHBseSh0aGF0LCBhcmd1bWVudHMpO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiByZXN1bWUoY2FsbE9yaWdQbGF5KSB7XG4gICAgICAgIGlmIChpc0FkUGxheWluZygpICYmICFjYWxsT3JpZ1BsYXkpIHtcbiAgICAgICAgICBwbGF5ZXIudmFzdC5hZFVuaXQucmVzdW1lQWQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvcmlnUGxheS5hcHBseSh0aGF0LCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuXG4gICAgLyoqXG4gICAgICogTmVlZGVkIG1vbmtleSBwYXRjaCB0byBoYW5kbGUgcGF1c2Ugb2YgcGxheWluZyBhZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBjYWxsT3JpZ1BsYXkgbmVjZXNzYXJ5IGZsYWcgdG8gcHJldmVudCBpbmZpbml0ZSBsb29wIHdoZW4geW91IGFyZSBwYXVzaW5nIGEgVkFTVCBhZC5cbiAgICAgKiBAcmV0dXJucyB7cGxheWVyfVxuICAgICAqL1xuICAgIHZhciBvcmlnUGF1c2UgPSBwbGF5ZXIucGF1c2U7XG4gICAgcGxheWVyLnBhdXNlID0gZnVuY3Rpb24gKGNhbGxPcmlnUGF1c2UpIHtcbiAgICAgIGlmIChpc0FkUGxheWluZygpICYmICFjYWxsT3JpZ1BhdXNlKSB7XG4gICAgICAgIHBsYXllci52YXN0LmFkVW5pdC5wYXVzZUFkKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcmlnUGF1c2UuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cblxuICAgIC8qKlxuICAgICAqIE5lZWRlZCBtb25rZXkgcGF0Y2ggdG8gaGFuZGxlIHBhdXNlZCBzdGF0ZSBvZiB0aGUgcGxheWVyIHdoZW4gYWRzIGFyZSBwbGF5aW5nLlxuICAgICAqXG4gICAgICogQHBhcmFtIGNhbGxPcmlnUGxheSBuZWNlc3NhcnkgZmxhZyB0byBwcmV2ZW50IGluZmluaXRlIGxvb3Agd2hlbiB5b3UgYXJlIHBhdXNpbmcgYSBWQVNUIGFkLlxuICAgICAqIEByZXR1cm5zIHtwbGF5ZXJ9XG4gICAgICovXG4gICAgdmFyIG9yaWdQYXVzZWQgPSBwbGF5ZXIucGF1c2VkO1xuICAgIHBsYXllci5wYXVzZWQgPSBmdW5jdGlvbiAoY2FsbE9yaWdQYXVzZWQpIHtcbiAgICAgIGlmIChpc0FkUGxheWluZygpICYmICFjYWxsT3JpZ1BhdXNlZCkge1xuICAgICAgICByZXR1cm4gcGxheWVyLnZhc3QuYWRVbml0LmlzUGF1c2VkKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gb3JpZ1BhdXNlZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBpc0FkUGxheWluZygpIHtcbiAgICByZXR1cm4gcGxheWVyLnZhc3QgJiYgcGxheWVyLnZhc3QuYWRVbml0O1xuICB9XG5cbiAgZnVuY3Rpb24gdHJ5VG9UcmlnZ2VyRmlyc3RQbGF5KCkge1xuICAgIGlmIChpc0ZpcnN0UGxheSgpKSB7XG4gICAgICBfZmlyc3RQbGF5ID0gZmFsc2U7XG4gICAgICBwbGF5ZXIudHJpZ2dlcigndmFzdC5maXJzdFBsYXknKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZXNldEZpcnN0UGxheSgpIHtcbiAgICBfZmlyc3RQbGF5ID0gdHJ1ZTtcbiAgICBibGFja1Bvc3Rlci5zaG93KCk7XG4gICAgcmVzdG9yZUNvbnRlbnRWb2x1bWUoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzRmlyc3RQbGF5KCkge1xuICAgIHJldHVybiBfZmlyc3RQbGF5O1xuICB9XG5cbiAgZnVuY3Rpb24gc2F2ZVZvbHVtZVNuYXBzaG90KCkge1xuICAgIHJldHVybiB7XG4gICAgICBtdXRlZDogcGxheWVyLm11dGVkKCksXG4gICAgICB2b2x1bWU6IHBsYXllci52b2x1bWUoKVxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiByZXN0b3JlQ29udGVudFZvbHVtZSgpIHtcbiAgICBpZiAodm9sdW1lU25hcHNob3QpIHtcbiAgICAgIHBsYXllci5jdXJyZW50VGltZSgwKTtcbiAgICAgIHJlc3RvcmVWb2x1bWVTbmFwc2hvdCh2b2x1bWVTbmFwc2hvdCk7XG4gICAgICB2b2x1bWVTbmFwc2hvdCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVzdG9yZVZvbHVtZVNuYXBzaG90KHNuYXBzaG90KSB7XG4gICAgaWYgKHV0aWxpdGllcy5pc09iamVjdChzbmFwc2hvdCkpIHtcbiAgICAgIHBsYXllci52b2x1bWUoc25hcHNob3Qudm9sdW1lKTtcbiAgICAgIHBsYXllci5tdXRlZChzbmFwc2hvdC5tdXRlZCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaGlkZUJsYWNrUG9zdGVyKCkge1xuICAgIGlmICghZG9tLmhhc0NsYXNzKGJsYWNrUG9zdGVyLmVsKCksICd2anMtaGlkZGVuJykpIHtcbiAgICAgIGJsYWNrUG9zdGVyLmhpZGUoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBhZGRTdHlsZXMoKSB7XG4gICAgZG9tLmFkZENsYXNzKHBsYXllci5lbCgpLCAndmpzLWFkLXBsYXlpbmcnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbW92ZVN0eWxlcygpIHtcbiAgICBkb20ucmVtb3ZlQ2xhc3MocGxheWVyLmVsKCksICd2anMtYWQtcGxheWluZycpO1xuICB9XG59O1xuXG4vKipcbiAqIFJlbW92ZSB0aGUgcG9zdGVyIGF0dHJpYnV0ZSBmcm9tIHRoZSB2aWRlbyBlbGVtZW50IHRlY2gsIGlmIHByZXNlbnQuIFdoZW5cbiAqIHJldXNpbmcgYSB2aWRlbyBlbGVtZW50IGZvciBtdWx0aXBsZSB2aWRlb3MsIHRoZSBwb3N0ZXIgaW1hZ2Ugd2lsbCBicmllZmx5XG4gKiByZWFwcGVhciB3aGlsZSB0aGUgbmV3IHNvdXJjZSBsb2Fkcy4gUmVtb3ZpbmcgdGhlIGF0dHJpYnV0ZSBhaGVhZCBvZiB0aW1lXG4gKiBwcmV2ZW50cyB0aGUgcG9zdGVyIGZyb20gc2hvd2luZyB1cCBiZXR3ZWVuIHZpZGVvcy5cbiAqIEBwYXJhbSB7b2JqZWN0fSBwbGF5ZXIgVGhlIHZpZGVvanMgcGxheWVyIG9iamVjdFxuICovXG5wbGF5ZXJVdGlscy5yZW1vdmVOYXRpdmVQb3N0ZXIgPSBmdW5jdGlvbiAocGxheWVyKSB7XG4gIHZhciB0ZWNoID0gcGxheWVyLmVsKCkucXVlcnlTZWxlY3RvcignLnZqcy10ZWNoJyk7XG4gIGlmICh0ZWNoKSB7XG4gICAgdGVjaC5yZW1vdmVBdHRyaWJ1dGUoJ3Bvc3RlcicpO1xuICB9XG59O1xuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBsaXN0ZW4gdG8gbWFueSBldmVudHMgdW50aWwgb25lIG9mIHRoZW0gZ2V0cyBmaXJlZCwgdGhlbiB3ZVxuICogZXhlY3V0ZSB0aGUgaGFuZGxlciBhbmQgdW5zdWJzY3JpYmUgYWxsIHRoZSBldmVudCBsaXN0ZW5lcnM7XG4gKlxuICogQHBhcmFtIHBsYXllciBzcGVjaWZpYyBwbGF5ZXIgZnJvbSB3aGVyZSB0byBsaXN0ZW4gZm9yIHRoZSBldmVudHNcbiAqIEBwYXJhbSBldmVudHMgYXJyYXkgb2YgZXZlbnRzXG4gKiBAcGFyYW0gaGFuZGxlciBmdW5jdGlvbiB0byBleGVjdXRlIG9uY2Ugb25lIG9mIHRoZSBldmVudHMgZmlyZXNcbiAqL1xucGxheWVyVXRpbHMub25jZSA9IGZ1bmN0aW9uIG9uY2UocGxheWVyLCBldmVudHMsIGhhbmRsZXIpIHtcbiAgZnVuY3Rpb24gbGlzdGVuZXIoKSB7XG4gICAgaGFuZGxlci5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuXG4gICAgZXZlbnRzLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICBwbGF5ZXIub2ZmKGV2ZW50LCBsaXN0ZW5lcik7XG4gICAgfSk7XG4gIH1cblxuICBldmVudHMuZm9yRWFjaChmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICBwbGF5ZXIub24oZXZlbnQsIGxpc3RlbmVyKTtcbiAgfSk7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gcGxheWVyVXRpbHM7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbi8qKlxuICpcbiAqIElNUE9SVEFOVCBOT1RFOiBUaGlzIGZ1bmN0aW9uIGNvbWVzIGZyb20gYW5ndWxhckpzIGFuZCB3YXMgb3JpZ2luYWxseSBjYWxsZWQgdXJsUmVzb2x2ZVxuICogICAgICAgICAgICAgICAgIHlvdSBjYW4gdGFrZSBhIGxvb2sgYXQgdGhlIG9yaWdpbmFsIGNvZGUgaGVyZSBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyLmpzL2Jsb2IvbWFzdGVyL3NyYy9uZy91cmxVdGlscy5qc1xuICpcbiAqIEltcGxlbWVudGF0aW9uIE5vdGVzIGZvciBub24tSUUgYnJvd3NlcnNcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEFzc2lnbmluZyBhIFVSTCB0byB0aGUgaHJlZiBwcm9wZXJ0eSBvZiBhbiBhbmNob3IgRE9NIG5vZGUsIGV2ZW4gb25lIGF0dGFjaGVkIHRvIHRoZSBET00sXG4gKiByZXN1bHRzIGJvdGggaW4gdGhlIG5vcm1hbGl6aW5nIGFuZCBwYXJzaW5nIG9mIHRoZSBVUkwuICBOb3JtYWxpemluZyBtZWFucyB0aGF0IGEgcmVsYXRpdmVcbiAqIFVSTCB3aWxsIGJlIHJlc29sdmVkIGludG8gYW4gYWJzb2x1dGUgVVJMIGluIHRoZSBjb250ZXh0IG9mIHRoZSBhcHBsaWNhdGlvbiBkb2N1bWVudC5cbiAqIFBhcnNpbmcgbWVhbnMgdGhhdCB0aGUgYW5jaG9yIG5vZGUncyBob3N0LCBob3N0bmFtZSwgcHJvdG9jb2wsIHBvcnQsIHBhdGhuYW1lIGFuZCByZWxhdGVkXG4gKiBwcm9wZXJ0aWVzIGFyZSBhbGwgcG9wdWxhdGVkIHRvIHJlZmxlY3QgdGhlIG5vcm1hbGl6ZWQgVVJMLiAgVGhpcyBhcHByb2FjaCBoYXMgd2lkZVxuICogY29tcGF0aWJpbGl0eSAtIFNhZmFyaSAxKywgTW96aWxsYSAxKywgT3BlcmEgNyssZSBldGMuICBTZWVcbiAqIGh0dHA6Ly93d3cuYXB0YW5hLmNvbS9yZWZlcmVuY2UvaHRtbC9hcGkvSFRNTEFuY2hvckVsZW1lbnQuaHRtbFxuICpcbiAqIEltcGxlbWVudGF0aW9uIE5vdGVzIGZvciBJRVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBJRSA+PSA4IGFuZCA8PSAxMCBub3JtYWxpemVzIHRoZSBVUkwgd2hlbiBhc3NpZ25lZCB0byB0aGUgYW5jaG9yIG5vZGUgc2ltaWxhciB0byB0aGUgb3RoZXJcbiAqIGJyb3dzZXJzLiAgSG93ZXZlciwgdGhlIHBhcnNlZCBjb21wb25lbnRzIHdpbGwgbm90IGJlIHNldCBpZiB0aGUgVVJMIGFzc2lnbmVkIGRpZCBub3Qgc3BlY2lmeVxuICogdGhlbS4gIChlLmcuIGlmIHlvdSBhc3NpZ24gYS5ocmVmID0gXCJmb29cIiwgdGhlbiBhLnByb3RvY29sLCBhLmhvc3QsIGV0Yy4gd2lsbCBiZSBlbXB0eS4pICBXZVxuICogd29yayBhcm91bmQgdGhhdCBieSBwZXJmb3JtaW5nIHRoZSBwYXJzaW5nIGluIGEgMm5kIHN0ZXAgYnkgdGFraW5nIGEgcHJldmlvdXNseSBub3JtYWxpemVkXG4gKiBVUkwgKGUuZy4gYnkgYXNzaWduaW5nIHRvIGEuaHJlZikgYW5kIGFzc2lnbmluZyBpdCBhLmhyZWYgYWdhaW4uICBUaGlzIGNvcnJlY3RseSBwb3B1bGF0ZXMgdGhlXG4gKiBwcm9wZXJ0aWVzIHN1Y2ggYXMgcHJvdG9jb2wsIGhvc3RuYW1lLCBwb3J0LCBldGMuXG4gKlxuICogSUU3IGRvZXMgbm90IG5vcm1hbGl6ZSB0aGUgVVJMIHdoZW4gYXNzaWduZWQgdG8gYW4gYW5jaG9yIG5vZGUuICAoQXBwYXJlbnRseSwgaXQgZG9lcywgaWYgb25lXG4gKiB1c2VzIHRoZSBpbm5lciBIVE1MIGFwcHJvYWNoIHRvIGFzc2lnbiB0aGUgVVJMIGFzIHBhcnQgb2YgYW4gSFRNTCBzbmlwcGV0IC1cbiAqIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzQ3MjcyOSkgIEhvd2V2ZXIsIHNldHRpbmcgaW1nW3NyY10gZG9lcyBub3JtYWxpemUgdGhlIFVSTC5cbiAqIFVuZm9ydHVuYXRlbHksIHNldHRpbmcgaW1nW3NyY10gdG8gc29tZXRoaW5nIGxpa2UgXCJqYXZhc2NyaXB0OmZvb1wiIG9uIElFIHRocm93cyBhbiBleGNlcHRpb24uXG4gKiBTaW5jZSB0aGUgcHJpbWFyeSB1c2FnZSBmb3Igbm9ybWFsaXppbmcgVVJMcyBpcyB0byBzYW5pdGl6ZSBzdWNoIFVSTHMsIHdlIGNhbid0IHVzZSB0aGF0XG4gKiBtZXRob2QgYW5kIElFIDwgOCBpcyB1bnN1cHBvcnRlZC5cbiAqXG4gKiBSZWZlcmVuY2VzOlxuICogICBodHRwOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9IVE1MQW5jaG9yRWxlbWVudFxuICogICBodHRwOi8vd3d3LmFwdGFuYS5jb20vcmVmZXJlbmNlL2h0bWwvYXBpL0hUTUxBbmNob3JFbGVtZW50Lmh0bWxcbiAqICAgaHR0cDovL3VybC5zcGVjLndoYXR3Zy5vcmcvI3VybHV0aWxzXG4gKiAgIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2FuZ3VsYXIuanMvcHVsbC8yOTAyXG4gKiAgIGh0dHA6Ly9qYW1lcy5wYWRvbHNleS5jb20vamF2YXNjcmlwdC9wYXJzaW5nLXVybHMtd2l0aC10aGUtZG9tL1xuICpcbiAqIEBraW5kIGZ1bmN0aW9uXG4gKiBAcGFyYW0ge3N0cmluZ30gdXJsIFRoZSBVUkwgdG8gYmUgcGFyc2VkLlxuICogQGRlc2NyaXB0aW9uIE5vcm1hbGl6ZXMgYW5kIHBhcnNlcyBhIFVSTC5cbiAqIEByZXR1cm5zIHtvYmplY3R9IFJldHVybnMgdGhlIG5vcm1hbGl6ZWQgVVJMIGFzIGEgZGljdGlvbmFyeS5cbiAqXG4gKiAgIHwgbWVtYmVyIG5hbWUgICB8IERlc2NyaXB0aW9uICAgIHxcbiAqICAgfC0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tfFxuICogICB8IGhyZWYgICAgICAgICAgfCBBIG5vcm1hbGl6ZWQgdmVyc2lvbiBvZiB0aGUgcHJvdmlkZWQgVVJMIGlmIGl0IHdhcyBub3QgYW4gYWJzb2x1dGUgVVJMIHxcbiAqICAgfCBwcm90b2NvbCAgICAgIHwgVGhlIHByb3RvY29sIGluY2x1ZGluZyB0aGUgdHJhaWxpbmcgY29sb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgIHwgaG9zdCAgICAgICAgICB8IFRoZSBob3N0IGFuZCBwb3J0IChpZiB0aGUgcG9ydCBpcyBub24tZGVmYXVsdCkgb2YgdGhlIG5vcm1hbGl6ZWRVcmwgICAgfFxuICogICB8IHNlYXJjaCAgICAgICAgfCBUaGUgc2VhcmNoIHBhcmFtcywgbWludXMgdGhlIHF1ZXN0aW9uIG1hcmsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICAgfCBoYXNoICAgICAgICAgIHwgVGhlIGhhc2ggc3RyaW5nLCBtaW51cyB0aGUgaGFzaCBzeW1ib2xcbiAqICAgfCBob3N0bmFtZSAgICAgIHwgVGhlIGhvc3RuYW1lXG4gKiAgIHwgcG9ydCAgICAgICAgICB8IFRoZSBwb3J0LCB3aXRob3V0IFwiOlwiXG4gKiAgIHwgcGF0aG5hbWUgICAgICB8IFRoZSBwYXRobmFtZSwgYmVnaW5uaW5nIHdpdGggXCIvXCJcbiAqXG4gKi9cblxudmFyIHVybFBhcnNpbmdOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImFcIik7XG4vKipcbiAqIGRvY3VtZW50TW9kZSBpcyBhbiBJRS1vbmx5IHByb3BlcnR5XG4gKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaWUvY2MxOTY5ODgodj12cy44NSkuYXNweFxuICovXG52YXIgbXNpZSA9IGRvY3VtZW50LmRvY3VtZW50TW9kZTtcblxuZnVuY3Rpb24gdXJsUGFydHModXJsKSB7XG4gIHZhciBocmVmID0gdXJsO1xuXG4gIGlmIChtc2llKSB7XG4gICAgLy8gTm9ybWFsaXplIGJlZm9yZSBwYXJzZS4gIFJlZmVyIEltcGxlbWVudGF0aW9uIE5vdGVzIG9uIHdoeSB0aGlzIGlzXG4gICAgLy8gZG9uZSBpbiB0d28gc3RlcHMgb24gSUUuXG4gICAgdXJsUGFyc2luZ05vZGUuc2V0QXR0cmlidXRlKFwiaHJlZlwiLCBocmVmKTtcbiAgICBocmVmID0gdXJsUGFyc2luZ05vZGUuaHJlZjtcbiAgfVxuXG4gIHVybFBhcnNpbmdOb2RlLnNldEF0dHJpYnV0ZSgnaHJlZicsIGhyZWYpO1xuXG4gIC8vIHVybFBhcnNpbmdOb2RlIHByb3ZpZGVzIHRoZSBVcmxVdGlscyBpbnRlcmZhY2UgLSBodHRwOi8vdXJsLnNwZWMud2hhdHdnLm9yZy8jdXJsdXRpbHNcbiAgcmV0dXJuIHtcbiAgICBocmVmOiB1cmxQYXJzaW5nTm9kZS5ocmVmLFxuICAgIHByb3RvY29sOiB1cmxQYXJzaW5nTm9kZS5wcm90b2NvbCA/IHVybFBhcnNpbmdOb2RlLnByb3RvY29sLnJlcGxhY2UoLzokLywgJycpIDogJycsXG4gICAgaG9zdDogdXJsUGFyc2luZ05vZGUuaG9zdCxcbiAgICBzZWFyY2g6IHVybFBhcnNpbmdOb2RlLnNlYXJjaCA/IHVybFBhcnNpbmdOb2RlLnNlYXJjaC5yZXBsYWNlKC9eXFw/LywgJycpIDogJycsXG4gICAgaGFzaDogdXJsUGFyc2luZ05vZGUuaGFzaCA/IHVybFBhcnNpbmdOb2RlLmhhc2gucmVwbGFjZSgvXiMvLCAnJykgOiAnJyxcbiAgICBob3N0bmFtZTogdXJsUGFyc2luZ05vZGUuaG9zdG5hbWUsXG4gICAgcG9ydDogdXRpbGl0aWVzLmlzTm90RW1wdHlTdHJpbmcodXJsUGFyc2luZ05vZGUucG9ydCk/IHVybFBhcnNpbmdOb2RlLnBvcnQ6IDgwLFxuICAgIHBhdGhuYW1lOiAodXJsUGFyc2luZ05vZGUucGF0aG5hbWUuY2hhckF0KDApID09PSAnLycpXG4gICAgICA/IHVybFBhcnNpbmdOb2RlLnBhdGhuYW1lXG4gICAgICA6ICcvJyArIHVybFBhcnNpbmdOb2RlLnBhdGhuYW1lXG4gIH07XG59XG5cblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGFjY2VwdHMgYSBxdWVyeSBzdHJpbmcgKHNlYXJjaCBwYXJ0IG9mIGEgdXJsKSBhbmQgcmV0dXJucyBhIGRpY3Rpb25hcnkgd2l0aFxuICogdGhlIGRpZmZlcmVudCBrZXkgdmFsdWUgcGFpcnNcbiAqIEBwYXJhbSB7c3RyaW5nfSBxcyBxdWVyeVN0cmluZ1xuICovXG5mdW5jdGlvbiBxdWVyeVN0cmluZ1RvT2JqKHFzLCBjb25kKSB7XG4gIHZhciBwYWlycywgcXNPYmo7XG5cbiAgY29uZCA9IHV0aWxpdGllcy5pc0Z1bmN0aW9uKGNvbmQpPyBjb25kIDogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgcXMgPSBxcy50cmltKCkucmVwbGFjZSgvXlxcPy8sICcnKTtcbiAgcGFpcnMgPSBxcy5zcGxpdCgnJicpO1xuICBxc09iaiA9IHt9O1xuXG4gIHV0aWxpdGllcy5mb3JFYWNoKHBhaXJzLCBmdW5jdGlvbiAocGFpcikge1xuICAgIHZhciBrZXlWYWx1ZSwga2V5LCB2YWx1ZTtcbiAgICBpZiAocGFpciAhPT0gJycpIHtcbiAgICAgIGtleVZhbHVlID0gcGFpci5zcGxpdCgnPScpO1xuICAgICAga2V5ID0ga2V5VmFsdWVbMF07XG4gICAgICB2YWx1ZSA9IGtleVZhbHVlWzFdO1xuICAgICAgaWYoY29uZChrZXksIHZhbHVlKSl7XG4gICAgICAgIHFzT2JqW2tleV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBxc09iajtcbn1cblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGFjY2VwdHMgYW4gb2JqZWN0IGFuZCBzZXJpYWxpemVzIGl0IGludG8gYSBxdWVyeSBzdHJpbmcgd2l0aG91dCB0aGUgbGVhZGluZyAnPydcbiAqIEBwYXJhbSBvYmpcbiAqIEByZXR1cm5zIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIG9ialRvUXVlcnlTdHJpbmcob2JqKSB7XG4gIHZhciBwYWlycyA9IFtdO1xuICB1dGlsaXRpZXMuZm9yRWFjaChvYmosIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgcGFpcnMucHVzaChrZXkgKyAnPScgKyB2YWx1ZSk7XG4gIH0pO1xuICByZXR1cm4gcGFpcnMuam9pbignJicpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdXJsUGFydHM6IHVybFBhcnRzLFxuICBxdWVyeVN0cmluZ1RvT2JqOiBxdWVyeVN0cmluZ1RvT2JqLFxuICBvYmpUb1F1ZXJ5U3RyaW5nOiBvYmpUb1F1ZXJ5U3RyaW5nXG59O1xuIiwiLypqc2hpbnQgdW51c2VkOmZhbHNlICovXG5cInVzZSBzdHJpY3RcIjtcblxudmFyIE5PREVfVFlQRV9FTEVNRU5UID0gMTtcbnZhciBTTkFLRV9DQVNFX1JFR0VYUCA9IC9bQS1aXS9nO1xudmFyIEVNQUlMX1JFR0VYUCA9IC9eW2EtejAtOSEjJCUmJyorXFwvPT9eX2B7fH1+Li1dK0BbYS16MC05XShbYS16MC05LV0qW2EtejAtOV0pPyhcXC5bYS16MC05XShbYS16MC05LV0qW2EtejAtOV0pPykrJC9pO1xuLypqc2xpbnQgbWF4bGVuOiA1MDAgKi9cbnZhciBJU084MDg2X1JFR0VYUCA9IC9eKFtcXCstXT9cXGR7NH0oPyFcXGR7Mn1cXGIpKSgoLT8pKCgwWzEtOV18MVswLTJdKShcXDMoWzEyXVxcZHwwWzEtOV18M1swMV0pKT98VyhbMC00XVxcZHw1WzAtMl0pKC0/WzEtN10pP3woMDBbMS05XXwwWzEtOV1cXGR8WzEyXVxcZHsyfXwzKFswLTVdXFxkfDZbMS02XSkpKShbVFxcc10oKChbMDFdXFxkfDJbMC0zXSkoKDo/KVswLTVdXFxkKT98MjRcXDo/MDApKFtcXC4sXVxcZCsoPyE6KSk/KT8oXFwxN1swLTVdXFxkKFtcXC4sXVxcZCspPyk/KFt6Wl18KFtcXCstXSkoWzAxXVxcZHwyWzAtM10pOj8oWzAtNV1cXGQpPyk/KT8pPyQvO1xuXG5cbmZ1bmN0aW9uIG5vb3AoKXsgfVxuXG5mdW5jdGlvbiBpc051bGwobykge1xuICByZXR1cm4gbyA9PT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNEZWZpbmVkKG8pe1xuICByZXR1cm4gbyAhPT0gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChvKXtcbiAgcmV0dXJuIG8gPT09IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gaXNPYmplY3Qob2JqKSB7XG4gIHJldHVybiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jztcbn1cblxuZnVuY3Rpb24gaXNGdW5jdGlvbihzdHIpe1xuICByZXR1cm4gdHlwZW9mIHN0ciA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuZnVuY3Rpb24gaXNOdW1iZXIobnVtKXtcbiAgcmV0dXJuIHR5cGVvZiBudW0gPT09ICdudW1iZXInO1xufVxuXG5mdW5jdGlvbiBpc1dpbmRvdyhvYmopIHtcbiAgcmV0dXJuIHV0aWxpdGllcy5pc09iamVjdChvYmopICYmIG9iai53aW5kb3cgPT09IG9iajtcbn1cblxuZnVuY3Rpb24gaXNBcnJheShhcnJheSl7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoIGFycmF5ICkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXlMaWtlKG9iaikge1xuICBpZiAob2JqID09PSBudWxsIHx8IHV0aWxpdGllcy5pc1dpbmRvdyhvYmopIHx8IHV0aWxpdGllcy5pc0Z1bmN0aW9uKG9iaikgfHwgdXRpbGl0aWVzLmlzVW5kZWZpbmVkKG9iaikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgbGVuZ3RoID0gb2JqLmxlbmd0aDtcblxuICBpZiAob2JqLm5vZGVUeXBlID09PSBOT0RFX1RZUEVfRUxFTUVOVCAmJiBsZW5ndGgpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiB1dGlsaXRpZXMuaXNTdHJpbmcob2JqKSB8fCB1dGlsaXRpZXMuaXNBcnJheShvYmopIHx8IGxlbmd0aCA9PT0gMCB8fFxuICAgIHR5cGVvZiBsZW5ndGggPT09ICdudW1iZXInICYmIGxlbmd0aCA+IDAgJiYgKGxlbmd0aCAtIDEpIGluIG9iajtcbn1cblxuZnVuY3Rpb24gaXNTdHJpbmcoc3RyKXtcbiAgcmV0dXJuIHR5cGVvZiBzdHIgPT09ICdzdHJpbmcnO1xufVxuXG5mdW5jdGlvbiBpc0VtcHR5U3RyaW5nKHN0cikge1xuICByZXR1cm4gdXRpbGl0aWVzLmlzU3RyaW5nKHN0cikgJiYgc3RyLmxlbmd0aCA9PT0gMDtcbn1cblxuZnVuY3Rpb24gaXNOb3RFbXB0eVN0cmluZyhzdHIpIHtcbiAgcmV0dXJuIHV0aWxpdGllcy5pc1N0cmluZyhzdHIpICYmIHN0ci5sZW5ndGggIT09IDA7XG59XG5cbmZ1bmN0aW9uIGFycmF5TGlrZU9ialRvQXJyYXkoYXJncykge1xuICByZXR1cm4gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJncyk7XG59XG5cbmZ1bmN0aW9uIGZvckVhY2gob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICB2YXIga2V5LCBsZW5ndGg7XG4gIGlmIChvYmopIHtcbiAgICBpZiAoaXNGdW5jdGlvbihvYmopKSB7XG4gICAgICBmb3IgKGtleSBpbiBvYmopIHtcbiAgICAgICAgLy8gTmVlZCB0byBjaGVjayBpZiBoYXNPd25Qcm9wZXJ0eSBleGlzdHMsXG4gICAgICAgIC8vIGFzIG9uIElFOCB0aGUgcmVzdWx0IG9mIHF1ZXJ5U2VsZWN0b3JBbGwgaXMgYW4gb2JqZWN0IHdpdGhvdXQgYSBoYXNPd25Qcm9wZXJ0eSBmdW5jdGlvblxuICAgICAgICBpZiAoa2V5ICE9PSAncHJvdG90eXBlJyAmJiBrZXkgIT09ICdsZW5ndGgnICYmIGtleSAhPT0gJ25hbWUnICYmICghb2JqLmhhc093blByb3BlcnR5IHx8IG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSkge1xuICAgICAgICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgb2JqW2tleV0sIGtleSwgb2JqKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNBcnJheShvYmopKSB7XG4gICAgICB2YXIgaXNQcmltaXRpdmUgPSB0eXBlb2Ygb2JqICE9PSAnb2JqZWN0JztcbiAgICAgIGZvciAoa2V5ID0gMCwgbGVuZ3RoID0gb2JqLmxlbmd0aDsga2V5IDwgbGVuZ3RoOyBrZXkrKykge1xuICAgICAgICBpZiAoaXNQcmltaXRpdmUgfHwga2V5IGluIG9iaikge1xuICAgICAgICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgb2JqW2tleV0sIGtleSwgb2JqKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAob2JqLmZvckVhY2ggJiYgb2JqLmZvckVhY2ggIT09IGZvckVhY2gpIHtcbiAgICAgIG9iai5mb3JFYWNoKGl0ZXJhdG9yLCBjb250ZXh0LCBvYmopO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGtleSBpbiBvYmopIHtcbiAgICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgaXRlcmF0b3IuY2FsbChjb250ZXh0LCBvYmpba2V5XSwga2V5LCBvYmopO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBvYmo7XG59XG5cbmZ1bmN0aW9uIHNuYWtlX2Nhc2UobmFtZSwgc2VwYXJhdG9yKSB7XG4gIHNlcGFyYXRvciA9IHNlcGFyYXRvciB8fCAnXyc7XG4gIHJldHVybiBuYW1lLnJlcGxhY2UoU05BS0VfQ0FTRV9SRUdFWFAsIGZ1bmN0aW9uKGxldHRlciwgcG9zKSB7XG4gICAgcmV0dXJuIChwb3MgPyBzZXBhcmF0b3IgOiAnJykgKyBsZXR0ZXIudG9Mb3dlckNhc2UoKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGlzVmFsaWRFbWFpbChlbWFpbCl7XG4gIGlmKCF1dGlsaXRpZXMuaXNTdHJpbmcoZW1haWwpKXtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gRU1BSUxfUkVHRVhQLnRlc3QoZW1haWwudHJpbSgpKTtcbn1cblxuZnVuY3Rpb24gZXh0ZW5kIChvYmopIHtcbiAgdmFyIGFyZywgaSwgaztcbiAgZm9yIChpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIGFyZyA9IGFyZ3VtZW50c1tpXTtcbiAgICBmb3IgKGsgaW4gYXJnKSB7XG4gICAgICBpZiAoYXJnLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgIGlmKGlzT2JqZWN0KG9ialtrXSkgJiYgIWlzTnVsbChvYmpba10pICYmIGlzT2JqZWN0KGFyZ1trXSkpe1xuICAgICAgICAgIG9ialtrXSA9IGV4dGVuZCh7fSwgb2JqW2tdLCBhcmdba10pO1xuICAgICAgICB9ZWxzZSB7XG4gICAgICAgICAgb2JqW2tdID0gYXJnW2tdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBvYmo7XG59XG5cbmZ1bmN0aW9uIGNhcGl0YWxpemUocyl7XG4gIHJldHVybiBzLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgcy5zbGljZSgxKTtcbn1cblxuZnVuY3Rpb24gZGVjYXBpdGFsaXplKHMpIHtcbiAgcmV0dXJuIHMuY2hhckF0KDApLnRvTG93ZXJDYXNlKCkgKyBzLnNsaWNlKDEpO1xufVxuXG4vKipcbiAqIFRoaXMgbWV0aG9kIHdvcmtzIHRoZSBzYW1lIHdheSBhcnJheS5wcm90b3R5cGUubWFwIHdvcmtzIGJ1dCBpZiB0aGUgdHJhbnNmb3JtZXIgcmV0dXJucyB1bmRlZmluZSwgdGhlblxuICogaXQgd29uJ3QgYmUgYWRkZWQgdG8gdGhlIHRyYW5zZm9ybWVkIEFycmF5LlxuICovXG5mdW5jdGlvbiB0cmFuc2Zvcm1BcnJheShhcnJheSwgdHJhbnNmb3JtZXIpIHtcbiAgdmFyIHRyYW5zZm9ybWVkQXJyYXkgPSBbXTtcblxuICBhcnJheS5mb3JFYWNoKGZ1bmN0aW9uKGl0ZW0sIGluZGV4KXtcbiAgICB2YXIgdHJhbnNmb3JtZWRJdGVtID0gdHJhbnNmb3JtZXIoaXRlbSwgaW5kZXgpO1xuICAgIGlmKHV0aWxpdGllcy5pc0RlZmluZWQodHJhbnNmb3JtZWRJdGVtKSkge1xuICAgICAgdHJhbnNmb3JtZWRBcnJheS5wdXNoKHRyYW5zZm9ybWVkSXRlbSk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gdHJhbnNmb3JtZWRBcnJheTtcbn1cblxuZnVuY3Rpb24gdG9GaXhlZERpZ2l0cyhudW0sIGRpZ2l0cykge1xuICB2YXIgZm9ybWF0dGVkTnVtID0gbnVtICsgJyc7XG4gIGRpZ2l0cyA9IHV0aWxpdGllcy5pc051bWJlcihkaWdpdHMpID8gZGlnaXRzIDogMDtcbiAgbnVtID0gdXRpbGl0aWVzLmlzTnVtYmVyKG51bSkgPyBudW0gOiBwYXJzZUludChudW0sIDEwKTtcbiAgaWYodXRpbGl0aWVzLmlzTnVtYmVyKG51bSkgJiYgIWlzTmFOKG51bSkpe1xuICAgIGZvcm1hdHRlZE51bSA9IG51bSArICcnO1xuICAgIHdoaWxlKGZvcm1hdHRlZE51bS5sZW5ndGggPCBkaWdpdHMpIHtcbiAgICAgIGZvcm1hdHRlZE51bSA9ICcwJyArIGZvcm1hdHRlZE51bTtcbiAgICB9XG4gICAgcmV0dXJuIGZvcm1hdHRlZE51bTtcbiAgfVxuICByZXR1cm4gTmFOICsgJyc7XG59XG5cbmZ1bmN0aW9uIHRocm90dGxlKGNhbGxiYWNrLCBkZWxheSkge1xuICB2YXIgcHJldmlvdXNDYWxsID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgLSAoZGVsYXkgKyAxKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciB0aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgaWYgKCh0aW1lIC0gcHJldmlvdXNDYWxsKSA+PSBkZWxheSkge1xuICAgICAgcHJldmlvdXNDYWxsID0gdGltZTtcbiAgICAgIGNhbGxiYWNrLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBkZWJvdW5jZSAoY2FsbGJhY2ssIHdhaXQpIHtcbiAgdmFyIHRpbWVvdXRJZDtcblxuICByZXR1cm4gZnVuY3Rpb24gKCl7XG4gICAgaWYodGltZW91dElkKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICB9XG4gICAgdGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbigpe1xuICAgICAgY2FsbGJhY2suYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIHRpbWVvdXRJZCA9IHVuZGVmaW5lZDtcbiAgICB9LCB3YWl0KTtcbiAgfTtcbn1cblxuLy8gYSBmdW5jdGlvbiBkZXNpZ25lZCB0byBibG93IHVwIHRoZSBzdGFjayBpbiBhIG5haXZlIHdheVxuLy8gYnV0IGl0IGlzIG9rIGZvciB2aWRlb0pzIGNoaWxkcmVuIGNvbXBvbmVudHNcbmZ1bmN0aW9uIHRyZWVTZWFyY2gocm9vdCwgZ2V0Q2hpbGRyZW4sIGZvdW5kKXtcbiAgdmFyIGNoaWxkcmVuID0gZ2V0Q2hpbGRyZW4ocm9vdCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspe1xuICAgIGlmIChmb3VuZChjaGlsZHJlbltpXSkpIHtcbiAgICAgIHJldHVybiBjaGlsZHJlbltpXTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB2YXIgZWwgPSB0cmVlU2VhcmNoKGNoaWxkcmVuW2ldLCBnZXRDaGlsZHJlbiwgZm91bmQpO1xuICAgICAgaWYgKGVsKXtcbiAgICAgICAgcmV0dXJuIGVsO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBlY2hvRm4odmFsKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHZhbDtcbiAgfTtcbn1cblxuLy9Ob3RlOiBTdXBwb3J0ZWQgZm9ybWF0cyBjb21lIGZyb20gaHR0cDovL3d3dy53My5vcmcvVFIvTk9URS1kYXRldGltZVxuLy8gYW5kIHRoZSBpc284NjAxIHJlZ2V4IGNvbWVzIGZyb20gaHR0cDovL3d3dy5wZWxhZ29kZXNpZ24uY29tL2Jsb2cvMjAwOS8wNS8yMC9pc28tODYwMS1kYXRlLXZhbGlkYXRpb24tdGhhdC1kb2VzbnQtc3Vjay9cbmZ1bmN0aW9uIGlzSVNPODYwMSh2YWx1ZSkge1xuICBpZih1dGlsaXRpZXMuaXNOdW1iZXIodmFsdWUpKXtcbiAgICB2YWx1ZSA9IHZhbHVlICsgJyc7ICAvL3dlIG1ha2Ugc3VyZSB0aGF0IHdlIGFyZSB3b3JraW5nIHdpdGggc3RyaW5nc1xuICB9XG5cbiAgaWYoIXV0aWxpdGllcy5pc1N0cmluZyh2YWx1ZSkpe1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBJU084MDg2X1JFR0VYUC50ZXN0KHZhbHVlLnRyaW0oKSk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBCcm93c2VyIGlzIElFOSBhbmQgYmVsb3dcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBpc09sZElFKCkge1xuICB2YXIgdmVyc2lvbiA9IHV0aWxpdGllcy5nZXRJbnRlcm5ldEV4cGxvcmVyVmVyc2lvbihuYXZpZ2F0b3IpO1xuICBpZiAodmVyc2lvbiA9PT0gLTEpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdmVyc2lvbiA8IDEwO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHZlcnNpb24gb2YgSW50ZXJuZXQgRXhwbG9yZXIgb3IgYSAtMSAoaW5kaWNhdGluZyB0aGUgdXNlIG9mIGFub3RoZXIgYnJvd3NlcikuXG4gKiBTb3VyY2U6IGh0dHBzOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvbXM1Mzc1MDkodj12cy44NSkuYXNweFxuICogQHJldHVybnMge251bWJlcn0gdGhlIHZlcnNpb24gb2YgSW50ZXJuZXQgRXhwbG9yZXIgb3IgYSAtMSAoaW5kaWNhdGluZyB0aGUgdXNlIG9mIGFub3RoZXIgYnJvd3NlcikuXG4gKi9cbmZ1bmN0aW9uIGdldEludGVybmV0RXhwbG9yZXJWZXJzaW9uKG5hdmlnYXRvcikge1xuICB2YXIgcnYgPSAtMTtcblxuICBpZiAobmF2aWdhdG9yLmFwcE5hbWUgPT0gJ01pY3Jvc29mdCBJbnRlcm5ldCBFeHBsb3JlcicpIHtcbiAgICB2YXIgdWEgPSBuYXZpZ2F0b3IudXNlckFnZW50O1xuICAgIHZhciByZSA9IG5ldyBSZWdFeHAoXCJNU0lFIChbMC05XXsxLH1bXFwuMC05XXswLH0pXCIpO1xuICAgIHZhciByZXMgPSByZS5leGVjKHVhKTtcbiAgICBpZiAocmVzICE9PSBudWxsKSB7XG4gICAgICBydiA9IHBhcnNlRmxvYXQocmVzWzFdKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcnY7XG59XG5cbi8qKiogTW9iaWxlIFV0aWxpdHkgZnVuY3Rpb25zICoqKi9cbmZ1bmN0aW9uIGlzSURldmljZSgpIHtcbiAgcmV0dXJuIC9pUChob25lfGFkKS8udGVzdCh1dGlsaXRpZXMuX1VBKTtcbn1cblxuZnVuY3Rpb24gaXNNb2JpbGUoKSB7XG4gIHJldHVybiAvaVAoaG9uZXxhZHxvZCl8QW5kcm9pZHxXaW5kb3dzIFBob25lLy50ZXN0KHV0aWxpdGllcy5fVUEpO1xufVxuXG5mdW5jdGlvbiBpc0lQaG9uZSgpIHtcbiAgcmV0dXJuIC9pUChob25lfG9kKS8udGVzdCh1dGlsaXRpZXMuX1VBKTtcbn1cblxuZnVuY3Rpb24gaXNBbmRyb2lkKCkge1xuICByZXR1cm4gL0FuZHJvaWQvLnRlc3QodXRpbGl0aWVzLl9VQSk7XG59XG5cbnZhciB1dGlsaXRpZXMgPSB7XG4gIF9VQTogbmF2aWdhdG9yLnVzZXJBZ2VudCxcbiAgbm9vcDogbm9vcCxcbiAgaXNOdWxsOiBpc051bGwsXG4gIGlzRGVmaW5lZDogaXNEZWZpbmVkLFxuICBpc1VuZGVmaW5lZDogaXNVbmRlZmluZWQsXG4gIGlzT2JqZWN0OiBpc09iamVjdCxcbiAgaXNGdW5jdGlvbjogaXNGdW5jdGlvbixcbiAgaXNOdW1iZXI6IGlzTnVtYmVyLFxuICBpc1dpbmRvdzogaXNXaW5kb3csXG4gIGlzQXJyYXk6IGlzQXJyYXksXG4gIGlzQXJyYXlMaWtlOiBpc0FycmF5TGlrZSxcbiAgaXNTdHJpbmc6IGlzU3RyaW5nLFxuICBpc0VtcHR5U3RyaW5nOiBpc0VtcHR5U3RyaW5nLFxuICBpc05vdEVtcHR5U3RyaW5nOiBpc05vdEVtcHR5U3RyaW5nLFxuICBhcnJheUxpa2VPYmpUb0FycmF5OiBhcnJheUxpa2VPYmpUb0FycmF5LFxuICBmb3JFYWNoOiBmb3JFYWNoLFxuICBzbmFrZV9jYXNlOiBzbmFrZV9jYXNlLFxuICBpc1ZhbGlkRW1haWw6IGlzVmFsaWRFbWFpbCxcbiAgZXh0ZW5kOiBleHRlbmQsXG4gIGNhcGl0YWxpemU6IGNhcGl0YWxpemUsXG4gIGRlY2FwaXRhbGl6ZTogZGVjYXBpdGFsaXplLFxuICB0cmFuc2Zvcm1BcnJheTogdHJhbnNmb3JtQXJyYXksXG4gIHRvRml4ZWREaWdpdHM6IHRvRml4ZWREaWdpdHMsXG4gIHRocm90dGxlOiB0aHJvdHRsZSxcbiAgZGVib3VuY2U6IGRlYm91bmNlLFxuICB0cmVlU2VhcmNoOiB0cmVlU2VhcmNoLFxuICBlY2hvRm46IGVjaG9GbixcbiAgaXNJU084NjAxOiBpc0lTTzg2MDEsXG4gIGlzT2xkSUU6IGlzT2xkSUUsXG4gIGdldEludGVybmV0RXhwbG9yZXJWZXJzaW9uOiBnZXRJbnRlcm5ldEV4cGxvcmVyVmVyc2lvbixcbiAgaXNJRGV2aWNlOiBpc0lEZXZpY2UsXG4gIGlzTW9iaWxlOiBpc01vYmlsZSxcbiAgaXNJUGhvbmU6IGlzSVBob25lLFxuICBpc0FuZHJvaWQ6IGlzQW5kcm9pZFxufTtcblxubW9kdWxlLmV4cG9ydHMgPSB1dGlsaXRpZXM7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbnZhciB4bWwgPSB7fTtcblxueG1sLnN0clRvWE1MRG9jID0gZnVuY3Rpb24gc3RyVG9YTUxEb2Moc3RyaW5nQ29udGFpbmluZ1hNTFNvdXJjZSl7XG4gIC8vSUUgOFxuICBpZih0eXBlb2Ygd2luZG93LkRPTVBhcnNlciA9PT0gJ3VuZGVmaW5lZCcpe1xuICAgIHZhciB4bWxEb2N1bWVudCA9IG5ldyBBY3RpdmVYT2JqZWN0KCdNaWNyb3NvZnQuWE1MRE9NJyk7XG4gICAgeG1sRG9jdW1lbnQuYXN5bmMgPSBmYWxzZTtcbiAgICB4bWxEb2N1bWVudC5sb2FkWE1MKHN0cmluZ0NvbnRhaW5pbmdYTUxTb3VyY2UpO1xuICAgIHJldHVybiB4bWxEb2N1bWVudDtcbiAgfVxuXG4gIHJldHVybiBwYXJzZVN0cmluZyhzdHJpbmdDb250YWluaW5nWE1MU291cmNlKTtcblxuICBmdW5jdGlvbiBwYXJzZVN0cmluZyhzdHJpbmdDb250YWluaW5nWE1MU291cmNlKXtcbiAgICB2YXIgcGFyc2VyID0gbmV3IERPTVBhcnNlcigpO1xuICAgIHZhciBwYXJzZWREb2N1bWVudDtcblxuICAgIC8vTm90ZTogVGhpcyB0cnkgY2F0Y2ggaXMgdG8gZGVhbCB3aXRoIHRoZSBmYWN0IHRoYXQgb24gSUUgcGFyc2VyLnBhcnNlRnJvbVN0cmluZyBkb2VzIHRocm93IGFuIGVycm9yIGJ1dCB0aGUgcmVzdCBvZiB0aGUgYnJvd3NlcnMgZG9uJ3QuXG4gICAgdHJ5IHtcbiAgICAgIHBhcnNlZERvY3VtZW50ID0gcGFyc2VyLnBhcnNlRnJvbVN0cmluZyhzdHJpbmdDb250YWluaW5nWE1MU291cmNlLCBcImFwcGxpY2F0aW9uL3htbFwiKTtcblxuICAgICAgaWYoaXNQYXJzZUVycm9yKHBhcnNlZERvY3VtZW50KSB8fCB1dGlsaXRpZXMuaXNFbXB0eVN0cmluZyhzdHJpbmdDb250YWluaW5nWE1MU291cmNlKSl7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgfVxuICAgIH1jYXRjaChlKXtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcInhtbC5zdHJUb1hNTERPQzogRXJyb3IgcGFyc2luZyB0aGUgc3RyaW5nOiAnXCIgKyBzdHJpbmdDb250YWluaW5nWE1MU291cmNlICsgXCInXCIpO1xuICAgIH1cblxuICAgIHJldHVybiBwYXJzZWREb2N1bWVudDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzUGFyc2VFcnJvcihwYXJzZWREb2N1bWVudCkge1xuICAgIHRyeSB7IC8vIHBhcnNlciBhbmQgcGFyc2VyZXJyb3JOUyBjb3VsZCBiZSBjYWNoZWQgb24gc3RhcnR1cCBmb3IgZWZmaWNpZW5jeVxuICAgICAgdmFyIHBhcnNlciA9IG5ldyBET01QYXJzZXIoKSxcbiAgICAgICAgZXJyb25lb3VzUGFyc2UgPSBwYXJzZXIucGFyc2VGcm9tU3RyaW5nKCdJTlZBTElEJywgJ3RleHQveG1sJyksXG4gICAgICAgIHBhcnNlcmVycm9yTlMgPSBlcnJvbmVvdXNQYXJzZS5nZXRFbGVtZW50c0J5VGFnTmFtZShcInBhcnNlcmVycm9yXCIpWzBdLm5hbWVzcGFjZVVSSTtcblxuICAgICAgaWYgKHBhcnNlcmVycm9yTlMgPT09ICdodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sJykge1xuICAgICAgICAvLyBJbiBQaGFudG9tSlMgdGhlIHBhcnNlZXJyb3IgZWxlbWVudCBkb2Vzbid0IHNlZW0gdG8gaGF2ZSBhIHNwZWNpYWwgbmFtZXNwYWNlLCBzbyB3ZSBhcmUganVzdCBndWVzc2luZyBoZXJlIDooXG4gICAgICAgIHJldHVybiBwYXJzZWREb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcInBhcnNlcmVycm9yXCIpLmxlbmd0aCA+IDA7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYXJzZWREb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKHBhcnNlcmVycm9yTlMsICdwYXJzZXJlcnJvcicpLmxlbmd0aCA+IDA7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy9Ob3RlIG9uIElFIHBhcnNlU3RyaW5nIHRocm93cyBhbiBlcnJvciBieSBpdHNlbGYgYW5kIGl0IHdpbGwgbmV2ZXIgcmVhY2ggdGhpcyBjb2RlLiBCZWNhdXNlIGl0IHdpbGwgaGF2ZSBmYWlsZWQgYmVmb3JlXG4gICAgfVxuICB9XG59O1xuXG54bWwucGFyc2VUZXh0ID0gZnVuY3Rpb24gcGFyc2VUZXh0IChzVmFsdWUpIHtcbiAgaWYgKC9eXFxzKiQvLnRlc3Qoc1ZhbHVlKSkgeyByZXR1cm4gbnVsbDsgfVxuICBpZiAoL14oPzp0cnVlfGZhbHNlKSQvaS50ZXN0KHNWYWx1ZSkpIHsgcmV0dXJuIHNWYWx1ZS50b0xvd2VyQ2FzZSgpID09PSBcInRydWVcIjsgfVxuICBpZiAoaXNGaW5pdGUoc1ZhbHVlKSkgeyByZXR1cm4gcGFyc2VGbG9hdChzVmFsdWUpOyB9XG4gIGlmICh1dGlsaXRpZXMuaXNJU084NjAxKHNWYWx1ZSkpIHsgcmV0dXJuIG5ldyBEYXRlKHNWYWx1ZSk7IH1cbiAgcmV0dXJuIHNWYWx1ZS50cmltKCk7XG59O1xuXG54bWwuSlhPTlRyZWUgPSBmdW5jdGlvbiBKWE9OVHJlZSAob1hNTFBhcmVudCkge1xuICB2YXIgcGFyc2VUZXh0ID0geG1sLnBhcnNlVGV4dDtcblxuICAvL1RoZSBkb2N1bWVudCBvYmplY3QgaXMgYW4gZXNwZWNpYWwgb2JqZWN0IHRoYXQgaXQgbWF5IG1pc3Mgc29tZSBmdW5jdGlvbnMgb3IgYXR0cnMgZGVwZW5kaW5nIG9uIHRoZSBicm93c2VyLlxuICAvL1RvIHByZXZlbnQgdGhpcyBwcm9ibGVtIHdpdGggY3JlYXRlIHRoZSBKWE9OVHJlZSB1c2luZyB0aGUgcm9vdCBjaGlsZE5vZGUgd2hpY2ggaXMgYSBmdWxseSBmbGVzaGVkIG5vZGUgb24gYWxsIHN1cHBvcnRlZFxuICAvL2Jyb3dzZXJzLlxuICBpZihvWE1MUGFyZW50LmRvY3VtZW50RWxlbWVudCl7XG4gICAgcmV0dXJuIG5ldyB4bWwuSlhPTlRyZWUob1hNTFBhcmVudC5kb2N1bWVudEVsZW1lbnQpO1xuICB9XG5cbiAgaWYgKG9YTUxQYXJlbnQuaGFzQ2hpbGROb2RlcygpKSB7XG4gICAgdmFyIHNDb2xsZWN0ZWRUeHQgPSBcIlwiO1xuICAgIGZvciAodmFyIG9Ob2RlLCBzUHJvcCwgdkNvbnRlbnQsIG5JdGVtID0gMDsgbkl0ZW0gPCBvWE1MUGFyZW50LmNoaWxkTm9kZXMubGVuZ3RoOyBuSXRlbSsrKSB7XG4gICAgICBvTm9kZSA9IG9YTUxQYXJlbnQuY2hpbGROb2Rlcy5pdGVtKG5JdGVtKTtcbiAgICAgIC8qanNoaW50IGJpdHdpc2U6IGZhbHNlKi9cbiAgICAgIGlmICgob05vZGUubm9kZVR5cGUgLSAxIHwgMSkgPT09IDMpIHsgc0NvbGxlY3RlZFR4dCArPSBvTm9kZS5ub2RlVHlwZSA9PT0gMyA/IG9Ob2RlLm5vZGVWYWx1ZS50cmltKCkgOiBvTm9kZS5ub2RlVmFsdWU7IH1cbiAgICAgIGVsc2UgaWYgKG9Ob2RlLm5vZGVUeXBlID09PSAxICYmICFvTm9kZS5wcmVmaXgpIHtcbiAgICAgICAgc1Byb3AgPSB1dGlsaXRpZXMuZGVjYXBpdGFsaXplKG9Ob2RlLm5vZGVOYW1lKTtcbiAgICAgICAgdkNvbnRlbnQgPSBuZXcgeG1sLkpYT05UcmVlKG9Ob2RlKTtcbiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoc1Byb3ApKSB7XG4gICAgICAgICAgaWYgKHRoaXNbc1Byb3BdLmNvbnN0cnVjdG9yICE9PSBBcnJheSkgeyB0aGlzW3NQcm9wXSA9IFt0aGlzW3NQcm9wXV07IH1cbiAgICAgICAgICB0aGlzW3NQcm9wXS5wdXNoKHZDb250ZW50KTtcbiAgICAgICAgfSBlbHNlIHsgdGhpc1tzUHJvcF0gPSB2Q29udGVudDsgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc0NvbGxlY3RlZFR4dCkgeyB0aGlzLmtleVZhbHVlID0gcGFyc2VUZXh0KHNDb2xsZWN0ZWRUeHQpOyB9XG4gIH1cblxuICAvL0lFOCBTdHVwaWQgZml4XG4gIHZhciBoYXNBdHRyID0gdHlwZW9mIG9YTUxQYXJlbnQuaGFzQXR0cmlidXRlcyA9PT0gJ3VuZGVmaW5lZCc/IG9YTUxQYXJlbnQuYXR0cmlidXRlcy5sZW5ndGggPiAwOiBvWE1MUGFyZW50Lmhhc0F0dHJpYnV0ZXMoKTtcbiAgaWYgKGhhc0F0dHIpIHtcbiAgICB2YXIgb0F0dHJpYjtcbiAgICBmb3IgKHZhciBuQXR0cmliID0gMDsgbkF0dHJpYiA8IG9YTUxQYXJlbnQuYXR0cmlidXRlcy5sZW5ndGg7IG5BdHRyaWIrKykge1xuICAgICAgb0F0dHJpYiA9IG9YTUxQYXJlbnQuYXR0cmlidXRlcy5pdGVtKG5BdHRyaWIpO1xuICAgICAgdGhpc1tcIkBcIiArIHV0aWxpdGllcy5kZWNhcGl0YWxpemUob0F0dHJpYi5uYW1lKV0gPSBwYXJzZVRleHQob0F0dHJpYi52YWx1ZS50cmltKCkpO1xuICAgIH1cbiAgfVxufTtcblxueG1sLkpYT05UcmVlLnByb3RvdHlwZS5hdHRyID0gZnVuY3Rpb24oYXR0cikge1xuICByZXR1cm4gdGhpc1snQCcgKyB1dGlsaXRpZXMuZGVjYXBpdGFsaXplKGF0dHIpXTtcbn07XG5cbnhtbC50b0pYT05UcmVlID0gZnVuY3Rpb24gdG9KWE9OVHJlZSh4bWxTdHJpbmcpe1xuICB2YXIgeG1sRG9jID0geG1sLnN0clRvWE1MRG9jKHhtbFN0cmluZyk7XG4gIHJldHVybiBuZXcgeG1sLkpYT05UcmVlKHhtbERvYyk7XG59O1xuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBleHRyYWN0IHRoZSBrZXl2YWx1ZSBvZiBhIEpYT05UcmVlIG9ialxuICpcbiAqIEBwYXJhbSB4bWxPYmoge0pYT05UcmVlfVxuICogcmV0dXJuIHRoZSBrZXkgdmFsdWUgb3IgdW5kZWZpbmVkO1xuICovXG54bWwua2V5VmFsdWUgPSBmdW5jdGlvbiBnZXRLZXlWYWx1ZSh4bWxPYmopIHtcbiAgaWYoeG1sT2JqKXtcbiAgICByZXR1cm4geG1sT2JqLmtleVZhbHVlO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59O1xuXG54bWwuYXR0ciA9IGZ1bmN0aW9uIGdldEF0dHJWYWx1ZSh4bWxPYmosIGF0dHIpIHtcbiAgaWYoeG1sT2JqKSB7XG4gICAgcmV0dXJuIHhtbE9ialsnQCcgKyB1dGlsaXRpZXMuZGVjYXBpdGFsaXplKGF0dHIpXTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufTtcblxueG1sLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZVhNTChzdHIpIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC8mL2csICcmYW1wOycpXG4gICAgLnJlcGxhY2UoLzwvZywgJyZsdDsnKVxuICAgIC5yZXBsYWNlKC8+L2csICcmZ3Q7JylcbiAgICAucmVwbGFjZSgvXCIvZywgJyZxdW90OycpXG4gICAgLnJlcGxhY2UoLycvZywgJyZhcG9zOycpO1xufTtcblxueG1sLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZVhNTChzdHIpIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC8mYXBvczsvZywgXCInXCIpXG4gICAgLnJlcGxhY2UoLyZxdW90Oy9nLCAnXCInKVxuICAgIC5yZXBsYWNlKC8mZ3Q7L2csICc+JylcbiAgICAucmVwbGFjZSgvJmx0Oy9nLCAnPCcpXG4gICAgLnJlcGxhY2UoLyZhbXA7L2csICcmJyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHhtbDsiLCIndXNlIHN0cmljdCc7XG5cbnJlcXVpcmUoJy4vcGx1Z2luL2NvbXBvbmVudHMvYWRzLWxhYmVsXzQnKTtcbnJlcXVpcmUoJy4vcGx1Z2luL2NvbXBvbmVudHMvYmxhY2stcG9zdGVyXzQnKTtcblxudmFyIHZpZGVvSnNWQVNUID0gcmVxdWlyZSgnLi9wbHVnaW4vdmlkZW9qcy52YXN0LnZwYWlkJyk7XG5cbnZpZGVvanMucGx1Z2luKCd2YXN0Q2xpZW50JywgdmlkZW9Kc1ZBU1QpO1xuXG4iXX0= diff --git a/bin/videojs_4.vast.vpaid.min.js b/bin/videojs_4.vast.vpaid.min.js index 357400d2..5469e37e 100644 --- a/bin/videojs_4.vast.vpaid.min.js +++ b/bin/videojs_4.vast.vpaid.min.js @@ -1,5 +1,4 @@ -(function t(e,n,i){function r(s,o){if(!n[s]){if(!e[s]){var u=typeof require=="function"&&require;if(!o&&u)return u(s,!0);if(a)return a(s,!0);var l=new Error("Cannot find module '"+s+"'");throw l.code="MODULE_NOT_FOUND",l}var c=n[s]={exports:{}};e[s][0].call(c.exports,function(t){var n=e[s][1][t];return r(n?n:t)},c,c.exports,t,e,n,i)}return n[s].exports}var a=typeof require=="function"&&require;for(var s=0;s0){i(e)}},0)}})}},{key:"_callCallback",value:function k(t,e,n,i){var r=this._callbacks.get(e);if(!r){if(n&&e===""){this.trigger(f,n)}return}p.call(this,e,n,i)}},{key:"_handShake",value:function _(t,e){this._ready=true;if(this._handShakeHandler){this._handShakeHandler(t,e);delete this._handShakeHandler}}},{key:"getSize",value:function w(){return{width:this._width,height:this._height}}},{key:"setSize",value:function b(t,e){this._width=s(t,this._width);this._height=s(e,this._height);this._el.setAttribute("width",this._width);this._el.setAttribute("height",this._height)}},{key:"getWidth",value:function E(){return this._width}},{key:"setWidth",value:function T(t){this.setSize(t,this._height)}},{key:"getHeight",value:function S(){return this._height}},{key:"setHeight",value:function V(t){this.setSize(this._width,t)}},{key:"getFlashID",value:function C(){return this._flashID}},{key:"getFlashURL",value:function I(){return this._flashURL}},{key:"isReady",value:function F(){return this._ready}},{key:"destroy",value:function L(){this.offAll();this.removeAllCallbacks();c.removeInstanceByID(this._flashID);if(this._el.parentElement){this._el.parentElement.removeChild(this._el)}}}]);return t}();function p(t,e,n){var i=this;setTimeout(function(){var r=i._callbacks.get(t);if(r){i._callbacks.remove(t);r(e,n)}},0)}Object.defineProperty(h,"VPAID_FLASH_HANDLER",{writable:false,configurable:false,value:d});window[d]=function(t,e,n,i,r,a){var s=c.getInstanceByID(t);if(!s)return;if(n==="handShake"){s._handShake(r,a)}else{if(e!=="event"){s._callCallback(n,i,r,a)}else{s._trigger(n,a)}}}},{"./jsFlashBridgeRegistry":6,"./registry":7,"./utils":8}],6:[function(t,e,n){"use strict";var i=t("./registry").SingleValueRegistry;var r=new i;var a={};Object.defineProperty(a,"addInstance",{writable:false,configurable:false,value:function s(t,e){r.add(t,e)}});Object.defineProperty(a,"getInstanceByID",{writable:false,configurable:false,value:function o(t){return r.get(t)}});Object.defineProperty(a,"removeInstanceByID",{writable:false,configurable:false,value:function u(t){return r.remove(t)}});e.exports=a},{"./registry":7}],7:[function(t,e,n){"use strict";var i=function(){function t(t,e){for(var n=0;n0?t:e}var u=function(){if(String.prototype.endsWith)return String.prototype.endsWith;return function t(e,n){var i=this.toString();if(n===undefined||n>i.length){n=i.length}n-=e.length;var r=i.indexOf(e,n);return r!==-1&&r===n}}();function l(t,e){return u.call(t,e)}function c(t){t.style.position="absolute";t.style.left="-1px";t.style.top="-1px";t.style.width="1px";t.style.height="1px"}},{}],9:[function(t,e,n){"use strict";var i=["handshakeVersion","initAd","startAd","stopAd","skipAd","resizeAd","pauseAd","resumeAd","expandAd","collapseAd","subscribe","unsubscribe"];var r=["AdLoaded","AdStarted","AdStopped","AdSkipped","AdSkippableStateChange","AdSizeChange","AdLinearChange","AdDurationChange","AdExpandedChange","AdRemainingTimeChange","AdVolumeChange","AdImpression","AdVideoStart","AdVideoFirstQuartile","AdVideoMidpoint","AdVideoThirdQuartile","AdVideoComplete","AdClickThru","AdInteraction","AdUserAcceptInvitation","AdUserMinimize","AdUserClose","AdPaused","AdPlaying","AdLog","AdError"];var a=["getAdLinear","getAdWidth","getAdHeight","getAdExpanded","getAdSkippableState","getAdRemainingTime","getAdDuration","getAdVolume","getAdCompanions","getAdIcons"];var s=["setAdVolume"];function o(t,e,n){}o.prototype.handshakeVersion=function(t,e){};o.prototype.initAd=function(t,e,n,i,r,a,s){};o.prototype.startAd=function(t){};o.prototype.stopAd=function(t){};o.prototype.skipAd=function(t){};o.prototype.resizeAd=function(t,e,n,i){};o.prototype.pauseAd=function(t){};o.prototype.resumeAd=function(t){};o.prototype.expandAd=function(t){};o.prototype.collapseAd=function(t){};o.prototype.subscribe=function(t,e,n){};o.prototype.unsubscribe=function(t,e){};o.prototype.getAdLinear=function(t){};o.prototype.getAdWidth=function(t){};o.prototype.getAdHeight=function(t){};o.prototype.getAdExpanded=function(t){};o.prototype.getAdSkippableState=function(t){};o.prototype.getAdRemainingTime=function(t){};o.prototype.getAdDuration=function(t){};o.prototype.getAdVolume=function(t){};o.prototype.getAdCompanions=function(t){};o.prototype.getAdIcons=function(t){};o.prototype.setAdVolume=function(t,e){};l(o,"METHODS",i);l(o,"GETTERS",a);l(o,"SETTERS",s);l(o,"EVENTS",r);var u=i.filter(function(t){return["skipAd"].indexOf(t)===-1});l(o,"checkVPAIDInterface",function c(t){var e=u.every(function(e){return typeof t[e]==="function"});return e});e.exports=o;function l(t,e,n){Object.defineProperty(t,e,{writable:false,configurable:false,value:n})}},{}],10:[function(t,e,n){"use strict";var i=t("./IVPAIDAdUnit");var r=t("./subscriber");var a=i.checkVPAIDInterface;var s=t("./utils");var o=i.METHODS;var u="AdError";var l="AdClickThru";var c=i.EVENTS.filter(function(t){return t!=l});function d(t,e,n,i){this._isValid=a(t);if(this._isValid){this._creative=t;this._el=e;this._videoEl=n;this._iframe=i;this._subscribers=new r;f.call(this)}}d.prototype=Object.create(i.prototype);d.prototype.isValidVPAIDAd=function g(){return this._isValid};i.METHODS.forEach(function(t){var e=["subscribe","unsubscribe","initAd"];if(e.indexOf(t)!==-1)return;d.prototype[t]=function(){var e=i.prototype[t].length;var n=Array.prototype.slice.call(arguments);var r=e===n.length?n.pop():undefined;setTimeout(function(){var e,i=null;try{e=this._creative[t].apply(this._creative,n)}catch(a){i=a}v(r,this._subscribers,i,e)}.bind(this),0)}});d.prototype.initAd=function y(t,e,n,i,r,a,o){r=r||{};a=s.extend({slot:this._el,videoSlot:this._videoEl},a||{});setTimeout(function(){var s;try{this._creative.initAd(t,e,n,i,r,a)}catch(u){s=u}v(o,this._subscribers,s)}.bind(this),0)};d.prototype.subscribe=function m(t,e,n){this._subscribers.subscribe(e,t,n)};d.prototype.unsubscribe=function A(t,e){this._subscribers.unsubscribe(e,t)};d.prototype.on=d.prototype.subscribe;d.prototype.off=d.prototype.unsubscribe;i.GETTERS.forEach(function(t){d.prototype[t]=function(e){setTimeout(function(){var n,i=null;try{n=this._creative[t]()}catch(r){i=r}v(e,this._subscribers,i,n)}.bind(this),0)}});d.prototype.setAdVolume=function k(t,e){setTimeout(function(){var n,i=null;try{this._creative.setAdVolume(t);n=this._creative.getAdVolume()}catch(r){i=r}if(!i){i=s.validate(n===t,"failed to apply volume: "+t)}v(e,this._subscribers,i,n)}.bind(this),0)};d.prototype._destroy=function _(){this.stopAd();this._subscribers.unsubscribeAll()};function f(){c.forEach(function(t){this._creative.subscribe(p.bind(this,t),t)}.bind(this));this._creative.subscribe(h.bind(this),l);if(this._videoEl){var t=this._iframe.contentDocument.documentElement;var e=this._videoEl;t.addEventListener("click",function(n){if(n.target===t){e.click()}})}}function h(t,e,n){this._subscribers.triggerSync(l,{url:t,id:e,playerHandles:n})}function p(t){this._subscribers.trigger(t,Array.prototype.slice(arguments,1))}function v(t,e,n,i){if(t){t(n,i)}else if(n){e.trigger(u,n)}}e.exports=d},{"./IVPAIDAdUnit":9,"./subscriber":12,"./utils":13}],11:[function(t,e,n){"use strict";var i=t("./utils");var r=i.unique("vpaidIframe");var a=t("./VPAIDAdUnit");var s=""+''+''+'
'+''+'"+""+"";var o="AdStopped";function u(t,e,n,a){n=n||{};this._id=r();this._destroyed=false;this._frameContainer=i.createElementInEl(t,"div");this._videoEl=e;this._vpaidOptions=a||{timeout:1e4};this._templateConfig={template:n.template||s,extraOptions:n.extraOptions||{}}}u.prototype.destroy=function y(){if(this._destroyed){return}this._destroyed=true;d.call(this)};u.prototype.isDestroyed=function m(){return this._destroyed};u.prototype.loadAdUnit=function A(t,e){v.call(this);d.call(this);var n=this;var r=i.createIframeWithContent(this._frameContainer,this._templateConfig.template,i.extend({iframeURL_JS:t,iframeID:this.getID(),origin:g()},this._templateConfig.extraOptions));this._frame=r;this._onLoad=i.callbackTimeout(this._vpaidOptions.timeout,s.bind(this),u.bind(this));window.addEventListener("message",this._onLoad);function s(t){if(t.origin!==g())return;var r=JSON.parse(t.data);if(r.id!==n.getID())return;var s,u,l;if(!n._frame.contentWindow){u="the iframe is not anymore in the DOM tree"}else{l=n._frame.contentWindow.getVPAIDAd;u=i.validate(typeof l==="function","the ad didn't return a function to create an ad")}if(!u){var d=n._frame.contentWindow.document.querySelector(".ad-element");s=new a(l(),d,n._videoEl,n._frame);s.subscribe(o,c.bind(n));u=i.validate(s.isValidVPAIDAd(),"the add is not fully complaint with VPAID specification")}n._adUnit=s;h.call(n);e(u,u?null:s);return true}function u(){e("timeout",null)}};u.prototype.unloadAdUnit=function k(){d.call(this)};u.prototype.getID=function(){return this._id};function l(t){var e=this[t];if(e){e.remove();delete this[t]}}function c(){f.call(this);delete this._adUnit}function d(){f.call(this);p.call(this)}function f(){l.call(this,"_frame");h.call(this)}function h(){if(this._onLoad){window.removeEventListener("message",this._onLoad);i.clearCallbackTimeout(this._onLoad);delete this._onLoad}}function p(){if(this._adUnit){this._adUnit.stopAd();delete this._adUnit}}function v(){if(this._destroyed){throw new Error("VPAIDHTML5Client already destroyed!")}}function g(){if(window.location.origin){return window.location.origin}else{return window.location.protocol+"//"+window.location.hostname+(window.location.port?":"+window.location.port:"")}}e.exports=u;window.VPAIDHTML5Client=u},{"./VPAIDAdUnit":10,"./utils":13}],12:[function(t,e,n){"use strict";function i(){this._subscribers={}}i.prototype.subscribe=function r(t,e,n){if(!this.isHandlerAttached(t,e)){this.get(e).push({handler:t,context:n,eventName:e})}};i.prototype.unsubscribe=function a(t,e){this._subscribers[e]=this.get(e).filter(function(e){return t!==e.handler})};i.prototype.unsubscribeAll=function s(){this._subscribers={}};i.prototype.trigger=function(t,e){var n=this;var i=this.get(t).concat(this.get("*"));i.forEach(function(t){setTimeout(function(){if(n.isHandlerAttached(t.handler,t.eventName)){t.handler.call(t.context,e)}},0)})};i.prototype.triggerSync=function(t,e){var n=this.get(t).concat(this.get("*"));n.forEach(function(t){t.handler.call(t.context,e)})};i.prototype.get=function o(t){if(!this._subscribers[t]){this._subscribers[t]=[]}return this._subscribers[t]};i.prototype.isHandlerAttached=function u(t,e){return this.get(e).some(function(e){return t===e.handler})};e.exports=i},{}],13:[function(t,e,n){"use strict";function i(){}function r(t,e){return t?null:new Error(e)}var a={};function s(t){var e=a[t];if(e){clearTimeout(e);delete a[t]}}function o(t,e,n){var r,o;o=setTimeout(function(){e=i;delete o[r];n()},t);r=function(){if(e.apply(this,arguments)){s(r)}};a[r]=o;return r}function u(t,e,n){var i=document.createElement(e);if(n)i.id=n;t.appendChild(i);return i}function l(t,e,n){var i=c(t,null,n.zIndex);if(!f(i,d(e,n)))return;return i}function c(t,e,n){var i=document.createElement("iframe");i.src=e||"about:blank";i.marginWidth="0";i.marginHeight="0";i.frameBorder="0";i.width="100%";i.height="100%";i.style.position="absolute";i.style.left="0";i.style.top="0";i.style.margin="0px";i.style.padding="0px";i.style.border="none";if(n){i.style.zIndex=n}i.setAttribute("SCROLLING","NO");t.innerHTML="";t.appendChild(i);return i}function d(t,e){Object.keys(e).forEach(function(n){var i=typeof i==="object"?JSON.stringify(e[n]):e[n];t=t.replace(new RegExp("{{"+n+"}}","g"),i)});return t}function f(t,e){var n=t.contentWindow&&t.contentWindow.document;if(!n)return false;n.write(e);return true}function h(t,e){Object.keys(e).forEach(function(n){t[n]=e[n]});return t}function p(t){var e=-1;return function(){return t+"_"+ ++e}}e.exports={noop:i,validate:r,clearCallbackTimeout:s,callbackTimeout:o,createElementInEl:u,createIframeWithContent:l,createIframe:c,simpleTemplate:d,setIframeContent:f,extend:h,unique:p}},{}],14:[function(t,e,n){(function(t,n){if(typeof define==="function"&&define.amd){define(n)}else if(typeof e==="object"&&e.exports){e.exports=n()}else{t.swfobject=n()}})(this,function(){var t="undefined",e="object",n="Shockwave Flash",i="ShockwaveFlash.ShockwaveFlash",r="application/x-shockwave-flash",a="SWFObjectExprInst",s="onreadystatechange",o=window,u=document,l=navigator,c=false,d=[],f=[],h=[],p=[],v,g,y,m,A=false,k=false,_,w,b=true,E=false,T=function(){var a=typeof u.getElementById!==t&&typeof u.getElementsByTagName!==t&&typeof u.createElement!==t,s=l.userAgent.toLowerCase(),d=l.platform.toLowerCase(),f=d?/win/.test(d):/win/.test(s),h=d?/mac/.test(d):/mac/.test(s),p=/webkit/.test(s)?parseFloat(s.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,v=l.appName==="Microsoft Internet Explorer",g=[0,0,0],y=null;if(typeof l.plugins!==t&&typeof l.plugins[n]===e){y=l.plugins[n].description;if(y&&(typeof l.mimeTypes!==t&&l.mimeTypes[r]&&l.mimeTypes[r].enabledPlugin)){c=true;v=false;y=y.replace(/^.*\s+(\S+\s+\S+$)/,"$1"); -g[0]=q(y.replace(/^(.*)\..*$/,"$1"));g[1]=q(y.replace(/^.*\.(.*)\s.*$/,"$1"));g[2]=/[a-zA-Z]/.test(y)?q(y.replace(/^.*[a-zA-Z]+(.*)$/,"$1")):0}}else if(typeof o.ActiveXObject!==t){try{var m=new ActiveXObject(i);if(m){y=m.GetVariable("$version");if(y){v=true;y=y.split(" ")[1].split(",");g=[q(y[0]),q(y[1]),q(y[2])]}}}catch(A){}}return{w3:a,pv:g,wk:p,ie:v,win:f,mac:h}}(),S=function(){if(!T.w3){return}if(typeof u.readyState!==t&&(u.readyState==="complete"||u.readyState==="interactive")||typeof u.readyState===t&&(u.getElementsByTagName("body")[0]||u.body)){V()}if(!A){if(typeof u.addEventListener!==t){u.addEventListener("DOMContentLoaded",V,false)}if(T.ie){u.attachEvent(s,function e(){if(u.readyState==="complete"){u.detachEvent(s,e);V()}});if(o==top){(function n(){if(A){return}try{u.documentElement.doScroll("left")}catch(t){setTimeout(n,0);return}V()})()}}if(T.wk){(function i(){if(A){return}if(!/loaded|complete/.test(u.readyState)){setTimeout(i,0);return}V()})()}}}();function V(){if(A||!document.getElementsByTagName("body")[0]){return}try{var t,e=z("span");e.style.display="none";t=u.getElementsByTagName("body")[0].appendChild(e);t.parentNode.removeChild(t);t=null;e=null}catch(n){return}A=true;var i=d.length;for(var r=0;r0){for(var n=0;n0){var s=W(i);if(s){if(J(f[n].swfVersion)&&!(T.wk&&T.wk<312)){Q(i,true);if(r){a.success=true;a.ref=U(i);a.id=i;r(a)}}else if(f[n].expressInstall&&P()){var o={};o.data=f[n].expressInstall;o.width=s.getAttribute("width")||"0";o.height=s.getAttribute("height")||"0";if(s.getAttribute("class")){o.styleclass=s.getAttribute("class")}if(s.getAttribute("align")){o.align=s.getAttribute("align")}var u={};var l=s.getElementsByTagName("param");var c=l.length;for(var d=0;d"+e+"";return n.firstChild}function O(n,i,a){var s,o=W(a);a=B(a);if(T.wk&&T.wk<312){return s}if(o){var u=T.ie?z("div"):z(e),l,c,d;if(typeof n.id===t){n.id=a}for(d in i){if(i.hasOwnProperty(d)&&d.toLowerCase()!=="movie"){N(u,d,i[d])}}if(T.ie){u=R(n.data,u.innerHTML)}for(l in n){if(n.hasOwnProperty(l)){c=l.toLowerCase();if(c==="styleclass"){u.setAttribute("class",n[l])}else if(c!=="classid"&&c!=="data"){u.setAttribute(l,n[l])}}}if(T.ie){h[h.length]=n.id}else{u.setAttribute("type",r);u.setAttribute("data",n.data)}o.parentNode.replaceChild(u,o);s=u}return s}function N(t,e,n){var i=z("param");i.setAttribute("name",e);i.setAttribute("value",n);t.appendChild(i)}function j(t){var e=W(t);if(e&&e.nodeName.toUpperCase()==="OBJECT"){if(T.ie){e.style.display="none";(function n(){if(e.readyState==4){for(var t in e){if(typeof e[t]==="function"){e[t]=null}}e.parentNode.removeChild(e)}else{setTimeout(n,10)}})()}else{e.parentNode.removeChild(e)}}}function H(t){return t&&t.nodeType&&t.nodeType===1}function B(t){return H(t)?t.id:t}function W(t){if(H(t)){return t}var e=null;try{e=u.getElementById(t)}catch(n){}return e}function z(t){return u.createElement(t)}function q(t){return parseInt(t,10)}function X(t,e,n){t.attachEvent(e,n);p[p.length]=[t,e,n]}function J(t){t+="";var e=T.pv,n=t.split(".");n[0]=q(n[0]);n[1]=q(n[1])||0;n[2]=q(n[2])||0;return e[0]>n[0]||e[0]==n[0]&&e[1]>n[1]||e[0]==n[0]&&e[1]==n[1]&&e[2]>=n[2]?true:false}function $(e,n,i,r){var a=u.getElementsByTagName("head")[0];if(!a){return}var s=typeof i==="string"?i:"screen";if(r){_=null;w=null}if(!_||w!=s){var o=z("style");o.setAttribute("type","text/css");o.setAttribute("media",s);_=a.appendChild(o);if(T.ie&&typeof u.styleSheets!==t&&u.styleSheets.length>0){_=u.styleSheets[u.styleSheets.length-1]}w=s}if(_){if(typeof _.addRule!==t){_.addRule(e,n)}else if(typeof u.createTextNode!==t){_.appendChild(u.createTextNode(e+" {"+n+"}"))}}}function Q(t,e){if(!b){return}var n=e?"visible":"hidden",i=W(t);if(A&&i){i.style.visibility=n}else if(typeof t==="string"){$("#"+t,"visibility:"+n)}}function G(e){var n=/[\\\"<>\.;]/;var i=n.exec(e)!==null;return i&&typeof encodeURIComponent!==t?encodeURIComponent(e):e}var K=function(){if(T.ie){window.attachEvent("onunload",function(){var t=p.length;for(var e=0;e0){d(r.shift(),[],a)}else{e(t,i)}}else{e(null,i)}}});function a(t,e){var i=n._requestVASTXml.bind(n,t);o.waterfall([i,s],e)}function s(t,e){var n;try{n=c.toJXONTree(t);if(l.isArray(n.ad)){n.ads=n.ad}else if(n.ad){n.ads=[n.ad]}else{n.ads=[]}e(u(n),n)}catch(i){e(new r("on VASTClient.getVASTAd.buildVastWaterfall, error parsing xml",100),null)}}function u(t){var e=c.attr(t,"version");if(!t.ad){return new r("on VASTClient.getVASTAd.validateVASTTree, no Ad in VAST tree",303)}if(e&&(e!=3&&e!=2)){return new r('on VASTClient.getVASTAd.validateVASTTree, not supported VAST version "'+e+'"',102)}return null}function d(t,e,i){if(e.length>=n.WRAPPER_LIMIT){return i(new r("on VASTClient.getVASTAd.getAd, players wrapper limit reached (the limit is "+n.WRAPPER_LIMIT+")",302),e)}o.waterfall([function(e){if(l.isString(t)){p(t,e)}else{e(null,t)}},f],function(t,n){if(n){e.push(n)}if(t){return i(t,e)}if(n.wrapper){return d(n.wrapper.VASTAdTagURI,e,i)}return i(null,e)})}function f(t,e){try{var n=new i(t);e(h(n),n)}catch(a){e(new r("on VASTClient.getVASTAd.buildAd, error parsing xml",100),null)}}function h(t){var e=t.wrapper;var n=t.inLine;var i="on VASTClient.getVASTAd.validateAd, ";if(n&&e){return new r(i+"InLine and Wrapper both found on the same Ad",101)}if(!n&&!e){return new r(i+"nor wrapper nor inline elements found on the Ad",101)}if(n&&!n.isSupported()){return new r(i+"could not find MediaFile that is supported by this video player",403)}if(e&&!e.VASTAdTagURI){return new r(i+"missing 'VASTAdTagURI' in wrapper",101)}return null}function p(t,e){n._requestVASTXml(t,function(t,n){if(t){return e(t)}try{var i=c.toJXONTree(n);e(u(i),i.ad)}catch(a){e(new r("on VASTClient.getVASTAd.requestVASTAd, error parsing xml",100))}})}};d.prototype._requestVASTXml=function h(t,e){try{if(l.isFunction(t)){t(i)}else{u.get(t,i,{withCredentials:true})}}catch(n){e(n)}function i(t,n,i){if(t){var a=l.isDefined(i)?"on VASTClient.requestVastXML, HTTP request error with status '"+i+"'":"on VASTClient.requestVastXML, Error getting the the VAST XML with he passed adTagXML fn";return e(new r(a,301),null)}e(null,n)}};d.prototype._buildVASTResponse=function p(t){var e=new a;n(e,t);i(e);return e;function n(t,e){e.forEach(function(e){t.addAd(e)})}function i(t){var e=t.trackingEvents.progress;if(!t.hasLinear()){throw new r("on VASTClient._buildVASTResponse, Received an Ad type that is not supported",200)}if(t.duration===undefined){throw new r("on VASTClient._buildVASTResponse, Missing duration field in VAST response",101)}if(e){e.forEach(function(t){if(!l.isNumber(t.offset)){throw new r("on VASTClient._buildVASTResponse, missing or wrong offset attribute on progress tracking event",101)}})}}};d.prototype._trackError=function(t,e){if(!l.isArray(e)||e.length===0){return}var n=[];e.forEach(i);s.track(n,{ERRORCODE:t.code||900});function i(t){if(t.wrapper&&t.wrapper.error){n.push(t.wrapper.error)}if(t.inLine&&t.inLine.error){n.push(t.inLine.error)}}};e.exports=d},{"../../utils/async":40,"../../utils/http":42,"../../utils/utilityFunctions":45,"../../utils/xml":46,"./Ad":15,"./VASTError":23,"./VASTResponse":25,"./vastUtil":30}],23:[function(t,e,n){"use strict";function i(t,e){this.message="VAST Error: "+(t||"");if(e){this.code=e}}i.prototype=new Error;i.prototype.name="VAST Error";e.exports=i},{}],24:[function(t,e,n){"use strict";var i=t("./VASTResponse");var r=t("./VASTError");var a=t("./VASTTracker");var s=t("./vastUtil");var o=t("../../utils/async");var u=t("../../utils/dom");var l=t("../../utils/playerUtils");var c=t("../../utils/utilityFunctions");function d(t){if(!(this instanceof d)){return new d(t)}this.player=t}d.prototype.playAd=function f(t,e){var n=this;e=e||c.noop;if(!(t instanceof i)){return e(new r("On VASTIntegrator, missing required VASTResponse"))}o.waterfall([function(e){e(null,t)},this._selectAdSource.bind(this),this._createVASTTracker.bind(this),this._addClickThrough.bind(this),this._addSkipButton.bind(this),this._setupEvents.bind(this),this._playSelectedAd.bind(this)],function(t,i){if(t&&i){n._trackError(t,i)}e(t,i)});this._adUnit={_src:null,type:"VAST",pauseAd:function(){n.player.pause(true)},resumeAd:function(){n.player.play(true)},isPaused:function(){return n.player.paused(true)},getSrc:function(){return this._src}};return this._adUnit};d.prototype._selectAdSource=function h(t,e){var n;var i=u.getDimension(this.player.el()).width;t.mediaFiles.sort(function a(t,e){var n=Math.abs(i-t.width);var r=Math.abs(i-e.width);return n-r});n=this.player.selectSource(t.mediaFiles).source;if(n){if(this._adUnit){this._adUnit._src=n}return e(null,n,t)}e(new r("Could not find Ad mediafile supported by this player",403),t)};d.prototype._createVASTTracker=function p(t,e,n){try{n(null,t,new a(t.src,e),e)}catch(i){n(i,e)}};d.prototype._setupEvents=function v(t,e,n,i){var r;var a=this.player;a.on("fullscreenchange",o);a.on("vast.adStart",d);a.on("pause",u);a.on("timeupdate",c);a.on("volumechange",f);l.once(a,["vast.adEnd","vast.adsCancel"],s);l.once(a,["vast.adEnd","vast.adsCancel","vast.adSkip"],function(t){if(t.type==="vast.adEnd"){e.trackComplete()}});return i(null,t,n);function s(){a.off("fullscreenchange",o);a.off("vast.adStart",d);a.off("pause",u);a.off("timeupdate",c);a.off("volumechange",f)}function o(){if(a.isFullscreen()){e.trackFullscreen()}else{e.trackExitFullscreen()}}function u(){if(Math.abs(a.duration()-a.currentTime())<2){return}e.trackPause();l.once(a,["play","vast.adEnd","vast.adsCancel"],function(t){if(t.type==="play"){e.trackResume()}})}function c(){var t=a.currentTime()*1e3;e.trackProgress(t)}function d(){e.trackImpressions();e.trackCreativeView()}function f(){var t=a.muted();if(t){e.trackMute()}else if(r){e.trackUnmute()}r=t}};d.prototype._addSkipButton=function g(t,e,n,i){var r;var a=this;if(c.isNumber(n.skipoffset)){r=n.skipoffset/1e3;s(this.player,r)}i(null,t,e,n);function s(t,e){var n=o(t);var i=d.bind(a,n,e,t);t.el().appendChild(n);t.on("timeupdate",i);l.once(t,["vast.adEnd","vast.adsCancel"],r);function r(){t.off("timeupdate",i);u.remove(n)}}function o(t){var n=window.document.createElement("div");u.addClass(n,"vast-skip-button");n.onclick=function(i){if(u.hasClass(n,"enabled")){e.trackSkip();t.trigger("vast.adSkip")}if(window.Event.prototype.stopPropagation!==undefined){i.stopPropagation()}else{return false}};return n}function d(t,e,n){var i=Math.ceil(e-n.currentTime());if(i>0){t.innerHTML="Skip in "+c.toFixedDigits(i,2)+"..."}else{if(!u.hasClass(t,"enabled")){u.addClass(t,"enabled");t.innerHTML="Skip ad"}}}};d.prototype._addClickThrough=function y(t,e,n,i){var r=this.player;var a=d(r,e,n);var o=f.bind(this,a,n,r);r.el().insertBefore(a,r.controlBar.el());r.on("timeupdate",o);l.once(r,["vast.adEnd","vast.adsCancel"],p);return i(null,t,e,n);function d(t,e,n){var i=window.document.createElement("a");var r=n.clickThrough;u.addClass(i,"vast-blocker");i.href=h(r,t);if(c.isString(r)){i.target="_blank"}i.onclick=function(n){if(t.paused()){t.play();if(window.Event.prototype.stopPropagation!==undefined){n.stopPropagation()}return false}t.pause();e.trackClick()};return i}function f(t,e,n){t.href=h(e.clickThrough,n)}function h(e,n){var i={ASSETURI:t.src,CONTENTPLAYHEAD:s.formatProgress(n.currentTime()*1e3)};return e?s.parseURLMacro(e,i):"#"}function p(){r.off("timeupdate",o);u.remove(a)}};d.prototype._playSelectedAd=function m(t,e,n){var i=this.player;i.preload("auto");i.src(t);l.once(i,["durationchange","error","vast.adsCancel"],function(t){if(t.type==="durationchange"){a()}else if(t.type==="error"){n(new r("on VASTIntegrator, Player is unable to play the Ad",400),e)}});function a(){l.once(i,["playing","vast.adsCancel"],function(t){if(t.type==="vast.adsCancel"){return}i.trigger("vast.adStart");i.on("ended",r);i.on("vast.adsCancel",r);i.on("vast.adSkip",r);function r(t){if(t.type==="ended"&&i.duration()-i.currentTime()>3){return}i.off("ended",r);i.off("vast.adsCancel",r);i.off("vast.adSkip",r);if(t.type==="ended"||t.type==="vast.adSkip"){n(null,e)}}});i.play()}};d.prototype._trackError=function A(t,e){s.track(e.errorURLMacros,{ERRORCODE:t.code||900})};e.exports=d},{"../../utils/async":40,"../../utils/dom":41,"../../utils/playerUtils":43,"../../utils/utilityFunctions":45,"./VASTError":23,"./VASTResponse":25,"./VASTTracker":26,"./vastUtil":30}],25:[function(t,e,n){"use strict";var i=t("./Ad");var r=t("./VideoClicks");var a=t("./Linear");var s=t("./InLine");var o=t("./Wrapper");var u=t("../../utils/utilityFunctions");var l=t("../../utils/xml");window.InLine__A=s;function c(){if(!(this instanceof c)){return new c}this._linearAdded=false;this.ads=[];this.errorURLMacros=[];this.impressions=[];this.clickTrackings=[];this.customClicks=[];this.trackingEvents={};this.mediaFiles=[];this.clickThrough=undefined;this.adTitle="";this.duration=undefined;this.skipoffset=undefined}c.prototype.addAd=function(t){var e,n;if(t instanceof i){e=t.inLine;n=t.wrapper;this.ads.push(t);if(e){this._addInLine(e)}if(n){this._addWrapper(n)}}};c.prototype._addErrorTrackUrl=function(t){var e=t instanceof l.JXONTree?l.keyValue(t):t;if(e){this.errorURLMacros.push(e)}};c.prototype._addImpressions=function(t){u.isArray(t)&&d(this.impressions,t)};c.prototype._addClickThrough=function(t){if(u.isNotEmptyString(t)){this.clickThrough=t}};c.prototype._addClickTrackings=function(t){u.isArray(t)&&d(this.clickTrackings,t)};c.prototype._addCustomClicks=function(t){u.isArray(t)&&d(this.customClicks,t)};c.prototype._addTrackingEvents=function(t){var e=this.trackingEvents;if(t){t=u.isArray(t)?t:[t];t.forEach(function(t){if(!e[t.name]){e[t.name]=[]}e[t.name].push(t)})}};c.prototype._addTitle=function(t){if(u.isNotEmptyString(t)){this.adTitle=t}};c.prototype._addDuration=function(t){if(u.isNumber(t)){this.duration=t}};c.prototype._addVideoClicks=function(t){if(t instanceof r){this._addClickThrough(t.clickThrough);this._addClickTrackings(t.clickTrackings);this._addCustomClicks(t.customClicks)}};c.prototype._addMediaFiles=function(t){u.isArray(t)&&d(this.mediaFiles,t)};c.prototype._addSkipoffset=function(t){if(t){this.skipoffset=t}};c.prototype._addAdParameters=function(t){if(t){this.adParameters=t}};c.prototype._addLinear=function(t){if(t instanceof a){this._addDuration(t.duration);this._addTrackingEvents(t.trackingEvents);this._addVideoClicks(t.videoClicks);this._addMediaFiles(t.mediaFiles);this._addSkipoffset(t.skipoffset);this._addAdParameters(t.adParameters);this._linearAdded=true}};c.prototype._addInLine=function(t){var e=this;if(t instanceof s){this._addTitle(t.adTitle);this._addErrorTrackUrl(t.error);this._addImpressions(t.impressions);t.creatives.forEach(function(t){if(t.linear){e._addLinear(t.linear)}})}};c.prototype._addWrapper=function(t){var e=this;if(t instanceof o){this._addErrorTrackUrl(t.error);this._addImpressions(t.impressions);t.creatives.forEach(function(t){var n=t.linear;if(n){e._addVideoClicks(n.videoClicks);e.clickThrough=undefined;e._addTrackingEvents(n.trackingEvents)}})}};c.prototype.hasLinear=function(){return this._linearAdded};function d(t,e){e.forEach(function(e){t.push(e)})}e.exports=c},{"../../utils/utilityFunctions":45,"../../utils/xml":46,"./Ad":15,"./InLine":18,"./Linear":19,"./VideoClicks":27,"./Wrapper":28}],26:[function(t,e,n){"use strict";var i=t("./VASTError");var r=t("./VASTResponse");var a=t("./vastUtil");var s=t("../../utils/utilityFunctions");function o(t,e){if(!(this instanceof o)){return new o(t,e)}this.sanityCheck(t,e);this.initialize(t,e)}o.prototype.initialize=function(t,e){this.response=e;this.assetURI=t;this.progress=0;this.quartiles={firstQuartile:{tracked:false,time:Math.round(25*e.duration)/100},midpoint:{tracked:false,time:Math.round(50*e.duration)/100},thirdQuartile:{tracked:false,time:Math.round(75*e.duration)/100}}};o.prototype.sanityCheck=function(t,e){if(!s.isString(t)||s.isEmptyString(t)){throw new i("on VASTTracker constructor, missing required the URI of the ad asset being played")}if(!(e instanceof r)){throw new i("on VASTTracker constructor, missing required VAST response")}};o.prototype.trackURLs=function u(t,e){if(s.isArray(t)&&t.length>0){e=s.extend({ASSETURI:this.assetURI,CONTENTPLAYHEAD:a.formatProgress(this.progress)},e||{});a.track(t,e)}};o.prototype.trackEvent=function l(t,e){this.trackURLs(n(this.response.trackingEvents[t]));if(e){this.response.trackingEvents[t]=undefined}function n(t){var e;if(t){e=[];t.forEach(function(t){e.push(t.uri)})}return e}};o.prototype.trackProgress=function c(t){var e=this;var n=[];var i=true;var r=false;var a=this.response.trackingEvents;if(s.isNumber(t)){u("start",i,t>0);u("rewind",r,o(this.progress,t));l(t);d(t);f();this.progress=t}function o(e,n){var i=3e3;return e>t&&Math.abs(n-e)>i}function u(t,e,i){if(a[t]&&i){n.push({name:t,trackOnce:!!e})}}function l(t){var n=e.quartiles;var r=e.quartiles.firstQuartile;var a=e.quartiles.midpoint;var s=e.quartiles.thirdQuartile;if(!r.tracked){o("firstQuartile",t)}else if(!a.tracked){o("midpoint",t)}else if(!s.tracked){o("thirdQuartile",t)}function o(t,e){var r=n[t];if(c(r,e)){r.tracked=true;u(t,i,true)}}}function c(t,e){var n=t.time;return e>=n&&e<=n+5e3}function d(t){if(!s.isArray(a.progress)){return}var n=[];a.progress.forEach(function(i){if(i.offset<=t){e.trackURLs([i.uri])}else{n.push(i)}});a.progress=n}function f(){n.forEach(function(t){e.trackEvent(t.name,t.trackOnce)})}};["rewind","fullscreen","exitFullscreen","pause","resume","mute","unmute","acceptInvitation","acceptInvitationLinear","collapse","expand"].forEach(function(t){o.prototype["track"+s.capitalize(t)]=function(){this.trackEvent(t)}});["start","skip","close","closeLinear"].forEach(function(t){o.prototype["track"+s.capitalize(t)]=function(){this.trackEvent(t,true)}});["firstQuartile","midpoint","thirdQuartile"].forEach(function(t){o.prototype["track"+s.capitalize(t)]=function(){this.quartiles[t].tracked=true;this.trackEvent(t,true)}});o.prototype.trackComplete=function(){if(this.quartiles.thirdQuartile.tracked){this.trackEvent("complete",true)}};o.prototype.trackErrorWithCode=function d(t){if(s.isNumber(t)){this.trackURLs(this.response.errorURLMacros,{ERRORCODE:t})}};o.prototype.trackImpressions=function f(){this.trackURLs(this.response.impressions)};o.prototype.trackCreativeView=function h(){this.trackEvent("creativeView")};o.prototype.trackClick=function p(){this.trackURLs(this.response.clickTrackings)};e.exports=o},{"../../utils/utilityFunctions":45,"./VASTError":23,"./VASTResponse":25,"./vastUtil":30}],27:[function(t,e,n){"use strict";var i=t("../../utils/utilityFunctions");var r=t("../../utils/xml");function a(t){if(!(this instanceof a)){return new a(t)}this.clickThrough=r.keyValue(t.clickThrough);this.clickTrackings=e(t.clickTracking);this.customClicks=e(t.customClick);function e(t){var e=[];if(t){t=i.isArray(t)?t:[t];t.forEach(function(t){e.push(r.keyValue(t))})}return e}}e.exports=a},{"../../utils/utilityFunctions":45,"../../utils/xml":46}],28:[function(t,e,n){"use strict";var i=t("./vastUtil");var r=t("./Creative");var a=t("../../utils/utilityFunctions");var s=t("../../utils/xml");function o(t){if(!(this instanceof o)){return new o(t)}this.adSystem=s.keyValue(t.adSystem);this.impressions=i.parseImpressions(t.impression);this.VASTAdTagURI=s.keyValue(t.vASTAdTagURI);this.creatives=r.parseCreatives(t.creatives);this.error=s.keyValue(t.error);this.extensions=t.extensions;this.followAdditionalWrappers=a.isDefined(s.attr(t,"followAdditionalWrappers"))?s.attr(t,"followAdditionalWrappers"):true;this.allowMultipleAds=s.attr(t,"allowMultipleAds");this.fallbackOnNoAd=s.attr(t,"fallbackOnNoAd")}e.exports=o},{"../../utils/utilityFunctions":45,"../../utils/xml":46,"./Creative":17,"./vastUtil":30}],29:[function(t,e,n){"use strict";var i=t("../../utils/utilityFunctions");var r=/(\d\d):(\d\d):(\d\d)(\.(\d\d\d))?/;var a={duration:function s(t){var e,n;if(i.isString(t)){e=t.match(r);if(e){n=a(e[1])+s(e[2])+o(e[3])+parseInt(e[5]||0)}}return isNaN(n)?null:n;function a(t){return parseInt(t,10)*60*60*1e3}function s(t){return parseInt(t,10)*60*1e3}function o(t){return parseInt(t,10)*1e3}},offset:function o(t,e){if(n(t)){return i(t,e)}return a.duration(t);function n(t){var e=/^\d+(\.\d+)?%$/g;return e.test(t)}function i(t,e){if(e){return r(e,parseFloat(t.replace("%","")))}return null}function r(t,e){return t*e/100}}};e.exports=a},{"../../utils/utilityFunctions":45}],30:[function(t,e,n){"use strict";var i=t("../../utils/utilityFunctions");var r=t("../vpaid/VPAIDHTML5Tech");var a=t("../vpaid/VPAIDFlashTech");var s=t("VPAIDFLASHClient/js/VPAIDFLASHClient"); -var o={track:function u(t,e){var n=o.parseURLMacros(t,e);var i=[];n.forEach(function(t){var e=new Image;e.src=t;i.push(e)});return i},parseURLMacros:function l(t,e){var n=[];e=e||{};if(!e["CACHEBUSTING"]){e["CACHEBUSTING"]=Math.round(Math.random()*1e10)}t.forEach(function(t){n.push(o._parseURLMacro(t,e))});return n},parseURLMacro:function c(t,e){e=e||{};if(!e["CACHEBUSTING"]){e["CACHEBUSTING"]=Math.round(Math.random()*1e10)}return o._parseURLMacro(t,e)},_parseURLMacro:function d(t,e){e=e||{};i.forEach(e,function(e,n){t=t.replace(new RegExp("\\["+n+"\\]","gm"),e)});return t},parseDuration:function f(t){var e=/(\d\d):(\d\d):(\d\d)(\.(\d\d\d))?/;var n,r;if(i.isString(t)){n=t.match(e);if(n){r=a(n[1])+s(n[2])+o(n[3])+parseInt(n[5]||0)}}return isNaN(r)?null:r;function a(t){return parseInt(t,10)*60*60*1e3}function s(t){return parseInt(t,10)*60*1e3}function o(t){return parseInt(t,10)*1e3}},parseImpressions:function h(t){if(t){t=i.isArray(t)?t:[t];return i.transformArray(t,function(t){if(i.isNotEmptyString(t.keyValue)){return t.keyValue}return undefined})}return[]},formatProgress:function p(t){var e,n,r,a;e=t/(60*60*1e3);e=Math.floor(e);n=t/(60*1e3)%60;n=Math.floor(n);r=t/1e3%60;r=Math.floor(r);a=t%1e3;return i.toFixedDigits(e,2)+":"+i.toFixedDigits(n,2)+":"+i.toFixedDigits(r,2)+"."+i.toFixedDigits(a,3)},parseOffset:function v(t,e){if(n(t)){return i(t,e)}return o.parseDuration(t);function n(t){var e=/^\d+(\.\d+)?%$/g;return e.test(t)}function i(t,e){if(e){return r(e,parseFloat(t.replace("%","")))}return null}function r(t,e){return t*e/100}},VPAID_techs:[a,r],isVPAID:function g(t){return!!t&&t.apiFramework==="VPAID"},findSupportedVPAIDTech:function y(t){var e,n,i;for(e=0,n=this.VPAID_techs.length;e=1&&e<=2}function a(t){var e=t.split(".");return parseInt(e[0],10)}};f.prototype._initAd=function(t,e,n){var i=this.player.el().querySelector(".vjs-tech");var r=l.getDimension(i);t.initAd(r.width,r.height,this.VIEW_MODE.NORMAL,-1,{AdParameters:e.adParameters||""},function(i){n(i,t,e)})};f.prototype._createVASTTracker=function(t,e){return new a(t,e)};f.prototype._setupEvents=function(t,e,n){var i=t.options.src;var r=this._createVASTTracker(i,e);var a=this.player;var o=this;t.on("AdSkipped",function(){a.trigger("vpaid.AdSkipped");r.trackSkip()});t.on("AdImpression",function(){a.trigger("vpaid.AdImpression");r.trackImpressions()});t.on("AdStarted",function(){a.trigger("vpaid.AdStarted");r.trackCreativeView();u()});t.on("AdVideoStart",function(){a.trigger("vpaid.AdVideoStart");r.trackStart();u()});t.on("AdPlaying",function(){a.trigger("vpaid.AdPlaying");r.trackResume();u()});t.on("AdPaused",function(){a.trigger("vpaid.AdPaused");r.trackPause();c()});function u(){if(o._adUnit&&o._adUnit.isPaused()){o._adUnit._paused=false}a.trigger("play")}function c(){if(o._adUnit){o._adUnit._paused=true}a.trigger("pause")}t.on("AdVideoFirstQuartile",function(){a.trigger("vpaid.AdVideoFirstQuartile");r.trackFirstQuartile()});t.on("AdVideoMidpoint",function(){a.trigger("vpaid.AdVideoMidpoint");r.trackMidpoint()});t.on("AdVideoThirdQuartile",function(){a.trigger("vpaid.AdVideoThirdQuartile");r.trackThirdQuartile()});t.on("AdVideoComplete",function(){a.trigger("vpaid.AdVideoComplete");r.trackComplete()});t.on("AdClickThru",function(n){a.trigger("vpaid.AdClickThru");var i=n.url;var o=n.playerHandles;var u=d.isNotEmptyString(i)?i:l(e.clickThrough);r.trackClick();if(o&&u){window.open(u,"_blank")}function l(e){var n={ASSETURI:t.options.src,CONTENTPLAYHEAD:0};return e?s.parseURLMacro(e,n):null}});t.on("AdUserAcceptInvitation",function(){a.trigger("vpaid.AdUserAcceptInvitation");r.trackAcceptInvitation();r.trackAcceptInvitationLinear()});t.on("AdUserClose",function(){a.trigger("vpaid.AdUserClose");r.trackClose();r.trackCloseLinear()});t.on("AdUserMinimize",function(){a.trigger("vpaid.AdUserMinimize");r.trackCollapse()});t.on("AdError",function(){a.trigger("vpaid.AdError");r.trackErrorWithCode(901)});t.on("AdVolumeChange",function(){a.trigger("vpaid.AdVolumeChange");var e=a.volume();t.getAdVolume(function(t,n){if(n===0&&e>0){r.trackMute()}if(n>0&&e===0){r.trackUnmute()}a.volume(n)})});var f=h.bind(this,a,t,this.VIEW_MODE);var p=d.throttle(f,100);var v=this.settings.autoResize;if(v){l.addEventListener(window,"resize",p);l.addEventListener(window,"orientationchange",p)}a.on("vast.resize",f);a.on("vpaid.pauseAd",g);a.on("vpaid.resumeAd",y);a.one("vpaid.adEnd",function(){a.off("vast.resize",f);a.off("vpaid.pauseAd",g);a.off("vpaid.resumeAd",y);if(v){l.removeEventListener(window,"resize",p);l.removeEventListener(window,"orientationchange",p)}});n(null,t,e);function g(){t.pauseAd(d.noop)}function y(){t.resumeAd(d.noop)}};f.prototype._addSkipButton=function(t,e,n){var i;var r=this.player;t.on("AdSkippableStateChange",a);c.once(r,["vast.adEnd","vast.adsCancel"],o);n(null,t,e);function a(){r.trigger("vpaid.AdSkippableStateChange");t.getAdSkippableState(function(t,e){if(e){if(!i){s(r)}}else{o(r)}})}function s(t){i=u(t);t.el().appendChild(i)}function o(){l.remove(i);i=null}function u(){var e=window.document.createElement("div");l.addClass(e,"vast-skip-button");l.addClass(e,"enabled");e.innerHTML="Skip ad";e.onclick=function(e){t.skipAd(d.noop);if(window.Event.prototype.stopPropagation!==undefined){e.stopPropagation()}else{return false}};return e}};f.prototype._linkPlayerControls=function(t,e,n){var i=this;r(this.player,t);a(this.player,t,this.VIEW_MODE);n(null,t,e);function r(t,e){t.on("volumechange",n);e.on("AdVolumeChange",i);t.one("vpaid.adEnd",function(){t.off("volumechange",n)});function n(){var n=t.muted()?0:t.volume();e.setAdVolume(n,p)}function i(){t.trigger("vpaid.AdVolumeChange");e.getAdVolume(function(e,n){if(e){p(e)}else{t.volume(n)}})}}function a(t,e,n){var r=h.bind(i,t,e,n);t.on("fullscreenchange",r);t.one("vpaid.adEnd",function(){t.off("fullscreenchange",r)})}};f.prototype._startAd=function(t,e,n){var i=this.player;t.startAd(function(r){if(!r){i.trigger("vast.adStart")}n(r,t,e)})};f.prototype._finishPlaying=function(t,e,n){var r=this.player;t.on("AdStopped",function(){r.trigger("vpaid.AdStopped");a(null)});t.on("AdError",function(t){var e=t?t.message:"on VPAIDIntegrator, error while waiting for the adUnit to finish playing";a(new i(e))});function a(i){n(i,t,e)}};f.prototype._trackError=function y(t,e){s.track(t.errorURLMacros,{ERRORCODE:e||901})};function h(t,e,n){var i=t.el().querySelector(".vjs-tech");var r=l.getDimension(i);var a=t.isFullscreen()?n.FULLSCREEN:n.NORMAL;e.resizeAd(r.width,r.height,a,p)}function p(t){if(t&&console&&console.log){console.log("ERROR: "+t.message,t)}}e.exports=f},{"../../utils/async":40,"../../utils/dom":41,"../../utils/playerUtils":43,"../../utils/utilityFunctions":45,"../vast/VASTError":23,"../vast/VASTResponse":25,"../vast/VASTTracker":26,"../vast/vastUtil":30,"./VPAIDAdUnitWrapper":31}],35:[function(t,e,n){"use strict";var i=t("../../utils/dom");var r=document.createElement("div");r.className="vjs-ads-label vjs-control vjs-label-hidden";r.innerHTML="Advertisement";var a=function(t){return{init:function e(n,a){a.el=r;t.call(this,n,a);setTimeout(function(){var t=n.controlBar&&(n.controlBar.getChild("timerControls")||n.controlBar.getChild("currentTimeDisplay"));if(t){n.controlBar.el().insertBefore(r,t.el())}i.removeClass(r,"vjs-label-hidden")},0)},el:function n(){return r}}};e.exports=a},{"../../utils/dom":41}],36:[function(t,e,n){"use strict";var i=videojs.Component;var r=t("./ads-label")(i);videojs.AdsLabel=videojs.Component.extend(r)},{"./ads-label":35}],37:[function(t,e,n){"use strict";var i=document.createElement("div");var r=function(t){return{init:function e(n,r){r.el=i;i.className="vjs-black-poster";t.call(this,n,r);var a=n.getChild("posterImage");setTimeout(function(){if(a&&n&&n.el()){n.el().insertBefore(i,a.el())}},0)},el:function n(){return i}}};e.exports=r},{}],38:[function(t,e,n){"use strict";var i=videojs.Component;var r=t("./black-poster")(i);videojs.BlackPoster=videojs.Component.extend(r)},{"./black-poster":37}],39:[function(t,e,n){"use strict";var i=t("../ads/vast/VASTClient");var r=t("../ads/vast/VASTError");var a=t("../ads/vast/vastUtil");var s=t("../ads/vast/VASTIntegrator");var o=t("../ads/vpaid/VPAIDIntegrator");var u=t("../utils/async");var l=t("../utils/dom");var c=t("../utils/playerUtils");var d=t("../utils/utilityFunctions");e.exports=function f(t){var e;var n=this;var f=new i;var h=false;var p={timeout:500,iosPrerollCancelTimeout:2e3,adCancelTimeout:3e3,playAdAlways:false,adsEnabled:true,autoResize:true,vpaidFlashLoaderPath:"/VPAIDFlash.swf"};var v=d.extend({},p,t||{});if(d.isUndefined(v.adTagUrl)&&d.isDefined(v.url)){v.adTagUrl=v.url}if(d.isString(v.adTagUrl)){v.adTagUrl=d.echoFn(v.adTagUrl)}if(d.isDefined(v.adTagXML)&&!d.isFunction(v.adTagXML)){return _(new r("on VideoJS VAST plugin, the passed adTagXML option does not contain a function"))}if(!d.isDefined(v.adTagUrl)&&!d.isFunction(v.adTagXML)){return _(new r("on VideoJS VAST plugin, missing adTagUrl on options object"))}a.runFlashSupportCheck(v.vpaidFlashLoaderPath);c.prepareForAds(n);if(v.playAdAlways){n.on("vast.contentEnd",function(){setTimeout(function(){n.trigger("vast.reset")},0)})}n.on("vast.firstPlay",g);n.on("vast.reset",function(){e=null;y()});n.vast={isEnabled:function(){return v.adsEnabled},enable:function(){v.adsEnabled=true},disable:function(){v.adsEnabled=false}};return n.vast;function g(){c.removeNativePoster(n);c.once(n,["vast.adsCancel","vast.adEnd"],function(){t();i()});u.waterfall([s,o,p,m],function(t,e){if(t){_(t,e)}else{n.trigger("vast.adEnd")}});function t(){if(n.vast&&n.vast.adUnit){n.vast.adUnit=null}}function i(){a();if(e){c.restorePlayerSnapshot(n,e);e=null}}function a(){c.once(n,["playing","vast.reset","vast.firstPlay"],function(t){if(t.type!=="playing"){return}n.trigger("vast.contentStart");c.once(n,["ended","vast.reset","vast.firstPlay"],function(t){if(t.type==="ended"){n.trigger("vast.contentEnd")}})})}function s(t){if(v.adsEnabled){return t(null)}t(new r("Ads are not enabled"))}function o(t){if(f()){e=c.getPlayerSnapshot(n);n.pause();g();if(n.paused()){t(null)}else{c.once(n,["playing"],function(){n.pause();t(null)})}}else{t(new r("video content has been playing before preroll ad"))}}function f(){return!d.isIPhone()||n.currentTime()<=v.iosPrerollCancelTimeout}function p(t){var e;h=false;e=setTimeout(function(){_(new r("timeout while waiting for the video to start playing",402))},v.adCancelTimeout);c.once(n,["vast.adStart","vast.adsCancel"],i);function i(){if(e){clearTimeout(e);e=null}}t(null)}function g(){l.addClass(n.el(),"vjs-vast-ad-loading");c.once(n,["vast.adStart","vast.adsCancel"],y)}function y(){setTimeout(function(){l.removeClass(n.el(),"vjs-vast-ad-loading")},100)}}function y(){n.trigger("vast.adsCancel");h=true}function m(t){u.waterfall([A,k],t)}function A(t){f.getVASTResponse(v.adTagUrl?v.adTagUrl():v.adTagXML,t)}function k(t,e){if(h){return}var i=w(t)?new o(n,v):new s(n);var r=false;c.once(n,["vast.adStart","vast.adsCancel"],function(t){if(t.type==="vast.adStart"){a()}});c.once(n,["vast.adEnd","vast.adsCancel"],u);if(d.isIDevice()){l()}n.vast.vastResponse=t;n.vast.adUnit=i.playAd(t,e);function a(){if(r||n.controlBar.getChild("AdsLabel")){return}n.controlBar.addChild("AdsLabel")}function u(){n.controlBar.removeChild("AdsLabel");r=true}function l(){var t=3;var e=0;var i=0;n.on("timeupdate",a);n.on("ended",r);c.once(n,["vast.adEnd","vast.adsCancel","vast.adError"],s);function r(){if(n.duration()-e>t){n.pause(true);n.play(true);n.currentTime(e)}}function a(){var r=n.currentTime();var a=Math.abs(r-e);if(a>t){i+=1;if(i>=2){n.pause(true)}n.currentTime(e)}else{e=r}}function s(){n.off("timeupdate",a);n.off("ended",r)}}}function _(t,e){n.trigger({type:"vast.adError",error:t});y();if(console&&console.log){console.log("AD ERROR:",t.message,t,e)}}function w(t){var e,n;var i=t.mediaFiles;for(e=0,n=i.length;e0){u=setTimeout(function(){l&&l.abort()},o)}function c(t,e,n){if(!r.isString(t)||r.isEmptyString(t)){throw new a("Invalid url '"+t+"'")}if(!r.isFunction(e)){throw new a("Invalid handler '"+e+"' for the http request")}if(r.isDefined(n)&&!r.isObject(n)){throw new a("Invalid options map '"+n+"'")}}function d(t,e){r.forEach(e,function(e,n){if(r.isDefined(e)){t.setRequestHeader(n,e)}})}function f(){n(-1,null,null,"")}};s.prototype.get=function(t,e,n){this.run("GET",t,i,n);function i(t,n,i,s){if(r(t)){e(null,n,t,i,s)}else{e(new a(s),n,t,i,s)}}function r(t){return 200<=t&&t<300}};function o(){var t=new XMLHttpRequest;if(!("withCredentials"in t)){t=new XDomainRequest}return t}var u=new s(o);e.exports={http:u,HttpRequest:s,HttpRequestError:a,createXhr:o}},{"./urlUtils":44,"./utilityFunctions":45}],43:[function(t,e,n){"use strict";var i=t("./dom");var r=t("./utilityFunctions");var a={};a.getPlayerSnapshot=function s(t){var e=t.el().querySelector(".vjs-tech");var n={ended:t.ended(),src:t.currentSrc(),currentTime:t.currentTime(),type:t.currentType(),playing:!t.paused(),suppressedTracks:i(t)};if(e){n.nativePoster=e.poster;n.style=e.getAttribute("style")}return n;function i(t){var e=t.remoteTextTracks?t.remoteTextTracks():[];if(e&&r.isArray(e.tracks_)){e=e.tracks_}if(!r.isArray(e)){e=[]}var n=[];e.forEach(function(t){n.push({track:t,mode:t.mode});t.mode="disabled"});return n}};a.restorePlayerSnapshot=function o(t,e){var n=t.el().querySelector(".vjs-tech");var i=20;if(e.nativePoster){n.poster=e.nativePoster}if("style"in e){n.setAttribute("style",e.style||"")}if(s(t,e)){t.one("contentloadedmetadata",o);t.one("canplay",u);r();t.src({src:e.src,type:e.type});t.load()}else{o();if(e.playing){t.play()}}function r(){var e=setTimeout(function(){t.trigger("canplay")},1e3);t.one("canplay",function(){clearTimeout(e)})}function s(t,e){if(t.src()){return t.src()!==e.src}return t.currentSrc()!==e.src}function o(){var t=e.suppressedTracks;t.forEach(function(t){t.track.mode=t.mode})}function u(){if(!a.isReadyToResume(t)&&i--){setTimeout(u,50)}else{try{if(t.currentTime()!==e.currentTime){if(e.playing){t.one("seeked",function(){t.play()})}t.currentTime(e.currentTime)}else if(e.playing){t.play()}}catch(n){videojs.log.warn("Failed to resume the content after an advertisement",n)}}}};a.isReadyToResume=function(t){if(t.readyState()>1){return true}if(t.seekable()===undefined){return true}if(t.seekable().length>0){return true}return false};a.prepareForAds=function(t){var e=t.addChild("blackPoster");var n=true;var a;s();t.on("play",u);t.on("vast.reset",l);t.on("vast.firstPlay",f);t.on("error",p);t.on("vast.adStart",p);t.on("vast.adsCancel",p);t.on("vast.adError",p);t.on("vast.adStart",v);t.on("vast.adEnd",g);t.on("vast.adsCancel",g);function s(){var e=t.play;t.play=function(n){var i=this;if(c()){s()}else{u(n)}return this;function s(){if(!r.isIPhone()){a=d();t.muted(true)}e.apply(i,arguments)}function u(n){if(o()&&!n){t.vast.adUnit.resumeAd()}else{e.apply(i,arguments)}}};var n=t.pause;t.pause=function(e){if(o()&&!e){t.vast.adUnit.pauseAd()}else{n.apply(this,arguments)}return this};var i=t.paused;t.paused=function(e){if(o()&&!e){return t.vast.adUnit.isPaused()}return i.apply(this,arguments)}}function o(){return t.vast&&t.vast.adUnit}function u(){if(c()){n=false;t.trigger("vast.firstPlay")}}function l(){n=true;e.show();f()}function c(){return n}function d(){return{muted:t.muted(),volume:t.volume()}}function f(){if(a){t.currentTime(0);h(a);a=null}}function h(e){if(r.isObject(e)){t.volume(e.volume);t.muted(e.muted)}}function p(){if(!i.hasClass(e.el(),"vjs-hidden")){e.hide()}}function v(){i.addClass(t.el(),"vjs-ad-playing")}function g(){i.removeClass(t.el(),"vjs-ad-playing")}};a.removeNativePoster=function(t){var e=t.el().querySelector(".vjs-tech");if(e){e.removeAttribute("poster")}};a.once=function u(t,e,n){function i(){n.apply(null,arguments);e.forEach(function(e){t.off(e,i)})}e.forEach(function(e){t.on(e,i)})};e.exports=a},{"./dom":41,"./utilityFunctions":45}],44:[function(t,e,n){"use strict";var i=t("./utilityFunctions");var r=document.createElement("a");var a=document.documentMode;function s(t){var e=t;if(a){r.setAttribute("href",e);e=r.href}r.setAttribute("href",e);return{href:r.href,protocol:r.protocol?r.protocol.replace(/:$/,""):"",host:r.host,search:r.search?r.search.replace(/^\?/,""):"",hash:r.hash?r.hash.replace(/^#/,""):"",hostname:r.hostname,port:i.isNotEmptyString(r.port)?r.port:80,pathname:r.pathname.charAt(0)==="/"?r.pathname:"/"+r.pathname}}function o(t,e){var n,r;e=i.isFunction(e)?e:function(){return true};t=t.trim().replace(/^\?/,"");n=t.split("&");r={};i.forEach(n,function(t){ -var n,i,a;if(t!==""){n=t.split("=");i=n[0];a=n[1];if(e(i,a)){r[i]=a}}});return r}function u(t){var e=[];i.forEach(t,function(t,n){e.push(n+"="+t)});return e.join("&")}e.exports={urlParts:s,queryStringToObj:o,objToQueryString:u}},{"./utilityFunctions":45}],45:[function(t,e,n){"use strict";var i=1;var r=/[A-Z]/g;var a=/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/i;var s=/^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;function o(){}function u(t){return t===null}function l(t){return t!==undefined}function c(t){return t===undefined}function d(t){return typeof t==="object"}function f(t){return typeof t==="function"}function h(t){return typeof t==="number"}function p(t){return j.isObject(t)&&t.window===t}function v(t){return Object.prototype.toString.call(t)==="[object Array]"}function g(t){if(t===null||j.isWindow(t)||j.isFunction(t)||j.isUndefined(t)){return false}var e=t.length;if(t.nodeType===i&&e){return true}return j.isString(t)||j.isArray(t)||e===0||typeof e==="number"&&e>0&&e-1 in t}function y(t){return typeof t==="string"}function m(t){return j.isString(t)&&t.length===0}function A(t){return j.isString(t)&&t.length!==0}function k(t){return Array.prototype.slice.call(t)}function _(t,e,n){var i,r;if(t){if(f(t)){for(i in t){if(i!=="prototype"&&i!=="length"&&i!=="name"&&(!t.hasOwnProperty||t.hasOwnProperty(i))){e.call(n,t[i],i,t)}}}else if(v(t)){var a=typeof t!=="object";for(i=0,r=t.length;i=e){n=i;t.apply(this,arguments)}}}function F(t,e){var n;return function(){if(n){clearTimeout(n)}n=setTimeout(function(){t.apply(this,arguments);n=undefined},e)}}function L(t,e,n){var i=e(t);for(var r=0;r0}return t.getElementsByTagNameNS(i,"parsererror").length>0}catch(r){}}};r.parseText=function s(t){if(/^\s*$/.test(t)){return null}if(/^(?:true|false)$/i.test(t)){return t.toLowerCase()==="true"}if(isFinite(t)){return parseFloat(t)}if(i.isISO8601(t)){return new Date(t)}return t.trim()};r.JXONTree=function o(t){var e=r.parseText;if(t.documentElement){return new r.JXONTree(t.documentElement)}if(t.hasChildNodes()){var n="";for(var a,s,o,u=0;u0:t.hasAttributes();if(l){var c;for(var d=0;d/g,">").replace(/"/g,""").replace(/'/g,"'")};r.decode=function f(t){return t.replace(/'/g,"'").replace(/"/g,'"').replace(/>/g,">").replace(/</g,"<").replace(/&/g,"&")};e.exports=r},{"./utilityFunctions":45}],47:[function(t,e,n){"use strict";t("./plugin/components/ads-label_4");t("./plugin/components/black-poster_4");var i=t("./plugin/videojs.vast.vpaid");videojs.plugin("vastClient",i)},{"./plugin/components/ads-label_4":36,"./plugin/components/black-poster_4":38,"./plugin/videojs.vast.vpaid":39}]},{},[47]); +(function t(e,n,i){function r(s,o){if(!n[s]){if(!e[s]){var u=typeof require=="function"&&require;if(!o&&u)return u(s,!0);if(a)return a(s,!0);var l=new Error("Cannot find module '"+s+"'");throw l.code="MODULE_NOT_FOUND",l}var c=n[s]={exports:{}};e[s][0].call(c.exports,function(t){var n=e[s][1][t];return r(n?n:t)},c,c.exports,t,e,n,i)}return n[s].exports}var a=typeof require=="function"&&require;for(var s=0;s0){i(e)}},0)}})}},{key:"_callCallback",value:function k(t,e,n,i){var r=this._callbacks.get(e);if(!r){if(n&&e===""){this.trigger(f,n)}return}p.call(this,e,n,i)}},{key:"_handShake",value:function _(t,e){this._ready=true;if(this._handShakeHandler){this._handShakeHandler(t,e);delete this._handShakeHandler}}},{key:"getSize",value:function E(){return{width:this._width,height:this._height}}},{key:"setSize",value:function T(t,e){this._width=s(t,this._width);this._height=s(e,this._height);this._el.setAttribute("width",this._width);this._el.setAttribute("height",this._height)}},{key:"getWidth",value:function b(){return this._width}},{key:"setWidth",value:function w(t){this.setSize(t,this._height)}},{key:"getHeight",value:function S(){return this._height}},{key:"setHeight",value:function V(t){this.setSize(this._width,t)}},{key:"getFlashID",value:function C(){return this._flashID}},{key:"getFlashURL",value:function I(){return this._flashURL}},{key:"isReady",value:function L(){return this._ready}},{key:"destroy",value:function F(){this.offAll();this.removeAllCallbacks();c.removeInstanceByID(this._flashID);if(this._el.parentElement){this._el.parentElement.removeChild(this._el)}}}]);return t}();function p(t,e,n){var i=this;setTimeout(function(){var r=i._callbacks.get(t);if(r){i._callbacks.remove(t);r(e,n)}},0)}Object.defineProperty(h,"VPAID_FLASH_HANDLER",{writable:false,configurable:false,value:d});window[d]=function(t,e,n,i,r,a){var s=c.getInstanceByID(t);if(!s)return;if(n==="handShake"){s._handShake(r,a)}else{if(e!=="event"){s._callCallback(n,i,r,a)}else{s._trigger(n,a)}}}},{"./jsFlashBridgeRegistry":5,"./registry":6,"./utils":7}],5:[function(t,e,n){"use strict";var i=t("./registry").SingleValueRegistry;var r=new i;var a={};Object.defineProperty(a,"addInstance",{writable:false,configurable:false,value:function s(t,e){r.add(t,e)}});Object.defineProperty(a,"getInstanceByID",{writable:false,configurable:false,value:function o(t){return r.get(t)}});Object.defineProperty(a,"removeInstanceByID",{writable:false,configurable:false,value:function u(t){return r.remove(t)}});e.exports=a},{"./registry":6}],6:[function(t,e,n){"use strict";var i=function(){function t(t,e){for(var n=0;n0?t:e}var u=function(){if(String.prototype.endsWith)return String.prototype.endsWith;return function t(e,n){var i=this.toString();if(n===undefined||n>i.length){n=i.length}n-=e.length;var r=i.indexOf(e,n);return r!==-1&&r===n}}();function l(t,e){return u.call(t,e)}},{}],8:[function(t,e,n){"use strict";var i=["handshakeVersion","initAd","startAd","stopAd","skipAd","resizeAd","pauseAd","resumeAd","expandAd","collapseAd","subscribe","unsubscribe"];var r=["AdLoaded","AdStarted","AdStopped","AdSkipped","AdSkippableStateChange","AdSizeChange","AdLinearChange","AdDurationChange","AdExpandedChange","AdRemainingTimeChange","AdVolumeChange","AdImpression","AdVideoStart","AdVideoFirstQuartile","AdVideoMidpoint","AdVideoThirdQuartile","AdVideoComplete","AdClickThru","AdInteraction","AdUserAcceptInvitation","AdUserMinimize","AdUserClose","AdPaused","AdPlaying","AdLog","AdError"];var a=["getAdLinear","getAdWidth","getAdHeight","getAdExpanded","getAdSkippableState","getAdRemainingTime","getAdDuration","getAdVolume","getAdCompanions","getAdIcons"];var s=["setAdVolume"];function o(t,e,n){}o.prototype.handshakeVersion=function(t,e){};o.prototype.initAd=function(t,e,n,i,r,a,s){};o.prototype.startAd=function(t){};o.prototype.stopAd=function(t){};o.prototype.skipAd=function(t){};o.prototype.resizeAd=function(t,e,n,i){};o.prototype.pauseAd=function(t){};o.prototype.resumeAd=function(t){};o.prototype.expandAd=function(t){};o.prototype.collapseAd=function(t){};o.prototype.subscribe=function(t,e,n){};o.prototype.unsubscribe=function(t,e){};o.prototype.getAdLinear=function(t){};o.prototype.getAdWidth=function(t){};o.prototype.getAdHeight=function(t){};o.prototype.getAdExpanded=function(t){};o.prototype.getAdSkippableState=function(t){};o.prototype.getAdRemainingTime=function(t){};o.prototype.getAdDuration=function(t){};o.prototype.getAdVolume=function(t){};o.prototype.getAdCompanions=function(t){};o.prototype.getAdIcons=function(t){};o.prototype.setAdVolume=function(t,e){};l(o,"METHODS",i);l(o,"GETTERS",a);l(o,"SETTERS",s);l(o,"EVENTS",r);var u=i.filter(function(t){return["skipAd"].indexOf(t)===-1});l(o,"checkVPAIDInterface",function c(t){var e=u.every(function(e){return typeof t[e]==="function"});return e});e.exports=o;function l(t,e,n){Object.defineProperty(t,e,{writable:false,configurable:false,value:n})}},{}],9:[function(t,e,n){"use strict";var i=t("./IVPAIDAdUnit");var r=t("./subscriber");var a=i.checkVPAIDInterface;var s=t("./utils");var o=i.METHODS;var u="AdError";var l="AdClickThru";var c=i.EVENTS.filter(function(t){return t!=l});function d(t,e,n,i){this._isValid=a(t);if(this._isValid){this._creative=t;this._el=e;this._videoEl=n;this._iframe=i;this._subscribers=new r;f.call(this)}}d.prototype=Object.create(i.prototype);d.prototype.isValidVPAIDAd=function g(){return this._isValid};i.METHODS.forEach(function(t){var e=["subscribe","unsubscribe","initAd"];if(e.indexOf(t)!==-1)return;d.prototype[t]=function(){var e=i.prototype[t].length;var n=Array.prototype.slice.call(arguments);var r=e===n.length?n.pop():undefined;setTimeout(function(){var e,i=null;try{e=this._creative[t].apply(this._creative,n)}catch(a){i=a}v(r,this._subscribers,i,e)}.bind(this),0)}});d.prototype.initAd=function m(t,e,n,i,r,a,o){r=r||{};a=s.extend({slot:this._el,videoSlot:this._videoEl},a||{});setTimeout(function(){var s;try{this._creative.initAd(t,e,n,i,r,a)}catch(u){s=u}v(o,this._subscribers,s)}.bind(this),0)};d.prototype.subscribe=function y(t,e,n){this._subscribers.subscribe(e,t,n)};d.prototype.unsubscribe=function A(t,e){this._subscribers.unsubscribe(e,t)};d.prototype.on=d.prototype.subscribe;d.prototype.off=d.prototype.unsubscribe;i.GETTERS.forEach(function(t){d.prototype[t]=function(e){setTimeout(function(){var n,i=null;try{n=this._creative[t]()}catch(r){i=r}v(e,this._subscribers,i,n)}.bind(this),0)}});d.prototype.setAdVolume=function k(t,e){setTimeout(function(){var n,i=null;try{this._creative.setAdVolume(t);n=this._creative.getAdVolume()}catch(r){i=r}if(!i){i=s.validate(n===t,"failed to apply volume: "+t)}v(e,this._subscribers,i,n)}.bind(this),0)};d.prototype._destroy=function _(){this.stopAd();this._subscribers.unsubscribeAll()};function f(){c.forEach(function(t){this._creative.subscribe(p.bind(this,t),t)}.bind(this));this._creative.subscribe(h.bind(this),l);if(this._videoEl){var t=this._iframe.contentDocument.documentElement;var e=this._videoEl;t.addEventListener("click",function(n){if(n.target===t){e.click()}})}}function h(t,e,n){this._subscribers.triggerSync(l,{url:t,id:e,playerHandles:n})}function p(t){this._subscribers.trigger(t,Array.prototype.slice(arguments,1))}function v(t,e,n,i){if(t){t(n,i)}else if(n){e.trigger(u,n)}}e.exports=d},{"./IVPAIDAdUnit":8,"./subscriber":11,"./utils":12}],10:[function(t,e,n){"use strict";var i=t("./utils");var r=i.unique("vpaidIframe");var a=t("./VPAIDAdUnit");var s='';s+='
';var o="AdStopped";function u(t,e,n,a){n=n||{};this._id=r();this._destroyed=false;this._frameContainer=i.createElementInEl(t,"div");this._videoEl=e;this._vpaidOptions=a||{timeout:1e4};this._templateConfig={template:n.template||s,extraOptions:n.extraOptions||{}}}u.prototype.destroy=function g(){if(this._destroyed){return}this._destroyed=true;d.call(this)};u.prototype.isDestroyed=function m(){return this._destroyed};u.prototype.loadAdUnit=function y(t,e){v.call(this);d.call(this);var n=i.createIframeWithContent(this._frameContainer,this._templateConfig.template,i.extend({iframeURL_JS:t,iframeID:this.getID()},this._templateConfig.extraOptions));this._frame=n;this._onLoad=i.callbackTimeout(this._vpaidOptions.timeout,r.bind(this),s.bind(this));window.addEventListener("message",this._onLoad);function r(t){if(t.origin!==window.location.origin)return;var n=JSON.parse(t.data);if(n.id!==this.getID())return;var r,s,u;if(!this._frame.contentWindow){s="the iframe is not anymore in the DOM tree"}else{u=this._frame.contentWindow.getVPAIDAd;s=i.validate(typeof u==="function","the ad didn't return a function to create an ad")}if(!s){var l=this._frame.contentWindow.document.querySelector(".ad-element");r=new a(u(),l,this._videoEl,this._frame);r.subscribe(o,c.bind(this));s=i.validate(r.isValidVPAIDAd(),"the add is not fully complaint with VPAID specification")}this._adUnit=r;h.call(this);e(s,s?null:r);return true}function s(){e("timeout",null)}};u.prototype.unloadAdUnit=function A(){d.call(this)};u.prototype.getID=function(){return this._id};function l(t){var e=this[t];if(e){e.remove();delete this[t]}}function c(){f.call(this);delete this._adUnit}function d(){f.call(this);p.call(this)}function f(){l.call(this,"_frame");h.call(this)}function h(){if(this._onLoad){window.removeEventListener("message",this._onLoad);i.clearCallbackTimeout(this._onLoad);delete this._onLoad}}function p(){if(this._adUnit){this._adUnit.stopAd();delete this._adUnit}}function v(){if(this._destroyed){throw new Error("VPAIDHTML5Client already destroyed!")}}e.exports=u;window.VPAIDHTML5Client=u},{"./VPAIDAdUnit":9,"./utils":12}],11:[function(t,e,n){"use strict";function i(){this._subscribers={}}i.prototype.subscribe=function r(t,e,n){this.get(e).push({handler:t,context:n})};i.prototype.unsubscribe=function a(t,e){this._subscribers[e]=this.get(e).filter(function(e){return t===e.handler})};i.prototype.unsubscribeAll=function s(){this._subscribers={}};i.prototype.trigger=function(t,e){var n=this;n.get(t).forEach(function(i){setTimeout(function(){if(n.get(t)){i.handler.call(i.context,e)}},0)})};i.prototype.triggerSync=function(t,e){this.get(t).forEach(function(t){t.handler.call(t.context,e)})};i.prototype.get=function o(t){if(!this._subscribers[t]){this._subscribers[t]=[]}return this._subscribers[t]};e.exports=i},{}],12:[function(t,e,n){"use strict";function i(){}function r(t,e){return t?null:new Error(e)}var a={};function s(t){var e=a[t];if(e){clearTimeout(e);delete a[t]}}function o(t,e,n){var r,o;o=setTimeout(function(){e=i;delete o[r];n()},t);r=function(){if(e.apply(this,arguments)){s(r)}};a[r]=o;return r}function u(t,e,n){var i=document.createElement(e);if(n)i.id=n;t.appendChild(i);return i}function l(t,e,n){var i=c(t);if(!f(i,d(e,n)))return;return i}function c(t,e){var n=document.createElement("iframe");n.src=e||"about:blank";n.marginWidth="0";n.marginHeight="0";n.frameBorder="0";n.width="100%";n.height="100%";n.style.position="absolute";n.style.left="0";n.style.top="0";n.style.margin="0px";n.style.padding="0px";n.style.border="none";n.setAttribute("SCROLLING","NO");t.innerHTML="";t.appendChild(n);return n}function d(t,e){Object.keys(e).forEach(function(n){var i=typeof i==="object"?JSON.stringify(e[n]):e[n];t=t.replace(new RegExp("{{"+n+"}}","g"),i)});return t}function f(t,e){var n=t.contentWindow&&t.contentWindow.document;if(!n)return false;n.write(e);return true}function h(t,e){Object.keys(e).forEach(function(n){t[n]=e[n]});return t}function p(t){var e=-1;return function(){return t+"_"+ ++e}}e.exports={noop:i,validate:r,clearCallbackTimeout:s,callbackTimeout:o,createElementInEl:u,createIframeWithContent:l,createIframe:c,simpleTemplate:d,setIframeContent:f,extend:h,unique:p}},{}],13:[function(t,e,n){"use strict";var i=t("./InLine");var r=t("./Wrapper");function a(t){if(!(this instanceof a)){return new a(t)}this.initialize(t)}a.prototype.initialize=function(t){this.id=t.attr("id");this.sequence=t.attr("sequence");if(t.inLine){this.inLine=new i(t.inLine)}if(t.wrapper){this.wrapper=new r(t.wrapper)}};e.exports=a},{"./InLine":16,"./Wrapper":26}],14:[function(t,e,n){"use strict";var i=t("./TrackingEvent");var r=t("../../utils/utilityFunctions");var a=t("../../utils/xml");function s(t){if(!(this instanceof s)){return new s(t)}this.creativeType=a.attr(t.staticResource,"creativeType");this.staticResource=a.keyValue(t.staticResource);var e=null;if(a.keyValue(t.HTMLResource)){e=a.keyValue(t.HTMLResource)}else if(a.keyValue(t.hTMLResource)){e=a.keyValue(t.hTMLResource)}this.htmlResource=e;var n=null;if(a.keyValue(t.IFrameResource)){n=a.keyValue(t.IFrameResource)}else if(a.keyValue(t.iFrameresource)){n=a.keyValue(t.iFrameresource)}this.iframeResource=n;this.id=a.attr(t,"id");this.width=a.attr(t,"width");this.height=a.attr(t,"height");this.expandedWidth=a.attr(t,"expandedWidth");this.expandedHeight=a.attr(t,"expandedHeight");this.scalable=a.attr(t,"scalable");this.maintainAspectRatio=a.attr(t,"maintainAspectRatio");this.minSuggestedDuration=a.attr(t,"minSuggestedDuration");this.apiFramework=a.attr(t,"apiFramework");this.companionClickThrough=a.keyValue(t.companionClickThrough);this.trackingEvents=o(t.trackingEvents&&t.trackingEvents.tracking);function o(t){var e=[];if(r.isDefined(t)){t=r.isArray(t)?t:[t];t.forEach(function(t){e.push(new i(t))})}return e}}e.exports=s},{"../../utils/utilityFunctions":43,"../../utils/xml":44,"./TrackingEvent":19}],15:[function(t,e,n){"use strict";var i=t("./Linear");var r=t("./Companion");var a=t("../../utils/utilityFunctions");function s(t){if(!(this instanceof s)){return new s(t)}this.id=t.attr("id");this.sequence=t.attr("sequence");this.adId=t.attr("adId");this.apiFramework=t.attr("apiFramework");if(t.linear){this.linear=new i(t.linear)}if(t.companionAds){var e=[];var n=t.companionAds&&t.companionAds.companion;n=a.isArray(n)?n:[n];n.forEach(function(t){e.push(new r(t))});this.companionAds=e}}e.exports=s},{"../../utils/utilityFunctions":43,"./Companion":14,"./Linear":17}],16:[function(t,e,n){"use strict";var i=t("./vastUtil");var r=t("../../utils/utilityFunctions");var a=t("../../utils/xml");function s(t){if(!(this instanceof s)){return new s(t)}this.adTitle=a.keyValue(t.adTitle);this.adSystem=a.keyValue(t.adSystem);this.impressions=i.parseImpressions(t.impression);this.creatives=i.parseCreatives(t.creatives);this.description=a.keyValue(t.description);this.advertiser=a.keyValue(t.advertiser);this.surveys=e(t.survey);this.error=a.keyValue(t.error);this.pricing=a.keyValue(t.pricing);this.extensions=t.extensions;function e(t){if(t){return r.transformArray(r.isArray(t)?t:[t],function(t){if(r.isNotEmptyString(t.keyValue)){return{uri:t.keyValue,type:t.attr("type")}}return undefined})}return[]}}e.exports=s},{"../../utils/utilityFunctions":43,"../../utils/xml":44,"./vastUtil":28}],17:[function(t,e,n){"use strict";var i=t("./TrackingEvent");var r=t("./MediaFile");var a=t("./VideoClicks");var s=t("../../utils/utilityFunctions");var o=t("./parsers");var u=t("../../utils/xml");function l(t){if(!(this instanceof l)){return new l(t)}this.duration=o.duration(u.keyValue(t.duration));this.mediaFiles=n(t.mediaFiles&&t.mediaFiles.mediaFile);this.trackingEvents=e(t.trackingEvents&&t.trackingEvents.tracking,this.duration);this.skipoffset=o.offset(u.attr(t,"skipoffset"),this.duration); +if(t.videoClicks){this.videoClicks=new a(t.videoClicks)}if(t.adParameters){this.adParameters=u.keyValue(t.adParameters);if(u.attr(t.adParameters,"xmlEncoded")){this.adParameters=u.decode(this.adParameters)}}function e(t,e){var n=[];if(s.isDefined(t)){t=s.isArray(t)?t:[t];t.forEach(function(t){n.push(new i(t,e))})}return n}function n(t){var e=[];if(s.isDefined(t)){t=s.isArray(t)?t:[t];t.forEach(function(t){e.push(new r(t))})}return e}}e.exports=l},{"../../utils/utilityFunctions":43,"../../utils/xml":44,"./MediaFile":18,"./TrackingEvent":19,"./VideoClicks":25,"./parsers":27}],18:[function(t,e,n){"use strict";var i=t("../../utils/xml");var r=["delivery","type","width","height","codec","id","bitrate","minBitrate","maxBitrate","scalable","maintainAspectRatio","apiFramework"];function a(t){if(!(this instanceof a)){return new a(t)}this.src=i.keyValue(t);for(var e=0;e0){d(r.shift(),[],a)}else{e(t,i)}}else{e(null,i)}}});function a(t,e){var i=n._requestVASTXml.bind(n,t);o.waterfall([i,s],e)}function s(t,e){var n;try{n=c.toJXONTree(t);if(l.isArray(n.ad)){n.ads=n.ad}else if(n.ad){n.ads=[n.ad]}else{n.ads=[]}e(u(n),n)}catch(i){e(new r("on VASTClient.getVASTAd.buildVastWaterfall, error parsing xml",100),null)}}function u(t){var e=c.attr(t,"version");if(!t.ad){return new r("on VASTClient.getVASTAd.validateVASTTree, no Ad in VAST tree",303)}if(e&&(e!=3&&e!=2)){return new r('on VASTClient.getVASTAd.validateVASTTree, not supported VAST version "'+e+'"',102)}return null}function d(t,e,i){if(e.length>=n.WRAPPER_LIMIT){return i(new r("on VASTClient.getVASTAd.getAd, players wrapper limit reached (the limit is "+n.WRAPPER_LIMIT+")",302),e)}o.waterfall([function(e){if(l.isString(t)){p(t,e)}else{e(null,t)}},f],function(t,n){if(n){e.push(n)}if(t){return i(t,e)}if(n.wrapper){return d(n.wrapper.VASTAdTagURI,e,i)}return i(null,e)})}function f(t,e){try{var n=new i(t);e(h(n),n)}catch(a){e(new r("on VASTClient.getVASTAd.buildAd, error parsing xml",100),null)}}function h(t){var e=t.wrapper;var n=t.inLine;var i="on VASTClient.getVASTAd.validateAd, ";if(n&&e){return new r(i+"InLine and Wrapper both found on the same Ad",101)}if(!n&&!e){return new r(i+"nor wrapper nor inline elements found on the Ad",101)}if(n&&n.creatives.length===0){return new r(i+"missing creative in InLine element",101)}if(e&&!e.VASTAdTagURI){return new r(i+"missing 'VASTAdTagURI' in wrapper",101)}}function p(t,e){n._requestVASTXml(t,function(t,n){if(t){return e(t)}try{var i=c.toJXONTree(n);e(u(i),i.ad)}catch(a){e(new r("on VASTClient.getVASTAd.requestVASTAd, error parsing xml",100))}})}};d.prototype._requestVASTXml=function h(t,e){try{if(l.isFunction(t)){t(i)}else{u.get(t,i,{withCredentials:true})}}catch(n){e(n)}function i(t,n,i){if(t){var a=l.isDefined(i)?"on VASTClient.requestVastXML, HTTP request error with status '"+i+"'":"on VASTClient.requestVastXML, Error getting the the VAST XML with he passed adTagXML fn";return e(new r(a,301),null)}e(null,n)}};d.prototype._buildVASTResponse=function p(t){var e=new a;n(e,t);i(e);return e;function n(t,e){e.forEach(function(e){t.addAd(e)})}function i(t){var e=t.trackingEvents.progress;if(!t.hasLinear()){throw new r("on VASTClient._buildVASTResponse, Received an Ad type that is not supported",200)}if(t.duration===undefined){throw new r("on VASTClient._buildVASTResponse, Missing duration field in VAST response",101)}if(e){e.forEach(function(t){if(!l.isNumber(t.offset)){throw new r("on VASTClient._buildVASTResponse, missing or wrong offset attribute on progress tracking event",101)}})}}};d.prototype._trackError=function(t,e){if(!l.isArray(e)||e.length===0){return}var n=[];e.forEach(i);s.track(n,{ERRORCODE:t.code||900});function i(t){if(t.wrapper&&t.wrapper.error){n.push(t.wrapper.error)}if(t.inLine&&t.inLine.error){n.push(t.inLine.error)}}};e.exports=d},{"../../utils/async":38,"../../utils/http":40,"../../utils/utilityFunctions":43,"../../utils/xml":44,"./Ad":13,"./VASTError":21,"./VASTResponse":23,"./vastUtil":28}],21:[function(t,e,n){"use strict";function i(t,e){this.message="VAST Error: "+(t||"");if(e){this.code=e}}i.prototype=new Error;i.prototype.name="VAST Error";e.exports=i},{}],22:[function(t,e,n){"use strict";var i=t("./VASTResponse");var r=t("./VASTError");var a=t("./VASTTracker");var s=t("./vastUtil");var o=t("../../utils/async");var u=t("../../utils/dom");var l=t("../../utils/playerUtils");var c=t("../../utils/utilityFunctions");function d(t){if(!(this instanceof d)){return new d(t)}this.player=t}d.prototype.playAd=function f(t,e){var n=this;e=e||c.noop;if(!(t instanceof i)){return e(new r("On VASTIntegrator, missing required VASTResponse"))}o.waterfall([function(e){e(null,t)},this._selectAdSource.bind(this),this._createVASTTracker.bind(this),this._addClickThrough.bind(this),this._addSkipButton.bind(this),this._setupEvents.bind(this),this._playSelectedAd.bind(this)],function(t,i){if(t&&i){n._trackError(t,i)}e(t,i)});this._adUnit={_src:null,type:"VAST",pauseAd:function(){n.player.pause(true)},resumeAd:function(){n.player.play(true)},isPaused:function(){return n.player.paused(true)},getSrc:function(){return this._src}};return this._adUnit};d.prototype._selectAdSource=function h(t,e){var n;var i=u.getDimension(this.player.el()).width;t.mediaFiles.sort(function a(t,e){var n=Math.abs(i-t.width);var r=Math.abs(i-e.width);return n-r});n=this.player.selectSource(t.mediaFiles).source;if(n){if(this._adUnit){this._adUnit._src=n}return e(null,n,t)}e(new r("Could not find Ad mediafile supported by this player",403),t)};d.prototype._createVASTTracker=function p(t,e,n){try{n(null,t,new a(t.src,e),e)}catch(i){n(i,e)}};d.prototype._setupEvents=function v(t,e,n,i){var r;var a=this.player;a.on("fullscreenchange",o);a.on("vast.adStart",d);a.on("pause",u);a.on("timeupdate",c);a.on("volumechange",f);l.once(a,["vast.adEnd","vast.adsCancel"],s);l.once(a,["vast.adEnd","vast.adsCancel","vast.adSkip"],function(t){if(t.type==="vast.adEnd"){e.trackComplete()}});return i(null,t,n);function s(){a.off("fullscreenchange",o);a.off("vast.adStart",d);a.off("pause",u);a.off("timeupdate",c);a.off("volumechange",f)}function o(){if(a.isFullscreen()){e.trackFullscreen()}else{e.trackExitFullscreen()}}function u(){if(Math.abs(a.duration()-a.currentTime())<2){return}e.trackPause();l.once(a,["play","vast.adEnd","vast.adsCancel"],function(t){if(t.type==="play"){e.trackResume()}})}function c(){var t=a.currentTime()*1e3;e.trackProgress(t)}function d(){e.trackImpressions();e.trackCreativeView()}function f(){var t=a.muted();if(t){e.trackMute()}else if(r){e.trackUnmute()}r=t}};d.prototype._addSkipButton=function g(t,e,n,i){var r;var a=this;if(c.isNumber(n.skipoffset)){r=n.skipoffset/1e3;s(this.player,r)}i(null,t,e,n);function s(t,e){var n=o(t);var i=d.bind(a,n,e,t);t.el().appendChild(n);t.on("timeupdate",i);l.once(t,["vast.adEnd","vast.adsCancel"],r);function r(){t.off("timeupdate",i);u.remove(n)}}function o(t){var n=window.document.createElement("div");u.addClass(n,"vast-skip-button");n.onclick=function(i){if(u.hasClass(n,"enabled")){e.trackSkip();t.trigger("vast.adSkip")}if(window.Event.prototype.stopPropagation!==undefined){i.stopPropagation()}else{return false}};return n}function d(t,e,n){var i=Math.ceil(e-n.currentTime());if(i>0){t.innerHTML="Skip in "+c.toFixedDigits(i,2)+"..."}else{if(!u.hasClass(t,"enabled")){u.addClass(t,"enabled");t.innerHTML="Skip ad"}}}};d.prototype._addClickThrough=function m(t,e,n,i){var r=this.player;var a=d(r,e,n);var o=f.bind(this,a,n,r);r.el().insertBefore(a,r.controlBar.el());r.on("timeupdate",o);l.once(r,["vast.adEnd","vast.adsCancel"],p);return i(null,t,e,n);function d(t,e,n){var i=window.document.createElement("a");var r=n.clickThrough;u.addClass(i,"vast-blocker");i.href=h(r,t);if(c.isString(r)){i.target="_blank"}i.onclick=function(n){if(t.paused()){t.play();if(window.Event.prototype.stopPropagation!==undefined){n.stopPropagation()}return false}t.pause();e.trackClick()};return i}function f(t,e,n){t.href=h(e.clickThrough,n)}function h(e,n){var i={ASSETURI:t.src,CONTENTPLAYHEAD:s.formatProgress(n.currentTime()*1e3)};return e?s.parseURLMacro(e,i):"#"}function p(){r.off("timeupdate",o);u.remove(a)}};d.prototype._playSelectedAd=function y(t,e,n){var i=this.player;i.preload("auto");i.src(t);l.once(i,["durationchange","error","vast.adsCancel"],function(t){if(t.type==="durationchange"){a()}else if(t.type==="error"){n(new r("on VASTIntegrator, Player is unable to play the Ad",400),e)}});function a(){l.once(i,["playing","vast.adsCancel"],function(t){if(t.type==="vast.adsCancel"){return}i.trigger("vast.adStart");l.once(i,["ended","vast.adsCancel","vast.adSkip"],function(t){if(t.type==="ended"||t.type==="vast.adSkip"){n(null,e)}})});i.play()}};d.prototype._trackError=function A(t,e){s.track(e.errorURLMacros,{ERRORCODE:t.code||900})};e.exports=d},{"../../utils/async":38,"../../utils/dom":39,"../../utils/playerUtils":41,"../../utils/utilityFunctions":43,"./VASTError":21,"./VASTResponse":23,"./VASTTracker":24,"./vastUtil":28}],23:[function(t,e,n){"use strict";var i=t("./Ad");var r=t("./VideoClicks");var a=t("./Linear");var s=t("./InLine");var o=t("./Wrapper");var u=t("../../utils/utilityFunctions");var l=t("../../utils/xml");window.InLine__A=s;function c(){if(!(this instanceof c)){return new c}this._linearAdded=false;this.ads=[];this.errorURLMacros=[];this.impressions=[];this.clickTrackings=[];this.customClicks=[];this.trackingEvents={};this.mediaFiles=[];this.clickThrough=undefined;this.adTitle="";this.duration=undefined;this.skipoffset=undefined}c.prototype.addAd=function(t){var e,n;if(t instanceof i){e=t.inLine;n=t.wrapper;this.ads.push(t);if(e){this._addInLine(e)}if(n){this._addWrapper(n)}}};c.prototype._addErrorTrackUrl=function(t){var e=t instanceof l.JXONTree?l.keyValue(t):t;if(e){this.errorURLMacros.push(e)}};c.prototype._addImpressions=function(t){u.isArray(t)&&d(this.impressions,t)};c.prototype._addClickThrough=function(t){if(u.isNotEmptyString(t)){this.clickThrough=t}};c.prototype._addClickTrackings=function(t){u.isArray(t)&&d(this.clickTrackings,t)};c.prototype._addCustomClicks=function(t){u.isArray(t)&&d(this.customClicks,t)};c.prototype._addTrackingEvents=function(t){var e=this.trackingEvents;if(t){t=u.isArray(t)?t:[t];t.forEach(function(t){if(!e[t.name]){e[t.name]=[]}e[t.name].push(t)})}};c.prototype._addTitle=function(t){if(u.isNotEmptyString(t)){this.adTitle=t}};c.prototype._addDuration=function(t){if(u.isNumber(t)){this.duration=t}};c.prototype._addVideoClicks=function(t){if(t instanceof r){this._addClickThrough(t.clickThrough);this._addClickTrackings(t.clickTrackings);this._addCustomClicks(t.customClicks)}};c.prototype._addMediaFiles=function(t){u.isArray(t)&&d(this.mediaFiles,t)};c.prototype._addSkipoffset=function(t){if(t){this.skipoffset=t}};c.prototype._addAdParameters=function(t){if(t){this.adParameters=t}};c.prototype._addLinear=function(t){if(t instanceof a){this._addDuration(t.duration);this._addTrackingEvents(t.trackingEvents);this._addVideoClicks(t.videoClicks);this._addMediaFiles(t.mediaFiles);this._addSkipoffset(t.skipoffset);this._addAdParameters(t.adParameters);this._linearAdded=true}};c.prototype._addInLine=function(t){var e=this;if(t instanceof s){this._addTitle(t.adTitle);this._addErrorTrackUrl(t.error);this._addImpressions(t.impressions);t.creatives.forEach(function(t){if(t.linear){e._addLinear(t.linear)}})}};c.prototype._addWrapper=function(t){var e=this;if(t instanceof o){this._addErrorTrackUrl(t.error);this._addImpressions(t.impressions);t.creatives.forEach(function(t){var n=t.linear;if(n){e._addVideoClicks(n.videoClicks);e.clickThrough=undefined;e._addTrackingEvents(n.trackingEvents)}})}};c.prototype.hasLinear=function(){return this._linearAdded};function d(t,e){e.forEach(function(e){t.push(e)})}e.exports=c},{"../../utils/utilityFunctions":43,"../../utils/xml":44,"./Ad":13,"./InLine":16,"./Linear":17,"./VideoClicks":25,"./Wrapper":26}],24:[function(t,e,n){"use strict";var i=t("./VASTError");var r=t("./VASTResponse");var a=t("./vastUtil");var s=t("../../utils/utilityFunctions");function o(t,e){if(!(this instanceof o)){return new o(t,e)}this.sanityCheck(t,e);this.initialize(t,e)}o.prototype.initialize=function(t,e){this.response=e;this.assetURI=t;this.progress=0;this.quartiles={firstQuartile:{tracked:false,time:Math.round(25*e.duration)/100},midpoint:{tracked:false,time:Math.round(50*e.duration)/100},thirdQuartile:{tracked:false,time:Math.round(75*e.duration)/100}}};o.prototype.sanityCheck=function(t,e){if(!s.isString(t)||s.isEmptyString(t)){throw new i("on VASTTracker constructor, missing required the URI of the ad asset being played")}if(!(e instanceof r)){throw new i("on VASTTracker constructor, missing required VAST response")}};o.prototype.trackURLs=function u(t,e){if(s.isArray(t)&&t.length>0){e=s.extend({ASSETURI:this.assetURI,CONTENTPLAYHEAD:a.formatProgress(this.progress)},e||{});a.track(t,e)}};o.prototype.trackEvent=function l(t,e){this.trackURLs(n(this.response.trackingEvents[t]));if(e){this.response.trackingEvents[t]=undefined}function n(t){var e;if(t){e=[];t.forEach(function(t){e.push(t.uri)})}return e}};o.prototype.trackProgress=function c(t){var e=this;var n=[];var i=true;var r=false;var a=this.response.trackingEvents;if(s.isNumber(t)){u("start",i,t>0);u("rewind",r,o(this.progress,t));l(t);d(t);f();this.progress=t}function o(e,n){var i=3e3;return e>t&&Math.abs(n-e)>i}function u(t,e,i){if(a[t]&&i){n.push({name:t,trackOnce:!!e})}}function l(t){var n=e.quartiles;var r=e.quartiles.firstQuartile;var a=e.quartiles.midpoint;var s=e.quartiles.thirdQuartile;if(!r.tracked){o("firstQuartile",t)}else if(!a.tracked){o("midpoint",t)}else if(!s.tracked){o("thirdQuartile",t)}function o(t,e){var r=n[t];if(c(r,e)){r.tracked=true;u(t,i,true)}}}function c(t,e){var n=t.time;return e>=n&&e<=n+5e3}function d(t){if(!s.isArray(a.progress)){return}var n=[];a.progress.forEach(function(i){if(i.offset<=t){e.trackURLs([i.uri])}else{n.push(i)}});a.progress=n}function f(){n.forEach(function(t){e.trackEvent(t.name,t.trackOnce)})}};["rewind","fullscreen","exitFullscreen","pause","resume","mute","unmute","acceptInvitation","acceptInvitationLinear","collapse","expand"].forEach(function(t){o.prototype["track"+s.capitalize(t)]=function(){this.trackEvent(t)}});["start","skip","close","closeLinear"].forEach(function(t){o.prototype["track"+s.capitalize(t)]=function(){this.trackEvent(t,true)}});["firstQuartile","midpoint","thirdQuartile"].forEach(function(t){o.prototype["track"+s.capitalize(t)]=function(){this.quartiles[t].tracked=true;this.trackEvent(t,true)}});o.prototype.trackComplete=function(){if(this.quartiles.thirdQuartile.tracked){this.trackEvent("complete",true)}};o.prototype.trackErrorWithCode=function d(t){if(s.isNumber(t)){this.trackURLs(this.response.errorURLMacros,{ERRORCODE:t})}};o.prototype.trackImpressions=function f(){this.trackURLs(this.response.impressions)};o.prototype.trackCreativeView=function h(){this.trackEvent("creativeView")};o.prototype.trackClick=function p(){this.trackURLs(this.response.clickTrackings)};e.exports=o},{"../../utils/utilityFunctions":43,"./VASTError":21,"./VASTResponse":23,"./vastUtil":28}],25:[function(t,e,n){"use strict";var i=t("../../utils/utilityFunctions");var r=t("../../utils/xml");function a(t){if(!(this instanceof a)){return new a(t)}this.clickThrough=r.keyValue(t.clickThrough);this.clickTrackings=e(t.clickTracking);this.customClicks=e(t.customClick);function e(t){var e=[];if(t){t=i.isArray(t)?t:[t];t.forEach(function(t){e.push(r.keyValue(t))})}return e}}e.exports=a},{"../../utils/utilityFunctions":43,"../../utils/xml":44}],26:[function(t,e,n){"use strict";var i=t("./vastUtil");var r=t("../../utils/utilityFunctions");var a=t("../../utils/xml");function s(t){if(!(this instanceof s)){return new s(t)}this.adSystem=a.keyValue(t.adSystem);this.impressions=i.parseImpressions(t.impression);this.VASTAdTagURI=a.keyValue(t.vASTAdTagURI);this.creatives=i.parseCreatives(t.creatives);this.error=a.keyValue(t.error);this.extensions=t.extensions;this.followAdditionalWrappers=r.isDefined(a.attr(t,"followAdditionalWrappers"))?a.attr(t,"followAdditionalWrappers"):true;this.allowMultipleAds=a.attr(t,"allowMultipleAds");this.fallbackOnNoAd=a.attr(t,"fallbackOnNoAd")}e.exports=s},{"../../utils/utilityFunctions":43,"../../utils/xml":44,"./vastUtil":28}],27:[function(t,e,n){"use strict";var i=t("../../utils/utilityFunctions");var r=/(\d\d):(\d\d):(\d\d)(\.(\d\d\d))?/;var a={duration:function s(t){var e,n;if(i.isString(t)){e=t.match(r);if(e){n=a(e[1])+s(e[2])+o(e[3])+parseInt(e[5]||0)}}return isNaN(n)?null:n;function a(t){return parseInt(t,10)*60*60*1e3}function s(t){return parseInt(t,10)*60*1e3}function o(t){return parseInt(t,10)*1e3}},offset:function o(t,e){if(n(t)){return i(t,e)}return a.duration(t);function n(t){var e=/^\d+(\.\d+)?%$/g;return e.test(t)}function i(t,e){if(e){return r(e,parseFloat(t.replace("%","")))}return null}function r(t,e){return t*e/100}}};e.exports=a},{"../../utils/utilityFunctions":43}],28:[function(t,e,n){"use strict";var i=t("./Creative");var r=t("../../utils/utilityFunctions");var a={track:function s(t,e){var n=a.parseURLMacros(t,e);var i=[];n.forEach(function(t){var e=new Image;e.src=t;i.push(e)});return i},parseURLMacros:function o(t,e){var n=[];e=e||{};if(!e["CACHEBUSTING"]){e["CACHEBUSTING"]=Math.round(Math.random()*1e10)}t.forEach(function(t){n.push(a._parseURLMacro(t,e))});return n},parseURLMacro:function u(t,e){e=e||{};if(!e["CACHEBUSTING"]){e["CACHEBUSTING"]=Math.round(Math.random()*1e10)}return a._parseURLMacro(t,e)},_parseURLMacro:function l(t,e){e=e||{};r.forEach(e,function(e,n){t=t.replace(new RegExp("\\["+n+"\\]","gm"),e)});return t},parseDuration:function c(t){var e=/(\d\d):(\d\d):(\d\d)(\.(\d\d\d))?/;var n,i;if(r.isString(t)){n=t.match(e);if(n){i=a(n[1])+s(n[2])+o(n[3])+parseInt(n[5]||0)}}return isNaN(i)?null:i;function a(t){return parseInt(t,10)*60*60*1e3}function s(t){return parseInt(t,10)*60*1e3}function o(t){return parseInt(t,10)*1e3}},parseImpressions:function d(t){if(t){t=r.isArray(t)?t:[t];return r.transformArray(t,function(t){if(r.isNotEmptyString(t.keyValue)){return t.keyValue}return undefined})}return[]},parseCreatives:function f(t){var e=[];var n;if(r.isDefined(t)&&r.isDefined(t.creative)){n=r.isArray(t.creative)?t.creative:[t.creative];n.forEach(function(t){e.push(new i(t))})}return e},formatProgress:function h(t){var e,n,i,a;e=t/(60*60*1e3);e=Math.floor(e);n=t/(60*1e3)%60;n=Math.floor(n);i=t/1e3%60;i=Math.floor(i);a=t%1e3;return r.toFixedDigits(e,2)+":"+r.toFixedDigits(n,2)+":"+r.toFixedDigits(i,2)+"."+r.toFixedDigits(a,3)},parseOffset:function p(t,e){if(n(t)){return i(t,e)}return a.parseDuration(t);function n(t){var e=/^\d+(\.\d+)?%$/g;return e.test(t)}function i(t,e){if(e){return r(e,parseFloat(t.replace("%","")))}return null}function r(t,e){return t*e/100}},isVPAID:function v(t){return!!t&&t.apiFramework==="VPAID"}};e.exports=a},{"../../utils/utilityFunctions":43,"./Creative":15}],29:[function(t,e,n){"use strict";var i=t("../vast/VASTError");var r=t("../../utils/utilityFunctions");function a(t,e){if(!(this instanceof a)){return new a(t,e)}n(t,e);this.options=r.extend({},e);this._adUnit=t;function n(t,e){if(!t||!a.checkVPAIDInterface(t)){throw new i("on VPAIDAdUnitWrapper, the passed VPAID adUnit does not fully implement the VPAID interface")}if(!r.isObject(e)){throw new i("on VPAIDAdUnitWrapper, expected options hash but got '"+e+"'")}if(!("responseTimeout"in e)||!r.isNumber(e.responseTimeout)){throw new i("on VPAIDAdUnitWrapper, expected responseTimeout in options")}}}a.checkVPAIDInterface=function s(t){var e=["handshakeVersion","initAd","startAd","stopAd","resizeAd","pauseAd","expandAd","collapseAd"];for(var n=0,i=e.length;n=1&&e<=2}function a(t){var e=t.split(".");return parseInt(e[0],10)}};p.prototype._initAd=function(t,e,n){var i=this.player.el().querySelector(".vjs-tech");var r=d.getDimension(i);t.initAd(r.width,r.height,this.VIEW_MODE.NORMAL,-1,{AdParameters:e.adParameters||""},function(i){n(i,t,e)})};p.prototype._createVASTTracker=function(t,e){return new a(t,e)};p.prototype._setupEvents=function(t,e,n){var i=t.options.src;var r=this._createVASTTracker(i,e);var a=this.player;var o=this;t.on("AdSkipped",function(){a.trigger("vpaid.AdSkipped");r.trackSkip()});t.on("AdImpression",function(){a.trigger("vpaid.AdImpression");r.trackImpressions()});t.on("AdStarted",function(){a.trigger("vpaid.AdStarted");r.trackCreativeView();u()});t.on("AdVideoStart",function(){a.trigger("vpaid.AdVideoStart");r.trackStart();u()});t.on("AdPlaying",function(){a.trigger("vpaid.AdPlaying");r.trackResume();u()});t.on("AdPaused",function(){a.trigger("vpaid.AdPaused");r.trackPause();l()});function u(){if(o._adUnit&&o._adUnit.isPaused()){o._adUnit._paused=false}a.trigger("play")}function l(){if(o._adUnit){o._adUnit._paused=true}a.trigger("pause")}t.on("AdVideoFirstQuartile",function(){a.trigger("vpaid.AdVideoFirstQuartile");r.trackFirstQuartile()});t.on("AdVideoMidpoint",function(){a.trigger("vpaid.AdVideoMidpoint");r.trackMidpoint()});t.on("AdVideoThirdQuartile",function(){a.trigger("vpaid.AdVideoThirdQuartile");r.trackThirdQuartile()});t.on("AdVideoComplete",function(){a.trigger("vpaid.AdVideoComplete");r.trackComplete()});t.on("AdClickThru",function(n){a.trigger("vpaid.AdClickThru");var i=n.url; +var o=n.playerHandles;var u=h.isNotEmptyString(i)?i:l(e.clickThrough);r.trackClick();if(o&&u){window.open(u,"_blank")}function l(e){var n={ASSETURI:t.options.src,CONTENTPLAYHEAD:0};return e?s.parseURLMacro(e,n):null}});t.on("AdUserAcceptInvitation",function(){a.trigger("vpaid.AdUserAcceptInvitation");r.trackAcceptInvitation();r.trackAcceptInvitationLinear()});t.on("AdUserClose",function(){a.trigger("vpaid.AdUserClose");r.trackClose();r.trackCloseLinear()});t.on("AdUserMinimize",function(){a.trigger("vpaid.AdUserMinimize");r.trackCollapse()});t.on("AdError",function(){a.trigger("vpaid.AdError");r.trackErrorWithCode(901)});t.on("AdVolumeChange",function(){a.trigger("vpaid.AdVolumeChange");var e=a.volume();t.getAdVolume(function(t,n){if(n===0&&e>0){r.trackMute()}if(n>0&&e===0){r.trackUnmute()}a.volume(n)})});var c=v.bind(this,a,t,this.VIEW_MODE);var f=h.throttle(c,100);var p=this.settings.autoResize;if(p){d.addEventListener(window,"resize",f);d.addEventListener(window,"orientationchange",f)}a.on("vast.resize",c);a.on("vpaid.pauseAd",g);a.on("vpaid.resumeAd",m);a.one("vpaid.adEnd",function(){a.off("vast.resize",c);a.off("vpaid.pauseAd",g);a.off("vpaid.resumeAd",m);if(p){d.removeEventListener(window,"resize",f);d.removeEventListener(window,"orientationchange",f)}});n(null,t,e);function g(){t.pauseAd(h.noop)}function m(){t.resumeAd(h.noop)}};p.prototype._addSkipButton=function(t,e,n){var i;var r=this.player;t.on("AdSkippableStateChange",a);f.once(r,["vast.adEnd","vast.adsCancel"],o);n(null,t,e);function a(){r.trigger("vpaid.AdSkippableStateChange");t.getAdSkippableState(function(t,e){if(e){if(!i){s(r)}}else{o(r)}})}function s(t){i=u(t);t.el().appendChild(i)}function o(){d.remove(i);i=null}function u(){var e=window.document.createElement("div");d.addClass(e,"vast-skip-button");d.addClass(e,"enabled");e.innerHTML="Skip ad";e.onclick=function(e){t.skipAd(h.noop);if(window.Event.prototype.stopPropagation!==undefined){e.stopPropagation()}else{return false}};return e}};p.prototype._linkPlayerControls=function(t,e,n){var i=this;r(this.player,t);a(this.player,t,this.VIEW_MODE);n(null,t,e);function r(t,e){t.on("volumechange",n);e.on("AdVolumeChange",i);t.one("vpaid.adEnd",function(){t.off("volumechange",n)});function n(){var n=t.muted()?0:t.volume();e.setAdVolume(n,g)}function i(){t.trigger("vpaid.AdVolumeChange");e.getAdVolume(function(e,n){if(e){g(e)}else{t.volume(n)}})}}function a(t,e,n){var r=v.bind(i,t,e,n);t.on("fullscreenchange",r);t.one("vpaid.adEnd",function(){t.off("fullscreenchange",r)})}};p.prototype._startAd=function(t,e,n){var i=this.player;t.startAd(function(r){if(!r){i.trigger("vast.adStart")}n(r,t,e)})};p.prototype._finishPlaying=function(t,e,n){var r=this.player;t.on("AdStopped",function(){r.trigger("vpaid.AdStopped");a(null)});t.on("AdError",function(t){var e=t?t.message:"on VPAIDIntegrator, error while waiting for the adUnit to finish playing";a(new i(e))});function a(i){n(i,t,e)}};p.prototype._trackError=function A(t){s.track(t.errorURLMacros,{ERRORCODE:901})};function v(t,e,n){var i=t.el().querySelector(".vjs-tech");var r=d.getDimension(i);var a=t.isFullscreen()?n.FULLSCREEN:n.NORMAL;e.resizeAd(r.width,r.height,a,g)}function g(t){if(t&&console&&console.log){console.log("ERROR: "+t.message,t)}}e.exports=p},{"../../utils/async":38,"../../utils/dom":39,"../../utils/playerUtils":41,"../../utils/utilityFunctions":43,"../vast/VASTError":21,"../vast/VASTResponse":23,"../vast/VASTTracker":24,"../vast/vastUtil":28,"./VPAIDAdUnitWrapper":29,"./VPAIDFlashTech":30,"./VPAIDHTML5Tech":31}],33:[function(t,e,n){"use strict";var i=t("../../utils/dom");var r=document.createElement("div");r.className="vjs-ads-label vjs-control vjs-label-hidden";r.innerHTML="Advertisement";var a=function(t){return{init:function e(n,a){a.el=r;t.call(this,n,a);setTimeout(function(){var t=n.controlBar&&(n.controlBar.getChild("timerControls")||n.controlBar.getChild("currentTimeDisplay"));if(t){n.controlBar.el().insertBefore(r,t.el())}i.removeClass(r,"vjs-label-hidden")},0)},el:function n(){return r}}};e.exports=a},{"../../utils/dom":39}],34:[function(t,e,n){"use strict";var i=videojs.Component;var r=t("./ads-label")(i);videojs.AdsLabel=videojs.Component.extend(r)},{"./ads-label":33}],35:[function(t,e,n){"use strict";var i=document.createElement("div");var r=function(t){return{init:function e(n,r){r.el=i;i.className="vjs-black-poster";t.call(this,n,r);var a=n.getChild("posterImage");setTimeout(function(){if(a&&n&&n.el()){n.el().insertBefore(i,a.el())}},0)},el:function n(){return i}}};e.exports=r},{}],36:[function(t,e,n){"use strict";var i=videojs.Component;var r=t("./black-poster")(i);videojs.BlackPoster=videojs.Component.extend(r)},{"./black-poster":35}],37:[function(t,e,n){"use strict";var i=t("../ads/vast/VASTClient");var r=t("../ads/vast/VASTError");var a=t("../ads/vast/vastUtil");var s=t("../ads/vast/VASTIntegrator");var o=t("../ads/vpaid/VPAIDIntegrator");var u=t("../utils/async");var l=t("../utils/dom");var c=t("../utils/playerUtils");var d=t("../utils/utilityFunctions");e.exports=function f(t){var e;var n=this;var f=new i;var h=false;var p={timeout:500,iosPrerollCancelTimeout:2e3,adCancelTimeout:3e3,playAdAlways:false,adsEnabled:true,autoResize:true,vpaidFlashLoaderPath:"/VPAIDFlash.swf"};var v=d.extend({},p,t||{});if(d.isUndefined(v.adTagUrl)&&d.isDefined(v.url)){v.adTagUrl=v.url}if(d.isString(v.adTagUrl)){v.adTagUrl=d.echoFn(v.adTagUrl)}if(d.isDefined(v.adTagXML)&&!d.isFunction(v.adTagXML)){return _(new r("on VideoJS VAST plugin, the passed adTagXML option does not contain a function"))}if(!d.isDefined(v.adTagUrl)&&!d.isFunction(v.adTagXML)){return _(new r("on VideoJS VAST plugin, missing adTagUrl on options object"))}c.prepareForAds(n);if(v.playAdAlways){n.on("vast.contentEnd",function(){setTimeout(function(){n.trigger("vast.reset")},0)})}n.on("vast.firstPlay",g);n.on("vast.reset",function(){e=null;m()});n.vast={isEnabled:function(){return v.adsEnabled},enable:function(){v.adsEnabled=true},disable:function(){v.adsEnabled=false}};return n.vast;function g(){c.removeNativePoster(n);c.once(n,["vast.adsCancel","vast.adEnd"],function(){t();i()});u.waterfall([s,o,p,y],function(t,e){if(t){_(t,e)}else{n.trigger("vast.adEnd")}});function t(){if(n.vast&&n.vast.adUnit){n.vast.adUnit=null}}function i(){a();if(e){c.restorePlayerSnapshot(n,e);e=null}}function a(){c.once(n,["playing","vast.reset","vast.firstPlay"],function(t){if(t.type!=="playing"){return}n.trigger("vast.contentStart");c.once(n,["ended","vast.reset","vast.firstPlay"],function(t){if(t.type==="ended"){n.trigger("vast.contentEnd")}})})}function s(t){if(v.adsEnabled){return t(null)}t(new r("Ads are not enabled"))}function o(t){if(f()){e=c.getPlayerSnapshot(n);n.pause();g();if(n.paused()){t(null)}else{c.once(n,["playing"],function(){n.pause();t(null)})}}else{t(new r("video content has been playing before preroll ad"))}}function f(){return!d.isIPhone()||n.currentTime()<=v.iosPrerollCancelTimeout}function p(t){var e;h=false;e=setTimeout(function(){_(new r("timeout while waiting for the video to start playing",402))},v.adCancelTimeout);c.once(n,["vast.adStart","vast.adsCancel"],i);function i(){if(e){clearTimeout(e);e=null}}t(null)}function g(){l.addClass(n.el(),"vjs-vast-ad-loading");c.once(n,["vast.adStart","vast.adsCancel"],m)}function m(){setTimeout(function(){l.removeClass(n.el(),"vjs-vast-ad-loading")},100)}}function m(){n.trigger("vast.adsCancel");h=true}function y(t){u.waterfall([A,k],t)}function A(t){f.getVASTResponse(v.adTagUrl?v.adTagUrl():v.adTagXML,t)}function k(t,e){if(h){return}var i=E(t)?new o(n,v):new s(n);var r=false;c.once(n,["vast.adStart","vast.adsCancel"],function(t){if(t.type==="vast.adStart"){a()}});c.once(n,["vast.adEnd","vast.adsCancel"],u);if(d.isIDevice()){l()}n.vast.vastResponse=t;n.vast.adUnit=i.playAd(t,e);function a(){if(r||n.controlBar.getChild("AdsLabel")){return}n.controlBar.addChild("AdsLabel")}function u(){n.controlBar.removeChild("AdsLabel");r=true}function l(){var t=3;var e=0;var i=0;n.on("timeupdate",r);c.once(n,["vast.adEnd","vast.adsCancel","vast.adError"],a);function r(){var r=n.currentTime();var a=Math.abs(r-e);if(a>t){i+=1;if(i>=2){n.pause()}n.currentTime(e)}else{e=r}}function a(){n.off("timeupdate",r)}}}function _(t,e){n.trigger({type:"vast.adError",error:t});m();if(console&&console.log){console.log("AD ERROR:",t.message,t,e)}}function E(t){var e,n;var i=t.mediaFiles;for(e=0,n=i.length;e0){u=setTimeout(function(){l&&l.abort()},o)}function c(t,e,n){if(!r.isString(t)||r.isEmptyString(t)){throw new a("Invalid url '"+t+"'")}if(!r.isFunction(e)){throw new a("Invalid handler '"+e+"' for the http request")}if(r.isDefined(n)&&!r.isObject(n)){throw new a("Invalid options map '"+n+"'")}}function d(t,e){r.forEach(e,function(e,n){if(r.isDefined(e)){t.setRequestHeader(n,e)}})}function f(){n(-1,null,null,"")}};s.prototype.get=function(t,e,n){this.run("GET",t,i,n);function i(t,n,i,s){if(r(t)){e(null,n,t,i,s)}else{e(new a(s),n,t,i,s)}}function r(t){return 200<=t&&t<300}};function o(){var t=new XMLHttpRequest;if(!("withCredentials"in t)){t=new XDomainRequest}return t}var u=new s(o);e.exports={http:u,HttpRequest:s,HttpRequestError:a,createXhr:o}},{"./urlUtils":42,"./utilityFunctions":43}],41:[function(t,e,n){"use strict";var i=t("./dom");var r=t("./utilityFunctions");var a={};a.getPlayerSnapshot=function s(t){var e=t.el().querySelector(".vjs-tech");var n={ended:t.ended(),src:t.currentSrc(),currentTime:t.currentTime(),type:t.currentType(),playing:!t.paused(),suppressedTracks:i(t)};if(e){n.nativePoster=e.poster;n.style=e.getAttribute("style")}return n;function i(t){var e=t.remoteTextTracks?t.remoteTextTracks():[];if(e&&r.isArray(e.tracks_)){e=e.tracks_}if(!r.isArray(e)){e=[]}var n=[];e.forEach(function(t){n.push({track:t,mode:t.mode});t.mode="disabled"});return n}};a.restorePlayerSnapshot=function o(t,e){var n=t.el().querySelector(".vjs-tech");var i=20;if(e.nativePoster){n.poster=e.nativePoster}if("style"in e){n.setAttribute("style",e.style||"")}if(s(t,e)){t.one("contentloadedmetadata",o);t.one("canplay",u);r();t.src({src:e.src,type:e.type});t.load()}else{o();if(e.playing){t.play()}}function r(){var e=setTimeout(function(){t.trigger("canplay")},1e3);t.one("canplay",function(){clearTimeout(e)})}function s(t,e){if(t.src()){return t.src()!==e.src}return t.currentSrc()!==e.src}function o(){var t=e.suppressedTracks;t.forEach(function(t){t.track.mode=t.mode})}function u(){if(!a.isReadyToResume(t)&&i--){setTimeout(u,50)}else{try{if(t.currentTime()!==e.currentTime){if(e.playing){t.one("seeked",function(){t.play()})}t.currentTime(e.currentTime)}else if(e.playing){t.play()}}catch(n){videojs.log.warn("Failed to resume the content after an advertisement",n)}}}};a.isReadyToResume=function(t){if(t.readyState()>1){return true}if(t.seekable()===undefined){return true}if(t.seekable().length>0){return true}return false};a.prepareForAds=function(t){var e=t.addChild("blackPoster");var n=true;var a;s();t.on("play",u);t.on("vast.reset",l);t.on("vast.firstPlay",f);t.on("error",p);t.on("vast.adStart",p);t.on("vast.adsCancel",p);t.on("vast.adError",p);t.on("vast.adStart",v);t.on("vast.adEnd",g);t.on("vast.adsCancel",g);function s(){var e=t.play;t.play=function(n){var i=this;if(c()){s()}else{u(n)}return this;function s(){if(!r.isIPhone()){a=d();t.muted(true)}e.apply(i,arguments)}function u(n){if(o()&&!n){t.vast.adUnit.resumeAd()}else{e.apply(i,arguments)}}};var n=t.pause;t.pause=function(e){if(o()&&!e){t.vast.adUnit.pauseAd()}else{n.apply(this,arguments)}return this};var i=t.paused;t.paused=function(e){if(o()&&!e){return t.vast.adUnit.isPaused()}return i.apply(this,arguments)}}function o(){return t.vast&&t.vast.adUnit}function u(){if(c()){n=false;t.trigger("vast.firstPlay")}}function l(){n=true;e.show();f()}function c(){return n}function d(){return{muted:t.muted(),volume:t.volume()}}function f(){if(a){t.currentTime(0);h(a);a=null}}function h(e){if(r.isObject(e)){t.volume(e.volume);t.muted(e.muted)}}function p(){if(!i.hasClass(e.el(),"vjs-hidden")){e.hide()}}function v(){i.addClass(t.el(),"vjs-ad-playing")}function g(){i.removeClass(t.el(),"vjs-ad-playing")}};a.removeNativePoster=function(t){var e=t.el().querySelector(".vjs-tech");if(e){e.removeAttribute("poster")}};a.once=function u(t,e,n){function i(){n.apply(null,arguments);e.forEach(function(e){t.off(e,i)})}e.forEach(function(e){t.on(e,i)})};e.exports=a},{"./dom":39,"./utilityFunctions":43}],42:[function(t,e,n){"use strict";var i=t("./utilityFunctions");var r=document.createElement("a");var a=document.documentMode;function s(t){var e=t;if(a){r.setAttribute("href",e);e=r.href}r.setAttribute("href",e);return{href:r.href,protocol:r.protocol?r.protocol.replace(/:$/,""):"",host:r.host,search:r.search?r.search.replace(/^\?/,""):"",hash:r.hash?r.hash.replace(/^#/,""):"",hostname:r.hostname,port:i.isNotEmptyString(r.port)?r.port:80,pathname:r.pathname.charAt(0)==="/"?r.pathname:"/"+r.pathname}}function o(t,e){var n,r;e=i.isFunction(e)?e:function(){return true};t=t.trim().replace(/^\?/,"");n=t.split("&");r={};i.forEach(n,function(t){var n,i,a;if(t!==""){n=t.split("=");i=n[0];a=n[1];if(e(i,a)){r[i]=a}}});return r}function u(t){var e=[];i.forEach(t,function(t,n){e.push(n+"="+t)});return e.join("&")}e.exports={urlParts:s,queryStringToObj:o,objToQueryString:u}},{"./utilityFunctions":43}],43:[function(t,e,n){"use strict";var i=1;var r=/[A-Z]/g;var a=/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/i;var s=/^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;function o(){}function u(t){return t===null}function l(t){return t!==undefined}function c(t){return t===undefined}function d(t){return typeof t==="object"}function f(t){return typeof t==="function"}function h(t){return typeof t==="number"}function p(t){return j.isObject(t)&&t.window===t}function v(t){return Object.prototype.toString.call(t)==="[object Array]"}function g(t){if(t===null||j.isWindow(t)||j.isFunction(t)||j.isUndefined(t)){return false}var e=t.length;if(t.nodeType===i&&e){return true}return j.isString(t)||j.isArray(t)||e===0||typeof e==="number"&&e>0&&e-1 in t}function m(t){return typeof t==="string"}function y(t){return j.isString(t)&&t.length===0}function A(t){return j.isString(t)&&t.length!==0}function k(t){return Array.prototype.slice.call(t)}function _(t,e,n){var i,r;if(t){if(f(t)){for(i in t){if(i!=="prototype"&&i!=="length"&&i!=="name"&&(!t.hasOwnProperty||t.hasOwnProperty(i))){e.call(n,t[i],i,t)}}}else if(v(t)){var a=typeof t!=="object";for(i=0,r=t.length;i=e){n=i;t.apply(this,arguments)}}}function L(t,e){var n;return function(){if(n){clearTimeout(n)}n=setTimeout(function(){t.apply(this,arguments);n=undefined},e)}}function F(t,e,n){var i=e(t);for(var r=0;r0}return t.getElementsByTagNameNS(i,"parsererror").length>0}catch(r){}}};r.parseText=function s(t){if(/^\s*$/.test(t)){return null}if(/^(?:true|false)$/i.test(t)){return t.toLowerCase()==="true"}if(isFinite(t)){return parseFloat(t)}if(i.isISO8601(t)){return new Date(t)}return t.trim()};r.JXONTree=function o(t){var e=r.parseText;if(t.documentElement){return new r.JXONTree(t.documentElement)}if(t.hasChildNodes()){var n="";for(var a,s,o,u=0;u0:t.hasAttributes();if(l){var c;for(var d=0;d/g,">").replace(/"/g,""").replace(/'/g,"'")};r.decode=function f(t){return t.replace(/'/g,"'").replace(/"/g,'"').replace(/>/g,">").replace(/</g,"<").replace(/&/g,"&")};e.exports=r},{"./utilityFunctions":43}],45:[function(t,e,n){"use strict";t("./plugin/components/ads-label_4");t("./plugin/components/black-poster_4");var i=t("./plugin/videojs.vast.vpaid");videojs.plugin("vastClient",i)},{"./plugin/components/ads-label_4":34,"./plugin/components/black-poster_4":36,"./plugin/videojs.vast.vpaid":37}]},{},[45]); //# sourceMappingURL=videojs_4.vast.vpaid.min.js.map diff --git a/bin/videojs_4.vast.vpaid.min.js.map b/bin/videojs_4.vast.vpaid.min.js.map index 7d42945f..237603e6 100644 --- a/bin/videojs_4.vast.vpaid.min.js.map +++ b/bin/videojs_4.vast.vpaid.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["node_modules/browser-pack/_prelude.js","bower_components/VPAIDFLASHClient/js/IVPAIDAdUnit.js","videojs_4.vast.vpaid.js","bower_components/VPAIDFLASHClient/js/VPAIDAdUnit.js","bower_components/VPAIDFLASHClient/js/VPAIDFLASHClient.js","bower_components/VPAIDFLASHClient/js/flashTester.js","bower_components/VPAIDFLASHClient/js/jsFlashBridge.js","bower_components/VPAIDFLASHClient/js/jsFlashBridgeRegistry.js","bower_components/VPAIDFLASHClient/js/registry.js","bower_components/VPAIDFLASHClient/js/utils.js","bower_components/VPAIDHTML5Client/js/IVPAIDAdUnit.js","bower_components/VPAIDHTML5Client/js/VPAIDAdUnit.js","bower_components/VPAIDHTML5Client/js/VPAIDHTML5Client.js","bower_components/VPAIDHTML5Client/js/subscriber.js","bower_components/VPAIDHTML5Client/js/utils.js","bower_components/swfobject/swfobject/src/swfobject.js","src/scripts/ads/vast/Ad.js","src/scripts/ads/vast/Companion.js","src/scripts/ads/vast/Creative.js","src/scripts/ads/vast/InLine.js","src/scripts/ads/vast/Linear.js","src/scripts/ads/vast/MediaFile.js","src/scripts/ads/vast/TrackingEvent.js","src/scripts/ads/vast/VASTClient.js","src/scripts/ads/vast/VASTError.js","src/scripts/ads/vast/VASTIntegrator.js","src/scripts/ads/vast/VASTResponse.js","src/scripts/ads/vast/VASTTracker.js","src/scripts/ads/vast/VideoClicks.js","src/scripts/ads/vast/Wrapper.js","src/scripts/ads/vast/parsers.js","src/scripts/ads/vast/vastUtil.js","src/scripts/ads/vpaid/VPAIDAdUnitWrapper.js","src/scripts/ads/vpaid/VPAIDFlashTech.js","src/scripts/ads/vpaid/VPAIDHTML5Tech.js","src/scripts/ads/vpaid/VPAIDIntegrator.js","src/scripts/plugin/components/ads-label.js","src/scripts/plugin/components/ads-label_4.js","src/scripts/plugin/components/black-poster.js","src/scripts/plugin/components/black-poster_4.js","src/scripts/plugin/videojs.vast.vpaid.js","src/scripts/utils/async.js","src/scripts/utils/dom.js","src/scripts/utils/http.js","src/scripts/utils/playerUtils.js","src/scripts/utils/urlUtils.js","src/scripts/utils/utilityFunctions.js","src/scripts/utils/xml.js","src/scripts/videojs_4.vast.vpaid.js"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length",1,"module","_createClass","defineProperties","target","props","descriptor","enumerable","configurable","writable","Object","defineProperty","key","Constructor","protoProps","staticProps","prototype","value","_classCallCheck","instance","TypeError","IVPAIDAdUnit","this","handshakeVersion","playerVPAIDVersion","arguments","undefined","callback","initAd","width","height","viewMode","desiredBitrate","creativeData","AdParameters","environmentVars","flashVars","resizeAd","startAd","stopAd","pauseAd","resumeAd","expandAd","collapseAd","skipAd","getAdLinear","getAdWidth","getAdHeight","getAdExpanded","getAdSkippableState","getAdRemainingTime","getAdDuration","setAdVolume","soundVolume","getAdVolume","getAdCompanions","getAdIcons",2,"_typeof","Symbol","iterator","obj","constructor","_possibleConstructorReturn","self","ReferenceError","_inherits","subClass","superClass","create","setPrototypeOf","__proto__","ALL_VPAID_METHODS","getOwnPropertyNames","filter","property","indexOf","VPAIDAdUnit","_IVPAIDAdUnit","flash","_this","getPrototypeOf","_destroyed","_flash","_destroy","_this2","forEach","methodName","removeCallbackByMethodName","EVENTS","event","offEvent","isDestroyed","on","eventName","off","callFlashMethod","setSize","getWidth","getHeight","volume","./IVPAIDAdUnit",3,"swfobject","JSFlashBridge","noop","callbackTimeout","isPositiveInt","createElementWithID","uniqueVPAID","unique","createFlashTester","ERROR","FLASH_VERSION","flashTester","isSupported","VPAIDFLASHClient","vpaidParentEl","swfConfig","data","params","wmode","salign","align","allowScriptAccess","scale","allowFullScreen","quality","vpaidOptions","debug","timeout","me","_vpaidParentEl","_flashID","movie","FlashVars","VPAID_FLASH_HANDLER","onError","el","createSWF","handler","err","$loadPendedAdUnit","error","setTimeout","destroy","_destroyAdUnit","_loadLater","_adUnitLoad","removeCallback","_adUnit","loadAdUnit","adURL","$throwIfDestroyed","isReady","message","url","unloadAdUnit","getFlashID","getFlashURL","setStaticProperty","hasFlashPlayerVersion","document","body","propertyName","./VPAIDAdUnit","./flashTester.js","./jsFlashBridge","./utils",4,"FLASH_TEST","FLASH_TEST_EL","utils","MultipleValuesRegistry","FlashTester","parent","parentEl","hideFlashEl","_handlers","_isSupported","support","get","add","window","./registry",5,"stringEndsWith","SingleValueRegistry","registry","flashURL","flashID","loadHandShake","_el","_flashURL","_width","_height","_callbacks","_uniqueMethodIdentifier","_ready","_handShakeHandler","addInstance","remove","removeByKey","offAll","removeAll","args","callbackID","concat","$asyncCallback","_trigger","removeByValue","suffix","filterKeys","removeAllCallbacks","_callCallback","result","trigger","_handShake","getSize","newWidth","newHeight","setAttribute","setWidth","setHeight","removeInstanceByID","parentElement","removeChild","_this3","typeID","typeName","getInstanceByID","./jsFlashBridgeRegistry",6,"instances","JSFlashBridgeRegistry","id",7,"_registries","push","keys","findByValue","index","splice","old","map","size","_this4",8,"prefix","count","timer","onSuccess","onTimeout","clearTimeout","apply","cleanContent","nEl","createElement","innerHTML","appendChild","newVal","oldVal","isNaN","parseFloat","isFinite","endsWith","String","searchString","position","subjectString","toString","lastIndex","string","search","style","left","top",9,"METHODS","GETTERS","SETTERS","creative","video","VPAIDVersion","subscribe","context","unsubscribe","addStaticToInterface","VPAID1_METHODS","method","checkVPAIDInterface","every","Interface","name",10,"Subscriber","AD_CLICK","FILTERED_EVENTS","VPAIDCreative","iframe","_isValid","_creative","_videoEl","_iframe","_subscribers","$addEventsSubscribers","isValidVPAIDAd","ignores","ariaty","Array","slice","pop","callOrTriggerEvent","bind","extend","slot","videoSlot","getter","validate","unsubscribeAll","$trigger","$clickThruHook","documentElement","contentDocument","videoEl","addEventListener","click","playerHandles","triggerSync","subscribers","./subscriber",11,"defaultTemplate","AD_STOPPED","VPAIDHTML5Client","templateConfig","_id","_frameContainer","createElementInEl","_vpaidOptions","_templateConfig","template","extraOptions","$unloadPreviousAdUnit","that","frame","createIframeWithContent","iframeURL_JS","iframeID","getID","origin","getOrigin","_frame","_onLoad","onLoad","JSON","parse","adUnit","createAd","contentWindow","getVPAIDAd","adEl","querySelector","$adDestroyed","$destroyLoadListener","$removeEl","$removeAdElements","$destroyAdUnit","removeEventListener","clearCallbackTimeout","location","protocol","hostname","port",12,"isHandlerAttached","subscriber","some",13,"isValid","timeouts","func","tagName","createIframe","zIndex","setIframeContent","simpleTemplate","src","marginWidth","marginHeight","frameBorder","margin","padding","border","stringify","replace","RegExp","iframeEl","content","iframeDoc","write","toExtend","fromSource",14,"root","factory","define","amd","UNDEF","OBJECT","SHOCKWAVE_FLASH","SHOCKWAVE_FLASH_AX","FLASH_MIME_TYPE","EXPRESS_INSTALL_ID","ON_READY_STATE_CHANGE","win","doc","nav","navigator","plugin","domLoadFnArr","regObjArr","objIdArr","listenersArr","storedFbContent","storedFbContentId","storedCallbackFn","storedCallbackObj","isDomLoaded","isExpressInstallActive","dynamicStylesheet","dynamicStylesheetMedia","autoHideShow","encodeURIEnabled","ua","w3cdom","getElementById","getElementsByTagName","userAgent","toLowerCase","p","platform","windows","test","mac","webkit","ie","appName","playerVersion","d","plugins","description","mimeTypes","enabledPlugin","toInt","ActiveXObject","GetVariable","split","w3","pv","wk","onDomLoad","readyState","callDomLoadFunctions","attachEvent","detach","detachEvent","checkDomLoadedIE","doScroll","checkDomLoadedWK","span","display","parentNode","dl","addDomLoadEvent","fn","addLoadEvent","addListener","onload","fnOld","testPlayerVersion","b","counter","checkGetVariable","matchVersions","rl","cb","callbackFn","cbObj","success","hasPlayerVersion","swfVersion","setVisibility","ref","getObjectById","expressInstall","canExpressInstall","att","getAttribute","styleclass","par","pl","j","showExpressInstall","displayFbContent","SetVariable","objectIdStr","nodeName","toUpperCase","replaceElemIdStr","getId","abstractFbContent","pt","fv","encodeURIComponent","title","flashvars","newObj","insertBefore","removeSWF","replaceChild","ac","nestedObj","c","childNodes","cl","nodeType","cloneNode","createIeObject","paramStr","div","firstChild","attObj","parObj","attr","attrLower","param","hasOwnProperty","createObjParam","pName","pValue","removeSWFInIE","isElement","thing","str","parseInt","eventType","rv","v","createCSS","sel","decl","media","newStyle","h","m","styleSheets","addRule","createTextNode","isVisible","visibility","urlEncodeIfNecessary","regex","hasBadChars","exec","cleanup","ll","il","k","registerObject","swfVersionStr","xiSwfUrlStr","regObj","embedSWF","swfUrlStr","widthStr","heightStr","flashvarsObj","callbackObj","switchOffAutoHideShow","enableUriEncoding","bool","getFlashPlayerVersion","major","minor","release","objElemIdStr","selStr","declStr","mediaStr","newStyleBoolean","getQueryParamValue","q","hash","pairs","substring","expressInstallCallback","version",15,"InLine","Wrapper","Ad","adJTree","initialize","sequence","inLine","wrapper","./InLine","./Wrapper",16,"TrackingEvent","utilities","xml","Companion","companionJTree","creativeType","staticResource","keyValue","htmlResource","HTMLResource","hTMLResource","iframeResource","IFrameResource","iFrameresource","expandedWidth","expandedHeight","scalable","maintainAspectRatio","minSuggestedDuration","apiFramework","companionClickThrough","trackingEvents","parseTrackingEvents","tracking","trackings","isDefined","isArray","trackingData","../../utils/utilityFunctions","../../utils/xml","./TrackingEvent",17,"Linear","Creative","creativeJTree","adId","linear","companionAds","companions","companion","companionData","parseCreatives","creativesJTree","creatives","creativesData","./Companion","./Linear",18,"vastUtil","inlineJTree","adTitle","adSystem","impressions","parseImpressions","impression","advertiser","surveys","parseSurveys","survey","pricing","extensions","inlineSurveys","transformArray","isNotEmptyString","uri","type","len","./Creative","./vastUtil",19,"MediaFile","VideoClicks","parsers","linearJTree","duration","mediaFiles","parseMediaFiles","mediaFile","skipoffset","offset","videoClicks","adParameters","decode","mediaFilesJxonTree","mfData","./MediaFile","./VideoClicks","./parsers",20,"attributesList","mediaFileJTree","x","attribute","isVPAID","findSupportedVPAIDTech","isFlashSupported",21,"trackingJTree",22,"VASTError","VASTResponse","async","http","VASTClient","options","defaultOptions","WRAPPER_LIMIT","settings","errorURLMacros","getVASTResponse","adTagUrl","sanityCheck","isFunction","waterfall","_getVASTAd","buildVASTResponse","adsChain","response","_buildVASTResponse","getAdWaterfall","vastTree","waterfallAds","ads","_trackError","getAd","shift","waterfallHandler","adChain","requestVastXML","_requestVASTXml","buildVastWaterfall","xmlStr","toJXONTree","ad","validateVASTTree","vastVersion","next","isString","requestVASTAd","buildAd","VASTAdTagURI","adJxonTree","validateAd","errMsgPrefix","requestVASTXml","requestHandler","withCredentials","status","errMsg","addAdsToResponse","validateResponse","addAd","progressEvents","progress","hasLinear","progressEvent","isNumber","addErrorUrlMacros","track","ERRORCODE","../../utils/async","../../utils/http","./Ad","./VASTError","./VASTResponse",23,24,"VASTTracker","dom","playerUtils","VASTIntegrator","player","playAd","vastResponse","_selectAdSource","_createVASTTracker","_addClickThrough","_addSkipButton","_setupEvents","_playSelectedAd","_src","pause","play","isPaused","paused","getSrc","selectAdSource","source","playerWidth","getDimension","sort","compareTo","deltaA","Math","abs","deltaB","selectSource","createVASTTracker","adMediaFile","setupEvents","tracker","previouslyMuted","trackFullscreenChange","trackImpressions","trackPause","trackProgress","trackVolumeChange","once","unbindEvents","evt","trackComplete","isFullscreen","trackFullscreen","trackExitFullscreen","currentTime","trackResume","currentTimeInMs","trackCreativeView","muted","trackMute","trackUnmute","addSkipButton","skipOffsetInSec","addSkipButtonToPlayer","skipOffset","skipButton","createSkipButton","updateSkipButton","updateSkipButtonState","removeSkipButton","addClass","onclick","hasClass","trackSkip","Event","stopPropagation","timeLeft","ceil","toFixedDigits","addClickThrough","blocker","createClickThroughBlocker","updateBlocker","updateBlockerURL","controlBar","removeBlocker","clickThroughMacro","clickThrough","href","generateClickThroughURL","trackClick","variables","ASSETURI","CONTENTPLAYHEAD","formatProgress","parseURLMacro","playSelectedAd","preload","proceed","trackError","../../utils/dom","../../utils/playerUtils","./VASTTracker",25,"InLine__A","_linearAdded","clickTrackings","customClicks","_addInLine","_addWrapper","_addErrorTrackUrl","errorURL","JXONTree","_addImpressions","appendToArray","_addClickTrackings","_addCustomClicks","_addTrackingEvents","eventsMap","trackingEvent","_addTitle","_addDuration","_addVideoClicks","_addMediaFiles","_addSkipoffset","_addAdParameters","_addLinear","array","items","item",26,"assetURI","quartiles","firstQuartile","tracked","time","round","midpoint","thirdQuartile","isEmptyString","trackURLs","urls","trackEvent","trackOnce","getEventUris","uris","newProgressInMs","events","ONCE","ALWAYS","addTrackEvent","hasRewound","addQuartileEvents","trackProgressEvents","trackEvents","currentProgress","newProgress","REWIND_THRESHOLD","canBeAdded","trackQuartile","quartileName","quartile","canBeTracked","quartileTime","pendingProgressEvts","capitalize","trackErrorWithCode","errorcode",27,"videoClickJTree","parseClickTrackings","clickTracking","customClick","clickTrackingData",28,"wrapperJTree","vASTAdTagURI","followAdditionalWrappers","allowMultipleAds","fallbackOnNoAd",29,"durationRegex","parseDuration","durationStr","match","durationInMs","parseHoursToMs","parseMinToMs","parseSecToMs","hourStr","minStr","secStr","parseOffset","isPercentage","calculatePercentage","percentageRegex","percentStr","calcPercent","quantity","percent",30,"VPAIDHTML5Tech","VPAIDFlashTech","URLMacros","sources","parseURLMacros","trackImgs","img","Image","parseMacros","parsedURLs","random","URLMacro","_parseURLMacro","parseMacro","hours","minutes","seconds","milliseconds","floor","VPAID_techs","isVPAIDMediaFile","mimeType","VPAIDTech","supports","runFlashSupportCheck","vpaidFlashLoaderPath","runFlashTest","../vpaid/VPAIDFlashTech","../vpaid/VPAIDHTML5Tech","VPAIDFLASHClient/js/VPAIDFLASHClient",31,"VPAIDAdUnitWrapper","vpaidAdUnit","opts","isObject","responseTimeout","VPAIDInterfaceMethods","canSubscribeToEvents","canUnsubscribeFromEvents","adUnitAsyncCall","arrayLikeObjToArray","timeoutId","wrapCallback","evtName","waitForEvent","responseListener","unshift","adUnitData","getterName","../vast/VASTError",32,"containerEl","vpaidFlashClient","loadFlashCreative","objectEl","flashClientOpts","container","isDomElement","console","log",33,"vpaidHTMLClient","INVALID_MEDIA_FILE","isOldIE","INVALID_DOM_CONTAINER_EL","MISSING_CALLBACK","PREFIX","INVALID_DOM_VIDEO_EL","VPAIDHTML5Client/js/VPAIDHTML5Client",34,"VPAIDIntegrator","VIEW_MODE","NORMAL","FULLSCREEN","THUMBNAIL","createVPAIDContainerEl","VPAID_VERSION","playVPaidAd","tech","_findSupportedTech","triggerVpaidAdEnd","one","removeAdUnit","_loadAdUnit","_playAdUnit","_finishPlaying","adComplete","_paused","removeClass","vpaidMediaFiles","_createVPAIDAdUnitWrapper","vjsTechEl","WrappedAdUnit","techClass","_handshake","_initAd","_linkPlayerControls","_startAd","handshake","isSupportedVersion","majorNum","parts","dimension","adUnitSrc","notifyPlayToPlayer","trackStart","notifyPauseToPlayer","trackFirstQuartile","trackMidpoint","trackThirdQuartile","clickThruUrl","open","trackAcceptInvitation","trackAcceptInvitationLinear","trackClose","trackCloseLinear","trackCollapse","lastVolume","currentVolume","updateViewSize","updateViewSizeThrottled","throttle","autoResize","pauseAdUnit","resumeAdUnit","isSkippable","linkVolumeControl","linkFullScreenControl","updateAdUnitVolume","updatePlayerVolume","vol","logError","finishPlayingAd","errorCode","MODE","../vast/VASTResponse","../vast/VASTTracker","../vast/vastUtil","./VPAIDAdUnitWrapper",35,"element","className","AdsLabelFactory","baseComponent","init","currentTimeComp","getChild","getElement",36,"baseVideoJsComponent","videojs","Component","AdsLabel","./ads-label",37,"BlackPosterFactory","posterImg",38,"BlackPoster","./black-poster",39,"VASTPlugin","snapshot","vast","adsCanceled","defaultOpts","iosPrerollCancelTimeout","adCancelTimeout","playAdAlways","adsEnabled","isUndefined","echoFn","adTagXML","trackAdError","prepareForAds","tryToPlayPrerollAd","cancelAds","isEnabled","enable","disable","removeNativePoster","restoreVideoContent","checkAdsEnabled","preparePlayerForAd","startAdCancelTimeout","playPrerollAd","setupContentEvents","restorePlayerSnapshot","canPlayPrerollAd","getPlayerSnapshot","addSpinnerIcon","isIPhone","adCancelTimeoutId","clearAdCancelTimeout","removeSpinnerIcon","getVastResponse","adIntegrator","adFinished","addAdsLabel","removeAdsLabel","isIDevice","preventManualProgress","addChild","PROGRESS_THRESHOLD","previousTime","skipad_attempts","preventAdSeek","preventAdSkip","stopPreventManualProgress","progressDelta","../ads/vast/VASTClient","../ads/vast/VASTError","../ads/vast/VASTIntegrator","../ads/vast/vastUtil","../ads/vpaid/VPAIDIntegrator","../utils/async","../utils/dom","../utils/playerUtils","../utils/utilityFunctions",40,"setImmediate","tasks","makeCallback","wrapIterator","when","condition","isAllowed","./utilityFunctions",41,"getComputedStyle","isHidden","isShown","hide","__prev_style_display_","show","cssClass","classes","classList","contains","join","newClasses","dispatchEvent","fireEvent","isDescendant","child","node","getTextContent","textContent","text","prependChild","removeNode","Element","handlerWrap","rect","getBoundingClientRect","offsetWidth","offsetHeight",42,"urlUtils","HttpRequestError","HttpRequest","createXhr","run","xhr","urlParts","headers","setHeaders","statusText","getAllResponseHeaders","responseText","onerror","requestError","onabort","send","abort","setRequestHeader","processResponse","headersString","isSuccess","XMLHttpRequest","XDomainRequest","./urlUtils",43,"ended","currentSrc","currentType","playing","suppressedTracks","getSuppressedTracks","nativePoster","poster","tracks","remoteTextTracks","tracks_","mode","attempts","hasSrcChanged","restoreTracks","tryToResume","ensureCanplayEvtGetsFired","load","trackSnapshot","isReadyToResume","warn","seekable","blackPoster","_firstPlay","volumeSnapshot","monkeyPatchPlayerApi","tryToTriggerFirstPlay","resetFirstPlay","restoreContentVolume","hideBlackPoster","addStyles","removeStyles","origPlay","callOrigPlay","isFirstPlay","firstPlay","resume","saveVolumeSnapshot","isAdPlaying","origPause","callOrigPause","origPaused","callOrigPaused","restoreVolumeSnapshot","removeAttribute","listener","./dom",44,"urlParsingNode","msie","documentMode","host","pathname","charAt","queryStringToObj","qs","cond","qsObj","trim","pair","objToQueryString",45,"NODE_TYPE_ELEMENT","SNAKE_CASE_REGEXP","EMAIL_REGEXP","ISO8086_REGEXP","isNull","num","isWindow","isArrayLike","isPrimitive","snake_case","separator","letter","pos","isValidEmail","email","arg","decapitalize","transformer","transformedArray","transformedItem","digits","formattedNum","NaN","delay","previousCall","Date","getTime","debounce","wait","treeSearch","getChildren","found","children","val","isISO8601","getInternetExplorerVersion","re","res","_UA","isMobile","isAndroid",46,"strToXMLDoc","stringContainingXMLSource","DOMParser","xmlDocument","loadXML","parseString","parser","parsedDocument","parseFromString","isParseError","erroneousParse","parsererrorNS","namespaceURI","getElementsByTagNameNS","parseText","sValue","oXMLParent","hasChildNodes","sCollectedTxt","oNode","sProp","vContent","nItem","nodeValue","hasAttr","hasAttributes","attributes","oAttrib","nAttrib","xmlString","xmlDoc","getKeyValue","xmlObj","getAttrValue","encode","encodeXML","decodeXML",47,"videoJsVAST","./plugin/components/ads-label_4","./plugin/components/black-poster_4","./plugin/videojs.vast.vpaid"],"mappings":"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","file":"videojs_4.vast.vpaid.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o 0) {\n callback(event);\n }\n }, 0);\n }\n });\n }\n }, {\n key: '_callCallback',\n value: function _callCallback(methodName, callbackID, err, result) {\n\n var callback = this._callbacks.get(callbackID);\n\n //not all methods callback's are mandatory\n //but if there exist an error, fire the error event\n if (!callback) {\n if (err && callbackID === '') {\n this.trigger(ERROR, err);\n }\n return;\n }\n\n $asyncCallback.call(this, callbackID, err, result);\n }\n }, {\n key: '_handShake',\n value: function _handShake(err, data) {\n this._ready = true;\n if (this._handShakeHandler) {\n this._handShakeHandler(err, data);\n delete this._handShakeHandler;\n }\n }\n\n //methods like properties specific to this implementation of VPAID\n\n }, {\n key: 'getSize',\n value: function getSize() {\n return { width: this._width, height: this._height };\n }\n }, {\n key: 'setSize',\n value: function setSize(newWidth, newHeight) {\n this._width = isPositiveInt(newWidth, this._width);\n this._height = isPositiveInt(newHeight, this._height);\n this._el.setAttribute('width', this._width);\n this._el.setAttribute('height', this._height);\n }\n }, {\n key: 'getWidth',\n value: function getWidth() {\n return this._width;\n }\n }, {\n key: 'setWidth',\n value: function setWidth(newWidth) {\n this.setSize(newWidth, this._height);\n }\n }, {\n key: 'getHeight',\n value: function getHeight() {\n return this._height;\n }\n }, {\n key: 'setHeight',\n value: function setHeight(newHeight) {\n this.setSize(this._width, newHeight);\n }\n }, {\n key: 'getFlashID',\n value: function getFlashID() {\n return this._flashID;\n }\n }, {\n key: 'getFlashURL',\n value: function getFlashURL() {\n return this._flashURL;\n }\n }, {\n key: 'isReady',\n value: function isReady() {\n return this._ready;\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.offAll();\n this.removeAllCallbacks();\n registry.removeInstanceByID(this._flashID);\n if (this._el.parentElement) {\n this._el.parentElement.removeChild(this._el);\n }\n }\n }]);\n\n return JSFlashBridge;\n}();\n\nfunction $asyncCallback(callbackID, err, result) {\n var _this3 = this;\n\n setTimeout(function () {\n var callback = _this3._callbacks.get(callbackID);\n if (callback) {\n _this3._callbacks.remove(callbackID);\n callback(err, result);\n }\n }, 0);\n}\n\nObject.defineProperty(JSFlashBridge, 'VPAID_FLASH_HANDLER', {\n writable: false,\n configurable: false,\n value: VPAID_FLASH_HANDLER\n});\n\n/**\n * External interface handler\n *\n * @param {string} flashID identifier of the flash who call this\n * @param {string} typeID what type of message is, can be 'event' or 'callback'\n * @param {string} typeName if the typeID is a event the typeName will be the eventName, if is a callback the typeID is the methodName that is related this callback\n * @param {string} callbackID only applies when the typeID is 'callback', identifier of the callback to call\n * @param {object} error error object\n * @param {object} data\n */\nwindow[VPAID_FLASH_HANDLER] = function (flashID, typeID, typeName, callbackID, error, data) {\n var instance = registry.getInstanceByID(flashID);\n if (!instance) return;\n if (typeName === 'handShake') {\n instance._handShake(error, data);\n } else {\n if (typeID !== 'event') {\n instance._callCallback(typeName, callbackID, error, data);\n } else {\n instance._trigger(typeName, data);\n }\n }\n};\n\n},{\"./jsFlashBridgeRegistry\":6,\"./registry\":7,\"./utils\":8}],6:[function(require,module,exports){\n'use strict';\n\nvar SingleValueRegistry = require('./registry').SingleValueRegistry;\nvar instances = new SingleValueRegistry();\n\nvar JSFlashBridgeRegistry = {};\nObject.defineProperty(JSFlashBridgeRegistry, 'addInstance', {\n writable: false,\n configurable: false,\n value: function value(id, instance) {\n instances.add(id, instance);\n }\n});\n\nObject.defineProperty(JSFlashBridgeRegistry, 'getInstanceByID', {\n writable: false,\n configurable: false,\n value: function value(id) {\n return instances.get(id);\n }\n});\n\nObject.defineProperty(JSFlashBridgeRegistry, 'removeInstanceByID', {\n writable: false,\n configurable: false,\n value: function value(id) {\n return instances.remove(id);\n }\n});\n\nmodule.exports = JSFlashBridgeRegistry;\n\n},{\"./registry\":7}],7:[function(require,module,exports){\n'use strict';\n\nvar _createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if (\"value\" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);\n }\n }return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;\n };\n}();\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nfunction _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}\n\nvar MultipleValuesRegistry = exports.MultipleValuesRegistry = function () {\n function MultipleValuesRegistry() {\n _classCallCheck(this, MultipleValuesRegistry);\n\n this._registries = {};\n }\n\n _createClass(MultipleValuesRegistry, [{\n key: 'add',\n value: function add(id, value) {\n if (!this._registries[id]) {\n this._registries[id] = [];\n }\n if (this._registries[id].indexOf(value) === -1) {\n this._registries[id].push(value);\n }\n }\n }, {\n key: 'get',\n value: function get(id) {\n return this._registries[id] || [];\n }\n }, {\n key: 'filterKeys',\n value: function filterKeys(handler) {\n return Object.keys(this._registries).filter(handler);\n }\n }, {\n key: 'findByValue',\n value: function findByValue(value) {\n var _this = this;\n\n var keys = Object.keys(this._registries).filter(function (key) {\n return _this._registries[key].indexOf(value) !== -1;\n });\n\n return keys;\n }\n }, {\n key: 'remove',\n value: function remove(key, value) {\n if (!this._registries[key]) {\n return;\n }\n\n var index = this._registries[key].indexOf(value);\n\n if (index < 0) {\n return;\n }\n return this._registries[key].splice(index, 1);\n }\n }, {\n key: 'removeByKey',\n value: function removeByKey(id) {\n var old = this._registries[id];\n delete this._registries[id];\n return old;\n }\n }, {\n key: 'removeByValue',\n value: function removeByValue(value) {\n var _this2 = this;\n\n var keys = this.findByValue(value);\n return keys.map(function (key) {\n return _this2.remove(key, value);\n });\n }\n }, {\n key: 'removeAll',\n value: function removeAll() {\n var old = this._registries;\n this._registries = {};\n return old;\n }\n }, {\n key: 'size',\n value: function size() {\n return Object.keys(this._registries).length;\n }\n }]);\n\n return MultipleValuesRegistry;\n}();\n\nvar SingleValueRegistry = exports.SingleValueRegistry = function () {\n function SingleValueRegistry() {\n _classCallCheck(this, SingleValueRegistry);\n\n this._registries = {};\n }\n\n _createClass(SingleValueRegistry, [{\n key: 'add',\n value: function add(id, value) {\n this._registries[id] = value;\n }\n }, {\n key: 'get',\n value: function get(id) {\n return this._registries[id];\n }\n }, {\n key: 'filterKeys',\n value: function filterKeys(handler) {\n return Object.keys(this._registries).filter(handler);\n }\n }, {\n key: 'findByValue',\n value: function findByValue(value) {\n var _this3 = this;\n\n var keys = Object.keys(this._registries).filter(function (key) {\n return _this3._registries[key] === value;\n });\n\n return keys;\n }\n }, {\n key: 'remove',\n value: function remove(id) {\n var old = this._registries[id];\n delete this._registries[id];\n return old;\n }\n }, {\n key: 'removeByValue',\n value: function removeByValue(value) {\n var _this4 = this;\n\n var keys = this.findByValue(value);\n return keys.map(function (key) {\n return _this4.remove(key);\n });\n }\n }, {\n key: 'removeAll',\n value: function removeAll() {\n var old = this._registries;\n this._registries = {};\n return old;\n }\n }, {\n key: 'size',\n value: function size() {\n return Object.keys(this._registries).length;\n }\n }]);\n\n return SingleValueRegistry;\n}();\n\n},{}],8:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.unique = unique;\nexports.noop = noop;\nexports.callbackTimeout = callbackTimeout;\nexports.createElementWithID = createElementWithID;\nexports.isPositiveInt = isPositiveInt;\nexports.stringEndsWith = stringEndsWith;\nexports.hideFlashEl = hideFlashEl;\nfunction unique(prefix) {\n var count = -1;\n return function (f) {\n return prefix + '_' + ++count;\n };\n}\n\nfunction noop() {}\n\nfunction callbackTimeout(timer, onSuccess, onTimeout) {\n\n var timeout = setTimeout(function () {\n\n onSuccess = noop;\n onTimeout();\n }, timer);\n\n return function () {\n clearTimeout(timeout);\n onSuccess.apply(this, arguments);\n };\n}\n\nfunction createElementWithID(parent, id) {\n var cleanContent = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n var nEl = document.createElement('div');\n nEl.id = id;\n if (cleanContent) {\n parent.innerHTML = '';\n }\n parent.appendChild(nEl);\n return nEl;\n}\n\nfunction isPositiveInt(newVal, oldVal) {\n return !isNaN(parseFloat(newVal)) && isFinite(newVal) && newVal > 0 ? newVal : oldVal;\n}\n\nvar endsWith = function () {\n if (String.prototype.endsWith) return String.prototype.endsWith;\n return function endsWith(searchString, position) {\n var subjectString = this.toString();\n if (position === undefined || position > subjectString.length) {\n position = subjectString.length;\n }\n position -= searchString.length;\n var lastIndex = subjectString.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n };\n}();\n\nfunction stringEndsWith(string, search) {\n return endsWith.call(string, search);\n}\n\nfunction hideFlashEl(el) {\n // can't use display none or visibility none because will block flash in some browsers\n el.style.position = 'absolute';\n el.style.left = '-1px';\n el.style.top = '-1px';\n el.style.width = '1px';\n el.style.height = '1px';\n}\n\n},{}],9:[function(require,module,exports){\n'use strict';\n\nvar METHODS = [\n 'handshakeVersion',\n 'initAd',\n 'startAd',\n 'stopAd',\n 'skipAd', // VPAID 2.0 new method\n 'resizeAd',\n 'pauseAd',\n 'resumeAd',\n 'expandAd',\n 'collapseAd',\n 'subscribe',\n 'unsubscribe'\n];\n\nvar EVENTS = [\n 'AdLoaded',\n 'AdStarted',\n 'AdStopped',\n 'AdSkipped',\n 'AdSkippableStateChange', // VPAID 2.0 new event\n 'AdSizeChange', // VPAID 2.0 new event\n 'AdLinearChange',\n 'AdDurationChange', // VPAID 2.0 new event\n 'AdExpandedChange',\n 'AdRemainingTimeChange', // [Deprecated in 2.0] but will be still fired for backwards compatibility\n 'AdVolumeChange',\n 'AdImpression',\n 'AdVideoStart',\n 'AdVideoFirstQuartile',\n 'AdVideoMidpoint',\n 'AdVideoThirdQuartile',\n 'AdVideoComplete',\n 'AdClickThru',\n 'AdInteraction', // VPAID 2.0 new event\n 'AdUserAcceptInvitation',\n 'AdUserMinimize',\n 'AdUserClose',\n 'AdPaused',\n 'AdPlaying',\n 'AdLog',\n 'AdError'\n];\n\nvar GETTERS = [\n 'getAdLinear',\n 'getAdWidth', // VPAID 2.0 new getter\n 'getAdHeight', // VPAID 2.0 new getter\n 'getAdExpanded',\n 'getAdSkippableState', // VPAID 2.0 new getter\n 'getAdRemainingTime',\n 'getAdDuration', // VPAID 2.0 new getter\n 'getAdVolume',\n 'getAdCompanions', // VPAID 2.0 new getter\n 'getAdIcons' // VPAID 2.0 new getter\n];\n\nvar SETTERS = [\n 'setAdVolume'\n];\n\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n\n/**\n * IVPAIDAdUnit\n *\n * @class\n *\n * @param {object} creative\n * @param {HTMLElement} el\n * @param {HTMLVideoElement} video\n */\nfunction IVPAIDAdUnit(creative, el, video) {}\n\n\n/**\n * handshakeVersion\n *\n * @param {string} VPAIDVersion\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.handshakeVersion = function (VPAIDVersion, callback) {};\n\n/**\n * initAd\n *\n * @param {number} width\n * @param {number} height\n * @param {string} viewMode can be 'normal', 'thumbnail' or 'fullscreen'\n * @param {number} desiredBitrate indicates the desired bitrate in kbps\n * @param {object} [creativeData] used for additional initialization data\n * @param {object} [environmentVars] used for passing implementation-specific of js version\n * @param {NodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.initAd = function(width, height, viewMode, desiredBitrate, creativeData, environmentVars, callback) {};\n\n/**\n * startAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.startAd = function(callback) {};\n\n/**\n * stopAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.stopAd = function(callback) {};\n\n/**\n * skipAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.skipAd = function(callback) {};\n\n/**\n * resizeAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.resizeAd = function(width, height, viewMode, callback) {};\n\n/**\n * pauseAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.pauseAd = function(callback) {};\n\n/**\n * resumeAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.resumeAd = function(callback) {};\n\n/**\n * expandAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.expandAd = function(callback) {};\n\n/**\n * collapseAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.collapseAd = function(callback) {};\n\n/**\n * subscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n * @param {object} context\n */\nIVPAIDAdUnit.prototype.subscribe = function(event, handler, context) {};\n\n/**\n * startAd\n *\n * @param {string} event\n * @param {function} handler\n */\nIVPAIDAdUnit.prototype.unsubscribe = function(event, handler) {};\n\n\n\n/**\n * getAdLinear\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdLinear = function(callback) {};\n\n/**\n * getAdWidth\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdWidth = function(callback) {};\n\n/**\n * getAdHeight\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdHeight = function(callback) {};\n\n/**\n * getAdExpanded\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdExpanded = function(callback) {};\n\n/**\n * getAdSkippableState\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdSkippableState = function(callback) {};\n\n/**\n * getAdRemainingTime\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdRemainingTime = function(callback) {};\n\n/**\n * getAdDuration\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdDuration = function(callback) {};\n\n/**\n * getAdVolume\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdVolume = function(callback) {};\n\n/**\n * getAdCompanions\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdCompanions = function(callback) {};\n\n/**\n * getAdIcons\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdIcons = function(callback) {};\n\n/**\n * setAdVolume\n *\n * @param {number} volume\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.setAdVolume = function(volume, callback) {};\n\naddStaticToInterface(IVPAIDAdUnit, 'METHODS', METHODS);\naddStaticToInterface(IVPAIDAdUnit, 'GETTERS', GETTERS);\naddStaticToInterface(IVPAIDAdUnit, 'SETTERS', SETTERS);\naddStaticToInterface(IVPAIDAdUnit, 'EVENTS', EVENTS);\n\n\nvar VPAID1_METHODS = METHODS.filter(function(method) {\n return ['skipAd'].indexOf(method) === -1;\n});\n\naddStaticToInterface(IVPAIDAdUnit, 'checkVPAIDInterface', function checkVPAIDInterface (creative) {\n var result = VPAID1_METHODS.every(function(key) {\n return typeof creative[key] === 'function';\n });\n return result;\n});\n\nmodule.exports = IVPAIDAdUnit;\n\nfunction addStaticToInterface(Interface, name, value) {\n Object.defineProperty(Interface, name, {\n writable: false,\n configurable: false,\n value: value\n });\n}\n\n\n},{}],10:[function(require,module,exports){\n'use strict';\n\nvar IVPAIDAdUnit = require('./IVPAIDAdUnit');\nvar Subscriber = require('./subscriber');\nvar checkVPAIDInterface = IVPAIDAdUnit.checkVPAIDInterface;\nvar utils = require('./utils');\nvar METHODS = IVPAIDAdUnit.METHODS;\nvar ERROR = 'AdError';\nvar AD_CLICK = 'AdClickThru';\nvar FILTERED_EVENTS = IVPAIDAdUnit.EVENTS.filter(function (event) {\n return event != AD_CLICK;\n});\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n\n/**\n * VPAIDAdUnit\n * @class\n *\n * @param VPAIDCreative\n * @param {HTMLElement} [el] this will be used in initAd environmentVars.slot if defined\n * @param {HTMLVideoElement} [video] this will be used in initAd environmentVars.videoSlot if defined\n */\nfunction VPAIDAdUnit(VPAIDCreative, el, video, iframe) {\n this._isValid = checkVPAIDInterface(VPAIDCreative);\n if (this._isValid) {\n this._creative = VPAIDCreative;\n this._el = el;\n this._videoEl = video;\n this._iframe = iframe;\n this._subscribers = new Subscriber();\n $addEventsSubscribers.call(this);\n }\n}\n\nVPAIDAdUnit.prototype = Object.create(IVPAIDAdUnit.prototype);\n\n/**\n * isValidVPAIDAd will return if the VPAIDCreative passed in constructor is valid or not\n *\n * @return {boolean}\n */\nVPAIDAdUnit.prototype.isValidVPAIDAd = function isValidVPAIDAd() {\n return this._isValid;\n};\n\nIVPAIDAdUnit.METHODS.forEach(function(method) {\n //NOTE: this methods arguments order are implemented differently from the spec\n var ignores = [\n 'subscribe',\n 'unsubscribe',\n 'initAd'\n ];\n\n if (ignores.indexOf(method) !== -1) return;\n\n VPAIDAdUnit.prototype[method] = function () {\n var ariaty = IVPAIDAdUnit.prototype[method].length;\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n var args = Array.prototype.slice.call(arguments);\n var callback = (ariaty === args.length) ? args.pop() : undefined;\n\n setTimeout(function () {\n var result, error = null;\n try {\n result = this._creative[method].apply(this._creative, args);\n } catch(e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n };\n});\n\n\n/**\n * initAd concreate implementation\n *\n * @param {number} width\n * @param {number} height\n * @param {string} viewMode can be 'normal', 'thumbnail' or 'fullscreen'\n * @param {number} desiredBitrate indicates the desired bitrate in kbps\n * @param {object} [creativeData] used for additional initialization data\n * @param {object} [environmentVars] used for passing implementation-specific of js version, if el & video was used in constructor slot & videoSlot will be added to the object\n * @param {NodeStyleCallback} callback\n */\nVPAIDAdUnit.prototype.initAd = function initAd(width, height, viewMode, desiredBitrate, creativeData, environmentVars, callback) {\n creativeData = creativeData || {};\n environmentVars = utils.extend({\n slot: this._el,\n videoSlot: this._videoEl\n }, environmentVars || {});\n\n setTimeout(function () {\n var error;\n try {\n this._creative.initAd(width, height, viewMode, desiredBitrate, creativeData, environmentVars);\n } catch (e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error);\n }.bind(this), 0);\n};\n\n/**\n * subscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n * @param {object} context\n */\nVPAIDAdUnit.prototype.subscribe = function subscribe(event, handler, context) {\n this._subscribers.subscribe(handler, event, context);\n};\n\n\n/**\n * unsubscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n */\nVPAIDAdUnit.prototype.unsubscribe = function unsubscribe(event, handler) {\n this._subscribers.unsubscribe(handler, event);\n};\n\n//alias\nVPAIDAdUnit.prototype.on = VPAIDAdUnit.prototype.subscribe;\nVPAIDAdUnit.prototype.off = VPAIDAdUnit.prototype.unsubscribe;\n\nIVPAIDAdUnit.GETTERS.forEach(function(getter) {\n VPAIDAdUnit.prototype[getter] = function (callback) {\n setTimeout(function () {\n\n var result, error = null;\n try {\n result = this._creative[getter]();\n } catch(e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n };\n});\n\n/**\n * setAdVolume\n *\n * @param volume\n * @param {nodeStyleCallback} callback\n */\nVPAIDAdUnit.prototype.setAdVolume = function setAdVolume(volume, callback) {\n setTimeout(function () {\n\n var result, error = null;\n try {\n this._creative.setAdVolume(volume);\n result = this._creative.getAdVolume();\n } catch(e) {\n error = e;\n }\n\n if (!error) {\n error = utils.validate(result === volume, 'failed to apply volume: ' + volume);\n }\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n};\n\nVPAIDAdUnit.prototype._destroy = function destroy() {\n this.stopAd();\n this._subscribers.unsubscribeAll();\n};\n\nfunction $addEventsSubscribers() {\n // some ads implement\n // so they only handle one subscriber\n // to handle this we create our one\n FILTERED_EVENTS.forEach(function (event) {\n this._creative.subscribe($trigger.bind(this, event), event);\n }.bind(this));\n\n // map the click event to be an object instead of depending of the order of the arguments\n // and to be consistent with the flash\n this._creative.subscribe($clickThruHook.bind(this), AD_CLICK);\n\n // because we are adding the element inside the iframe\n // the user is not able to click in the video\n if (this._videoEl) {\n var documentElement = this._iframe.contentDocument.documentElement;\n var videoEl = this._videoEl;\n documentElement.addEventListener('click', function(e) {\n if (e.target === documentElement) {\n videoEl.click();\n }\n });\n }\n}\n\nfunction $clickThruHook(url, id, playerHandles) {\n this._subscribers.triggerSync(AD_CLICK, {url: url, id: id, playerHandles: playerHandles});\n}\n\nfunction $trigger(event) {\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n this._subscribers.trigger(event, Array.prototype.slice(arguments, 1));\n}\n\nfunction callOrTriggerEvent(callback, subscribers, error, result) {\n if (callback) {\n callback(error, result);\n } else if (error) {\n subscribers.trigger(ERROR, error);\n }\n}\n\nmodule.exports = VPAIDAdUnit;\n\n\n},{\"./IVPAIDAdUnit\":9,\"./subscriber\":12,\"./utils\":13}],11:[function(require,module,exports){\n'use strict';\n\nvar utils = require('./utils');\nvar unique = utils.unique('vpaidIframe');\nvar VPAIDAdUnit = require('./VPAIDAdUnit');\n\nvar defaultTemplate = '' +\n '' +\n '' +\n '
' +\n '' +\n '' +\n '' +\n '';\n\nvar AD_STOPPED = 'AdStopped';\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n/**\n * VPAIDHTML5Client\n * @class\n *\n * @param {HTMLElement} el that will contain the iframe to load adUnit and a el to add to adUnit slot\n * @param {HTMLVideoElement} video default video element to be used by adUnit\n * @param {object} [templateConfig] template: html template to be used instead of the default, extraOptions: to be used when rendering the template\n * @param {object} [vpaidOptions] timeout: when loading adUnit\n */\nfunction VPAIDHTML5Client(el, video, templateConfig, vpaidOptions) {\n templateConfig = templateConfig || {};\n\n this._id = unique();\n this._destroyed = false;\n\n this._frameContainer = utils.createElementInEl(el, 'div');\n this._videoEl = video;\n this._vpaidOptions = vpaidOptions || {timeout: 10000};\n\n this._templateConfig = {\n template: templateConfig.template || defaultTemplate,\n extraOptions: templateConfig.extraOptions || {}\n };\n}\n\n/**\n * destroy\n *\n */\nVPAIDHTML5Client.prototype.destroy = function destroy() {\n if (this._destroyed) {\n return;\n }\n this._destroyed = true;\n $unloadPreviousAdUnit.call(this);\n};\n\n/**\n * isDestroyed\n *\n * @return {boolean}\n */\nVPAIDHTML5Client.prototype.isDestroyed = function isDestroyed() {\n return this._destroyed;\n};\n\n/**\n * loadAdUnit\n *\n * @param {string} adURL url of the js of the adUnit\n * @param {nodeStyleCallback} callback\n */\nVPAIDHTML5Client.prototype.loadAdUnit = function loadAdUnit(adURL, callback) {\n $throwIfDestroyed.call(this);\n $unloadPreviousAdUnit.call(this);\n var that = this;\n\n var frame = utils.createIframeWithContent(\n this._frameContainer,\n this._templateConfig.template,\n utils.extend({\n iframeURL_JS: adURL,\n iframeID: this.getID(),\n origin: getOrigin()\n }, this._templateConfig.extraOptions)\n );\n\n this._frame = frame;\n\n this._onLoad = utils.callbackTimeout(\n this._vpaidOptions.timeout,\n onLoad.bind(this),\n onTimeout.bind(this)\n );\n\n window.addEventListener('message', this._onLoad);\n\n function onLoad (e) {\n /*jshint validthis: false */\n //don't clear timeout\n if (e.origin !== getOrigin()) return;\n var result = JSON.parse(e.data);\n\n //don't clear timeout\n if (result.id !== that.getID()) return;\n\n var adUnit, error, createAd;\n if (!that._frame.contentWindow) {\n\n error = 'the iframe is not anymore in the DOM tree';\n\n } else {\n createAd = that._frame.contentWindow.getVPAIDAd;\n error = utils.validate(typeof createAd === 'function', 'the ad didn\\'t return a function to create an ad');\n }\n\n if (!error) {\n var adEl = that._frame.contentWindow.document.querySelector('.ad-element');\n adUnit = new VPAIDAdUnit(createAd(), adEl, that._videoEl, that._frame);\n adUnit.subscribe(AD_STOPPED, $adDestroyed.bind(that));\n error = utils.validate(adUnit.isValidVPAIDAd(), 'the add is not fully complaint with VPAID specification');\n }\n\n that._adUnit = adUnit;\n $destroyLoadListener.call(that);\n callback(error, error ? null : adUnit);\n\n //clear timeout\n return true;\n }\n\n function onTimeout() {\n callback('timeout', null);\n }\n};\n\n/**\n * unloadAdUnit\n *\n */\nVPAIDHTML5Client.prototype.unloadAdUnit = function unloadAdUnit() {\n $unloadPreviousAdUnit.call(this);\n};\n\n/**\n * getID will return the unique id\n *\n * @return {string}\n */\nVPAIDHTML5Client.prototype.getID = function () {\n return this._id;\n};\n\n\n/**\n * $removeEl\n *\n * @param {string} key\n */\nfunction $removeEl(key) {\n var el = this[key];\n if (el) {\n el.remove();\n delete this[key];\n }\n}\n\nfunction $adDestroyed() {\n $removeAdElements.call(this);\n delete this._adUnit;\n}\n\nfunction $unloadPreviousAdUnit() {\n $removeAdElements.call(this);\n $destroyAdUnit.call(this);\n}\n\nfunction $removeAdElements() {\n $removeEl.call(this, '_frame');\n $destroyLoadListener.call(this);\n}\n\n/**\n * $destroyLoadListener\n *\n */\nfunction $destroyLoadListener() {\n if (this._onLoad) {\n window.removeEventListener('message', this._onLoad);\n utils.clearCallbackTimeout(this._onLoad);\n delete this._onLoad;\n }\n}\n\n\nfunction $destroyAdUnit() {\n if (this._adUnit) {\n this._adUnit.stopAd();\n delete this._adUnit;\n }\n}\n\n/**\n * $throwIfDestroyed\n *\n */\nfunction $throwIfDestroyed() {\n if (this._destroyed) {\n throw new Error ('VPAIDHTML5Client already destroyed!');\n }\n}\n\nfunction getOrigin() {\n if( window.location.origin ) {\n return window.location.origin;\n }\n else {\n return window.location.protocol + \"//\" +\n window.location.hostname +\n (window.location.port ? ':' + window.location.port: '');\n }\n}\n\nmodule.exports = VPAIDHTML5Client;\nwindow.VPAIDHTML5Client = VPAIDHTML5Client;\n\n\n},{\"./VPAIDAdUnit\":10,\"./utils\":13}],12:[function(require,module,exports){\n'use strict';\n\nfunction Subscriber() {\n this._subscribers = {};\n}\n\nSubscriber.prototype.subscribe = function subscribe(handler, eventName, context) {\n if (!this.isHandlerAttached(handler, eventName)) {\n this.get(eventName).push({handler: handler, context: context, eventName: eventName});\n }\n};\n\nSubscriber.prototype.unsubscribe = function unsubscribe(handler, eventName) {\n this._subscribers[eventName] = this.get(eventName).filter(function (subscriber) {\n return handler !== subscriber.handler;\n });\n};\n\nSubscriber.prototype.unsubscribeAll = function unsubscribeAll() {\n this._subscribers = {};\n};\n\nSubscriber.prototype.trigger = function(eventName, data) {\n var that = this;\n var subscribers = this.get(eventName)\n .concat(this.get('*'));\n\n subscribers.forEach(function (subscriber) {\n setTimeout(function () {\n if (that.isHandlerAttached(subscriber.handler, subscriber.eventName)) {\n subscriber.handler.call(subscriber.context, data);\n }\n }, 0);\n });\n};\n\nSubscriber.prototype.triggerSync = function(eventName, data) {\n var subscribers = this.get(eventName)\n .concat(this.get('*'));\n\n subscribers.forEach(function (subscriber) {\n subscriber.handler.call(subscriber.context, data);\n });\n};\n\nSubscriber.prototype.get = function get(eventName) {\n if (!this._subscribers[eventName]) {\n this._subscribers[eventName] = [];\n }\n return this._subscribers[eventName];\n};\n\nSubscriber.prototype.isHandlerAttached = function isHandlerAttached(handler, eventName) {\n return this.get(eventName).some(function(subscriber) {\n return handler === subscriber.handler;\n })\n};\n\nmodule.exports = Subscriber;\n\n\n},{}],13:[function(require,module,exports){\n'use strict';\n\n/**\n * noop a empty function\n */\nfunction noop() {}\n\n/**\n * validate if is not validate will return an Error with the message\n *\n * @param {boolean} isValid\n * @param {string} message\n */\nfunction validate(isValid, message) {\n return isValid ? null : new Error(message);\n}\n\nvar timeouts = {};\n/**\n * clearCallbackTimeout\n *\n * @param {function} func handler to remove\n */\nfunction clearCallbackTimeout(func) {\n var timeout = timeouts[func];\n if (timeout) {\n clearTimeout(timeout);\n delete timeouts[func];\n }\n}\n\n/**\n * callbackTimeout if the onSuccess is not called and returns true in the timelimit then onTimeout will be called\n *\n * @param {number} timer\n * @param {function} onSuccess\n * @param {function} onTimeout\n */\nfunction callbackTimeout(timer, onSuccess, onTimeout) {\n var callback, timeout;\n\n timeout = setTimeout(function () {\n onSuccess = noop;\n delete timeout[callback];\n onTimeout();\n }, timer);\n\n callback = function () {\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n if (onSuccess.apply(this, arguments)) {\n clearCallbackTimeout(callback);\n }\n };\n\n timeouts[callback] = timeout;\n\n return callback;\n}\n\n\n/**\n * createElementInEl\n *\n * @param {HTMLElement} parent\n * @param {string} tagName\n * @param {string} id\n */\nfunction createElementInEl(parent, tagName, id) {\n var nEl = document.createElement(tagName);\n if (id) nEl.id = id;\n parent.appendChild(nEl);\n return nEl;\n}\n\n/**\n * createIframeWithContent\n *\n * @param {HTMLElement} parent\n * @param {string} template simple template using {{var}}\n * @param {object} data\n */\nfunction createIframeWithContent(parent, template, data) {\n var iframe = createIframe(parent, null, data.zIndex);\n if (!setIframeContent(iframe, simpleTemplate(template, data))) return;\n return iframe;\n}\n\n/**\n * createIframe\n *\n * @param {HTMLElement} parent\n * @param {string} url\n */\nfunction createIframe(parent, url, zIndex) {\n var nEl = document.createElement('iframe');\n nEl.src = url || 'about:blank';\n nEl.marginWidth = '0';\n nEl.marginHeight = '0';\n nEl.frameBorder = '0';\n nEl.width = '100%';\n nEl.height = '100%';\n nEl.style.position = 'absolute';\n nEl.style.left = '0';\n nEl.style.top = '0';\n nEl.style.margin = '0px';\n nEl.style.padding = '0px';\n nEl.style.border = 'none';\n\n if(zIndex){\n nEl.style.zIndex = zIndex;\n }\n\n nEl.setAttribute('SCROLLING','NO');\n parent.innerHTML = '';\n parent.appendChild(nEl);\n return nEl;\n}\n\n/**\n * simpleTemplate\n *\n * @param {string} template\n * @param {object} data\n */\nfunction simpleTemplate(template, data) {\n Object.keys(data).forEach(function (key) {\n var value = (typeof value === 'object') ? JSON.stringify(data[key]) : data[key];\n template = template.replace(new RegExp('{{' + key + '}}', 'g'), value);\n });\n return template;\n}\n\n/**\n * setIframeContent\n *\n * @param {HTMLIframeElement} iframeEl\n * @param content\n */\nfunction setIframeContent(iframeEl, content) {\n var iframeDoc = iframeEl.contentWindow && iframeEl.contentWindow.document;\n if (!iframeDoc) return false;\n\n iframeDoc.write(content);\n\n return true;\n}\n\n\n/**\n * extend object with keys from another object\n *\n * @param {object} toExtend\n * @param {object} fromSource\n */\nfunction extend(toExtend, fromSource) {\n Object.keys(fromSource).forEach(function(key) {\n toExtend[key] = fromSource[key];\n });\n return toExtend;\n}\n\n\n/**\n * unique will create a unique string everytime is called, sequentially and prefixed\n *\n * @param {string} prefix\n */\nfunction unique(prefix) {\n var count = -1;\n return function () {\n return prefix + '_' + (++count);\n };\n}\n\nmodule.exports = {\n noop: noop,\n validate: validate,\n clearCallbackTimeout: clearCallbackTimeout,\n callbackTimeout: callbackTimeout,\n createElementInEl: createElementInEl,\n createIframeWithContent: createIframeWithContent,\n createIframe: createIframe,\n simpleTemplate: simpleTemplate,\n setIframeContent: setIframeContent,\n extend: extend,\n unique: unique\n};\n\n\n},{}],14:[function(require,module,exports){\n/*! SWFObject v2.3.20130521 \r\n is released under the MIT License \r\n*/\r\n\r\n/* global ActiveXObject: false */\r\n\r\n(function (root, factory) {\r\n if (typeof define === 'function' && define.amd) {\r\n // AMD\r\n define(factory);\r\n } else if (typeof module === 'object' && module.exports) {\r\n // Node, CommonJS-like\r\n module.exports = factory();\r\n } else {\r\n // Browser globals (root is window)\r\n root.swfobject = factory();\r\n }\r\n}(this, function () {\r\n\r\n var UNDEF = \"undefined\",\r\n OBJECT = \"object\",\r\n SHOCKWAVE_FLASH = \"Shockwave Flash\",\r\n SHOCKWAVE_FLASH_AX = \"ShockwaveFlash.ShockwaveFlash\",\r\n FLASH_MIME_TYPE = \"application/x-shockwave-flash\",\r\n EXPRESS_INSTALL_ID = \"SWFObjectExprInst\",\r\n ON_READY_STATE_CHANGE = \"onreadystatechange\",\r\n\r\n win = window,\r\n doc = document,\r\n nav = navigator,\r\n\r\n plugin = false,\r\n domLoadFnArr = [],\r\n regObjArr = [],\r\n objIdArr = [],\r\n listenersArr = [],\r\n storedFbContent,\r\n storedFbContentId,\r\n storedCallbackFn,\r\n storedCallbackObj,\r\n isDomLoaded = false,\r\n isExpressInstallActive = false,\r\n dynamicStylesheet,\r\n dynamicStylesheetMedia,\r\n autoHideShow = true,\r\n encodeURIEnabled = false,\r\n\r\n /* Centralized function for browser feature detection\r\n - User agent string detection is only used when no good alternative is possible\r\n - Is executed directly for optimal performance\r\n */\r\n ua = function () {\r\n var w3cdom = typeof doc.getElementById !== UNDEF && typeof doc.getElementsByTagName !== UNDEF && typeof doc.createElement !== UNDEF,\r\n u = nav.userAgent.toLowerCase(),\r\n p = nav.platform.toLowerCase(),\r\n windows = p ? /win/.test(p) : /win/.test(u),\r\n mac = p ? /mac/.test(p) : /mac/.test(u),\r\n webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\\/(\\d+(\\.\\d+)?).*$/, \"$1\")) : false, // returns either the webkit version or false if not webkit\r\n ie = nav.appName === \"Microsoft Internet Explorer\",\r\n playerVersion = [0, 0, 0],\r\n d = null;\r\n if (typeof nav.plugins !== UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] === OBJECT) {\r\n d = nav.plugins[SHOCKWAVE_FLASH].description;\r\n // nav.mimeTypes[\"application/x-shockwave-flash\"].enabledPlugin indicates whether plug-ins are enabled or disabled in Safari 3+\r\n if (d && (typeof nav.mimeTypes !== UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) {\r\n plugin = true;\r\n ie = false; // cascaded feature detection for Internet Explorer\r\n d = d.replace(/^.*\\s+(\\S+\\s+\\S+$)/, \"$1\");\r\n playerVersion[0] = toInt(d.replace(/^(.*)\\..*$/, \"$1\"));\r\n playerVersion[1] = toInt(d.replace(/^.*\\.(.*)\\s.*$/, \"$1\"));\r\n playerVersion[2] = /[a-zA-Z]/.test(d) ? toInt(d.replace(/^.*[a-zA-Z]+(.*)$/, \"$1\")) : 0;\r\n }\r\n }\r\n else if (typeof win.ActiveXObject !== UNDEF) {\r\n try {\r\n var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);\r\n if (a) { // a will return null when ActiveX is disabled\r\n d = a.GetVariable(\"$version\");\r\n if (d) {\r\n ie = true; // cascaded feature detection for Internet Explorer\r\n d = d.split(\" \")[1].split(\",\");\r\n playerVersion = [toInt(d[0]), toInt(d[1]), toInt(d[2])];\r\n }\r\n }\r\n }\r\n catch (e) {}\r\n }\r\n return {w3: w3cdom, pv: playerVersion, wk: webkit, ie: ie, win: windows, mac: mac};\r\n }(),\r\n\r\n /* Cross-browser onDomLoad\r\n - Will fire an event as soon as the DOM of a web page is loaded\r\n - Internet Explorer workaround based on Diego Perini's solution: http://javascript.nwbox.com/IEContentLoaded/\r\n - Regular onload serves as fallback\r\n */\r\n onDomLoad = function () {\r\n if (!ua.w3) { return; }\r\n if ((typeof doc.readyState !== UNDEF && (doc.readyState === \"complete\" || doc.readyState === \"interactive\")) || (typeof doc.readyState === UNDEF && (doc.getElementsByTagName(\"body\")[0] || doc.body))) { // function is fired after onload, e.g. when script is inserted dynamically\r\n callDomLoadFunctions();\r\n }\r\n if (!isDomLoaded) {\r\n if (typeof doc.addEventListener !== UNDEF) {\r\n doc.addEventListener(\"DOMContentLoaded\", callDomLoadFunctions, false);\r\n }\r\n if (ua.ie) {\r\n doc.attachEvent(ON_READY_STATE_CHANGE, function detach() {\r\n if (doc.readyState === \"complete\") {\r\n doc.detachEvent(ON_READY_STATE_CHANGE, detach);\r\n callDomLoadFunctions();\r\n }\r\n });\r\n if (win == top) { // if not inside an iframe\r\n (function checkDomLoadedIE() {\r\n if (isDomLoaded) { return; }\r\n try {\r\n doc.documentElement.doScroll(\"left\");\r\n }\r\n catch (e) {\r\n setTimeout(checkDomLoadedIE, 0);\r\n return;\r\n }\r\n callDomLoadFunctions();\r\n }());\r\n }\r\n }\r\n if (ua.wk) {\r\n (function checkDomLoadedWK() {\r\n if (isDomLoaded) { return; }\r\n if (!/loaded|complete/.test(doc.readyState)) {\r\n setTimeout(checkDomLoadedWK, 0);\r\n return;\r\n }\r\n callDomLoadFunctions();\r\n }());\r\n }\r\n }\r\n }();\r\n\r\n function callDomLoadFunctions() {\r\n if (isDomLoaded || !document.getElementsByTagName(\"body\")[0]) { return; }\r\n try { // test if we can really add/remove elements to/from the DOM; we don't want to fire it too early\r\n var t, span = createElement(\"span\");\r\n span.style.display = \"none\"; //hide the span in case someone has styled spans via CSS\r\n t = doc.getElementsByTagName(\"body\")[0].appendChild(span);\r\n t.parentNode.removeChild(t);\r\n t = null; //clear the variables\r\n span = null;\r\n }\r\n catch (e) { return; }\r\n isDomLoaded = true;\r\n var dl = domLoadFnArr.length;\r\n for (var i = 0; i < dl; i++) {\r\n domLoadFnArr[i]();\r\n }\r\n }\r\n\r\n function addDomLoadEvent(fn) {\r\n if (isDomLoaded) {\r\n fn();\r\n }\r\n else {\r\n domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+\r\n }\r\n }\r\n\r\n /* Cross-browser onload\r\n - Based on James Edwards' solution: http://brothercake.com/site/resources/scripts/onload/\r\n - Will fire an event as soon as a web page including all of its assets are loaded\r\n */\r\n function addLoadEvent(fn) {\r\n if (typeof win.addEventListener !== UNDEF) {\r\n win.addEventListener(\"load\", fn, false);\r\n }\r\n else if (typeof doc.addEventListener !== UNDEF) {\r\n doc.addEventListener(\"load\", fn, false);\r\n }\r\n else if (typeof win.attachEvent !== UNDEF) {\r\n addListener(win, \"onload\", fn);\r\n }\r\n else if (typeof win.onload === \"function\") {\r\n var fnOld = win.onload;\r\n win.onload = function () {\r\n fnOld();\r\n fn();\r\n };\r\n }\r\n else {\r\n win.onload = fn;\r\n }\r\n }\r\n\r\n /* Detect the Flash Player version for non-Internet Explorer browsers\r\n - Detecting the plug-in version via the object element is more precise than using the plugins collection item's description:\r\n a. Both release and build numbers can be detected\r\n b. Avoid wrong descriptions by corrupt installers provided by Adobe\r\n c. Avoid wrong descriptions by multiple Flash Player entries in the plugin Array, caused by incorrect browser imports\r\n - Disadvantage of this method is that it depends on the availability of the DOM, while the plugins collection is immediately available\r\n */\r\n function testPlayerVersion() {\r\n var b = doc.getElementsByTagName(\"body\")[0];\r\n var o = createElement(OBJECT);\r\n o.setAttribute(\"style\", \"visibility: hidden;\");\r\n o.setAttribute(\"type\", FLASH_MIME_TYPE);\r\n var t = b.appendChild(o);\r\n if (t) {\r\n var counter = 0;\r\n (function checkGetVariable() {\r\n if (typeof t.GetVariable !== UNDEF) {\r\n try {\r\n var d = t.GetVariable(\"$version\");\r\n if (d) {\r\n d = d.split(\" \")[1].split(\",\");\r\n ua.pv = [toInt(d[0]), toInt(d[1]), toInt(d[2])];\r\n }\r\n } catch (e) {\r\n //t.GetVariable(\"$version\") is known to fail in Flash Player 8 on Firefox\r\n //If this error is encountered, assume FP8 or lower. Time to upgrade.\r\n ua.pv = [8, 0, 0];\r\n }\r\n }\r\n else if (counter < 10) {\r\n counter++;\r\n setTimeout(checkGetVariable, 10);\r\n return;\r\n }\r\n b.removeChild(o);\r\n t = null;\r\n matchVersions();\r\n }());\r\n }\r\n else {\r\n matchVersions();\r\n }\r\n }\r\n\r\n /* Perform Flash Player and SWF version matching; static publishing only\r\n */\r\n function matchVersions() {\r\n var rl = regObjArr.length;\r\n if (rl > 0) {\r\n for (var i = 0; i < rl; i++) { // for each registered object element\r\n var id = regObjArr[i].id;\r\n var cb = regObjArr[i].callbackFn;\r\n var cbObj = {success: false, id: id};\r\n if (ua.pv[0] > 0) {\r\n var obj = getElementById(id);\r\n if (obj) {\r\n if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { // Flash Player version >= published SWF version: Houston, we have a match!\r\n setVisibility(id, true);\r\n if (cb) {\r\n cbObj.success = true;\r\n cbObj.ref = getObjectById(id);\r\n cbObj.id = id;\r\n cb(cbObj);\r\n }\r\n }\r\n else if (regObjArr[i].expressInstall && canExpressInstall()) { // show the Adobe Express Install dialog if set by the web page author and if supported\r\n var att = {};\r\n att.data = regObjArr[i].expressInstall;\r\n att.width = obj.getAttribute(\"width\") || \"0\";\r\n att.height = obj.getAttribute(\"height\") || \"0\";\r\n if (obj.getAttribute(\"class\")) { att.styleclass = obj.getAttribute(\"class\"); }\r\n if (obj.getAttribute(\"align\")) { att.align = obj.getAttribute(\"align\"); }\r\n // parse HTML object param element's name-value pairs\r\n var par = {};\r\n var p = obj.getElementsByTagName(\"param\");\r\n var pl = p.length;\r\n for (var j = 0; j < pl; j++) {\r\n if (p[j].getAttribute(\"name\").toLowerCase() !== \"movie\") {\r\n par[p[j].getAttribute(\"name\")] = p[j].getAttribute(\"value\");\r\n }\r\n }\r\n showExpressInstall(att, par, id, cb);\r\n }\r\n else { // Flash Player and SWF version mismatch or an older Webkit engine that ignores the HTML object element's nested param elements: display fallback content instead of SWF\r\n displayFbContent(obj);\r\n if (cb) { cb(cbObj); }\r\n }\r\n }\r\n }\r\n else { // if no Flash Player is installed or the fp version cannot be detected we let the HTML object element do its job (either show a SWF or fallback content)\r\n setVisibility(id, true);\r\n if (cb) {\r\n var o = getObjectById(id); // test whether there is an HTML object element or not\r\n if (o && typeof o.SetVariable !== UNDEF) {\r\n cbObj.success = true;\r\n cbObj.ref = o;\r\n cbObj.id = o.id;\r\n }\r\n cb(cbObj);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /* Main function\r\n - Will preferably execute onDomLoad, otherwise onload (as a fallback)\r\n */\r\n domLoadFnArr[0] = function () {\r\n if (plugin) {\r\n testPlayerVersion();\r\n }\r\n else {\r\n matchVersions();\r\n }\r\n };\r\n\r\n function getObjectById(objectIdStr) {\r\n var r = null,\r\n o = getElementById(objectIdStr);\r\n\r\n if (o && o.nodeName.toUpperCase() === \"OBJECT\") {\r\n //If targeted object is valid Flash file\r\n if (typeof o.SetVariable !== UNDEF) {\r\n r = o;\r\n } else {\r\n //If SetVariable is not working on targeted object but a nested object is\r\n //available, assume classic nested object markup. Return nested object.\r\n\r\n //If SetVariable is not working on targeted object and there is no nested object,\r\n //return the original object anyway. This is probably new simplified markup.\r\n\r\n r = o.getElementsByTagName(OBJECT)[0] || o;\r\n }\r\n }\r\n\r\n return r;\r\n }\r\n\r\n /* Requirements for Adobe Express Install\r\n - only one instance can be active at a time\r\n - fp 6.0.65 or higher\r\n - Win/Mac OS only\r\n - no Webkit engines older than version 312\r\n */\r\n function canExpressInstall() {\r\n return !isExpressInstallActive && hasPlayerVersion(\"6.0.65\") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);\r\n }\r\n\r\n /* Show the Adobe Express Install dialog\r\n - Reference: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75\r\n */\r\n function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {\r\n\r\n var obj = getElementById(replaceElemIdStr);\r\n\r\n //Ensure that replaceElemIdStr is really a string and not an element\r\n replaceElemIdStr = getId(replaceElemIdStr);\r\n\r\n isExpressInstallActive = true;\r\n storedCallbackFn = callbackFn || null;\r\n storedCallbackObj = {success: false, id: replaceElemIdStr};\r\n\r\n if (obj) {\r\n if (obj.nodeName.toUpperCase() === \"OBJECT\") { // static publishing\r\n storedFbContent = abstractFbContent(obj);\r\n storedFbContentId = null;\r\n }\r\n else { // dynamic publishing\r\n storedFbContent = obj;\r\n storedFbContentId = replaceElemIdStr;\r\n }\r\n att.id = EXPRESS_INSTALL_ID;\r\n if (typeof att.width === UNDEF || (!/%$/.test(att.width) && toInt(att.width) < 310)) { att.width = \"310\"; }\r\n if (typeof att.height === UNDEF || (!/%$/.test(att.height) && toInt(att.height) < 137)) { att.height = \"137\"; }\r\n var pt = ua.ie ? \"ActiveX\" : \"PlugIn\",\r\n fv = \"MMredirectURL=\" + encodeURIComponent(win.location.toString().replace(/&/g, \"%26\")) + \"&MMplayerType=\" + pt + \"&MMdoctitle=\" + encodeURIComponent(doc.title.slice(0, 47) + \" - Flash Player Installation\");\r\n if (typeof par.flashvars !== UNDEF) {\r\n par.flashvars += \"&\" + fv;\r\n }\r\n else {\r\n par.flashvars = fv;\r\n }\r\n // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it,\r\n // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work\r\n if (ua.ie && obj.readyState != 4) {\r\n var newObj = createElement(\"div\");\r\n replaceElemIdStr += \"SWFObjectNew\";\r\n newObj.setAttribute(\"id\", replaceElemIdStr);\r\n obj.parentNode.insertBefore(newObj, obj); // insert placeholder div that will be replaced by the object element that loads expressinstall.swf\r\n obj.style.display = \"none\";\r\n removeSWF(obj); //removeSWF accepts elements now\r\n }\r\n createSWF(att, par, replaceElemIdStr);\r\n }\r\n }\r\n\r\n /* Functions to abstract and display fallback content\r\n */\r\n function displayFbContent(obj) {\r\n if (ua.ie && obj.readyState != 4) {\r\n // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it,\r\n // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work\r\n obj.style.display = \"none\";\r\n var el = createElement(\"div\");\r\n obj.parentNode.insertBefore(el, obj); // insert placeholder div that will be replaced by the fallback content\r\n el.parentNode.replaceChild(abstractFbContent(obj), el);\r\n removeSWF(obj); //removeSWF accepts elements now\r\n }\r\n else {\r\n obj.parentNode.replaceChild(abstractFbContent(obj), obj);\r\n }\r\n }\r\n\r\n function abstractFbContent(obj) {\r\n var ac = createElement(\"div\");\r\n if (ua.win && ua.ie) {\r\n ac.innerHTML = obj.innerHTML;\r\n }\r\n else {\r\n var nestedObj = obj.getElementsByTagName(OBJECT)[0];\r\n if (nestedObj) {\r\n var c = nestedObj.childNodes;\r\n if (c) {\r\n var cl = c.length;\r\n for (var i = 0; i < cl; i++) {\r\n if (!(c[i].nodeType == 1 && c[i].nodeName === \"PARAM\") && !(c[i].nodeType == 8)) {\r\n ac.appendChild(c[i].cloneNode(true));\r\n }\r\n }\r\n }\r\n }\r\n }\r\n return ac;\r\n }\r\n\r\n function createIeObject(url, paramStr) {\r\n var div = createElement(\"div\");\r\n div.innerHTML = \"\" + paramStr + \"\";\r\n return div.firstChild;\r\n }\r\n\r\n /* Cross-browser dynamic SWF creation\r\n */\r\n function createSWF(attObj, parObj, id) {\r\n var r, el = getElementById(id);\r\n id = getId(id); // ensure id is truly an ID and not an element\r\n\r\n if (ua.wk && ua.wk < 312) { return r; }\r\n\r\n if (el) {\r\n var o = (ua.ie) ? createElement(\"div\") : createElement(OBJECT),\r\n attr,\r\n attrLower,\r\n param;\r\n\r\n if (typeof attObj.id === UNDEF) { // if no 'id' is defined for the object element, it will inherit the 'id' from the fallback content\r\n attObj.id = id;\r\n }\r\n\r\n //Add params\r\n for (param in parObj) {\r\n //filter out prototype additions from other potential libraries and IE specific param element\r\n if (parObj.hasOwnProperty(param) && param.toLowerCase() !== \"movie\") {\r\n createObjParam(o, param, parObj[param]);\r\n }\r\n }\r\n\r\n //Create IE object, complete with param nodes\r\n if (ua.ie) { o = createIeObject(attObj.data, o.innerHTML); }\r\n\r\n //Add attributes to object\r\n for (attr in attObj) {\r\n if (attObj.hasOwnProperty(attr)) { // filter out prototype additions from other potential libraries\r\n attrLower = attr.toLowerCase();\r\n\r\n // 'class' is an ECMA4 reserved keyword\r\n if (attrLower === \"styleclass\") {\r\n o.setAttribute(\"class\", attObj[attr]);\r\n } else if (attrLower !== \"classid\" && attrLower !== \"data\") {\r\n o.setAttribute(attr, attObj[attr]);\r\n }\r\n }\r\n }\r\n\r\n if (ua.ie) {\r\n objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on unload (dynamic publishing only)\r\n } else {\r\n o.setAttribute(\"type\", FLASH_MIME_TYPE);\r\n o.setAttribute(\"data\", attObj.data);\r\n }\r\n\r\n el.parentNode.replaceChild(o, el);\r\n r = o;\r\n }\r\n\r\n return r;\r\n }\r\n\r\n function createObjParam(el, pName, pValue) {\r\n var p = createElement(\"param\");\r\n p.setAttribute(\"name\", pName);\r\n p.setAttribute(\"value\", pValue);\r\n el.appendChild(p);\r\n }\r\n\r\n /* Cross-browser SWF removal\r\n - Especially needed to safely and completely remove a SWF in Internet Explorer\r\n */\r\n function removeSWF(id) {\r\n var obj = getElementById(id);\r\n if (obj && obj.nodeName.toUpperCase() === \"OBJECT\") {\r\n if (ua.ie) {\r\n obj.style.display = \"none\";\r\n (function removeSWFInIE() {\r\n if (obj.readyState == 4) {\r\n //This step prevents memory leaks in Internet Explorer\r\n for (var i in obj) {\r\n if (typeof obj[i] === \"function\") {\r\n obj[i] = null;\r\n }\r\n }\r\n obj.parentNode.removeChild(obj);\r\n } else {\r\n setTimeout(removeSWFInIE, 10);\r\n }\r\n }());\r\n }\r\n else {\r\n obj.parentNode.removeChild(obj);\r\n }\r\n }\r\n }\r\n\r\n function isElement(id) {\r\n return (id && id.nodeType && id.nodeType === 1);\r\n }\r\n\r\n function getId(thing) {\r\n return (isElement(thing)) ? thing.id : thing;\r\n }\r\n\r\n /* Functions to optimize JavaScript compression\r\n */\r\n function getElementById(id) {\r\n\r\n //Allow users to pass an element OR an element's ID\r\n if (isElement(id)) { return id; }\r\n\r\n var el = null;\r\n try {\r\n el = doc.getElementById(id);\r\n }\r\n catch (e) {}\r\n return el;\r\n }\r\n\r\n function createElement(el) {\r\n return doc.createElement(el);\r\n }\r\n\r\n //To aid compression; replaces 14 instances of pareseInt with radix\r\n function toInt(str) {\r\n return parseInt(str, 10);\r\n }\r\n\r\n /* Updated attachEvent function for Internet Explorer\r\n - Stores attachEvent information in an Array, so on unload the detachEvent functions can be called to avoid memory leaks\r\n */\r\n function addListener(target, eventType, fn) {\r\n target.attachEvent(eventType, fn);\r\n listenersArr[listenersArr.length] = [target, eventType, fn];\r\n }\r\n\r\n /* Flash Player and SWF content version matching\r\n */\r\n function hasPlayerVersion(rv) {\r\n rv += \"\"; //Coerce number to string, if needed.\r\n var pv = ua.pv, v = rv.split(\".\");\r\n v[0] = toInt(v[0]);\r\n v[1] = toInt(v[1]) || 0; // supports short notation, e.g. \"9\" instead of \"9.0.0\"\r\n v[2] = toInt(v[2]) || 0;\r\n return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;\r\n }\r\n\r\n /* Cross-browser dynamic CSS creation\r\n - Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php\r\n */\r\n function createCSS(sel, decl, media, newStyle) {\r\n var h = doc.getElementsByTagName(\"head\")[0];\r\n if (!h) { return; } // to also support badly authored HTML pages that lack a head element\r\n var m = (typeof media === \"string\") ? media : \"screen\";\r\n if (newStyle) {\r\n dynamicStylesheet = null;\r\n dynamicStylesheetMedia = null;\r\n }\r\n if (!dynamicStylesheet || dynamicStylesheetMedia != m) {\r\n // create dynamic stylesheet + get a global reference to it\r\n var s = createElement(\"style\");\r\n s.setAttribute(\"type\", \"text/css\");\r\n s.setAttribute(\"media\", m);\r\n dynamicStylesheet = h.appendChild(s);\r\n if (ua.ie && typeof doc.styleSheets !== UNDEF && doc.styleSheets.length > 0) {\r\n dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];\r\n }\r\n dynamicStylesheetMedia = m;\r\n }\r\n // add style rule\r\n if (dynamicStylesheet) {\r\n if (typeof dynamicStylesheet.addRule !== UNDEF) {\r\n dynamicStylesheet.addRule(sel, decl);\r\n } else if (typeof doc.createTextNode !== UNDEF) {\r\n dynamicStylesheet.appendChild(doc.createTextNode(sel + \" {\" + decl + \"}\"));\r\n }\r\n }\r\n }\r\n\r\n function setVisibility(id, isVisible) {\r\n if (!autoHideShow) { return; }\r\n var v = isVisible ? \"visible\" : \"hidden\",\r\n el = getElementById(id);\r\n if (isDomLoaded && el) {\r\n el.style.visibility = v;\r\n } else if (typeof id === \"string\") {\r\n createCSS(\"#\" + id, \"visibility:\" + v);\r\n }\r\n }\r\n\r\n /* Filter to avoid XSS attacks\r\n */\r\n function urlEncodeIfNecessary(s) {\r\n var regex = /[\\\\\\\"<>\\.;]/;\r\n var hasBadChars = regex.exec(s) !== null;\r\n return hasBadChars && typeof encodeURIComponent !== UNDEF ? encodeURIComponent(s) : s;\r\n }\r\n\r\n /* Release memory to avoid memory leaks caused by closures, fix hanging audio/video threads and force open sockets/NetConnections to disconnect (Internet Explorer only)\r\n */\r\n var cleanup = function () {\r\n if (ua.ie) {\r\n window.attachEvent(\"onunload\", function () {\r\n // remove listeners to avoid memory leaks\r\n var ll = listenersArr.length;\r\n for (var i = 0; i < ll; i++) {\r\n listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);\r\n }\r\n // cleanup dynamically embedded objects to fix audio/video threads and force open sockets and NetConnections to disconnect\r\n var il = objIdArr.length;\r\n for (var j = 0; j < il; j++) {\r\n removeSWF(objIdArr[j]);\r\n }\r\n // cleanup library's main closures to avoid memory leaks\r\n for (var k in ua) {\r\n ua[k] = null;\r\n }\r\n ua = null;\r\n for (var l in swfobject) {\r\n swfobject[l] = null;\r\n }\r\n swfobject = null;\r\n });\r\n }\r\n }();\r\n\r\n return {\r\n /* Public API\r\n - Reference: http://code.google.com/p/swfobject/wiki/documentation\r\n */\r\n registerObject: function (objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {\r\n if (ua.w3 && objectIdStr && swfVersionStr) {\r\n var regObj = {};\r\n regObj.id = objectIdStr;\r\n regObj.swfVersion = swfVersionStr;\r\n regObj.expressInstall = xiSwfUrlStr;\r\n regObj.callbackFn = callbackFn;\r\n regObjArr[regObjArr.length] = regObj;\r\n setVisibility(objectIdStr, false);\r\n }\r\n else if (callbackFn) {\r\n callbackFn({success: false, id: objectIdStr});\r\n }\r\n },\r\n\r\n getObjectById: function (objectIdStr) {\r\n if (ua.w3) {\r\n return getObjectById(objectIdStr);\r\n }\r\n },\r\n\r\n embedSWF: function (swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {\r\n\r\n var id = getId(replaceElemIdStr),\r\n callbackObj = {success: false, id: id};\r\n\r\n if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {\r\n setVisibility(id, false);\r\n addDomLoadEvent(function () {\r\n widthStr += \"\"; // auto-convert to string\r\n heightStr += \"\";\r\n var att = {};\r\n if (attObj && typeof attObj === OBJECT) {\r\n for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs\r\n att[i] = attObj[i];\r\n }\r\n }\r\n att.data = swfUrlStr;\r\n att.width = widthStr;\r\n att.height = heightStr;\r\n var par = {};\r\n if (parObj && typeof parObj === OBJECT) {\r\n for (var j in parObj) { // copy object to avoid the use of references, because web authors often reuse parObj for multiple SWFs\r\n par[j] = parObj[j];\r\n }\r\n }\r\n if (flashvarsObj && typeof flashvarsObj === OBJECT) {\r\n for (var k in flashvarsObj) { // copy object to avoid the use of references, because web authors often reuse flashvarsObj for multiple SWFs\r\n if (flashvarsObj.hasOwnProperty(k)) {\r\n\r\n var key = (encodeURIEnabled) ? encodeURIComponent(k) : k,\r\n value = (encodeURIEnabled) ? encodeURIComponent(flashvarsObj[k]) : flashvarsObj[k];\r\n\r\n if (typeof par.flashvars !== UNDEF) {\r\n par.flashvars += \"&\" + key + \"=\" + value;\r\n }\r\n else {\r\n par.flashvars = key + \"=\" + value;\r\n }\r\n\r\n }\r\n }\r\n }\r\n if (hasPlayerVersion(swfVersionStr)) { // create SWF\r\n var obj = createSWF(att, par, replaceElemIdStr);\r\n if (att.id == id) {\r\n setVisibility(id, true);\r\n }\r\n callbackObj.success = true;\r\n callbackObj.ref = obj;\r\n callbackObj.id = obj.id;\r\n }\r\n else if (xiSwfUrlStr && canExpressInstall()) { // show Adobe Express Install\r\n att.data = xiSwfUrlStr;\r\n showExpressInstall(att, par, replaceElemIdStr, callbackFn);\r\n return;\r\n }\r\n else { // show fallback content\r\n setVisibility(id, true);\r\n }\r\n if (callbackFn) { callbackFn(callbackObj); }\r\n });\r\n }\r\n else if (callbackFn) { callbackFn(callbackObj); }\r\n },\r\n\r\n switchOffAutoHideShow: function () {\r\n autoHideShow = false;\r\n },\r\n\r\n enableUriEncoding: function (bool) {\r\n encodeURIEnabled = (typeof bool === UNDEF) ? true : bool;\r\n },\r\n\r\n ua: ua,\r\n\r\n getFlashPlayerVersion: function () {\r\n return {major: ua.pv[0], minor: ua.pv[1], release: ua.pv[2]};\r\n },\r\n\r\n hasFlashPlayerVersion: hasPlayerVersion,\r\n\r\n createSWF: function (attObj, parObj, replaceElemIdStr) {\r\n if (ua.w3) {\r\n return createSWF(attObj, parObj, replaceElemIdStr);\r\n }\r\n else {\r\n return undefined;\r\n }\r\n },\r\n\r\n showExpressInstall: function (att, par, replaceElemIdStr, callbackFn) {\r\n if (ua.w3 && canExpressInstall()) {\r\n showExpressInstall(att, par, replaceElemIdStr, callbackFn);\r\n }\r\n },\r\n\r\n removeSWF: function (objElemIdStr) {\r\n if (ua.w3) {\r\n removeSWF(objElemIdStr);\r\n }\r\n },\r\n\r\n createCSS: function (selStr, declStr, mediaStr, newStyleBoolean) {\r\n if (ua.w3) {\r\n createCSS(selStr, declStr, mediaStr, newStyleBoolean);\r\n }\r\n },\r\n\r\n addDomLoadEvent: addDomLoadEvent,\r\n\r\n addLoadEvent: addLoadEvent,\r\n\r\n getQueryParamValue: function (param) {\r\n var q = doc.location.search || doc.location.hash;\r\n if (q) {\r\n if (/\\?/.test(q)) { q = q.split(\"?\")[1]; } // strip question mark\r\n if (!param) {\r\n return urlEncodeIfNecessary(q);\r\n }\r\n var pairs = q.split(\"&\");\r\n for (var i = 0; i < pairs.length; i++) {\r\n if (pairs[i].substring(0, pairs[i].indexOf(\"=\")) == param) {\r\n return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf(\"=\") + 1)));\r\n }\r\n }\r\n }\r\n return \"\";\r\n },\r\n\r\n // For internal usage only\r\n expressInstallCallback: function () {\r\n if (isExpressInstallActive) {\r\n var obj = getElementById(EXPRESS_INSTALL_ID);\r\n if (obj && storedFbContent) {\r\n obj.parentNode.replaceChild(storedFbContent, obj);\r\n if (storedFbContentId) {\r\n setVisibility(storedFbContentId, true);\r\n if (ua.ie) { storedFbContent.style.display = \"block\"; }\r\n }\r\n if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }\r\n }\r\n isExpressInstallActive = false;\r\n }\r\n },\r\n\r\n version: \"2.3\"\r\n\r\n };\r\n}));\r\n\n},{}],15:[function(require,module,exports){\n'use strict';\n\nvar InLine = require('./InLine');\nvar Wrapper = require('./Wrapper');\n\nfunction Ad(adJTree) {\n if (!(this instanceof Ad)) {\n return new Ad(adJTree);\n }\n this.initialize(adJTree);\n}\n\nAd.prototype.initialize = function(adJTree) {\n this.id = adJTree.attr('id');\n this.sequence = adJTree.attr('sequence');\n\n if(adJTree.inLine) {\n this.inLine = new InLine(adJTree.inLine);\n }\n\n if(adJTree.wrapper){\n this.wrapper = new Wrapper(adJTree.wrapper);\n }\n};\n\nmodule.exports = Ad;\n},{\"./InLine\":18,\"./Wrapper\":28}],16:[function(require,module,exports){\n'use strict';\n\nvar TrackingEvent = require('./TrackingEvent');\n\nvar utilities = require('../../utils/utilityFunctions');\n\nvar xml = require('../../utils/xml');\n\n\nfunction Companion(companionJTree) {\n if (!(this instanceof Companion)) {\n return new Companion(companionJTree);\n }\n\n //Required Elements\n this.creativeType = xml.attr(companionJTree.staticResource, 'creativeType');\n this.staticResource = xml.keyValue(companionJTree.staticResource);\n\n // Weird bug when the JXON tree is built it doesn't handle casing properly in this situation...\n var htmlResource = null;\n if (xml.keyValue(companionJTree.HTMLResource)) {\n htmlResource = xml.keyValue(companionJTree.HTMLResource);\n } else if (xml.keyValue(companionJTree.hTMLResource)) {\n htmlResource = xml.keyValue(companionJTree.hTMLResource);\n }\n this.htmlResource = htmlResource;\n\n var iframeResource = null;\n if (xml.keyValue(companionJTree.IFrameResource)) {\n iframeResource = xml.keyValue(companionJTree.IFrameResource);\n } else if (xml.keyValue(companionJTree.iFrameresource)) {\n iframeResource = xml.keyValue(companionJTree.iFrameresource);\n }\n this.iframeResource = iframeResource;\n\n //Optional fields\n this.id = xml.attr(companionJTree, 'id');\n this.width = xml.attr(companionJTree, 'width');\n this.height = xml.attr(companionJTree, 'height');\n this.expandedWidth = xml.attr(companionJTree, 'expandedWidth');\n this.expandedHeight = xml.attr(companionJTree, 'expandedHeight');\n this.scalable = xml.attr(companionJTree, 'scalable');\n this.maintainAspectRatio = xml.attr(companionJTree, 'maintainAspectRatio');\n this.minSuggestedDuration = xml.attr(companionJTree, 'minSuggestedDuration');\n this.apiFramework = xml.attr(companionJTree, 'apiFramework');\n this.companionClickThrough = xml.keyValue(companionJTree.companionClickThrough);\n this.trackingEvents = parseTrackingEvents(companionJTree.trackingEvents && companionJTree.trackingEvents.tracking);\n\n /*** Local functions ***/\n function parseTrackingEvents(trackingEvents) {\n var trackings = [];\n if (utilities.isDefined(trackingEvents)) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingData) {\n trackings.push(new TrackingEvent(trackingData));\n });\n }\n return trackings;\n }\n}\n\nmodule.exports = Companion;\n},{\"../../utils/utilityFunctions\":45,\"../../utils/xml\":46,\"./TrackingEvent\":21}],17:[function(require,module,exports){\n'use strict';\n\nvar Linear = require('./Linear');\nvar Companion = require('./Companion');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction Creative(creativeJTree) {\n if(!(this instanceof Creative)) {\n return new Creative(creativeJTree);\n }\n\n this.id = creativeJTree.attr('id');\n this.sequence = creativeJTree.attr('sequence');\n this.adId = creativeJTree.attr('adId');\n this.apiFramework = creativeJTree.attr('apiFramework');\n\n if(creativeJTree.linear) {\n this.linear = new Linear(creativeJTree.linear);\n }\n\n if (creativeJTree.companionAds) {\n var companions = [];\n var companionAds = creativeJTree.companionAds && creativeJTree.companionAds.companion;\n if (utilities.isDefined(companionAds)) {\n companionAds = utilities.isArray(companionAds) ? companionAds : [companionAds];\n companionAds.forEach(function (companionData) {\n companions.push(new Companion(companionData));\n });\n }\n this.companionAds = companions;\n }\n}\n\n/**\n * Returns true if the browser supports at the creative.\n */\nCreative.prototype.isSupported = function(){\n if(this.linear) {\n return this.linear.isSupported();\n }\n\n return true;\n};\n\nCreative.parseCreatives = function parseCreatives(creativesJTree) {\n var creatives = [];\n var creativesData;\n if (utilities.isDefined(creativesJTree) && utilities.isDefined(creativesJTree.creative)) {\n creativesData = utilities.isArray(creativesJTree.creative) ? creativesJTree.creative : [creativesJTree.creative];\n creativesData.forEach(function (creative) {\n creatives.push(new Creative(creative));\n });\n }\n return creatives;\n};\n\nmodule.exports = Creative;\n\n},{\"../../utils/utilityFunctions\":45,\"./Companion\":16,\"./Linear\":19}],18:[function(require,module,exports){\n'use strict';\n\nvar vastUtil = require('./vastUtil');\nvar Creative = require('./Creative');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction InLine(inlineJTree) {\n if (!(this instanceof InLine)) {\n return new InLine(inlineJTree);\n }\n\n //Required Fields\n this.adTitle = xml.keyValue(inlineJTree.adTitle);\n this.adSystem = xml.keyValue(inlineJTree.adSystem);\n this.impressions = vastUtil.parseImpressions(inlineJTree.impression);\n this.creatives = Creative.parseCreatives(inlineJTree.creatives);\n\n //Optional Fields\n this.description = xml.keyValue(inlineJTree.description);\n this.advertiser = xml.keyValue(inlineJTree.advertiser);\n this.surveys = parseSurveys(inlineJTree.survey);\n this.error = xml.keyValue(inlineJTree.error);\n this.pricing = xml.keyValue(inlineJTree.pricing);\n this.extensions = inlineJTree.extensions;\n\n /*** Local Functions ***/\n function parseSurveys(inlineSurveys) {\n if (inlineSurveys) {\n return utilities.transformArray(utilities.isArray(inlineSurveys) ? inlineSurveys : [inlineSurveys], function (survey) {\n if(utilities.isNotEmptyString(survey.keyValue)){\n return {\n uri: survey.keyValue,\n type: survey.attr('type')\n };\n }\n\n return undefined;\n });\n }\n return [];\n }\n}\n\n\n/**\n * Returns true if the browser supports all the creatives.\n */\nInLine.prototype.isSupported = function(){\n var i,len;\n\n if(this.creatives.length === 0) {\n return false;\n }\n\n for(i = 0, len = this.creatives.length; i< len; i+=1){\n if(!this.creatives[i].isSupported()){\n return false;\n }\n }\n return true;\n};\n\nmodule.exports = InLine;\n\n},{\"../../utils/utilityFunctions\":45,\"../../utils/xml\":46,\"./Creative\":17,\"./vastUtil\":30}],19:[function(require,module,exports){\n'use strict';\n\nvar TrackingEvent = require('./TrackingEvent');\nvar MediaFile = require('./MediaFile');\nvar VideoClicks = require('./VideoClicks');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar parsers = require('./parsers');\n\nvar xml = require('../../utils/xml');\n\n\nfunction Linear(linearJTree) {\n if (!(this instanceof Linear)) {\n return new Linear(linearJTree);\n }\n\n //Required Elements\n this.duration = parsers.duration(xml.keyValue(linearJTree.duration));\n this.mediaFiles = parseMediaFiles(linearJTree.mediaFiles && linearJTree.mediaFiles.mediaFile);\n\n //Optional fields\n this.trackingEvents = parseTrackingEvents(linearJTree.trackingEvents && linearJTree.trackingEvents.tracking, this.duration);\n this.skipoffset = parsers.offset(xml.attr(linearJTree, 'skipoffset'), this.duration);\n\n if (linearJTree.videoClicks) {\n this.videoClicks = new VideoClicks(linearJTree.videoClicks);\n }\n\n if(linearJTree.adParameters) {\n this.adParameters = xml.keyValue(linearJTree.adParameters);\n\n if(xml.attr(linearJTree.adParameters, 'xmlEncoded')){\n this.adParameters = xml.decode(this.adParameters);\n }\n }\n\n /*** Local functions ***/\n function parseTrackingEvents(trackingEvents, duration) {\n var trackings = [];\n if (utilities.isDefined(trackingEvents)) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingData) {\n trackings.push(new TrackingEvent(trackingData, duration));\n });\n }\n return trackings;\n }\n\n function parseMediaFiles(mediaFilesJxonTree) {\n var mediaFiles = [];\n if (utilities.isDefined(mediaFilesJxonTree)) {\n mediaFilesJxonTree = utilities.isArray(mediaFilesJxonTree) ? mediaFilesJxonTree : [mediaFilesJxonTree];\n\n mediaFilesJxonTree.forEach(function (mfData) {\n mediaFiles.push(new MediaFile(mfData));\n });\n }\n return mediaFiles;\n }\n}\n\n/**\n * Must return true if at least one of the MediaFiles' type is supported\n */\nLinear.prototype.isSupported = function () {\n var i, len;\n for(i=0, len=this.mediaFiles.length; i 0) {\n getAd(waterfallAds.shift(),[], waterfallHandler);\n } else {\n callback(error, adChain);\n }\n } else {\n callback(null, adChain);\n }\n }\n });\n\n /*** Local functions ***/\n function getAdWaterfall(adTagUrl, callback) {\n var requestVastXML = that._requestVASTXml.bind(that, adTagUrl);\n async.waterfall([\n requestVastXML,\n buildVastWaterfall\n ], callback);\n }\n\n function buildVastWaterfall(xmlStr, callback) {\n var vastTree;\n try {\n vastTree = xml.toJXONTree(xmlStr);\n\n if(utilities.isArray(vastTree.ad)) {\n vastTree.ads = vastTree.ad;\n } else if(vastTree.ad){\n vastTree.ads = [vastTree.ad];\n } else {\n vastTree.ads = [];\n }\n callback(validateVASTTree(vastTree), vastTree);\n\n } catch (e) {\n callback(new VASTError(\"on VASTClient.getVASTAd.buildVastWaterfall, error parsing xml\", 100), null);\n }\n }\n\n function validateVASTTree(vastTree) {\n var vastVersion = xml.attr(vastTree, 'version');\n\n if (!vastTree.ad) {\n return new VASTError('on VASTClient.getVASTAd.validateVASTTree, no Ad in VAST tree', 303);\n }\n\n if (vastVersion && (vastVersion != 3 && vastVersion != 2)) {\n return new VASTError('on VASTClient.getVASTAd.validateVASTTree, not supported VAST version \"' + vastVersion + '\"', 102);\n }\n\n return null;\n }\n\n function getAd(adTagUrl, adChain, callback) {\n if (adChain.length >= that.WRAPPER_LIMIT) {\n return callback(new VASTError(\"on VASTClient.getVASTAd.getAd, players wrapper limit reached (the limit is \" + that.WRAPPER_LIMIT + \")\", 302), adChain);\n }\n\n async.waterfall([\n function (next) {\n if (utilities.isString(adTagUrl)) {\n requestVASTAd(adTagUrl, next);\n } else {\n next(null, adTagUrl);\n }\n },\n buildAd\n ], function (error, ad) {\n if (ad) {\n adChain.push(ad);\n }\n\n if (error) {\n return callback(error, adChain);\n }\n\n if (ad.wrapper) {\n return getAd(ad.wrapper.VASTAdTagURI, adChain, callback);\n }\n\n return callback(null, adChain);\n });\n }\n\n function buildAd(adJxonTree, callback) {\n try {\n var ad = new Ad(adJxonTree);\n callback(validateAd(ad), ad);\n } catch (e) {\n callback(new VASTError('on VASTClient.getVASTAd.buildAd, error parsing xml', 100), null);\n }\n }\n\n function validateAd(ad) {\n var wrapper = ad.wrapper;\n var inLine = ad.inLine;\n var errMsgPrefix = 'on VASTClient.getVASTAd.validateAd, ';\n\n if (inLine && wrapper) {\n return new VASTError(errMsgPrefix +\"InLine and Wrapper both found on the same Ad\", 101);\n }\n\n if (!inLine && !wrapper) {\n return new VASTError(errMsgPrefix + \"nor wrapper nor inline elements found on the Ad\", 101);\n }\n\n if (inLine && !inLine.isSupported()) {\n return new VASTError(errMsgPrefix + \"could not find MediaFile that is supported by this video player\", 403);\n }\n\n if (wrapper && !wrapper.VASTAdTagURI) {\n return new VASTError(errMsgPrefix + \"missing 'VASTAdTagURI' in wrapper\", 101);\n }\n\n return null;\n }\n\n function requestVASTAd(adTagUrl, callback) {\n that._requestVASTXml(adTagUrl, function (error, xmlStr) {\n if (error) {\n return callback(error);\n }\n try {\n var vastTree = xml.toJXONTree(xmlStr);\n callback(validateVASTTree(vastTree), vastTree.ad);\n } catch (e) {\n callback(new VASTError(\"on VASTClient.getVASTAd.requestVASTAd, error parsing xml\", 100));\n }\n });\n }\n};\n\nVASTClient.prototype._requestVASTXml = function requestVASTXml(adTagUrl, callback) {\n try {\n if (utilities.isFunction(adTagUrl)) {\n adTagUrl(requestHandler);\n } else {\n http.get(adTagUrl, requestHandler, {\n withCredentials: true\n });\n }\n } catch (e) {\n callback(e);\n }\n\n /*** Local functions ***/\n function requestHandler(error, response, status) {\n if (error) {\n var errMsg = utilities.isDefined(status) ?\n \"on VASTClient.requestVastXML, HTTP request error with status '\" + status + \"'\" :\n \"on VASTClient.requestVastXML, Error getting the the VAST XML with he passed adTagXML fn\";\n return callback(new VASTError(errMsg, 301), null);\n }\n\n callback(null, response);\n }\n};\n\nVASTClient.prototype._buildVASTResponse = function buildVASTResponse(adsChain) {\n var response = new VASTResponse();\n addAdsToResponse(response, adsChain);\n validateResponse(response);\n\n return response;\n\n //*** Local function ****\n function addAdsToResponse(response, ads) {\n ads.forEach(function (ad) {\n response.addAd(ad);\n });\n }\n\n function validateResponse(response) {\n var progressEvents = response.trackingEvents.progress;\n\n if (!response.hasLinear()) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, Received an Ad type that is not supported\", 200);\n }\n\n if (response.duration === undefined) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, Missing duration field in VAST response\", 101);\n }\n\n if (progressEvents) {\n progressEvents.forEach(function (progressEvent) {\n if (!utilities.isNumber(progressEvent.offset)) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, missing or wrong offset attribute on progress tracking event\", 101);\n }\n });\n }\n }\n};\n\nVASTClient.prototype._trackError = function (error, adChain) {\n if (!utilities.isArray(adChain) || adChain.length === 0) { //There is nothing to track\n return;\n }\n\n var errorURLMacros = [];\n adChain.forEach(addErrorUrlMacros);\n vastUtil.track(errorURLMacros, {ERRORCODE: error.code || 900}); //900 <== Undefined error\n\n /*** Local functions ***/\n function addErrorUrlMacros(ad) {\n if (ad.wrapper && ad.wrapper.error) {\n errorURLMacros.push(ad.wrapper.error);\n }\n\n if (ad.inLine && ad.inLine.error) {\n errorURLMacros.push(ad.inLine.error);\n }\n }\n};\n\nmodule.exports = VASTClient;\n\n},{\"../../utils/async\":40,\"../../utils/http\":42,\"../../utils/utilityFunctions\":45,\"../../utils/xml\":46,\"./Ad\":15,\"./VASTError\":23,\"./VASTResponse\":25,\"./vastUtil\":30}],23:[function(require,module,exports){\n'use strict';\n\nfunction VASTError(message, code) {\n this.message = 'VAST Error: ' + (message || '');\n if (code) {\n this.code = code;\n }\n}\n\nVASTError.prototype = new Error();\nVASTError.prototype.name = \"VAST Error\";\n\nmodule.exports = VASTError;\n},{}],24:[function(require,module,exports){\n'use strict';\n\n/**\n * Inner helper class that deals with the logic of the individual steps needed to setup an ad in the player.\n *\n * @param player {object} instance of the player that will play the ad. It assumes that the videojs-contrib-ads plugin\n * has been initialized when you use its utility functions.\n *\n * @constructor\n */\n\nvar VASTResponse = require('./VASTResponse');\nvar VASTError = require('./VASTError');\nvar VASTTracker = require('./VASTTracker');\nvar vastUtil = require('./vastUtil');\n\nvar async = require('../../utils/async');\nvar dom = require('../../utils/dom');\nvar playerUtils = require('../../utils/playerUtils');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VASTIntegrator(player) {\n if (!(this instanceof VASTIntegrator)) {\n return new VASTIntegrator(player);\n }\n\n this.player = player;\n}\n\nVASTIntegrator.prototype.playAd = function playAd(vastResponse, callback) {\n var that = this;\n callback = callback || utilities.noop;\n\n if (!(vastResponse instanceof VASTResponse)) {\n return callback(new VASTError('On VASTIntegrator, missing required VASTResponse'));\n }\n\n async.waterfall([\n function (next) {\n next(null, vastResponse);\n },\n this._selectAdSource.bind(this),\n this._createVASTTracker.bind(this),\n this._addClickThrough.bind(this),\n this._addSkipButton.bind(this),\n this._setupEvents.bind(this),\n this._playSelectedAd.bind(this)\n ], function (error, response) {\n if (error && response) {\n that._trackError(error, response);\n }\n callback(error, response);\n });\n\n this._adUnit = {\n _src: null,\n type: 'VAST',\n pauseAd: function () {\n that.player.pause(true);\n },\n\n resumeAd: function () {\n that.player.play(true);\n },\n\n isPaused: function () {\n return that.player.paused(true);\n },\n\n getSrc: function () {\n return this._src;\n }\n };\n\n return this._adUnit;\n};\n\nVASTIntegrator.prototype._selectAdSource = function selectAdSource(response, callback) {\n var source;\n\n var playerWidth = dom.getDimension(this.player.el()).width;\n response.mediaFiles.sort(function compareTo(a, b) {\n var deltaA = Math.abs(playerWidth - a.width);\n var deltaB = Math.abs(playerWidth - b.width);\n return deltaA - deltaB;\n });\n\n source = this.player.selectSource(response.mediaFiles).source;\n\n if (source) {\n if (this._adUnit) {\n this._adUnit._src = source;\n }\n return callback(null, source, response);\n }\n\n // code 403 <== Couldn't find MediaFile that is supported by this video player\n callback(new VASTError(\"Could not find Ad mediafile supported by this player\", 403), response);\n};\n\nVASTIntegrator.prototype._createVASTTracker = function createVASTTracker(adMediaFile, response, callback) {\n try {\n callback(null, adMediaFile, new VASTTracker(adMediaFile.src, response), response);\n } catch (e) {\n callback(e, response);\n }\n};\n\nVASTIntegrator.prototype._setupEvents = function setupEvents(adMediaFile, tracker, response, callback) {\n var previouslyMuted;\n var player = this.player;\n player.on('fullscreenchange', trackFullscreenChange);\n player.on('vast.adStart', trackImpressions);\n player.on('pause', trackPause);\n player.on('timeupdate', trackProgress);\n player.on('volumechange', trackVolumeChange);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], unbindEvents);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel', 'vast.adSkip'], function(evt){\n if(evt.type === 'vast.adEnd'){\n tracker.trackComplete();\n }\n });\n\n return callback(null, adMediaFile, response);\n\n /*** Local Functions ***/\n function unbindEvents() {\n player.off('fullscreenchange', trackFullscreenChange);\n player.off('vast.adStart', trackImpressions);\n player.off('pause', trackPause);\n player.off('timeupdate', trackProgress);\n player.off('volumechange', trackVolumeChange);\n }\n\n function trackFullscreenChange() {\n if (player.isFullscreen()) {\n tracker.trackFullscreen();\n } else {\n tracker.trackExitFullscreen();\n }\n }\n\n function trackPause() {\n //NOTE: whenever a video ends the video Element triggers a 'pause' event before the 'ended' event.\n // We should not track this pause event because it makes the VAST tracking confusing again we use a\n // Threshold of 2 seconds to prevent false positives on IOS.\n if (Math.abs(player.duration() - player.currentTime()) < 2) {\n return;\n }\n\n tracker.trackPause();\n playerUtils.once(player, ['play', 'vast.adEnd', 'vast.adsCancel'], function (evt) {\n if(evt.type === 'play'){\n tracker.trackResume();\n }\n });\n }\n\n function trackProgress() {\n var currentTimeInMs = player.currentTime() * 1000;\n tracker.trackProgress(currentTimeInMs);\n }\n\n function trackImpressions() {\n tracker.trackImpressions();\n tracker.trackCreativeView();\n }\n\n function trackVolumeChange() {\n var muted = player.muted();\n if (muted) {\n tracker.trackMute();\n } else if (previouslyMuted) {\n tracker.trackUnmute();\n }\n previouslyMuted = muted;\n }\n};\n\nVASTIntegrator.prototype._addSkipButton = function addSkipButton(source, tracker, response, callback) {\n var skipOffsetInSec;\n var that = this;\n\n if (utilities.isNumber(response.skipoffset)) {\n skipOffsetInSec = response.skipoffset / 1000;\n addSkipButtonToPlayer(this.player, skipOffsetInSec);\n }\n callback(null, source, tracker, response);\n\n /*** Local function ***/\n function addSkipButtonToPlayer(player, skipOffset) {\n var skipButton = createSkipButton(player);\n var updateSkipButton = updateSkipButtonState.bind(that, skipButton, skipOffset, player);\n\n player.el().appendChild(skipButton);\n player.on('timeupdate', updateSkipButton);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeSkipButton);\n\n function removeSkipButton() {\n player.off('timeupdate', updateSkipButton);\n dom.remove(skipButton);\n }\n }\n\n function createSkipButton(player) {\n var skipButton = window.document.createElement(\"div\");\n dom.addClass(skipButton, \"vast-skip-button\");\n\n skipButton.onclick = function (e) {\n if (dom.hasClass(skipButton, 'enabled')) {\n tracker.trackSkip();\n player.trigger('vast.adSkip');\n }\n\n //We prevent event propagation to avoid problems with the clickThrough and so on\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n } else {\n return false;\n }\n };\n\n return skipButton;\n }\n\n function updateSkipButtonState(skipButton, skipOffset, player) {\n var timeLeft = Math.ceil(skipOffset - player.currentTime());\n if (timeLeft > 0) {\n skipButton.innerHTML = \"Skip in \" + utilities.toFixedDigits(timeLeft, 2) + \"...\";\n } else {\n if (!dom.hasClass(skipButton, 'enabled')) {\n dom.addClass(skipButton, 'enabled');\n skipButton.innerHTML = \"Skip ad\";\n }\n }\n }\n};\n\nVASTIntegrator.prototype._addClickThrough = function addClickThrough(mediaFile, tracker, response, callback) {\n var player = this.player;\n var blocker = createClickThroughBlocker(player, tracker, response);\n var updateBlocker = updateBlockerURL.bind(this, blocker, response, player);\n\n player.el().insertBefore(blocker, player.controlBar.el());\n player.on('timeupdate', updateBlocker);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeBlocker);\n\n return callback(null, mediaFile, tracker, response);\n\n /*** Local Functions ***/\n\n function createClickThroughBlocker(player, tracker, response) {\n var blocker = window.document.createElement(\"a\");\n var clickThroughMacro = response.clickThrough;\n\n dom.addClass(blocker, 'vast-blocker');\n blocker.href = generateClickThroughURL(clickThroughMacro, player);\n\n if (utilities.isString(clickThroughMacro)) {\n blocker.target = \"_blank\";\n }\n\n blocker.onclick = function (e) {\n if (player.paused()) {\n player.play();\n\n //We prevent event propagation to avoid problems with the player's normal pause mechanism\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n }\n return false;\n }\n\n player.pause();\n tracker.trackClick();\n };\n\n return blocker;\n }\n\n function updateBlockerURL(blocker, response, player) {\n blocker.href = generateClickThroughURL(response.clickThrough, player);\n }\n\n function generateClickThroughURL(clickThroughMacro, player) {\n var variables = {\n ASSETURI: mediaFile.src,\n CONTENTPLAYHEAD: vastUtil.formatProgress(player.currentTime() * 1000)\n };\n\n return clickThroughMacro ? vastUtil.parseURLMacro(clickThroughMacro, variables) : '#';\n }\n\n function removeBlocker() {\n player.off('timeupdate', updateBlocker);\n dom.remove(blocker);\n }\n};\n\nVASTIntegrator.prototype._playSelectedAd = function playSelectedAd(source, response, callback) {\n var player = this.player;\n\n player.preload(\"auto\"); //without preload=auto the durationchange event is never fired\n player.src(source);\n\n playerUtils.once(player, ['durationchange', 'error', 'vast.adsCancel'], function (evt) {\n if (evt.type === 'durationchange') {\n playAd();\n } else if(evt.type === 'error') {\n callback(new VASTError(\"on VASTIntegrator, Player is unable to play the Ad\", 400), response);\n }\n //NOTE: If the ads get canceled we do nothing/\n });\n\n /**** local functions ******/\n function playAd() {\n\n playerUtils.once(player, ['playing', 'vast.adsCancel'], function (evt) {\n if(evt.type === 'vast.adsCancel'){\n return;\n }\n\n player.trigger('vast.adStart');\n\n player.on('ended', proceed);\n player.on('vast.adsCancel', proceed);\n player.on('vast.adSkip', proceed);\n\n function proceed(evt) {\n\n if(evt.type === 'ended' && (player.duration() - player.currentTime()) > 3 ) {\n // Ignore ended event if the Ad time was not 'near' the end\n // avoids issues where IOS controls could skip the Ad\n return;\n }\n\n player.off('ended', proceed);\n player.off('vast.adsCancel', proceed);\n player.off('vast.adSkip', proceed);\n\n //NOTE: if the ads get cancel we do nothing apart removing the listners\n if(evt.type === 'ended' || evt.type === 'vast.adSkip'){\n callback(null, response);\n }\n }\n });\n\n player.play();\n }\n};\n\nVASTIntegrator.prototype._trackError = function trackError(error, response) {\n vastUtil.track(response.errorURLMacros, {ERRORCODE: error.code || 900});\n};\n\nmodule.exports = VASTIntegrator;\n},{\"../../utils/async\":40,\"../../utils/dom\":41,\"../../utils/playerUtils\":43,\"../../utils/utilityFunctions\":45,\"./VASTError\":23,\"./VASTResponse\":25,\"./VASTTracker\":26,\"./vastUtil\":30}],25:[function(require,module,exports){\n'use strict';\n\nvar Ad = require('./Ad');\nvar VideoClicks = require('./VideoClicks');\nvar Linear = require('./Linear');\nvar InLine = require('./InLine');\nvar Wrapper = require('./Wrapper');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nwindow.InLine__A = InLine;\nfunction VASTResponse() {\n if (!(this instanceof VASTResponse)) {\n return new VASTResponse();\n }\n\n this._linearAdded = false;\n this.ads = [];\n this.errorURLMacros = [];\n this.impressions = [];\n this.clickTrackings = [];\n this.customClicks = [];\n this.trackingEvents = {};\n this.mediaFiles = [];\n this.clickThrough = undefined;\n this.adTitle = '';\n this.duration = undefined;\n this.skipoffset = undefined;\n}\n\nVASTResponse.prototype.addAd = function (ad) {\n var inLine, wrapper;\n if (ad instanceof Ad) {\n inLine = ad.inLine;\n wrapper = ad.wrapper;\n\n this.ads.push(ad);\n\n if (inLine) {\n this._addInLine(inLine);\n }\n\n if (wrapper) {\n this._addWrapper(wrapper);\n }\n }\n};\n\nVASTResponse.prototype._addErrorTrackUrl = function (error) {\n var errorURL = error instanceof xml.JXONTree ? xml.keyValue(error) : error;\n if (errorURL) {\n this.errorURLMacros.push(errorURL);\n }\n};\n\nVASTResponse.prototype._addImpressions = function (impressions) {\n utilities.isArray(impressions) && appendToArray(this.impressions, impressions);\n};\n\nVASTResponse.prototype._addClickThrough = function (clickThrough) {\n if (utilities.isNotEmptyString(clickThrough)) {\n this.clickThrough = clickThrough;\n }\n};\n\nVASTResponse.prototype._addClickTrackings = function (clickTrackings) {\n utilities.isArray(clickTrackings) && appendToArray(this.clickTrackings, clickTrackings);\n};\n\nVASTResponse.prototype._addCustomClicks = function (customClicks) {\n utilities.isArray(customClicks) && appendToArray(this.customClicks, customClicks);\n};\n\nVASTResponse.prototype._addTrackingEvents = function (trackingEvents) {\n var eventsMap = this.trackingEvents;\n\n if (trackingEvents) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingEvent) {\n if (!eventsMap[trackingEvent.name]) {\n eventsMap[trackingEvent.name] = [];\n }\n eventsMap[trackingEvent.name].push(trackingEvent);\n });\n }\n};\n\nVASTResponse.prototype._addTitle = function (title) {\n if (utilities.isNotEmptyString(title)) {\n this.adTitle = title;\n }\n};\n\nVASTResponse.prototype._addDuration = function (duration) {\n if (utilities.isNumber(duration)) {\n this.duration = duration;\n }\n};\n\nVASTResponse.prototype._addVideoClicks = function (videoClicks) {\n if (videoClicks instanceof VideoClicks) {\n this._addClickThrough(videoClicks.clickThrough);\n this._addClickTrackings(videoClicks.clickTrackings);\n this._addCustomClicks(videoClicks.customClicks);\n }\n};\n\nVASTResponse.prototype._addMediaFiles = function (mediaFiles) {\n utilities.isArray(mediaFiles) && appendToArray(this.mediaFiles, mediaFiles);\n};\n\nVASTResponse.prototype._addSkipoffset = function (offset) {\n if (offset) {\n this.skipoffset = offset;\n }\n};\n\nVASTResponse.prototype._addAdParameters = function (adParameters) {\n if (adParameters) {\n this.adParameters = adParameters;\n }\n};\n\nVASTResponse.prototype._addLinear = function (linear) {\n if (linear instanceof Linear) {\n this._addDuration(linear.duration);\n this._addTrackingEvents(linear.trackingEvents);\n this._addVideoClicks(linear.videoClicks);\n this._addMediaFiles(linear.mediaFiles);\n this._addSkipoffset(linear.skipoffset);\n this._addAdParameters(linear.adParameters);\n this._linearAdded = true;\n }\n};\n\nVASTResponse.prototype._addInLine = function (inLine) {\n var that = this;\n\n if (inLine instanceof InLine) {\n this._addTitle(inLine.adTitle);\n this._addErrorTrackUrl(inLine.error);\n this._addImpressions(inLine.impressions);\n\n inLine.creatives.forEach(function (creative) {\n if (creative.linear) {\n that._addLinear(creative.linear);\n }\n });\n }\n};\n\nVASTResponse.prototype._addWrapper = function (wrapper) {\n var that = this;\n\n if (wrapper instanceof Wrapper) {\n this._addErrorTrackUrl(wrapper.error);\n this._addImpressions(wrapper.impressions);\n\n wrapper.creatives.forEach(function (creative) {\n var linear = creative.linear;\n if (linear) {\n that._addVideoClicks(linear.videoClicks);\n that.clickThrough = undefined;//We ensure that no clickThrough has been added\n that._addTrackingEvents(linear.trackingEvents);\n }\n });\n }\n};\n\nVASTResponse.prototype.hasLinear = function(){\n return this._linearAdded;\n};\n\nfunction appendToArray(array, items) {\n items.forEach(function (item) {\n array.push(item);\n });\n}\n\nmodule.exports = VASTResponse;\n\n\n},{\"../../utils/utilityFunctions\":45,\"../../utils/xml\":46,\"./Ad\":15,\"./InLine\":18,\"./Linear\":19,\"./VideoClicks\":27,\"./Wrapper\":28}],26:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('./VASTError');\nvar VASTResponse = require('./VASTResponse');\nvar vastUtil = require('./vastUtil');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VASTTracker(assetURI, vastResponse) {\n if (!(this instanceof VASTTracker)) {\n return new VASTTracker(assetURI, vastResponse);\n }\n\n this.sanityCheck(assetURI, vastResponse);\n this.initialize(assetURI, vastResponse);\n\n}\n\nVASTTracker.prototype.initialize = function(assetURI, vastResponse) {\n this.response = vastResponse;\n this.assetURI = assetURI;\n this.progress = 0;\n this.quartiles = {\n firstQuartile: {tracked: false, time: Math.round(25 * vastResponse.duration) / 100},\n midpoint: {tracked: false, time: Math.round(50 * vastResponse.duration) / 100},\n thirdQuartile: {tracked: false, time: Math.round(75 * vastResponse.duration) / 100}\n };\n};\n\nVASTTracker.prototype.sanityCheck = function(assetURI, vastResponse) {\n if (!utilities.isString(assetURI) || utilities.isEmptyString(assetURI)) {\n throw new VASTError('on VASTTracker constructor, missing required the URI of the ad asset being played');\n }\n\n if (!(vastResponse instanceof VASTResponse)) {\n throw new VASTError('on VASTTracker constructor, missing required VAST response');\n }\n};\n\nVASTTracker.prototype.trackURLs = function trackURLs(urls, variables) {\n if (utilities.isArray(urls) && urls.length > 0) {\n variables = utilities.extend({\n ASSETURI: this.assetURI,\n CONTENTPLAYHEAD: vastUtil.formatProgress(this.progress)\n }, variables || {});\n\n vastUtil.track(urls, variables);\n }\n};\n\nVASTTracker.prototype.trackEvent = function trackEvent(eventName, trackOnce) {\n this.trackURLs(getEventUris(this.response.trackingEvents[eventName]));\n if (trackOnce) {\n this.response.trackingEvents[eventName] = undefined;\n }\n\n /*** Local function ***/\n function getEventUris(trackingEvents) {\n var uris;\n\n if (trackingEvents) {\n uris = [];\n trackingEvents.forEach(function (event) {\n uris.push(event.uri);\n });\n }\n return uris;\n }\n};\n\nVASTTracker.prototype.trackProgress = function trackProgress(newProgressInMs) {\n var that = this;\n var events = [];\n var ONCE = true;\n var ALWAYS = false;\n var trackingEvents = this.response.trackingEvents;\n\n if (utilities.isNumber(newProgressInMs)) {\n addTrackEvent('start', ONCE, newProgressInMs > 0);\n addTrackEvent('rewind', ALWAYS, hasRewound(this.progress, newProgressInMs));\n addQuartileEvents(newProgressInMs);\n trackProgressEvents(newProgressInMs);\n trackEvents();\n this.progress = newProgressInMs;\n }\n\n /*** Local function ***/\n function hasRewound(currentProgress, newProgress) {\n var REWIND_THRESHOLD = 3000; //IOS video clock is very unreliable and we need a 3 seconds threshold to ensure that there was a rewind an that it was on purpose.\n return currentProgress > newProgressInMs && Math.abs(newProgress - currentProgress) > REWIND_THRESHOLD;\n }\n\n function addTrackEvent(eventName, trackOnce, canBeAdded) {\n if (trackingEvents[eventName] && canBeAdded) {\n events.push({\n name: eventName,\n trackOnce: !!trackOnce\n });\n }\n }\n\n function addQuartileEvents(progress) {\n var quartiles = that.quartiles;\n var firstQuartile = that.quartiles.firstQuartile;\n var midpoint = that.quartiles.midpoint;\n var thirdQuartile = that.quartiles.thirdQuartile;\n\n if (!firstQuartile.tracked) {\n trackQuartile('firstQuartile', progress);\n } else if (!midpoint.tracked) {\n trackQuartile('midpoint', progress);\n } else if (!thirdQuartile.tracked){\n trackQuartile('thirdQuartile', progress);\n }\n\n /*** Local function ***/\n function trackQuartile(quartileName, progress){\n var quartile = quartiles[quartileName];\n if(canBeTracked(quartile, progress)){\n quartile.tracked = true;\n addTrackEvent(quartileName, ONCE, true);\n }\n }\n }\n\n function canBeTracked(quartile, progress) {\n var quartileTime = quartile.time;\n //We only fire the quartile event if the progress is bigger than the quartile time by 5 seconds at most.\n return progress >= quartileTime && progress <= (quartileTime + 5000);\n }\n\n function trackProgressEvents(progress) {\n if (!utilities.isArray(trackingEvents.progress)) {\n return; //Nothing to track\n }\n\n var pendingProgressEvts = [];\n\n trackingEvents.progress.forEach(function (evt) {\n if (evt.offset <= progress) {\n that.trackURLs([evt.uri]);\n } else {\n pendingProgressEvts.push(evt);\n }\n });\n trackingEvents.progress = pendingProgressEvts;\n }\n\n function trackEvents() {\n events.forEach(function (event) {\n that.trackEvent(event.name, event.trackOnce);\n });\n }\n};\n\n[\n 'rewind',\n 'fullscreen',\n 'exitFullscreen',\n 'pause',\n 'resume',\n 'mute',\n 'unmute',\n 'acceptInvitation',\n 'acceptInvitationLinear',\n 'collapse',\n 'expand'\n].forEach(function (eventName) {\n VASTTracker.prototype['track' + utilities.capitalize(eventName)] = function () {\n this.trackEvent(eventName);\n };\n });\n\n[\n 'start',\n 'skip',\n 'close',\n 'closeLinear'\n].forEach(function (eventName) {\n VASTTracker.prototype['track' + utilities.capitalize(eventName)] = function () {\n this.trackEvent(eventName, true);\n };\n });\n\n[\n 'firstQuartile',\n 'midpoint',\n 'thirdQuartile'\n].forEach(function (quartile) {\n VASTTracker.prototype['track' + utilities.capitalize(quartile)] = function () {\n this.quartiles[quartile].tracked = true;\n this.trackEvent(quartile, true);\n };\n });\n\nVASTTracker.prototype.trackComplete = function () {\n if(this.quartiles.thirdQuartile.tracked){\n this.trackEvent('complete', true);\n }\n};\n\nVASTTracker.prototype.trackErrorWithCode = function trackErrorWithCode(errorcode) {\n if (utilities.isNumber(errorcode)) {\n this.trackURLs(this.response.errorURLMacros, {ERRORCODE: errorcode});\n }\n};\n\nVASTTracker.prototype.trackImpressions = function trackImpressions() {\n this.trackURLs(this.response.impressions);\n};\n\nVASTTracker.prototype.trackCreativeView = function trackCreativeView() {\n this.trackEvent('creativeView');\n};\n\nVASTTracker.prototype.trackClick = function trackClick() {\n this.trackURLs(this.response.clickTrackings);\n};\n\nmodule.exports = VASTTracker;\n\n},{\"../../utils/utilityFunctions\":45,\"./VASTError\":23,\"./VASTResponse\":25,\"./vastUtil\":30}],27:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction VideoClicks(videoClickJTree) {\n if (!(this instanceof VideoClicks)) {\n return new VideoClicks(videoClickJTree);\n }\n\n this.clickThrough = xml.keyValue(videoClickJTree.clickThrough);\n this.clickTrackings = parseClickTrackings(videoClickJTree.clickTracking);\n this.customClicks = parseClickTrackings(videoClickJTree.customClick);\n\n /*** Local functions ***/\n function parseClickTrackings(trackingData) {\n var clickTrackings = [];\n if (trackingData) {\n trackingData = utilities.isArray(trackingData) ? trackingData : [trackingData];\n trackingData.forEach(function (clickTrackingData) {\n clickTrackings.push(xml.keyValue(clickTrackingData));\n });\n }\n return clickTrackings;\n }\n}\n\nmodule.exports = VideoClicks;\n},{\"../../utils/utilityFunctions\":45,\"../../utils/xml\":46}],28:[function(require,module,exports){\n'use strict';\n\nvar vastUtil = require('./vastUtil');\nvar Creative = require('./Creative');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction Wrapper(wrapperJTree) {\n if(!(this instanceof Wrapper)) {\n return new Wrapper(wrapperJTree);\n }\n\n //Required elements\n this.adSystem = xml.keyValue(wrapperJTree.adSystem);\n this.impressions = vastUtil.parseImpressions(wrapperJTree.impression);\n this.VASTAdTagURI = xml.keyValue(wrapperJTree.vASTAdTagURI);\n\n //Optional elements\n this.creatives = Creative.parseCreatives(wrapperJTree.creatives);\n this.error = xml.keyValue(wrapperJTree.error);\n this.extensions = wrapperJTree.extensions;\n\n //Optional attrs\n this.followAdditionalWrappers = utilities.isDefined(xml.attr(wrapperJTree, 'followAdditionalWrappers'))? xml.attr(wrapperJTree, 'followAdditionalWrappers'): true;\n this.allowMultipleAds = xml.attr(wrapperJTree, 'allowMultipleAds');\n this.fallbackOnNoAd = xml.attr(wrapperJTree, 'fallbackOnNoAd');\n}\n\nmodule.exports = Wrapper;\n\n},{\"../../utils/utilityFunctions\":45,\"../../utils/xml\":46,\"./Creative\":17,\"./vastUtil\":30}],29:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\n\nvar durationRegex = /(\\d\\d):(\\d\\d):(\\d\\d)(\\.(\\d\\d\\d))?/;\n\nvar parsers = {\n\n duration: function parseDuration(durationStr) {\n\n var match, durationInMs;\n\n if (utilities.isString(durationStr)) {\n match = durationStr.match(durationRegex);\n if (match) {\n durationInMs = parseHoursToMs(match[1]) + parseMinToMs(match[2]) + parseSecToMs(match[3]) + parseInt(match[5] || 0);\n }\n }\n\n return isNaN(durationInMs) ? null : durationInMs;\n\n /*** local functions ***/\n function parseHoursToMs(hourStr) {\n return parseInt(hourStr, 10) * 60 * 60 * 1000;\n }\n\n function parseMinToMs(minStr) {\n return parseInt(minStr, 10) * 60 * 1000;\n }\n\n function parseSecToMs(secStr) {\n return parseInt(secStr, 10) * 1000;\n }\n },\n\n offset: function parseOffset(offset, duration) {\n if(isPercentage(offset)){\n return calculatePercentage(offset, duration);\n }\n return parsers.duration(offset);\n\n /*** Local function ***/\n function isPercentage(offset) {\n var percentageRegex = /^\\d+(\\.\\d+)?%$/g;\n return percentageRegex.test(offset);\n }\n\n function calculatePercentage(percentStr, duration) {\n if(duration) {\n return calcPercent(duration, parseFloat(percentStr.replace('%', '')));\n }\n return null;\n }\n\n function calcPercent(quantity, percent){\n return quantity * percent / 100;\n }\n }\n\n};\n\n\nmodule.exports = parsers;\n},{\"../../utils/utilityFunctions\":45}],30:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\nvar VPAIDHTML5Tech = require('../vpaid/VPAIDHTML5Tech');\nvar VPAIDFlashTech = require('../vpaid/VPAIDFlashTech');\nvar VPAIDFLASHClient = require('VPAIDFLASHClient/js/VPAIDFLASHClient');\n\nvar vastUtil = {\n\n track: function track(URLMacros, variables) {\n var sources = vastUtil.parseURLMacros(URLMacros, variables);\n var trackImgs = [];\n sources.forEach(function (src) {\n var img = new Image();\n img.src = src;\n trackImgs.push(img);\n });\n return trackImgs;\n },\n\n parseURLMacros: function parseMacros(URLMacros, variables) {\n var parsedURLs = [];\n\n variables = variables || {};\n\n if (!(variables[\"CACHEBUSTING\"])) {\n variables[\"CACHEBUSTING\"] = Math.round(Math.random() * 1.0e+10);\n }\n\n URLMacros.forEach(function (URLMacro) {\n parsedURLs.push(vastUtil._parseURLMacro(URLMacro, variables));\n });\n\n return parsedURLs;\n },\n\n parseURLMacro: function parseMacro(URLMacro, variables) {\n variables = variables || {};\n\n if (!(variables[\"CACHEBUSTING\"])) {\n variables[\"CACHEBUSTING\"] = Math.round(Math.random() * 1.0e+10);\n }\n\n return vastUtil._parseURLMacro(URLMacro, variables);\n },\n\n _parseURLMacro: function parseMacro(URLMacro, variables) {\n variables = variables || {};\n\n utilities.forEach(variables, function (value, key) {\n URLMacro = URLMacro.replace(new RegExp(\"\\\\[\" + key + \"\\\\\\]\", 'gm'), value);\n });\n\n return URLMacro;\n },\n\n parseDuration: function parseDuration(durationStr) {\n var durationRegex = /(\\d\\d):(\\d\\d):(\\d\\d)(\\.(\\d\\d\\d))?/;\n var match, durationInMs;\n\n if (utilities.isString(durationStr)) {\n match = durationStr.match(durationRegex);\n if (match) {\n durationInMs = parseHoursToMs(match[1]) + parseMinToMs(match[2]) + parseSecToMs(match[3]) + parseInt(match[5] || 0);\n }\n }\n\n return isNaN(durationInMs) ? null : durationInMs;\n\n /*** local functions ***/\n function parseHoursToMs(hourStr) {\n return parseInt(hourStr, 10) * 60 * 60 * 1000;\n }\n\n function parseMinToMs(minStr) {\n return parseInt(minStr, 10) * 60 * 1000;\n }\n\n function parseSecToMs(secStr) {\n return parseInt(secStr, 10) * 1000;\n }\n },\n\n parseImpressions: function parseImpressions(impressions) {\n if (impressions) {\n impressions = utilities.isArray(impressions) ? impressions : [impressions];\n return utilities.transformArray(impressions, function (impression) {\n if (utilities.isNotEmptyString(impression.keyValue)) {\n return impression.keyValue;\n }\n return undefined;\n });\n }\n return [];\n },\n\n\n //We assume that the progress is going to arrive in milliseconds\n formatProgress: function formatProgress(progress) {\n var hours, minutes, seconds, milliseconds;\n hours = progress / (60 * 60 * 1000);\n hours = Math.floor(hours);\n minutes = (progress / (60 * 1000)) % 60;\n minutes = Math.floor(minutes);\n seconds = (progress / 1000) % 60;\n seconds = Math.floor(seconds);\n milliseconds = progress % 1000;\n return utilities.toFixedDigits(hours, 2) + ':' + utilities.toFixedDigits(minutes, 2) + ':' + utilities.toFixedDigits(seconds, 2) + '.' + utilities.toFixedDigits(milliseconds, 3);\n },\n\n parseOffset: function parseOffset(offset, duration) {\n if (isPercentage(offset)) {\n return calculatePercentage(offset, duration);\n }\n return vastUtil.parseDuration(offset);\n\n /*** Local function ***/\n function isPercentage(offset) {\n var percentageRegex = /^\\d+(\\.\\d+)?%$/g;\n return percentageRegex.test(offset);\n }\n\n function calculatePercentage(percentStr, duration) {\n if (duration) {\n return calcPercent(duration, parseFloat(percentStr.replace('%', '')));\n }\n return null;\n }\n\n function calcPercent(quantity, percent) {\n return quantity * percent / 100;\n }\n },\n\n\n //List of supported VPAID technologies\n VPAID_techs: [\n VPAIDFlashTech,\n VPAIDHTML5Tech\n ],\n\n isVPAID: function isVPAIDMediaFile(mediaFile) {\n return !!mediaFile && mediaFile.apiFramework === 'VPAID';\n },\n\n findSupportedVPAIDTech: function findSupportedVPAIDTech(mimeType) {\n var i, len, VPAIDTech;\n\n for (i = 0, len = this.VPAID_techs.length; i < len; i += 1) {\n VPAIDTech = this.VPAID_techs[i];\n if (VPAIDTech.supports(mimeType)) {\n return VPAIDTech;\n }\n }\n return null;\n },\n\n isFlashSupported: function isFlashSupported() {\n return VPAIDFLASHClient.isSupported();\n },\n\n /**\n * Necessary step for VPAIDFLAShClient to know if flash is supported and not blocked.\n * IMPORTANT NOTE: This is an async test and needs to be run as soon as possible.\n *\n * @param vpaidFlashLoaderPath the path to the vpaidFlashLoader swf obj.\n */\n runFlashSupportCheck: function runFlashSupportCheck(vpaidFlashLoaderPath) {\n VPAIDFLASHClient.runFlashTest({data: vpaidFlashLoaderPath});\n }\n\n};\n\nmodule.exports = vastUtil;\n\n},{\"../../utils/utilityFunctions\":45,\"../vpaid/VPAIDFlashTech\":32,\"../vpaid/VPAIDHTML5Tech\":33,\"VPAIDFLASHClient/js/VPAIDFLASHClient\":3}],31:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VPAIDAdUnitWrapper(vpaidAdUnit, opts) {\n if (!(this instanceof VPAIDAdUnitWrapper)) {\n return new VPAIDAdUnitWrapper(vpaidAdUnit, opts);\n }\n sanityCheck(vpaidAdUnit, opts);\n\n this.options = utilities.extend({}, opts);\n\n this._adUnit = vpaidAdUnit;\n\n /*** Local Functions ***/\n function sanityCheck(adUnit, opts) {\n if (!adUnit || !VPAIDAdUnitWrapper.checkVPAIDInterface(adUnit)) {\n throw new VASTError('on VPAIDAdUnitWrapper, the passed VPAID adUnit does not fully implement the VPAID interface');\n }\n\n if (!utilities.isObject(opts)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper, expected options hash but got '\" + opts + \"'\");\n }\n\n if (!(\"responseTimeout\" in opts) || !utilities.isNumber(opts.responseTimeout) ){\n throw new VASTError(\"on VPAIDAdUnitWrapper, expected responseTimeout in options\");\n }\n }\n}\n\nVPAIDAdUnitWrapper.checkVPAIDInterface = function checkVPAIDInterface(VPAIDAdUnit) {\n //NOTE: skipAd is not part of the method list because it only appears in VPAID 2.0 and we support VPAID 1.0\n var VPAIDInterfaceMethods = [\n 'handshakeVersion', 'initAd', 'startAd', 'stopAd', 'resizeAd', 'pauseAd', 'expandAd', 'collapseAd'\n ];\n\n for (var i = 0, len = VPAIDInterfaceMethods.length; i < len; i++) {\n if (!VPAIDAdUnit || !utilities.isFunction(VPAIDAdUnit[VPAIDInterfaceMethods[i]])) {\n return false;\n }\n }\n\n\n return canSubscribeToEvents(VPAIDAdUnit) && canUnsubscribeFromEvents(VPAIDAdUnit);\n\n /*** Local Functions ***/\n\n function canSubscribeToEvents(adUnit) {\n return utilities.isFunction(adUnit.subscribe) || utilities.isFunction(adUnit.addEventListener) || utilities.isFunction(adUnit.on);\n }\n\n function canUnsubscribeFromEvents(adUnit) {\n return utilities.isFunction(adUnit.unsubscribe) || utilities.isFunction(adUnit.removeEventListener) || utilities.isFunction(adUnit.off);\n\n }\n};\n\nVPAIDAdUnitWrapper.prototype.adUnitAsyncCall = function () {\n var args = utilities.arrayLikeObjToArray(arguments);\n var method = args.shift();\n var cb = args.pop();\n var timeoutId;\n\n sanityCheck(method, cb, this._adUnit);\n args.push(wrapCallback());\n\n this._adUnit[method].apply(this._adUnit, args);\n timeoutId = setTimeout(function () {\n timeoutId = null;\n cb(new VASTError(\"on VPAIDAdUnitWrapper, timeout while waiting for a response on call '\" + method + \"'\"));\n cb = utilities.noop;\n }, this.options.responseTimeout);\n\n /*** Local functions ***/\n function sanityCheck(method, cb, adUnit) {\n if (!utilities.isString(method) || !utilities.isFunction(adUnit[method])) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.adUnitAsyncCall, invalid method name\");\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.adUnitAsyncCall, missing callback\");\n }\n }\n\n function wrapCallback() {\n return function () {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n cb.apply(this, arguments);\n };\n }\n};\n\nVPAIDAdUnitWrapper.prototype.on = function (evtName, handler) {\n var addEventListener = this._adUnit.addEventListener || this._adUnit.subscribe || this._adUnit.on;\n addEventListener.call(this._adUnit, evtName, handler);\n};\n\nVPAIDAdUnitWrapper.prototype.off = function (evtName, handler) {\n var removeEventListener = this._adUnit.removeEventListener || this._adUnit.unsubscribe || this._adUnit.off;\n removeEventListener.call(this._adUnit, evtName, handler);\n};\n\nVPAIDAdUnitWrapper.prototype.waitForEvent = function (evtName, cb, context) {\n var timeoutId;\n sanityCheck(evtName, cb);\n context = context || null;\n\n this.on(evtName, responseListener);\n\n timeoutId = setTimeout(function () {\n cb(new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, timeout while waiting for event '\" + evtName + \"'\"));\n timeoutId = null;\n cb = utilities.noop;\n }, this.options.responseTimeout);\n\n /*** Local functions ***/\n function sanityCheck(evtName, cb) {\n if (!utilities.isString(evtName)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, missing evt name\");\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, missing callback\");\n }\n }\n\n function responseListener() {\n var args = utilities.arrayLikeObjToArray(arguments);\n\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n\n args.unshift(null);\n cb.apply(context, args);\n }\n};\n\n// VPAID METHODS\nVPAIDAdUnitWrapper.prototype.handshakeVersion = function (version, cb) {\n this.adUnitAsyncCall('handshakeVersion', version, cb);\n};\n\n/* jshint maxparams:6 */\nVPAIDAdUnitWrapper.prototype.initAd = function (width, height, viewMode, desiredBitrate, adUnitData, cb) {\n this.waitForEvent('AdLoaded', cb);\n this._adUnit.initAd(width, height, viewMode, desiredBitrate, adUnitData);\n};\n\nVPAIDAdUnitWrapper.prototype.resizeAd = function (width, height, viewMode, cb) {\n // NOTE: AdSizeChange event is only supported on VPAID 2.0 so for the moment we are not going to use it\n // and will assume that everything is fine after the async call\n this.adUnitAsyncCall('resizeAd', width, height, viewMode, cb);\n};\n\nVPAIDAdUnitWrapper.prototype.startAd = function (cb) {\n this.waitForEvent('AdStarted', cb);\n this._adUnit.startAd();\n};\n\nVPAIDAdUnitWrapper.prototype.stopAd = function (cb) {\n this.waitForEvent('AdStopped', cb);\n this._adUnit.stopAd();\n};\n\nVPAIDAdUnitWrapper.prototype.pauseAd = function (cb) {\n this.waitForEvent('AdPaused', cb);\n this._adUnit.pauseAd();\n};\n\nVPAIDAdUnitWrapper.prototype.resumeAd = function (cb) {\n this.waitForEvent('AdPlaying', cb);\n this._adUnit.resumeAd();\n};\n\nVPAIDAdUnitWrapper.prototype.expandAd = function (cb) {\n this.waitForEvent('AdExpandedChange', cb);\n this._adUnit.expandAd();\n};\n\nVPAIDAdUnitWrapper.prototype.collapseAd = function (cb) {\n this.waitForEvent('AdExpandedChange', cb);\n this._adUnit.collapseAd();\n};\n\nVPAIDAdUnitWrapper.prototype.skipAd = function (cb) {\n this.waitForEvent('AdSkipped', cb);\n this._adUnit.skipAd();\n};\n\n//VPAID property getters\n[\n 'adLinear',\n 'adWidth',\n 'adHeight',\n 'adExpanded',\n 'adSkippableState',\n 'adRemainingTime',\n 'adDuration',\n 'adVolume',\n 'adCompanions',\n 'adIcons'\n].forEach(function (property) {\n var getterName = 'get' + utilities.capitalize(property);\n\n VPAIDAdUnitWrapper.prototype[getterName] = function (cb) {\n this.adUnitAsyncCall(getterName, cb);\n };\n});\n\n//VPAID property setters\nVPAIDAdUnitWrapper.prototype.setAdVolume = function(volume, cb){\n this.adUnitAsyncCall('setAdVolume',volume, cb);\n};\n\nmodule.exports = VPAIDAdUnitWrapper;\n\n},{\"../../utils/utilityFunctions\":45,\"../vast/VASTError\":23}],32:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar VPAIDFLASHClient = require('VPAIDFLASHClient/js/VPAIDFLASHClient');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar dom = require('../../utils/dom');\n\nfunction VPAIDFlashTech(mediaFile, settings) {\n if (!(this instanceof VPAIDFlashTech)) {\n return new VPAIDFlashTech(mediaFile);\n }\n sanityCheck(mediaFile);\n this.name = 'vpaid-flash';\n this.mediaFile = mediaFile;\n this.containerEl = null;\n this.vpaidFlashClient = null;\n this.settings = settings;\n\n /*** local functions ***/\n function sanityCheck(mediaFile) {\n if (!mediaFile || !utilities.isString(mediaFile.src)) {\n throw new VASTError('on VPAIDFlashTech, invalid MediaFile');\n }\n }\n}\n\nVPAIDFlashTech.VPAIDFLASHClient = VPAIDFLASHClient;\n\nVPAIDFlashTech.supports = function (type) {\n return type === 'application/x-shockwave-flash' && VPAIDFlashTech.VPAIDFLASHClient.isSupported();\n};\n\nVPAIDFlashTech.prototype.loadAdUnit = function loadFlashCreative(containerEl, objectEl, callback) {\n var that = this;\n var flashClientOpts = this.settings && this.settings.vpaidFlashLoaderPath ? {data: this.settings.vpaidFlashLoaderPath} : undefined;\n sanityCheck(containerEl, callback);\n\n this.containerEl = containerEl;\n this.vpaidFlashClient = new VPAIDFlashTech.VPAIDFLASHClient(containerEl, function (error) {\n if (error) {\n return callback(error);\n }\n\n that.vpaidFlashClient.loadAdUnit(that.mediaFile.src, callback);\n }, flashClientOpts);\n\n /*** Local Functions ***/\n function sanityCheck(container, cb) {\n\n if (!dom.isDomElement(container)) {\n throw new VASTError('on VPAIDFlashTech.loadAdUnit, invalid dom container element');\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError('on VPAIDFlashTech.loadAdUnit, missing valid callback');\n }\n }\n};\n\nVPAIDFlashTech.prototype.unloadAdUnit = function () {\n if (this.vpaidFlashClient) {\n try{\n this.vpaidFlashClient.destroy();\n } catch(e){\n if(console && utilities.isFunction(console.log)){\n console.log('VAST ERROR: trying to unload the VPAID adunit');\n }\n }\n this.vpaidFlashClient = null;\n }\n\n if (this.containerEl) {\n dom.remove(this.containerEl);\n this.containerEl = null;\n }\n};\n\nmodule.exports = VPAIDFlashTech;\n\n},{\"../../utils/dom\":41,\"../../utils/utilityFunctions\":45,\"../vast/VASTError\":23,\"VPAIDFLASHClient/js/VPAIDFLASHClient\":3}],33:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar VPAIDHTML5Client = require('VPAIDHTML5Client/js/VPAIDHTML5Client');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar dom = require('../../utils/dom');\n\nfunction VPAIDHTML5Tech(mediaFile) {\n\n if(!(this instanceof VPAIDHTML5Tech)) {\n return new VPAIDHTML5Tech(mediaFile);\n }\n\n sanityCheck(mediaFile);\n\n this.name = 'vpaid-html5';\n this.containerEl = null;\n this.videoEl = null;\n this.vpaidHTMLClient = null;\n\n this.mediaFile = mediaFile;\n\n function sanityCheck(mediaFile) {\n if (!mediaFile || !utilities.isString(mediaFile.src)) {\n throw new VASTError(VPAIDHTML5Tech.INVALID_MEDIA_FILE);\n }\n }\n}\n\nVPAIDHTML5Tech.VPAIDHTML5Client = VPAIDHTML5Client;\n\nVPAIDHTML5Tech.supports = function (type) {\n return !utilities.isOldIE() && type === 'application/javascript';\n};\n\nVPAIDHTML5Tech.prototype.loadAdUnit = function loadAdUnit(containerEl, videoEl, callback) {\n sanityCheck(containerEl, videoEl, callback);\n\n this.containerEl = containerEl;\n this.videoEl = videoEl;\n this.vpaidHTMLClient = new VPAIDHTML5Tech.VPAIDHTML5Client(containerEl, videoEl, {});\n this.vpaidHTMLClient.loadAdUnit(this.mediaFile.src, callback);\n\n function sanityCheck(container, video, cb) {\n if (!dom.isDomElement(container)) {\n throw new VASTError(VPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL);\n }\n\n if (!dom.isDomElement(video) || video.tagName.toLowerCase() !== 'video') {\n throw new VASTError(VPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL);\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(VPAIDHTML5Tech.MISSING_CALLBACK);\n }\n }\n};\n\nVPAIDHTML5Tech.prototype.unloadAdUnit = function unloadAdUnit() {\n if (this.vpaidHTMLClient) {\n try {\n this.vpaidHTMLClient.destroy();\n } catch(e) {\n if (console && utilities.isFunction(console.log)) {\n console.log('VAST ERROR: trying to unload the VPAID adunit');\n }\n }\n\n this.vpaidHTMLClient = null;\n }\n\n if (this.containerEl) {\n dom.remove(this.containerEl);\n this.containerEl = null;\n }\n};\n\nvar PREFIX = 'on VPAIDHTML5Tech';\nVPAIDHTML5Tech.INVALID_MEDIA_FILE = PREFIX + ', invalid MediaFile';\nVPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL = PREFIX + ', invalid container HtmlElement';\nVPAIDHTML5Tech.INVALID_DOM_VIDEO_EL = PREFIX + ', invalid HTMLVideoElement';\nVPAIDHTML5Tech.MISSING_CALLBACK = PREFIX + ', missing valid callback';\n\nmodule.exports = VPAIDHTML5Tech;\n},{\"../../utils/dom\":41,\"../../utils/utilityFunctions\":45,\"../vast/VASTError\":23,\"VPAIDHTML5Client/js/VPAIDHTML5Client\":11}],34:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('../vast/VASTError');\nvar VASTResponse = require('../vast/VASTResponse');\nvar VASTTracker = require('../vast/VASTTracker');\nvar vastUtil = require('../vast/vastUtil');\n\nvar VPAIDAdUnitWrapper = require('./VPAIDAdUnitWrapper');\n\nvar async = require('../../utils/async');\nvar dom = require('../../utils/dom');\nvar playerUtils = require('../../utils/playerUtils');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VPAIDIntegrator(player, settings) {\n if (!(this instanceof VPAIDIntegrator)) {\n return new VPAIDIntegrator(player);\n }\n\n this.VIEW_MODE = {\n NORMAL: 'normal',\n FULLSCREEN: \"fullscreen\",\n THUMBNAIL: \"thumbnail\"\n };\n this.player = player;\n this.containerEl = createVPAIDContainerEl(player);\n this.options = {\n responseTimeout: 5000,\n VPAID_VERSION: '2.0'\n };\n this.settings = settings;\n\n /*** Local functions ***/\n\n function createVPAIDContainerEl() {\n var containerEl = document.createElement('div');\n dom.addClass(containerEl, 'VPAID-container');\n player.el().insertBefore(containerEl, player.controlBar.el());\n return containerEl;\n\n }\n}\n\nVPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) {\n if (!(vastResponse instanceof VASTResponse)) {\n return callback(new VASTError('on VASTIntegrator.playAd, missing required VASTResponse'));\n }\n\n var that = this;\n var player = this.player;\n var tech = this._findSupportedTech(vastResponse, this.settings);\n\n callback = callback || utilities.noop;\n\n this._adUnit = null;\n\n dom.addClass(player.el(), 'vjs-vpaid-ad');\n\n player.on('vast.adsCancel', triggerVpaidAdEnd);\n player.one('vpaid.adEnd', function(){\n player.off('vast.adsCancel', triggerVpaidAdEnd);\n removeAdUnit();\n });\n\n if (tech) {\n async.waterfall([\n function (next) {\n next(null, tech, vastResponse);\n },\n this._loadAdUnit.bind(this),\n this._playAdUnit.bind(this),\n this._finishPlaying.bind(this)\n\n ], adComplete);\n\n this._adUnit = {\n _paused: true,\n type: 'VPAID',\n pauseAd: function() {\n player.trigger('vpaid.pauseAd');\n player.pause(true);//we make sure that the video content gets stopped.\n },\n resumeAd: function() {\n player.trigger('vpaid.resumeAd');\n },\n isPaused: function() {\n return this._paused;\n },\n getSrc: function() {\n return tech.mediaFile;\n }\n };\n\n } else {\n var error = new VASTError('on VPAIDIntegrator.playAd, could not find a supported mediaFile', 403);\n adComplete(error, this._adUnit, vastResponse);\n }\n\n return this._adUnit;\n\n /*** Local functions ***/\n function adComplete(error, adUnit, vastResponse) {\n if (error && vastResponse) {\n that._trackError(vastResponse, error.code);\n }\n player.trigger('vpaid.adEnd');\n callback(error, vastResponse);\n }\n\n function triggerVpaidAdEnd(){\n player.trigger('vpaid.adEnd');\n }\n\n function removeAdUnit() {\n if (tech) {\n tech.unloadAdUnit();\n }\n dom.removeClass(player.el(), 'vjs-vpaid-ad');\n }\n};\n\nVPAIDIntegrator.prototype._findSupportedTech = function (vastResponse, settings) {\n if (!(vastResponse instanceof VASTResponse)) {\n return null;\n }\n\n var vpaidMediaFiles = vastResponse.mediaFiles.filter(vastUtil.isVPAID);\n var i, len, mediaFile, VPAIDTech;\n\n for (i = 0, len = vpaidMediaFiles.length; i < len; i += 1) {\n mediaFile = vpaidMediaFiles[i];\n VPAIDTech = vastUtil.findSupportedVPAIDTech(mediaFile.type);\n if (VPAIDTech) {\n return new VPAIDTech(mediaFile, settings);\n }\n }\n return null;\n};\n\nVPAIDIntegrator.prototype._createVPAIDAdUnitWrapper = function(adUnit, src, responseTimeout) {\n return new VPAIDAdUnitWrapper(adUnit, {src: src, responseTimeout: responseTimeout});\n};\n\nVPAIDIntegrator.prototype._loadAdUnit = function (tech, vastResponse, next) {\n var that = this;\n var player = this.player;\n var vjsTechEl = player.el().querySelector('.vjs-tech');\n var responseTimeout = this.settings.responseTimeout || this.options.responseTimeout;\n tech.loadAdUnit(this.containerEl, vjsTechEl, function (error, adUnit) {\n if (error) {\n return next(error, adUnit, vastResponse);\n }\n\n try {\n var WrappedAdUnit = that._createVPAIDAdUnitWrapper(adUnit, tech.mediaFile.src, responseTimeout);\n var techClass = 'vjs-' + tech.name + '-ad';\n dom.addClass(player.el(), techClass);\n player.one('vpaid.adEnd', function() {\n dom.removeClass(player.el(),techClass);\n });\n next(null, WrappedAdUnit, vastResponse);\n } catch (e) {\n next(e, adUnit, vastResponse);\n }\n });\n};\n\nVPAIDIntegrator.prototype._playAdUnit = function (adUnit, vastResponse, callback) {\n async.waterfall([\n function (next) {\n next(null, adUnit, vastResponse);\n },\n this._handshake.bind(this),\n this._initAd.bind(this),\n this._setupEvents.bind(this),\n this._addSkipButton.bind(this),\n this._linkPlayerControls.bind(this),\n this._startAd.bind(this)\n ], callback);\n};\n\nVPAIDIntegrator.prototype._handshake = function handshake(adUnit, vastResponse, next) {\n adUnit.handshakeVersion(this.options.VPAID_VERSION, function (error, version) {\n if (error) {\n return next(error, adUnit, vastResponse);\n }\n\n if (version && isSupportedVersion(version)) {\n return next(null, adUnit, vastResponse);\n }\n\n return next(new VASTError('on VPAIDIntegrator._handshake, unsupported version \"' + version + '\"'), adUnit, vastResponse);\n });\n\n function isSupportedVersion(version) {\n var majorNum = major(version);\n return majorNum >= 1 && majorNum <= 2;\n }\n\n function major(version) {\n var parts = version.split('.');\n return parseInt(parts[0], 10);\n }\n};\n\nVPAIDIntegrator.prototype._initAd = function (adUnit, vastResponse, next) {\n var tech = this.player.el().querySelector('.vjs-tech');\n var dimension = dom.getDimension(tech);\n adUnit.initAd(dimension.width, dimension.height, this.VIEW_MODE.NORMAL, -1, {AdParameters: vastResponse.adParameters || ''}, function (error) {\n next(error, adUnit, vastResponse);\n });\n};\n\nVPAIDIntegrator.prototype._createVASTTracker = function(adUnitSrc, vastResponse) {\n return new VASTTracker(adUnitSrc, vastResponse);\n};\n\nVPAIDIntegrator.prototype._setupEvents = function (adUnit, vastResponse, next) {\n var adUnitSrc = adUnit.options.src;\n var tracker = this._createVASTTracker(adUnitSrc, vastResponse);\n var player = this.player;\n var that = this;\n\n adUnit.on('AdSkipped', function () {\n player.trigger('vpaid.AdSkipped');\n tracker.trackSkip();\n });\n\n adUnit.on('AdImpression', function () {\n player.trigger('vpaid.AdImpression');\n tracker.trackImpressions();\n });\n\n adUnit.on('AdStarted', function () {\n player.trigger('vpaid.AdStarted');\n tracker.trackCreativeView();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdVideoStart', function () {\n player.trigger('vpaid.AdVideoStart');\n tracker.trackStart();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdPlaying', function () {\n player.trigger('vpaid.AdPlaying');\n tracker.trackResume();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdPaused', function () {\n player.trigger('vpaid.AdPaused');\n tracker.trackPause();\n notifyPauseToPlayer();\n });\n\n function notifyPlayToPlayer(){\n if(that._adUnit && that._adUnit.isPaused()){\n that._adUnit._paused = false;\n }\n player.trigger('play');\n\n }\n\n function notifyPauseToPlayer() {\n if(that._adUnit){\n that._adUnit._paused = true;\n }\n player.trigger('pause');\n }\n\n adUnit.on('AdVideoFirstQuartile', function () {\n player.trigger('vpaid.AdVideoFirstQuartile');\n tracker.trackFirstQuartile();\n });\n\n adUnit.on('AdVideoMidpoint', function () {\n player.trigger('vpaid.AdVideoMidpoint');\n tracker.trackMidpoint();\n });\n\n adUnit.on('AdVideoThirdQuartile', function () {\n player.trigger('vpaid.AdVideoThirdQuartile');\n tracker.trackThirdQuartile();\n });\n\n adUnit.on('AdVideoComplete', function () {\n player.trigger('vpaid.AdVideoComplete');\n tracker.trackComplete();\n });\n\n adUnit.on('AdClickThru', function (data) {\n player.trigger('vpaid.AdClickThru');\n var url = data.url;\n var playerHandles = data.playerHandles;\n var clickThruUrl = utilities.isNotEmptyString(url) ? url : generateClickThroughURL(vastResponse.clickThrough);\n\n tracker.trackClick();\n if (playerHandles && clickThruUrl) {\n window.open(clickThruUrl, '_blank');\n }\n\n function generateClickThroughURL(clickThroughMacro) {\n var variables = {\n ASSETURI: adUnit.options.src,\n CONTENTPLAYHEAD: 0 //In VPAID there is no method to know the current time from the adUnit\n };\n\n return clickThroughMacro ? vastUtil.parseURLMacro(clickThroughMacro, variables) : null;\n }\n });\n\n adUnit.on('AdUserAcceptInvitation', function () {\n player.trigger('vpaid.AdUserAcceptInvitation');\n tracker.trackAcceptInvitation();\n tracker.trackAcceptInvitationLinear();\n });\n\n adUnit.on('AdUserClose', function () {\n player.trigger('vpaid.AdUserClose');\n tracker.trackClose();\n tracker.trackCloseLinear();\n });\n\n adUnit.on('AdUserMinimize', function () {\n player.trigger('vpaid.AdUserMinimize');\n tracker.trackCollapse();\n });\n\n adUnit.on('AdError', function () {\n player.trigger('vpaid.AdError');\n //NOTE: we track errors code 901, as noted in VAST 3.0\n tracker.trackErrorWithCode(901);\n });\n\n adUnit.on('AdVolumeChange', function () {\n player.trigger('vpaid.AdVolumeChange');\n var lastVolume = player.volume();\n adUnit.getAdVolume(function (error, currentVolume) {\n if (currentVolume === 0 && lastVolume > 0) {\n tracker.trackMute();\n }\n\n if (currentVolume > 0 && lastVolume === 0) {\n tracker.trackUnmute();\n }\n\n player.volume(currentVolume);\n });\n });\n\n var updateViewSize = resizeAd.bind(this, player, adUnit, this.VIEW_MODE);\n var updateViewSizeThrottled = utilities.throttle(updateViewSize, 100);\n var autoResize = this.settings.autoResize;\n\n if (autoResize) {\n dom.addEventListener(window, 'resize', updateViewSizeThrottled);\n dom.addEventListener(window, 'orientationchange', updateViewSizeThrottled);\n }\n\n player.on('vast.resize', updateViewSize);\n player.on('vpaid.pauseAd', pauseAdUnit);\n player.on('vpaid.resumeAd', resumeAdUnit);\n\n player.one('vpaid.adEnd', function () {\n player.off('vast.resize', updateViewSize);\n player.off('vpaid.pauseAd', pauseAdUnit);\n player.off('vpaid.resumeAd', resumeAdUnit);\n\n if (autoResize) {\n dom.removeEventListener(window, 'resize', updateViewSizeThrottled);\n dom.removeEventListener(window, 'orientationchange', updateViewSizeThrottled);\n }\n });\n\n next(null, adUnit, vastResponse);\n\n /*** Local Functions ***/\n function pauseAdUnit() {\n adUnit.pauseAd(utilities.noop);\n }\n\n function resumeAdUnit() {\n adUnit.resumeAd(utilities.noop);\n }\n};\n\nVPAIDIntegrator.prototype._addSkipButton = function (adUnit, vastResponse, next) {\n var skipButton;\n var player = this.player;\n\n adUnit.on('AdSkippableStateChange', updateSkipButtonState);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeSkipButton);\n\n next(null, adUnit, vastResponse);\n\n /*** Local function ***/\n function updateSkipButtonState() {\n player.trigger('vpaid.AdSkippableStateChange');\n adUnit.getAdSkippableState(function (error, isSkippable) {\n if (isSkippable) {\n if (!skipButton) {\n addSkipButton(player);\n }\n } else {\n removeSkipButton(player);\n }\n });\n }\n\n function addSkipButton(player) {\n skipButton = createSkipButton(player);\n player.el().appendChild(skipButton);\n }\n\n function removeSkipButton() {\n dom.remove(skipButton);\n skipButton = null;\n }\n\n function createSkipButton() {\n var skipButton = window.document.createElement(\"div\");\n dom.addClass(skipButton, \"vast-skip-button\");\n dom.addClass(skipButton, \"enabled\");\n skipButton.innerHTML = \"Skip ad\";\n\n skipButton.onclick = function (e) {\n adUnit.skipAd(utilities.noop);//We skip the adUnit\n\n //We prevent event propagation to avoid problems with the clickThrough and so on\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n } else {\n return false;\n }\n };\n\n return skipButton;\n }\n};\n\nVPAIDIntegrator.prototype._linkPlayerControls = function (adUnit, vastResponse, next) {\n var that = this;\n linkVolumeControl(this.player, adUnit);\n linkFullScreenControl(this.player, adUnit, this.VIEW_MODE);\n\n next(null, adUnit, vastResponse);\n\n /*** Local functions ***/\n function linkVolumeControl(player, adUnit) {\n player.on('volumechange', updateAdUnitVolume);\n adUnit.on('AdVolumeChange', updatePlayerVolume);\n\n player.one('vpaid.adEnd', function () {\n player.off('volumechange', updateAdUnitVolume);\n });\n\n\n /*** local functions ***/\n function updateAdUnitVolume() {\n var vol = player.muted() ? 0 : player.volume();\n adUnit.setAdVolume(vol, logError);\n }\n\n function updatePlayerVolume() {\n player.trigger('vpaid.AdVolumeChange');\n adUnit.getAdVolume(function (error, vol) {\n if (error) {\n logError(error);\n } else {\n player.volume(vol);\n }\n });\n }\n }\n\n function linkFullScreenControl(player, adUnit, VIEW_MODE) {\n var updateViewSize = resizeAd.bind(that, player, adUnit, VIEW_MODE);\n\n player.on('fullscreenchange', updateViewSize);\n\n player.one('vpaid.adEnd', function () {\n player.off('fullscreenchange', updateViewSize);\n });\n }\n};\n\nVPAIDIntegrator.prototype._startAd = function (adUnit, vastResponse, next) {\n var player = this.player;\n\n adUnit.startAd(function (error) {\n if (!error) {\n player.trigger('vast.adStart');\n }\n next(error, adUnit, vastResponse);\n });\n};\n\nVPAIDIntegrator.prototype._finishPlaying = function (adUnit, vastResponse, next) {\n var player = this.player;\n adUnit.on('AdStopped', function () {\n player.trigger('vpaid.AdStopped');\n finishPlayingAd(null);\n });\n\n adUnit.on('AdError', function (error) {\n var errMsg = error? error.message : 'on VPAIDIntegrator, error while waiting for the adUnit to finish playing';\n finishPlayingAd(new VASTError(errMsg));\n });\n\n /*** local functions ***/\n function finishPlayingAd(error) {\n next(error, adUnit, vastResponse);\n }\n};\n\nVPAIDIntegrator.prototype._trackError = function trackError(response, errorCode) {\n vastUtil.track(response.errorURLMacros, {ERRORCODE: errorCode || 901});\n};\n\nfunction resizeAd(player, adUnit, VIEW_MODE) {\n var tech = player.el().querySelector('.vjs-tech');\n var dimension = dom.getDimension(tech);\n var MODE = player.isFullscreen() ? VIEW_MODE.FULLSCREEN : VIEW_MODE.NORMAL;\n adUnit.resizeAd(dimension.width, dimension.height, MODE, logError);\n}\n\nfunction logError(error) {\n if (error && console && console.log) {\n console.log('ERROR: ' + error.message, error);\n }\n}\n\nmodule.exports = VPAIDIntegrator;\n},{\"../../utils/async\":40,\"../../utils/dom\":41,\"../../utils/playerUtils\":43,\"../../utils/utilityFunctions\":45,\"../vast/VASTError\":23,\"../vast/VASTResponse\":25,\"../vast/VASTTracker\":26,\"../vast/vastUtil\":30,\"./VPAIDAdUnitWrapper\":31}],35:[function(require,module,exports){\n'use strict';\n\nvar dom = require('../../utils/dom');\n\nvar element = document.createElement('div');\nelement.className = 'vjs-ads-label vjs-control vjs-label-hidden';\nelement.innerHTML = 'Advertisement';\n\nvar AdsLabelFactory = function(baseComponent) {\n return {\n /** @constructor */\n init: function init(player, options) {\n options.el = element;\n baseComponent.call(this, player, options);\n\n // We asynchronously reposition the ads label element\n setTimeout(function () {\n var currentTimeComp = player.controlBar &&( player.controlBar.getChild(\"timerControls\") || player.controlBar.getChild(\"currentTimeDisplay\") );\n if(currentTimeComp) {\n player.controlBar.el().insertBefore(element, currentTimeComp.el());\n }\n dom.removeClass(element, 'vjs-label-hidden');\n }, 0);\n },\n\n el: function getElement() {\n return element;\n }\n };\n};\n\nmodule.exports = AdsLabelFactory;\n},{\"../../utils/dom\":41}],36:[function(require,module,exports){\n'use strict';\n\nvar baseVideoJsComponent = videojs.Component;\n\nvar AdsLabel = require('./ads-label')(baseVideoJsComponent);\n\nvideojs.AdsLabel = videojs.Component.extend(AdsLabel);\n\n},{\"./ads-label\":35}],37:[function(require,module,exports){\n'use strict';\n\n/**\n * The component that shows a black screen until the ads plugin has decided if it can or it can not play the ad.\n *\n * Note: In case you wonder why instead of this black poster we don't just show the spinner loader.\n * IOS devices do not work well with animations and the browser chrashes from time to time That is why we chose to\n * have a secondary black poster.\n *\n * It also makes it much more easier for the users of the plugin since it does not change the default behaviour of the\n * spinner and the player works the same way with and without the plugin.\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvar element = document.createElement('div');\n\nvar BlackPosterFactory = function(baseComponent) {\n return {\n /** @constructor */\n init: function init(player, options) {\n options.el = element;\n element.className = 'vjs-black-poster';\n baseComponent.call(this, player, options);\n\n var posterImg = player.getChild('posterImage');\n\n //We need to do it asynchronously to be sure that the black poster el is on the dom.\n setTimeout(function() {\n if(posterImg && player && player.el()) {\n player.el().insertBefore(element, posterImg.el());\n }\n }, 0);\n },\n el: function getElement() {\n return element;\n }\n };\n};\n\nmodule.exports = BlackPosterFactory;\n},{}],38:[function(require,module,exports){\n'use strict';\n\nvar baseVideoJsComponent = videojs.Component;\n\nvar BlackPoster = require('./black-poster')(baseVideoJsComponent);\n\nvideojs.BlackPoster = videojs.Component.extend(BlackPoster);\n\n},{\"./black-poster\":37}],39:[function(require,module,exports){\n'use strict';\n\nvar VASTClient = require('../ads/vast/VASTClient');\nvar VASTError = require('../ads/vast/VASTError');\nvar vastUtil = require('../ads/vast/vastUtil');\n\nvar VASTIntegrator = require('../ads/vast/VASTIntegrator');\nvar VPAIDIntegrator = require('../ads/vpaid/VPAIDIntegrator');\n\nvar async = require('../utils/async');\nvar dom = require('../utils/dom');\nvar playerUtils = require('../utils/playerUtils');\nvar utilities = require('../utils/utilityFunctions');\n\nmodule.exports = function VASTPlugin(options) {\n var snapshot;\n var player = this;\n var vast = new VASTClient();\n var adsCanceled = false;\n var defaultOpts = {\n // maximum amount of time in ms to wait to receive `adsready` from the ad\n // implementation after play has been requested. Ad implementations are\n // expected to load any dynamic libraries and make any requests to determine\n // ad policies for a video during this time.\n timeout: 500,\n\n //TODO:finish this IOS FIX\n //Whenever you play an add on IOS, the native player kicks in and we loose control of it. On very heavy pages the 'play' event\n // May occur after the video content has already started. This is wrong if you want to play a preroll ad that needs to happen before the user\n // starts watching the content. To prevent this usec\n iosPrerollCancelTimeout: 2000,\n\n // maximun amount of time for the ad to actually start playing. If this timeout gets\n // triggered the ads will be cancelled\n adCancelTimeout: 3000,\n\n // Boolean flag that configures the player to play a new ad before the user sees the video again\n // the current video\n playAdAlways: false,\n\n // Flag to enable or disable the ads by default.\n adsEnabled: true,\n\n // Boolean flag to enable or disable the resize with window.resize or orientationchange\n autoResize: true,\n\n // Path to the VPAID flash ad's loader\n vpaidFlashLoaderPath: '/VPAIDFlash.swf'\n };\n\n var settings = utilities.extend({}, defaultOpts, options || {});\n\n if(utilities.isUndefined(settings.adTagUrl) && utilities.isDefined(settings.url)){\n settings.adTagUrl = settings.url;\n }\n\n if (utilities.isString(settings.adTagUrl)) {\n settings.adTagUrl = utilities.echoFn(settings.adTagUrl);\n }\n\n if (utilities.isDefined(settings.adTagXML) && !utilities.isFunction(settings.adTagXML)) {\n return trackAdError(new VASTError('on VideoJS VAST plugin, the passed adTagXML option does not contain a function'));\n }\n\n if (!utilities.isDefined(settings.adTagUrl) && !utilities.isFunction(settings.adTagXML)) {\n return trackAdError(new VASTError('on VideoJS VAST plugin, missing adTagUrl on options object'));\n }\n\n vastUtil.runFlashSupportCheck(settings.vpaidFlashLoaderPath);// Necessary step for VPAIDFLASHClient to work.\n\n playerUtils.prepareForAds(player);\n\n if (settings.playAdAlways) {\n // No matter what happens we play a new ad before the user sees the video again.\n player.on('vast.contentEnd', function () {\n setTimeout(function () {\n player.trigger('vast.reset');\n }, 0);\n });\n }\n\n player.on('vast.firstPlay', tryToPlayPrerollAd);\n\n player.on('vast.reset', function () {\n //If we are reseting the plugin, we don't want to restore the content\n snapshot = null;\n cancelAds();\n });\n\n player.vast = {\n isEnabled: function () {\n return settings.adsEnabled;\n },\n\n enable: function () {\n settings.adsEnabled = true;\n },\n\n disable: function () {\n settings.adsEnabled = false;\n }\n };\n\n return player.vast;\n\n /**** Local functions ****/\n function tryToPlayPrerollAd() {\n //We remove the poster to prevent flickering whenever the content starts playing\n playerUtils.removeNativePoster(player);\n\n playerUtils.once(player, ['vast.adsCancel', 'vast.adEnd'], function () {\n removeAdUnit();\n restoreVideoContent();\n });\n\n async.waterfall([\n checkAdsEnabled,\n preparePlayerForAd,\n startAdCancelTimeout,\n playPrerollAd\n ], function (error, response) {\n if (error) {\n trackAdError(error, response);\n } else {\n player.trigger('vast.adEnd');\n }\n });\n\n /*** Local functions ***/\n\n function removeAdUnit() {\n if (player.vast && player.vast.adUnit) {\n player.vast.adUnit = null; //We remove the adUnit\n }\n }\n\n function restoreVideoContent() {\n setupContentEvents();\n if (snapshot) {\n playerUtils.restorePlayerSnapshot(player, snapshot);\n snapshot = null;\n }\n }\n\n function setupContentEvents() {\n playerUtils.once(player, ['playing', 'vast.reset', 'vast.firstPlay'], function (evt) {\n if (evt.type !== 'playing') {\n return;\n }\n\n player.trigger('vast.contentStart');\n\n playerUtils.once(player, ['ended', 'vast.reset', 'vast.firstPlay'], function (evt) {\n if (evt.type === 'ended') {\n player.trigger('vast.contentEnd');\n }\n });\n });\n }\n\n function checkAdsEnabled(next) {\n if (settings.adsEnabled) {\n return next(null);\n }\n next(new VASTError('Ads are not enabled'));\n }\n\n function preparePlayerForAd(next) {\n if (canPlayPrerollAd()) {\n snapshot = playerUtils.getPlayerSnapshot(player);\n player.pause();\n addSpinnerIcon();\n\n if(player.paused()) {\n next(null);\n } else {\n playerUtils.once(player, ['playing'], function() {\n player.pause();\n next(null);\n });\n }\n } else {\n next(new VASTError('video content has been playing before preroll ad'));\n }\n }\n\n function canPlayPrerollAd() {\n return !utilities.isIPhone() || player.currentTime() <= settings.iosPrerollCancelTimeout;\n }\n\n function startAdCancelTimeout(next) {\n var adCancelTimeoutId;\n adsCanceled = false;\n\n adCancelTimeoutId = setTimeout(function () {\n trackAdError(new VASTError('timeout while waiting for the video to start playing', 402));\n }, settings.adCancelTimeout);\n\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], clearAdCancelTimeout);\n\n /*** local functions ***/\n function clearAdCancelTimeout() {\n if (adCancelTimeoutId) {\n clearTimeout(adCancelTimeoutId);\n adCancelTimeoutId = null;\n }\n }\n\n next(null);\n }\n\n function addSpinnerIcon() {\n dom.addClass(player.el(), 'vjs-vast-ad-loading');\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], removeSpinnerIcon);\n }\n\n function removeSpinnerIcon() {\n //IMPORTANT NOTE: We remove the spinnerIcon asynchronously to give time to the browser to start the video.\n // If we remove it synchronously we see a flash of the content video before the ad starts playing.\n setTimeout(function () {\n dom.removeClass(player.el(), 'vjs-vast-ad-loading');\n }, 100);\n }\n\n }\n\n function cancelAds() {\n player.trigger('vast.adsCancel');\n adsCanceled = true;\n }\n\n function playPrerollAd(callback) {\n async.waterfall([\n getVastResponse,\n playAd\n ], callback);\n }\n\n function getVastResponse(callback) {\n vast.getVASTResponse(settings.adTagUrl ? settings.adTagUrl() : settings.adTagXML, callback);\n }\n\n function playAd(vastResponse, callback) {\n //TODO: Find a better way to stop the play. The 'playPrerollWaterfall' ends in an inconsistent situation\n //If the state is not 'preroll?' it means the ads were canceled therefore, we break the waterfall\n if (adsCanceled) {\n return;\n }\n\n var adIntegrator = isVPAID(vastResponse) ? new VPAIDIntegrator(player, settings) : new VASTIntegrator(player);\n var adFinished = false;\n\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], function (evt) {\n if (evt.type === 'vast.adStart') {\n addAdsLabel();\n }\n });\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeAdsLabel);\n\n if (utilities.isIDevice()) {\n preventManualProgress();\n }\n\n player.vast.vastResponse = vastResponse;\n player.vast.adUnit = adIntegrator.playAd(vastResponse, callback);\n\n /*** Local functions ****/\n function addAdsLabel() {\n if (adFinished || player.controlBar.getChild('AdsLabel')) {\n return;\n }\n\n player.controlBar.addChild('AdsLabel');\n }\n\n function removeAdsLabel() {\n player.controlBar.removeChild('AdsLabel');\n adFinished = true;\n }\n\n function preventManualProgress() {\n //IOS video clock is very unreliable and we need a 3 seconds threshold to ensure that the user forwarded/rewound the ad\n var PROGRESS_THRESHOLD = 3;\n var previousTime = 0;\n var skipad_attempts = 0;\n\n player.on('timeupdate', preventAdSeek);\n player.on('ended', preventAdSkip);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel', 'vast.adError'], stopPreventManualProgress);\n\n /*** Local functions ***/\n function preventAdSkip() {\n // Ignore ended event if the Ad time was not 'near' the end\n // and revert time to the previous 'valid' time\n if ((player.duration() - previousTime) > PROGRESS_THRESHOLD) {\n player.pause(true); // this reduce the video jitter if the IOS skip button is pressed\n player.play(true); // we need to trigger the play to put the video element back in a valid state\n player.currentTime(previousTime);\n }\n }\n\n function preventAdSeek() {\n var currentTime = player.currentTime();\n var progressDelta = Math.abs(currentTime - previousTime);\n if (progressDelta > PROGRESS_THRESHOLD) {\n skipad_attempts += 1;\n if (skipad_attempts >= 2) {\n player.pause(true);\n }\n player.currentTime(previousTime);\n } else {\n previousTime = currentTime;\n }\n }\n\n function stopPreventManualProgress() {\n player.off('timeupdate', preventAdSeek);\n player.off('ended', preventAdSkip);\n }\n }\n }\n\n function trackAdError(error, vastResponse) {\n player.trigger({type: 'vast.adError', error: error});\n cancelAds();\n if (console && console.log) {\n console.log('AD ERROR:', error.message, error, vastResponse);\n }\n }\n\n function isVPAID(vastResponse) {\n var i, len;\n var mediaFiles = vastResponse.mediaFiles;\n for (i = 0, len = mediaFiles.length; i < len; i++) {\n if (vastUtil.isVPAID(mediaFiles[i])) {\n return true;\n }\n }\n return false;\n }\n};\n\n},{\"../ads/vast/VASTClient\":22,\"../ads/vast/VASTError\":23,\"../ads/vast/VASTIntegrator\":24,\"../ads/vast/vastUtil\":30,\"../ads/vpaid/VPAIDIntegrator\":34,\"../utils/async\":40,\"../utils/dom\":41,\"../utils/playerUtils\":43,\"../utils/utilityFunctions\":45}],40:[function(require,module,exports){\n//Small subset of async\n\nvar utilities = require('./utilityFunctions');\n\nvar async = {};\n\nasync.setImmediate = function (fn) {\n setTimeout(fn, 0);\n};\n\nasync.iterator = function (tasks) {\n var makeCallback = function (index) {\n var fn = function () {\n if (tasks.length) {\n tasks[index].apply(null, arguments);\n }\n return fn.next();\n };\n fn.next = function () {\n return (index < tasks.length - 1) ? makeCallback(index + 1) : null;\n };\n return fn;\n };\n return makeCallback(0);\n};\n\n\nasync.waterfall = function (tasks, callback) {\n callback = callback || function () { };\n if (!utilities.isArray(tasks)) {\n var err = new Error('First argument to waterfall must be an array of functions');\n return callback(err);\n }\n if (!tasks.length) {\n return callback();\n }\n var wrapIterator = function (iterator) {\n return function (err) {\n if (err) {\n callback.apply(null, arguments);\n callback = function () {\n };\n }\n else {\n var args = Array.prototype.slice.call(arguments, 1);\n var next = iterator.next();\n if (next) {\n args.push(wrapIterator(next));\n }\n else {\n args.push(callback);\n }\n async.setImmediate(function () {\n iterator.apply(null, args);\n });\n }\n };\n };\n wrapIterator(async.iterator(tasks))();\n};\n\nasync.when = function (condition, callback) {\n if (!utilities.isFunction(callback)) {\n throw new Error(\"async.when error: missing callback argument\");\n }\n\n var isAllowed = utilities.isFunction(condition) ? condition : function () {\n return !!condition;\n };\n\n return function () {\n var args = utilities.arrayLikeObjToArray(arguments);\n var next = args.pop();\n\n if (isAllowed.apply(null, args)) {\n return callback.apply(this, arguments);\n }\n\n args.unshift(null);\n return next.apply(null, args);\n };\n};\n\nmodule.exports = async;\n\n\n},{\"./utilityFunctions\":45}],41:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('./utilityFunctions');\n\nvar dom = {};\n\ndom.isVisible = function isVisible(el) {\n var style = window.getComputedStyle(el);\n return style.visibility !== 'hidden';\n};\n\ndom.isHidden = function isHidden(el) {\n var style = window.getComputedStyle(el);\n return style.display === 'none';\n};\n\ndom.isShown = function isShown(el) {\n return !dom.isHidden(el);\n};\n\ndom.hide = function hide(el) {\n el.__prev_style_display_ = el.style.display;\n el.style.display = 'none';\n};\n\ndom.show = function show(el) {\n if (dom.isHidden(el)) {\n el.style.display = el.__prev_style_display_;\n }\n el.__prev_style_display_ = undefined;\n};\n\ndom.hasClass = function hasClass(el, cssClass) {\n var classes, i, len;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.contains(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n cssClass = (cssClass || '');\n\n for (i = 0, len = classes.length; i < len; i += 1) {\n if (classes[i] === cssClass) {\n return true;\n }\n }\n }\n return false;\n};\n\ndom.addClass = function (el, cssClass) {\n var classes;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.add(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n if (utilities.isString(cssClass) && utilities.isNotEmptyString(cssClass.replace(/\\s+/, ''))) {\n classes.push(cssClass);\n el.setAttribute('class', classes.join(' '));\n }\n }\n};\n\ndom.removeClass = function (el, cssClass) {\n var classes;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.remove(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n var newClasses = [];\n var i, len;\n if (utilities.isString(cssClass) && utilities.isNotEmptyString(cssClass.replace(/\\s+/, ''))) {\n\n for (i = 0, len = classes.length; i < len; i += 1) {\n if (cssClass !== classes[i]) {\n newClasses.push(classes[i]);\n }\n }\n el.setAttribute('class', newClasses.join(' '));\n }\n }\n};\n\ndom.addEventListener = function addEventListener(el, type, handler) {\n if(utilities.isArray(el)){\n utilities.forEach(el, function(e) {\n dom.addEventListener(e, type, handler);\n });\n return;\n }\n\n if(utilities.isArray(type)){\n utilities.forEach(type, function(t) {\n dom.addEventListener(el, t, handler);\n });\n return;\n }\n\n if (el.addEventListener) {\n el.addEventListener(type, handler, false);\n } else if (el.attachEvent) {\n // WARNING!!! this is a very naive implementation !\n // the event object that should be passed to the handler\n // would not be there for IE8\n // we should use \"window.event\" and then \"event.srcElement\"\n // instead of \"event.target\"\n el.attachEvent(\"on\" + type, handler);\n }\n};\n\ndom.removeEventListener = function removeEventListener(el, type, handler) {\n if(utilities.isArray(el)){\n utilities.forEach(el, function(e) {\n dom.removeEventListener(e, type, handler);\n });\n return;\n }\n\n if(utilities.isArray(type)){\n utilities.forEach(type, function(t) {\n dom.removeEventListener(el, t, handler);\n });\n return;\n }\n\n if (el.removeEventListener) {\n el.removeEventListener(type, handler, false);\n } else if (el.detachEvent) {\n el.detachEvent(\"on\" + type, handler);\n } else {\n el[\"on\" + type] = null;\n }\n};\n\ndom.dispatchEvent = function dispatchEvent(el, event) {\n if (el.dispatchEvent) {\n el.dispatchEvent(event);\n } else {\n el.fireEvent(\"on\" + event.eventType, event);\n }\n};\n\ndom.isDescendant = function isDescendant(parent, child) {\n var node = child.parentNode;\n while (node !== null) {\n if (node === parent) {\n return true;\n }\n node = node.parentNode;\n }\n return false;\n};\n\ndom.getTextContent = function getTextContent(el){\n return el.textContent || el.text;\n};\n\ndom.prependChild = function prependChild(parent, child) {\n if(child.parentNode){\n child.parentNode.removeChild(child);\n }\n return parent.insertBefore(child, parent.firstChild);\n};\n\ndom.remove = function removeNode(node){\n if(node && node.parentNode){\n node.parentNode.removeChild(node);\n }\n};\n\ndom.isDomElement = function isDomElement(o) {\n return o instanceof Element;\n};\n\ndom.click = function(el, handler) {\n dom.addEventListener(el, 'click', handler);\n};\n\ndom.once = function(el, type, handler) {\n function handlerWrap() {\n handler.apply(null, arguments);\n dom.removeEventListener(el, type, handlerWrap);\n }\n\n dom.addEventListener(el, type, handlerWrap);\n};\n\n//Note: there is no getBoundingClientRect on iPad so we need a fallback\ndom.getDimension = function getDimension(element) {\n var rect;\n\n //On IE9 and below getBoundingClientRect does not work consistently\n if(!utilities.isOldIE() && element.getBoundingClientRect) {\n rect = element.getBoundingClientRect();\n return {\n width: rect.width,\n height: rect.height\n };\n }\n\n return {\n width: element.offsetWidth,\n height: element.offsetHeight\n };\n};\n\nmodule.exports = dom;\n},{\"./utilityFunctions\":45}],42:[function(require,module,exports){\n'use strict';\n\nvar urlUtils = require('./urlUtils');\nvar utilities = require('./utilityFunctions');\n\nfunction HttpRequestError(message) {\n this.message = 'HttpRequest Error: ' + (message || '');\n}\nHttpRequestError.prototype = new Error();\nHttpRequestError.prototype.name = \"HttpRequest Error\";\n\nfunction HttpRequest(createXhr) {\n if (!utilities.isFunction(createXhr)) {\n throw new HttpRequestError('Missing XMLHttpRequest factory method');\n }\n\n this.createXhr = createXhr;\n}\n\nHttpRequest.prototype.run = function (method, url, callback, options) {\n sanityCheck(url, callback, options);\n var timeout, timeoutId;\n var xhr = this.createXhr();\n options = options || {};\n timeout = utilities.isNumber(options.timeout) ? options.timeout : 0;\n\n xhr.open(method, urlUtils.urlParts(url).href, true);\n\n if (options.headers) {\n setHeaders(xhr, options.headers);\n }\n\n if (options.withCredentials) {\n xhr.withCredentials = true;\n }\n\n xhr.onload = function () {\n var statusText, response, status;\n\n /**\n * The only way to do a secure request on IE8 and IE9 is with the XDomainRequest object. Unfortunately, microsoft is\n * so nice that decided that the status property and the 'getAllResponseHeaders' method where not needed so we have to\n * fake them. If the request gets done with an XDomainRequest instance, we will assume that there are no headers and\n * the status will always be 200. If you don't like it, DO NOT USE ANCIENT BROWSERS!!!\n *\n * For mor info go to: https://msdn.microsoft.com/en-us/library/cc288060(v=vs.85).aspx\n */\n if (!xhr.getAllResponseHeaders) {\n xhr.getAllResponseHeaders = function () {\n return null;\n };\n }\n\n if (!xhr.status) {\n xhr.status = 200;\n }\n\n if (utilities.isDefined(timeoutId)) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n\n statusText = xhr.statusText || '';\n\n // responseText is the old-school way of retrieving response (supported by IE8 & 9)\n // response/responseType properties were introduced in XHR Level2 spec (supported by IE10)\n response = ('response' in xhr) ? xhr.response : xhr.responseText;\n\n // normalize IE9 bug (http://bugs.jquery.com/ticket/1450)\n status = xhr.status === 1223 ? 204 : xhr.status;\n\n callback(\n status,\n response,\n xhr.getAllResponseHeaders(),\n statusText);\n };\n\n xhr.onerror = requestError;\n xhr.onabort = requestError;\n\n xhr.send();\n\n if (timeout > 0) {\n timeoutId = setTimeout(function () {\n xhr && xhr.abort();\n }, timeout);\n }\n\n function sanityCheck(url, callback, options) {\n if (!utilities.isString(url) || utilities.isEmptyString(url)) {\n throw new HttpRequestError(\"Invalid url '\" + url + \"'\");\n }\n\n if (!utilities.isFunction(callback)) {\n throw new HttpRequestError(\"Invalid handler '\" + callback + \"' for the http request\");\n }\n\n if (utilities.isDefined(options) && !utilities.isObject(options)) {\n throw new HttpRequestError(\"Invalid options map '\" + options + \"'\");\n }\n }\n\n function setHeaders(xhr, headers) {\n utilities.forEach(headers, function (value, key) {\n if (utilities.isDefined(value)) {\n xhr.setRequestHeader(key, value);\n }\n });\n }\n\n function requestError() {\n callback(-1, null, null, '');\n }\n};\n\nHttpRequest.prototype.get = function (url, callback, options) {\n this.run('GET', url, processResponse, options);\n\n function processResponse(status, response, headersString, statusText) {\n if (isSuccess(status)) {\n callback(null, response, status, headersString, statusText);\n } else {\n callback(new HttpRequestError(statusText), response, status, headersString, statusText);\n }\n }\n\n function isSuccess(status) {\n return 200 <= status && status < 300;\n }\n};\n\nfunction createXhr() {\n var xhr = new XMLHttpRequest();\n if (!(\"withCredentials\" in xhr)) {\n // XDomainRequest for IE.\n xhr = new XDomainRequest();\n }\n return xhr;\n}\n\nvar http = new HttpRequest(createXhr);\n\nmodule.exports = {\n http: http,\n HttpRequest: HttpRequest,\n HttpRequestError: HttpRequestError,\n createXhr: createXhr\n};\n\n},{\"./urlUtils\":44,\"./utilityFunctions\":45}],43:[function(require,module,exports){\n'use strict';\n\nvar dom = require('./dom');\nvar utilities = require('./utilityFunctions');\n\nvar playerUtils = {};\n\n/**\n * Returns an object that captures the portions of player state relevant to\n * video playback. The result of this function can be passed to\n * restorePlayerSnapshot with a player to return the player to the state it\n * was in when this function was invoked.\n * @param {object} player The videojs player object\n */\nplayerUtils.getPlayerSnapshot = function getPlayerSnapshot(player) {\n var tech = player.el().querySelector('.vjs-tech');\n\n var snapshot = {\n ended: player.ended(),\n src: player.currentSrc(),\n currentTime: player.currentTime(),\n type: player.currentType(),\n playing: !player.paused(),\n suppressedTracks: getSuppressedTracks(player)\n };\n\n if (tech) {\n snapshot.nativePoster = tech.poster;\n snapshot.style = tech.getAttribute('style');\n }\n return snapshot;\n\n /**** Local Functions ****/\n function getSuppressedTracks(player) {\n var tracks = player.remoteTextTracks ? player.remoteTextTracks() : [];\n\n if (tracks && utilities.isArray(tracks.tracks_)) {\n tracks = tracks.tracks_;\n }\n\n if (!utilities.isArray(tracks)) {\n tracks = [];\n }\n\n var suppressedTracks = [];\n tracks.forEach(function (track) {\n suppressedTracks.push({\n track: track,\n mode: track.mode\n });\n track.mode = 'disabled';\n });\n\n return suppressedTracks;\n }\n};\n\n/**\n * Attempts to modify the specified player so that its state is equivalent to\n * the state of the snapshot.\n * @param {object} snapshot - the player state to apply\n */\nplayerUtils.restorePlayerSnapshot = function restorePlayerSnapshot(player, snapshot) {\n var tech = player.el().querySelector('.vjs-tech');\n var attempts = 20; // the number of remaining attempts to restore the snapshot\n\n if (snapshot.nativePoster) {\n tech.poster = snapshot.nativePoster;\n }\n\n if ('style' in snapshot) {\n // overwrite all css style properties to restore state precisely\n tech.setAttribute('style', snapshot.style || '');\n }\n\n if (hasSrcChanged(player, snapshot)) {\n\n // on ios7, fiddling with textTracks too early will cause safari to crash\n player.one('contentloadedmetadata', restoreTracks);\n\n player.one('canplay', tryToResume);\n ensureCanplayEvtGetsFired();\n\n // if the src changed for ad playback, reset it\n player.src({src: snapshot.src, type: snapshot.type});\n\n // safari requires a call to `load` to pick up a changed source\n player.load();\n\n } else {\n restoreTracks();\n\n if (snapshot.playing) {\n player.play();\n }\n }\n\n /*** Local Functions ***/\n\n /**\n * Sometimes firefox does not trigger the 'canplay' evt.\n * This code ensure that it always gets triggered triggered.\n */\n function ensureCanplayEvtGetsFired() {\n var timeoutId = setTimeout(function() {\n player.trigger('canplay');\n }, 1000);\n\n player.one('canplay', function(){\n clearTimeout(timeoutId);\n });\n }\n\n /**\n * Determine whether the player needs to be restored to its state\n * before ad playback began. With a custom ad display or burned-in\n * ads, the content player state hasn't been modified and so no\n * restoration is required\n */\n function hasSrcChanged(player, snapshot) {\n if (player.src()) {\n return player.src() !== snapshot.src;\n }\n // the player was configured through source element children\n return player.currentSrc() !== snapshot.src;\n }\n\n function restoreTracks() {\n var suppressedTracks = snapshot.suppressedTracks;\n suppressedTracks.forEach(function (trackSnapshot) {\n trackSnapshot.track.mode = trackSnapshot.mode;\n });\n }\n\n /**\n * Determine if the video element has loaded enough of the snapshot source\n * to be ready to apply the rest of the state\n */\n function tryToResume() {\n\n // if some period of the video is seekable, resume playback\n // otherwise delay a bit and then check again unless we're out of attempts\n\n if (!playerUtils.isReadyToResume(player) && attempts--) {\n setTimeout(tryToResume, 50);\n } else {\n try {\n if(player.currentTime() !== snapshot.currentTime) {\n if (snapshot.playing) { // if needed restore playing status after seek completes\n player.one('seeked', function() {\n player.play();\n });\n }\n player.currentTime(snapshot.currentTime);\n\n } else if (snapshot.playing) {\n // if needed and no seek has been performed, restore playing status immediately\n player.play();\n }\n\n } catch (e) {\n videojs.log.warn('Failed to resume the content after an advertisement', e);\n }\n }\n }\n};\n\nplayerUtils.isReadyToResume = function (player) {\n\n if (player.readyState() > 1) {\n // some browsers and media aren't \"seekable\".\n // readyState greater than 1 allows for seeking without exceptions\n return true;\n }\n\n if (player.seekable() === undefined) {\n // if the player doesn't expose the seekable time ranges, try to\n // resume playback immediately\n return true;\n }\n\n if (player.seekable().length > 0) {\n // if some period of the video is seekable, resume playback\n return true;\n }\n\n return false;\n};\n\n/**\n * This function prepares the player to display ads.\n * Adding convenience events like the 'vast.firsPlay' that gets fired when the video is first played\n * and ads the blackPoster to the player to prevent content from being displayed before the preroll ad.\n *\n * @param player\n */\nplayerUtils.prepareForAds = function (player) {\n var blackPoster = player.addChild('blackPoster');\n var _firstPlay = true;\n var volumeSnapshot;\n\n\n monkeyPatchPlayerApi();\n\n player.on('play', tryToTriggerFirstPlay);\n player.on('vast.reset', resetFirstPlay);//Every time we change the sources we reset the first play.\n player.on('vast.firstPlay', restoreContentVolume);\n player.on('error', hideBlackPoster);//If there is an error in the player we remove the blackposter to show the err msg\n player.on('vast.adStart', hideBlackPoster);\n player.on('vast.adsCancel', hideBlackPoster);\n player.on('vast.adError', hideBlackPoster);\n player.on('vast.adStart', addStyles);\n player.on('vast.adEnd', removeStyles);\n player.on('vast.adsCancel', removeStyles);\n\n /*** Local Functions ***/\n\n /**\n What this function does is ugly and horrible and I should think twice before calling myself a good developer. With that said,\n it is the best solution I could find to mute the video until the 'play' event happens (on mobile devices) and the plugin can decide whether\n to play the ad or not.\n\n We also need this monkeypatch to be able to pause and resume an ad using the player's API\n\n If you have a better solution please do tell me.\n */\n function monkeyPatchPlayerApi() {\n\n /**\n * Monkey patch needed to handle firstPlay and resume of playing ad.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are restoring a VAST ad.\n * @returns {player}\n */\n var origPlay = player.play;\n player.play = function (callOrigPlay) {\n var that = this;\n\n if (isFirstPlay()) {\n firstPlay();\n } else {\n resume(callOrigPlay);\n }\n\n return this;\n\n /*** local functions ***/\n function firstPlay() {\n if (!utilities.isIPhone()) {\n volumeSnapshot = saveVolumeSnapshot();\n player.muted(true);\n }\n\n origPlay.apply(that, arguments);\n }\n\n function resume(callOrigPlay) {\n if (isAdPlaying() && !callOrigPlay) {\n player.vast.adUnit.resumeAd();\n } else {\n origPlay.apply(that, arguments);\n }\n }\n };\n\n\n /**\n * Needed monkey patch to handle pause of playing ad.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are pausing a VAST ad.\n * @returns {player}\n */\n var origPause = player.pause;\n player.pause = function (callOrigPause) {\n if (isAdPlaying() && !callOrigPause) {\n player.vast.adUnit.pauseAd();\n } else {\n origPause.apply(this, arguments);\n }\n return this;\n };\n\n\n /**\n * Needed monkey patch to handle paused state of the player when ads are playing.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are pausing a VAST ad.\n * @returns {player}\n */\n var origPaused = player.paused;\n player.paused = function (callOrigPaused) {\n if (isAdPlaying() && !callOrigPaused) {\n return player.vast.adUnit.isPaused();\n }\n return origPaused.apply(this, arguments);\n };\n }\n\n function isAdPlaying() {\n return player.vast && player.vast.adUnit;\n }\n\n function tryToTriggerFirstPlay() {\n if (isFirstPlay()) {\n _firstPlay = false;\n player.trigger('vast.firstPlay');\n }\n }\n\n function resetFirstPlay() {\n _firstPlay = true;\n blackPoster.show();\n restoreContentVolume();\n }\n\n function isFirstPlay() {\n return _firstPlay;\n }\n\n function saveVolumeSnapshot() {\n return {\n muted: player.muted(),\n volume: player.volume()\n };\n }\n\n function restoreContentVolume() {\n if (volumeSnapshot) {\n player.currentTime(0);\n restoreVolumeSnapshot(volumeSnapshot);\n volumeSnapshot = null;\n }\n }\n\n function restoreVolumeSnapshot(snapshot) {\n if (utilities.isObject(snapshot)) {\n player.volume(snapshot.volume);\n player.muted(snapshot.muted);\n }\n }\n\n function hideBlackPoster() {\n if (!dom.hasClass(blackPoster.el(), 'vjs-hidden')) {\n blackPoster.hide();\n }\n }\n\n function addStyles() {\n dom.addClass(player.el(), 'vjs-ad-playing');\n }\n\n function removeStyles() {\n dom.removeClass(player.el(), 'vjs-ad-playing');\n }\n};\n\n/**\n * Remove the poster attribute from the video element tech, if present. When\n * reusing a video element for multiple videos, the poster image will briefly\n * reappear while the new source loads. Removing the attribute ahead of time\n * prevents the poster from showing up between videos.\n * @param {object} player The videojs player object\n */\nplayerUtils.removeNativePoster = function (player) {\n var tech = player.el().querySelector('.vjs-tech');\n if (tech) {\n tech.removeAttribute('poster');\n }\n};\n\n/**\n * Helper function to listen to many events until one of them gets fired, then we\n * execute the handler and unsubscribe all the event listeners;\n *\n * @param player specific player from where to listen for the events\n * @param events array of events\n * @param handler function to execute once one of the events fires\n */\nplayerUtils.once = function once(player, events, handler) {\n function listener() {\n handler.apply(null, arguments);\n\n events.forEach(function (event) {\n player.off(event, listener);\n });\n }\n\n events.forEach(function (event) {\n player.on(event, listener);\n });\n};\n\n\nmodule.exports = playerUtils;\n},{\"./dom\":41,\"./utilityFunctions\":45}],44:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('./utilityFunctions');\n\n/**\n *\n * IMPORTANT NOTE: This function comes from angularJs and was originally called urlResolve\n * you can take a look at the original code here https://github.com/angular/angular.js/blob/master/src/ng/urlUtils.js\n *\n * Implementation Notes for non-IE browsers\n * ----------------------------------------\n * Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM,\n * results both in the normalizing and parsing of the URL. Normalizing means that a relative\n * URL will be resolved into an absolute URL in the context of the application document.\n * Parsing means that the anchor node's host, hostname, protocol, port, pathname and related\n * properties are all populated to reflect the normalized URL. This approach has wide\n * compatibility - Safari 1+, Mozilla 1+, Opera 7+,e etc. See\n * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n *\n * Implementation Notes for IE\n * ---------------------------\n * IE >= 8 and <= 10 normalizes the URL when assigned to the anchor node similar to the other\n * browsers. However, the parsed components will not be set if the URL assigned did not specify\n * them. (e.g. if you assign a.href = \"foo\", then a.protocol, a.host, etc. will be empty.) We\n * work around that by performing the parsing in a 2nd step by taking a previously normalized\n * URL (e.g. by assigning to a.href) and assigning it a.href again. This correctly populates the\n * properties such as protocol, hostname, port, etc.\n *\n * IE7 does not normalize the URL when assigned to an anchor node. (Apparently, it does, if one\n * uses the inner HTML approach to assign the URL as part of an HTML snippet -\n * http://stackoverflow.com/a/472729) However, setting img[src] does normalize the URL.\n * Unfortunately, setting img[src] to something like \"javascript:foo\" on IE throws an exception.\n * Since the primary usage for normalizing URLs is to sanitize such URLs, we can't use that\n * method and IE < 8 is unsupported.\n *\n * References:\n * http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement\n * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n * http://url.spec.whatwg.org/#urlutils\n * https://github.com/angular/angular.js/pull/2902\n * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/\n *\n * @kind function\n * @param {string} url The URL to be parsed.\n * @description Normalizes and parses a URL.\n * @returns {object} Returns the normalized URL as a dictionary.\n *\n * | member name | Description |\n * |---------------|----------------|\n * | href | A normalized version of the provided URL if it was not an absolute URL |\n * | protocol | The protocol including the trailing colon |\n * | host | The host and port (if the port is non-default) of the normalizedUrl |\n * | search | The search params, minus the question mark |\n * | hash | The hash string, minus the hash symbol\n * | hostname | The hostname\n * | port | The port, without \":\"\n * | pathname | The pathname, beginning with \"/\"\n *\n */\n\nvar urlParsingNode = document.createElement(\"a\");\n/**\n * documentMode is an IE-only property\n * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx\n */\nvar msie = document.documentMode;\n\nfunction urlParts(url) {\n var href = url;\n\n if (msie) {\n // Normalize before parse. Refer Implementation Notes on why this is\n // done in two steps on IE.\n urlParsingNode.setAttribute(\"href\", href);\n href = urlParsingNode.href;\n }\n\n urlParsingNode.setAttribute('href', href);\n\n // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n return {\n href: urlParsingNode.href,\n protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n host: urlParsingNode.host,\n search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n hostname: urlParsingNode.hostname,\n port: utilities.isNotEmptyString(urlParsingNode.port)? urlParsingNode.port: 80,\n pathname: (urlParsingNode.pathname.charAt(0) === '/')\n ? urlParsingNode.pathname\n : '/' + urlParsingNode.pathname\n };\n}\n\n\n/**\n * This function accepts a query string (search part of a url) and returns a dictionary with\n * the different key value pairs\n * @param {string} qs queryString\n */\nfunction queryStringToObj(qs, cond) {\n var pairs, qsObj;\n\n cond = utilities.isFunction(cond)? cond : function() {\n return true;\n };\n\n qs = qs.trim().replace(/^\\?/, '');\n pairs = qs.split('&');\n qsObj = {};\n\n utilities.forEach(pairs, function (pair) {\n var keyValue, key, value;\n if (pair !== '') {\n keyValue = pair.split('=');\n key = keyValue[0];\n value = keyValue[1];\n if(cond(key, value)){\n qsObj[key] = value;\n }\n }\n });\n\n return qsObj;\n}\n\n/**\n * This function accepts an object and serializes it into a query string without the leading '?'\n * @param obj\n * @returns {string}\n */\nfunction objToQueryString(obj) {\n var pairs = [];\n utilities.forEach(obj, function (value, key) {\n pairs.push(key + '=' + value);\n });\n return pairs.join('&');\n}\n\nmodule.exports = {\n urlParts: urlParts,\n queryStringToObj: queryStringToObj,\n objToQueryString: objToQueryString\n};\n\n},{\"./utilityFunctions\":45}],45:[function(require,module,exports){\n/*jshint unused:false */\n\"use strict\";\n\nvar NODE_TYPE_ELEMENT = 1;\nvar SNAKE_CASE_REGEXP = /[A-Z]/g;\nvar EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/i;\n/*jslint maxlen: 500 */\nvar ISO8086_REGEXP = /^([\\+-]?\\d{4}(?!\\d{2}\\b))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))([T\\s]((([01]\\d|2[0-3])((:?)[0-5]\\d)?|24\\:?00)([\\.,]\\d+(?!:))?)?(\\17[0-5]\\d([\\.,]\\d+)?)?([zZ]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)?$/;\n\n\nfunction noop(){ }\n\nfunction isNull(o) {\n return o === null;\n}\n\nfunction isDefined(o){\n return o !== undefined;\n}\n\nfunction isUndefined(o){\n return o === undefined;\n}\n\nfunction isObject(obj) {\n return typeof obj === 'object';\n}\n\nfunction isFunction(str){\n return typeof str === 'function';\n}\n\nfunction isNumber(num){\n return typeof num === 'number';\n}\n\nfunction isWindow(obj) {\n return utilities.isObject(obj) && obj.window === obj;\n}\n\nfunction isArray(array){\n return Object.prototype.toString.call( array ) === '[object Array]';\n}\n\nfunction isArrayLike(obj) {\n if (obj === null || utilities.isWindow(obj) || utilities.isFunction(obj) || utilities.isUndefined(obj)) {\n return false;\n }\n\n var length = obj.length;\n\n if (obj.nodeType === NODE_TYPE_ELEMENT && length) {\n return true;\n }\n\n return utilities.isString(obj) || utilities.isArray(obj) || length === 0 ||\n typeof length === 'number' && length > 0 && (length - 1) in obj;\n}\n\nfunction isString(str){\n return typeof str === 'string';\n}\n\nfunction isEmptyString(str) {\n return utilities.isString(str) && str.length === 0;\n}\n\nfunction isNotEmptyString(str) {\n return utilities.isString(str) && str.length !== 0;\n}\n\nfunction arrayLikeObjToArray(args) {\n return Array.prototype.slice.call(args);\n}\n\nfunction forEach(obj, iterator, context) {\n var key, length;\n if (obj) {\n if (isFunction(obj)) {\n for (key in obj) {\n // Need to check if hasOwnProperty exists,\n // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function\n if (key !== 'prototype' && key !== 'length' && key !== 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n } else if (isArray(obj)) {\n var isPrimitive = typeof obj !== 'object';\n for (key = 0, length = obj.length; key < length; key++) {\n if (isPrimitive || key in obj) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n } else if (obj.forEach && obj.forEach !== forEach) {\n obj.forEach(iterator, context, obj);\n } else {\n for (key in obj) {\n if (obj.hasOwnProperty(key)) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n }\n }\n return obj;\n}\n\nfunction snake_case(name, separator) {\n separator = separator || '_';\n return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {\n return (pos ? separator : '') + letter.toLowerCase();\n });\n}\n\nfunction isValidEmail(email){\n if(!utilities.isString(email)){\n return false;\n }\n\n return EMAIL_REGEXP.test(email.trim());\n}\n\nfunction extend (obj) {\n var arg, i, k;\n for (i = 1; i < arguments.length; i++) {\n arg = arguments[i];\n for (k in arg) {\n if (arg.hasOwnProperty(k)) {\n if(isObject(obj[k]) && !isNull(obj[k]) && isObject(arg[k])){\n obj[k] = extend({}, obj[k], arg[k]);\n }else {\n obj[k] = arg[k];\n }\n }\n }\n }\n return obj;\n}\n\nfunction capitalize(s){\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nfunction decapitalize(s) {\n return s.charAt(0).toLowerCase() + s.slice(1);\n}\n\n/**\n * This method works the same way array.prototype.map works but if the transformer returns undefine, then\n * it won't be added to the transformed Array.\n */\nfunction transformArray(array, transformer) {\n var transformedArray = [];\n\n array.forEach(function(item, index){\n var transformedItem = transformer(item, index);\n if(utilities.isDefined(transformedItem)) {\n transformedArray.push(transformedItem);\n }\n });\n\n return transformedArray;\n}\n\nfunction toFixedDigits(num, digits) {\n var formattedNum = num + '';\n digits = utilities.isNumber(digits) ? digits : 0;\n num = utilities.isNumber(num) ? num : parseInt(num, 10);\n if(utilities.isNumber(num) && !isNaN(num)){\n formattedNum = num + '';\n while(formattedNum.length < digits) {\n formattedNum = '0' + formattedNum;\n }\n return formattedNum;\n }\n return NaN + '';\n}\n\nfunction throttle(callback, delay) {\n var previousCall = new Date().getTime() - (delay + 1);\n return function() {\n var time = new Date().getTime();\n if ((time - previousCall) >= delay) {\n previousCall = time;\n callback.apply(this, arguments);\n }\n };\n}\n\nfunction debounce (callback, wait) {\n var timeoutId;\n\n return function (){\n if(timeoutId) {\n clearTimeout(timeoutId);\n }\n timeoutId = setTimeout(function(){\n callback.apply(this, arguments);\n timeoutId = undefined;\n }, wait);\n };\n}\n\n// a function designed to blow up the stack in a naive way\n// but it is ok for videoJs children components\nfunction treeSearch(root, getChildren, found){\n var children = getChildren(root);\n for (var i = 0; i < children.length; i++){\n if (found(children[i])) {\n return children[i];\n }\n else {\n var el = treeSearch(children[i], getChildren, found);\n if (el){\n return el;\n }\n }\n }\n}\n\nfunction echoFn(val) {\n return function () {\n return val;\n };\n}\n\n//Note: Supported formats come from http://www.w3.org/TR/NOTE-datetime\n// and the iso8601 regex comes from http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/\nfunction isISO8601(value) {\n if(utilities.isNumber(value)){\n value = value + ''; //we make sure that we are working with strings\n }\n\n if(!utilities.isString(value)){\n return false;\n }\n\n return ISO8086_REGEXP.test(value.trim());\n}\n\n/**\n * Checks if the Browser is IE9 and below\n * @returns {boolean}\n */\nfunction isOldIE() {\n var version = utilities.getInternetExplorerVersion(navigator);\n if (version === -1) {\n return false;\n }\n\n return version < 10;\n}\n\n/**\n * Returns the version of Internet Explorer or a -1 (indicating the use of another browser).\n * Source: https://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx\n * @returns {number} the version of Internet Explorer or a -1 (indicating the use of another browser).\n */\nfunction getInternetExplorerVersion(navigator) {\n var rv = -1;\n\n if (navigator.appName == 'Microsoft Internet Explorer') {\n var ua = navigator.userAgent;\n var re = new RegExp(\"MSIE ([0-9]{1,}[\\.0-9]{0,})\");\n var res = re.exec(ua);\n if (res !== null) {\n rv = parseFloat(res[1]);\n }\n }\n\n return rv;\n}\n\n/*** Mobile Utility functions ***/\nfunction isIDevice() {\n return /iP(hone|ad)/.test(utilities._UA);\n}\n\nfunction isMobile() {\n return /iP(hone|ad|od)|Android|Windows Phone/.test(utilities._UA);\n}\n\nfunction isIPhone() {\n return /iP(hone|od)/.test(utilities._UA);\n}\n\nfunction isAndroid() {\n return /Android/.test(utilities._UA);\n}\n\nvar utilities = {\n _UA: navigator.userAgent,\n noop: noop,\n isNull: isNull,\n isDefined: isDefined,\n isUndefined: isUndefined,\n isObject: isObject,\n isFunction: isFunction,\n isNumber: isNumber,\n isWindow: isWindow,\n isArray: isArray,\n isArrayLike: isArrayLike,\n isString: isString,\n isEmptyString: isEmptyString,\n isNotEmptyString: isNotEmptyString,\n arrayLikeObjToArray: arrayLikeObjToArray,\n forEach: forEach,\n snake_case: snake_case,\n isValidEmail: isValidEmail,\n extend: extend,\n capitalize: capitalize,\n decapitalize: decapitalize,\n transformArray: transformArray,\n toFixedDigits: toFixedDigits,\n throttle: throttle,\n debounce: debounce,\n treeSearch: treeSearch,\n echoFn: echoFn,\n isISO8601: isISO8601,\n isOldIE: isOldIE,\n getInternetExplorerVersion: getInternetExplorerVersion,\n isIDevice: isIDevice,\n isMobile: isMobile,\n isIPhone: isIPhone,\n isAndroid: isAndroid\n};\n\nmodule.exports = utilities;\n},{}],46:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('./utilityFunctions');\n\nvar xml = {};\n\nxml.strToXMLDoc = function strToXMLDoc(stringContainingXMLSource){\n //IE 8\n if(typeof window.DOMParser === 'undefined'){\n var xmlDocument = new ActiveXObject('Microsoft.XMLDOM');\n xmlDocument.async = false;\n xmlDocument.loadXML(stringContainingXMLSource);\n return xmlDocument;\n }\n\n return parseString(stringContainingXMLSource);\n\n function parseString(stringContainingXMLSource){\n var parser = new DOMParser();\n var parsedDocument;\n\n //Note: This try catch is to deal with the fact that on IE parser.parseFromString does throw an error but the rest of the browsers don't.\n try {\n parsedDocument = parser.parseFromString(stringContainingXMLSource, \"application/xml\");\n\n if(isParseError(parsedDocument) || utilities.isEmptyString(stringContainingXMLSource)){\n throw new Error();\n }\n }catch(e){\n throw new Error(\"xml.strToXMLDOC: Error parsing the string: '\" + stringContainingXMLSource + \"'\");\n }\n\n return parsedDocument;\n }\n\n function isParseError(parsedDocument) {\n try { // parser and parsererrorNS could be cached on startup for efficiency\n var parser = new DOMParser(),\n erroneousParse = parser.parseFromString('INVALID', 'text/xml'),\n parsererrorNS = erroneousParse.getElementsByTagName(\"parsererror\")[0].namespaceURI;\n\n if (parsererrorNS === 'http://www.w3.org/1999/xhtml') {\n // In PhantomJS the parseerror element doesn't seem to have a special namespace, so we are just guessing here :(\n return parsedDocument.getElementsByTagName(\"parsererror\").length > 0;\n }\n\n return parsedDocument.getElementsByTagNameNS(parsererrorNS, 'parsererror').length > 0;\n } catch (e) {\n //Note on IE parseString throws an error by itself and it will never reach this code. Because it will have failed before\n }\n }\n};\n\nxml.parseText = function parseText (sValue) {\n if (/^\\s*$/.test(sValue)) { return null; }\n if (/^(?:true|false)$/i.test(sValue)) { return sValue.toLowerCase() === \"true\"; }\n if (isFinite(sValue)) { return parseFloat(sValue); }\n if (utilities.isISO8601(sValue)) { return new Date(sValue); }\n return sValue.trim();\n};\n\nxml.JXONTree = function JXONTree (oXMLParent) {\n var parseText = xml.parseText;\n\n //The document object is an especial object that it may miss some functions or attrs depending on the browser.\n //To prevent this problem with create the JXONTree using the root childNode which is a fully fleshed node on all supported\n //browsers.\n if(oXMLParent.documentElement){\n return new xml.JXONTree(oXMLParent.documentElement);\n }\n\n if (oXMLParent.hasChildNodes()) {\n var sCollectedTxt = \"\";\n for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {\n oNode = oXMLParent.childNodes.item(nItem);\n /*jshint bitwise: false*/\n if ((oNode.nodeType - 1 | 1) === 3) { sCollectedTxt += oNode.nodeType === 3 ? oNode.nodeValue.trim() : oNode.nodeValue; }\n else if (oNode.nodeType === 1 && !oNode.prefix) {\n sProp = utilities.decapitalize(oNode.nodeName);\n vContent = new xml.JXONTree(oNode);\n if (this.hasOwnProperty(sProp)) {\n if (this[sProp].constructor !== Array) { this[sProp] = [this[sProp]]; }\n this[sProp].push(vContent);\n } else { this[sProp] = vContent; }\n }\n }\n if (sCollectedTxt) { this.keyValue = parseText(sCollectedTxt); }\n }\n\n //IE8 Stupid fix\n var hasAttr = typeof oXMLParent.hasAttributes === 'undefined'? oXMLParent.attributes.length > 0: oXMLParent.hasAttributes();\n if (hasAttr) {\n var oAttrib;\n for (var nAttrib = 0; nAttrib < oXMLParent.attributes.length; nAttrib++) {\n oAttrib = oXMLParent.attributes.item(nAttrib);\n this[\"@\" + utilities.decapitalize(oAttrib.name)] = parseText(oAttrib.value.trim());\n }\n }\n};\n\nxml.JXONTree.prototype.attr = function(attr) {\n return this['@' + utilities.decapitalize(attr)];\n};\n\nxml.toJXONTree = function toJXONTree(xmlString){\n var xmlDoc = xml.strToXMLDoc(xmlString);\n return new xml.JXONTree(xmlDoc);\n};\n\n/**\n * Helper function to extract the keyvalue of a JXONTree obj\n *\n * @param xmlObj {JXONTree}\n * return the key value or undefined;\n */\nxml.keyValue = function getKeyValue(xmlObj) {\n if(xmlObj){\n return xmlObj.keyValue;\n }\n return undefined;\n};\n\nxml.attr = function getAttrValue(xmlObj, attr) {\n if(xmlObj) {\n return xmlObj['@' + utilities.decapitalize(attr)];\n }\n return undefined;\n};\n\nxml.encode = function encodeXML(str) {\n return str.replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n};\n\nxml.decode = function decodeXML(str) {\n return str.replace(/'/g, \"'\")\n .replace(/"/g, '\"')\n .replace(/>/g, '>')\n .replace(/</g, '<')\n .replace(/&/g, '&');\n};\n\nmodule.exports = xml;\n},{\"./utilityFunctions\":45}],47:[function(require,module,exports){\n'use strict';\n\nrequire('./plugin/components/ads-label_4');\nrequire('./plugin/components/black-poster_4');\n\nvar videoJsVAST = require('./plugin/videojs.vast.vpaid');\n\nvideojs.plugin('vastClient', videoJsVAST);\n\n\n},{\"./plugin/components/ads-label_4\":36,\"./plugin/components/black-poster_4\":38,\"./plugin/videojs.vast.vpaid\":39}]},{},[47])\n\n","'use strict';\n\nlet IVPAIDAdUnit = require('./IVPAIDAdUnit').IVPAIDAdUnit;\nlet ALL_VPAID_METHODS = Object.getOwnPropertyNames(IVPAIDAdUnit.prototype).filter(function (property) {\n return ['constructor'].indexOf(property) === -1;\n});\n\nexport class VPAIDAdUnit extends IVPAIDAdUnit {\n constructor (flash) {\n super();\n this._destroyed = false;\n this._flash = flash;\n }\n\n _destroy() {\n this._destroyed = true;\n ALL_VPAID_METHODS.forEach((methodName) => {\n this._flash.removeCallbackByMethodName(methodName);\n });\n IVPAIDAdUnit.EVENTS.forEach((event) => {\n this._flash.offEvent(event);\n });\n\n this._flash = null;\n }\n\n isDestroyed () {\n return this._destroyed;\n }\n\n on(eventName, callback) {\n this._flash.on(eventName, callback);\n }\n\n off(eventName, callback) {\n this._flash.off(eventName, callback);\n }\n\n //VPAID interface\n handshakeVersion(playerVPAIDVersion = '2.0', callback = undefined) {\n this._flash.callFlashMethod('handshakeVersion', [playerVPAIDVersion], callback);\n }\n initAd (width, height, viewMode, desiredBitrate, creativeData = {AdParameters: ''}, environmentVars = {flashVars: ''}, callback = undefined) {\n //resize element that has the flash object\n this._flash.setSize(width, height);\n creativeData = creativeData || {AdParameters: ''};\n environmentVars = environmentVars || {flashVars: ''};\n\n this._flash.callFlashMethod('initAd', [this._flash.getWidth(), this._flash.getHeight(), viewMode, desiredBitrate, creativeData.AdParameters || '', environmentVars.flashVars || ''], callback);\n }\n resizeAd(width, height, viewMode, callback = undefined) {\n //resize element that has the flash object\n this._flash.setSize(width, height);\n\n //resize ad inside the flash\n this._flash.callFlashMethod('resizeAd', [this._flash.getWidth(), this._flash.getHeight(), viewMode], callback);\n }\n startAd(callback = undefined) {\n this._flash.callFlashMethod('startAd', [], callback);\n }\n stopAd(callback = undefined) {\n this._flash.callFlashMethod('stopAd', [], callback);\n }\n pauseAd(callback = undefined) {\n this._flash.callFlashMethod('pauseAd', [], callback);\n }\n resumeAd(callback = undefined) {\n this._flash.callFlashMethod('resumeAd', [], callback);\n }\n expandAd(callback = undefined) {\n this._flash.callFlashMethod('expandAd', [], callback);\n }\n collapseAd(callback = undefined) {\n this._flash.callFlashMethod('collapseAd', [], callback);\n }\n skipAd(callback = undefined) {\n this._flash.callFlashMethod('skipAd', [], callback);\n }\n\n //properties that will be treat as async methods\n getAdLinear(callback) {\n this._flash.callFlashMethod('getAdLinear', [], callback);\n }\n getAdWidth(callback) {\n this._flash.callFlashMethod('getAdWidth', [], callback);\n }\n getAdHeight(callback) {\n this._flash.callFlashMethod('getAdHeight', [], callback);\n }\n getAdExpanded(callback) {\n this._flash.callFlashMethod('getAdExpanded', [], callback);\n }\n getAdSkippableState(callback) {\n this._flash.callFlashMethod('getAdSkippableState', [], callback);\n }\n getAdRemainingTime(callback) {\n this._flash.callFlashMethod('getAdRemainingTime', [], callback);\n }\n getAdDuration(callback) {\n this._flash.callFlashMethod('getAdDuration', [], callback);\n }\n setAdVolume(volume, callback = undefined) {\n this._flash.callFlashMethod('setAdVolume', [volume], callback);\n }\n getAdVolume(callback) {\n this._flash.callFlashMethod('getAdVolume', [], callback);\n }\n getAdCompanions(callback) {\n this._flash.callFlashMethod('getAdCompanions', [], callback);\n }\n getAdIcons(callback) {\n this._flash.callFlashMethod('getAdIcons', [], callback);\n }\n}\n\n","'use strict';\n\nconst swfobject = require('swfobject');\n\nconst JSFlashBridge = require('./jsFlashBridge').JSFlashBridge;\nconst VPAIDAdUnit = require('./VPAIDAdUnit').VPAIDAdUnit;\n\nconst noop = require('./utils').noop;\nconst callbackTimeout = require('./utils').callbackTimeout;\nconst isPositiveInt = require('./utils').isPositiveInt;\nconst createElementWithID = require('./utils').createElementWithID;\nconst uniqueVPAID = require('./utils').unique('vpaid');\nconst createFlashTester = require('./flashTester.js').createFlashTester;\n\nconst ERROR = 'error';\nconst FLASH_VERSION = '10.1.0';\n\nlet flashTester = {isSupported: ()=> true}; // if the runFlashTest is not run the flashTester will always return true\n\nclass VPAIDFLASHClient {\n constructor (vpaidParentEl, callback, swfConfig = {data: 'VPAIDFlash.swf', width: 800, height: 400}, params = { wmode: 'transparent', salign: 'tl', align: 'left', allowScriptAccess: 'always', scale: 'noScale', allowFullScreen: 'true', quality: 'high'}, vpaidOptions = { debug: false, timeout: 10000 }) {\n\n var me = this;\n\n this._vpaidParentEl = vpaidParentEl;\n this._flashID = uniqueVPAID();\n this._destroyed = false;\n callback = callback || noop;\n\n swfConfig.width = isPositiveInt(swfConfig.width, 800);\n swfConfig.height = isPositiveInt(swfConfig.height, 400);\n\n createElementWithID(vpaidParentEl, this._flashID, true);\n\n params.movie = swfConfig.data;\n params.FlashVars = `flashid=${this._flashID}&handler=${JSFlashBridge.VPAID_FLASH_HANDLER}&debug=${vpaidOptions.debug}&salign=${params.salign}`;\n\n if (!VPAIDFLASHClient.isSupported()) {\n return onError('user don\\'t support flash or doesn\\'t have the minimum required version of flash ' + FLASH_VERSION);\n }\n\n this.el = swfobject.createSWF(swfConfig, params, this._flashID);\n\n if (!this.el) {\n return onError( 'swfobject failed to create object in element' );\n }\n\n var handler = callbackTimeout(vpaidOptions.timeout,\n (err, data) => {\n $loadPendedAdUnit.call(this);\n callback(err, data);\n }, () => {\n callback('vpaid flash load timeout ' + vpaidOptions.timeout);\n }\n );\n\n this._flash = new JSFlashBridge(this.el, swfConfig.data, this._flashID, swfConfig.width, swfConfig.height, handler);\n\n function onError(error) {\n setTimeout(() => {\n callback(new Error(error));\n }, 0);\n return me;\n }\n\n }\n\n destroy () {\n this._destroyAdUnit();\n\n if (this._flash) {\n this._flash.destroy();\n this._flash = null;\n }\n this.el = null;\n this._destroyed = true;\n }\n\n isDestroyed () {\n return this._destroyed;\n }\n\n _destroyAdUnit() {\n delete this._loadLater;\n\n if (this._adUnitLoad) {\n this._adUnitLoad = null;\n this._flash.removeCallback(this._adUnitLoad);\n }\n\n if (this._adUnit) {\n this._adUnit._destroy();\n this._adUnit = null;\n }\n }\n\n loadAdUnit(adURL, callback) {\n $throwIfDestroyed.call(this);\n\n if (this._adUnit) {\n this._destroyAdUnit();\n }\n\n if (this._flash.isReady()) {\n this._adUnitLoad = (err, message) => {\n if (!err) {\n this._adUnit = new VPAIDAdUnit(this._flash);\n }\n this._adUnitLoad = null;\n callback(err, this._adUnit);\n };\n\n this._flash.callFlashMethod('loadAdUnit', [adURL], this._adUnitLoad);\n }else {\n this._loadLater = {url: adURL, callback};\n }\n }\n\n unloadAdUnit(callback = undefined) {\n $throwIfDestroyed.call(this);\n\n this._destroyAdUnit();\n this._flash.callFlashMethod('unloadAdUnit', [], callback);\n }\n getFlashID() {\n $throwIfDestroyed.call(this);\n return this._flash.getFlashID();\n }\n getFlashURL() {\n $throwIfDestroyed.call(this);\n return this._flash.getFlashURL();\n }\n}\n\nsetStaticProperty('isSupported', () => {\n return swfobject.hasFlashPlayerVersion(FLASH_VERSION) && flashTester.isSupported();\n}, true);\n\nsetStaticProperty('runFlashTest', (swfConfig) => {\n flashTester = createFlashTester(document.body, swfConfig);\n});\n\nfunction $throwIfDestroyed() {\n if(this._destroyed) {\n throw new Error('VPAIDFlashToJS is destroyed!');\n }\n}\n\nfunction $loadPendedAdUnit() {\n if (this._loadLater) {\n this.loadAdUnit(this._loadLater.url, this._loadLater.callback);\n delete this._loadLater;\n }\n}\n\nfunction setStaticProperty(propertyName, value, writable = false) {\n Object.defineProperty(VPAIDFLASHClient, propertyName, {\n writable: writable,\n configurable: false,\n value: value\n });\n}\n\nVPAIDFLASHClient.swfobject = swfobject;\n\nmodule.exports = VPAIDFLASHClient;\n","'use strict';\n\nconst swfobject = require('swfobject');\n\nconst FLASH_TEST = 'vpaid_video_flash_tester';\nconst FLASH_TEST_EL = 'vpaid_video_flash_tester_el';\nconst JSFlashBridge = require('./jsFlashBridge').JSFlashBridge;\nconst utils = require('./utils');\nconst MultipleValuesRegistry = require('./registry').MultipleValuesRegistry;\n\nclass FlashTester {\n constructor(parent, swfConfig = {data: 'VPAIDFlash.swf', width: 800, height: 400}) {\n this.parentEl = utils.createElementWithID(parent, FLASH_TEST_EL); // some browsers create global variables using the element id http://stackoverflow.com/questions/3434278/do-dom-tree-elements-with-ids-become-global-variables\n utils.hideFlashEl(this.parentEl);\n var params = {};\n params.movie = swfConfig.data;\n params.FlashVars = `flashid=${FLASH_TEST_EL}&handler=${JSFlashBridge.VPAID_FLASH_HANDLER}`;\n\n this.el = swfobject.createSWF(swfConfig, params, FLASH_TEST_EL);\n this._handlers = new MultipleValuesRegistry();\n this._isSupported = false;\n if (this.el) {\n utils.hideFlashEl(this.el);\n this._flash = new JSFlashBridge(this.el, swfConfig.data, FLASH_TEST_EL, 400, 400, ()=> {\n const support = true;\n this._isSupported = support;\n this._handlers.get('change').forEach((callback) => {\n setTimeout(()=> {\n callback('change', support);\n }, 0);\n });\n });\n }\n }\n isSupported() {\n return this._isSupported;\n }\n on(eventName, callback) {\n this._handlers.add(eventName, callback);\n }\n}\n\nexport var createFlashTester = function createFlashTester(el, swfConfig) {\n if (!window[FLASH_TEST]) {\n window[FLASH_TEST] = new FlashTester(el, swfConfig);\n }\n return window[FLASH_TEST];\n};\n","'use strict';\n\nlet unique = require('./utils').unique;\nlet isPositiveInt = require('./utils').isPositiveInt;\nlet stringEndsWith = require('./utils').stringEndsWith;\nlet SingleValueRegistry = require('./registry').SingleValueRegistry;\nlet MultipleValuesRegistry = require('./registry').MultipleValuesRegistry;\nconst registry = require('./jsFlashBridgeRegistry');\nconst VPAID_FLASH_HANDLER = 'vpaid_video_flash_handler';\nconst ERROR = 'AdError';\n\nexport class JSFlashBridge {\n constructor (el, flashURL, flashID, width, height, loadHandShake) {\n this._el = el;\n this._flashID = flashID;\n this._flashURL = flashURL;\n this._width = width;\n this._height = height;\n this._handlers = new MultipleValuesRegistry();\n this._callbacks = new SingleValueRegistry();\n this._uniqueMethodIdentifier = unique(this._flashID);\n this._ready = false;\n this._handShakeHandler = loadHandShake;\n\n registry.addInstance(this._flashID, this);\n }\n\n on(eventName, callback) {\n this._handlers.add(eventName, callback);\n }\n\n off(eventName, callback) {\n return this._handlers.remove(eventName, callback);\n }\n\n offEvent(eventName) {\n return this._handlers.removeByKey(eventName);\n }\n\n offAll() {\n return this._handlers.removeAll();\n }\n\n callFlashMethod(methodName, args = [], callback = undefined) {\n var callbackID = '';\n // if no callback, some methods the return is void so they don't need callback\n if (callback) {\n callbackID = `${this._uniqueMethodIdentifier()}_${methodName}`;\n this._callbacks.add(callbackID, callback);\n }\n\n\n try {\n //methods are created by ExternalInterface.addCallback in as3 code, if for some reason it failed\n //this code will throw an error\n this._el[methodName]([callbackID].concat(args));\n\n } catch (e) {\n if (callback) {\n $asyncCallback.call(this, callbackID, e);\n } else {\n\n //if there isn't any callback to return error use error event handler\n this._trigger(ERROR, e);\n }\n }\n }\n\n removeCallback(callback) {\n return this._callbacks.removeByValue(callback);\n }\n\n removeCallbackByMethodName(suffix) {\n this._callbacks.filterKeys((key) => {\n return stringEndsWith(key, suffix);\n }).forEach((key) => {\n this._callbacks.remove(key);\n });\n }\n\n removeAllCallbacks() {\n return this._callbacks.removeAll();\n }\n\n _trigger(eventName, event) {\n this._handlers.get(eventName).forEach((callback) => {\n //clickThru has to be sync, if not will be block by the popupblocker\n if (eventName === 'AdClickThru') {\n callback(event);\n } else {\n setTimeout(() => {\n if (this._handlers.get(eventName).length > 0) {\n callback(event);\n }\n }, 0);\n }\n });\n }\n\n _callCallback(methodName, callbackID, err, result) {\n\n let callback = this._callbacks.get(callbackID);\n\n //not all methods callback's are mandatory\n //but if there exist an error, fire the error event\n if (!callback) {\n if (err && callbackID === '') {\n this.trigger(ERROR, err);\n }\n return;\n }\n\n $asyncCallback.call(this, callbackID, err, result);\n\n }\n\n _handShake(err, data) {\n this._ready = true;\n if (this._handShakeHandler) {\n this._handShakeHandler(err, data);\n delete this._handShakeHandler;\n }\n }\n\n //methods like properties specific to this implementation of VPAID\n getSize() {\n return {width: this._width, height: this._height};\n }\n setSize(newWidth, newHeight) {\n this._width = isPositiveInt(newWidth, this._width);\n this._height = isPositiveInt(newHeight, this._height);\n this._el.setAttribute('width', this._width);\n this._el.setAttribute('height', this._height);\n }\n getWidth() {\n return this._width;\n }\n setWidth(newWidth) {\n this.setSize(newWidth, this._height);\n }\n getHeight() {\n return this._height;\n }\n setHeight(newHeight) {\n this.setSize(this._width, newHeight);\n }\n getFlashID() {\n return this._flashID;\n }\n getFlashURL() {\n return this._flashURL;\n }\n isReady() {\n return this._ready;\n }\n destroy() {\n this.offAll();\n this.removeAllCallbacks();\n registry.removeInstanceByID(this._flashID);\n if (this._el.parentElement) {\n this._el.parentElement.removeChild(this._el);\n }\n }\n}\n\nfunction $asyncCallback(callbackID, err, result) {\n setTimeout(() => {\n let callback = this._callbacks.get(callbackID);\n if (callback) {\n this._callbacks.remove(callbackID);\n callback(err, result);\n }\n }, 0);\n}\n\nObject.defineProperty(JSFlashBridge, 'VPAID_FLASH_HANDLER', {\n writable: false,\n configurable: false,\n value: VPAID_FLASH_HANDLER\n});\n\n/**\n * External interface handler\n *\n * @param {string} flashID identifier of the flash who call this\n * @param {string} typeID what type of message is, can be 'event' or 'callback'\n * @param {string} typeName if the typeID is a event the typeName will be the eventName, if is a callback the typeID is the methodName that is related this callback\n * @param {string} callbackID only applies when the typeID is 'callback', identifier of the callback to call\n * @param {object} error error object\n * @param {object} data\n */\nwindow[VPAID_FLASH_HANDLER] = (flashID, typeID, typeName, callbackID, error, data) => {\n let instance = registry.getInstanceByID(flashID);\n if (!instance) return;\n if (typeName === 'handShake') {\n instance._handShake(error, data);\n } else {\n if (typeID !== 'event') {\n instance._callCallback(typeName, callbackID, error, data);\n } else {\n instance._trigger(typeName, data);\n }\n }\n};\n\n","'use strict';\n\nlet SingleValueRegistry = require('./registry').SingleValueRegistry;\nlet instances = new SingleValueRegistry();\n\nconst JSFlashBridgeRegistry = {};\nObject.defineProperty(JSFlashBridgeRegistry, 'addInstance', {\n writable: false,\n configurable: false,\n value: function (id, instance) {\n instances.add(id, instance);\n }\n});\n\nObject.defineProperty(JSFlashBridgeRegistry, 'getInstanceByID', {\n writable: false,\n configurable: false,\n value: function (id) {\n return instances.get(id);\n }\n});\n\nObject.defineProperty(JSFlashBridgeRegistry, 'removeInstanceByID', {\n writable: false,\n configurable: false,\n value: function (id) {\n return instances.remove(id);\n }\n});\n\nmodule.exports = JSFlashBridgeRegistry;\n\n","'use strict';\n\nexport class MultipleValuesRegistry {\n constructor () {\n this._registries = {};\n }\n add (id, value) {\n if (!this._registries[id]) {\n this._registries[id] = [];\n }\n if (this._registries[id].indexOf(value) === -1) {\n this._registries[id].push(value);\n }\n }\n get (id) {\n return this._registries[id] || [];\n }\n filterKeys (handler) {\n return Object.keys(this._registries).filter(handler);\n }\n findByValue (value) {\n var keys = Object.keys(this._registries).filter((key) => {\n return this._registries[key].indexOf(value) !== -1;\n });\n\n return keys;\n }\n remove(key, value) {\n if (!this._registries[key]) { return; }\n\n var index = this._registries[key].indexOf(value);\n\n if (index < 0) { return; }\n return this._registries[key].splice(index, 1);\n }\n removeByKey (id) {\n let old = this._registries[id];\n delete this._registries[id];\n return old;\n }\n removeByValue (value) {\n let keys = this.findByValue(value);\n return keys.map((key) => {\n return this.remove(key, value);\n });\n }\n removeAll() {\n let old = this._registries;\n this._registries = {};\n return old;\n }\n size() {\n return Object.keys(this._registries).length;\n }\n}\n\nexport class SingleValueRegistry {\n constructor () {\n this._registries = {};\n }\n add (id, value) {\n this._registries[id] = value;\n }\n get (id) {\n return this._registries[id];\n }\n filterKeys (handler) {\n return Object.keys(this._registries).filter(handler);\n }\n findByValue (value) {\n var keys = Object.keys(this._registries).filter((key) => {\n return this._registries[key] === value;\n });\n\n return keys;\n }\n remove (id) {\n let old = this._registries[id];\n delete this._registries[id];\n return old;\n }\n removeByValue (value) {\n let keys = this.findByValue(value);\n return keys.map((key) => {\n return this.remove(key);\n });\n }\n removeAll() {\n let old = this._registries;\n this._registries = {};\n return old;\n }\n size() {\n return Object.keys(this._registries).length;\n }\n}\n\n","'use strict';\n\nexport function unique(prefix) {\n let count = -1;\n return f => {\n return `${prefix}_${++count}`;\n };\n}\n\nexport function noop() {\n}\n\n\nexport function callbackTimeout(timer, onSuccess, onTimeout) {\n\n let timeout = setTimeout(() => {\n\n onSuccess = noop;\n onTimeout();\n\n }, timer);\n\n return function () {\n clearTimeout(timeout);\n onSuccess.apply(this, arguments);\n };\n}\n\n\nexport function createElementWithID(parent, id, cleanContent = false) {\n var nEl = document.createElement('div');\n nEl.id = id;\n if (cleanContent) {\n parent.innerHTML = '';\n }\n parent.appendChild(nEl);\n return nEl;\n}\n\nexport function isPositiveInt(newVal, oldVal) {\n return !isNaN(parseFloat(newVal)) && isFinite(newVal) && newVal > 0 ? newVal : oldVal;\n}\n\nlet endsWith = (function () {\n if (String.prototype.endsWith) return String.prototype.endsWith;\n return function endsWith (searchString, position) {\n var subjectString = this.toString();\n if (position === undefined || position > subjectString.length) {\n position = subjectString.length;\n }\n position -= searchString.length;\n var lastIndex = subjectString.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n };\n})();\n\nexport function stringEndsWith(string, search) {\n return endsWith.call(string, search);\n}\n\nexport function hideFlashEl(el) {\n // can't use display none or visibility none because will block flash in some browsers\n el.style.position = 'absolute';\n el.style.left = '-1px';\n el.style.top = '-1px';\n el.style.width = '1px';\n el.style.height = '1px';\n}\n","'use strict';\n\nvar METHODS = [\n 'handshakeVersion',\n 'initAd',\n 'startAd',\n 'stopAd',\n 'skipAd', // VPAID 2.0 new method\n 'resizeAd',\n 'pauseAd',\n 'resumeAd',\n 'expandAd',\n 'collapseAd',\n 'subscribe',\n 'unsubscribe'\n];\n\nvar EVENTS = [\n 'AdLoaded',\n 'AdStarted',\n 'AdStopped',\n 'AdSkipped',\n 'AdSkippableStateChange', // VPAID 2.0 new event\n 'AdSizeChange', // VPAID 2.0 new event\n 'AdLinearChange',\n 'AdDurationChange', // VPAID 2.0 new event\n 'AdExpandedChange',\n 'AdRemainingTimeChange', // [Deprecated in 2.0] but will be still fired for backwards compatibility\n 'AdVolumeChange',\n 'AdImpression',\n 'AdVideoStart',\n 'AdVideoFirstQuartile',\n 'AdVideoMidpoint',\n 'AdVideoThirdQuartile',\n 'AdVideoComplete',\n 'AdClickThru',\n 'AdInteraction', // VPAID 2.0 new event\n 'AdUserAcceptInvitation',\n 'AdUserMinimize',\n 'AdUserClose',\n 'AdPaused',\n 'AdPlaying',\n 'AdLog',\n 'AdError'\n];\n\nvar GETTERS = [\n 'getAdLinear',\n 'getAdWidth', // VPAID 2.0 new getter\n 'getAdHeight', // VPAID 2.0 new getter\n 'getAdExpanded',\n 'getAdSkippableState', // VPAID 2.0 new getter\n 'getAdRemainingTime',\n 'getAdDuration', // VPAID 2.0 new getter\n 'getAdVolume',\n 'getAdCompanions', // VPAID 2.0 new getter\n 'getAdIcons' // VPAID 2.0 new getter\n];\n\nvar SETTERS = [\n 'setAdVolume'\n];\n\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n\n/**\n * IVPAIDAdUnit\n *\n * @class\n *\n * @param {object} creative\n * @param {HTMLElement} el\n * @param {HTMLVideoElement} video\n */\nfunction IVPAIDAdUnit(creative, el, video) {}\n\n\n/**\n * handshakeVersion\n *\n * @param {string} VPAIDVersion\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.handshakeVersion = function (VPAIDVersion, callback) {};\n\n/**\n * initAd\n *\n * @param {number} width\n * @param {number} height\n * @param {string} viewMode can be 'normal', 'thumbnail' or 'fullscreen'\n * @param {number} desiredBitrate indicates the desired bitrate in kbps\n * @param {object} [creativeData] used for additional initialization data\n * @param {object} [environmentVars] used for passing implementation-specific of js version\n * @param {NodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.initAd = function(width, height, viewMode, desiredBitrate, creativeData, environmentVars, callback) {};\n\n/**\n * startAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.startAd = function(callback) {};\n\n/**\n * stopAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.stopAd = function(callback) {};\n\n/**\n * skipAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.skipAd = function(callback) {};\n\n/**\n * resizeAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.resizeAd = function(width, height, viewMode, callback) {};\n\n/**\n * pauseAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.pauseAd = function(callback) {};\n\n/**\n * resumeAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.resumeAd = function(callback) {};\n\n/**\n * expandAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.expandAd = function(callback) {};\n\n/**\n * collapseAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.collapseAd = function(callback) {};\n\n/**\n * subscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n * @param {object} context\n */\nIVPAIDAdUnit.prototype.subscribe = function(event, handler, context) {};\n\n/**\n * startAd\n *\n * @param {string} event\n * @param {function} handler\n */\nIVPAIDAdUnit.prototype.unsubscribe = function(event, handler) {};\n\n\n\n/**\n * getAdLinear\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdLinear = function(callback) {};\n\n/**\n * getAdWidth\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdWidth = function(callback) {};\n\n/**\n * getAdHeight\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdHeight = function(callback) {};\n\n/**\n * getAdExpanded\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdExpanded = function(callback) {};\n\n/**\n * getAdSkippableState\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdSkippableState = function(callback) {};\n\n/**\n * getAdRemainingTime\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdRemainingTime = function(callback) {};\n\n/**\n * getAdDuration\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdDuration = function(callback) {};\n\n/**\n * getAdVolume\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdVolume = function(callback) {};\n\n/**\n * getAdCompanions\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdCompanions = function(callback) {};\n\n/**\n * getAdIcons\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdIcons = function(callback) {};\n\n/**\n * setAdVolume\n *\n * @param {number} volume\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.setAdVolume = function(volume, callback) {};\n\naddStaticToInterface(IVPAIDAdUnit, 'METHODS', METHODS);\naddStaticToInterface(IVPAIDAdUnit, 'GETTERS', GETTERS);\naddStaticToInterface(IVPAIDAdUnit, 'SETTERS', SETTERS);\naddStaticToInterface(IVPAIDAdUnit, 'EVENTS', EVENTS);\n\n\nvar VPAID1_METHODS = METHODS.filter(function(method) {\n return ['skipAd'].indexOf(method) === -1;\n});\n\naddStaticToInterface(IVPAIDAdUnit, 'checkVPAIDInterface', function checkVPAIDInterface (creative) {\n var result = VPAID1_METHODS.every(function(key) {\n return typeof creative[key] === 'function';\n });\n return result;\n});\n\nmodule.exports = IVPAIDAdUnit;\n\nfunction addStaticToInterface(Interface, name, value) {\n Object.defineProperty(Interface, name, {\n writable: false,\n configurable: false,\n value: value\n });\n}\n\n","'use strict';\n\nvar IVPAIDAdUnit = require('./IVPAIDAdUnit');\nvar Subscriber = require('./subscriber');\nvar checkVPAIDInterface = IVPAIDAdUnit.checkVPAIDInterface;\nvar utils = require('./utils');\nvar METHODS = IVPAIDAdUnit.METHODS;\nvar ERROR = 'AdError';\nvar AD_CLICK = 'AdClickThru';\nvar FILTERED_EVENTS = IVPAIDAdUnit.EVENTS.filter(function (event) {\n return event != AD_CLICK;\n});\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n\n/**\n * VPAIDAdUnit\n * @class\n *\n * @param VPAIDCreative\n * @param {HTMLElement} [el] this will be used in initAd environmentVars.slot if defined\n * @param {HTMLVideoElement} [video] this will be used in initAd environmentVars.videoSlot if defined\n */\nfunction VPAIDAdUnit(VPAIDCreative, el, video, iframe) {\n this._isValid = checkVPAIDInterface(VPAIDCreative);\n if (this._isValid) {\n this._creative = VPAIDCreative;\n this._el = el;\n this._videoEl = video;\n this._iframe = iframe;\n this._subscribers = new Subscriber();\n $addEventsSubscribers.call(this);\n }\n}\n\nVPAIDAdUnit.prototype = Object.create(IVPAIDAdUnit.prototype);\n\n/**\n * isValidVPAIDAd will return if the VPAIDCreative passed in constructor is valid or not\n *\n * @return {boolean}\n */\nVPAIDAdUnit.prototype.isValidVPAIDAd = function isValidVPAIDAd() {\n return this._isValid;\n};\n\nIVPAIDAdUnit.METHODS.forEach(function(method) {\n //NOTE: this methods arguments order are implemented differently from the spec\n var ignores = [\n 'subscribe',\n 'unsubscribe',\n 'initAd'\n ];\n\n if (ignores.indexOf(method) !== -1) return;\n\n VPAIDAdUnit.prototype[method] = function () {\n var ariaty = IVPAIDAdUnit.prototype[method].length;\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n var args = Array.prototype.slice.call(arguments);\n var callback = (ariaty === args.length) ? args.pop() : undefined;\n\n setTimeout(function () {\n var result, error = null;\n try {\n result = this._creative[method].apply(this._creative, args);\n } catch(e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n };\n});\n\n\n/**\n * initAd concreate implementation\n *\n * @param {number} width\n * @param {number} height\n * @param {string} viewMode can be 'normal', 'thumbnail' or 'fullscreen'\n * @param {number} desiredBitrate indicates the desired bitrate in kbps\n * @param {object} [creativeData] used for additional initialization data\n * @param {object} [environmentVars] used for passing implementation-specific of js version, if el & video was used in constructor slot & videoSlot will be added to the object\n * @param {NodeStyleCallback} callback\n */\nVPAIDAdUnit.prototype.initAd = function initAd(width, height, viewMode, desiredBitrate, creativeData, environmentVars, callback) {\n creativeData = creativeData || {};\n environmentVars = utils.extend({\n slot: this._el,\n videoSlot: this._videoEl\n }, environmentVars || {});\n\n setTimeout(function () {\n var error;\n try {\n this._creative.initAd(width, height, viewMode, desiredBitrate, creativeData, environmentVars);\n } catch (e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error);\n }.bind(this), 0);\n};\n\n/**\n * subscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n * @param {object} context\n */\nVPAIDAdUnit.prototype.subscribe = function subscribe(event, handler, context) {\n this._subscribers.subscribe(handler, event, context);\n};\n\n\n/**\n * unsubscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n */\nVPAIDAdUnit.prototype.unsubscribe = function unsubscribe(event, handler) {\n this._subscribers.unsubscribe(handler, event);\n};\n\n//alias\nVPAIDAdUnit.prototype.on = VPAIDAdUnit.prototype.subscribe;\nVPAIDAdUnit.prototype.off = VPAIDAdUnit.prototype.unsubscribe;\n\nIVPAIDAdUnit.GETTERS.forEach(function(getter) {\n VPAIDAdUnit.prototype[getter] = function (callback) {\n setTimeout(function () {\n\n var result, error = null;\n try {\n result = this._creative[getter]();\n } catch(e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n };\n});\n\n/**\n * setAdVolume\n *\n * @param volume\n * @param {nodeStyleCallback} callback\n */\nVPAIDAdUnit.prototype.setAdVolume = function setAdVolume(volume, callback) {\n setTimeout(function () {\n\n var result, error = null;\n try {\n this._creative.setAdVolume(volume);\n result = this._creative.getAdVolume();\n } catch(e) {\n error = e;\n }\n\n if (!error) {\n error = utils.validate(result === volume, 'failed to apply volume: ' + volume);\n }\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n};\n\nVPAIDAdUnit.prototype._destroy = function destroy() {\n this.stopAd();\n this._subscribers.unsubscribeAll();\n};\n\nfunction $addEventsSubscribers() {\n // some ads implement\n // so they only handle one subscriber\n // to handle this we create our one\n FILTERED_EVENTS.forEach(function (event) {\n this._creative.subscribe($trigger.bind(this, event), event);\n }.bind(this));\n\n // map the click event to be an object instead of depending of the order of the arguments\n // and to be consistent with the flash\n this._creative.subscribe($clickThruHook.bind(this), AD_CLICK);\n\n // because we are adding the element inside the iframe\n // the user is not able to click in the video\n if (this._videoEl) {\n var documentElement = this._iframe.contentDocument.documentElement;\n var videoEl = this._videoEl;\n documentElement.addEventListener('click', function(e) {\n if (e.target === documentElement) {\n videoEl.click();\n }\n });\n }\n}\n\nfunction $clickThruHook(url, id, playerHandles) {\n this._subscribers.triggerSync(AD_CLICK, {url: url, id: id, playerHandles: playerHandles});\n}\n\nfunction $trigger(event) {\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n this._subscribers.trigger(event, Array.prototype.slice(arguments, 1));\n}\n\nfunction callOrTriggerEvent(callback, subscribers, error, result) {\n if (callback) {\n callback(error, result);\n } else if (error) {\n subscribers.trigger(ERROR, error);\n }\n}\n\nmodule.exports = VPAIDAdUnit;\n\n","'use strict';\n\nvar utils = require('./utils');\nvar unique = utils.unique('vpaidIframe');\nvar VPAIDAdUnit = require('./VPAIDAdUnit');\n\nvar defaultTemplate = '' +\n '' +\n '' +\n '
' +\n '' +\n '' +\n '' +\n '';\n\nvar AD_STOPPED = 'AdStopped';\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n/**\n * VPAIDHTML5Client\n * @class\n *\n * @param {HTMLElement} el that will contain the iframe to load adUnit and a el to add to adUnit slot\n * @param {HTMLVideoElement} video default video element to be used by adUnit\n * @param {object} [templateConfig] template: html template to be used instead of the default, extraOptions: to be used when rendering the template\n * @param {object} [vpaidOptions] timeout: when loading adUnit\n */\nfunction VPAIDHTML5Client(el, video, templateConfig, vpaidOptions) {\n templateConfig = templateConfig || {};\n\n this._id = unique();\n this._destroyed = false;\n\n this._frameContainer = utils.createElementInEl(el, 'div');\n this._videoEl = video;\n this._vpaidOptions = vpaidOptions || {timeout: 10000};\n\n this._templateConfig = {\n template: templateConfig.template || defaultTemplate,\n extraOptions: templateConfig.extraOptions || {}\n };\n}\n\n/**\n * destroy\n *\n */\nVPAIDHTML5Client.prototype.destroy = function destroy() {\n if (this._destroyed) {\n return;\n }\n this._destroyed = true;\n $unloadPreviousAdUnit.call(this);\n};\n\n/**\n * isDestroyed\n *\n * @return {boolean}\n */\nVPAIDHTML5Client.prototype.isDestroyed = function isDestroyed() {\n return this._destroyed;\n};\n\n/**\n * loadAdUnit\n *\n * @param {string} adURL url of the js of the adUnit\n * @param {nodeStyleCallback} callback\n */\nVPAIDHTML5Client.prototype.loadAdUnit = function loadAdUnit(adURL, callback) {\n $throwIfDestroyed.call(this);\n $unloadPreviousAdUnit.call(this);\n var that = this;\n\n var frame = utils.createIframeWithContent(\n this._frameContainer,\n this._templateConfig.template,\n utils.extend({\n iframeURL_JS: adURL,\n iframeID: this.getID(),\n origin: getOrigin()\n }, this._templateConfig.extraOptions)\n );\n\n this._frame = frame;\n\n this._onLoad = utils.callbackTimeout(\n this._vpaidOptions.timeout,\n onLoad.bind(this),\n onTimeout.bind(this)\n );\n\n window.addEventListener('message', this._onLoad);\n\n function onLoad (e) {\n /*jshint validthis: false */\n //don't clear timeout\n if (e.origin !== getOrigin()) return;\n var result = JSON.parse(e.data);\n\n //don't clear timeout\n if (result.id !== that.getID()) return;\n\n var adUnit, error, createAd;\n if (!that._frame.contentWindow) {\n\n error = 'the iframe is not anymore in the DOM tree';\n\n } else {\n createAd = that._frame.contentWindow.getVPAIDAd;\n error = utils.validate(typeof createAd === 'function', 'the ad didn\\'t return a function to create an ad');\n }\n\n if (!error) {\n var adEl = that._frame.contentWindow.document.querySelector('.ad-element');\n adUnit = new VPAIDAdUnit(createAd(), adEl, that._videoEl, that._frame);\n adUnit.subscribe(AD_STOPPED, $adDestroyed.bind(that));\n error = utils.validate(adUnit.isValidVPAIDAd(), 'the add is not fully complaint with VPAID specification');\n }\n\n that._adUnit = adUnit;\n $destroyLoadListener.call(that);\n callback(error, error ? null : adUnit);\n\n //clear timeout\n return true;\n }\n\n function onTimeout() {\n callback('timeout', null);\n }\n};\n\n/**\n * unloadAdUnit\n *\n */\nVPAIDHTML5Client.prototype.unloadAdUnit = function unloadAdUnit() {\n $unloadPreviousAdUnit.call(this);\n};\n\n/**\n * getID will return the unique id\n *\n * @return {string}\n */\nVPAIDHTML5Client.prototype.getID = function () {\n return this._id;\n};\n\n\n/**\n * $removeEl\n *\n * @param {string} key\n */\nfunction $removeEl(key) {\n var el = this[key];\n if (el) {\n el.remove();\n delete this[key];\n }\n}\n\nfunction $adDestroyed() {\n $removeAdElements.call(this);\n delete this._adUnit;\n}\n\nfunction $unloadPreviousAdUnit() {\n $removeAdElements.call(this);\n $destroyAdUnit.call(this);\n}\n\nfunction $removeAdElements() {\n $removeEl.call(this, '_frame');\n $destroyLoadListener.call(this);\n}\n\n/**\n * $destroyLoadListener\n *\n */\nfunction $destroyLoadListener() {\n if (this._onLoad) {\n window.removeEventListener('message', this._onLoad);\n utils.clearCallbackTimeout(this._onLoad);\n delete this._onLoad;\n }\n}\n\n\nfunction $destroyAdUnit() {\n if (this._adUnit) {\n this._adUnit.stopAd();\n delete this._adUnit;\n }\n}\n\n/**\n * $throwIfDestroyed\n *\n */\nfunction $throwIfDestroyed() {\n if (this._destroyed) {\n throw new Error ('VPAIDHTML5Client already destroyed!');\n }\n}\n\nfunction getOrigin() {\n if( window.location.origin ) {\n return window.location.origin;\n }\n else {\n return window.location.protocol + \"//\" +\n window.location.hostname +\n (window.location.port ? ':' + window.location.port: '');\n }\n}\n\nmodule.exports = VPAIDHTML5Client;\nwindow.VPAIDHTML5Client = VPAIDHTML5Client;\n\n","'use strict';\n\nfunction Subscriber() {\n this._subscribers = {};\n}\n\nSubscriber.prototype.subscribe = function subscribe(handler, eventName, context) {\n if (!this.isHandlerAttached(handler, eventName)) {\n this.get(eventName).push({handler: handler, context: context, eventName: eventName});\n }\n};\n\nSubscriber.prototype.unsubscribe = function unsubscribe(handler, eventName) {\n this._subscribers[eventName] = this.get(eventName).filter(function (subscriber) {\n return handler !== subscriber.handler;\n });\n};\n\nSubscriber.prototype.unsubscribeAll = function unsubscribeAll() {\n this._subscribers = {};\n};\n\nSubscriber.prototype.trigger = function(eventName, data) {\n var that = this;\n var subscribers = this.get(eventName)\n .concat(this.get('*'));\n\n subscribers.forEach(function (subscriber) {\n setTimeout(function () {\n if (that.isHandlerAttached(subscriber.handler, subscriber.eventName)) {\n subscriber.handler.call(subscriber.context, data);\n }\n }, 0);\n });\n};\n\nSubscriber.prototype.triggerSync = function(eventName, data) {\n var subscribers = this.get(eventName)\n .concat(this.get('*'));\n\n subscribers.forEach(function (subscriber) {\n subscriber.handler.call(subscriber.context, data);\n });\n};\n\nSubscriber.prototype.get = function get(eventName) {\n if (!this._subscribers[eventName]) {\n this._subscribers[eventName] = [];\n }\n return this._subscribers[eventName];\n};\n\nSubscriber.prototype.isHandlerAttached = function isHandlerAttached(handler, eventName) {\n return this.get(eventName).some(function(subscriber) {\n return handler === subscriber.handler;\n })\n};\n\nmodule.exports = Subscriber;\n\n","'use strict';\n\n/**\n * noop a empty function\n */\nfunction noop() {}\n\n/**\n * validate if is not validate will return an Error with the message\n *\n * @param {boolean} isValid\n * @param {string} message\n */\nfunction validate(isValid, message) {\n return isValid ? null : new Error(message);\n}\n\nvar timeouts = {};\n/**\n * clearCallbackTimeout\n *\n * @param {function} func handler to remove\n */\nfunction clearCallbackTimeout(func) {\n var timeout = timeouts[func];\n if (timeout) {\n clearTimeout(timeout);\n delete timeouts[func];\n }\n}\n\n/**\n * callbackTimeout if the onSuccess is not called and returns true in the timelimit then onTimeout will be called\n *\n * @param {number} timer\n * @param {function} onSuccess\n * @param {function} onTimeout\n */\nfunction callbackTimeout(timer, onSuccess, onTimeout) {\n var callback, timeout;\n\n timeout = setTimeout(function () {\n onSuccess = noop;\n delete timeout[callback];\n onTimeout();\n }, timer);\n\n callback = function () {\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n if (onSuccess.apply(this, arguments)) {\n clearCallbackTimeout(callback);\n }\n };\n\n timeouts[callback] = timeout;\n\n return callback;\n}\n\n\n/**\n * createElementInEl\n *\n * @param {HTMLElement} parent\n * @param {string} tagName\n * @param {string} id\n */\nfunction createElementInEl(parent, tagName, id) {\n var nEl = document.createElement(tagName);\n if (id) nEl.id = id;\n parent.appendChild(nEl);\n return nEl;\n}\n\n/**\n * createIframeWithContent\n *\n * @param {HTMLElement} parent\n * @param {string} template simple template using {{var}}\n * @param {object} data\n */\nfunction createIframeWithContent(parent, template, data) {\n var iframe = createIframe(parent, null, data.zIndex);\n if (!setIframeContent(iframe, simpleTemplate(template, data))) return;\n return iframe;\n}\n\n/**\n * createIframe\n *\n * @param {HTMLElement} parent\n * @param {string} url\n */\nfunction createIframe(parent, url, zIndex) {\n var nEl = document.createElement('iframe');\n nEl.src = url || 'about:blank';\n nEl.marginWidth = '0';\n nEl.marginHeight = '0';\n nEl.frameBorder = '0';\n nEl.width = '100%';\n nEl.height = '100%';\n nEl.style.position = 'absolute';\n nEl.style.left = '0';\n nEl.style.top = '0';\n nEl.style.margin = '0px';\n nEl.style.padding = '0px';\n nEl.style.border = 'none';\n\n if(zIndex){\n nEl.style.zIndex = zIndex;\n }\n\n nEl.setAttribute('SCROLLING','NO');\n parent.innerHTML = '';\n parent.appendChild(nEl);\n return nEl;\n}\n\n/**\n * simpleTemplate\n *\n * @param {string} template\n * @param {object} data\n */\nfunction simpleTemplate(template, data) {\n Object.keys(data).forEach(function (key) {\n var value = (typeof value === 'object') ? JSON.stringify(data[key]) : data[key];\n template = template.replace(new RegExp('{{' + key + '}}', 'g'), value);\n });\n return template;\n}\n\n/**\n * setIframeContent\n *\n * @param {HTMLIframeElement} iframeEl\n * @param content\n */\nfunction setIframeContent(iframeEl, content) {\n var iframeDoc = iframeEl.contentWindow && iframeEl.contentWindow.document;\n if (!iframeDoc) return false;\n\n iframeDoc.write(content);\n\n return true;\n}\n\n\n/**\n * extend object with keys from another object\n *\n * @param {object} toExtend\n * @param {object} fromSource\n */\nfunction extend(toExtend, fromSource) {\n Object.keys(fromSource).forEach(function(key) {\n toExtend[key] = fromSource[key];\n });\n return toExtend;\n}\n\n\n/**\n * unique will create a unique string everytime is called, sequentially and prefixed\n *\n * @param {string} prefix\n */\nfunction unique(prefix) {\n var count = -1;\n return function () {\n return prefix + '_' + (++count);\n };\n}\n\nmodule.exports = {\n noop: noop,\n validate: validate,\n clearCallbackTimeout: clearCallbackTimeout,\n callbackTimeout: callbackTimeout,\n createElementInEl: createElementInEl,\n createIframeWithContent: createIframeWithContent,\n createIframe: createIframe,\n simpleTemplate: simpleTemplate,\n setIframeContent: setIframeContent,\n extend: extend,\n unique: unique\n};\n\n","/*! SWFObject v2.3.20130521 \r\n is released under the MIT License \r\n*/\r\n\r\n/* global ActiveXObject: false */\r\n\r\n(function (root, factory) {\r\n if (typeof define === 'function' && define.amd) {\r\n // AMD\r\n define(factory);\r\n } else if (typeof module === 'object' && module.exports) {\r\n // Node, CommonJS-like\r\n module.exports = factory();\r\n } else {\r\n // Browser globals (root is window)\r\n root.swfobject = factory();\r\n }\r\n}(this, function () {\r\n\r\n var UNDEF = \"undefined\",\r\n OBJECT = \"object\",\r\n SHOCKWAVE_FLASH = \"Shockwave Flash\",\r\n SHOCKWAVE_FLASH_AX = \"ShockwaveFlash.ShockwaveFlash\",\r\n FLASH_MIME_TYPE = \"application/x-shockwave-flash\",\r\n EXPRESS_INSTALL_ID = \"SWFObjectExprInst\",\r\n ON_READY_STATE_CHANGE = \"onreadystatechange\",\r\n\r\n win = window,\r\n doc = document,\r\n nav = navigator,\r\n\r\n plugin = false,\r\n domLoadFnArr = [],\r\n regObjArr = [],\r\n objIdArr = [],\r\n listenersArr = [],\r\n storedFbContent,\r\n storedFbContentId,\r\n storedCallbackFn,\r\n storedCallbackObj,\r\n isDomLoaded = false,\r\n isExpressInstallActive = false,\r\n dynamicStylesheet,\r\n dynamicStylesheetMedia,\r\n autoHideShow = true,\r\n encodeURIEnabled = false,\r\n\r\n /* Centralized function for browser feature detection\r\n - User agent string detection is only used when no good alternative is possible\r\n - Is executed directly for optimal performance\r\n */\r\n ua = function () {\r\n var w3cdom = typeof doc.getElementById !== UNDEF && typeof doc.getElementsByTagName !== UNDEF && typeof doc.createElement !== UNDEF,\r\n u = nav.userAgent.toLowerCase(),\r\n p = nav.platform.toLowerCase(),\r\n windows = p ? /win/.test(p) : /win/.test(u),\r\n mac = p ? /mac/.test(p) : /mac/.test(u),\r\n webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\\/(\\d+(\\.\\d+)?).*$/, \"$1\")) : false, // returns either the webkit version or false if not webkit\r\n ie = nav.appName === \"Microsoft Internet Explorer\",\r\n playerVersion = [0, 0, 0],\r\n d = null;\r\n if (typeof nav.plugins !== UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] === OBJECT) {\r\n d = nav.plugins[SHOCKWAVE_FLASH].description;\r\n // nav.mimeTypes[\"application/x-shockwave-flash\"].enabledPlugin indicates whether plug-ins are enabled or disabled in Safari 3+\r\n if (d && (typeof nav.mimeTypes !== UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) {\r\n plugin = true;\r\n ie = false; // cascaded feature detection for Internet Explorer\r\n d = d.replace(/^.*\\s+(\\S+\\s+\\S+$)/, \"$1\");\r\n playerVersion[0] = toInt(d.replace(/^(.*)\\..*$/, \"$1\"));\r\n playerVersion[1] = toInt(d.replace(/^.*\\.(.*)\\s.*$/, \"$1\"));\r\n playerVersion[2] = /[a-zA-Z]/.test(d) ? toInt(d.replace(/^.*[a-zA-Z]+(.*)$/, \"$1\")) : 0;\r\n }\r\n }\r\n else if (typeof win.ActiveXObject !== UNDEF) {\r\n try {\r\n var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);\r\n if (a) { // a will return null when ActiveX is disabled\r\n d = a.GetVariable(\"$version\");\r\n if (d) {\r\n ie = true; // cascaded feature detection for Internet Explorer\r\n d = d.split(\" \")[1].split(\",\");\r\n playerVersion = [toInt(d[0]), toInt(d[1]), toInt(d[2])];\r\n }\r\n }\r\n }\r\n catch (e) {}\r\n }\r\n return {w3: w3cdom, pv: playerVersion, wk: webkit, ie: ie, win: windows, mac: mac};\r\n }(),\r\n\r\n /* Cross-browser onDomLoad\r\n - Will fire an event as soon as the DOM of a web page is loaded\r\n - Internet Explorer workaround based on Diego Perini's solution: http://javascript.nwbox.com/IEContentLoaded/\r\n - Regular onload serves as fallback\r\n */\r\n onDomLoad = function () {\r\n if (!ua.w3) { return; }\r\n if ((typeof doc.readyState !== UNDEF && (doc.readyState === \"complete\" || doc.readyState === \"interactive\")) || (typeof doc.readyState === UNDEF && (doc.getElementsByTagName(\"body\")[0] || doc.body))) { // function is fired after onload, e.g. when script is inserted dynamically\r\n callDomLoadFunctions();\r\n }\r\n if (!isDomLoaded) {\r\n if (typeof doc.addEventListener !== UNDEF) {\r\n doc.addEventListener(\"DOMContentLoaded\", callDomLoadFunctions, false);\r\n }\r\n if (ua.ie) {\r\n doc.attachEvent(ON_READY_STATE_CHANGE, function detach() {\r\n if (doc.readyState === \"complete\") {\r\n doc.detachEvent(ON_READY_STATE_CHANGE, detach);\r\n callDomLoadFunctions();\r\n }\r\n });\r\n if (win == top) { // if not inside an iframe\r\n (function checkDomLoadedIE() {\r\n if (isDomLoaded) { return; }\r\n try {\r\n doc.documentElement.doScroll(\"left\");\r\n }\r\n catch (e) {\r\n setTimeout(checkDomLoadedIE, 0);\r\n return;\r\n }\r\n callDomLoadFunctions();\r\n }());\r\n }\r\n }\r\n if (ua.wk) {\r\n (function checkDomLoadedWK() {\r\n if (isDomLoaded) { return; }\r\n if (!/loaded|complete/.test(doc.readyState)) {\r\n setTimeout(checkDomLoadedWK, 0);\r\n return;\r\n }\r\n callDomLoadFunctions();\r\n }());\r\n }\r\n }\r\n }();\r\n\r\n function callDomLoadFunctions() {\r\n if (isDomLoaded || !document.getElementsByTagName(\"body\")[0]) { return; }\r\n try { // test if we can really add/remove elements to/from the DOM; we don't want to fire it too early\r\n var t, span = createElement(\"span\");\r\n span.style.display = \"none\"; //hide the span in case someone has styled spans via CSS\r\n t = doc.getElementsByTagName(\"body\")[0].appendChild(span);\r\n t.parentNode.removeChild(t);\r\n t = null; //clear the variables\r\n span = null;\r\n }\r\n catch (e) { return; }\r\n isDomLoaded = true;\r\n var dl = domLoadFnArr.length;\r\n for (var i = 0; i < dl; i++) {\r\n domLoadFnArr[i]();\r\n }\r\n }\r\n\r\n function addDomLoadEvent(fn) {\r\n if (isDomLoaded) {\r\n fn();\r\n }\r\n else {\r\n domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+\r\n }\r\n }\r\n\r\n /* Cross-browser onload\r\n - Based on James Edwards' solution: http://brothercake.com/site/resources/scripts/onload/\r\n - Will fire an event as soon as a web page including all of its assets are loaded\r\n */\r\n function addLoadEvent(fn) {\r\n if (typeof win.addEventListener !== UNDEF) {\r\n win.addEventListener(\"load\", fn, false);\r\n }\r\n else if (typeof doc.addEventListener !== UNDEF) {\r\n doc.addEventListener(\"load\", fn, false);\r\n }\r\n else if (typeof win.attachEvent !== UNDEF) {\r\n addListener(win, \"onload\", fn);\r\n }\r\n else if (typeof win.onload === \"function\") {\r\n var fnOld = win.onload;\r\n win.onload = function () {\r\n fnOld();\r\n fn();\r\n };\r\n }\r\n else {\r\n win.onload = fn;\r\n }\r\n }\r\n\r\n /* Detect the Flash Player version for non-Internet Explorer browsers\r\n - Detecting the plug-in version via the object element is more precise than using the plugins collection item's description:\r\n a. Both release and build numbers can be detected\r\n b. Avoid wrong descriptions by corrupt installers provided by Adobe\r\n c. Avoid wrong descriptions by multiple Flash Player entries in the plugin Array, caused by incorrect browser imports\r\n - Disadvantage of this method is that it depends on the availability of the DOM, while the plugins collection is immediately available\r\n */\r\n function testPlayerVersion() {\r\n var b = doc.getElementsByTagName(\"body\")[0];\r\n var o = createElement(OBJECT);\r\n o.setAttribute(\"style\", \"visibility: hidden;\");\r\n o.setAttribute(\"type\", FLASH_MIME_TYPE);\r\n var t = b.appendChild(o);\r\n if (t) {\r\n var counter = 0;\r\n (function checkGetVariable() {\r\n if (typeof t.GetVariable !== UNDEF) {\r\n try {\r\n var d = t.GetVariable(\"$version\");\r\n if (d) {\r\n d = d.split(\" \")[1].split(\",\");\r\n ua.pv = [toInt(d[0]), toInt(d[1]), toInt(d[2])];\r\n }\r\n } catch (e) {\r\n //t.GetVariable(\"$version\") is known to fail in Flash Player 8 on Firefox\r\n //If this error is encountered, assume FP8 or lower. Time to upgrade.\r\n ua.pv = [8, 0, 0];\r\n }\r\n }\r\n else if (counter < 10) {\r\n counter++;\r\n setTimeout(checkGetVariable, 10);\r\n return;\r\n }\r\n b.removeChild(o);\r\n t = null;\r\n matchVersions();\r\n }());\r\n }\r\n else {\r\n matchVersions();\r\n }\r\n }\r\n\r\n /* Perform Flash Player and SWF version matching; static publishing only\r\n */\r\n function matchVersions() {\r\n var rl = regObjArr.length;\r\n if (rl > 0) {\r\n for (var i = 0; i < rl; i++) { // for each registered object element\r\n var id = regObjArr[i].id;\r\n var cb = regObjArr[i].callbackFn;\r\n var cbObj = {success: false, id: id};\r\n if (ua.pv[0] > 0) {\r\n var obj = getElementById(id);\r\n if (obj) {\r\n if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { // Flash Player version >= published SWF version: Houston, we have a match!\r\n setVisibility(id, true);\r\n if (cb) {\r\n cbObj.success = true;\r\n cbObj.ref = getObjectById(id);\r\n cbObj.id = id;\r\n cb(cbObj);\r\n }\r\n }\r\n else if (regObjArr[i].expressInstall && canExpressInstall()) { // show the Adobe Express Install dialog if set by the web page author and if supported\r\n var att = {};\r\n att.data = regObjArr[i].expressInstall;\r\n att.width = obj.getAttribute(\"width\") || \"0\";\r\n att.height = obj.getAttribute(\"height\") || \"0\";\r\n if (obj.getAttribute(\"class\")) { att.styleclass = obj.getAttribute(\"class\"); }\r\n if (obj.getAttribute(\"align\")) { att.align = obj.getAttribute(\"align\"); }\r\n // parse HTML object param element's name-value pairs\r\n var par = {};\r\n var p = obj.getElementsByTagName(\"param\");\r\n var pl = p.length;\r\n for (var j = 0; j < pl; j++) {\r\n if (p[j].getAttribute(\"name\").toLowerCase() !== \"movie\") {\r\n par[p[j].getAttribute(\"name\")] = p[j].getAttribute(\"value\");\r\n }\r\n }\r\n showExpressInstall(att, par, id, cb);\r\n }\r\n else { // Flash Player and SWF version mismatch or an older Webkit engine that ignores the HTML object element's nested param elements: display fallback content instead of SWF\r\n displayFbContent(obj);\r\n if (cb) { cb(cbObj); }\r\n }\r\n }\r\n }\r\n else { // if no Flash Player is installed or the fp version cannot be detected we let the HTML object element do its job (either show a SWF or fallback content)\r\n setVisibility(id, true);\r\n if (cb) {\r\n var o = getObjectById(id); // test whether there is an HTML object element or not\r\n if (o && typeof o.SetVariable !== UNDEF) {\r\n cbObj.success = true;\r\n cbObj.ref = o;\r\n cbObj.id = o.id;\r\n }\r\n cb(cbObj);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /* Main function\r\n - Will preferably execute onDomLoad, otherwise onload (as a fallback)\r\n */\r\n domLoadFnArr[0] = function () {\r\n if (plugin) {\r\n testPlayerVersion();\r\n }\r\n else {\r\n matchVersions();\r\n }\r\n };\r\n\r\n function getObjectById(objectIdStr) {\r\n var r = null,\r\n o = getElementById(objectIdStr);\r\n\r\n if (o && o.nodeName.toUpperCase() === \"OBJECT\") {\r\n //If targeted object is valid Flash file\r\n if (typeof o.SetVariable !== UNDEF) {\r\n r = o;\r\n } else {\r\n //If SetVariable is not working on targeted object but a nested object is\r\n //available, assume classic nested object markup. Return nested object.\r\n\r\n //If SetVariable is not working on targeted object and there is no nested object,\r\n //return the original object anyway. This is probably new simplified markup.\r\n\r\n r = o.getElementsByTagName(OBJECT)[0] || o;\r\n }\r\n }\r\n\r\n return r;\r\n }\r\n\r\n /* Requirements for Adobe Express Install\r\n - only one instance can be active at a time\r\n - fp 6.0.65 or higher\r\n - Win/Mac OS only\r\n - no Webkit engines older than version 312\r\n */\r\n function canExpressInstall() {\r\n return !isExpressInstallActive && hasPlayerVersion(\"6.0.65\") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);\r\n }\r\n\r\n /* Show the Adobe Express Install dialog\r\n - Reference: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75\r\n */\r\n function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {\r\n\r\n var obj = getElementById(replaceElemIdStr);\r\n\r\n //Ensure that replaceElemIdStr is really a string and not an element\r\n replaceElemIdStr = getId(replaceElemIdStr);\r\n\r\n isExpressInstallActive = true;\r\n storedCallbackFn = callbackFn || null;\r\n storedCallbackObj = {success: false, id: replaceElemIdStr};\r\n\r\n if (obj) {\r\n if (obj.nodeName.toUpperCase() === \"OBJECT\") { // static publishing\r\n storedFbContent = abstractFbContent(obj);\r\n storedFbContentId = null;\r\n }\r\n else { // dynamic publishing\r\n storedFbContent = obj;\r\n storedFbContentId = replaceElemIdStr;\r\n }\r\n att.id = EXPRESS_INSTALL_ID;\r\n if (typeof att.width === UNDEF || (!/%$/.test(att.width) && toInt(att.width) < 310)) { att.width = \"310\"; }\r\n if (typeof att.height === UNDEF || (!/%$/.test(att.height) && toInt(att.height) < 137)) { att.height = \"137\"; }\r\n var pt = ua.ie ? \"ActiveX\" : \"PlugIn\",\r\n fv = \"MMredirectURL=\" + encodeURIComponent(win.location.toString().replace(/&/g, \"%26\")) + \"&MMplayerType=\" + pt + \"&MMdoctitle=\" + encodeURIComponent(doc.title.slice(0, 47) + \" - Flash Player Installation\");\r\n if (typeof par.flashvars !== UNDEF) {\r\n par.flashvars += \"&\" + fv;\r\n }\r\n else {\r\n par.flashvars = fv;\r\n }\r\n // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it,\r\n // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work\r\n if (ua.ie && obj.readyState != 4) {\r\n var newObj = createElement(\"div\");\r\n replaceElemIdStr += \"SWFObjectNew\";\r\n newObj.setAttribute(\"id\", replaceElemIdStr);\r\n obj.parentNode.insertBefore(newObj, obj); // insert placeholder div that will be replaced by the object element that loads expressinstall.swf\r\n obj.style.display = \"none\";\r\n removeSWF(obj); //removeSWF accepts elements now\r\n }\r\n createSWF(att, par, replaceElemIdStr);\r\n }\r\n }\r\n\r\n /* Functions to abstract and display fallback content\r\n */\r\n function displayFbContent(obj) {\r\n if (ua.ie && obj.readyState != 4) {\r\n // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it,\r\n // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work\r\n obj.style.display = \"none\";\r\n var el = createElement(\"div\");\r\n obj.parentNode.insertBefore(el, obj); // insert placeholder div that will be replaced by the fallback content\r\n el.parentNode.replaceChild(abstractFbContent(obj), el);\r\n removeSWF(obj); //removeSWF accepts elements now\r\n }\r\n else {\r\n obj.parentNode.replaceChild(abstractFbContent(obj), obj);\r\n }\r\n }\r\n\r\n function abstractFbContent(obj) {\r\n var ac = createElement(\"div\");\r\n if (ua.win && ua.ie) {\r\n ac.innerHTML = obj.innerHTML;\r\n }\r\n else {\r\n var nestedObj = obj.getElementsByTagName(OBJECT)[0];\r\n if (nestedObj) {\r\n var c = nestedObj.childNodes;\r\n if (c) {\r\n var cl = c.length;\r\n for (var i = 0; i < cl; i++) {\r\n if (!(c[i].nodeType == 1 && c[i].nodeName === \"PARAM\") && !(c[i].nodeType == 8)) {\r\n ac.appendChild(c[i].cloneNode(true));\r\n }\r\n }\r\n }\r\n }\r\n }\r\n return ac;\r\n }\r\n\r\n function createIeObject(url, paramStr) {\r\n var div = createElement(\"div\");\r\n div.innerHTML = \"\" + paramStr + \"\";\r\n return div.firstChild;\r\n }\r\n\r\n /* Cross-browser dynamic SWF creation\r\n */\r\n function createSWF(attObj, parObj, id) {\r\n var r, el = getElementById(id);\r\n id = getId(id); // ensure id is truly an ID and not an element\r\n\r\n if (ua.wk && ua.wk < 312) { return r; }\r\n\r\n if (el) {\r\n var o = (ua.ie) ? createElement(\"div\") : createElement(OBJECT),\r\n attr,\r\n attrLower,\r\n param;\r\n\r\n if (typeof attObj.id === UNDEF) { // if no 'id' is defined for the object element, it will inherit the 'id' from the fallback content\r\n attObj.id = id;\r\n }\r\n\r\n //Add params\r\n for (param in parObj) {\r\n //filter out prototype additions from other potential libraries and IE specific param element\r\n if (parObj.hasOwnProperty(param) && param.toLowerCase() !== \"movie\") {\r\n createObjParam(o, param, parObj[param]);\r\n }\r\n }\r\n\r\n //Create IE object, complete with param nodes\r\n if (ua.ie) { o = createIeObject(attObj.data, o.innerHTML); }\r\n\r\n //Add attributes to object\r\n for (attr in attObj) {\r\n if (attObj.hasOwnProperty(attr)) { // filter out prototype additions from other potential libraries\r\n attrLower = attr.toLowerCase();\r\n\r\n // 'class' is an ECMA4 reserved keyword\r\n if (attrLower === \"styleclass\") {\r\n o.setAttribute(\"class\", attObj[attr]);\r\n } else if (attrLower !== \"classid\" && attrLower !== \"data\") {\r\n o.setAttribute(attr, attObj[attr]);\r\n }\r\n }\r\n }\r\n\r\n if (ua.ie) {\r\n objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on unload (dynamic publishing only)\r\n } else {\r\n o.setAttribute(\"type\", FLASH_MIME_TYPE);\r\n o.setAttribute(\"data\", attObj.data);\r\n }\r\n\r\n el.parentNode.replaceChild(o, el);\r\n r = o;\r\n }\r\n\r\n return r;\r\n }\r\n\r\n function createObjParam(el, pName, pValue) {\r\n var p = createElement(\"param\");\r\n p.setAttribute(\"name\", pName);\r\n p.setAttribute(\"value\", pValue);\r\n el.appendChild(p);\r\n }\r\n\r\n /* Cross-browser SWF removal\r\n - Especially needed to safely and completely remove a SWF in Internet Explorer\r\n */\r\n function removeSWF(id) {\r\n var obj = getElementById(id);\r\n if (obj && obj.nodeName.toUpperCase() === \"OBJECT\") {\r\n if (ua.ie) {\r\n obj.style.display = \"none\";\r\n (function removeSWFInIE() {\r\n if (obj.readyState == 4) {\r\n //This step prevents memory leaks in Internet Explorer\r\n for (var i in obj) {\r\n if (typeof obj[i] === \"function\") {\r\n obj[i] = null;\r\n }\r\n }\r\n obj.parentNode.removeChild(obj);\r\n } else {\r\n setTimeout(removeSWFInIE, 10);\r\n }\r\n }());\r\n }\r\n else {\r\n obj.parentNode.removeChild(obj);\r\n }\r\n }\r\n }\r\n\r\n function isElement(id) {\r\n return (id && id.nodeType && id.nodeType === 1);\r\n }\r\n\r\n function getId(thing) {\r\n return (isElement(thing)) ? thing.id : thing;\r\n }\r\n\r\n /* Functions to optimize JavaScript compression\r\n */\r\n function getElementById(id) {\r\n\r\n //Allow users to pass an element OR an element's ID\r\n if (isElement(id)) { return id; }\r\n\r\n var el = null;\r\n try {\r\n el = doc.getElementById(id);\r\n }\r\n catch (e) {}\r\n return el;\r\n }\r\n\r\n function createElement(el) {\r\n return doc.createElement(el);\r\n }\r\n\r\n //To aid compression; replaces 14 instances of pareseInt with radix\r\n function toInt(str) {\r\n return parseInt(str, 10);\r\n }\r\n\r\n /* Updated attachEvent function for Internet Explorer\r\n - Stores attachEvent information in an Array, so on unload the detachEvent functions can be called to avoid memory leaks\r\n */\r\n function addListener(target, eventType, fn) {\r\n target.attachEvent(eventType, fn);\r\n listenersArr[listenersArr.length] = [target, eventType, fn];\r\n }\r\n\r\n /* Flash Player and SWF content version matching\r\n */\r\n function hasPlayerVersion(rv) {\r\n rv += \"\"; //Coerce number to string, if needed.\r\n var pv = ua.pv, v = rv.split(\".\");\r\n v[0] = toInt(v[0]);\r\n v[1] = toInt(v[1]) || 0; // supports short notation, e.g. \"9\" instead of \"9.0.0\"\r\n v[2] = toInt(v[2]) || 0;\r\n return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;\r\n }\r\n\r\n /* Cross-browser dynamic CSS creation\r\n - Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php\r\n */\r\n function createCSS(sel, decl, media, newStyle) {\r\n var h = doc.getElementsByTagName(\"head\")[0];\r\n if (!h) { return; } // to also support badly authored HTML pages that lack a head element\r\n var m = (typeof media === \"string\") ? media : \"screen\";\r\n if (newStyle) {\r\n dynamicStylesheet = null;\r\n dynamicStylesheetMedia = null;\r\n }\r\n if (!dynamicStylesheet || dynamicStylesheetMedia != m) {\r\n // create dynamic stylesheet + get a global reference to it\r\n var s = createElement(\"style\");\r\n s.setAttribute(\"type\", \"text/css\");\r\n s.setAttribute(\"media\", m);\r\n dynamicStylesheet = h.appendChild(s);\r\n if (ua.ie && typeof doc.styleSheets !== UNDEF && doc.styleSheets.length > 0) {\r\n dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];\r\n }\r\n dynamicStylesheetMedia = m;\r\n }\r\n // add style rule\r\n if (dynamicStylesheet) {\r\n if (typeof dynamicStylesheet.addRule !== UNDEF) {\r\n dynamicStylesheet.addRule(sel, decl);\r\n } else if (typeof doc.createTextNode !== UNDEF) {\r\n dynamicStylesheet.appendChild(doc.createTextNode(sel + \" {\" + decl + \"}\"));\r\n }\r\n }\r\n }\r\n\r\n function setVisibility(id, isVisible) {\r\n if (!autoHideShow) { return; }\r\n var v = isVisible ? \"visible\" : \"hidden\",\r\n el = getElementById(id);\r\n if (isDomLoaded && el) {\r\n el.style.visibility = v;\r\n } else if (typeof id === \"string\") {\r\n createCSS(\"#\" + id, \"visibility:\" + v);\r\n }\r\n }\r\n\r\n /* Filter to avoid XSS attacks\r\n */\r\n function urlEncodeIfNecessary(s) {\r\n var regex = /[\\\\\\\"<>\\.;]/;\r\n var hasBadChars = regex.exec(s) !== null;\r\n return hasBadChars && typeof encodeURIComponent !== UNDEF ? encodeURIComponent(s) : s;\r\n }\r\n\r\n /* Release memory to avoid memory leaks caused by closures, fix hanging audio/video threads and force open sockets/NetConnections to disconnect (Internet Explorer only)\r\n */\r\n var cleanup = function () {\r\n if (ua.ie) {\r\n window.attachEvent(\"onunload\", function () {\r\n // remove listeners to avoid memory leaks\r\n var ll = listenersArr.length;\r\n for (var i = 0; i < ll; i++) {\r\n listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);\r\n }\r\n // cleanup dynamically embedded objects to fix audio/video threads and force open sockets and NetConnections to disconnect\r\n var il = objIdArr.length;\r\n for (var j = 0; j < il; j++) {\r\n removeSWF(objIdArr[j]);\r\n }\r\n // cleanup library's main closures to avoid memory leaks\r\n for (var k in ua) {\r\n ua[k] = null;\r\n }\r\n ua = null;\r\n for (var l in swfobject) {\r\n swfobject[l] = null;\r\n }\r\n swfobject = null;\r\n });\r\n }\r\n }();\r\n\r\n return {\r\n /* Public API\r\n - Reference: http://code.google.com/p/swfobject/wiki/documentation\r\n */\r\n registerObject: function (objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {\r\n if (ua.w3 && objectIdStr && swfVersionStr) {\r\n var regObj = {};\r\n regObj.id = objectIdStr;\r\n regObj.swfVersion = swfVersionStr;\r\n regObj.expressInstall = xiSwfUrlStr;\r\n regObj.callbackFn = callbackFn;\r\n regObjArr[regObjArr.length] = regObj;\r\n setVisibility(objectIdStr, false);\r\n }\r\n else if (callbackFn) {\r\n callbackFn({success: false, id: objectIdStr});\r\n }\r\n },\r\n\r\n getObjectById: function (objectIdStr) {\r\n if (ua.w3) {\r\n return getObjectById(objectIdStr);\r\n }\r\n },\r\n\r\n embedSWF: function (swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {\r\n\r\n var id = getId(replaceElemIdStr),\r\n callbackObj = {success: false, id: id};\r\n\r\n if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {\r\n setVisibility(id, false);\r\n addDomLoadEvent(function () {\r\n widthStr += \"\"; // auto-convert to string\r\n heightStr += \"\";\r\n var att = {};\r\n if (attObj && typeof attObj === OBJECT) {\r\n for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs\r\n att[i] = attObj[i];\r\n }\r\n }\r\n att.data = swfUrlStr;\r\n att.width = widthStr;\r\n att.height = heightStr;\r\n var par = {};\r\n if (parObj && typeof parObj === OBJECT) {\r\n for (var j in parObj) { // copy object to avoid the use of references, because web authors often reuse parObj for multiple SWFs\r\n par[j] = parObj[j];\r\n }\r\n }\r\n if (flashvarsObj && typeof flashvarsObj === OBJECT) {\r\n for (var k in flashvarsObj) { // copy object to avoid the use of references, because web authors often reuse flashvarsObj for multiple SWFs\r\n if (flashvarsObj.hasOwnProperty(k)) {\r\n\r\n var key = (encodeURIEnabled) ? encodeURIComponent(k) : k,\r\n value = (encodeURIEnabled) ? encodeURIComponent(flashvarsObj[k]) : flashvarsObj[k];\r\n\r\n if (typeof par.flashvars !== UNDEF) {\r\n par.flashvars += \"&\" + key + \"=\" + value;\r\n }\r\n else {\r\n par.flashvars = key + \"=\" + value;\r\n }\r\n\r\n }\r\n }\r\n }\r\n if (hasPlayerVersion(swfVersionStr)) { // create SWF\r\n var obj = createSWF(att, par, replaceElemIdStr);\r\n if (att.id == id) {\r\n setVisibility(id, true);\r\n }\r\n callbackObj.success = true;\r\n callbackObj.ref = obj;\r\n callbackObj.id = obj.id;\r\n }\r\n else if (xiSwfUrlStr && canExpressInstall()) { // show Adobe Express Install\r\n att.data = xiSwfUrlStr;\r\n showExpressInstall(att, par, replaceElemIdStr, callbackFn);\r\n return;\r\n }\r\n else { // show fallback content\r\n setVisibility(id, true);\r\n }\r\n if (callbackFn) { callbackFn(callbackObj); }\r\n });\r\n }\r\n else if (callbackFn) { callbackFn(callbackObj); }\r\n },\r\n\r\n switchOffAutoHideShow: function () {\r\n autoHideShow = false;\r\n },\r\n\r\n enableUriEncoding: function (bool) {\r\n encodeURIEnabled = (typeof bool === UNDEF) ? true : bool;\r\n },\r\n\r\n ua: ua,\r\n\r\n getFlashPlayerVersion: function () {\r\n return {major: ua.pv[0], minor: ua.pv[1], release: ua.pv[2]};\r\n },\r\n\r\n hasFlashPlayerVersion: hasPlayerVersion,\r\n\r\n createSWF: function (attObj, parObj, replaceElemIdStr) {\r\n if (ua.w3) {\r\n return createSWF(attObj, parObj, replaceElemIdStr);\r\n }\r\n else {\r\n return undefined;\r\n }\r\n },\r\n\r\n showExpressInstall: function (att, par, replaceElemIdStr, callbackFn) {\r\n if (ua.w3 && canExpressInstall()) {\r\n showExpressInstall(att, par, replaceElemIdStr, callbackFn);\r\n }\r\n },\r\n\r\n removeSWF: function (objElemIdStr) {\r\n if (ua.w3) {\r\n removeSWF(objElemIdStr);\r\n }\r\n },\r\n\r\n createCSS: function (selStr, declStr, mediaStr, newStyleBoolean) {\r\n if (ua.w3) {\r\n createCSS(selStr, declStr, mediaStr, newStyleBoolean);\r\n }\r\n },\r\n\r\n addDomLoadEvent: addDomLoadEvent,\r\n\r\n addLoadEvent: addLoadEvent,\r\n\r\n getQueryParamValue: function (param) {\r\n var q = doc.location.search || doc.location.hash;\r\n if (q) {\r\n if (/\\?/.test(q)) { q = q.split(\"?\")[1]; } // strip question mark\r\n if (!param) {\r\n return urlEncodeIfNecessary(q);\r\n }\r\n var pairs = q.split(\"&\");\r\n for (var i = 0; i < pairs.length; i++) {\r\n if (pairs[i].substring(0, pairs[i].indexOf(\"=\")) == param) {\r\n return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf(\"=\") + 1)));\r\n }\r\n }\r\n }\r\n return \"\";\r\n },\r\n\r\n // For internal usage only\r\n expressInstallCallback: function () {\r\n if (isExpressInstallActive) {\r\n var obj = getElementById(EXPRESS_INSTALL_ID);\r\n if (obj && storedFbContent) {\r\n obj.parentNode.replaceChild(storedFbContent, obj);\r\n if (storedFbContentId) {\r\n setVisibility(storedFbContentId, true);\r\n if (ua.ie) { storedFbContent.style.display = \"block\"; }\r\n }\r\n if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }\r\n }\r\n isExpressInstallActive = false;\r\n }\r\n },\r\n\r\n version: \"2.3\"\r\n\r\n };\r\n}));\r\n","'use strict';\n\nvar InLine = require('./InLine');\nvar Wrapper = require('./Wrapper');\n\nfunction Ad(adJTree) {\n if (!(this instanceof Ad)) {\n return new Ad(adJTree);\n }\n this.initialize(adJTree);\n}\n\nAd.prototype.initialize = function(adJTree) {\n this.id = adJTree.attr('id');\n this.sequence = adJTree.attr('sequence');\n\n if(adJTree.inLine) {\n this.inLine = new InLine(adJTree.inLine);\n }\n\n if(adJTree.wrapper){\n this.wrapper = new Wrapper(adJTree.wrapper);\n }\n};\n\nmodule.exports = Ad;","'use strict';\n\nvar TrackingEvent = require('./TrackingEvent');\n\nvar utilities = require('../../utils/utilityFunctions');\n\nvar xml = require('../../utils/xml');\n\n\nfunction Companion(companionJTree) {\n if (!(this instanceof Companion)) {\n return new Companion(companionJTree);\n }\n\n //Required Elements\n this.creativeType = xml.attr(companionJTree.staticResource, 'creativeType');\n this.staticResource = xml.keyValue(companionJTree.staticResource);\n\n // Weird bug when the JXON tree is built it doesn't handle casing properly in this situation...\n var htmlResource = null;\n if (xml.keyValue(companionJTree.HTMLResource)) {\n htmlResource = xml.keyValue(companionJTree.HTMLResource);\n } else if (xml.keyValue(companionJTree.hTMLResource)) {\n htmlResource = xml.keyValue(companionJTree.hTMLResource);\n }\n this.htmlResource = htmlResource;\n\n var iframeResource = null;\n if (xml.keyValue(companionJTree.IFrameResource)) {\n iframeResource = xml.keyValue(companionJTree.IFrameResource);\n } else if (xml.keyValue(companionJTree.iFrameresource)) {\n iframeResource = xml.keyValue(companionJTree.iFrameresource);\n }\n this.iframeResource = iframeResource;\n\n //Optional fields\n this.id = xml.attr(companionJTree, 'id');\n this.width = xml.attr(companionJTree, 'width');\n this.height = xml.attr(companionJTree, 'height');\n this.expandedWidth = xml.attr(companionJTree, 'expandedWidth');\n this.expandedHeight = xml.attr(companionJTree, 'expandedHeight');\n this.scalable = xml.attr(companionJTree, 'scalable');\n this.maintainAspectRatio = xml.attr(companionJTree, 'maintainAspectRatio');\n this.minSuggestedDuration = xml.attr(companionJTree, 'minSuggestedDuration');\n this.apiFramework = xml.attr(companionJTree, 'apiFramework');\n this.companionClickThrough = xml.keyValue(companionJTree.companionClickThrough);\n this.trackingEvents = parseTrackingEvents(companionJTree.trackingEvents && companionJTree.trackingEvents.tracking);\n\n /*** Local functions ***/\n function parseTrackingEvents(trackingEvents) {\n var trackings = [];\n if (utilities.isDefined(trackingEvents)) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingData) {\n trackings.push(new TrackingEvent(trackingData));\n });\n }\n return trackings;\n }\n}\n\nmodule.exports = Companion;","'use strict';\n\nvar Linear = require('./Linear');\nvar Companion = require('./Companion');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction Creative(creativeJTree) {\n if(!(this instanceof Creative)) {\n return new Creative(creativeJTree);\n }\n\n this.id = creativeJTree.attr('id');\n this.sequence = creativeJTree.attr('sequence');\n this.adId = creativeJTree.attr('adId');\n this.apiFramework = creativeJTree.attr('apiFramework');\n\n if(creativeJTree.linear) {\n this.linear = new Linear(creativeJTree.linear);\n }\n\n if (creativeJTree.companionAds) {\n var companions = [];\n var companionAds = creativeJTree.companionAds && creativeJTree.companionAds.companion;\n if (utilities.isDefined(companionAds)) {\n companionAds = utilities.isArray(companionAds) ? companionAds : [companionAds];\n companionAds.forEach(function (companionData) {\n companions.push(new Companion(companionData));\n });\n }\n this.companionAds = companions;\n }\n}\n\n/**\n * Returns true if the browser supports at the creative.\n */\nCreative.prototype.isSupported = function(){\n if(this.linear) {\n return this.linear.isSupported();\n }\n\n return true;\n};\n\nCreative.parseCreatives = function parseCreatives(creativesJTree) {\n var creatives = [];\n var creativesData;\n if (utilities.isDefined(creativesJTree) && utilities.isDefined(creativesJTree.creative)) {\n creativesData = utilities.isArray(creativesJTree.creative) ? creativesJTree.creative : [creativesJTree.creative];\n creativesData.forEach(function (creative) {\n creatives.push(new Creative(creative));\n });\n }\n return creatives;\n};\n\nmodule.exports = Creative;\n","'use strict';\n\nvar vastUtil = require('./vastUtil');\nvar Creative = require('./Creative');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction InLine(inlineJTree) {\n if (!(this instanceof InLine)) {\n return new InLine(inlineJTree);\n }\n\n //Required Fields\n this.adTitle = xml.keyValue(inlineJTree.adTitle);\n this.adSystem = xml.keyValue(inlineJTree.adSystem);\n this.impressions = vastUtil.parseImpressions(inlineJTree.impression);\n this.creatives = Creative.parseCreatives(inlineJTree.creatives);\n\n //Optional Fields\n this.description = xml.keyValue(inlineJTree.description);\n this.advertiser = xml.keyValue(inlineJTree.advertiser);\n this.surveys = parseSurveys(inlineJTree.survey);\n this.error = xml.keyValue(inlineJTree.error);\n this.pricing = xml.keyValue(inlineJTree.pricing);\n this.extensions = inlineJTree.extensions;\n\n /*** Local Functions ***/\n function parseSurveys(inlineSurveys) {\n if (inlineSurveys) {\n return utilities.transformArray(utilities.isArray(inlineSurveys) ? inlineSurveys : [inlineSurveys], function (survey) {\n if(utilities.isNotEmptyString(survey.keyValue)){\n return {\n uri: survey.keyValue,\n type: survey.attr('type')\n };\n }\n\n return undefined;\n });\n }\n return [];\n }\n}\n\n\n/**\n * Returns true if the browser supports all the creatives.\n */\nInLine.prototype.isSupported = function(){\n var i,len;\n\n if(this.creatives.length === 0) {\n return false;\n }\n\n for(i = 0, len = this.creatives.length; i< len; i+=1){\n if(!this.creatives[i].isSupported()){\n return false;\n }\n }\n return true;\n};\n\nmodule.exports = InLine;\n","'use strict';\n\nvar TrackingEvent = require('./TrackingEvent');\nvar MediaFile = require('./MediaFile');\nvar VideoClicks = require('./VideoClicks');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar parsers = require('./parsers');\n\nvar xml = require('../../utils/xml');\n\n\nfunction Linear(linearJTree) {\n if (!(this instanceof Linear)) {\n return new Linear(linearJTree);\n }\n\n //Required Elements\n this.duration = parsers.duration(xml.keyValue(linearJTree.duration));\n this.mediaFiles = parseMediaFiles(linearJTree.mediaFiles && linearJTree.mediaFiles.mediaFile);\n\n //Optional fields\n this.trackingEvents = parseTrackingEvents(linearJTree.trackingEvents && linearJTree.trackingEvents.tracking, this.duration);\n this.skipoffset = parsers.offset(xml.attr(linearJTree, 'skipoffset'), this.duration);\n\n if (linearJTree.videoClicks) {\n this.videoClicks = new VideoClicks(linearJTree.videoClicks);\n }\n\n if(linearJTree.adParameters) {\n this.adParameters = xml.keyValue(linearJTree.adParameters);\n\n if(xml.attr(linearJTree.adParameters, 'xmlEncoded')){\n this.adParameters = xml.decode(this.adParameters);\n }\n }\n\n /*** Local functions ***/\n function parseTrackingEvents(trackingEvents, duration) {\n var trackings = [];\n if (utilities.isDefined(trackingEvents)) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingData) {\n trackings.push(new TrackingEvent(trackingData, duration));\n });\n }\n return trackings;\n }\n\n function parseMediaFiles(mediaFilesJxonTree) {\n var mediaFiles = [];\n if (utilities.isDefined(mediaFilesJxonTree)) {\n mediaFilesJxonTree = utilities.isArray(mediaFilesJxonTree) ? mediaFilesJxonTree : [mediaFilesJxonTree];\n\n mediaFilesJxonTree.forEach(function (mfData) {\n mediaFiles.push(new MediaFile(mfData));\n });\n }\n return mediaFiles;\n }\n}\n\n/**\n * Must return true if at least one of the MediaFiles' type is supported\n */\nLinear.prototype.isSupported = function () {\n var i, len;\n for(i=0, len=this.mediaFiles.length; i 0) {\n getAd(waterfallAds.shift(),[], waterfallHandler);\n } else {\n callback(error, adChain);\n }\n } else {\n callback(null, adChain);\n }\n }\n });\n\n /*** Local functions ***/\n function getAdWaterfall(adTagUrl, callback) {\n var requestVastXML = that._requestVASTXml.bind(that, adTagUrl);\n async.waterfall([\n requestVastXML,\n buildVastWaterfall\n ], callback);\n }\n\n function buildVastWaterfall(xmlStr, callback) {\n var vastTree;\n try {\n vastTree = xml.toJXONTree(xmlStr);\n\n if(utilities.isArray(vastTree.ad)) {\n vastTree.ads = vastTree.ad;\n } else if(vastTree.ad){\n vastTree.ads = [vastTree.ad];\n } else {\n vastTree.ads = [];\n }\n callback(validateVASTTree(vastTree), vastTree);\n\n } catch (e) {\n callback(new VASTError(\"on VASTClient.getVASTAd.buildVastWaterfall, error parsing xml\", 100), null);\n }\n }\n\n function validateVASTTree(vastTree) {\n var vastVersion = xml.attr(vastTree, 'version');\n\n if (!vastTree.ad) {\n return new VASTError('on VASTClient.getVASTAd.validateVASTTree, no Ad in VAST tree', 303);\n }\n\n if (vastVersion && (vastVersion != 3 && vastVersion != 2)) {\n return new VASTError('on VASTClient.getVASTAd.validateVASTTree, not supported VAST version \"' + vastVersion + '\"', 102);\n }\n\n return null;\n }\n\n function getAd(adTagUrl, adChain, callback) {\n if (adChain.length >= that.WRAPPER_LIMIT) {\n return callback(new VASTError(\"on VASTClient.getVASTAd.getAd, players wrapper limit reached (the limit is \" + that.WRAPPER_LIMIT + \")\", 302), adChain);\n }\n\n async.waterfall([\n function (next) {\n if (utilities.isString(adTagUrl)) {\n requestVASTAd(adTagUrl, next);\n } else {\n next(null, adTagUrl);\n }\n },\n buildAd\n ], function (error, ad) {\n if (ad) {\n adChain.push(ad);\n }\n\n if (error) {\n return callback(error, adChain);\n }\n\n if (ad.wrapper) {\n return getAd(ad.wrapper.VASTAdTagURI, adChain, callback);\n }\n\n return callback(null, adChain);\n });\n }\n\n function buildAd(adJxonTree, callback) {\n try {\n var ad = new Ad(adJxonTree);\n callback(validateAd(ad), ad);\n } catch (e) {\n callback(new VASTError('on VASTClient.getVASTAd.buildAd, error parsing xml', 100), null);\n }\n }\n\n function validateAd(ad) {\n var wrapper = ad.wrapper;\n var inLine = ad.inLine;\n var errMsgPrefix = 'on VASTClient.getVASTAd.validateAd, ';\n\n if (inLine && wrapper) {\n return new VASTError(errMsgPrefix +\"InLine and Wrapper both found on the same Ad\", 101);\n }\n\n if (!inLine && !wrapper) {\n return new VASTError(errMsgPrefix + \"nor wrapper nor inline elements found on the Ad\", 101);\n }\n\n if (inLine && !inLine.isSupported()) {\n return new VASTError(errMsgPrefix + \"could not find MediaFile that is supported by this video player\", 403);\n }\n\n if (wrapper && !wrapper.VASTAdTagURI) {\n return new VASTError(errMsgPrefix + \"missing 'VASTAdTagURI' in wrapper\", 101);\n }\n\n return null;\n }\n\n function requestVASTAd(adTagUrl, callback) {\n that._requestVASTXml(adTagUrl, function (error, xmlStr) {\n if (error) {\n return callback(error);\n }\n try {\n var vastTree = xml.toJXONTree(xmlStr);\n callback(validateVASTTree(vastTree), vastTree.ad);\n } catch (e) {\n callback(new VASTError(\"on VASTClient.getVASTAd.requestVASTAd, error parsing xml\", 100));\n }\n });\n }\n};\n\nVASTClient.prototype._requestVASTXml = function requestVASTXml(adTagUrl, callback) {\n try {\n if (utilities.isFunction(adTagUrl)) {\n adTagUrl(requestHandler);\n } else {\n http.get(adTagUrl, requestHandler, {\n withCredentials: true\n });\n }\n } catch (e) {\n callback(e);\n }\n\n /*** Local functions ***/\n function requestHandler(error, response, status) {\n if (error) {\n var errMsg = utilities.isDefined(status) ?\n \"on VASTClient.requestVastXML, HTTP request error with status '\" + status + \"'\" :\n \"on VASTClient.requestVastXML, Error getting the the VAST XML with he passed adTagXML fn\";\n return callback(new VASTError(errMsg, 301), null);\n }\n\n callback(null, response);\n }\n};\n\nVASTClient.prototype._buildVASTResponse = function buildVASTResponse(adsChain) {\n var response = new VASTResponse();\n addAdsToResponse(response, adsChain);\n validateResponse(response);\n\n return response;\n\n //*** Local function ****\n function addAdsToResponse(response, ads) {\n ads.forEach(function (ad) {\n response.addAd(ad);\n });\n }\n\n function validateResponse(response) {\n var progressEvents = response.trackingEvents.progress;\n\n if (!response.hasLinear()) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, Received an Ad type that is not supported\", 200);\n }\n\n if (response.duration === undefined) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, Missing duration field in VAST response\", 101);\n }\n\n if (progressEvents) {\n progressEvents.forEach(function (progressEvent) {\n if (!utilities.isNumber(progressEvent.offset)) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, missing or wrong offset attribute on progress tracking event\", 101);\n }\n });\n }\n }\n};\n\nVASTClient.prototype._trackError = function (error, adChain) {\n if (!utilities.isArray(adChain) || adChain.length === 0) { //There is nothing to track\n return;\n }\n\n var errorURLMacros = [];\n adChain.forEach(addErrorUrlMacros);\n vastUtil.track(errorURLMacros, {ERRORCODE: error.code || 900}); //900 <== Undefined error\n\n /*** Local functions ***/\n function addErrorUrlMacros(ad) {\n if (ad.wrapper && ad.wrapper.error) {\n errorURLMacros.push(ad.wrapper.error);\n }\n\n if (ad.inLine && ad.inLine.error) {\n errorURLMacros.push(ad.inLine.error);\n }\n }\n};\n\nmodule.exports = VASTClient;\n","'use strict';\n\nfunction VASTError(message, code) {\n this.message = 'VAST Error: ' + (message || '');\n if (code) {\n this.code = code;\n }\n}\n\nVASTError.prototype = new Error();\nVASTError.prototype.name = \"VAST Error\";\n\nmodule.exports = VASTError;","'use strict';\n\n/**\n * Inner helper class that deals with the logic of the individual steps needed to setup an ad in the player.\n *\n * @param player {object} instance of the player that will play the ad. It assumes that the videojs-contrib-ads plugin\n * has been initialized when you use its utility functions.\n *\n * @constructor\n */\n\nvar VASTResponse = require('./VASTResponse');\nvar VASTError = require('./VASTError');\nvar VASTTracker = require('./VASTTracker');\nvar vastUtil = require('./vastUtil');\n\nvar async = require('../../utils/async');\nvar dom = require('../../utils/dom');\nvar playerUtils = require('../../utils/playerUtils');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VASTIntegrator(player) {\n if (!(this instanceof VASTIntegrator)) {\n return new VASTIntegrator(player);\n }\n\n this.player = player;\n}\n\nVASTIntegrator.prototype.playAd = function playAd(vastResponse, callback) {\n var that = this;\n callback = callback || utilities.noop;\n\n if (!(vastResponse instanceof VASTResponse)) {\n return callback(new VASTError('On VASTIntegrator, missing required VASTResponse'));\n }\n\n async.waterfall([\n function (next) {\n next(null, vastResponse);\n },\n this._selectAdSource.bind(this),\n this._createVASTTracker.bind(this),\n this._addClickThrough.bind(this),\n this._addSkipButton.bind(this),\n this._setupEvents.bind(this),\n this._playSelectedAd.bind(this)\n ], function (error, response) {\n if (error && response) {\n that._trackError(error, response);\n }\n callback(error, response);\n });\n\n this._adUnit = {\n _src: null,\n type: 'VAST',\n pauseAd: function () {\n that.player.pause(true);\n },\n\n resumeAd: function () {\n that.player.play(true);\n },\n\n isPaused: function () {\n return that.player.paused(true);\n },\n\n getSrc: function () {\n return this._src;\n }\n };\n\n return this._adUnit;\n};\n\nVASTIntegrator.prototype._selectAdSource = function selectAdSource(response, callback) {\n var source;\n\n var playerWidth = dom.getDimension(this.player.el()).width;\n response.mediaFiles.sort(function compareTo(a, b) {\n var deltaA = Math.abs(playerWidth - a.width);\n var deltaB = Math.abs(playerWidth - b.width);\n return deltaA - deltaB;\n });\n\n source = this.player.selectSource(response.mediaFiles).source;\n\n if (source) {\n if (this._adUnit) {\n this._adUnit._src = source;\n }\n return callback(null, source, response);\n }\n\n // code 403 <== Couldn't find MediaFile that is supported by this video player\n callback(new VASTError(\"Could not find Ad mediafile supported by this player\", 403), response);\n};\n\nVASTIntegrator.prototype._createVASTTracker = function createVASTTracker(adMediaFile, response, callback) {\n try {\n callback(null, adMediaFile, new VASTTracker(adMediaFile.src, response), response);\n } catch (e) {\n callback(e, response);\n }\n};\n\nVASTIntegrator.prototype._setupEvents = function setupEvents(adMediaFile, tracker, response, callback) {\n var previouslyMuted;\n var player = this.player;\n player.on('fullscreenchange', trackFullscreenChange);\n player.on('vast.adStart', trackImpressions);\n player.on('pause', trackPause);\n player.on('timeupdate', trackProgress);\n player.on('volumechange', trackVolumeChange);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], unbindEvents);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel', 'vast.adSkip'], function(evt){\n if(evt.type === 'vast.adEnd'){\n tracker.trackComplete();\n }\n });\n\n return callback(null, adMediaFile, response);\n\n /*** Local Functions ***/\n function unbindEvents() {\n player.off('fullscreenchange', trackFullscreenChange);\n player.off('vast.adStart', trackImpressions);\n player.off('pause', trackPause);\n player.off('timeupdate', trackProgress);\n player.off('volumechange', trackVolumeChange);\n }\n\n function trackFullscreenChange() {\n if (player.isFullscreen()) {\n tracker.trackFullscreen();\n } else {\n tracker.trackExitFullscreen();\n }\n }\n\n function trackPause() {\n //NOTE: whenever a video ends the video Element triggers a 'pause' event before the 'ended' event.\n // We should not track this pause event because it makes the VAST tracking confusing again we use a\n // Threshold of 2 seconds to prevent false positives on IOS.\n if (Math.abs(player.duration() - player.currentTime()) < 2) {\n return;\n }\n\n tracker.trackPause();\n playerUtils.once(player, ['play', 'vast.adEnd', 'vast.adsCancel'], function (evt) {\n if(evt.type === 'play'){\n tracker.trackResume();\n }\n });\n }\n\n function trackProgress() {\n var currentTimeInMs = player.currentTime() * 1000;\n tracker.trackProgress(currentTimeInMs);\n }\n\n function trackImpressions() {\n tracker.trackImpressions();\n tracker.trackCreativeView();\n }\n\n function trackVolumeChange() {\n var muted = player.muted();\n if (muted) {\n tracker.trackMute();\n } else if (previouslyMuted) {\n tracker.trackUnmute();\n }\n previouslyMuted = muted;\n }\n};\n\nVASTIntegrator.prototype._addSkipButton = function addSkipButton(source, tracker, response, callback) {\n var skipOffsetInSec;\n var that = this;\n\n if (utilities.isNumber(response.skipoffset)) {\n skipOffsetInSec = response.skipoffset / 1000;\n addSkipButtonToPlayer(this.player, skipOffsetInSec);\n }\n callback(null, source, tracker, response);\n\n /*** Local function ***/\n function addSkipButtonToPlayer(player, skipOffset) {\n var skipButton = createSkipButton(player);\n var updateSkipButton = updateSkipButtonState.bind(that, skipButton, skipOffset, player);\n\n player.el().appendChild(skipButton);\n player.on('timeupdate', updateSkipButton);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeSkipButton);\n\n function removeSkipButton() {\n player.off('timeupdate', updateSkipButton);\n dom.remove(skipButton);\n }\n }\n\n function createSkipButton(player) {\n var skipButton = window.document.createElement(\"div\");\n dom.addClass(skipButton, \"vast-skip-button\");\n\n skipButton.onclick = function (e) {\n if (dom.hasClass(skipButton, 'enabled')) {\n tracker.trackSkip();\n player.trigger('vast.adSkip');\n }\n\n //We prevent event propagation to avoid problems with the clickThrough and so on\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n } else {\n return false;\n }\n };\n\n return skipButton;\n }\n\n function updateSkipButtonState(skipButton, skipOffset, player) {\n var timeLeft = Math.ceil(skipOffset - player.currentTime());\n if (timeLeft > 0) {\n skipButton.innerHTML = \"Skip in \" + utilities.toFixedDigits(timeLeft, 2) + \"...\";\n } else {\n if (!dom.hasClass(skipButton, 'enabled')) {\n dom.addClass(skipButton, 'enabled');\n skipButton.innerHTML = \"Skip ad\";\n }\n }\n }\n};\n\nVASTIntegrator.prototype._addClickThrough = function addClickThrough(mediaFile, tracker, response, callback) {\n var player = this.player;\n var blocker = createClickThroughBlocker(player, tracker, response);\n var updateBlocker = updateBlockerURL.bind(this, blocker, response, player);\n\n player.el().insertBefore(blocker, player.controlBar.el());\n player.on('timeupdate', updateBlocker);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeBlocker);\n\n return callback(null, mediaFile, tracker, response);\n\n /*** Local Functions ***/\n\n function createClickThroughBlocker(player, tracker, response) {\n var blocker = window.document.createElement(\"a\");\n var clickThroughMacro = response.clickThrough;\n\n dom.addClass(blocker, 'vast-blocker');\n blocker.href = generateClickThroughURL(clickThroughMacro, player);\n\n if (utilities.isString(clickThroughMacro)) {\n blocker.target = \"_blank\";\n }\n\n blocker.onclick = function (e) {\n if (player.paused()) {\n player.play();\n\n //We prevent event propagation to avoid problems with the player's normal pause mechanism\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n }\n return false;\n }\n\n player.pause();\n tracker.trackClick();\n };\n\n return blocker;\n }\n\n function updateBlockerURL(blocker, response, player) {\n blocker.href = generateClickThroughURL(response.clickThrough, player);\n }\n\n function generateClickThroughURL(clickThroughMacro, player) {\n var variables = {\n ASSETURI: mediaFile.src,\n CONTENTPLAYHEAD: vastUtil.formatProgress(player.currentTime() * 1000)\n };\n\n return clickThroughMacro ? vastUtil.parseURLMacro(clickThroughMacro, variables) : '#';\n }\n\n function removeBlocker() {\n player.off('timeupdate', updateBlocker);\n dom.remove(blocker);\n }\n};\n\nVASTIntegrator.prototype._playSelectedAd = function playSelectedAd(source, response, callback) {\n var player = this.player;\n\n player.preload(\"auto\"); //without preload=auto the durationchange event is never fired\n player.src(source);\n\n playerUtils.once(player, ['durationchange', 'error', 'vast.adsCancel'], function (evt) {\n if (evt.type === 'durationchange') {\n playAd();\n } else if(evt.type === 'error') {\n callback(new VASTError(\"on VASTIntegrator, Player is unable to play the Ad\", 400), response);\n }\n //NOTE: If the ads get canceled we do nothing/\n });\n\n /**** local functions ******/\n function playAd() {\n\n playerUtils.once(player, ['playing', 'vast.adsCancel'], function (evt) {\n if(evt.type === 'vast.adsCancel'){\n return;\n }\n\n player.trigger('vast.adStart');\n\n player.on('ended', proceed);\n player.on('vast.adsCancel', proceed);\n player.on('vast.adSkip', proceed);\n\n function proceed(evt) {\n\n if(evt.type === 'ended' && (player.duration() - player.currentTime()) > 3 ) {\n // Ignore ended event if the Ad time was not 'near' the end\n // avoids issues where IOS controls could skip the Ad\n return;\n }\n\n player.off('ended', proceed);\n player.off('vast.adsCancel', proceed);\n player.off('vast.adSkip', proceed);\n\n //NOTE: if the ads get cancel we do nothing apart removing the listners\n if(evt.type === 'ended' || evt.type === 'vast.adSkip'){\n callback(null, response);\n }\n }\n });\n\n player.play();\n }\n};\n\nVASTIntegrator.prototype._trackError = function trackError(error, response) {\n vastUtil.track(response.errorURLMacros, {ERRORCODE: error.code || 900});\n};\n\nmodule.exports = VASTIntegrator;","'use strict';\n\nvar Ad = require('./Ad');\nvar VideoClicks = require('./VideoClicks');\nvar Linear = require('./Linear');\nvar InLine = require('./InLine');\nvar Wrapper = require('./Wrapper');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nwindow.InLine__A = InLine;\nfunction VASTResponse() {\n if (!(this instanceof VASTResponse)) {\n return new VASTResponse();\n }\n\n this._linearAdded = false;\n this.ads = [];\n this.errorURLMacros = [];\n this.impressions = [];\n this.clickTrackings = [];\n this.customClicks = [];\n this.trackingEvents = {};\n this.mediaFiles = [];\n this.clickThrough = undefined;\n this.adTitle = '';\n this.duration = undefined;\n this.skipoffset = undefined;\n}\n\nVASTResponse.prototype.addAd = function (ad) {\n var inLine, wrapper;\n if (ad instanceof Ad) {\n inLine = ad.inLine;\n wrapper = ad.wrapper;\n\n this.ads.push(ad);\n\n if (inLine) {\n this._addInLine(inLine);\n }\n\n if (wrapper) {\n this._addWrapper(wrapper);\n }\n }\n};\n\nVASTResponse.prototype._addErrorTrackUrl = function (error) {\n var errorURL = error instanceof xml.JXONTree ? xml.keyValue(error) : error;\n if (errorURL) {\n this.errorURLMacros.push(errorURL);\n }\n};\n\nVASTResponse.prototype._addImpressions = function (impressions) {\n utilities.isArray(impressions) && appendToArray(this.impressions, impressions);\n};\n\nVASTResponse.prototype._addClickThrough = function (clickThrough) {\n if (utilities.isNotEmptyString(clickThrough)) {\n this.clickThrough = clickThrough;\n }\n};\n\nVASTResponse.prototype._addClickTrackings = function (clickTrackings) {\n utilities.isArray(clickTrackings) && appendToArray(this.clickTrackings, clickTrackings);\n};\n\nVASTResponse.prototype._addCustomClicks = function (customClicks) {\n utilities.isArray(customClicks) && appendToArray(this.customClicks, customClicks);\n};\n\nVASTResponse.prototype._addTrackingEvents = function (trackingEvents) {\n var eventsMap = this.trackingEvents;\n\n if (trackingEvents) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingEvent) {\n if (!eventsMap[trackingEvent.name]) {\n eventsMap[trackingEvent.name] = [];\n }\n eventsMap[trackingEvent.name].push(trackingEvent);\n });\n }\n};\n\nVASTResponse.prototype._addTitle = function (title) {\n if (utilities.isNotEmptyString(title)) {\n this.adTitle = title;\n }\n};\n\nVASTResponse.prototype._addDuration = function (duration) {\n if (utilities.isNumber(duration)) {\n this.duration = duration;\n }\n};\n\nVASTResponse.prototype._addVideoClicks = function (videoClicks) {\n if (videoClicks instanceof VideoClicks) {\n this._addClickThrough(videoClicks.clickThrough);\n this._addClickTrackings(videoClicks.clickTrackings);\n this._addCustomClicks(videoClicks.customClicks);\n }\n};\n\nVASTResponse.prototype._addMediaFiles = function (mediaFiles) {\n utilities.isArray(mediaFiles) && appendToArray(this.mediaFiles, mediaFiles);\n};\n\nVASTResponse.prototype._addSkipoffset = function (offset) {\n if (offset) {\n this.skipoffset = offset;\n }\n};\n\nVASTResponse.prototype._addAdParameters = function (adParameters) {\n if (adParameters) {\n this.adParameters = adParameters;\n }\n};\n\nVASTResponse.prototype._addLinear = function (linear) {\n if (linear instanceof Linear) {\n this._addDuration(linear.duration);\n this._addTrackingEvents(linear.trackingEvents);\n this._addVideoClicks(linear.videoClicks);\n this._addMediaFiles(linear.mediaFiles);\n this._addSkipoffset(linear.skipoffset);\n this._addAdParameters(linear.adParameters);\n this._linearAdded = true;\n }\n};\n\nVASTResponse.prototype._addInLine = function (inLine) {\n var that = this;\n\n if (inLine instanceof InLine) {\n this._addTitle(inLine.adTitle);\n this._addErrorTrackUrl(inLine.error);\n this._addImpressions(inLine.impressions);\n\n inLine.creatives.forEach(function (creative) {\n if (creative.linear) {\n that._addLinear(creative.linear);\n }\n });\n }\n};\n\nVASTResponse.prototype._addWrapper = function (wrapper) {\n var that = this;\n\n if (wrapper instanceof Wrapper) {\n this._addErrorTrackUrl(wrapper.error);\n this._addImpressions(wrapper.impressions);\n\n wrapper.creatives.forEach(function (creative) {\n var linear = creative.linear;\n if (linear) {\n that._addVideoClicks(linear.videoClicks);\n that.clickThrough = undefined;//We ensure that no clickThrough has been added\n that._addTrackingEvents(linear.trackingEvents);\n }\n });\n }\n};\n\nVASTResponse.prototype.hasLinear = function(){\n return this._linearAdded;\n};\n\nfunction appendToArray(array, items) {\n items.forEach(function (item) {\n array.push(item);\n });\n}\n\nmodule.exports = VASTResponse;\n\n","'use strict';\n\nvar VASTError = require('./VASTError');\nvar VASTResponse = require('./VASTResponse');\nvar vastUtil = require('./vastUtil');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VASTTracker(assetURI, vastResponse) {\n if (!(this instanceof VASTTracker)) {\n return new VASTTracker(assetURI, vastResponse);\n }\n\n this.sanityCheck(assetURI, vastResponse);\n this.initialize(assetURI, vastResponse);\n\n}\n\nVASTTracker.prototype.initialize = function(assetURI, vastResponse) {\n this.response = vastResponse;\n this.assetURI = assetURI;\n this.progress = 0;\n this.quartiles = {\n firstQuartile: {tracked: false, time: Math.round(25 * vastResponse.duration) / 100},\n midpoint: {tracked: false, time: Math.round(50 * vastResponse.duration) / 100},\n thirdQuartile: {tracked: false, time: Math.round(75 * vastResponse.duration) / 100}\n };\n};\n\nVASTTracker.prototype.sanityCheck = function(assetURI, vastResponse) {\n if (!utilities.isString(assetURI) || utilities.isEmptyString(assetURI)) {\n throw new VASTError('on VASTTracker constructor, missing required the URI of the ad asset being played');\n }\n\n if (!(vastResponse instanceof VASTResponse)) {\n throw new VASTError('on VASTTracker constructor, missing required VAST response');\n }\n};\n\nVASTTracker.prototype.trackURLs = function trackURLs(urls, variables) {\n if (utilities.isArray(urls) && urls.length > 0) {\n variables = utilities.extend({\n ASSETURI: this.assetURI,\n CONTENTPLAYHEAD: vastUtil.formatProgress(this.progress)\n }, variables || {});\n\n vastUtil.track(urls, variables);\n }\n};\n\nVASTTracker.prototype.trackEvent = function trackEvent(eventName, trackOnce) {\n this.trackURLs(getEventUris(this.response.trackingEvents[eventName]));\n if (trackOnce) {\n this.response.trackingEvents[eventName] = undefined;\n }\n\n /*** Local function ***/\n function getEventUris(trackingEvents) {\n var uris;\n\n if (trackingEvents) {\n uris = [];\n trackingEvents.forEach(function (event) {\n uris.push(event.uri);\n });\n }\n return uris;\n }\n};\n\nVASTTracker.prototype.trackProgress = function trackProgress(newProgressInMs) {\n var that = this;\n var events = [];\n var ONCE = true;\n var ALWAYS = false;\n var trackingEvents = this.response.trackingEvents;\n\n if (utilities.isNumber(newProgressInMs)) {\n addTrackEvent('start', ONCE, newProgressInMs > 0);\n addTrackEvent('rewind', ALWAYS, hasRewound(this.progress, newProgressInMs));\n addQuartileEvents(newProgressInMs);\n trackProgressEvents(newProgressInMs);\n trackEvents();\n this.progress = newProgressInMs;\n }\n\n /*** Local function ***/\n function hasRewound(currentProgress, newProgress) {\n var REWIND_THRESHOLD = 3000; //IOS video clock is very unreliable and we need a 3 seconds threshold to ensure that there was a rewind an that it was on purpose.\n return currentProgress > newProgressInMs && Math.abs(newProgress - currentProgress) > REWIND_THRESHOLD;\n }\n\n function addTrackEvent(eventName, trackOnce, canBeAdded) {\n if (trackingEvents[eventName] && canBeAdded) {\n events.push({\n name: eventName,\n trackOnce: !!trackOnce\n });\n }\n }\n\n function addQuartileEvents(progress) {\n var quartiles = that.quartiles;\n var firstQuartile = that.quartiles.firstQuartile;\n var midpoint = that.quartiles.midpoint;\n var thirdQuartile = that.quartiles.thirdQuartile;\n\n if (!firstQuartile.tracked) {\n trackQuartile('firstQuartile', progress);\n } else if (!midpoint.tracked) {\n trackQuartile('midpoint', progress);\n } else if (!thirdQuartile.tracked){\n trackQuartile('thirdQuartile', progress);\n }\n\n /*** Local function ***/\n function trackQuartile(quartileName, progress){\n var quartile = quartiles[quartileName];\n if(canBeTracked(quartile, progress)){\n quartile.tracked = true;\n addTrackEvent(quartileName, ONCE, true);\n }\n }\n }\n\n function canBeTracked(quartile, progress) {\n var quartileTime = quartile.time;\n //We only fire the quartile event if the progress is bigger than the quartile time by 5 seconds at most.\n return progress >= quartileTime && progress <= (quartileTime + 5000);\n }\n\n function trackProgressEvents(progress) {\n if (!utilities.isArray(trackingEvents.progress)) {\n return; //Nothing to track\n }\n\n var pendingProgressEvts = [];\n\n trackingEvents.progress.forEach(function (evt) {\n if (evt.offset <= progress) {\n that.trackURLs([evt.uri]);\n } else {\n pendingProgressEvts.push(evt);\n }\n });\n trackingEvents.progress = pendingProgressEvts;\n }\n\n function trackEvents() {\n events.forEach(function (event) {\n that.trackEvent(event.name, event.trackOnce);\n });\n }\n};\n\n[\n 'rewind',\n 'fullscreen',\n 'exitFullscreen',\n 'pause',\n 'resume',\n 'mute',\n 'unmute',\n 'acceptInvitation',\n 'acceptInvitationLinear',\n 'collapse',\n 'expand'\n].forEach(function (eventName) {\n VASTTracker.prototype['track' + utilities.capitalize(eventName)] = function () {\n this.trackEvent(eventName);\n };\n });\n\n[\n 'start',\n 'skip',\n 'close',\n 'closeLinear'\n].forEach(function (eventName) {\n VASTTracker.prototype['track' + utilities.capitalize(eventName)] = function () {\n this.trackEvent(eventName, true);\n };\n });\n\n[\n 'firstQuartile',\n 'midpoint',\n 'thirdQuartile'\n].forEach(function (quartile) {\n VASTTracker.prototype['track' + utilities.capitalize(quartile)] = function () {\n this.quartiles[quartile].tracked = true;\n this.trackEvent(quartile, true);\n };\n });\n\nVASTTracker.prototype.trackComplete = function () {\n if(this.quartiles.thirdQuartile.tracked){\n this.trackEvent('complete', true);\n }\n};\n\nVASTTracker.prototype.trackErrorWithCode = function trackErrorWithCode(errorcode) {\n if (utilities.isNumber(errorcode)) {\n this.trackURLs(this.response.errorURLMacros, {ERRORCODE: errorcode});\n }\n};\n\nVASTTracker.prototype.trackImpressions = function trackImpressions() {\n this.trackURLs(this.response.impressions);\n};\n\nVASTTracker.prototype.trackCreativeView = function trackCreativeView() {\n this.trackEvent('creativeView');\n};\n\nVASTTracker.prototype.trackClick = function trackClick() {\n this.trackURLs(this.response.clickTrackings);\n};\n\nmodule.exports = VASTTracker;\n","'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction VideoClicks(videoClickJTree) {\n if (!(this instanceof VideoClicks)) {\n return new VideoClicks(videoClickJTree);\n }\n\n this.clickThrough = xml.keyValue(videoClickJTree.clickThrough);\n this.clickTrackings = parseClickTrackings(videoClickJTree.clickTracking);\n this.customClicks = parseClickTrackings(videoClickJTree.customClick);\n\n /*** Local functions ***/\n function parseClickTrackings(trackingData) {\n var clickTrackings = [];\n if (trackingData) {\n trackingData = utilities.isArray(trackingData) ? trackingData : [trackingData];\n trackingData.forEach(function (clickTrackingData) {\n clickTrackings.push(xml.keyValue(clickTrackingData));\n });\n }\n return clickTrackings;\n }\n}\n\nmodule.exports = VideoClicks;","'use strict';\n\nvar vastUtil = require('./vastUtil');\nvar Creative = require('./Creative');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction Wrapper(wrapperJTree) {\n if(!(this instanceof Wrapper)) {\n return new Wrapper(wrapperJTree);\n }\n\n //Required elements\n this.adSystem = xml.keyValue(wrapperJTree.adSystem);\n this.impressions = vastUtil.parseImpressions(wrapperJTree.impression);\n this.VASTAdTagURI = xml.keyValue(wrapperJTree.vASTAdTagURI);\n\n //Optional elements\n this.creatives = Creative.parseCreatives(wrapperJTree.creatives);\n this.error = xml.keyValue(wrapperJTree.error);\n this.extensions = wrapperJTree.extensions;\n\n //Optional attrs\n this.followAdditionalWrappers = utilities.isDefined(xml.attr(wrapperJTree, 'followAdditionalWrappers'))? xml.attr(wrapperJTree, 'followAdditionalWrappers'): true;\n this.allowMultipleAds = xml.attr(wrapperJTree, 'allowMultipleAds');\n this.fallbackOnNoAd = xml.attr(wrapperJTree, 'fallbackOnNoAd');\n}\n\nmodule.exports = Wrapper;\n","'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\n\nvar durationRegex = /(\\d\\d):(\\d\\d):(\\d\\d)(\\.(\\d\\d\\d))?/;\n\nvar parsers = {\n\n duration: function parseDuration(durationStr) {\n\n var match, durationInMs;\n\n if (utilities.isString(durationStr)) {\n match = durationStr.match(durationRegex);\n if (match) {\n durationInMs = parseHoursToMs(match[1]) + parseMinToMs(match[2]) + parseSecToMs(match[3]) + parseInt(match[5] || 0);\n }\n }\n\n return isNaN(durationInMs) ? null : durationInMs;\n\n /*** local functions ***/\n function parseHoursToMs(hourStr) {\n return parseInt(hourStr, 10) * 60 * 60 * 1000;\n }\n\n function parseMinToMs(minStr) {\n return parseInt(minStr, 10) * 60 * 1000;\n }\n\n function parseSecToMs(secStr) {\n return parseInt(secStr, 10) * 1000;\n }\n },\n\n offset: function parseOffset(offset, duration) {\n if(isPercentage(offset)){\n return calculatePercentage(offset, duration);\n }\n return parsers.duration(offset);\n\n /*** Local function ***/\n function isPercentage(offset) {\n var percentageRegex = /^\\d+(\\.\\d+)?%$/g;\n return percentageRegex.test(offset);\n }\n\n function calculatePercentage(percentStr, duration) {\n if(duration) {\n return calcPercent(duration, parseFloat(percentStr.replace('%', '')));\n }\n return null;\n }\n\n function calcPercent(quantity, percent){\n return quantity * percent / 100;\n }\n }\n\n};\n\n\nmodule.exports = parsers;","'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\nvar VPAIDHTML5Tech = require('../vpaid/VPAIDHTML5Tech');\nvar VPAIDFlashTech = require('../vpaid/VPAIDFlashTech');\nvar VPAIDFLASHClient = require('VPAIDFLASHClient/js/VPAIDFLASHClient');\n\nvar vastUtil = {\n\n track: function track(URLMacros, variables) {\n var sources = vastUtil.parseURLMacros(URLMacros, variables);\n var trackImgs = [];\n sources.forEach(function (src) {\n var img = new Image();\n img.src = src;\n trackImgs.push(img);\n });\n return trackImgs;\n },\n\n parseURLMacros: function parseMacros(URLMacros, variables) {\n var parsedURLs = [];\n\n variables = variables || {};\n\n if (!(variables[\"CACHEBUSTING\"])) {\n variables[\"CACHEBUSTING\"] = Math.round(Math.random() * 1.0e+10);\n }\n\n URLMacros.forEach(function (URLMacro) {\n parsedURLs.push(vastUtil._parseURLMacro(URLMacro, variables));\n });\n\n return parsedURLs;\n },\n\n parseURLMacro: function parseMacro(URLMacro, variables) {\n variables = variables || {};\n\n if (!(variables[\"CACHEBUSTING\"])) {\n variables[\"CACHEBUSTING\"] = Math.round(Math.random() * 1.0e+10);\n }\n\n return vastUtil._parseURLMacro(URLMacro, variables);\n },\n\n _parseURLMacro: function parseMacro(URLMacro, variables) {\n variables = variables || {};\n\n utilities.forEach(variables, function (value, key) {\n URLMacro = URLMacro.replace(new RegExp(\"\\\\[\" + key + \"\\\\\\]\", 'gm'), value);\n });\n\n return URLMacro;\n },\n\n parseDuration: function parseDuration(durationStr) {\n var durationRegex = /(\\d\\d):(\\d\\d):(\\d\\d)(\\.(\\d\\d\\d))?/;\n var match, durationInMs;\n\n if (utilities.isString(durationStr)) {\n match = durationStr.match(durationRegex);\n if (match) {\n durationInMs = parseHoursToMs(match[1]) + parseMinToMs(match[2]) + parseSecToMs(match[3]) + parseInt(match[5] || 0);\n }\n }\n\n return isNaN(durationInMs) ? null : durationInMs;\n\n /*** local functions ***/\n function parseHoursToMs(hourStr) {\n return parseInt(hourStr, 10) * 60 * 60 * 1000;\n }\n\n function parseMinToMs(minStr) {\n return parseInt(minStr, 10) * 60 * 1000;\n }\n\n function parseSecToMs(secStr) {\n return parseInt(secStr, 10) * 1000;\n }\n },\n\n parseImpressions: function parseImpressions(impressions) {\n if (impressions) {\n impressions = utilities.isArray(impressions) ? impressions : [impressions];\n return utilities.transformArray(impressions, function (impression) {\n if (utilities.isNotEmptyString(impression.keyValue)) {\n return impression.keyValue;\n }\n return undefined;\n });\n }\n return [];\n },\n\n\n //We assume that the progress is going to arrive in milliseconds\n formatProgress: function formatProgress(progress) {\n var hours, minutes, seconds, milliseconds;\n hours = progress / (60 * 60 * 1000);\n hours = Math.floor(hours);\n minutes = (progress / (60 * 1000)) % 60;\n minutes = Math.floor(minutes);\n seconds = (progress / 1000) % 60;\n seconds = Math.floor(seconds);\n milliseconds = progress % 1000;\n return utilities.toFixedDigits(hours, 2) + ':' + utilities.toFixedDigits(minutes, 2) + ':' + utilities.toFixedDigits(seconds, 2) + '.' + utilities.toFixedDigits(milliseconds, 3);\n },\n\n parseOffset: function parseOffset(offset, duration) {\n if (isPercentage(offset)) {\n return calculatePercentage(offset, duration);\n }\n return vastUtil.parseDuration(offset);\n\n /*** Local function ***/\n function isPercentage(offset) {\n var percentageRegex = /^\\d+(\\.\\d+)?%$/g;\n return percentageRegex.test(offset);\n }\n\n function calculatePercentage(percentStr, duration) {\n if (duration) {\n return calcPercent(duration, parseFloat(percentStr.replace('%', '')));\n }\n return null;\n }\n\n function calcPercent(quantity, percent) {\n return quantity * percent / 100;\n }\n },\n\n\n //List of supported VPAID technologies\n VPAID_techs: [\n VPAIDFlashTech,\n VPAIDHTML5Tech\n ],\n\n isVPAID: function isVPAIDMediaFile(mediaFile) {\n return !!mediaFile && mediaFile.apiFramework === 'VPAID';\n },\n\n findSupportedVPAIDTech: function findSupportedVPAIDTech(mimeType) {\n var i, len, VPAIDTech;\n\n for (i = 0, len = this.VPAID_techs.length; i < len; i += 1) {\n VPAIDTech = this.VPAID_techs[i];\n if (VPAIDTech.supports(mimeType)) {\n return VPAIDTech;\n }\n }\n return null;\n },\n\n isFlashSupported: function isFlashSupported() {\n return VPAIDFLASHClient.isSupported();\n },\n\n /**\n * Necessary step for VPAIDFLAShClient to know if flash is supported and not blocked.\n * IMPORTANT NOTE: This is an async test and needs to be run as soon as possible.\n *\n * @param vpaidFlashLoaderPath the path to the vpaidFlashLoader swf obj.\n */\n runFlashSupportCheck: function runFlashSupportCheck(vpaidFlashLoaderPath) {\n VPAIDFLASHClient.runFlashTest({data: vpaidFlashLoaderPath});\n }\n\n};\n\nmodule.exports = vastUtil;\n","'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VPAIDAdUnitWrapper(vpaidAdUnit, opts) {\n if (!(this instanceof VPAIDAdUnitWrapper)) {\n return new VPAIDAdUnitWrapper(vpaidAdUnit, opts);\n }\n sanityCheck(vpaidAdUnit, opts);\n\n this.options = utilities.extend({}, opts);\n\n this._adUnit = vpaidAdUnit;\n\n /*** Local Functions ***/\n function sanityCheck(adUnit, opts) {\n if (!adUnit || !VPAIDAdUnitWrapper.checkVPAIDInterface(adUnit)) {\n throw new VASTError('on VPAIDAdUnitWrapper, the passed VPAID adUnit does not fully implement the VPAID interface');\n }\n\n if (!utilities.isObject(opts)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper, expected options hash but got '\" + opts + \"'\");\n }\n\n if (!(\"responseTimeout\" in opts) || !utilities.isNumber(opts.responseTimeout) ){\n throw new VASTError(\"on VPAIDAdUnitWrapper, expected responseTimeout in options\");\n }\n }\n}\n\nVPAIDAdUnitWrapper.checkVPAIDInterface = function checkVPAIDInterface(VPAIDAdUnit) {\n //NOTE: skipAd is not part of the method list because it only appears in VPAID 2.0 and we support VPAID 1.0\n var VPAIDInterfaceMethods = [\n 'handshakeVersion', 'initAd', 'startAd', 'stopAd', 'resizeAd', 'pauseAd', 'expandAd', 'collapseAd'\n ];\n\n for (var i = 0, len = VPAIDInterfaceMethods.length; i < len; i++) {\n if (!VPAIDAdUnit || !utilities.isFunction(VPAIDAdUnit[VPAIDInterfaceMethods[i]])) {\n return false;\n }\n }\n\n\n return canSubscribeToEvents(VPAIDAdUnit) && canUnsubscribeFromEvents(VPAIDAdUnit);\n\n /*** Local Functions ***/\n\n function canSubscribeToEvents(adUnit) {\n return utilities.isFunction(adUnit.subscribe) || utilities.isFunction(adUnit.addEventListener) || utilities.isFunction(adUnit.on);\n }\n\n function canUnsubscribeFromEvents(adUnit) {\n return utilities.isFunction(adUnit.unsubscribe) || utilities.isFunction(adUnit.removeEventListener) || utilities.isFunction(adUnit.off);\n\n }\n};\n\nVPAIDAdUnitWrapper.prototype.adUnitAsyncCall = function () {\n var args = utilities.arrayLikeObjToArray(arguments);\n var method = args.shift();\n var cb = args.pop();\n var timeoutId;\n\n sanityCheck(method, cb, this._adUnit);\n args.push(wrapCallback());\n\n this._adUnit[method].apply(this._adUnit, args);\n timeoutId = setTimeout(function () {\n timeoutId = null;\n cb(new VASTError(\"on VPAIDAdUnitWrapper, timeout while waiting for a response on call '\" + method + \"'\"));\n cb = utilities.noop;\n }, this.options.responseTimeout);\n\n /*** Local functions ***/\n function sanityCheck(method, cb, adUnit) {\n if (!utilities.isString(method) || !utilities.isFunction(adUnit[method])) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.adUnitAsyncCall, invalid method name\");\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.adUnitAsyncCall, missing callback\");\n }\n }\n\n function wrapCallback() {\n return function () {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n cb.apply(this, arguments);\n };\n }\n};\n\nVPAIDAdUnitWrapper.prototype.on = function (evtName, handler) {\n var addEventListener = this._adUnit.addEventListener || this._adUnit.subscribe || this._adUnit.on;\n addEventListener.call(this._adUnit, evtName, handler);\n};\n\nVPAIDAdUnitWrapper.prototype.off = function (evtName, handler) {\n var removeEventListener = this._adUnit.removeEventListener || this._adUnit.unsubscribe || this._adUnit.off;\n removeEventListener.call(this._adUnit, evtName, handler);\n};\n\nVPAIDAdUnitWrapper.prototype.waitForEvent = function (evtName, cb, context) {\n var timeoutId;\n sanityCheck(evtName, cb);\n context = context || null;\n\n this.on(evtName, responseListener);\n\n timeoutId = setTimeout(function () {\n cb(new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, timeout while waiting for event '\" + evtName + \"'\"));\n timeoutId = null;\n cb = utilities.noop;\n }, this.options.responseTimeout);\n\n /*** Local functions ***/\n function sanityCheck(evtName, cb) {\n if (!utilities.isString(evtName)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, missing evt name\");\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, missing callback\");\n }\n }\n\n function responseListener() {\n var args = utilities.arrayLikeObjToArray(arguments);\n\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n\n args.unshift(null);\n cb.apply(context, args);\n }\n};\n\n// VPAID METHODS\nVPAIDAdUnitWrapper.prototype.handshakeVersion = function (version, cb) {\n this.adUnitAsyncCall('handshakeVersion', version, cb);\n};\n\n/* jshint maxparams:6 */\nVPAIDAdUnitWrapper.prototype.initAd = function (width, height, viewMode, desiredBitrate, adUnitData, cb) {\n this.waitForEvent('AdLoaded', cb);\n this._adUnit.initAd(width, height, viewMode, desiredBitrate, adUnitData);\n};\n\nVPAIDAdUnitWrapper.prototype.resizeAd = function (width, height, viewMode, cb) {\n // NOTE: AdSizeChange event is only supported on VPAID 2.0 so for the moment we are not going to use it\n // and will assume that everything is fine after the async call\n this.adUnitAsyncCall('resizeAd', width, height, viewMode, cb);\n};\n\nVPAIDAdUnitWrapper.prototype.startAd = function (cb) {\n this.waitForEvent('AdStarted', cb);\n this._adUnit.startAd();\n};\n\nVPAIDAdUnitWrapper.prototype.stopAd = function (cb) {\n this.waitForEvent('AdStopped', cb);\n this._adUnit.stopAd();\n};\n\nVPAIDAdUnitWrapper.prototype.pauseAd = function (cb) {\n this.waitForEvent('AdPaused', cb);\n this._adUnit.pauseAd();\n};\n\nVPAIDAdUnitWrapper.prototype.resumeAd = function (cb) {\n this.waitForEvent('AdPlaying', cb);\n this._adUnit.resumeAd();\n};\n\nVPAIDAdUnitWrapper.prototype.expandAd = function (cb) {\n this.waitForEvent('AdExpandedChange', cb);\n this._adUnit.expandAd();\n};\n\nVPAIDAdUnitWrapper.prototype.collapseAd = function (cb) {\n this.waitForEvent('AdExpandedChange', cb);\n this._adUnit.collapseAd();\n};\n\nVPAIDAdUnitWrapper.prototype.skipAd = function (cb) {\n this.waitForEvent('AdSkipped', cb);\n this._adUnit.skipAd();\n};\n\n//VPAID property getters\n[\n 'adLinear',\n 'adWidth',\n 'adHeight',\n 'adExpanded',\n 'adSkippableState',\n 'adRemainingTime',\n 'adDuration',\n 'adVolume',\n 'adCompanions',\n 'adIcons'\n].forEach(function (property) {\n var getterName = 'get' + utilities.capitalize(property);\n\n VPAIDAdUnitWrapper.prototype[getterName] = function (cb) {\n this.adUnitAsyncCall(getterName, cb);\n };\n});\n\n//VPAID property setters\nVPAIDAdUnitWrapper.prototype.setAdVolume = function(volume, cb){\n this.adUnitAsyncCall('setAdVolume',volume, cb);\n};\n\nmodule.exports = VPAIDAdUnitWrapper;\n","'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar VPAIDFLASHClient = require('VPAIDFLASHClient/js/VPAIDFLASHClient');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar dom = require('../../utils/dom');\n\nfunction VPAIDFlashTech(mediaFile, settings) {\n if (!(this instanceof VPAIDFlashTech)) {\n return new VPAIDFlashTech(mediaFile);\n }\n sanityCheck(mediaFile);\n this.name = 'vpaid-flash';\n this.mediaFile = mediaFile;\n this.containerEl = null;\n this.vpaidFlashClient = null;\n this.settings = settings;\n\n /*** local functions ***/\n function sanityCheck(mediaFile) {\n if (!mediaFile || !utilities.isString(mediaFile.src)) {\n throw new VASTError('on VPAIDFlashTech, invalid MediaFile');\n }\n }\n}\n\nVPAIDFlashTech.VPAIDFLASHClient = VPAIDFLASHClient;\n\nVPAIDFlashTech.supports = function (type) {\n return type === 'application/x-shockwave-flash' && VPAIDFlashTech.VPAIDFLASHClient.isSupported();\n};\n\nVPAIDFlashTech.prototype.loadAdUnit = function loadFlashCreative(containerEl, objectEl, callback) {\n var that = this;\n var flashClientOpts = this.settings && this.settings.vpaidFlashLoaderPath ? {data: this.settings.vpaidFlashLoaderPath} : undefined;\n sanityCheck(containerEl, callback);\n\n this.containerEl = containerEl;\n this.vpaidFlashClient = new VPAIDFlashTech.VPAIDFLASHClient(containerEl, function (error) {\n if (error) {\n return callback(error);\n }\n\n that.vpaidFlashClient.loadAdUnit(that.mediaFile.src, callback);\n }, flashClientOpts);\n\n /*** Local Functions ***/\n function sanityCheck(container, cb) {\n\n if (!dom.isDomElement(container)) {\n throw new VASTError('on VPAIDFlashTech.loadAdUnit, invalid dom container element');\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError('on VPAIDFlashTech.loadAdUnit, missing valid callback');\n }\n }\n};\n\nVPAIDFlashTech.prototype.unloadAdUnit = function () {\n if (this.vpaidFlashClient) {\n try{\n this.vpaidFlashClient.destroy();\n } catch(e){\n if(console && utilities.isFunction(console.log)){\n console.log('VAST ERROR: trying to unload the VPAID adunit');\n }\n }\n this.vpaidFlashClient = null;\n }\n\n if (this.containerEl) {\n dom.remove(this.containerEl);\n this.containerEl = null;\n }\n};\n\nmodule.exports = VPAIDFlashTech;\n","'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar VPAIDHTML5Client = require('VPAIDHTML5Client/js/VPAIDHTML5Client');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar dom = require('../../utils/dom');\n\nfunction VPAIDHTML5Tech(mediaFile) {\n\n if(!(this instanceof VPAIDHTML5Tech)) {\n return new VPAIDHTML5Tech(mediaFile);\n }\n\n sanityCheck(mediaFile);\n\n this.name = 'vpaid-html5';\n this.containerEl = null;\n this.videoEl = null;\n this.vpaidHTMLClient = null;\n\n this.mediaFile = mediaFile;\n\n function sanityCheck(mediaFile) {\n if (!mediaFile || !utilities.isString(mediaFile.src)) {\n throw new VASTError(VPAIDHTML5Tech.INVALID_MEDIA_FILE);\n }\n }\n}\n\nVPAIDHTML5Tech.VPAIDHTML5Client = VPAIDHTML5Client;\n\nVPAIDHTML5Tech.supports = function (type) {\n return !utilities.isOldIE() && type === 'application/javascript';\n};\n\nVPAIDHTML5Tech.prototype.loadAdUnit = function loadAdUnit(containerEl, videoEl, callback) {\n sanityCheck(containerEl, videoEl, callback);\n\n this.containerEl = containerEl;\n this.videoEl = videoEl;\n this.vpaidHTMLClient = new VPAIDHTML5Tech.VPAIDHTML5Client(containerEl, videoEl, {});\n this.vpaidHTMLClient.loadAdUnit(this.mediaFile.src, callback);\n\n function sanityCheck(container, video, cb) {\n if (!dom.isDomElement(container)) {\n throw new VASTError(VPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL);\n }\n\n if (!dom.isDomElement(video) || video.tagName.toLowerCase() !== 'video') {\n throw new VASTError(VPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL);\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(VPAIDHTML5Tech.MISSING_CALLBACK);\n }\n }\n};\n\nVPAIDHTML5Tech.prototype.unloadAdUnit = function unloadAdUnit() {\n if (this.vpaidHTMLClient) {\n try {\n this.vpaidHTMLClient.destroy();\n } catch(e) {\n if (console && utilities.isFunction(console.log)) {\n console.log('VAST ERROR: trying to unload the VPAID adunit');\n }\n }\n\n this.vpaidHTMLClient = null;\n }\n\n if (this.containerEl) {\n dom.remove(this.containerEl);\n this.containerEl = null;\n }\n};\n\nvar PREFIX = 'on VPAIDHTML5Tech';\nVPAIDHTML5Tech.INVALID_MEDIA_FILE = PREFIX + ', invalid MediaFile';\nVPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL = PREFIX + ', invalid container HtmlElement';\nVPAIDHTML5Tech.INVALID_DOM_VIDEO_EL = PREFIX + ', invalid HTMLVideoElement';\nVPAIDHTML5Tech.MISSING_CALLBACK = PREFIX + ', missing valid callback';\n\nmodule.exports = VPAIDHTML5Tech;","'use strict';\n\nvar VASTError = require('../vast/VASTError');\nvar VASTResponse = require('../vast/VASTResponse');\nvar VASTTracker = require('../vast/VASTTracker');\nvar vastUtil = require('../vast/vastUtil');\n\nvar VPAIDAdUnitWrapper = require('./VPAIDAdUnitWrapper');\n\nvar async = require('../../utils/async');\nvar dom = require('../../utils/dom');\nvar playerUtils = require('../../utils/playerUtils');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VPAIDIntegrator(player, settings) {\n if (!(this instanceof VPAIDIntegrator)) {\n return new VPAIDIntegrator(player);\n }\n\n this.VIEW_MODE = {\n NORMAL: 'normal',\n FULLSCREEN: \"fullscreen\",\n THUMBNAIL: \"thumbnail\"\n };\n this.player = player;\n this.containerEl = createVPAIDContainerEl(player);\n this.options = {\n responseTimeout: 5000,\n VPAID_VERSION: '2.0'\n };\n this.settings = settings;\n\n /*** Local functions ***/\n\n function createVPAIDContainerEl() {\n var containerEl = document.createElement('div');\n dom.addClass(containerEl, 'VPAID-container');\n player.el().insertBefore(containerEl, player.controlBar.el());\n return containerEl;\n\n }\n}\n\nVPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) {\n if (!(vastResponse instanceof VASTResponse)) {\n return callback(new VASTError('on VASTIntegrator.playAd, missing required VASTResponse'));\n }\n\n var that = this;\n var player = this.player;\n var tech = this._findSupportedTech(vastResponse, this.settings);\n\n callback = callback || utilities.noop;\n\n this._adUnit = null;\n\n dom.addClass(player.el(), 'vjs-vpaid-ad');\n\n player.on('vast.adsCancel', triggerVpaidAdEnd);\n player.one('vpaid.adEnd', function(){\n player.off('vast.adsCancel', triggerVpaidAdEnd);\n removeAdUnit();\n });\n\n if (tech) {\n async.waterfall([\n function (next) {\n next(null, tech, vastResponse);\n },\n this._loadAdUnit.bind(this),\n this._playAdUnit.bind(this),\n this._finishPlaying.bind(this)\n\n ], adComplete);\n\n this._adUnit = {\n _paused: true,\n type: 'VPAID',\n pauseAd: function() {\n player.trigger('vpaid.pauseAd');\n player.pause(true);//we make sure that the video content gets stopped.\n },\n resumeAd: function() {\n player.trigger('vpaid.resumeAd');\n },\n isPaused: function() {\n return this._paused;\n },\n getSrc: function() {\n return tech.mediaFile;\n }\n };\n\n } else {\n var error = new VASTError('on VPAIDIntegrator.playAd, could not find a supported mediaFile', 403);\n adComplete(error, this._adUnit, vastResponse);\n }\n\n return this._adUnit;\n\n /*** Local functions ***/\n function adComplete(error, adUnit, vastResponse) {\n if (error && vastResponse) {\n that._trackError(vastResponse, error.code);\n }\n player.trigger('vpaid.adEnd');\n callback(error, vastResponse);\n }\n\n function triggerVpaidAdEnd(){\n player.trigger('vpaid.adEnd');\n }\n\n function removeAdUnit() {\n if (tech) {\n tech.unloadAdUnit();\n }\n dom.removeClass(player.el(), 'vjs-vpaid-ad');\n }\n};\n\nVPAIDIntegrator.prototype._findSupportedTech = function (vastResponse, settings) {\n if (!(vastResponse instanceof VASTResponse)) {\n return null;\n }\n\n var vpaidMediaFiles = vastResponse.mediaFiles.filter(vastUtil.isVPAID);\n var i, len, mediaFile, VPAIDTech;\n\n for (i = 0, len = vpaidMediaFiles.length; i < len; i += 1) {\n mediaFile = vpaidMediaFiles[i];\n VPAIDTech = vastUtil.findSupportedVPAIDTech(mediaFile.type);\n if (VPAIDTech) {\n return new VPAIDTech(mediaFile, settings);\n }\n }\n return null;\n};\n\nVPAIDIntegrator.prototype._createVPAIDAdUnitWrapper = function(adUnit, src, responseTimeout) {\n return new VPAIDAdUnitWrapper(adUnit, {src: src, responseTimeout: responseTimeout});\n};\n\nVPAIDIntegrator.prototype._loadAdUnit = function (tech, vastResponse, next) {\n var that = this;\n var player = this.player;\n var vjsTechEl = player.el().querySelector('.vjs-tech');\n var responseTimeout = this.settings.responseTimeout || this.options.responseTimeout;\n tech.loadAdUnit(this.containerEl, vjsTechEl, function (error, adUnit) {\n if (error) {\n return next(error, adUnit, vastResponse);\n }\n\n try {\n var WrappedAdUnit = that._createVPAIDAdUnitWrapper(adUnit, tech.mediaFile.src, responseTimeout);\n var techClass = 'vjs-' + tech.name + '-ad';\n dom.addClass(player.el(), techClass);\n player.one('vpaid.adEnd', function() {\n dom.removeClass(player.el(),techClass);\n });\n next(null, WrappedAdUnit, vastResponse);\n } catch (e) {\n next(e, adUnit, vastResponse);\n }\n });\n};\n\nVPAIDIntegrator.prototype._playAdUnit = function (adUnit, vastResponse, callback) {\n async.waterfall([\n function (next) {\n next(null, adUnit, vastResponse);\n },\n this._handshake.bind(this),\n this._initAd.bind(this),\n this._setupEvents.bind(this),\n this._addSkipButton.bind(this),\n this._linkPlayerControls.bind(this),\n this._startAd.bind(this)\n ], callback);\n};\n\nVPAIDIntegrator.prototype._handshake = function handshake(adUnit, vastResponse, next) {\n adUnit.handshakeVersion(this.options.VPAID_VERSION, function (error, version) {\n if (error) {\n return next(error, adUnit, vastResponse);\n }\n\n if (version && isSupportedVersion(version)) {\n return next(null, adUnit, vastResponse);\n }\n\n return next(new VASTError('on VPAIDIntegrator._handshake, unsupported version \"' + version + '\"'), adUnit, vastResponse);\n });\n\n function isSupportedVersion(version) {\n var majorNum = major(version);\n return majorNum >= 1 && majorNum <= 2;\n }\n\n function major(version) {\n var parts = version.split('.');\n return parseInt(parts[0], 10);\n }\n};\n\nVPAIDIntegrator.prototype._initAd = function (adUnit, vastResponse, next) {\n var tech = this.player.el().querySelector('.vjs-tech');\n var dimension = dom.getDimension(tech);\n adUnit.initAd(dimension.width, dimension.height, this.VIEW_MODE.NORMAL, -1, {AdParameters: vastResponse.adParameters || ''}, function (error) {\n next(error, adUnit, vastResponse);\n });\n};\n\nVPAIDIntegrator.prototype._createVASTTracker = function(adUnitSrc, vastResponse) {\n return new VASTTracker(adUnitSrc, vastResponse);\n};\n\nVPAIDIntegrator.prototype._setupEvents = function (adUnit, vastResponse, next) {\n var adUnitSrc = adUnit.options.src;\n var tracker = this._createVASTTracker(adUnitSrc, vastResponse);\n var player = this.player;\n var that = this;\n\n adUnit.on('AdSkipped', function () {\n player.trigger('vpaid.AdSkipped');\n tracker.trackSkip();\n });\n\n adUnit.on('AdImpression', function () {\n player.trigger('vpaid.AdImpression');\n tracker.trackImpressions();\n });\n\n adUnit.on('AdStarted', function () {\n player.trigger('vpaid.AdStarted');\n tracker.trackCreativeView();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdVideoStart', function () {\n player.trigger('vpaid.AdVideoStart');\n tracker.trackStart();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdPlaying', function () {\n player.trigger('vpaid.AdPlaying');\n tracker.trackResume();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdPaused', function () {\n player.trigger('vpaid.AdPaused');\n tracker.trackPause();\n notifyPauseToPlayer();\n });\n\n function notifyPlayToPlayer(){\n if(that._adUnit && that._adUnit.isPaused()){\n that._adUnit._paused = false;\n }\n player.trigger('play');\n\n }\n\n function notifyPauseToPlayer() {\n if(that._adUnit){\n that._adUnit._paused = true;\n }\n player.trigger('pause');\n }\n\n adUnit.on('AdVideoFirstQuartile', function () {\n player.trigger('vpaid.AdVideoFirstQuartile');\n tracker.trackFirstQuartile();\n });\n\n adUnit.on('AdVideoMidpoint', function () {\n player.trigger('vpaid.AdVideoMidpoint');\n tracker.trackMidpoint();\n });\n\n adUnit.on('AdVideoThirdQuartile', function () {\n player.trigger('vpaid.AdVideoThirdQuartile');\n tracker.trackThirdQuartile();\n });\n\n adUnit.on('AdVideoComplete', function () {\n player.trigger('vpaid.AdVideoComplete');\n tracker.trackComplete();\n });\n\n adUnit.on('AdClickThru', function (data) {\n player.trigger('vpaid.AdClickThru');\n var url = data.url;\n var playerHandles = data.playerHandles;\n var clickThruUrl = utilities.isNotEmptyString(url) ? url : generateClickThroughURL(vastResponse.clickThrough);\n\n tracker.trackClick();\n if (playerHandles && clickThruUrl) {\n window.open(clickThruUrl, '_blank');\n }\n\n function generateClickThroughURL(clickThroughMacro) {\n var variables = {\n ASSETURI: adUnit.options.src,\n CONTENTPLAYHEAD: 0 //In VPAID there is no method to know the current time from the adUnit\n };\n\n return clickThroughMacro ? vastUtil.parseURLMacro(clickThroughMacro, variables) : null;\n }\n });\n\n adUnit.on('AdUserAcceptInvitation', function () {\n player.trigger('vpaid.AdUserAcceptInvitation');\n tracker.trackAcceptInvitation();\n tracker.trackAcceptInvitationLinear();\n });\n\n adUnit.on('AdUserClose', function () {\n player.trigger('vpaid.AdUserClose');\n tracker.trackClose();\n tracker.trackCloseLinear();\n });\n\n adUnit.on('AdUserMinimize', function () {\n player.trigger('vpaid.AdUserMinimize');\n tracker.trackCollapse();\n });\n\n adUnit.on('AdError', function () {\n player.trigger('vpaid.AdError');\n //NOTE: we track errors code 901, as noted in VAST 3.0\n tracker.trackErrorWithCode(901);\n });\n\n adUnit.on('AdVolumeChange', function () {\n player.trigger('vpaid.AdVolumeChange');\n var lastVolume = player.volume();\n adUnit.getAdVolume(function (error, currentVolume) {\n if (currentVolume === 0 && lastVolume > 0) {\n tracker.trackMute();\n }\n\n if (currentVolume > 0 && lastVolume === 0) {\n tracker.trackUnmute();\n }\n\n player.volume(currentVolume);\n });\n });\n\n var updateViewSize = resizeAd.bind(this, player, adUnit, this.VIEW_MODE);\n var updateViewSizeThrottled = utilities.throttle(updateViewSize, 100);\n var autoResize = this.settings.autoResize;\n\n if (autoResize) {\n dom.addEventListener(window, 'resize', updateViewSizeThrottled);\n dom.addEventListener(window, 'orientationchange', updateViewSizeThrottled);\n }\n\n player.on('vast.resize', updateViewSize);\n player.on('vpaid.pauseAd', pauseAdUnit);\n player.on('vpaid.resumeAd', resumeAdUnit);\n\n player.one('vpaid.adEnd', function () {\n player.off('vast.resize', updateViewSize);\n player.off('vpaid.pauseAd', pauseAdUnit);\n player.off('vpaid.resumeAd', resumeAdUnit);\n\n if (autoResize) {\n dom.removeEventListener(window, 'resize', updateViewSizeThrottled);\n dom.removeEventListener(window, 'orientationchange', updateViewSizeThrottled);\n }\n });\n\n next(null, adUnit, vastResponse);\n\n /*** Local Functions ***/\n function pauseAdUnit() {\n adUnit.pauseAd(utilities.noop);\n }\n\n function resumeAdUnit() {\n adUnit.resumeAd(utilities.noop);\n }\n};\n\nVPAIDIntegrator.prototype._addSkipButton = function (adUnit, vastResponse, next) {\n var skipButton;\n var player = this.player;\n\n adUnit.on('AdSkippableStateChange', updateSkipButtonState);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeSkipButton);\n\n next(null, adUnit, vastResponse);\n\n /*** Local function ***/\n function updateSkipButtonState() {\n player.trigger('vpaid.AdSkippableStateChange');\n adUnit.getAdSkippableState(function (error, isSkippable) {\n if (isSkippable) {\n if (!skipButton) {\n addSkipButton(player);\n }\n } else {\n removeSkipButton(player);\n }\n });\n }\n\n function addSkipButton(player) {\n skipButton = createSkipButton(player);\n player.el().appendChild(skipButton);\n }\n\n function removeSkipButton() {\n dom.remove(skipButton);\n skipButton = null;\n }\n\n function createSkipButton() {\n var skipButton = window.document.createElement(\"div\");\n dom.addClass(skipButton, \"vast-skip-button\");\n dom.addClass(skipButton, \"enabled\");\n skipButton.innerHTML = \"Skip ad\";\n\n skipButton.onclick = function (e) {\n adUnit.skipAd(utilities.noop);//We skip the adUnit\n\n //We prevent event propagation to avoid problems with the clickThrough and so on\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n } else {\n return false;\n }\n };\n\n return skipButton;\n }\n};\n\nVPAIDIntegrator.prototype._linkPlayerControls = function (adUnit, vastResponse, next) {\n var that = this;\n linkVolumeControl(this.player, adUnit);\n linkFullScreenControl(this.player, adUnit, this.VIEW_MODE);\n\n next(null, adUnit, vastResponse);\n\n /*** Local functions ***/\n function linkVolumeControl(player, adUnit) {\n player.on('volumechange', updateAdUnitVolume);\n adUnit.on('AdVolumeChange', updatePlayerVolume);\n\n player.one('vpaid.adEnd', function () {\n player.off('volumechange', updateAdUnitVolume);\n });\n\n\n /*** local functions ***/\n function updateAdUnitVolume() {\n var vol = player.muted() ? 0 : player.volume();\n adUnit.setAdVolume(vol, logError);\n }\n\n function updatePlayerVolume() {\n player.trigger('vpaid.AdVolumeChange');\n adUnit.getAdVolume(function (error, vol) {\n if (error) {\n logError(error);\n } else {\n player.volume(vol);\n }\n });\n }\n }\n\n function linkFullScreenControl(player, adUnit, VIEW_MODE) {\n var updateViewSize = resizeAd.bind(that, player, adUnit, VIEW_MODE);\n\n player.on('fullscreenchange', updateViewSize);\n\n player.one('vpaid.adEnd', function () {\n player.off('fullscreenchange', updateViewSize);\n });\n }\n};\n\nVPAIDIntegrator.prototype._startAd = function (adUnit, vastResponse, next) {\n var player = this.player;\n\n adUnit.startAd(function (error) {\n if (!error) {\n player.trigger('vast.adStart');\n }\n next(error, adUnit, vastResponse);\n });\n};\n\nVPAIDIntegrator.prototype._finishPlaying = function (adUnit, vastResponse, next) {\n var player = this.player;\n adUnit.on('AdStopped', function () {\n player.trigger('vpaid.AdStopped');\n finishPlayingAd(null);\n });\n\n adUnit.on('AdError', function (error) {\n var errMsg = error? error.message : 'on VPAIDIntegrator, error while waiting for the adUnit to finish playing';\n finishPlayingAd(new VASTError(errMsg));\n });\n\n /*** local functions ***/\n function finishPlayingAd(error) {\n next(error, adUnit, vastResponse);\n }\n};\n\nVPAIDIntegrator.prototype._trackError = function trackError(response, errorCode) {\n vastUtil.track(response.errorURLMacros, {ERRORCODE: errorCode || 901});\n};\n\nfunction resizeAd(player, adUnit, VIEW_MODE) {\n var tech = player.el().querySelector('.vjs-tech');\n var dimension = dom.getDimension(tech);\n var MODE = player.isFullscreen() ? VIEW_MODE.FULLSCREEN : VIEW_MODE.NORMAL;\n adUnit.resizeAd(dimension.width, dimension.height, MODE, logError);\n}\n\nfunction logError(error) {\n if (error && console && console.log) {\n console.log('ERROR: ' + error.message, error);\n }\n}\n\nmodule.exports = VPAIDIntegrator;","'use strict';\n\nvar dom = require('../../utils/dom');\n\nvar element = document.createElement('div');\nelement.className = 'vjs-ads-label vjs-control vjs-label-hidden';\nelement.innerHTML = 'Advertisement';\n\nvar AdsLabelFactory = function(baseComponent) {\n return {\n /** @constructor */\n init: function init(player, options) {\n options.el = element;\n baseComponent.call(this, player, options);\n\n // We asynchronously reposition the ads label element\n setTimeout(function () {\n var currentTimeComp = player.controlBar &&( player.controlBar.getChild(\"timerControls\") || player.controlBar.getChild(\"currentTimeDisplay\") );\n if(currentTimeComp) {\n player.controlBar.el().insertBefore(element, currentTimeComp.el());\n }\n dom.removeClass(element, 'vjs-label-hidden');\n }, 0);\n },\n\n el: function getElement() {\n return element;\n }\n };\n};\n\nmodule.exports = AdsLabelFactory;","'use strict';\n\nvar baseVideoJsComponent = videojs.Component;\n\nvar AdsLabel = require('./ads-label')(baseVideoJsComponent);\n\nvideojs.AdsLabel = videojs.Component.extend(AdsLabel);\n","'use strict';\n\n/**\n * The component that shows a black screen until the ads plugin has decided if it can or it can not play the ad.\n *\n * Note: In case you wonder why instead of this black poster we don't just show the spinner loader.\n * IOS devices do not work well with animations and the browser chrashes from time to time That is why we chose to\n * have a secondary black poster.\n *\n * It also makes it much more easier for the users of the plugin since it does not change the default behaviour of the\n * spinner and the player works the same way with and without the plugin.\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvar element = document.createElement('div');\n\nvar BlackPosterFactory = function(baseComponent) {\n return {\n /** @constructor */\n init: function init(player, options) {\n options.el = element;\n element.className = 'vjs-black-poster';\n baseComponent.call(this, player, options);\n\n var posterImg = player.getChild('posterImage');\n\n //We need to do it asynchronously to be sure that the black poster el is on the dom.\n setTimeout(function() {\n if(posterImg && player && player.el()) {\n player.el().insertBefore(element, posterImg.el());\n }\n }, 0);\n },\n el: function getElement() {\n return element;\n }\n };\n};\n\nmodule.exports = BlackPosterFactory;","'use strict';\n\nvar baseVideoJsComponent = videojs.Component;\n\nvar BlackPoster = require('./black-poster')(baseVideoJsComponent);\n\nvideojs.BlackPoster = videojs.Component.extend(BlackPoster);\n","'use strict';\n\nvar VASTClient = require('../ads/vast/VASTClient');\nvar VASTError = require('../ads/vast/VASTError');\nvar vastUtil = require('../ads/vast/vastUtil');\n\nvar VASTIntegrator = require('../ads/vast/VASTIntegrator');\nvar VPAIDIntegrator = require('../ads/vpaid/VPAIDIntegrator');\n\nvar async = require('../utils/async');\nvar dom = require('../utils/dom');\nvar playerUtils = require('../utils/playerUtils');\nvar utilities = require('../utils/utilityFunctions');\n\nmodule.exports = function VASTPlugin(options) {\n var snapshot;\n var player = this;\n var vast = new VASTClient();\n var adsCanceled = false;\n var defaultOpts = {\n // maximum amount of time in ms to wait to receive `adsready` from the ad\n // implementation after play has been requested. Ad implementations are\n // expected to load any dynamic libraries and make any requests to determine\n // ad policies for a video during this time.\n timeout: 500,\n\n //TODO:finish this IOS FIX\n //Whenever you play an add on IOS, the native player kicks in and we loose control of it. On very heavy pages the 'play' event\n // May occur after the video content has already started. This is wrong if you want to play a preroll ad that needs to happen before the user\n // starts watching the content. To prevent this usec\n iosPrerollCancelTimeout: 2000,\n\n // maximun amount of time for the ad to actually start playing. If this timeout gets\n // triggered the ads will be cancelled\n adCancelTimeout: 3000,\n\n // Boolean flag that configures the player to play a new ad before the user sees the video again\n // the current video\n playAdAlways: false,\n\n // Flag to enable or disable the ads by default.\n adsEnabled: true,\n\n // Boolean flag to enable or disable the resize with window.resize or orientationchange\n autoResize: true,\n\n // Path to the VPAID flash ad's loader\n vpaidFlashLoaderPath: '/VPAIDFlash.swf'\n };\n\n var settings = utilities.extend({}, defaultOpts, options || {});\n\n if(utilities.isUndefined(settings.adTagUrl) && utilities.isDefined(settings.url)){\n settings.adTagUrl = settings.url;\n }\n\n if (utilities.isString(settings.adTagUrl)) {\n settings.adTagUrl = utilities.echoFn(settings.adTagUrl);\n }\n\n if (utilities.isDefined(settings.adTagXML) && !utilities.isFunction(settings.adTagXML)) {\n return trackAdError(new VASTError('on VideoJS VAST plugin, the passed adTagXML option does not contain a function'));\n }\n\n if (!utilities.isDefined(settings.adTagUrl) && !utilities.isFunction(settings.adTagXML)) {\n return trackAdError(new VASTError('on VideoJS VAST plugin, missing adTagUrl on options object'));\n }\n\n vastUtil.runFlashSupportCheck(settings.vpaidFlashLoaderPath);// Necessary step for VPAIDFLASHClient to work.\n\n playerUtils.prepareForAds(player);\n\n if (settings.playAdAlways) {\n // No matter what happens we play a new ad before the user sees the video again.\n player.on('vast.contentEnd', function () {\n setTimeout(function () {\n player.trigger('vast.reset');\n }, 0);\n });\n }\n\n player.on('vast.firstPlay', tryToPlayPrerollAd);\n\n player.on('vast.reset', function () {\n //If we are reseting the plugin, we don't want to restore the content\n snapshot = null;\n cancelAds();\n });\n\n player.vast = {\n isEnabled: function () {\n return settings.adsEnabled;\n },\n\n enable: function () {\n settings.adsEnabled = true;\n },\n\n disable: function () {\n settings.adsEnabled = false;\n }\n };\n\n return player.vast;\n\n /**** Local functions ****/\n function tryToPlayPrerollAd() {\n //We remove the poster to prevent flickering whenever the content starts playing\n playerUtils.removeNativePoster(player);\n\n playerUtils.once(player, ['vast.adsCancel', 'vast.adEnd'], function () {\n removeAdUnit();\n restoreVideoContent();\n });\n\n async.waterfall([\n checkAdsEnabled,\n preparePlayerForAd,\n startAdCancelTimeout,\n playPrerollAd\n ], function (error, response) {\n if (error) {\n trackAdError(error, response);\n } else {\n player.trigger('vast.adEnd');\n }\n });\n\n /*** Local functions ***/\n\n function removeAdUnit() {\n if (player.vast && player.vast.adUnit) {\n player.vast.adUnit = null; //We remove the adUnit\n }\n }\n\n function restoreVideoContent() {\n setupContentEvents();\n if (snapshot) {\n playerUtils.restorePlayerSnapshot(player, snapshot);\n snapshot = null;\n }\n }\n\n function setupContentEvents() {\n playerUtils.once(player, ['playing', 'vast.reset', 'vast.firstPlay'], function (evt) {\n if (evt.type !== 'playing') {\n return;\n }\n\n player.trigger('vast.contentStart');\n\n playerUtils.once(player, ['ended', 'vast.reset', 'vast.firstPlay'], function (evt) {\n if (evt.type === 'ended') {\n player.trigger('vast.contentEnd');\n }\n });\n });\n }\n\n function checkAdsEnabled(next) {\n if (settings.adsEnabled) {\n return next(null);\n }\n next(new VASTError('Ads are not enabled'));\n }\n\n function preparePlayerForAd(next) {\n if (canPlayPrerollAd()) {\n snapshot = playerUtils.getPlayerSnapshot(player);\n player.pause();\n addSpinnerIcon();\n\n if(player.paused()) {\n next(null);\n } else {\n playerUtils.once(player, ['playing'], function() {\n player.pause();\n next(null);\n });\n }\n } else {\n next(new VASTError('video content has been playing before preroll ad'));\n }\n }\n\n function canPlayPrerollAd() {\n return !utilities.isIPhone() || player.currentTime() <= settings.iosPrerollCancelTimeout;\n }\n\n function startAdCancelTimeout(next) {\n var adCancelTimeoutId;\n adsCanceled = false;\n\n adCancelTimeoutId = setTimeout(function () {\n trackAdError(new VASTError('timeout while waiting for the video to start playing', 402));\n }, settings.adCancelTimeout);\n\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], clearAdCancelTimeout);\n\n /*** local functions ***/\n function clearAdCancelTimeout() {\n if (adCancelTimeoutId) {\n clearTimeout(adCancelTimeoutId);\n adCancelTimeoutId = null;\n }\n }\n\n next(null);\n }\n\n function addSpinnerIcon() {\n dom.addClass(player.el(), 'vjs-vast-ad-loading');\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], removeSpinnerIcon);\n }\n\n function removeSpinnerIcon() {\n //IMPORTANT NOTE: We remove the spinnerIcon asynchronously to give time to the browser to start the video.\n // If we remove it synchronously we see a flash of the content video before the ad starts playing.\n setTimeout(function () {\n dom.removeClass(player.el(), 'vjs-vast-ad-loading');\n }, 100);\n }\n\n }\n\n function cancelAds() {\n player.trigger('vast.adsCancel');\n adsCanceled = true;\n }\n\n function playPrerollAd(callback) {\n async.waterfall([\n getVastResponse,\n playAd\n ], callback);\n }\n\n function getVastResponse(callback) {\n vast.getVASTResponse(settings.adTagUrl ? settings.adTagUrl() : settings.adTagXML, callback);\n }\n\n function playAd(vastResponse, callback) {\n //TODO: Find a better way to stop the play. The 'playPrerollWaterfall' ends in an inconsistent situation\n //If the state is not 'preroll?' it means the ads were canceled therefore, we break the waterfall\n if (adsCanceled) {\n return;\n }\n\n var adIntegrator = isVPAID(vastResponse) ? new VPAIDIntegrator(player, settings) : new VASTIntegrator(player);\n var adFinished = false;\n\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], function (evt) {\n if (evt.type === 'vast.adStart') {\n addAdsLabel();\n }\n });\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeAdsLabel);\n\n if (utilities.isIDevice()) {\n preventManualProgress();\n }\n\n player.vast.vastResponse = vastResponse;\n player.vast.adUnit = adIntegrator.playAd(vastResponse, callback);\n\n /*** Local functions ****/\n function addAdsLabel() {\n if (adFinished || player.controlBar.getChild('AdsLabel')) {\n return;\n }\n\n player.controlBar.addChild('AdsLabel');\n }\n\n function removeAdsLabel() {\n player.controlBar.removeChild('AdsLabel');\n adFinished = true;\n }\n\n function preventManualProgress() {\n //IOS video clock is very unreliable and we need a 3 seconds threshold to ensure that the user forwarded/rewound the ad\n var PROGRESS_THRESHOLD = 3;\n var previousTime = 0;\n var skipad_attempts = 0;\n\n player.on('timeupdate', preventAdSeek);\n player.on('ended', preventAdSkip);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel', 'vast.adError'], stopPreventManualProgress);\n\n /*** Local functions ***/\n function preventAdSkip() {\n // Ignore ended event if the Ad time was not 'near' the end\n // and revert time to the previous 'valid' time\n if ((player.duration() - previousTime) > PROGRESS_THRESHOLD) {\n player.pause(true); // this reduce the video jitter if the IOS skip button is pressed\n player.play(true); // we need to trigger the play to put the video element back in a valid state\n player.currentTime(previousTime);\n }\n }\n\n function preventAdSeek() {\n var currentTime = player.currentTime();\n var progressDelta = Math.abs(currentTime - previousTime);\n if (progressDelta > PROGRESS_THRESHOLD) {\n skipad_attempts += 1;\n if (skipad_attempts >= 2) {\n player.pause(true);\n }\n player.currentTime(previousTime);\n } else {\n previousTime = currentTime;\n }\n }\n\n function stopPreventManualProgress() {\n player.off('timeupdate', preventAdSeek);\n player.off('ended', preventAdSkip);\n }\n }\n }\n\n function trackAdError(error, vastResponse) {\n player.trigger({type: 'vast.adError', error: error});\n cancelAds();\n if (console && console.log) {\n console.log('AD ERROR:', error.message, error, vastResponse);\n }\n }\n\n function isVPAID(vastResponse) {\n var i, len;\n var mediaFiles = vastResponse.mediaFiles;\n for (i = 0, len = mediaFiles.length; i < len; i++) {\n if (vastUtil.isVPAID(mediaFiles[i])) {\n return true;\n }\n }\n return false;\n }\n};\n","//Small subset of async\n\nvar utilities = require('./utilityFunctions');\n\nvar async = {};\n\nasync.setImmediate = function (fn) {\n setTimeout(fn, 0);\n};\n\nasync.iterator = function (tasks) {\n var makeCallback = function (index) {\n var fn = function () {\n if (tasks.length) {\n tasks[index].apply(null, arguments);\n }\n return fn.next();\n };\n fn.next = function () {\n return (index < tasks.length - 1) ? makeCallback(index + 1) : null;\n };\n return fn;\n };\n return makeCallback(0);\n};\n\n\nasync.waterfall = function (tasks, callback) {\n callback = callback || function () { };\n if (!utilities.isArray(tasks)) {\n var err = new Error('First argument to waterfall must be an array of functions');\n return callback(err);\n }\n if (!tasks.length) {\n return callback();\n }\n var wrapIterator = function (iterator) {\n return function (err) {\n if (err) {\n callback.apply(null, arguments);\n callback = function () {\n };\n }\n else {\n var args = Array.prototype.slice.call(arguments, 1);\n var next = iterator.next();\n if (next) {\n args.push(wrapIterator(next));\n }\n else {\n args.push(callback);\n }\n async.setImmediate(function () {\n iterator.apply(null, args);\n });\n }\n };\n };\n wrapIterator(async.iterator(tasks))();\n};\n\nasync.when = function (condition, callback) {\n if (!utilities.isFunction(callback)) {\n throw new Error(\"async.when error: missing callback argument\");\n }\n\n var isAllowed = utilities.isFunction(condition) ? condition : function () {\n return !!condition;\n };\n\n return function () {\n var args = utilities.arrayLikeObjToArray(arguments);\n var next = args.pop();\n\n if (isAllowed.apply(null, args)) {\n return callback.apply(this, arguments);\n }\n\n args.unshift(null);\n return next.apply(null, args);\n };\n};\n\nmodule.exports = async;\n\n","'use strict';\n\nvar utilities = require('./utilityFunctions');\n\nvar dom = {};\n\ndom.isVisible = function isVisible(el) {\n var style = window.getComputedStyle(el);\n return style.visibility !== 'hidden';\n};\n\ndom.isHidden = function isHidden(el) {\n var style = window.getComputedStyle(el);\n return style.display === 'none';\n};\n\ndom.isShown = function isShown(el) {\n return !dom.isHidden(el);\n};\n\ndom.hide = function hide(el) {\n el.__prev_style_display_ = el.style.display;\n el.style.display = 'none';\n};\n\ndom.show = function show(el) {\n if (dom.isHidden(el)) {\n el.style.display = el.__prev_style_display_;\n }\n el.__prev_style_display_ = undefined;\n};\n\ndom.hasClass = function hasClass(el, cssClass) {\n var classes, i, len;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.contains(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n cssClass = (cssClass || '');\n\n for (i = 0, len = classes.length; i < len; i += 1) {\n if (classes[i] === cssClass) {\n return true;\n }\n }\n }\n return false;\n};\n\ndom.addClass = function (el, cssClass) {\n var classes;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.add(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n if (utilities.isString(cssClass) && utilities.isNotEmptyString(cssClass.replace(/\\s+/, ''))) {\n classes.push(cssClass);\n el.setAttribute('class', classes.join(' '));\n }\n }\n};\n\ndom.removeClass = function (el, cssClass) {\n var classes;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.remove(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n var newClasses = [];\n var i, len;\n if (utilities.isString(cssClass) && utilities.isNotEmptyString(cssClass.replace(/\\s+/, ''))) {\n\n for (i = 0, len = classes.length; i < len; i += 1) {\n if (cssClass !== classes[i]) {\n newClasses.push(classes[i]);\n }\n }\n el.setAttribute('class', newClasses.join(' '));\n }\n }\n};\n\ndom.addEventListener = function addEventListener(el, type, handler) {\n if(utilities.isArray(el)){\n utilities.forEach(el, function(e) {\n dom.addEventListener(e, type, handler);\n });\n return;\n }\n\n if(utilities.isArray(type)){\n utilities.forEach(type, function(t) {\n dom.addEventListener(el, t, handler);\n });\n return;\n }\n\n if (el.addEventListener) {\n el.addEventListener(type, handler, false);\n } else if (el.attachEvent) {\n // WARNING!!! this is a very naive implementation !\n // the event object that should be passed to the handler\n // would not be there for IE8\n // we should use \"window.event\" and then \"event.srcElement\"\n // instead of \"event.target\"\n el.attachEvent(\"on\" + type, handler);\n }\n};\n\ndom.removeEventListener = function removeEventListener(el, type, handler) {\n if(utilities.isArray(el)){\n utilities.forEach(el, function(e) {\n dom.removeEventListener(e, type, handler);\n });\n return;\n }\n\n if(utilities.isArray(type)){\n utilities.forEach(type, function(t) {\n dom.removeEventListener(el, t, handler);\n });\n return;\n }\n\n if (el.removeEventListener) {\n el.removeEventListener(type, handler, false);\n } else if (el.detachEvent) {\n el.detachEvent(\"on\" + type, handler);\n } else {\n el[\"on\" + type] = null;\n }\n};\n\ndom.dispatchEvent = function dispatchEvent(el, event) {\n if (el.dispatchEvent) {\n el.dispatchEvent(event);\n } else {\n el.fireEvent(\"on\" + event.eventType, event);\n }\n};\n\ndom.isDescendant = function isDescendant(parent, child) {\n var node = child.parentNode;\n while (node !== null) {\n if (node === parent) {\n return true;\n }\n node = node.parentNode;\n }\n return false;\n};\n\ndom.getTextContent = function getTextContent(el){\n return el.textContent || el.text;\n};\n\ndom.prependChild = function prependChild(parent, child) {\n if(child.parentNode){\n child.parentNode.removeChild(child);\n }\n return parent.insertBefore(child, parent.firstChild);\n};\n\ndom.remove = function removeNode(node){\n if(node && node.parentNode){\n node.parentNode.removeChild(node);\n }\n};\n\ndom.isDomElement = function isDomElement(o) {\n return o instanceof Element;\n};\n\ndom.click = function(el, handler) {\n dom.addEventListener(el, 'click', handler);\n};\n\ndom.once = function(el, type, handler) {\n function handlerWrap() {\n handler.apply(null, arguments);\n dom.removeEventListener(el, type, handlerWrap);\n }\n\n dom.addEventListener(el, type, handlerWrap);\n};\n\n//Note: there is no getBoundingClientRect on iPad so we need a fallback\ndom.getDimension = function getDimension(element) {\n var rect;\n\n //On IE9 and below getBoundingClientRect does not work consistently\n if(!utilities.isOldIE() && element.getBoundingClientRect) {\n rect = element.getBoundingClientRect();\n return {\n width: rect.width,\n height: rect.height\n };\n }\n\n return {\n width: element.offsetWidth,\n height: element.offsetHeight\n };\n};\n\nmodule.exports = dom;","'use strict';\n\nvar urlUtils = require('./urlUtils');\nvar utilities = require('./utilityFunctions');\n\nfunction HttpRequestError(message) {\n this.message = 'HttpRequest Error: ' + (message || '');\n}\nHttpRequestError.prototype = new Error();\nHttpRequestError.prototype.name = \"HttpRequest Error\";\n\nfunction HttpRequest(createXhr) {\n if (!utilities.isFunction(createXhr)) {\n throw new HttpRequestError('Missing XMLHttpRequest factory method');\n }\n\n this.createXhr = createXhr;\n}\n\nHttpRequest.prototype.run = function (method, url, callback, options) {\n sanityCheck(url, callback, options);\n var timeout, timeoutId;\n var xhr = this.createXhr();\n options = options || {};\n timeout = utilities.isNumber(options.timeout) ? options.timeout : 0;\n\n xhr.open(method, urlUtils.urlParts(url).href, true);\n\n if (options.headers) {\n setHeaders(xhr, options.headers);\n }\n\n if (options.withCredentials) {\n xhr.withCredentials = true;\n }\n\n xhr.onload = function () {\n var statusText, response, status;\n\n /**\n * The only way to do a secure request on IE8 and IE9 is with the XDomainRequest object. Unfortunately, microsoft is\n * so nice that decided that the status property and the 'getAllResponseHeaders' method where not needed so we have to\n * fake them. If the request gets done with an XDomainRequest instance, we will assume that there are no headers and\n * the status will always be 200. If you don't like it, DO NOT USE ANCIENT BROWSERS!!!\n *\n * For mor info go to: https://msdn.microsoft.com/en-us/library/cc288060(v=vs.85).aspx\n */\n if (!xhr.getAllResponseHeaders) {\n xhr.getAllResponseHeaders = function () {\n return null;\n };\n }\n\n if (!xhr.status) {\n xhr.status = 200;\n }\n\n if (utilities.isDefined(timeoutId)) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n\n statusText = xhr.statusText || '';\n\n // responseText is the old-school way of retrieving response (supported by IE8 & 9)\n // response/responseType properties were introduced in XHR Level2 spec (supported by IE10)\n response = ('response' in xhr) ? xhr.response : xhr.responseText;\n\n // normalize IE9 bug (http://bugs.jquery.com/ticket/1450)\n status = xhr.status === 1223 ? 204 : xhr.status;\n\n callback(\n status,\n response,\n xhr.getAllResponseHeaders(),\n statusText);\n };\n\n xhr.onerror = requestError;\n xhr.onabort = requestError;\n\n xhr.send();\n\n if (timeout > 0) {\n timeoutId = setTimeout(function () {\n xhr && xhr.abort();\n }, timeout);\n }\n\n function sanityCheck(url, callback, options) {\n if (!utilities.isString(url) || utilities.isEmptyString(url)) {\n throw new HttpRequestError(\"Invalid url '\" + url + \"'\");\n }\n\n if (!utilities.isFunction(callback)) {\n throw new HttpRequestError(\"Invalid handler '\" + callback + \"' for the http request\");\n }\n\n if (utilities.isDefined(options) && !utilities.isObject(options)) {\n throw new HttpRequestError(\"Invalid options map '\" + options + \"'\");\n }\n }\n\n function setHeaders(xhr, headers) {\n utilities.forEach(headers, function (value, key) {\n if (utilities.isDefined(value)) {\n xhr.setRequestHeader(key, value);\n }\n });\n }\n\n function requestError() {\n callback(-1, null, null, '');\n }\n};\n\nHttpRequest.prototype.get = function (url, callback, options) {\n this.run('GET', url, processResponse, options);\n\n function processResponse(status, response, headersString, statusText) {\n if (isSuccess(status)) {\n callback(null, response, status, headersString, statusText);\n } else {\n callback(new HttpRequestError(statusText), response, status, headersString, statusText);\n }\n }\n\n function isSuccess(status) {\n return 200 <= status && status < 300;\n }\n};\n\nfunction createXhr() {\n var xhr = new XMLHttpRequest();\n if (!(\"withCredentials\" in xhr)) {\n // XDomainRequest for IE.\n xhr = new XDomainRequest();\n }\n return xhr;\n}\n\nvar http = new HttpRequest(createXhr);\n\nmodule.exports = {\n http: http,\n HttpRequest: HttpRequest,\n HttpRequestError: HttpRequestError,\n createXhr: createXhr\n};\n","'use strict';\n\nvar dom = require('./dom');\nvar utilities = require('./utilityFunctions');\n\nvar playerUtils = {};\n\n/**\n * Returns an object that captures the portions of player state relevant to\n * video playback. The result of this function can be passed to\n * restorePlayerSnapshot with a player to return the player to the state it\n * was in when this function was invoked.\n * @param {object} player The videojs player object\n */\nplayerUtils.getPlayerSnapshot = function getPlayerSnapshot(player) {\n var tech = player.el().querySelector('.vjs-tech');\n\n var snapshot = {\n ended: player.ended(),\n src: player.currentSrc(),\n currentTime: player.currentTime(),\n type: player.currentType(),\n playing: !player.paused(),\n suppressedTracks: getSuppressedTracks(player)\n };\n\n if (tech) {\n snapshot.nativePoster = tech.poster;\n snapshot.style = tech.getAttribute('style');\n }\n return snapshot;\n\n /**** Local Functions ****/\n function getSuppressedTracks(player) {\n var tracks = player.remoteTextTracks ? player.remoteTextTracks() : [];\n\n if (tracks && utilities.isArray(tracks.tracks_)) {\n tracks = tracks.tracks_;\n }\n\n if (!utilities.isArray(tracks)) {\n tracks = [];\n }\n\n var suppressedTracks = [];\n tracks.forEach(function (track) {\n suppressedTracks.push({\n track: track,\n mode: track.mode\n });\n track.mode = 'disabled';\n });\n\n return suppressedTracks;\n }\n};\n\n/**\n * Attempts to modify the specified player so that its state is equivalent to\n * the state of the snapshot.\n * @param {object} snapshot - the player state to apply\n */\nplayerUtils.restorePlayerSnapshot = function restorePlayerSnapshot(player, snapshot) {\n var tech = player.el().querySelector('.vjs-tech');\n var attempts = 20; // the number of remaining attempts to restore the snapshot\n\n if (snapshot.nativePoster) {\n tech.poster = snapshot.nativePoster;\n }\n\n if ('style' in snapshot) {\n // overwrite all css style properties to restore state precisely\n tech.setAttribute('style', snapshot.style || '');\n }\n\n if (hasSrcChanged(player, snapshot)) {\n\n // on ios7, fiddling with textTracks too early will cause safari to crash\n player.one('contentloadedmetadata', restoreTracks);\n\n player.one('canplay', tryToResume);\n ensureCanplayEvtGetsFired();\n\n // if the src changed for ad playback, reset it\n player.src({src: snapshot.src, type: snapshot.type});\n\n // safari requires a call to `load` to pick up a changed source\n player.load();\n\n } else {\n restoreTracks();\n\n if (snapshot.playing) {\n player.play();\n }\n }\n\n /*** Local Functions ***/\n\n /**\n * Sometimes firefox does not trigger the 'canplay' evt.\n * This code ensure that it always gets triggered triggered.\n */\n function ensureCanplayEvtGetsFired() {\n var timeoutId = setTimeout(function() {\n player.trigger('canplay');\n }, 1000);\n\n player.one('canplay', function(){\n clearTimeout(timeoutId);\n });\n }\n\n /**\n * Determine whether the player needs to be restored to its state\n * before ad playback began. With a custom ad display or burned-in\n * ads, the content player state hasn't been modified and so no\n * restoration is required\n */\n function hasSrcChanged(player, snapshot) {\n if (player.src()) {\n return player.src() !== snapshot.src;\n }\n // the player was configured through source element children\n return player.currentSrc() !== snapshot.src;\n }\n\n function restoreTracks() {\n var suppressedTracks = snapshot.suppressedTracks;\n suppressedTracks.forEach(function (trackSnapshot) {\n trackSnapshot.track.mode = trackSnapshot.mode;\n });\n }\n\n /**\n * Determine if the video element has loaded enough of the snapshot source\n * to be ready to apply the rest of the state\n */\n function tryToResume() {\n\n // if some period of the video is seekable, resume playback\n // otherwise delay a bit and then check again unless we're out of attempts\n\n if (!playerUtils.isReadyToResume(player) && attempts--) {\n setTimeout(tryToResume, 50);\n } else {\n try {\n if(player.currentTime() !== snapshot.currentTime) {\n if (snapshot.playing) { // if needed restore playing status after seek completes\n player.one('seeked', function() {\n player.play();\n });\n }\n player.currentTime(snapshot.currentTime);\n\n } else if (snapshot.playing) {\n // if needed and no seek has been performed, restore playing status immediately\n player.play();\n }\n\n } catch (e) {\n videojs.log.warn('Failed to resume the content after an advertisement', e);\n }\n }\n }\n};\n\nplayerUtils.isReadyToResume = function (player) {\n\n if (player.readyState() > 1) {\n // some browsers and media aren't \"seekable\".\n // readyState greater than 1 allows for seeking without exceptions\n return true;\n }\n\n if (player.seekable() === undefined) {\n // if the player doesn't expose the seekable time ranges, try to\n // resume playback immediately\n return true;\n }\n\n if (player.seekable().length > 0) {\n // if some period of the video is seekable, resume playback\n return true;\n }\n\n return false;\n};\n\n/**\n * This function prepares the player to display ads.\n * Adding convenience events like the 'vast.firsPlay' that gets fired when the video is first played\n * and ads the blackPoster to the player to prevent content from being displayed before the preroll ad.\n *\n * @param player\n */\nplayerUtils.prepareForAds = function (player) {\n var blackPoster = player.addChild('blackPoster');\n var _firstPlay = true;\n var volumeSnapshot;\n\n\n monkeyPatchPlayerApi();\n\n player.on('play', tryToTriggerFirstPlay);\n player.on('vast.reset', resetFirstPlay);//Every time we change the sources we reset the first play.\n player.on('vast.firstPlay', restoreContentVolume);\n player.on('error', hideBlackPoster);//If there is an error in the player we remove the blackposter to show the err msg\n player.on('vast.adStart', hideBlackPoster);\n player.on('vast.adsCancel', hideBlackPoster);\n player.on('vast.adError', hideBlackPoster);\n player.on('vast.adStart', addStyles);\n player.on('vast.adEnd', removeStyles);\n player.on('vast.adsCancel', removeStyles);\n\n /*** Local Functions ***/\n\n /**\n What this function does is ugly and horrible and I should think twice before calling myself a good developer. With that said,\n it is the best solution I could find to mute the video until the 'play' event happens (on mobile devices) and the plugin can decide whether\n to play the ad or not.\n\n We also need this monkeypatch to be able to pause and resume an ad using the player's API\n\n If you have a better solution please do tell me.\n */\n function monkeyPatchPlayerApi() {\n\n /**\n * Monkey patch needed to handle firstPlay and resume of playing ad.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are restoring a VAST ad.\n * @returns {player}\n */\n var origPlay = player.play;\n player.play = function (callOrigPlay) {\n var that = this;\n\n if (isFirstPlay()) {\n firstPlay();\n } else {\n resume(callOrigPlay);\n }\n\n return this;\n\n /*** local functions ***/\n function firstPlay() {\n if (!utilities.isIPhone()) {\n volumeSnapshot = saveVolumeSnapshot();\n player.muted(true);\n }\n\n origPlay.apply(that, arguments);\n }\n\n function resume(callOrigPlay) {\n if (isAdPlaying() && !callOrigPlay) {\n player.vast.adUnit.resumeAd();\n } else {\n origPlay.apply(that, arguments);\n }\n }\n };\n\n\n /**\n * Needed monkey patch to handle pause of playing ad.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are pausing a VAST ad.\n * @returns {player}\n */\n var origPause = player.pause;\n player.pause = function (callOrigPause) {\n if (isAdPlaying() && !callOrigPause) {\n player.vast.adUnit.pauseAd();\n } else {\n origPause.apply(this, arguments);\n }\n return this;\n };\n\n\n /**\n * Needed monkey patch to handle paused state of the player when ads are playing.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are pausing a VAST ad.\n * @returns {player}\n */\n var origPaused = player.paused;\n player.paused = function (callOrigPaused) {\n if (isAdPlaying() && !callOrigPaused) {\n return player.vast.adUnit.isPaused();\n }\n return origPaused.apply(this, arguments);\n };\n }\n\n function isAdPlaying() {\n return player.vast && player.vast.adUnit;\n }\n\n function tryToTriggerFirstPlay() {\n if (isFirstPlay()) {\n _firstPlay = false;\n player.trigger('vast.firstPlay');\n }\n }\n\n function resetFirstPlay() {\n _firstPlay = true;\n blackPoster.show();\n restoreContentVolume();\n }\n\n function isFirstPlay() {\n return _firstPlay;\n }\n\n function saveVolumeSnapshot() {\n return {\n muted: player.muted(),\n volume: player.volume()\n };\n }\n\n function restoreContentVolume() {\n if (volumeSnapshot) {\n player.currentTime(0);\n restoreVolumeSnapshot(volumeSnapshot);\n volumeSnapshot = null;\n }\n }\n\n function restoreVolumeSnapshot(snapshot) {\n if (utilities.isObject(snapshot)) {\n player.volume(snapshot.volume);\n player.muted(snapshot.muted);\n }\n }\n\n function hideBlackPoster() {\n if (!dom.hasClass(blackPoster.el(), 'vjs-hidden')) {\n blackPoster.hide();\n }\n }\n\n function addStyles() {\n dom.addClass(player.el(), 'vjs-ad-playing');\n }\n\n function removeStyles() {\n dom.removeClass(player.el(), 'vjs-ad-playing');\n }\n};\n\n/**\n * Remove the poster attribute from the video element tech, if present. When\n * reusing a video element for multiple videos, the poster image will briefly\n * reappear while the new source loads. Removing the attribute ahead of time\n * prevents the poster from showing up between videos.\n * @param {object} player The videojs player object\n */\nplayerUtils.removeNativePoster = function (player) {\n var tech = player.el().querySelector('.vjs-tech');\n if (tech) {\n tech.removeAttribute('poster');\n }\n};\n\n/**\n * Helper function to listen to many events until one of them gets fired, then we\n * execute the handler and unsubscribe all the event listeners;\n *\n * @param player specific player from where to listen for the events\n * @param events array of events\n * @param handler function to execute once one of the events fires\n */\nplayerUtils.once = function once(player, events, handler) {\n function listener() {\n handler.apply(null, arguments);\n\n events.forEach(function (event) {\n player.off(event, listener);\n });\n }\n\n events.forEach(function (event) {\n player.on(event, listener);\n });\n};\n\n\nmodule.exports = playerUtils;","'use strict';\n\nvar utilities = require('./utilityFunctions');\n\n/**\n *\n * IMPORTANT NOTE: This function comes from angularJs and was originally called urlResolve\n * you can take a look at the original code here https://github.com/angular/angular.js/blob/master/src/ng/urlUtils.js\n *\n * Implementation Notes for non-IE browsers\n * ----------------------------------------\n * Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM,\n * results both in the normalizing and parsing of the URL. Normalizing means that a relative\n * URL will be resolved into an absolute URL in the context of the application document.\n * Parsing means that the anchor node's host, hostname, protocol, port, pathname and related\n * properties are all populated to reflect the normalized URL. This approach has wide\n * compatibility - Safari 1+, Mozilla 1+, Opera 7+,e etc. See\n * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n *\n * Implementation Notes for IE\n * ---------------------------\n * IE >= 8 and <= 10 normalizes the URL when assigned to the anchor node similar to the other\n * browsers. However, the parsed components will not be set if the URL assigned did not specify\n * them. (e.g. if you assign a.href = \"foo\", then a.protocol, a.host, etc. will be empty.) We\n * work around that by performing the parsing in a 2nd step by taking a previously normalized\n * URL (e.g. by assigning to a.href) and assigning it a.href again. This correctly populates the\n * properties such as protocol, hostname, port, etc.\n *\n * IE7 does not normalize the URL when assigned to an anchor node. (Apparently, it does, if one\n * uses the inner HTML approach to assign the URL as part of an HTML snippet -\n * http://stackoverflow.com/a/472729) However, setting img[src] does normalize the URL.\n * Unfortunately, setting img[src] to something like \"javascript:foo\" on IE throws an exception.\n * Since the primary usage for normalizing URLs is to sanitize such URLs, we can't use that\n * method and IE < 8 is unsupported.\n *\n * References:\n * http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement\n * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n * http://url.spec.whatwg.org/#urlutils\n * https://github.com/angular/angular.js/pull/2902\n * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/\n *\n * @kind function\n * @param {string} url The URL to be parsed.\n * @description Normalizes and parses a URL.\n * @returns {object} Returns the normalized URL as a dictionary.\n *\n * | member name | Description |\n * |---------------|----------------|\n * | href | A normalized version of the provided URL if it was not an absolute URL |\n * | protocol | The protocol including the trailing colon |\n * | host | The host and port (if the port is non-default) of the normalizedUrl |\n * | search | The search params, minus the question mark |\n * | hash | The hash string, minus the hash symbol\n * | hostname | The hostname\n * | port | The port, without \":\"\n * | pathname | The pathname, beginning with \"/\"\n *\n */\n\nvar urlParsingNode = document.createElement(\"a\");\n/**\n * documentMode is an IE-only property\n * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx\n */\nvar msie = document.documentMode;\n\nfunction urlParts(url) {\n var href = url;\n\n if (msie) {\n // Normalize before parse. Refer Implementation Notes on why this is\n // done in two steps on IE.\n urlParsingNode.setAttribute(\"href\", href);\n href = urlParsingNode.href;\n }\n\n urlParsingNode.setAttribute('href', href);\n\n // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n return {\n href: urlParsingNode.href,\n protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n host: urlParsingNode.host,\n search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n hostname: urlParsingNode.hostname,\n port: utilities.isNotEmptyString(urlParsingNode.port)? urlParsingNode.port: 80,\n pathname: (urlParsingNode.pathname.charAt(0) === '/')\n ? urlParsingNode.pathname\n : '/' + urlParsingNode.pathname\n };\n}\n\n\n/**\n * This function accepts a query string (search part of a url) and returns a dictionary with\n * the different key value pairs\n * @param {string} qs queryString\n */\nfunction queryStringToObj(qs, cond) {\n var pairs, qsObj;\n\n cond = utilities.isFunction(cond)? cond : function() {\n return true;\n };\n\n qs = qs.trim().replace(/^\\?/, '');\n pairs = qs.split('&');\n qsObj = {};\n\n utilities.forEach(pairs, function (pair) {\n var keyValue, key, value;\n if (pair !== '') {\n keyValue = pair.split('=');\n key = keyValue[0];\n value = keyValue[1];\n if(cond(key, value)){\n qsObj[key] = value;\n }\n }\n });\n\n return qsObj;\n}\n\n/**\n * This function accepts an object and serializes it into a query string without the leading '?'\n * @param obj\n * @returns {string}\n */\nfunction objToQueryString(obj) {\n var pairs = [];\n utilities.forEach(obj, function (value, key) {\n pairs.push(key + '=' + value);\n });\n return pairs.join('&');\n}\n\nmodule.exports = {\n urlParts: urlParts,\n queryStringToObj: queryStringToObj,\n objToQueryString: objToQueryString\n};\n","/*jshint unused:false */\n\"use strict\";\n\nvar NODE_TYPE_ELEMENT = 1;\nvar SNAKE_CASE_REGEXP = /[A-Z]/g;\nvar EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/i;\n/*jslint maxlen: 500 */\nvar ISO8086_REGEXP = /^([\\+-]?\\d{4}(?!\\d{2}\\b))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))([T\\s]((([01]\\d|2[0-3])((:?)[0-5]\\d)?|24\\:?00)([\\.,]\\d+(?!:))?)?(\\17[0-5]\\d([\\.,]\\d+)?)?([zZ]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)?$/;\n\n\nfunction noop(){ }\n\nfunction isNull(o) {\n return o === null;\n}\n\nfunction isDefined(o){\n return o !== undefined;\n}\n\nfunction isUndefined(o){\n return o === undefined;\n}\n\nfunction isObject(obj) {\n return typeof obj === 'object';\n}\n\nfunction isFunction(str){\n return typeof str === 'function';\n}\n\nfunction isNumber(num){\n return typeof num === 'number';\n}\n\nfunction isWindow(obj) {\n return utilities.isObject(obj) && obj.window === obj;\n}\n\nfunction isArray(array){\n return Object.prototype.toString.call( array ) === '[object Array]';\n}\n\nfunction isArrayLike(obj) {\n if (obj === null || utilities.isWindow(obj) || utilities.isFunction(obj) || utilities.isUndefined(obj)) {\n return false;\n }\n\n var length = obj.length;\n\n if (obj.nodeType === NODE_TYPE_ELEMENT && length) {\n return true;\n }\n\n return utilities.isString(obj) || utilities.isArray(obj) || length === 0 ||\n typeof length === 'number' && length > 0 && (length - 1) in obj;\n}\n\nfunction isString(str){\n return typeof str === 'string';\n}\n\nfunction isEmptyString(str) {\n return utilities.isString(str) && str.length === 0;\n}\n\nfunction isNotEmptyString(str) {\n return utilities.isString(str) && str.length !== 0;\n}\n\nfunction arrayLikeObjToArray(args) {\n return Array.prototype.slice.call(args);\n}\n\nfunction forEach(obj, iterator, context) {\n var key, length;\n if (obj) {\n if (isFunction(obj)) {\n for (key in obj) {\n // Need to check if hasOwnProperty exists,\n // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function\n if (key !== 'prototype' && key !== 'length' && key !== 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n } else if (isArray(obj)) {\n var isPrimitive = typeof obj !== 'object';\n for (key = 0, length = obj.length; key < length; key++) {\n if (isPrimitive || key in obj) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n } else if (obj.forEach && obj.forEach !== forEach) {\n obj.forEach(iterator, context, obj);\n } else {\n for (key in obj) {\n if (obj.hasOwnProperty(key)) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n }\n }\n return obj;\n}\n\nfunction snake_case(name, separator) {\n separator = separator || '_';\n return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {\n return (pos ? separator : '') + letter.toLowerCase();\n });\n}\n\nfunction isValidEmail(email){\n if(!utilities.isString(email)){\n return false;\n }\n\n return EMAIL_REGEXP.test(email.trim());\n}\n\nfunction extend (obj) {\n var arg, i, k;\n for (i = 1; i < arguments.length; i++) {\n arg = arguments[i];\n for (k in arg) {\n if (arg.hasOwnProperty(k)) {\n if(isObject(obj[k]) && !isNull(obj[k]) && isObject(arg[k])){\n obj[k] = extend({}, obj[k], arg[k]);\n }else {\n obj[k] = arg[k];\n }\n }\n }\n }\n return obj;\n}\n\nfunction capitalize(s){\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nfunction decapitalize(s) {\n return s.charAt(0).toLowerCase() + s.slice(1);\n}\n\n/**\n * This method works the same way array.prototype.map works but if the transformer returns undefine, then\n * it won't be added to the transformed Array.\n */\nfunction transformArray(array, transformer) {\n var transformedArray = [];\n\n array.forEach(function(item, index){\n var transformedItem = transformer(item, index);\n if(utilities.isDefined(transformedItem)) {\n transformedArray.push(transformedItem);\n }\n });\n\n return transformedArray;\n}\n\nfunction toFixedDigits(num, digits) {\n var formattedNum = num + '';\n digits = utilities.isNumber(digits) ? digits : 0;\n num = utilities.isNumber(num) ? num : parseInt(num, 10);\n if(utilities.isNumber(num) && !isNaN(num)){\n formattedNum = num + '';\n while(formattedNum.length < digits) {\n formattedNum = '0' + formattedNum;\n }\n return formattedNum;\n }\n return NaN + '';\n}\n\nfunction throttle(callback, delay) {\n var previousCall = new Date().getTime() - (delay + 1);\n return function() {\n var time = new Date().getTime();\n if ((time - previousCall) >= delay) {\n previousCall = time;\n callback.apply(this, arguments);\n }\n };\n}\n\nfunction debounce (callback, wait) {\n var timeoutId;\n\n return function (){\n if(timeoutId) {\n clearTimeout(timeoutId);\n }\n timeoutId = setTimeout(function(){\n callback.apply(this, arguments);\n timeoutId = undefined;\n }, wait);\n };\n}\n\n// a function designed to blow up the stack in a naive way\n// but it is ok for videoJs children components\nfunction treeSearch(root, getChildren, found){\n var children = getChildren(root);\n for (var i = 0; i < children.length; i++){\n if (found(children[i])) {\n return children[i];\n }\n else {\n var el = treeSearch(children[i], getChildren, found);\n if (el){\n return el;\n }\n }\n }\n}\n\nfunction echoFn(val) {\n return function () {\n return val;\n };\n}\n\n//Note: Supported formats come from http://www.w3.org/TR/NOTE-datetime\n// and the iso8601 regex comes from http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/\nfunction isISO8601(value) {\n if(utilities.isNumber(value)){\n value = value + ''; //we make sure that we are working with strings\n }\n\n if(!utilities.isString(value)){\n return false;\n }\n\n return ISO8086_REGEXP.test(value.trim());\n}\n\n/**\n * Checks if the Browser is IE9 and below\n * @returns {boolean}\n */\nfunction isOldIE() {\n var version = utilities.getInternetExplorerVersion(navigator);\n if (version === -1) {\n return false;\n }\n\n return version < 10;\n}\n\n/**\n * Returns the version of Internet Explorer or a -1 (indicating the use of another browser).\n * Source: https://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx\n * @returns {number} the version of Internet Explorer or a -1 (indicating the use of another browser).\n */\nfunction getInternetExplorerVersion(navigator) {\n var rv = -1;\n\n if (navigator.appName == 'Microsoft Internet Explorer') {\n var ua = navigator.userAgent;\n var re = new RegExp(\"MSIE ([0-9]{1,}[\\.0-9]{0,})\");\n var res = re.exec(ua);\n if (res !== null) {\n rv = parseFloat(res[1]);\n }\n }\n\n return rv;\n}\n\n/*** Mobile Utility functions ***/\nfunction isIDevice() {\n return /iP(hone|ad)/.test(utilities._UA);\n}\n\nfunction isMobile() {\n return /iP(hone|ad|od)|Android|Windows Phone/.test(utilities._UA);\n}\n\nfunction isIPhone() {\n return /iP(hone|od)/.test(utilities._UA);\n}\n\nfunction isAndroid() {\n return /Android/.test(utilities._UA);\n}\n\nvar utilities = {\n _UA: navigator.userAgent,\n noop: noop,\n isNull: isNull,\n isDefined: isDefined,\n isUndefined: isUndefined,\n isObject: isObject,\n isFunction: isFunction,\n isNumber: isNumber,\n isWindow: isWindow,\n isArray: isArray,\n isArrayLike: isArrayLike,\n isString: isString,\n isEmptyString: isEmptyString,\n isNotEmptyString: isNotEmptyString,\n arrayLikeObjToArray: arrayLikeObjToArray,\n forEach: forEach,\n snake_case: snake_case,\n isValidEmail: isValidEmail,\n extend: extend,\n capitalize: capitalize,\n decapitalize: decapitalize,\n transformArray: transformArray,\n toFixedDigits: toFixedDigits,\n throttle: throttle,\n debounce: debounce,\n treeSearch: treeSearch,\n echoFn: echoFn,\n isISO8601: isISO8601,\n isOldIE: isOldIE,\n getInternetExplorerVersion: getInternetExplorerVersion,\n isIDevice: isIDevice,\n isMobile: isMobile,\n isIPhone: isIPhone,\n isAndroid: isAndroid\n};\n\nmodule.exports = utilities;","'use strict';\n\nvar utilities = require('./utilityFunctions');\n\nvar xml = {};\n\nxml.strToXMLDoc = function strToXMLDoc(stringContainingXMLSource){\n //IE 8\n if(typeof window.DOMParser === 'undefined'){\n var xmlDocument = new ActiveXObject('Microsoft.XMLDOM');\n xmlDocument.async = false;\n xmlDocument.loadXML(stringContainingXMLSource);\n return xmlDocument;\n }\n\n return parseString(stringContainingXMLSource);\n\n function parseString(stringContainingXMLSource){\n var parser = new DOMParser();\n var parsedDocument;\n\n //Note: This try catch is to deal with the fact that on IE parser.parseFromString does throw an error but the rest of the browsers don't.\n try {\n parsedDocument = parser.parseFromString(stringContainingXMLSource, \"application/xml\");\n\n if(isParseError(parsedDocument) || utilities.isEmptyString(stringContainingXMLSource)){\n throw new Error();\n }\n }catch(e){\n throw new Error(\"xml.strToXMLDOC: Error parsing the string: '\" + stringContainingXMLSource + \"'\");\n }\n\n return parsedDocument;\n }\n\n function isParseError(parsedDocument) {\n try { // parser and parsererrorNS could be cached on startup for efficiency\n var parser = new DOMParser(),\n erroneousParse = parser.parseFromString('INVALID', 'text/xml'),\n parsererrorNS = erroneousParse.getElementsByTagName(\"parsererror\")[0].namespaceURI;\n\n if (parsererrorNS === 'http://www.w3.org/1999/xhtml') {\n // In PhantomJS the parseerror element doesn't seem to have a special namespace, so we are just guessing here :(\n return parsedDocument.getElementsByTagName(\"parsererror\").length > 0;\n }\n\n return parsedDocument.getElementsByTagNameNS(parsererrorNS, 'parsererror').length > 0;\n } catch (e) {\n //Note on IE parseString throws an error by itself and it will never reach this code. Because it will have failed before\n }\n }\n};\n\nxml.parseText = function parseText (sValue) {\n if (/^\\s*$/.test(sValue)) { return null; }\n if (/^(?:true|false)$/i.test(sValue)) { return sValue.toLowerCase() === \"true\"; }\n if (isFinite(sValue)) { return parseFloat(sValue); }\n if (utilities.isISO8601(sValue)) { return new Date(sValue); }\n return sValue.trim();\n};\n\nxml.JXONTree = function JXONTree (oXMLParent) {\n var parseText = xml.parseText;\n\n //The document object is an especial object that it may miss some functions or attrs depending on the browser.\n //To prevent this problem with create the JXONTree using the root childNode which is a fully fleshed node on all supported\n //browsers.\n if(oXMLParent.documentElement){\n return new xml.JXONTree(oXMLParent.documentElement);\n }\n\n if (oXMLParent.hasChildNodes()) {\n var sCollectedTxt = \"\";\n for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {\n oNode = oXMLParent.childNodes.item(nItem);\n /*jshint bitwise: false*/\n if ((oNode.nodeType - 1 | 1) === 3) { sCollectedTxt += oNode.nodeType === 3 ? oNode.nodeValue.trim() : oNode.nodeValue; }\n else if (oNode.nodeType === 1 && !oNode.prefix) {\n sProp = utilities.decapitalize(oNode.nodeName);\n vContent = new xml.JXONTree(oNode);\n if (this.hasOwnProperty(sProp)) {\n if (this[sProp].constructor !== Array) { this[sProp] = [this[sProp]]; }\n this[sProp].push(vContent);\n } else { this[sProp] = vContent; }\n }\n }\n if (sCollectedTxt) { this.keyValue = parseText(sCollectedTxt); }\n }\n\n //IE8 Stupid fix\n var hasAttr = typeof oXMLParent.hasAttributes === 'undefined'? oXMLParent.attributes.length > 0: oXMLParent.hasAttributes();\n if (hasAttr) {\n var oAttrib;\n for (var nAttrib = 0; nAttrib < oXMLParent.attributes.length; nAttrib++) {\n oAttrib = oXMLParent.attributes.item(nAttrib);\n this[\"@\" + utilities.decapitalize(oAttrib.name)] = parseText(oAttrib.value.trim());\n }\n }\n};\n\nxml.JXONTree.prototype.attr = function(attr) {\n return this['@' + utilities.decapitalize(attr)];\n};\n\nxml.toJXONTree = function toJXONTree(xmlString){\n var xmlDoc = xml.strToXMLDoc(xmlString);\n return new xml.JXONTree(xmlDoc);\n};\n\n/**\n * Helper function to extract the keyvalue of a JXONTree obj\n *\n * @param xmlObj {JXONTree}\n * return the key value or undefined;\n */\nxml.keyValue = function getKeyValue(xmlObj) {\n if(xmlObj){\n return xmlObj.keyValue;\n }\n return undefined;\n};\n\nxml.attr = function getAttrValue(xmlObj, attr) {\n if(xmlObj) {\n return xmlObj['@' + utilities.decapitalize(attr)];\n }\n return undefined;\n};\n\nxml.encode = function encodeXML(str) {\n return str.replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n};\n\nxml.decode = function decodeXML(str) {\n return str.replace(/'/g, \"'\")\n .replace(/"/g, '\"')\n .replace(/>/g, '>')\n .replace(/</g, '<')\n .replace(/&/g, '&');\n};\n\nmodule.exports = xml;","'use strict';\n\nrequire('./plugin/components/ads-label_4');\nrequire('./plugin/components/black-poster_4');\n\nvar videoJsVAST = require('./plugin/videojs.vast.vpaid');\n\nvideojs.plugin('vastClient', videoJsVAST);\n\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["node_modules/browser-pack/_prelude.js","bower_components/VPAIDFLASHClient/js/IVPAIDAdUnit.js","videojs_4.vast.vpaid.js","bower_components/VPAIDFLASHClient/js/VPAIDAdUnit.js","bower_components/VPAIDFLASHClient/js/VPAIDFLASHClient.js","bower_components/VPAIDFLASHClient/js/jsFlashBridge.js","bower_components/VPAIDFLASHClient/js/jsFlashBridgeRegistry.js","bower_components/VPAIDFLASHClient/js/registry.js","bower_components/VPAIDFLASHClient/js/utils.js","bower_components/VPAIDHTML5Client/js/IVPAIDAdUnit.js","bower_components/VPAIDHTML5Client/js/VPAIDAdUnit.js","bower_components/VPAIDHTML5Client/js/VPAIDHTML5Client.js","bower_components/VPAIDHTML5Client/js/subscriber.js","bower_components/VPAIDHTML5Client/js/utils.js","src/scripts/ads/vast/Ad.js","src/scripts/ads/vast/Companion.js","src/scripts/ads/vast/Creative.js","src/scripts/ads/vast/InLine.js","src/scripts/ads/vast/Linear.js","src/scripts/ads/vast/MediaFile.js","src/scripts/ads/vast/TrackingEvent.js","src/scripts/ads/vast/VASTClient.js","src/scripts/ads/vast/VASTError.js","src/scripts/ads/vast/VASTIntegrator.js","src/scripts/ads/vast/VASTResponse.js","src/scripts/ads/vast/VASTTracker.js","src/scripts/ads/vast/VideoClicks.js","src/scripts/ads/vast/Wrapper.js","src/scripts/ads/vast/parsers.js","src/scripts/ads/vast/vastUtil.js","src/scripts/ads/vpaid/VPAIDAdUnitWrapper.js","src/scripts/ads/vpaid/VPAIDFlashTech.js","src/scripts/ads/vpaid/VPAIDHTML5Tech.js","src/scripts/ads/vpaid/VPAIDIntegrator.js","src/scripts/plugin/components/ads-label.js","src/scripts/plugin/components/ads-label_4.js","src/scripts/plugin/components/black-poster.js","src/scripts/plugin/components/black-poster_4.js","src/scripts/plugin/videojs.vast.vpaid.js","src/scripts/utils/async.js","src/scripts/utils/dom.js","src/scripts/utils/http.js","src/scripts/utils/playerUtils.js","src/scripts/utils/urlUtils.js","src/scripts/utils/utilityFunctions.js","src/scripts/utils/xml.js","src/scripts/videojs_4.vast.vpaid.js"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length",1,"module","_createClass","defineProperties","target","props","descriptor","enumerable","configurable","writable","Object","defineProperty","key","Constructor","protoProps","staticProps","prototype","value","_classCallCheck","instance","TypeError","IVPAIDAdUnit","this","handshakeVersion","playerVPAIDVersion","arguments","undefined","callback","initAd","width","height","viewMode","desiredBitrate","creativeData","AdParameters","environmentVars","flashVars","resizeAd","startAd","stopAd","pauseAd","resumeAd","expandAd","collapseAd","skipAd","getAdLinear","getAdWidth","getAdHeight","getAdExpanded","getAdSkippableState","getAdRemainingTime","getAdDuration","setAdVolume","soundVolume","getAdVolume","getAdCompanions","getAdIcons",2,"_possibleConstructorReturn","self","ReferenceError","_inherits","subClass","superClass","create","constructor","setPrototypeOf","__proto__","ALL_VPAID_METHODS","getOwnPropertyNames","filter","property","indexOf","VPAIDAdUnit","_IVPAIDAdUnit","flash","_this","getPrototypeOf","_destroyed","_flash","_destroy","_this2","forEach","methodName","removeCallbackByMethodName","EVENTS","event","offEvent","isDestroyed","on","eventName","off","callFlashMethod","setSize","getWidth","getHeight","volume","./IVPAIDAdUnit",3,"JSFlashBridge","noop","callbackTimeout","isPositiveInt","createElementWithID","uniqueVPAID","unique","ERROR","FLASH_VERSION","VPAIDFLASHClient","vpaidParentEl","swfConfig","data","params","wmode","salign","align","allowScriptAccess","scale","allowFullScreen","quality","vpaidOptions","debug","timeout","hasExternalDependencies","onError","_vpaidParentEl","_flashID","movie","FlashVars","VPAID_FLASH_HANDLER","isSupported","el","swfobject","createSWF","handler","err","$loadPendedAdUnit","error","setTimeout","destroy","_destroyAdUnit","_loadLater","_adUnitLoad","removeCallback","_adUnit","loadAdUnit","adURL","$throwIfDestroyed","isReady","message","url","unloadAdUnit","getFlashID","getFlashURL","setStaticProperty","hasFlashPlayerVersion","window","propertyName","./VPAIDAdUnit","./jsFlashBridge","./utils",4,"stringEndsWith","SingleValueRegistry","MultipleValuesRegistry","registry","flashURL","flashID","loadHandShake","_el","_flashURL","_width","_height","_handlers","_callbacks","_uniqueMethodIdentifier","_ready","_handShakeHandler","addInstance","add","remove","removeByKey","offAll","removeAll","args","callbackID","concat","$asyncCallback","_trigger","removeByValue","suffix","filterKeys","removeAllCallbacks","get","_callCallback","result","trigger","_handShake","getSize","newWidth","newHeight","setAttribute","setWidth","setHeight","removeInstanceByID","parentElement","removeChild","_this3","typeID","typeName","getInstanceByID","./jsFlashBridgeRegistry","./registry",5,"instances","JSFlashBridgeRegistry","id",6,"_registries","push","keys","findByValue","index","splice","old","map","size","_this4",7,"prefix","count","timer","onSuccess","onTimeout","clearTimeout","apply","parent","nEl","document","createElement","innerHTML","appendChild","newVal","oldVal","isNaN","parseFloat","isFinite","endsWith","String","searchString","position","subjectString","toString","lastIndex","string","search",8,"METHODS","GETTERS","SETTERS","creative","video","VPAIDVersion","subscribe","context","unsubscribe","addStaticToInterface","VPAID1_METHODS","method","checkVPAIDInterface","every","Interface","name",9,"Subscriber","utils","AD_CLICK","FILTERED_EVENTS","VPAIDCreative","iframe","_isValid","_creative","_videoEl","_iframe","_subscribers","$addEventsSubscribers","isValidVPAIDAd","ignores","ariaty","Array","slice","pop","callOrTriggerEvent","bind","extend","slot","videoSlot","getter","validate","unsubscribeAll","$trigger","$clickThruHook","documentElement","contentDocument","videoEl","addEventListener","click","playerHandles","triggerSync","subscribers","./subscriber",10,"defaultTemplate","AD_STOPPED","VPAIDHTML5Client","templateConfig","_id","_frameContainer","createElementInEl","_vpaidOptions","_templateConfig","template","extraOptions","$unloadPreviousAdUnit","frame","createIframeWithContent","iframeURL_JS","iframeID","getID","_frame","_onLoad","onLoad","origin","location","JSON","parse","adUnit","createAd","contentWindow","getVPAIDAd","adEl","querySelector","$adDestroyed","$destroyLoadListener","$removeEl","$removeAdElements","$destroyAdUnit","removeEventListener","clearCallbackTimeout",11,"subscriber","that",12,"isValid","timeouts","func","tagName","createIframe","setIframeContent","simpleTemplate","src","marginWidth","marginHeight","frameBorder","style","left","top","margin","padding","border","stringify","replace","RegExp","iframeEl","content","iframeDoc","write","toExtend","fromSource",13,"InLine","Wrapper","Ad","adJTree","initialize","attr","sequence","inLine","wrapper","./InLine","./Wrapper",14,"TrackingEvent","utilities","xml","Companion","companionJTree","creativeType","staticResource","keyValue","htmlResource","HTMLResource","hTMLResource","iframeResource","IFrameResource","iFrameresource","expandedWidth","expandedHeight","scalable","maintainAspectRatio","minSuggestedDuration","apiFramework","companionClickThrough","trackingEvents","parseTrackingEvents","tracking","trackings","isDefined","isArray","trackingData","../../utils/utilityFunctions","../../utils/xml","./TrackingEvent",15,"Linear","Creative","creativeJTree","adId","linear","companionAds","companions","companion","companionData","./Companion","./Linear",16,"vastUtil","inlineJTree","adTitle","adSystem","impressions","parseImpressions","impression","creatives","parseCreatives","description","advertiser","surveys","parseSurveys","survey","pricing","extensions","inlineSurveys","transformArray","isNotEmptyString","uri","type","./vastUtil",17,"MediaFile","VideoClicks","parsers","linearJTree","duration","mediaFiles","parseMediaFiles","mediaFile","skipoffset","offset","videoClicks","adParameters","decode","mediaFilesJxonTree","mfData","./MediaFile","./VideoClicks","./parsers",18,"attributesList","mediaFileJTree","x","attribute",19,"trackingJTree",20,"VASTError","VASTResponse","async","http","VASTClient","options","defaultOptions","WRAPPER_LIMIT","settings","errorURLMacros","getVASTResponse","adTagUrl","sanityCheck","isFunction","waterfall","_getVASTAd","buildVASTResponse","adsChain","cb","response","_buildVASTResponse","getAdWaterfall","vastTree","waterfallAds","ads","_trackError","getAd","shift","waterfallHandler","adChain","requestVastXML","_requestVASTXml","buildVastWaterfall","xmlStr","toJXONTree","ad","validateVASTTree","vastVersion","next","isString","requestVASTAd","buildAd","VASTAdTagURI","adJxonTree","validateAd","errMsgPrefix","requestVASTXml","requestHandler","withCredentials","status","errMsg","addAdsToResponse","validateResponse","addAd","progressEvents","progress","hasLinear","progressEvent","isNumber","addErrorUrlMacros","track","ERRORCODE","../../utils/async","../../utils/http","./Ad","./VASTError","./VASTResponse",21,22,"VASTTracker","dom","playerUtils","VASTIntegrator","player","playAd","vastResponse","_selectAdSource","_createVASTTracker","_addClickThrough","_addSkipButton","_setupEvents","_playSelectedAd","_src","pause","play","isPaused","paused","getSrc","selectAdSource","source","playerWidth","getDimension","sort","compareTo","b","deltaA","Math","abs","deltaB","selectSource","createVASTTracker","adMediaFile","setupEvents","tracker","previouslyMuted","trackFullscreenChange","trackImpressions","trackPause","trackProgress","trackVolumeChange","once","unbindEvents","evt","trackComplete","isFullscreen","trackFullscreen","trackExitFullscreen","currentTime","trackResume","currentTimeInMs","trackCreativeView","muted","trackMute","trackUnmute","addSkipButton","skipOffsetInSec","addSkipButtonToPlayer","skipOffset","skipButton","createSkipButton","updateSkipButton","updateSkipButtonState","removeSkipButton","addClass","onclick","hasClass","trackSkip","Event","stopPropagation","timeLeft","ceil","toFixedDigits","addClickThrough","blocker","createClickThroughBlocker","updateBlocker","updateBlockerURL","insertBefore","controlBar","removeBlocker","clickThroughMacro","clickThrough","href","generateClickThroughURL","trackClick","variables","ASSETURI","CONTENTPLAYHEAD","formatProgress","parseURLMacro","playSelectedAd","preload","trackError","../../utils/dom","../../utils/playerUtils","./VASTTracker",23,"InLine__A","_linearAdded","clickTrackings","customClicks","_addInLine","_addWrapper","_addErrorTrackUrl","errorURL","JXONTree","_addImpressions","appendToArray","_addClickTrackings","_addCustomClicks","_addTrackingEvents","eventsMap","trackingEvent","_addTitle","title","_addDuration","_addVideoClicks","_addMediaFiles","_addSkipoffset","_addAdParameters","_addLinear","array","items","item",24,"assetURI","quartiles","firstQuartile","tracked","time","round","midpoint","thirdQuartile","isEmptyString","trackURLs","urls","trackEvent","trackOnce","getEventUris","uris","newProgressInMs","events","ONCE","ALWAYS","addTrackEvent","hasRewound","addQuartileEvents","trackProgressEvents","trackEvents","currentProgress","newProgress","REWIND_THRESHOLD","canBeAdded","trackQuartile","quartileName","quartile","canBeTracked","quartileTime","pendingProgressEvts","capitalize","trackErrorWithCode","errorcode",25,"videoClickJTree","parseClickTrackings","clickTracking","customClick","clickTrackingData",26,"wrapperJTree","vASTAdTagURI","followAdditionalWrappers","allowMultipleAds","fallbackOnNoAd",27,"durationRegex","parseDuration","durationStr","match","durationInMs","parseHoursToMs","parseMinToMs","parseSecToMs","parseInt","hourStr","minStr","secStr","parseOffset","isPercentage","calculatePercentage","percentageRegex","test","percentStr","calcPercent","quantity","percent",28,"URLMacros","sources","parseURLMacros","trackImgs","img","Image","parseMacros","parsedURLs","random","URLMacro","_parseURLMacro","parseMacro","creativesJTree","creativesData","hours","minutes","seconds","milliseconds","floor","isVPAID","isVPAIDMediaFile","./Creative",29,"VPAIDAdUnitWrapper","vpaidAdUnit","opts","isObject","responseTimeout","VPAIDInterfaceMethods","len","canSubscribeToEvents","canUnsubscribeFromEvents","adUnitAsyncCall","arrayLikeObjToArray","timeoutId","wrapCallback","evtName","waitForEvent","responseListener","unshift","version","adUnitData","getterName","../vast/VASTError",30,"VPAIDFlashTech","containerEl","vpaidFlashClient","supports","loadFlashCreative","objectEl","flashClientOpts","vpaidFlashLoaderPath","container","isDomElement","console","log","VPAIDFLASHClient/js/VPAIDFLASHClient",31,"VPAIDHTML5Tech","vpaidHTMLClient","INVALID_MEDIA_FILE","isOldIE","INVALID_DOM_CONTAINER_EL","toLowerCase","MISSING_CALLBACK","PREFIX","INVALID_DOM_VIDEO_EL","VPAIDHTML5Client/js/VPAIDHTML5Client",32,"VPAIDIntegrator","VIEW_MODE","NORMAL","FULLSCREEN","THUMBNAIL","createVPAIDContainerEl","VPAID_VERSION","techs","playVPaidAd","tech","_findSupportedTech","triggerVpaidAdEnd","one","removeAdUnit","_loadAdUnit","_playAdUnit","_finishPlaying","_paused","removeClass","vpaidMediaFiles","VPAIDTech","findSupportedTech","mediafile","_createVPAIDAdUnitWrapper","vjsTechEl","WrappedAdUnit","techClass","_handshake","_initAd","_linkPlayerControls","_startAd","handshake","isSupportedVersion","majorNum","major","parts","split","dimension","adUnitSrc","notifyPlayToPlayer","trackStart","notifyPauseToPlayer","trackFirstQuartile","trackMidpoint","trackThirdQuartile","clickThruUrl","open","trackAcceptInvitation","trackAcceptInvitationLinear","trackClose","trackCloseLinear","trackCollapse","lastVolume","currentVolume","updateViewSize","updateViewSizeThrottled","throttle","autoResize","pauseAdUnit","resumeAdUnit","isSkippable","linkVolumeControl","linkFullScreenControl","updateAdUnitVolume","updatePlayerVolume","vol","logError","finishPlayingAd","MODE","../vast/VASTResponse","../vast/VASTTracker","../vast/vastUtil","./VPAIDAdUnitWrapper","./VPAIDFlashTech","./VPAIDHTML5Tech",33,"element","className","AdsLabelFactory","baseComponent","init","currentTimeComp","getChild","getElement",34,"baseVideoJsComponent","videojs","Component","AdsLabel","./ads-label",35,"BlackPosterFactory","posterImg",36,"BlackPoster","./black-poster",37,"VASTPlugin","snapshot","vast","adsCanceled","defaultOpts","iosPrerollCancelTimeout","adCancelTimeout","playAdAlways","adsEnabled","isUndefined","echoFn","adTagXML","trackAdError","prepareForAds","tryToPlayPrerollAd","cancelAds","isEnabled","enable","disable","removeNativePoster","restoreVideoContent","checkAdsEnabled","preparePlayerForAd","startAdCancelTimeout","playPrerollAd","setupContentEvents","restorePlayerSnapshot","canPlayPrerollAd","getPlayerSnapshot","addSpinnerIcon","isIPhone","adCancelTimeoutId","clearAdCancelTimeout","removeSpinnerIcon","getVastResponse","adIntegrator","adFinished","addAdsLabel","removeAdsLabel","isIDevice","preventManualProgress","addChild","PROGRESS_THRESHOLD","previousTime","skipad_attempts","adTimeupdateHandler","stopPreventManualProgress","progressDelta","../ads/vast/VASTClient","../ads/vast/VASTError","../ads/vast/VASTIntegrator","../ads/vast/vastUtil","../ads/vpaid/VPAIDIntegrator","../utils/async","../utils/dom","../utils/playerUtils","../utils/utilityFunctions",38,"setImmediate","fn","iterator","tasks","makeCallback","wrapIterator","when","condition","isAllowed","./utilityFunctions",39,"isVisible","getComputedStyle","visibility","isHidden","display","isShown","hide","__prev_style_display_","show","cssClass","classes","classList","contains","getAttribute","join","newClasses","attachEvent","detachEvent","dispatchEvent","fireEvent","eventType","isDescendant","child","node","parentNode","getTextContent","textContent","text","prependChild","firstChild","removeNode","Element","handlerWrap","rect","getBoundingClientRect","offsetWidth","offsetHeight",40,"urlUtils","HttpRequestError","HttpRequest","createXhr","run","xhr","urlParts","headers","setHeaders","onload","statusText","getAllResponseHeaders","responseText","onerror","requestError","onabort","send","abort","setRequestHeader","processResponse","headersString","isSuccess","XMLHttpRequest","XDomainRequest","./urlUtils",41,"ended","currentSrc","currentType","playing","suppressedTracks","getSuppressedTracks","nativePoster","poster","tracks","remoteTextTracks","tracks_","mode","attempts","hasSrcChanged","restoreTracks","tryToResume","ensureCanplayEvtGetsFired","load","trackSnapshot","isReadyToResume","warn","readyState","seekable","blackPoster","_firstPlay","volumeSnapshot","monkeyPatchPlayerApi","tryToTriggerFirstPlay","resetFirstPlay","restoreContentVolume","hideBlackPoster","addStyles","removeStyles","origPlay","callOrigPlay","isFirstPlay","firstPlay","resume","saveVolumeSnapshot","isAdPlaying","origPause","callOrigPause","origPaused","callOrigPaused","restoreVolumeSnapshot","removeAttribute","listener","./dom",42,"urlParsingNode","msie","documentMode","protocol","host","hash","hostname","port","pathname","charAt","queryStringToObj","qs","cond","pairs","qsObj","trim","pair","objToQueryString","obj",43,"NODE_TYPE_ELEMENT","SNAKE_CASE_REGEXP","EMAIL_REGEXP","ISO8086_REGEXP","isNull","str","num","isWindow","isArrayLike","nodeType","hasOwnProperty","isPrimitive","snake_case","separator","letter","pos","isValidEmail","email","arg","k","toUpperCase","decapitalize","transformer","transformedArray","transformedItem","digits","formattedNum","NaN","delay","previousCall","Date","getTime","debounce","wait","treeSearch","root","getChildren","found","children","val","isISO8601","getInternetExplorerVersion","navigator","rv","appName","ua","userAgent","re","res","exec","_UA","isMobile","isAndroid",44,"strToXMLDoc","stringContainingXMLSource","DOMParser","xmlDocument","ActiveXObject","loadXML","parseString","parser","parsedDocument","parseFromString","isParseError","erroneousParse","parsererrorNS","getElementsByTagName","namespaceURI","getElementsByTagNameNS","parseText","sValue","oXMLParent","hasChildNodes","sCollectedTxt","oNode","sProp","vContent","nItem","childNodes","nodeValue","nodeName","hasAttr","hasAttributes","attributes","oAttrib","nAttrib","xmlString","xmlDoc","getKeyValue","xmlObj","getAttrValue","encode","encodeXML","decodeXML",45,"videoJsVAST","plugin","./plugin/components/ads-label_4","./plugin/components/black-poster_4","./plugin/videojs.vast.vpaid"],"mappings":"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","file":"videojs_4.vast.vpaid.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o 0) {\n callback(event);\n }\n }, 0);\n }\n });\n }\n }, {\n key: '_callCallback',\n value: function _callCallback(methodName, callbackID, err, result) {\n\n var callback = this._callbacks.get(callbackID);\n\n //not all methods callback's are mandatory\n //but if there exist an error, fire the error event\n if (!callback) {\n if (err && callbackID === '') {\n this.trigger(ERROR, err);\n }\n return;\n }\n\n $asyncCallback.call(this, callbackID, err, result);\n }\n }, {\n key: '_handShake',\n value: function _handShake(err, data) {\n this._ready = true;\n if (this._handShakeHandler) {\n this._handShakeHandler(err, data);\n delete this._handShakeHandler;\n }\n }\n\n //methods like properties specific to this implementation of VPAID\n\n }, {\n key: 'getSize',\n value: function getSize() {\n return { width: this._width, height: this._height };\n }\n }, {\n key: 'setSize',\n value: function setSize(newWidth, newHeight) {\n this._width = isPositiveInt(newWidth, this._width);\n this._height = isPositiveInt(newHeight, this._height);\n this._el.setAttribute('width', this._width);\n this._el.setAttribute('height', this._height);\n }\n }, {\n key: 'getWidth',\n value: function getWidth() {\n return this._width;\n }\n }, {\n key: 'setWidth',\n value: function setWidth(newWidth) {\n this.setSize(newWidth, this._height);\n }\n }, {\n key: 'getHeight',\n value: function getHeight() {\n return this._height;\n }\n }, {\n key: 'setHeight',\n value: function setHeight(newHeight) {\n this.setSize(this._width, newHeight);\n }\n }, {\n key: 'getFlashID',\n value: function getFlashID() {\n return this._flashID;\n }\n }, {\n key: 'getFlashURL',\n value: function getFlashURL() {\n return this._flashURL;\n }\n }, {\n key: 'isReady',\n value: function isReady() {\n return this._ready;\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.offAll();\n this.removeAllCallbacks();\n registry.removeInstanceByID(this._flashID);\n if (this._el.parentElement) {\n this._el.parentElement.removeChild(this._el);\n }\n }\n }]);\n\n return JSFlashBridge;\n}();\n\nfunction $asyncCallback(callbackID, err, result) {\n var _this3 = this;\n\n setTimeout(function () {\n var callback = _this3._callbacks.get(callbackID);\n if (callback) {\n _this3._callbacks.remove(callbackID);\n callback(err, result);\n }\n }, 0);\n}\n\nObject.defineProperty(JSFlashBridge, 'VPAID_FLASH_HANDLER', {\n writable: false,\n configurable: false,\n value: VPAID_FLASH_HANDLER\n});\n\n/**\n * External interface handler\n *\n * @param {string} flashID identifier of the flash who call this\n * @param {string} typeID what type of message is, can be 'event' or 'callback'\n * @param {string} typeName if the typeID is a event the typeName will be the eventName, if is a callback the typeID is the methodName that is related this callback\n * @param {string} callbackID only applies when the typeID is 'callback', identifier of the callback to call\n * @param {object} error error object\n * @param {object} data\n */\nwindow[VPAID_FLASH_HANDLER] = function (flashID, typeID, typeName, callbackID, error, data) {\n var instance = registry.getInstanceByID(flashID);\n if (!instance) return;\n if (typeName === 'handShake') {\n instance._handShake(error, data);\n } else {\n if (typeID !== 'event') {\n instance._callCallback(typeName, callbackID, error, data);\n } else {\n instance._trigger(typeName, data);\n }\n }\n};\n\n},{\"./jsFlashBridgeRegistry\":5,\"./registry\":6,\"./utils\":7}],5:[function(require,module,exports){\n'use strict';\n\nvar SingleValueRegistry = require('./registry').SingleValueRegistry;\nvar instances = new SingleValueRegistry();\n\nvar JSFlashBridgeRegistry = {};\nObject.defineProperty(JSFlashBridgeRegistry, 'addInstance', {\n writable: false,\n configurable: false,\n value: function value(id, instance) {\n instances.add(id, instance);\n }\n});\n\nObject.defineProperty(JSFlashBridgeRegistry, 'getInstanceByID', {\n writable: false,\n configurable: false,\n value: function value(id) {\n return instances.get(id);\n }\n});\n\nObject.defineProperty(JSFlashBridgeRegistry, 'removeInstanceByID', {\n writable: false,\n configurable: false,\n value: function value(id) {\n return instances.remove(id);\n }\n});\n\nmodule.exports = JSFlashBridgeRegistry;\n\n},{\"./registry\":6}],6:[function(require,module,exports){\n'use strict';\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar MultipleValuesRegistry = exports.MultipleValuesRegistry = function () {\n function MultipleValuesRegistry() {\n _classCallCheck(this, MultipleValuesRegistry);\n\n this._registries = {};\n }\n\n _createClass(MultipleValuesRegistry, [{\n key: 'add',\n value: function add(id, value) {\n if (!this._registries[id]) {\n this._registries[id] = [];\n }\n if (this._registries[id].indexOf(value) === -1) {\n this._registries[id].push(value);\n }\n }\n }, {\n key: 'get',\n value: function get(id) {\n return this._registries[id] || [];\n }\n }, {\n key: 'filterKeys',\n value: function filterKeys(handler) {\n return Object.keys(this._registries).filter(handler);\n }\n }, {\n key: 'findByValue',\n value: function findByValue(value) {\n var _this = this;\n\n var keys = Object.keys(this._registries).filter(function (key) {\n return _this._registries[key].indexOf(value) !== -1;\n });\n\n return keys;\n }\n }, {\n key: 'remove',\n value: function remove(key, value) {\n if (!this._registries[key]) {\n return;\n }\n\n var index = this._registries[key].indexOf(value);\n\n if (index < 0) {\n return;\n }\n return this._registries[key].splice(index, 1);\n }\n }, {\n key: 'removeByKey',\n value: function removeByKey(id) {\n var old = this._registries[id];\n delete this._registries[id];\n return old;\n }\n }, {\n key: 'removeByValue',\n value: function removeByValue(value) {\n var _this2 = this;\n\n var keys = this.findByValue(value);\n return keys.map(function (key) {\n return _this2.remove(key, value);\n });\n }\n }, {\n key: 'removeAll',\n value: function removeAll() {\n var old = this._registries;\n this._registries = {};\n return old;\n }\n }, {\n key: 'size',\n value: function size() {\n return Object.keys(this._registries).length;\n }\n }]);\n\n return MultipleValuesRegistry;\n}();\n\nvar SingleValueRegistry = exports.SingleValueRegistry = function () {\n function SingleValueRegistry() {\n _classCallCheck(this, SingleValueRegistry);\n\n this._registries = {};\n }\n\n _createClass(SingleValueRegistry, [{\n key: 'add',\n value: function add(id, value) {\n this._registries[id] = value;\n }\n }, {\n key: 'get',\n value: function get(id) {\n return this._registries[id];\n }\n }, {\n key: 'filterKeys',\n value: function filterKeys(handler) {\n return Object.keys(this._registries).filter(handler);\n }\n }, {\n key: 'findByValue',\n value: function findByValue(value) {\n var _this3 = this;\n\n var keys = Object.keys(this._registries).filter(function (key) {\n return _this3._registries[key] === value;\n });\n\n return keys;\n }\n }, {\n key: 'remove',\n value: function remove(id) {\n var old = this._registries[id];\n delete this._registries[id];\n return old;\n }\n }, {\n key: 'removeByValue',\n value: function removeByValue(value) {\n var _this4 = this;\n\n var keys = this.findByValue(value);\n return keys.map(function (key) {\n return _this4.remove(key);\n });\n }\n }, {\n key: 'removeAll',\n value: function removeAll() {\n var old = this._registries;\n this._registries = {};\n return old;\n }\n }, {\n key: 'size',\n value: function size() {\n return Object.keys(this._registries).length;\n }\n }]);\n\n return SingleValueRegistry;\n}();\n\n},{}],7:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.unique = unique;\nexports.noop = noop;\nexports.callbackTimeout = callbackTimeout;\nexports.createElementWithID = createElementWithID;\nexports.isPositiveInt = isPositiveInt;\nexports.stringEndsWith = stringEndsWith;\nfunction unique(prefix) {\n var count = -1;\n return function (f) {\n return prefix + '_' + ++count;\n };\n}\n\nfunction noop() {}\n\nfunction callbackTimeout(timer, onSuccess, onTimeout) {\n\n var timeout = setTimeout(function () {\n\n onSuccess = noop;\n onTimeout();\n }, timer);\n\n return function () {\n clearTimeout(timeout);\n onSuccess.apply(this, arguments);\n };\n}\n\nfunction createElementWithID(parent, id) {\n var nEl = document.createElement('div');\n nEl.id = id;\n parent.innerHTML = '';\n parent.appendChild(nEl);\n return nEl;\n}\n\nfunction isPositiveInt(newVal, oldVal) {\n return !isNaN(parseFloat(newVal)) && isFinite(newVal) && newVal > 0 ? newVal : oldVal;\n}\n\nvar endsWith = function () {\n if (String.prototype.endsWith) return String.prototype.endsWith;\n return function endsWith(searchString, position) {\n var subjectString = this.toString();\n if (position === undefined || position > subjectString.length) {\n position = subjectString.length;\n }\n position -= searchString.length;\n var lastIndex = subjectString.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n };\n}();\n\nfunction stringEndsWith(string, search) {\n return endsWith.call(string, search);\n}\n\n},{}],8:[function(require,module,exports){\n'use strict';\n\nvar METHODS = [\n 'handshakeVersion',\n 'initAd',\n 'startAd',\n 'stopAd',\n 'skipAd', // VPAID 2.0 new method\n 'resizeAd',\n 'pauseAd',\n 'resumeAd',\n 'expandAd',\n 'collapseAd',\n 'subscribe',\n 'unsubscribe'\n];\n\nvar EVENTS = [\n 'AdLoaded',\n 'AdStarted',\n 'AdStopped',\n 'AdSkipped',\n 'AdSkippableStateChange', // VPAID 2.0 new event\n 'AdSizeChange', // VPAID 2.0 new event\n 'AdLinearChange',\n 'AdDurationChange', // VPAID 2.0 new event\n 'AdExpandedChange',\n 'AdRemainingTimeChange', // [Deprecated in 2.0] but will be still fired for backwards compatibility\n 'AdVolumeChange',\n 'AdImpression',\n 'AdVideoStart',\n 'AdVideoFirstQuartile',\n 'AdVideoMidpoint',\n 'AdVideoThirdQuartile',\n 'AdVideoComplete',\n 'AdClickThru',\n 'AdInteraction', // VPAID 2.0 new event\n 'AdUserAcceptInvitation',\n 'AdUserMinimize',\n 'AdUserClose',\n 'AdPaused',\n 'AdPlaying',\n 'AdLog',\n 'AdError'\n];\n\nvar GETTERS = [\n 'getAdLinear',\n 'getAdWidth', // VPAID 2.0 new getter\n 'getAdHeight', // VPAID 2.0 new getter\n 'getAdExpanded',\n 'getAdSkippableState', // VPAID 2.0 new getter\n 'getAdRemainingTime',\n 'getAdDuration', // VPAID 2.0 new getter\n 'getAdVolume',\n 'getAdCompanions', // VPAID 2.0 new getter\n 'getAdIcons' // VPAID 2.0 new getter\n];\n\nvar SETTERS = [\n 'setAdVolume'\n];\n\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n\n/**\n * IVPAIDAdUnit\n *\n * @class\n *\n * @param {object} creative\n * @param {HTMLElement} el\n * @param {HTMLVideoElement} video\n */\nfunction IVPAIDAdUnit(creative, el, video) {}\n\n\n/**\n * handshakeVersion\n *\n * @param {string} VPAIDVersion\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.handshakeVersion = function (VPAIDVersion, callback) {};\n\n/**\n * initAd\n *\n * @param {number} width\n * @param {number} height\n * @param {string} viewMode can be 'normal', 'thumbnail' or 'fullscreen'\n * @param {number} desiredBitrate indicates the desired bitrate in kbps\n * @param {object} [creativeData] used for additional initialization data\n * @param {object} [environmentVars] used for passing implementation-specific of js version\n * @param {NodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.initAd = function(width, height, viewMode, desiredBitrate, creativeData, environmentVars, callback) {};\n\n/**\n * startAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.startAd = function(callback) {};\n\n/**\n * stopAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.stopAd = function(callback) {};\n\n/**\n * skipAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.skipAd = function(callback) {};\n\n/**\n * resizeAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.resizeAd = function(width, height, viewMode, callback) {};\n\n/**\n * pauseAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.pauseAd = function(callback) {};\n\n/**\n * resumeAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.resumeAd = function(callback) {};\n\n/**\n * expandAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.expandAd = function(callback) {};\n\n/**\n * collapseAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.collapseAd = function(callback) {};\n\n/**\n * subscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n * @param {object} context\n */\nIVPAIDAdUnit.prototype.subscribe = function(event, handler, context) {};\n\n/**\n * startAd\n *\n * @param {string} event\n * @param {function} handler\n */\nIVPAIDAdUnit.prototype.unsubscribe = function(event, handler) {};\n\n\n\n/**\n * getAdLinear\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdLinear = function(callback) {};\n\n/**\n * getAdWidth\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdWidth = function(callback) {};\n\n/**\n * getAdHeight\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdHeight = function(callback) {};\n\n/**\n * getAdExpanded\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdExpanded = function(callback) {};\n\n/**\n * getAdSkippableState\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdSkippableState = function(callback) {};\n\n/**\n * getAdRemainingTime\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdRemainingTime = function(callback) {};\n\n/**\n * getAdDuration\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdDuration = function(callback) {};\n\n/**\n * getAdVolume\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdVolume = function(callback) {};\n\n/**\n * getAdCompanions\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdCompanions = function(callback) {};\n\n/**\n * getAdIcons\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdIcons = function(callback) {};\n\n/**\n * setAdVolume\n *\n * @param {number} volume\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.setAdVolume = function(volume, callback) {};\n\naddStaticToInterface(IVPAIDAdUnit, 'METHODS', METHODS);\naddStaticToInterface(IVPAIDAdUnit, 'GETTERS', GETTERS);\naddStaticToInterface(IVPAIDAdUnit, 'SETTERS', SETTERS);\naddStaticToInterface(IVPAIDAdUnit, 'EVENTS', EVENTS);\n\n\nvar VPAID1_METHODS = METHODS.filter(function(method) {\n return ['skipAd'].indexOf(method) === -1;\n});\n\naddStaticToInterface(IVPAIDAdUnit, 'checkVPAIDInterface', function checkVPAIDInterface (creative) {\n var result = VPAID1_METHODS.every(function(key) {\n return typeof creative[key] === 'function';\n });\n return result;\n});\n\nmodule.exports = IVPAIDAdUnit;\n\nfunction addStaticToInterface(Interface, name, value) {\n Object.defineProperty(Interface, name, {\n writable: false,\n configurable: false,\n value: value\n });\n}\n\n\n},{}],9:[function(require,module,exports){\n'use strict';\n\nvar IVPAIDAdUnit = require('./IVPAIDAdUnit');\nvar Subscriber = require('./subscriber');\nvar checkVPAIDInterface = IVPAIDAdUnit.checkVPAIDInterface;\nvar utils = require('./utils');\nvar METHODS = IVPAIDAdUnit.METHODS;\nvar ERROR = 'AdError';\nvar AD_CLICK = 'AdClickThru';\nvar FILTERED_EVENTS = IVPAIDAdUnit.EVENTS.filter(function (event) {\n return event != AD_CLICK;\n});\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n\n/**\n * VPAIDAdUnit\n * @class\n *\n * @param VPAIDCreative\n * @param {HTMLElement} [el] this will be used in initAd environmentVars.slot if defined\n * @param {HTMLVideoElement} [video] this will be used in initAd environmentVars.videoSlot if defined\n */\nfunction VPAIDAdUnit(VPAIDCreative, el, video, iframe) {\n this._isValid = checkVPAIDInterface(VPAIDCreative);\n if (this._isValid) {\n this._creative = VPAIDCreative;\n this._el = el;\n this._videoEl = video;\n this._iframe = iframe;\n this._subscribers = new Subscriber();\n $addEventsSubscribers.call(this);\n }\n}\n\nVPAIDAdUnit.prototype = Object.create(IVPAIDAdUnit.prototype);\n\n/**\n * isValidVPAIDAd will return if the VPAIDCreative passed in constructor is valid or not\n *\n * @return {boolean}\n */\nVPAIDAdUnit.prototype.isValidVPAIDAd = function isValidVPAIDAd() {\n return this._isValid;\n};\n\nIVPAIDAdUnit.METHODS.forEach(function(method) {\n //NOTE: this methods arguments order are implemented differently from the spec\n var ignores = [\n 'subscribe',\n 'unsubscribe',\n 'initAd'\n ];\n\n if (ignores.indexOf(method) !== -1) return;\n\n VPAIDAdUnit.prototype[method] = function () {\n var ariaty = IVPAIDAdUnit.prototype[method].length;\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n var args = Array.prototype.slice.call(arguments);\n var callback = (ariaty === args.length) ? args.pop() : undefined;\n\n setTimeout(function () {\n var result, error = null;\n try {\n result = this._creative[method].apply(this._creative, args);\n } catch(e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n };\n});\n\n\n/**\n * initAd concreate implementation\n *\n * @param {number} width\n * @param {number} height\n * @param {string} viewMode can be 'normal', 'thumbnail' or 'fullscreen'\n * @param {number} desiredBitrate indicates the desired bitrate in kbps\n * @param {object} [creativeData] used for additional initialization data\n * @param {object} [environmentVars] used for passing implementation-specific of js version, if el & video was used in constructor slot & videoSlot will be added to the object\n * @param {NodeStyleCallback} callback\n */\nVPAIDAdUnit.prototype.initAd = function initAd(width, height, viewMode, desiredBitrate, creativeData, environmentVars, callback) {\n creativeData = creativeData || {};\n environmentVars = utils.extend({\n slot: this._el,\n videoSlot: this._videoEl\n }, environmentVars || {});\n\n setTimeout(function () {\n var error;\n try {\n this._creative.initAd(width, height, viewMode, desiredBitrate, creativeData, environmentVars);\n } catch (e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error);\n }.bind(this), 0);\n};\n\n/**\n * subscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n * @param {object} context\n */\nVPAIDAdUnit.prototype.subscribe = function subscribe(event, handler, context) {\n this._subscribers.subscribe(handler, event, context);\n};\n\n\n/**\n * unsubscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n */\nVPAIDAdUnit.prototype.unsubscribe = function unsubscribe(event, handler) {\n this._subscribers.unsubscribe(handler, event);\n};\n\n//alias\nVPAIDAdUnit.prototype.on = VPAIDAdUnit.prototype.subscribe;\nVPAIDAdUnit.prototype.off = VPAIDAdUnit.prototype.unsubscribe;\n\nIVPAIDAdUnit.GETTERS.forEach(function(getter) {\n VPAIDAdUnit.prototype[getter] = function (callback) {\n setTimeout(function () {\n\n var result, error = null;\n try {\n result = this._creative[getter]();\n } catch(e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n };\n});\n\n/**\n * setAdVolume\n *\n * @param volume\n * @param {nodeStyleCallback} callback\n */\nVPAIDAdUnit.prototype.setAdVolume = function setAdVolume(volume, callback) {\n setTimeout(function () {\n\n var result, error = null;\n try {\n this._creative.setAdVolume(volume);\n result = this._creative.getAdVolume();\n } catch(e) {\n error = e;\n }\n\n if (!error) {\n error = utils.validate(result === volume, 'failed to apply volume: ' + volume);\n }\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n};\n\nVPAIDAdUnit.prototype._destroy = function destroy() {\n this.stopAd();\n this._subscribers.unsubscribeAll();\n};\n\nfunction $addEventsSubscribers() {\n // some ads implement\n // so they only handle one subscriber\n // to handle this we create our one\n FILTERED_EVENTS.forEach(function (event) {\n this._creative.subscribe($trigger.bind(this, event), event);\n }.bind(this));\n\n // map the click event to be an object instead of depending of the order of the arguments\n // and to be consistent with the flash\n this._creative.subscribe($clickThruHook.bind(this), AD_CLICK);\n\n // because we are adding the element inside the iframe\n // the user is not able to click in the video\n if (this._videoEl) {\n var documentElement = this._iframe.contentDocument.documentElement;\n var videoEl = this._videoEl;\n documentElement.addEventListener('click', function(e) {\n if (e.target === documentElement) {\n videoEl.click();\n }\n });\n }\n}\n\nfunction $clickThruHook(url, id, playerHandles) {\n this._subscribers.triggerSync(AD_CLICK, {url: url, id: id, playerHandles: playerHandles});\n}\n\nfunction $trigger(event) {\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n this._subscribers.trigger(event, Array.prototype.slice(arguments, 1));\n}\n\nfunction callOrTriggerEvent(callback, subscribers, error, result) {\n if (callback) {\n callback(error, result);\n } else if (error) {\n subscribers.trigger(ERROR, error);\n }\n}\n\nmodule.exports = VPAIDAdUnit;\n\n\n},{\"./IVPAIDAdUnit\":8,\"./subscriber\":11,\"./utils\":12}],10:[function(require,module,exports){\n'use strict';\n\nvar utils = require('./utils');\nvar unique = utils.unique('vpaidIframe');\nvar VPAIDAdUnit = require('./VPAIDAdUnit');\n\nvar defaultTemplate = '';\ndefaultTemplate += '
';\n\nvar AD_STOPPED = 'AdStopped';\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n/**\n * VPAIDHTML5Client\n * @class\n *\n * @param {HTMLElement} el that will contain the iframe to load adUnit and a el to add to adUnit slot\n * @param {HTMLVideoElement} video default video element to be used by adUnit\n * @param {object} [templateConfig] template: html template to be used instead of the default, extraOptions: to be used when rendering the template\n * @param {object} [vpaidOptions] timeout: when loading adUnit\n */\nfunction VPAIDHTML5Client(el, video, templateConfig, vpaidOptions) {\n templateConfig = templateConfig || {};\n\n this._id = unique();\n this._destroyed = false;\n\n this._frameContainer = utils.createElementInEl(el, 'div');\n this._videoEl = video;\n this._vpaidOptions = vpaidOptions || {timeout: 10000};\n\n this._templateConfig = {\n template: templateConfig.template || defaultTemplate,\n extraOptions: templateConfig.extraOptions || {}\n };\n\n}\n\n/**\n * destroy\n *\n */\nVPAIDHTML5Client.prototype.destroy = function destroy() {\n if (this._destroyed) {\n return;\n }\n this._destroyed = true;\n $unloadPreviousAdUnit.call(this);\n};\n\n/**\n * isDestroyed\n *\n * @return {boolean}\n */\nVPAIDHTML5Client.prototype.isDestroyed = function isDestroyed() {\n return this._destroyed;\n};\n\n/**\n * loadAdUnit\n *\n * @param {string} adURL url of the js of the adUnit\n * @param {nodeStyleCallback} callback\n */\nVPAIDHTML5Client.prototype.loadAdUnit = function loadAdUnit(adURL, callback) {\n $throwIfDestroyed.call(this);\n $unloadPreviousAdUnit.call(this);\n\n var frame = utils.createIframeWithContent(\n this._frameContainer,\n this._templateConfig.template,\n utils.extend({\n iframeURL_JS: adURL,\n iframeID: this.getID()\n }, this._templateConfig.extraOptions)\n );\n this._frame = frame;\n\n this._onLoad = utils.callbackTimeout(\n this._vpaidOptions.timeout,\n onLoad.bind(this),\n onTimeout.bind(this)\n );\n\n window.addEventListener('message', this._onLoad);\n\n function onLoad (e) {\n /*jshint validthis: false */\n //don't clear timeout\n if (e.origin !== window.location.origin) return;\n var result = JSON.parse(e.data);\n\n //don't clear timeout\n if (result.id !== this.getID()) return;\n\n var adUnit, error, createAd;\n if (!this._frame.contentWindow) {\n\n error = 'the iframe is not anymore in the DOM tree';\n\n } else {\n createAd = this._frame.contentWindow.getVPAIDAd;\n error = utils.validate(typeof createAd === 'function', 'the ad didn\\'t return a function to create an ad');\n }\n\n if (!error) {\n var adEl = this._frame.contentWindow.document.querySelector('.ad-element');\n adUnit = new VPAIDAdUnit(createAd(), adEl, this._videoEl, this._frame);\n adUnit.subscribe(AD_STOPPED, $adDestroyed.bind(this));\n error = utils.validate(adUnit.isValidVPAIDAd(), 'the add is not fully complaint with VPAID specification');\n }\n\n this._adUnit = adUnit;\n $destroyLoadListener.call(this);\n callback(error, error ? null : adUnit);\n\n //clear timeout\n return true;\n }\n\n function onTimeout() {\n callback('timeout', null);\n }\n};\n\n/**\n * unloadAdUnit\n *\n */\nVPAIDHTML5Client.prototype.unloadAdUnit = function unloadAdUnit() {\n $unloadPreviousAdUnit.call(this);\n};\n\n/**\n * getID will return the unique id\n *\n * @return {string}\n */\nVPAIDHTML5Client.prototype.getID = function () {\n return this._id;\n};\n\n\n/**\n * $removeEl\n *\n * @param {string} key\n */\nfunction $removeEl(key) {\n var el = this[key];\n if (el) {\n el.remove();\n delete this[key];\n }\n}\n\nfunction $adDestroyed() {\n $removeAdElements.call(this);\n delete this._adUnit;\n}\n\nfunction $unloadPreviousAdUnit() {\n $removeAdElements.call(this);\n $destroyAdUnit.call(this);\n}\n\nfunction $removeAdElements() {\n $removeEl.call(this, '_frame');\n $destroyLoadListener.call(this);\n}\n\n/**\n * $destroyLoadListener\n *\n */\nfunction $destroyLoadListener() {\n if (this._onLoad) {\n window.removeEventListener('message', this._onLoad);\n utils.clearCallbackTimeout(this._onLoad);\n delete this._onLoad;\n }\n}\n\n\nfunction $destroyAdUnit() {\n if (this._adUnit) {\n this._adUnit.stopAd();\n delete this._adUnit;\n }\n}\n\n/**\n * $throwIfDestroyed\n *\n */\nfunction $throwIfDestroyed() {\n if (this._destroyed) {\n throw new Error ('VPAIDHTML5Client already destroyed!');\n }\n}\n\nmodule.exports = VPAIDHTML5Client;\nwindow.VPAIDHTML5Client = VPAIDHTML5Client;\n\n\n},{\"./VPAIDAdUnit\":9,\"./utils\":12}],11:[function(require,module,exports){\n'use strict';\n\nfunction Subscriber() {\n this._subscribers = {};\n}\n\nSubscriber.prototype.subscribe = function subscribe(handler, eventName, context) {\n this.get(eventName).push({handler: handler, context: context});\n};\n\nSubscriber.prototype.unsubscribe = function unsubscribe(handler, eventName) {\n this._subscribers[eventName] = this.get(eventName).filter(function (subscriber) {\n return handler === subscriber.handler;\n });\n};\n\nSubscriber.prototype.unsubscribeAll = function unsubscribeAll() {\n this._subscribers = {};\n};\n\nSubscriber.prototype.trigger = function(eventName, data) {\n var that = this;\n that.get(eventName).forEach(function (subscriber) {\n setTimeout(function () {\n if (that.get(eventName)) {\n subscriber.handler.call(subscriber.context, data);\n }\n }, 0);\n });\n};\n\nSubscriber.prototype.triggerSync = function(eventName, data) {\n this.get(eventName).forEach(function (subscriber) {\n subscriber.handler.call(subscriber.context, data);\n });\n};\n\nSubscriber.prototype.get = function get(eventName) {\n if (!this._subscribers[eventName]) {\n this._subscribers[eventName] = [];\n }\n return this._subscribers[eventName];\n};\n\nmodule.exports = Subscriber;\n\n\n},{}],12:[function(require,module,exports){\n'use strict';\n\n/**\n * noop a empty function\n */\nfunction noop() {}\n\n/**\n * validate if is not validate will return an Error with the message\n *\n * @param {boolean} isValid\n * @param {string} message\n */\nfunction validate(isValid, message) {\n return isValid ? null : new Error(message);\n}\n\nvar timeouts = {};\n/**\n * clearCallbackTimeout\n *\n * @param {function} func handler to remove\n */\nfunction clearCallbackTimeout(func) {\n var timeout = timeouts[func];\n if (timeout) {\n clearTimeout(timeout);\n delete timeouts[func];\n }\n}\n\n/**\n * callbackTimeout if the onSuccess is not called and returns true in the timelimit then onTimeout will be called\n *\n * @param {number} timer\n * @param {function} onSuccess\n * @param {function} onTimeout\n */\nfunction callbackTimeout(timer, onSuccess, onTimeout) {\n var callback, timeout;\n\n timeout = setTimeout(function () {\n onSuccess = noop;\n delete timeout[callback];\n onTimeout();\n }, timer);\n\n callback = function () {\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n if (onSuccess.apply(this, arguments)) {\n clearCallbackTimeout(callback);\n }\n };\n\n timeouts[callback] = timeout;\n\n return callback;\n}\n\n\n/**\n * createElementInEl\n *\n * @param {HTMLElement} parent\n * @param {string} tagName\n * @param {string} id\n */\nfunction createElementInEl(parent, tagName, id) {\n var nEl = document.createElement(tagName);\n if (id) nEl.id = id;\n parent.appendChild(nEl);\n return nEl;\n}\n\n/**\n * createIframeWithContent\n *\n * @param {HTMLElement} parent\n * @param {string} template simple template using {{var}}\n * @param {object} data\n */\nfunction createIframeWithContent(parent, template, data) {\n var iframe = createIframe(parent);\n if (!setIframeContent(iframe, simpleTemplate(template, data))) return;\n return iframe;\n}\n\n/**\n * createIframe\n *\n * @param {HTMLElement} parent\n * @param {string} url\n */\nfunction createIframe(parent, url) {\n var nEl = document.createElement('iframe');\n nEl.src = url || 'about:blank';\n nEl.marginWidth = '0';\n nEl.marginHeight = '0';\n nEl.frameBorder = '0';\n nEl.width = '100%';\n nEl.height = '100%';\n nEl.style.position = 'absolute';\n nEl.style.left = '0';\n nEl.style.top = '0';\n nEl.style.margin = '0px';\n nEl.style.padding = '0px';\n nEl.style.border = 'none';\n nEl.setAttribute('SCROLLING','NO');\n parent.innerHTML = '';\n parent.appendChild(nEl);\n return nEl;\n}\n\n/**\n * simpleTemplate\n *\n * @param {string} template\n * @param {object} data\n */\nfunction simpleTemplate(template, data) {\n Object.keys(data).forEach(function (key) {\n var value = (typeof value === 'object') ? JSON.stringify(data[key]) : data[key];\n template = template.replace(new RegExp('{{' + key + '}}', 'g'), value);\n });\n return template;\n}\n\n/**\n * setIframeContent\n *\n * @param {HTMLIframeElement} iframeEl\n * @param content\n */\nfunction setIframeContent(iframeEl, content) {\n var iframeDoc = iframeEl.contentWindow && iframeEl.contentWindow.document;\n if (!iframeDoc) return false;\n\n iframeDoc.write(content);\n\n return true;\n}\n\n\n/**\n * extend object with keys from another object\n *\n * @param {object} toExtend\n * @param {object} fromSource\n */\nfunction extend(toExtend, fromSource) {\n Object.keys(fromSource).forEach(function(key) {\n toExtend[key] = fromSource[key];\n });\n return toExtend;\n}\n\n\n/**\n * unique will create a unique string everytime is called, sequentially and prefixed\n *\n * @param {string} prefix\n */\nfunction unique(prefix) {\n var count = -1;\n return function () {\n return prefix + '_' + (++count);\n };\n}\n\nmodule.exports = {\n noop: noop,\n validate: validate,\n clearCallbackTimeout: clearCallbackTimeout,\n callbackTimeout: callbackTimeout,\n createElementInEl: createElementInEl,\n createIframeWithContent: createIframeWithContent,\n createIframe: createIframe,\n simpleTemplate: simpleTemplate,\n setIframeContent: setIframeContent,\n extend: extend,\n unique: unique\n};\n\n\n},{}],13:[function(require,module,exports){\n'use strict';\n\nvar InLine = require('./InLine');\nvar Wrapper = require('./Wrapper');\n\nfunction Ad(adJTree) {\n if (!(this instanceof Ad)) {\n return new Ad(adJTree);\n }\n this.initialize(adJTree);\n}\n\nAd.prototype.initialize = function(adJTree) {\n this.id = adJTree.attr('id');\n this.sequence = adJTree.attr('sequence');\n\n if(adJTree.inLine) {\n this.inLine = new InLine(adJTree.inLine);\n }\n\n if(adJTree.wrapper){\n this.wrapper = new Wrapper(adJTree.wrapper);\n }\n};\n\nmodule.exports = Ad;\n},{\"./InLine\":16,\"./Wrapper\":26}],14:[function(require,module,exports){\n'use strict';\n\nvar TrackingEvent = require('./TrackingEvent');\n\nvar utilities = require('../../utils/utilityFunctions');\n\nvar xml = require('../../utils/xml');\n\n\nfunction Companion(companionJTree) {\n if (!(this instanceof Companion)) {\n return new Companion(companionJTree);\n }\n\n //Required Elements\n this.creativeType = xml.attr(companionJTree.staticResource, 'creativeType');\n this.staticResource = xml.keyValue(companionJTree.staticResource);\n\n // Weird bug when the JXON tree is built it doesn't handle casing properly in this situation...\n var htmlResource = null;\n if (xml.keyValue(companionJTree.HTMLResource)) {\n htmlResource = xml.keyValue(companionJTree.HTMLResource);\n } else if (xml.keyValue(companionJTree.hTMLResource)) {\n htmlResource = xml.keyValue(companionJTree.hTMLResource);\n }\n this.htmlResource = htmlResource;\n\n var iframeResource = null;\n if (xml.keyValue(companionJTree.IFrameResource)) {\n iframeResource = xml.keyValue(companionJTree.IFrameResource);\n } else if (xml.keyValue(companionJTree.iFrameresource)) {\n iframeResource = xml.keyValue(companionJTree.iFrameresource);\n }\n this.iframeResource = iframeResource;\n\n //Optional fields\n this.id = xml.attr(companionJTree, 'id');\n this.width = xml.attr(companionJTree, 'width');\n this.height = xml.attr(companionJTree, 'height');\n this.expandedWidth = xml.attr(companionJTree, 'expandedWidth');\n this.expandedHeight = xml.attr(companionJTree, 'expandedHeight');\n this.scalable = xml.attr(companionJTree, 'scalable');\n this.maintainAspectRatio = xml.attr(companionJTree, 'maintainAspectRatio');\n this.minSuggestedDuration = xml.attr(companionJTree, 'minSuggestedDuration');\n this.apiFramework = xml.attr(companionJTree, 'apiFramework');\n this.companionClickThrough = xml.keyValue(companionJTree.companionClickThrough);\n this.trackingEvents = parseTrackingEvents(companionJTree.trackingEvents && companionJTree.trackingEvents.tracking);\n\n /*** Local functions ***/\n function parseTrackingEvents(trackingEvents) {\n var trackings = [];\n if (utilities.isDefined(trackingEvents)) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingData) {\n trackings.push(new TrackingEvent(trackingData));\n });\n }\n return trackings;\n }\n}\n\nmodule.exports = Companion;\n},{\"../../utils/utilityFunctions\":43,\"../../utils/xml\":44,\"./TrackingEvent\":19}],15:[function(require,module,exports){\n'use strict';\n\nvar Linear = require('./Linear');\nvar Companion = require('./Companion');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction Creative(creativeJTree) {\n if(!(this instanceof Creative)) {\n return new Creative(creativeJTree);\n }\n\n this.id = creativeJTree.attr('id');\n this.sequence = creativeJTree.attr('sequence');\n this.adId = creativeJTree.attr('adId');\n this.apiFramework = creativeJTree.attr('apiFramework');\n\n if(creativeJTree.linear) {\n this.linear = new Linear(creativeJTree.linear);\n }\n\n if (creativeJTree.companionAds) {\n var companions = [];\n var companionAds = creativeJTree.companionAds && creativeJTree.companionAds.companion;\n companionAds = utilities.isArray(companionAds) ? companionAds : [companionAds];\n companionAds.forEach(function (companionData) {\n companions.push(new Companion(companionData));\n });\n\n this.companionAds = companions;\n }\n}\n\nmodule.exports = Creative;\n},{\"../../utils/utilityFunctions\":43,\"./Companion\":14,\"./Linear\":17}],16:[function(require,module,exports){\n'use strict';\n\nvar vastUtil = require('./vastUtil');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction InLine(inlineJTree) {\n if (!(this instanceof InLine)) {\n return new InLine(inlineJTree);\n }\n\n //Required Fields\n this.adTitle = xml.keyValue(inlineJTree.adTitle);\n this.adSystem = xml.keyValue(inlineJTree.adSystem);\n this.impressions = vastUtil.parseImpressions(inlineJTree.impression);\n this.creatives = vastUtil.parseCreatives(inlineJTree.creatives);\n\n //Optional Fields\n this.description = xml.keyValue(inlineJTree.description);\n this.advertiser = xml.keyValue(inlineJTree.advertiser);\n this.surveys = parseSurveys(inlineJTree.survey);\n this.error = xml.keyValue(inlineJTree.error);\n this.pricing = xml.keyValue(inlineJTree.pricing);\n this.extensions = inlineJTree.extensions;\n\n /*** Local Functions ***/\n function parseSurveys(inlineSurveys) {\n if (inlineSurveys) {\n return utilities.transformArray(utilities.isArray(inlineSurveys) ? inlineSurveys : [inlineSurveys], function (survey) {\n if(utilities.isNotEmptyString(survey.keyValue)){\n return {\n uri: survey.keyValue,\n type: survey.attr('type')\n };\n }\n\n return undefined;\n });\n }\n return [];\n }\n}\n\nmodule.exports = InLine;\n},{\"../../utils/utilityFunctions\":43,\"../../utils/xml\":44,\"./vastUtil\":28}],17:[function(require,module,exports){\n'use strict';\n\nvar TrackingEvent = require('./TrackingEvent');\nvar MediaFile = require('./MediaFile');\nvar VideoClicks = require('./VideoClicks');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar parsers = require('./parsers');\n\nvar xml = require('../../utils/xml');\n\n\nfunction Linear(linearJTree) {\n if (!(this instanceof Linear)) {\n return new Linear(linearJTree);\n }\n\n //Required Elements\n this.duration = parsers.duration(xml.keyValue(linearJTree.duration));\n this.mediaFiles = parseMediaFiles(linearJTree.mediaFiles && linearJTree.mediaFiles.mediaFile);\n\n //Optional fields\n this.trackingEvents = parseTrackingEvents(linearJTree.trackingEvents && linearJTree.trackingEvents.tracking, this.duration);\n this.skipoffset = parsers.offset(xml.attr(linearJTree, 'skipoffset'), this.duration);\n\n if (linearJTree.videoClicks) {\n this.videoClicks = new VideoClicks(linearJTree.videoClicks);\n }\n\n if(linearJTree.adParameters) {\n this.adParameters = xml.keyValue(linearJTree.adParameters);\n\n if(xml.attr(linearJTree.adParameters, 'xmlEncoded')){\n this.adParameters = xml.decode(this.adParameters);\n }\n }\n\n /*** Local functions ***/\n function parseTrackingEvents(trackingEvents, duration) {\n var trackings = [];\n if (utilities.isDefined(trackingEvents)) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingData) {\n trackings.push(new TrackingEvent(trackingData, duration));\n });\n }\n return trackings;\n }\n\n function parseMediaFiles(mediaFilesJxonTree) {\n var mediaFiles = [];\n if (utilities.isDefined(mediaFilesJxonTree)) {\n mediaFilesJxonTree = utilities.isArray(mediaFilesJxonTree) ? mediaFilesJxonTree : [mediaFilesJxonTree];\n\n mediaFilesJxonTree.forEach(function (mfData) {\n mediaFiles.push(new MediaFile(mfData));\n });\n }\n return mediaFiles;\n }\n}\n\nmodule.exports = Linear;\n},{\"../../utils/utilityFunctions\":43,\"../../utils/xml\":44,\"./MediaFile\":18,\"./TrackingEvent\":19,\"./VideoClicks\":25,\"./parsers\":27}],18:[function(require,module,exports){\n'use strict';\n\nvar xml = require('../../utils/xml');\n\nvar attributesList = [\n //Required attributes\n 'delivery',\n 'type',\n 'width',\n 'height',\n //Optional attributes\n 'codec',\n 'id',\n 'bitrate',\n 'minBitrate',\n 'maxBitrate',\n 'scalable',\n 'maintainAspectRatio',\n 'apiFramework'\n];\n\nfunction MediaFile(mediaFileJTree) {\n if (!(this instanceof MediaFile)) {\n return new MediaFile(mediaFileJTree);\n }\n\n //Required attributes\n this.src = xml.keyValue(mediaFileJTree);\n\n for(var x=0; x 0) {\n getAd(waterfallAds.shift(),[], waterfallHandler);\n } else {\n callback(error, adChain);\n }\n } else {\n callback(null, adChain);\n }\n }\n });\n\n /*** Local functions ***/\n function getAdWaterfall(adTagUrl, callback) {\n var requestVastXML = that._requestVASTXml.bind(that, adTagUrl);\n async.waterfall([\n requestVastXML,\n buildVastWaterfall\n ], callback);\n }\n\n function buildVastWaterfall(xmlStr, callback) {\n var vastTree;\n try {\n vastTree = xml.toJXONTree(xmlStr);\n\n if(utilities.isArray(vastTree.ad)) {\n vastTree.ads = vastTree.ad;\n } else if(vastTree.ad){\n vastTree.ads = [vastTree.ad];\n } else {\n vastTree.ads = [];\n }\n callback(validateVASTTree(vastTree), vastTree);\n\n } catch (e) {\n callback(new VASTError(\"on VASTClient.getVASTAd.buildVastWaterfall, error parsing xml\", 100), null);\n }\n }\n\n function validateVASTTree(vastTree) {\n var vastVersion = xml.attr(vastTree, 'version');\n\n if (!vastTree.ad) {\n return new VASTError('on VASTClient.getVASTAd.validateVASTTree, no Ad in VAST tree', 303);\n }\n\n if (vastVersion && (vastVersion != 3 && vastVersion != 2)) {\n return new VASTError('on VASTClient.getVASTAd.validateVASTTree, not supported VAST version \"' + vastVersion + '\"', 102);\n }\n\n return null;\n }\n\n function getAd(adTagUrl, adChain, callback) {\n if (adChain.length >= that.WRAPPER_LIMIT) {\n return callback(new VASTError(\"on VASTClient.getVASTAd.getAd, players wrapper limit reached (the limit is \" + that.WRAPPER_LIMIT + \")\", 302), adChain);\n }\n\n async.waterfall([\n function (next) {\n if (utilities.isString(adTagUrl)) {\n requestVASTAd(adTagUrl, next);\n } else {\n next(null, adTagUrl);\n }\n },\n buildAd\n ], function (error, ad) {\n if (ad) {\n adChain.push(ad);\n }\n\n if (error) {\n return callback(error, adChain);\n }\n\n if (ad.wrapper) {\n return getAd(ad.wrapper.VASTAdTagURI, adChain, callback);\n }\n\n return callback(null, adChain);\n });\n }\n\n function buildAd(adJxonTree, callback) {\n try {\n var ad = new Ad(adJxonTree);\n callback(validateAd(ad), ad);\n } catch (e) {\n callback(new VASTError('on VASTClient.getVASTAd.buildAd, error parsing xml', 100), null);\n }\n }\n\n function validateAd(ad) {\n var wrapper = ad.wrapper;\n var inLine = ad.inLine;\n var errMsgPrefix = 'on VASTClient.getVASTAd.validateAd, ';\n\n if (inLine && wrapper) {\n return new VASTError(errMsgPrefix +\"InLine and Wrapper both found on the same Ad\", 101);\n }\n\n if (!inLine && !wrapper) {\n return new VASTError(errMsgPrefix + \"nor wrapper nor inline elements found on the Ad\", 101);\n }\n\n if (inLine && inLine.creatives.length === 0) {\n return new VASTError(errMsgPrefix + \"missing creative in InLine element\", 101);\n }\n\n if (wrapper && !wrapper.VASTAdTagURI) {\n return new VASTError(errMsgPrefix + \"missing 'VASTAdTagURI' in wrapper\", 101);\n }\n }\n\n function requestVASTAd(adTagUrl, callback) {\n that._requestVASTXml(adTagUrl, function (error, xmlStr) {\n if (error) {\n return callback(error);\n }\n try {\n var vastTree = xml.toJXONTree(xmlStr);\n callback(validateVASTTree(vastTree), vastTree.ad);\n } catch (e) {\n callback(new VASTError(\"on VASTClient.getVASTAd.requestVASTAd, error parsing xml\", 100));\n }\n });\n }\n};\n\nVASTClient.prototype._requestVASTXml = function requestVASTXml(adTagUrl, callback) {\n try {\n if (utilities.isFunction(adTagUrl)) {\n adTagUrl(requestHandler);\n } else {\n http.get(adTagUrl, requestHandler, {\n withCredentials: true\n });\n }\n } catch (e) {\n callback(e);\n }\n\n /*** Local functions ***/\n function requestHandler(error, response, status) {\n if (error) {\n var errMsg = utilities.isDefined(status) ?\n \"on VASTClient.requestVastXML, HTTP request error with status '\" + status + \"'\" :\n \"on VASTClient.requestVastXML, Error getting the the VAST XML with he passed adTagXML fn\";\n return callback(new VASTError(errMsg, 301), null);\n }\n\n callback(null, response);\n }\n};\n\nVASTClient.prototype._buildVASTResponse = function buildVASTResponse(adsChain) {\n var response = new VASTResponse();\n addAdsToResponse(response, adsChain);\n validateResponse(response);\n\n return response;\n\n //*** Local function ****\n function addAdsToResponse(response, ads) {\n ads.forEach(function (ad) {\n response.addAd(ad);\n });\n }\n\n function validateResponse(response) {\n var progressEvents = response.trackingEvents.progress;\n\n if (!response.hasLinear()) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, Received an Ad type that is not supported\", 200);\n }\n\n if (response.duration === undefined) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, Missing duration field in VAST response\", 101);\n }\n\n if (progressEvents) {\n progressEvents.forEach(function (progressEvent) {\n if (!utilities.isNumber(progressEvent.offset)) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, missing or wrong offset attribute on progress tracking event\", 101);\n }\n });\n }\n }\n};\n\nVASTClient.prototype._trackError = function (error, adChain) {\n if (!utilities.isArray(adChain) || adChain.length === 0) { //There is nothing to track\n return;\n }\n\n var errorURLMacros = [];\n adChain.forEach(addErrorUrlMacros);\n vastUtil.track(errorURLMacros, {ERRORCODE: error.code || 900}); //900 <== Undefined error\n\n /*** Local functions ***/\n function addErrorUrlMacros(ad) {\n if (ad.wrapper && ad.wrapper.error) {\n errorURLMacros.push(ad.wrapper.error);\n }\n\n if (ad.inLine && ad.inLine.error) {\n errorURLMacros.push(ad.inLine.error);\n }\n }\n};\n\nmodule.exports = VASTClient;\n\n},{\"../../utils/async\":38,\"../../utils/http\":40,\"../../utils/utilityFunctions\":43,\"../../utils/xml\":44,\"./Ad\":13,\"./VASTError\":21,\"./VASTResponse\":23,\"./vastUtil\":28}],21:[function(require,module,exports){\n'use strict';\n\nfunction VASTError(message, code) {\n this.message = 'VAST Error: ' + (message || '');\n if (code) {\n this.code = code;\n }\n}\n\nVASTError.prototype = new Error();\nVASTError.prototype.name = \"VAST Error\";\n\nmodule.exports = VASTError;\n},{}],22:[function(require,module,exports){\n'use strict';\n\n/**\n * Inner helper class that deals with the logic of the individual steps needed to setup an ad in the player.\n *\n * @param player {object} instance of the player that will play the ad. It assumes that the videojs-contrib-ads plugin\n * has been initialized when you use its utility functions.\n *\n * @constructor\n */\n\nvar VASTResponse = require('./VASTResponse');\nvar VASTError = require('./VASTError');\nvar VASTTracker = require('./VASTTracker');\nvar vastUtil = require('./vastUtil');\n\nvar async = require('../../utils/async');\nvar dom = require('../../utils/dom');\nvar playerUtils = require('../../utils/playerUtils');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VASTIntegrator(player) {\n if (!(this instanceof VASTIntegrator)) {\n return new VASTIntegrator(player);\n }\n\n this.player = player;\n}\n\nVASTIntegrator.prototype.playAd = function playAd(vastResponse, callback) {\n var that = this;\n callback = callback || utilities.noop;\n\n if (!(vastResponse instanceof VASTResponse)) {\n return callback(new VASTError('On VASTIntegrator, missing required VASTResponse'));\n }\n\n async.waterfall([\n function (next) {\n next(null, vastResponse);\n },\n this._selectAdSource.bind(this),\n this._createVASTTracker.bind(this),\n this._addClickThrough.bind(this),\n this._addSkipButton.bind(this),\n this._setupEvents.bind(this),\n this._playSelectedAd.bind(this)\n ], function (error, response) {\n if (error && response) {\n that._trackError(error, response);\n }\n callback(error, response);\n });\n\n this._adUnit = {\n _src: null,\n type: 'VAST',\n pauseAd: function () {\n that.player.pause(true);\n },\n\n resumeAd: function () {\n that.player.play(true);\n },\n\n isPaused: function () {\n return that.player.paused(true);\n },\n\n getSrc: function () {\n return this._src;\n }\n };\n\n return this._adUnit;\n};\n\nVASTIntegrator.prototype._selectAdSource = function selectAdSource(response, callback) {\n var source;\n\n var playerWidth = dom.getDimension(this.player.el()).width;\n response.mediaFiles.sort(function compareTo(a, b) {\n var deltaA = Math.abs(playerWidth - a.width);\n var deltaB = Math.abs(playerWidth - b.width);\n return deltaA - deltaB;\n });\n\n source = this.player.selectSource(response.mediaFiles).source;\n\n if (source) {\n if (this._adUnit) {\n this._adUnit._src = source;\n }\n return callback(null, source, response);\n }\n\n // code 403 <== Couldn't find MediaFile that is supported by this video player\n callback(new VASTError(\"Could not find Ad mediafile supported by this player\", 403), response);\n};\n\nVASTIntegrator.prototype._createVASTTracker = function createVASTTracker(adMediaFile, response, callback) {\n try {\n callback(null, adMediaFile, new VASTTracker(adMediaFile.src, response), response);\n } catch (e) {\n callback(e, response);\n }\n};\n\nVASTIntegrator.prototype._setupEvents = function setupEvents(adMediaFile, tracker, response, callback) {\n var previouslyMuted;\n var player = this.player;\n player.on('fullscreenchange', trackFullscreenChange);\n player.on('vast.adStart', trackImpressions);\n player.on('pause', trackPause);\n player.on('timeupdate', trackProgress);\n player.on('volumechange', trackVolumeChange);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], unbindEvents);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel', 'vast.adSkip'], function(evt){\n if(evt.type === 'vast.adEnd'){\n tracker.trackComplete();\n }\n });\n\n return callback(null, adMediaFile, response);\n\n /*** Local Functions ***/\n function unbindEvents() {\n player.off('fullscreenchange', trackFullscreenChange);\n player.off('vast.adStart', trackImpressions);\n player.off('pause', trackPause);\n player.off('timeupdate', trackProgress);\n player.off('volumechange', trackVolumeChange);\n }\n\n function trackFullscreenChange() {\n if (player.isFullscreen()) {\n tracker.trackFullscreen();\n } else {\n tracker.trackExitFullscreen();\n }\n }\n\n function trackPause() {\n //NOTE: whenever a video ends the video Element triggers a 'pause' event before the 'ended' event.\n // We should not track this pause event because it makes the VAST tracking confusing again we use a\n // Threshold of 2 seconds to prevent false positives on IOS.\n if (Math.abs(player.duration() - player.currentTime()) < 2) {\n return;\n }\n\n tracker.trackPause();\n playerUtils.once(player, ['play', 'vast.adEnd', 'vast.adsCancel'], function (evt) {\n if(evt.type === 'play'){\n tracker.trackResume();\n }\n });\n }\n\n function trackProgress() {\n var currentTimeInMs = player.currentTime() * 1000;\n tracker.trackProgress(currentTimeInMs);\n }\n\n function trackImpressions() {\n tracker.trackImpressions();\n tracker.trackCreativeView();\n }\n\n function trackVolumeChange() {\n var muted = player.muted();\n if (muted) {\n tracker.trackMute();\n } else if (previouslyMuted) {\n tracker.trackUnmute();\n }\n previouslyMuted = muted;\n }\n};\n\nVASTIntegrator.prototype._addSkipButton = function addSkipButton(source, tracker, response, callback) {\n var skipOffsetInSec;\n var that = this;\n\n if (utilities.isNumber(response.skipoffset)) {\n skipOffsetInSec = response.skipoffset / 1000;\n addSkipButtonToPlayer(this.player, skipOffsetInSec);\n }\n callback(null, source, tracker, response);\n\n /*** Local function ***/\n function addSkipButtonToPlayer(player, skipOffset) {\n var skipButton = createSkipButton(player);\n var updateSkipButton = updateSkipButtonState.bind(that, skipButton, skipOffset, player);\n\n player.el().appendChild(skipButton);\n player.on('timeupdate', updateSkipButton);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeSkipButton);\n\n function removeSkipButton() {\n player.off('timeupdate', updateSkipButton);\n dom.remove(skipButton);\n }\n }\n\n function createSkipButton(player) {\n var skipButton = window.document.createElement(\"div\");\n dom.addClass(skipButton, \"vast-skip-button\");\n\n skipButton.onclick = function (e) {\n if (dom.hasClass(skipButton, 'enabled')) {\n tracker.trackSkip();\n player.trigger('vast.adSkip');\n }\n\n //We prevent event propagation to avoid problems with the clickThrough and so on\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n } else {\n return false;\n }\n };\n\n return skipButton;\n }\n\n function updateSkipButtonState(skipButton, skipOffset, player) {\n var timeLeft = Math.ceil(skipOffset - player.currentTime());\n if (timeLeft > 0) {\n skipButton.innerHTML = \"Skip in \" + utilities.toFixedDigits(timeLeft, 2) + \"...\";\n } else {\n if (!dom.hasClass(skipButton, 'enabled')) {\n dom.addClass(skipButton, 'enabled');\n skipButton.innerHTML = \"Skip ad\";\n }\n }\n }\n};\n\nVASTIntegrator.prototype._addClickThrough = function addClickThrough(mediaFile, tracker, response, callback) {\n var player = this.player;\n var blocker = createClickThroughBlocker(player, tracker, response);\n var updateBlocker = updateBlockerURL.bind(this, blocker, response, player);\n\n player.el().insertBefore(blocker, player.controlBar.el());\n player.on('timeupdate', updateBlocker);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeBlocker);\n\n return callback(null, mediaFile, tracker, response);\n\n /*** Local Functions ***/\n\n function createClickThroughBlocker(player, tracker, response) {\n var blocker = window.document.createElement(\"a\");\n var clickThroughMacro = response.clickThrough;\n\n dom.addClass(blocker, 'vast-blocker');\n blocker.href = generateClickThroughURL(clickThroughMacro, player);\n\n if (utilities.isString(clickThroughMacro)) {\n blocker.target = \"_blank\";\n }\n\n blocker.onclick = function (e) {\n if (player.paused()) {\n player.play();\n\n //We prevent event propagation to avoid problems with the player's normal pause mechanism\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n }\n return false;\n }\n\n player.pause();\n tracker.trackClick();\n };\n\n return blocker;\n }\n\n function updateBlockerURL(blocker, response, player) {\n blocker.href = generateClickThroughURL(response.clickThrough, player);\n }\n\n function generateClickThroughURL(clickThroughMacro, player) {\n var variables = {\n ASSETURI: mediaFile.src,\n CONTENTPLAYHEAD: vastUtil.formatProgress(player.currentTime() * 1000)\n };\n\n return clickThroughMacro ? vastUtil.parseURLMacro(clickThroughMacro, variables) : '#';\n }\n\n function removeBlocker() {\n player.off('timeupdate', updateBlocker);\n dom.remove(blocker);\n }\n};\n\nVASTIntegrator.prototype._playSelectedAd = function playSelectedAd(source, response, callback) {\n var player = this.player;\n\n player.preload(\"auto\"); //without preload=auto the durationchange event is never fired\n player.src(source);\n\n playerUtils.once(player, ['durationchange', 'error', 'vast.adsCancel'], function (evt) {\n if (evt.type === 'durationchange') {\n playAd();\n } else if(evt.type === 'error') {\n callback(new VASTError(\"on VASTIntegrator, Player is unable to play the Ad\", 400), response);\n }\n //NOTE: If the ads get canceled we do nothing/\n });\n\n /**** local functions ******/\n function playAd() {\n playerUtils.once(player, ['playing', 'vast.adsCancel'], function (evt) {\n if(evt.type === 'vast.adsCancel'){\n return;\n }\n\n player.trigger('vast.adStart');\n\n playerUtils.once(player, ['ended', 'vast.adsCancel', 'vast.adSkip'], function (evt) {\n if(evt.type === 'ended' || evt.type === 'vast.adSkip'){\n callback(null, response);\n }\n //NOTE: if the ads get cancel we do nothing\n });\n });\n player.play();\n }\n};\n\nVASTIntegrator.prototype._trackError = function trackError(error, response) {\n vastUtil.track(response.errorURLMacros, {ERRORCODE: error.code || 900});\n};\n\nmodule.exports = VASTIntegrator;\n},{\"../../utils/async\":38,\"../../utils/dom\":39,\"../../utils/playerUtils\":41,\"../../utils/utilityFunctions\":43,\"./VASTError\":21,\"./VASTResponse\":23,\"./VASTTracker\":24,\"./vastUtil\":28}],23:[function(require,module,exports){\n'use strict';\n\nvar Ad = require('./Ad');\nvar VideoClicks = require('./VideoClicks');\nvar Linear = require('./Linear');\nvar InLine = require('./InLine');\nvar Wrapper = require('./Wrapper');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nwindow.InLine__A = InLine;\nfunction VASTResponse() {\n if (!(this instanceof VASTResponse)) {\n return new VASTResponse();\n }\n\n this._linearAdded = false;\n this.ads = [];\n this.errorURLMacros = [];\n this.impressions = [];\n this.clickTrackings = [];\n this.customClicks = [];\n this.trackingEvents = {};\n this.mediaFiles = [];\n this.clickThrough = undefined;\n this.adTitle = '';\n this.duration = undefined;\n this.skipoffset = undefined;\n}\n\nVASTResponse.prototype.addAd = function (ad) {\n var inLine, wrapper;\n if (ad instanceof Ad) {\n inLine = ad.inLine;\n wrapper = ad.wrapper;\n\n this.ads.push(ad);\n\n if (inLine) {\n this._addInLine(inLine);\n }\n\n if (wrapper) {\n this._addWrapper(wrapper);\n }\n }\n};\n\nVASTResponse.prototype._addErrorTrackUrl = function (error) {\n var errorURL = error instanceof xml.JXONTree ? xml.keyValue(error) : error;\n if (errorURL) {\n this.errorURLMacros.push(errorURL);\n }\n};\n\nVASTResponse.prototype._addImpressions = function (impressions) {\n utilities.isArray(impressions) && appendToArray(this.impressions, impressions);\n};\n\nVASTResponse.prototype._addClickThrough = function (clickThrough) {\n if (utilities.isNotEmptyString(clickThrough)) {\n this.clickThrough = clickThrough;\n }\n};\n\nVASTResponse.prototype._addClickTrackings = function (clickTrackings) {\n utilities.isArray(clickTrackings) && appendToArray(this.clickTrackings, clickTrackings);\n};\n\nVASTResponse.prototype._addCustomClicks = function (customClicks) {\n utilities.isArray(customClicks) && appendToArray(this.customClicks, customClicks);\n};\n\nVASTResponse.prototype._addTrackingEvents = function (trackingEvents) {\n var eventsMap = this.trackingEvents;\n\n if (trackingEvents) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingEvent) {\n if (!eventsMap[trackingEvent.name]) {\n eventsMap[trackingEvent.name] = [];\n }\n eventsMap[trackingEvent.name].push(trackingEvent);\n });\n }\n};\n\nVASTResponse.prototype._addTitle = function (title) {\n if (utilities.isNotEmptyString(title)) {\n this.adTitle = title;\n }\n};\n\nVASTResponse.prototype._addDuration = function (duration) {\n if (utilities.isNumber(duration)) {\n this.duration = duration;\n }\n};\n\nVASTResponse.prototype._addVideoClicks = function (videoClicks) {\n if (videoClicks instanceof VideoClicks) {\n this._addClickThrough(videoClicks.clickThrough);\n this._addClickTrackings(videoClicks.clickTrackings);\n this._addCustomClicks(videoClicks.customClicks);\n }\n};\n\nVASTResponse.prototype._addMediaFiles = function (mediaFiles) {\n utilities.isArray(mediaFiles) && appendToArray(this.mediaFiles, mediaFiles);\n};\n\nVASTResponse.prototype._addSkipoffset = function (offset) {\n if (offset) {\n this.skipoffset = offset;\n }\n};\n\nVASTResponse.prototype._addAdParameters = function (adParameters) {\n if (adParameters) {\n this.adParameters = adParameters;\n }\n};\n\nVASTResponse.prototype._addLinear = function (linear) {\n if (linear instanceof Linear) {\n this._addDuration(linear.duration);\n this._addTrackingEvents(linear.trackingEvents);\n this._addVideoClicks(linear.videoClicks);\n this._addMediaFiles(linear.mediaFiles);\n this._addSkipoffset(linear.skipoffset);\n this._addAdParameters(linear.adParameters);\n this._linearAdded = true;\n }\n};\n\nVASTResponse.prototype._addInLine = function (inLine) {\n var that = this;\n\n if (inLine instanceof InLine) {\n this._addTitle(inLine.adTitle);\n this._addErrorTrackUrl(inLine.error);\n this._addImpressions(inLine.impressions);\n\n inLine.creatives.forEach(function (creative) {\n if (creative.linear) {\n that._addLinear(creative.linear);\n }\n });\n }\n};\n\nVASTResponse.prototype._addWrapper = function (wrapper) {\n var that = this;\n\n if (wrapper instanceof Wrapper) {\n this._addErrorTrackUrl(wrapper.error);\n this._addImpressions(wrapper.impressions);\n\n wrapper.creatives.forEach(function (creative) {\n var linear = creative.linear;\n if (linear) {\n that._addVideoClicks(linear.videoClicks);\n that.clickThrough = undefined;//We ensure that no clickThrough has been added\n that._addTrackingEvents(linear.trackingEvents);\n }\n });\n }\n};\n\nVASTResponse.prototype.hasLinear = function(){\n return this._linearAdded;\n};\n\nfunction appendToArray(array, items) {\n items.forEach(function (item) {\n array.push(item);\n });\n}\n\nmodule.exports = VASTResponse;\n\n\n},{\"../../utils/utilityFunctions\":43,\"../../utils/xml\":44,\"./Ad\":13,\"./InLine\":16,\"./Linear\":17,\"./VideoClicks\":25,\"./Wrapper\":26}],24:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('./VASTError');\nvar VASTResponse = require('./VASTResponse');\nvar vastUtil = require('./vastUtil');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VASTTracker(assetURI, vastResponse) {\n if (!(this instanceof VASTTracker)) {\n return new VASTTracker(assetURI, vastResponse);\n }\n\n this.sanityCheck(assetURI, vastResponse);\n this.initialize(assetURI, vastResponse);\n\n}\n\nVASTTracker.prototype.initialize = function(assetURI, vastResponse) {\n this.response = vastResponse;\n this.assetURI = assetURI;\n this.progress = 0;\n this.quartiles = {\n firstQuartile: {tracked: false, time: Math.round(25 * vastResponse.duration) / 100},\n midpoint: {tracked: false, time: Math.round(50 * vastResponse.duration) / 100},\n thirdQuartile: {tracked: false, time: Math.round(75 * vastResponse.duration) / 100}\n };\n};\n\nVASTTracker.prototype.sanityCheck = function(assetURI, vastResponse) {\n if (!utilities.isString(assetURI) || utilities.isEmptyString(assetURI)) {\n throw new VASTError('on VASTTracker constructor, missing required the URI of the ad asset being played');\n }\n\n if (!(vastResponse instanceof VASTResponse)) {\n throw new VASTError('on VASTTracker constructor, missing required VAST response');\n }\n};\n\nVASTTracker.prototype.trackURLs = function trackURLs(urls, variables) {\n if (utilities.isArray(urls) && urls.length > 0) {\n variables = utilities.extend({\n ASSETURI: this.assetURI,\n CONTENTPLAYHEAD: vastUtil.formatProgress(this.progress)\n }, variables || {});\n\n vastUtil.track(urls, variables);\n }\n};\n\nVASTTracker.prototype.trackEvent = function trackEvent(eventName, trackOnce) {\n this.trackURLs(getEventUris(this.response.trackingEvents[eventName]));\n if (trackOnce) {\n this.response.trackingEvents[eventName] = undefined;\n }\n\n /*** Local function ***/\n function getEventUris(trackingEvents) {\n var uris;\n\n if (trackingEvents) {\n uris = [];\n trackingEvents.forEach(function (event) {\n uris.push(event.uri);\n });\n }\n return uris;\n }\n};\n\nVASTTracker.prototype.trackProgress = function trackProgress(newProgressInMs) {\n var that = this;\n var events = [];\n var ONCE = true;\n var ALWAYS = false;\n var trackingEvents = this.response.trackingEvents;\n\n if (utilities.isNumber(newProgressInMs)) {\n addTrackEvent('start', ONCE, newProgressInMs > 0);\n addTrackEvent('rewind', ALWAYS, hasRewound(this.progress, newProgressInMs));\n addQuartileEvents(newProgressInMs);\n trackProgressEvents(newProgressInMs);\n trackEvents();\n this.progress = newProgressInMs;\n }\n\n /*** Local function ***/\n function hasRewound(currentProgress, newProgress) {\n var REWIND_THRESHOLD = 3000; //IOS video clock is very unreliable and we need a 3 seconds threshold to ensure that there was a rewind an that it was on purpose.\n return currentProgress > newProgressInMs && Math.abs(newProgress - currentProgress) > REWIND_THRESHOLD;\n }\n\n function addTrackEvent(eventName, trackOnce, canBeAdded) {\n if (trackingEvents[eventName] && canBeAdded) {\n events.push({\n name: eventName,\n trackOnce: !!trackOnce\n });\n }\n }\n\n function addQuartileEvents(progress) {\n var quartiles = that.quartiles;\n var firstQuartile = that.quartiles.firstQuartile;\n var midpoint = that.quartiles.midpoint;\n var thirdQuartile = that.quartiles.thirdQuartile;\n\n if (!firstQuartile.tracked) {\n trackQuartile('firstQuartile', progress);\n } else if (!midpoint.tracked) {\n trackQuartile('midpoint', progress);\n } else if (!thirdQuartile.tracked){\n trackQuartile('thirdQuartile', progress);\n }\n\n /*** Local function ***/\n function trackQuartile(quartileName, progress){\n var quartile = quartiles[quartileName];\n if(canBeTracked(quartile, progress)){\n quartile.tracked = true;\n addTrackEvent(quartileName, ONCE, true);\n }\n }\n }\n\n function canBeTracked(quartile, progress) {\n var quartileTime = quartile.time;\n //We only fire the quartile event if the progress is bigger than the quartile time by 5 seconds at most.\n return progress >= quartileTime && progress <= (quartileTime + 5000);\n }\n\n function trackProgressEvents(progress) {\n if (!utilities.isArray(trackingEvents.progress)) {\n return; //Nothing to track\n }\n\n var pendingProgressEvts = [];\n\n trackingEvents.progress.forEach(function (evt) {\n if (evt.offset <= progress) {\n that.trackURLs([evt.uri]);\n } else {\n pendingProgressEvts.push(evt);\n }\n });\n trackingEvents.progress = pendingProgressEvts;\n }\n\n function trackEvents() {\n events.forEach(function (event) {\n that.trackEvent(event.name, event.trackOnce);\n });\n }\n};\n\n[\n 'rewind',\n 'fullscreen',\n 'exitFullscreen',\n 'pause',\n 'resume',\n 'mute',\n 'unmute',\n 'acceptInvitation',\n 'acceptInvitationLinear',\n 'collapse',\n 'expand'\n].forEach(function (eventName) {\n VASTTracker.prototype['track' + utilities.capitalize(eventName)] = function () {\n this.trackEvent(eventName);\n };\n });\n\n[\n 'start',\n 'skip',\n 'close',\n 'closeLinear'\n].forEach(function (eventName) {\n VASTTracker.prototype['track' + utilities.capitalize(eventName)] = function () {\n this.trackEvent(eventName, true);\n };\n });\n\n[\n 'firstQuartile',\n 'midpoint',\n 'thirdQuartile'\n].forEach(function (quartile) {\n VASTTracker.prototype['track' + utilities.capitalize(quartile)] = function () {\n this.quartiles[quartile].tracked = true;\n this.trackEvent(quartile, true);\n };\n });\n\nVASTTracker.prototype.trackComplete = function () {\n if(this.quartiles.thirdQuartile.tracked){\n this.trackEvent('complete', true);\n }\n};\n\nVASTTracker.prototype.trackErrorWithCode = function trackErrorWithCode(errorcode) {\n if (utilities.isNumber(errorcode)) {\n this.trackURLs(this.response.errorURLMacros, {ERRORCODE: errorcode});\n }\n};\n\nVASTTracker.prototype.trackImpressions = function trackImpressions() {\n this.trackURLs(this.response.impressions);\n};\n\nVASTTracker.prototype.trackCreativeView = function trackCreativeView() {\n this.trackEvent('creativeView');\n};\n\nVASTTracker.prototype.trackClick = function trackClick() {\n this.trackURLs(this.response.clickTrackings);\n};\n\nmodule.exports = VASTTracker;\n\n},{\"../../utils/utilityFunctions\":43,\"./VASTError\":21,\"./VASTResponse\":23,\"./vastUtil\":28}],25:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction VideoClicks(videoClickJTree) {\n if (!(this instanceof VideoClicks)) {\n return new VideoClicks(videoClickJTree);\n }\n\n this.clickThrough = xml.keyValue(videoClickJTree.clickThrough);\n this.clickTrackings = parseClickTrackings(videoClickJTree.clickTracking);\n this.customClicks = parseClickTrackings(videoClickJTree.customClick);\n\n /*** Local functions ***/\n function parseClickTrackings(trackingData) {\n var clickTrackings = [];\n if (trackingData) {\n trackingData = utilities.isArray(trackingData) ? trackingData : [trackingData];\n trackingData.forEach(function (clickTrackingData) {\n clickTrackings.push(xml.keyValue(clickTrackingData));\n });\n }\n return clickTrackings;\n }\n}\n\nmodule.exports = VideoClicks;\n},{\"../../utils/utilityFunctions\":43,\"../../utils/xml\":44}],26:[function(require,module,exports){\n'use strict';\n\nvar vastUtil = require('./vastUtil');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction Wrapper(wrapperJTree) {\n if(!(this instanceof Wrapper)) {\n return new Wrapper(wrapperJTree);\n }\n\n //Required elements\n this.adSystem = xml.keyValue(wrapperJTree.adSystem);\n this.impressions = vastUtil.parseImpressions(wrapperJTree.impression);\n this.VASTAdTagURI = xml.keyValue(wrapperJTree.vASTAdTagURI);\n\n //Optional elements\n this.creatives = vastUtil.parseCreatives(wrapperJTree.creatives);\n this.error = xml.keyValue(wrapperJTree.error);\n this.extensions = wrapperJTree.extensions;\n\n //Optional attrs\n this.followAdditionalWrappers = utilities.isDefined(xml.attr(wrapperJTree, 'followAdditionalWrappers'))? xml.attr(wrapperJTree, 'followAdditionalWrappers'): true;\n this.allowMultipleAds = xml.attr(wrapperJTree, 'allowMultipleAds');\n this.fallbackOnNoAd = xml.attr(wrapperJTree, 'fallbackOnNoAd');\n}\n\nmodule.exports = Wrapper;\n},{\"../../utils/utilityFunctions\":43,\"../../utils/xml\":44,\"./vastUtil\":28}],27:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\n\nvar durationRegex = /(\\d\\d):(\\d\\d):(\\d\\d)(\\.(\\d\\d\\d))?/;\n\nvar parsers = {\n\n duration: function parseDuration(durationStr) {\n\n var match, durationInMs;\n\n if (utilities.isString(durationStr)) {\n match = durationStr.match(durationRegex);\n if (match) {\n durationInMs = parseHoursToMs(match[1]) + parseMinToMs(match[2]) + parseSecToMs(match[3]) + parseInt(match[5] || 0);\n }\n }\n\n return isNaN(durationInMs) ? null : durationInMs;\n\n /*** local functions ***/\n function parseHoursToMs(hourStr) {\n return parseInt(hourStr, 10) * 60 * 60 * 1000;\n }\n\n function parseMinToMs(minStr) {\n return parseInt(minStr, 10) * 60 * 1000;\n }\n\n function parseSecToMs(secStr) {\n return parseInt(secStr, 10) * 1000;\n }\n },\n\n offset: function parseOffset(offset, duration) {\n if(isPercentage(offset)){\n return calculatePercentage(offset, duration);\n }\n return parsers.duration(offset);\n\n /*** Local function ***/\n function isPercentage(offset) {\n var percentageRegex = /^\\d+(\\.\\d+)?%$/g;\n return percentageRegex.test(offset);\n }\n\n function calculatePercentage(percentStr, duration) {\n if(duration) {\n return calcPercent(duration, parseFloat(percentStr.replace('%', '')));\n }\n return null;\n }\n\n function calcPercent(quantity, percent){\n return quantity * percent / 100;\n }\n }\n\n};\n\n\nmodule.exports = parsers;\n},{\"../../utils/utilityFunctions\":43}],28:[function(require,module,exports){\n'use strict';\n\nvar Creative = require('./Creative');\nvar utilities = require('../../utils/utilityFunctions');\n\nvar vastUtil = {\n\n track: function track(URLMacros, variables) {\n var sources = vastUtil.parseURLMacros(URLMacros, variables);\n var trackImgs = [];\n sources.forEach(function (src) {\n var img = new Image();\n img.src = src;\n trackImgs.push(img);\n });\n return trackImgs;\n },\n\n parseURLMacros: function parseMacros(URLMacros, variables) {\n var parsedURLs = [];\n\n variables = variables || {};\n\n if (!(variables[\"CACHEBUSTING\"])) {\n variables[\"CACHEBUSTING\"] = Math.round(Math.random() * 1.0e+10);\n }\n\n URLMacros.forEach(function (URLMacro) {\n parsedURLs.push(vastUtil._parseURLMacro(URLMacro, variables));\n });\n\n return parsedURLs;\n },\n\n parseURLMacro: function parseMacro(URLMacro, variables) {\n variables = variables || {};\n\n if (!(variables[\"CACHEBUSTING\"])) {\n variables[\"CACHEBUSTING\"] = Math.round(Math.random() * 1.0e+10);\n }\n\n return vastUtil._parseURLMacro(URLMacro, variables);\n },\n\n _parseURLMacro: function parseMacro(URLMacro, variables) {\n variables = variables || {};\n\n utilities.forEach(variables, function (value, key) {\n URLMacro = URLMacro.replace(new RegExp(\"\\\\[\" + key + \"\\\\\\]\", 'gm'), value);\n });\n\n return URLMacro;\n },\n\n parseDuration: function parseDuration(durationStr) {\n var durationRegex = /(\\d\\d):(\\d\\d):(\\d\\d)(\\.(\\d\\d\\d))?/;\n var match, durationInMs;\n\n if (utilities.isString(durationStr)) {\n match = durationStr.match(durationRegex);\n if (match) {\n durationInMs = parseHoursToMs(match[1]) + parseMinToMs(match[2]) + parseSecToMs(match[3]) + parseInt(match[5] || 0);\n }\n }\n\n return isNaN(durationInMs) ? null : durationInMs;\n\n /*** local functions ***/\n function parseHoursToMs(hourStr) {\n return parseInt(hourStr, 10) * 60 * 60 * 1000;\n }\n\n function parseMinToMs(minStr) {\n return parseInt(minStr, 10) * 60 * 1000;\n }\n\n function parseSecToMs(secStr) {\n return parseInt(secStr, 10) * 1000;\n }\n },\n\n parseImpressions: function parseImpressions(impressions) {\n if (impressions) {\n impressions = utilities.isArray(impressions) ? impressions : [impressions];\n return utilities.transformArray(impressions, function (impression) {\n if (utilities.isNotEmptyString(impression.keyValue)) {\n return impression.keyValue;\n }\n return undefined;\n });\n }\n return [];\n },\n\n parseCreatives: function parseCreatives(creativesJTree) {\n var creatives = [];\n var creativesData;\n if (utilities.isDefined(creativesJTree) && utilities.isDefined(creativesJTree.creative)) {\n creativesData = utilities.isArray(creativesJTree.creative) ? creativesJTree.creative : [creativesJTree.creative];\n creativesData.forEach(function (creative) {\n creatives.push(new Creative(creative));\n });\n }\n return creatives;\n },\n\n //We assume that the progress is going to arrive in milliseconds\n formatProgress: function formatProgress(progress) {\n var hours, minutes, seconds, milliseconds;\n hours = progress / (60 * 60 * 1000);\n hours = Math.floor(hours);\n minutes = (progress / (60 * 1000)) % 60;\n minutes = Math.floor(minutes);\n seconds = (progress / 1000) % 60;\n seconds = Math.floor(seconds);\n milliseconds = progress % 1000;\n return utilities.toFixedDigits(hours, 2) + ':' + utilities.toFixedDigits(minutes, 2) + ':' + utilities.toFixedDigits(seconds, 2) + '.' + utilities.toFixedDigits(milliseconds, 3);\n },\n\n parseOffset: function parseOffset(offset, duration) {\n if(isPercentage(offset)){\n return calculatePercentage(offset, duration);\n }\n return vastUtil.parseDuration(offset);\n\n /*** Local function ***/\n function isPercentage(offset) {\n var percentageRegex = /^\\d+(\\.\\d+)?%$/g;\n return percentageRegex.test(offset);\n }\n\n function calculatePercentage(percentStr, duration) {\n if(duration) {\n return calcPercent(duration, parseFloat(percentStr.replace('%', '')));\n }\n return null;\n }\n\n function calcPercent(quantity, percent){\n return quantity * percent / 100;\n }\n },\n\n isVPAID: function isVPAIDMediaFile(mediaFile) {\n return !!mediaFile && mediaFile.apiFramework === 'VPAID';\n }\n};\n\n\nmodule.exports = vastUtil;\n},{\"../../utils/utilityFunctions\":43,\"./Creative\":15}],29:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VPAIDAdUnitWrapper(vpaidAdUnit, opts) {\n if (!(this instanceof VPAIDAdUnitWrapper)) {\n return new VPAIDAdUnitWrapper(vpaidAdUnit, opts);\n }\n sanityCheck(vpaidAdUnit, opts);\n\n this.options = utilities.extend({}, opts);\n\n this._adUnit = vpaidAdUnit;\n\n /*** Local Functions ***/\n function sanityCheck(adUnit, opts) {\n if (!adUnit || !VPAIDAdUnitWrapper.checkVPAIDInterface(adUnit)) {\n throw new VASTError('on VPAIDAdUnitWrapper, the passed VPAID adUnit does not fully implement the VPAID interface');\n }\n\n if (!utilities.isObject(opts)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper, expected options hash but got '\" + opts + \"'\");\n }\n\n if (!(\"responseTimeout\" in opts) || !utilities.isNumber(opts.responseTimeout) ){\n throw new VASTError(\"on VPAIDAdUnitWrapper, expected responseTimeout in options\");\n }\n }\n}\n\nVPAIDAdUnitWrapper.checkVPAIDInterface = function checkVPAIDInterface(VPAIDAdUnit) {\n //NOTE: skipAd is not part of the method list because it only appears in VPAID 2.0 and we support VPAID 1.0\n var VPAIDInterfaceMethods = [\n 'handshakeVersion', 'initAd', 'startAd', 'stopAd', 'resizeAd', 'pauseAd', 'expandAd', 'collapseAd'\n ];\n\n for (var i = 0, len = VPAIDInterfaceMethods.length; i < len; i++) {\n if (!VPAIDAdUnit || !utilities.isFunction(VPAIDAdUnit[VPAIDInterfaceMethods[i]])) {\n return false;\n }\n }\n\n\n return canSubscribeToEvents(VPAIDAdUnit) && canUnsubscribeFromEvents(VPAIDAdUnit);\n\n /*** Local Functions ***/\n\n function canSubscribeToEvents(adUnit) {\n return utilities.isFunction(adUnit.subscribe) || utilities.isFunction(adUnit.addEventListener) || utilities.isFunction(adUnit.on);\n }\n\n function canUnsubscribeFromEvents(adUnit) {\n return utilities.isFunction(adUnit.unsubscribe) || utilities.isFunction(adUnit.removeEventListener) || utilities.isFunction(adUnit.off);\n\n }\n};\n\nVPAIDAdUnitWrapper.prototype.adUnitAsyncCall = function () {\n var args = utilities.arrayLikeObjToArray(arguments);\n var method = args.shift();\n var cb = args.pop();\n var timeoutId;\n\n sanityCheck(method, cb, this._adUnit);\n args.push(wrapCallback());\n\n this._adUnit[method].apply(this._adUnit, args);\n timeoutId = setTimeout(function () {\n timeoutId = null;\n cb(new VASTError(\"on VPAIDAdUnitWrapper, timeout while waiting for a response on call '\" + method + \"'\"));\n cb = utilities.noop;\n }, this.options.responseTimeout);\n\n /*** Local functions ***/\n function sanityCheck(method, cb, adUnit) {\n if (!utilities.isString(method) || !utilities.isFunction(adUnit[method])) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.adUnitAsyncCall, invalid method name\");\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.adUnitAsyncCall, missing callback\");\n }\n }\n\n function wrapCallback() {\n return function () {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n cb.apply(this, arguments);\n };\n }\n};\n\nVPAIDAdUnitWrapper.prototype.on = function (evtName, handler) {\n var addEventListener = this._adUnit.addEventListener || this._adUnit.subscribe || this._adUnit.on;\n addEventListener.call(this._adUnit, evtName, handler);\n};\n\nVPAIDAdUnitWrapper.prototype.off = function (evtName, handler) {\n var removeEventListener = this._adUnit.removeEventListener || this._adUnit.unsubscribe || this._adUnit.off;\n removeEventListener.call(this._adUnit, evtName, handler);\n};\n\nVPAIDAdUnitWrapper.prototype.waitForEvent = function (evtName, cb, context) {\n var timeoutId;\n sanityCheck(evtName, cb);\n context = context || null;\n\n this.on(evtName, responseListener);\n\n timeoutId = setTimeout(function () {\n cb(new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, timeout while waiting for event '\" + evtName + \"'\"));\n timeoutId = null;\n cb = utilities.noop;\n }, this.options.responseTimeout);\n\n /*** Local functions ***/\n function sanityCheck(evtName, cb) {\n if (!utilities.isString(evtName)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, missing evt name\");\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, missing callback\");\n }\n }\n\n function responseListener() {\n var args = utilities.arrayLikeObjToArray(arguments);\n\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n\n args.unshift(null);\n cb.apply(context, args);\n }\n};\n\n// VPAID METHODS\nVPAIDAdUnitWrapper.prototype.handshakeVersion = function (version, cb) {\n this.adUnitAsyncCall('handshakeVersion', version, cb);\n};\n\n/* jshint maxparams:6 */\nVPAIDAdUnitWrapper.prototype.initAd = function (width, height, viewMode, desiredBitrate, adUnitData, cb) {\n this.waitForEvent('AdLoaded', cb);\n this._adUnit.initAd(width, height, viewMode, desiredBitrate, adUnitData);\n};\n\nVPAIDAdUnitWrapper.prototype.resizeAd = function (width, height, viewMode, cb) {\n // NOTE: AdSizeChange event is only supported on VPAID 2.0 so for the moment we are not going to use it\n // and will assume that everything is fine after the async call\n this.adUnitAsyncCall('resizeAd', width, height, viewMode, cb);\n};\n\nVPAIDAdUnitWrapper.prototype.startAd = function (cb) {\n this.waitForEvent('AdStarted', cb);\n this._adUnit.startAd();\n};\n\nVPAIDAdUnitWrapper.prototype.stopAd = function (cb) {\n this.waitForEvent('AdStopped', cb);\n this._adUnit.stopAd();\n};\n\nVPAIDAdUnitWrapper.prototype.pauseAd = function (cb) {\n this.waitForEvent('AdPaused', cb);\n this._adUnit.pauseAd();\n};\n\nVPAIDAdUnitWrapper.prototype.resumeAd = function (cb) {\n this.waitForEvent('AdPlaying', cb);\n this._adUnit.resumeAd();\n};\n\nVPAIDAdUnitWrapper.prototype.expandAd = function (cb) {\n this.waitForEvent('AdExpandedChange', cb);\n this._adUnit.expandAd();\n};\n\nVPAIDAdUnitWrapper.prototype.collapseAd = function (cb) {\n this.waitForEvent('AdExpandedChange', cb);\n this._adUnit.collapseAd();\n};\n\nVPAIDAdUnitWrapper.prototype.skipAd = function (cb) {\n this.waitForEvent('AdSkipped', cb);\n this._adUnit.skipAd();\n};\n\n//VPAID property getters\n[\n 'adLinear',\n 'adWidth',\n 'adHeight',\n 'adExpanded',\n 'adSkippableState',\n 'adRemainingTime',\n 'adDuration',\n 'adVolume',\n 'adCompanions',\n 'adIcons'\n].forEach(function (property) {\n var getterName = 'get' + utilities.capitalize(property);\n\n VPAIDAdUnitWrapper.prototype[getterName] = function (cb) {\n this.adUnitAsyncCall(getterName, cb);\n };\n});\n\n//VPAID property setters\nVPAIDAdUnitWrapper.prototype.setAdVolume = function(volume, cb){\n this.adUnitAsyncCall('setAdVolume',volume, cb);\n};\n\nmodule.exports = VPAIDAdUnitWrapper;\n\n},{\"../../utils/utilityFunctions\":43,\"../vast/VASTError\":21}],30:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar VPAIDFLASHClient = require('VPAIDFLASHClient/js/VPAIDFLASHClient');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar dom = require('../../utils/dom');\n\nfunction VPAIDFlashTech(mediaFile, settings) {\n if (!(this instanceof VPAIDFlashTech)) {\n return new VPAIDFlashTech(mediaFile);\n }\n sanityCheck(mediaFile);\n this.name = 'vpaid-flash';\n this.mediaFile = mediaFile;\n this.containerEl = null;\n this.vpaidFlashClient = null;\n this.settings = settings;\n\n /*** local functions ***/\n function sanityCheck(mediaFile) {\n if (!mediaFile || !utilities.isString(mediaFile.src)) {\n throw new VASTError('on VPAIDFlashTech, invalid MediaFile');\n }\n }\n}\n\nVPAIDFlashTech.VPAIDFLASHClient = VPAIDFLASHClient;\n\nVPAIDFlashTech.supports = function (type) {\n return type === 'application/x-shockwave-flash' && VPAIDFlashTech.VPAIDFLASHClient.isSupported();\n};\n\nVPAIDFlashTech.prototype.loadAdUnit = function loadFlashCreative(containerEl, objectEl, callback) {\n var that = this;\n var flashClientOpts = this.settings && this.settings.vpaidFlashLoaderPath ? {data: this.settings.vpaidFlashLoaderPath} : undefined;\n sanityCheck(containerEl, callback);\n\n this.containerEl = containerEl;\n this.vpaidFlashClient = new VPAIDFlashTech.VPAIDFLASHClient(containerEl, function (error) {\n if (error) {\n return callback(error);\n }\n\n that.vpaidFlashClient.loadAdUnit(that.mediaFile.src, callback);\n }, flashClientOpts);\n\n /*** Local Functions ***/\n function sanityCheck(container, cb) {\n\n if (!dom.isDomElement(container)) {\n throw new VASTError('on VPAIDFlashTech.loadAdUnit, invalid dom container element');\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError('on VPAIDFlashTech.loadAdUnit, missing valid callback');\n }\n }\n};\n\nVPAIDFlashTech.prototype.unloadAdUnit = function () {\n if (this.vpaidFlashClient) {\n try{\n this.vpaidFlashClient.destroy();\n } catch(e){\n if(console && utilities.isFunction(console.log)){\n console.log('VAST ERROR: trying to unload the VPAID adunit');\n }\n }\n this.vpaidFlashClient = null;\n }\n\n if (this.containerEl) {\n dom.remove(this.containerEl);\n this.containerEl = null;\n }\n};\n\nmodule.exports = VPAIDFlashTech;\n},{\"../../utils/dom\":39,\"../../utils/utilityFunctions\":43,\"../vast/VASTError\":21,\"VPAIDFLASHClient/js/VPAIDFLASHClient\":3}],31:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar VPAIDHTML5Client = require('VPAIDHTML5Client/js/VPAIDHTML5Client');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar dom = require('../../utils/dom');\n\nfunction VPAIDHTML5Tech(mediaFile) {\n\n if(!(this instanceof VPAIDHTML5Tech)) {\n return new VPAIDHTML5Tech(mediaFile);\n }\n\n sanityCheck(mediaFile);\n\n this.name = 'vpaid-html5';\n this.containerEl = null;\n this.videoEl = null;\n this.vpaidHTMLClient = null;\n\n this.mediaFile = mediaFile;\n\n function sanityCheck(mediaFile) {\n if (!mediaFile || !utilities.isString(mediaFile.src)) {\n throw new VASTError(VPAIDHTML5Tech.INVALID_MEDIA_FILE);\n }\n }\n}\n\nVPAIDHTML5Tech.VPAIDHTML5Client = VPAIDHTML5Client;\n\nVPAIDHTML5Tech.supports = function (type) {\n return !utilities.isOldIE() && type === 'application/javascript';\n};\n\nVPAIDHTML5Tech.prototype.loadAdUnit = function loadAdUnit(containerEl, videoEl, callback) {\n sanityCheck(containerEl, videoEl, callback);\n\n this.containerEl = containerEl;\n this.videoEl = videoEl;\n this.vpaidHTMLClient = new VPAIDHTML5Tech.VPAIDHTML5Client(containerEl, videoEl, {});\n this.vpaidHTMLClient.loadAdUnit(this.mediaFile.src, callback);\n\n function sanityCheck(container, video, cb) {\n if (!dom.isDomElement(container)) {\n throw new VASTError(VPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL);\n }\n\n if (!dom.isDomElement(video) || video.tagName.toLowerCase() !== 'video') {\n throw new VASTError(VPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL);\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(VPAIDHTML5Tech.MISSING_CALLBACK);\n }\n }\n};\n\nVPAIDHTML5Tech.prototype.unloadAdUnit = function unloadAdUnit() {\n if (this.vpaidHTMLClient) {\n try {\n this.vpaidHTMLClient.destroy();\n } catch(e) {\n if (console && utilities.isFunction(console.log)) {\n console.log('VAST ERROR: trying to unload the VPAID adunit');\n }\n }\n\n this.vpaidHTMLClient = null;\n }\n\n if (this.containerEl) {\n dom.remove(this.containerEl);\n this.containerEl = null;\n }\n};\n\nvar PREFIX = 'on VPAIDHTML5Tech';\nVPAIDHTML5Tech.INVALID_MEDIA_FILE = PREFIX + ', invalid MediaFile';\nVPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL = PREFIX + ', invalid container HtmlElement';\nVPAIDHTML5Tech.INVALID_DOM_VIDEO_EL = PREFIX + ', invalid HTMLVideoElement';\nVPAIDHTML5Tech.MISSING_CALLBACK = PREFIX + ', missing valid callback';\n\nmodule.exports = VPAIDHTML5Tech;\n},{\"../../utils/dom\":39,\"../../utils/utilityFunctions\":43,\"../vast/VASTError\":21,\"VPAIDHTML5Client/js/VPAIDHTML5Client\":10}],32:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('../vast/VASTError');\nvar VASTResponse = require('../vast/VASTResponse');\nvar VASTTracker = require('../vast/VASTTracker');\nvar vastUtil = require('../vast/vastUtil');\n\nvar VPAIDAdUnitWrapper = require('./VPAIDAdUnitWrapper');\nvar VPAIDHTML5Tech = require('./VPAIDHTML5Tech');\nvar VPAIDFlashTech = require('./VPAIDFlashTech');\n\nvar async = require('../../utils/async');\nvar dom = require('../../utils/dom');\nvar playerUtils = require('../../utils/playerUtils');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VPAIDIntegrator(player, settings) {\n if (!(this instanceof VPAIDIntegrator)) {\n return new VPAIDIntegrator(player);\n }\n\n this.VIEW_MODE = {\n NORMAL: 'normal',\n FULLSCREEN: \"fullscreen\",\n THUMBNAIL: \"thumbnail\"\n };\n this.player = player;\n this.containerEl = createVPAIDContainerEl(player);\n this.options = {\n responseTimeout: 5000,\n VPAID_VERSION: '2.0'\n };\n this.settings = settings;\n\n /*** Local functions ***/\n\n function createVPAIDContainerEl() {\n var containerEl = document.createElement('div');\n dom.addClass(containerEl, 'VPAID-container');\n player.el().insertBefore(containerEl, player.controlBar.el());\n return containerEl;\n\n }\n}\n\n//List of supported VPAID technologies\nVPAIDIntegrator.techs = [\n VPAIDFlashTech,\n VPAIDHTML5Tech\n];\n\nVPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) {\n var that = this;\n var tech;\n var player = this.player;\n\n callback = callback || utilities.noop;\n if (!(vastResponse instanceof VASTResponse)) {\n return callback(new VASTError('on VASTIntegrator.playAd, missing required VASTResponse'));\n }\n\n tech = this._findSupportedTech(vastResponse, this.settings);\n dom.addClass(player.el(), 'vjs-vpaid-ad');\n\n player.on('vast.adsCancel', triggerVpaidAdEnd);\n player.one('vpaid.adEnd', function(){\n player.off('vast.adsCancel', triggerVpaidAdEnd);\n removeAdUnit();\n });\n\n if (tech) {\n async.waterfall([\n function (next) {\n next(null, tech, vastResponse);\n },\n this._loadAdUnit.bind(this),\n this._playAdUnit.bind(this),\n this._finishPlaying.bind(this)\n\n ], function (error, adUnit, vastResponse) {\n if (error) {\n that._trackError(vastResponse);\n }\n player.trigger('vpaid.adEnd');\n callback(error, vastResponse);\n });\n\n this._adUnit = {\n _paused: true,\n type: 'VPAID',\n pauseAd: function() {\n player.trigger('vpaid.pauseAd');\n player.pause(true);//we make sure that the video content gets stopped.\n },\n resumeAd: function() {\n player.trigger('vpaid.resumeAd');\n },\n isPaused: function() {\n return this._paused;\n },\n getSrc: function() {\n return tech.mediaFile;\n }\n };\n\n return this._adUnit;\n }\n\n callback(new VASTError('on VPAIDIntegrator.playAd, could not find a supported mediaFile'));\n\n return null;\n /*** Local functions ***/\n function triggerVpaidAdEnd(){\n player.trigger('vpaid.adEnd');\n }\n\n function removeAdUnit() {\n if (tech) {\n tech.unloadAdUnit();\n }\n dom.removeClass(player.el(), 'vjs-vpaid-ad');\n }\n};\n\nVPAIDIntegrator.prototype._findSupportedTech = function (vastResponse, settings) {\n if (!(vastResponse instanceof VASTResponse)) {\n return null;\n }\n\n var vpaidMediaFiles = vastResponse.mediaFiles.filter(vastUtil.isVPAID);\n var i, len, mediaFile, VPAIDTech;\n\n for (i = 0, len = vpaidMediaFiles.length; i < len; i += 1) {\n mediaFile = vpaidMediaFiles[i];\n VPAIDTech = findSupportedTech(mediaFile);\n if (VPAIDTech) {\n return new VPAIDTech(mediaFile, settings);\n }\n }\n return null;\n\n /*** Local functions ***/\n function findSupportedTech(mediafile) {\n var type = mediafile.type;\n var i, len, VPAIDTech;\n for (i = 0, len = VPAIDIntegrator.techs.length; i < len; i += 1) {\n VPAIDTech = VPAIDIntegrator.techs[i];\n if (VPAIDTech.supports(type)) {\n return VPAIDTech;\n }\n }\n return null;\n }\n};\n\nVPAIDIntegrator.prototype._createVPAIDAdUnitWrapper = function(adUnit, src, responseTimeout) {\n return new VPAIDAdUnitWrapper(adUnit, {src: src, responseTimeout: responseTimeout});\n};\n\nVPAIDIntegrator.prototype._loadAdUnit = function (tech, vastResponse, next) {\n var that = this;\n var player = this.player;\n var vjsTechEl = player.el().querySelector('.vjs-tech');\n var responseTimeout = this.settings.responseTimeout || this.options.responseTimeout;\n tech.loadAdUnit(this.containerEl, vjsTechEl, function (error, adUnit) {\n if (error) {\n return next(error, adUnit, vastResponse);\n }\n\n try {\n var WrappedAdUnit = that._createVPAIDAdUnitWrapper(adUnit, tech.mediaFile.src, responseTimeout);\n var techClass = 'vjs-' + tech.name + '-ad';\n dom.addClass(player.el(), techClass);\n player.one('vpaid.adEnd', function() {\n dom.removeClass(player.el(),techClass);\n });\n next(null, WrappedAdUnit, vastResponse);\n } catch (e) {\n next(e, adUnit, vastResponse);\n }\n });\n};\n\nVPAIDIntegrator.prototype._playAdUnit = function (adUnit, vastResponse, callback) {\n async.waterfall([\n function (next) {\n next(null, adUnit, vastResponse);\n },\n this._handshake.bind(this),\n this._initAd.bind(this),\n this._setupEvents.bind(this),\n this._addSkipButton.bind(this),\n this._linkPlayerControls.bind(this),\n this._startAd.bind(this)\n ], callback);\n};\n\nVPAIDIntegrator.prototype._handshake = function handshake(adUnit, vastResponse, next) {\n adUnit.handshakeVersion(this.options.VPAID_VERSION, function (error, version) {\n if (error) {\n return next(error, adUnit, vastResponse);\n }\n\n if (version && isSupportedVersion(version)) {\n return next(null, adUnit, vastResponse);\n }\n\n return next(new VASTError('on VPAIDIntegrator._handshake, unsupported version \"' + version + '\"'), adUnit, vastResponse);\n });\n\n function isSupportedVersion(version) {\n var majorNum = major(version);\n return majorNum >= 1 && majorNum <= 2;\n }\n\n function major(version) {\n var parts = version.split('.');\n return parseInt(parts[0], 10);\n }\n};\n\nVPAIDIntegrator.prototype._initAd = function (adUnit, vastResponse, next) {\n var tech = this.player.el().querySelector('.vjs-tech');\n var dimension = dom.getDimension(tech);\n adUnit.initAd(dimension.width, dimension.height, this.VIEW_MODE.NORMAL, -1, {AdParameters: vastResponse.adParameters || ''}, function (error) {\n next(error, adUnit, vastResponse);\n });\n};\n\nVPAIDIntegrator.prototype._createVASTTracker = function(adUnitSrc, vastResponse) {\n return new VASTTracker(adUnitSrc, vastResponse);\n};\n\nVPAIDIntegrator.prototype._setupEvents = function (adUnit, vastResponse, next) {\n var adUnitSrc = adUnit.options.src;\n var tracker = this._createVASTTracker(adUnitSrc, vastResponse);\n var player = this.player;\n var that = this;\n\n adUnit.on('AdSkipped', function () {\n player.trigger('vpaid.AdSkipped');\n tracker.trackSkip();\n });\n\n adUnit.on('AdImpression', function () {\n player.trigger('vpaid.AdImpression');\n tracker.trackImpressions();\n });\n\n adUnit.on('AdStarted', function () {\n player.trigger('vpaid.AdStarted');\n tracker.trackCreativeView();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdVideoStart', function () {\n player.trigger('vpaid.AdVideoStart');\n tracker.trackStart();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdPlaying', function () {\n player.trigger('vpaid.AdPlaying');\n tracker.trackResume();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdPaused', function () {\n player.trigger('vpaid.AdPaused');\n tracker.trackPause();\n notifyPauseToPlayer();\n });\n\n function notifyPlayToPlayer(){\n if(that._adUnit && that._adUnit.isPaused()){\n that._adUnit._paused = false;\n }\n player.trigger('play');\n\n }\n\n function notifyPauseToPlayer() {\n if(that._adUnit){\n that._adUnit._paused = true;\n }\n player.trigger('pause');\n }\n\n adUnit.on('AdVideoFirstQuartile', function () {\n player.trigger('vpaid.AdVideoFirstQuartile');\n tracker.trackFirstQuartile();\n });\n\n adUnit.on('AdVideoMidpoint', function () {\n player.trigger('vpaid.AdVideoMidpoint');\n tracker.trackMidpoint();\n });\n\n adUnit.on('AdVideoThirdQuartile', function () {\n player.trigger('vpaid.AdVideoThirdQuartile');\n tracker.trackThirdQuartile();\n });\n\n adUnit.on('AdVideoComplete', function () {\n player.trigger('vpaid.AdVideoComplete');\n tracker.trackComplete();\n });\n\n adUnit.on('AdClickThru', function (data) {\n player.trigger('vpaid.AdClickThru');\n var url = data.url;\n var playerHandles = data.playerHandles;\n var clickThruUrl = utilities.isNotEmptyString(url) ? url : generateClickThroughURL(vastResponse.clickThrough);\n\n tracker.trackClick();\n if (playerHandles && clickThruUrl) {\n window.open(clickThruUrl, '_blank');\n }\n\n function generateClickThroughURL(clickThroughMacro) {\n var variables = {\n ASSETURI: adUnit.options.src,\n CONTENTPLAYHEAD: 0 //In VPAID there is no method to know the current time from the adUnit\n };\n\n return clickThroughMacro ? vastUtil.parseURLMacro(clickThroughMacro, variables) : null;\n }\n });\n\n adUnit.on('AdUserAcceptInvitation', function () {\n player.trigger('vpaid.AdUserAcceptInvitation');\n tracker.trackAcceptInvitation();\n tracker.trackAcceptInvitationLinear();\n });\n\n adUnit.on('AdUserClose', function () {\n player.trigger('vpaid.AdUserClose');\n tracker.trackClose();\n tracker.trackCloseLinear();\n });\n\n adUnit.on('AdUserMinimize', function () {\n player.trigger('vpaid.AdUserMinimize');\n tracker.trackCollapse();\n });\n\n adUnit.on('AdError', function () {\n player.trigger('vpaid.AdError');\n //NOTE: we track errors code 901, as noted in VAST 3.0\n tracker.trackErrorWithCode(901);\n });\n\n adUnit.on('AdVolumeChange', function () {\n player.trigger('vpaid.AdVolumeChange');\n var lastVolume = player.volume();\n adUnit.getAdVolume(function (error, currentVolume) {\n if (currentVolume === 0 && lastVolume > 0) {\n tracker.trackMute();\n }\n\n if (currentVolume > 0 && lastVolume === 0) {\n tracker.trackUnmute();\n }\n\n player.volume(currentVolume);\n });\n });\n\n var updateViewSize = resizeAd.bind(this, player, adUnit, this.VIEW_MODE);\n var updateViewSizeThrottled = utilities.throttle(updateViewSize, 100);\n var autoResize = this.settings.autoResize;\n\n if (autoResize) {\n dom.addEventListener(window, 'resize', updateViewSizeThrottled);\n dom.addEventListener(window, 'orientationchange', updateViewSizeThrottled);\n }\n\n player.on('vast.resize', updateViewSize);\n player.on('vpaid.pauseAd', pauseAdUnit);\n player.on('vpaid.resumeAd', resumeAdUnit);\n\n player.one('vpaid.adEnd', function () {\n player.off('vast.resize', updateViewSize);\n player.off('vpaid.pauseAd', pauseAdUnit);\n player.off('vpaid.resumeAd', resumeAdUnit);\n\n if (autoResize) {\n dom.removeEventListener(window, 'resize', updateViewSizeThrottled);\n dom.removeEventListener(window, 'orientationchange', updateViewSizeThrottled);\n }\n });\n\n next(null, adUnit, vastResponse);\n\n /*** Local Functions ***/\n function pauseAdUnit() {\n adUnit.pauseAd(utilities.noop);\n }\n\n function resumeAdUnit() {\n adUnit.resumeAd(utilities.noop);\n }\n};\n\nVPAIDIntegrator.prototype._addSkipButton = function (adUnit, vastResponse, next) {\n var skipButton;\n var player = this.player;\n\n adUnit.on('AdSkippableStateChange', updateSkipButtonState);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeSkipButton);\n\n next(null, adUnit, vastResponse);\n\n /*** Local function ***/\n function updateSkipButtonState() {\n player.trigger('vpaid.AdSkippableStateChange');\n adUnit.getAdSkippableState(function (error, isSkippable) {\n if (isSkippable) {\n if (!skipButton) {\n addSkipButton(player);\n }\n } else {\n removeSkipButton(player);\n }\n });\n }\n\n function addSkipButton(player) {\n skipButton = createSkipButton(player);\n player.el().appendChild(skipButton);\n }\n\n function removeSkipButton() {\n dom.remove(skipButton);\n skipButton = null;\n }\n\n function createSkipButton() {\n var skipButton = window.document.createElement(\"div\");\n dom.addClass(skipButton, \"vast-skip-button\");\n dom.addClass(skipButton, \"enabled\");\n skipButton.innerHTML = \"Skip ad\";\n\n skipButton.onclick = function (e) {\n adUnit.skipAd(utilities.noop);//We skip the adUnit\n\n //We prevent event propagation to avoid problems with the clickThrough and so on\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n } else {\n return false;\n }\n };\n\n return skipButton;\n }\n};\n\nVPAIDIntegrator.prototype._linkPlayerControls = function (adUnit, vastResponse, next) {\n var that = this;\n linkVolumeControl(this.player, adUnit);\n linkFullScreenControl(this.player, adUnit, this.VIEW_MODE);\n\n next(null, adUnit, vastResponse);\n\n /*** Local functions ***/\n function linkVolumeControl(player, adUnit) {\n player.on('volumechange', updateAdUnitVolume);\n adUnit.on('AdVolumeChange', updatePlayerVolume);\n\n player.one('vpaid.adEnd', function () {\n player.off('volumechange', updateAdUnitVolume);\n });\n\n\n /*** local functions ***/\n function updateAdUnitVolume() {\n var vol = player.muted() ? 0 : player.volume();\n adUnit.setAdVolume(vol, logError);\n }\n\n function updatePlayerVolume() {\n player.trigger('vpaid.AdVolumeChange');\n adUnit.getAdVolume(function (error, vol) {\n if (error) {\n logError(error);\n } else {\n player.volume(vol);\n }\n });\n }\n }\n\n function linkFullScreenControl(player, adUnit, VIEW_MODE) {\n var updateViewSize = resizeAd.bind(that, player, adUnit, VIEW_MODE);\n\n player.on('fullscreenchange', updateViewSize);\n\n player.one('vpaid.adEnd', function () {\n player.off('fullscreenchange', updateViewSize);\n });\n }\n};\n\nVPAIDIntegrator.prototype._startAd = function (adUnit, vastResponse, next) {\n var player = this.player;\n\n adUnit.startAd(function (error) {\n if (!error) {\n player.trigger('vast.adStart');\n }\n next(error, adUnit, vastResponse);\n });\n};\n\nVPAIDIntegrator.prototype._finishPlaying = function (adUnit, vastResponse, next) {\n var player = this.player;\n adUnit.on('AdStopped', function () {\n player.trigger('vpaid.AdStopped');\n finishPlayingAd(null);\n });\n\n adUnit.on('AdError', function (error) {\n var errMsg = error? error.message : 'on VPAIDIntegrator, error while waiting for the adUnit to finish playing';\n finishPlayingAd(new VASTError(errMsg));\n });\n\n /*** local functions ***/\n function finishPlayingAd(error) {\n next(error, adUnit, vastResponse);\n }\n};\n\nVPAIDIntegrator.prototype._trackError = function trackError(response) {\n vastUtil.track(response.errorURLMacros, {ERRORCODE: 901});\n};\n\nfunction resizeAd(player, adUnit, VIEW_MODE) {\n var tech = player.el().querySelector('.vjs-tech');\n var dimension = dom.getDimension(tech);\n var MODE = player.isFullscreen() ? VIEW_MODE.FULLSCREEN : VIEW_MODE.NORMAL;\n adUnit.resizeAd(dimension.width, dimension.height, MODE, logError);\n}\n\nfunction logError(error) {\n if (error && console && console.log) {\n console.log('ERROR: ' + error.message, error);\n }\n}\n\nmodule.exports = VPAIDIntegrator;\n},{\"../../utils/async\":38,\"../../utils/dom\":39,\"../../utils/playerUtils\":41,\"../../utils/utilityFunctions\":43,\"../vast/VASTError\":21,\"../vast/VASTResponse\":23,\"../vast/VASTTracker\":24,\"../vast/vastUtil\":28,\"./VPAIDAdUnitWrapper\":29,\"./VPAIDFlashTech\":30,\"./VPAIDHTML5Tech\":31}],33:[function(require,module,exports){\n'use strict';\n\nvar dom = require('../../utils/dom');\n\nvar element = document.createElement('div');\nelement.className = 'vjs-ads-label vjs-control vjs-label-hidden';\nelement.innerHTML = 'Advertisement';\n\nvar AdsLabelFactory = function(baseComponent) {\n return {\n /** @constructor */\n init: function init(player, options) {\n options.el = element;\n baseComponent.call(this, player, options);\n\n // We asynchronously reposition the ads label element\n setTimeout(function () {\n var currentTimeComp = player.controlBar &&( player.controlBar.getChild(\"timerControls\") || player.controlBar.getChild(\"currentTimeDisplay\") );\n if(currentTimeComp) {\n player.controlBar.el().insertBefore(element, currentTimeComp.el());\n }\n dom.removeClass(element, 'vjs-label-hidden');\n }, 0);\n },\n\n el: function getElement() {\n return element;\n }\n };\n};\n\nmodule.exports = AdsLabelFactory;\n},{\"../../utils/dom\":39}],34:[function(require,module,exports){\n'use strict';\n\nvar baseVideoJsComponent = videojs.Component;\n\nvar AdsLabel = require('./ads-label')(baseVideoJsComponent);\n\nvideojs.AdsLabel = videojs.Component.extend(AdsLabel);\n\n},{\"./ads-label\":33}],35:[function(require,module,exports){\n'use strict';\n\n/**\n * The component that shows a black screen until the ads plugin has decided if it can or it can not play the ad.\n *\n * Note: In case you wonder why instead of this black poster we don't just show the spinner loader.\n * IOS devices do not work well with animations and the browser chrashes from time to time That is why we chose to\n * have a secondary black poster.\n *\n * It also makes it much more easier for the users of the plugin since it does not change the default behaviour of the\n * spinner and the player works the same way with and without the plugin.\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvar element = document.createElement('div');\n\nvar BlackPosterFactory = function(baseComponent) {\n return {\n /** @constructor */\n init: function init(player, options) {\n options.el = element;\n element.className = 'vjs-black-poster';\n baseComponent.call(this, player, options);\n\n var posterImg = player.getChild('posterImage');\n\n //We need to do it asynchronously to be sure that the black poster el is on the dom.\n setTimeout(function() {\n if(posterImg && player && player.el()) {\n player.el().insertBefore(element, posterImg.el());\n }\n }, 0);\n },\n el: function getElement() {\n return element;\n }\n };\n};\n\nmodule.exports = BlackPosterFactory;\n},{}],36:[function(require,module,exports){\n'use strict';\n\nvar baseVideoJsComponent = videojs.Component;\n\nvar BlackPoster = require('./black-poster')(baseVideoJsComponent);\n\nvideojs.BlackPoster = videojs.Component.extend(BlackPoster);\n\n},{\"./black-poster\":35}],37:[function(require,module,exports){\n'use strict';\n\nvar VASTClient = require('../ads/vast/VASTClient');\nvar VASTError = require('../ads/vast/VASTError');\nvar vastUtil = require('../ads/vast/vastUtil');\n\nvar VASTIntegrator = require('../ads/vast/VASTIntegrator');\nvar VPAIDIntegrator = require('../ads/vpaid/VPAIDIntegrator');\n\nvar async = require('../utils/async');\nvar dom = require('../utils/dom');\nvar playerUtils = require('../utils/playerUtils');\nvar utilities = require('../utils/utilityFunctions');\n\nmodule.exports = function VASTPlugin(options) {\n var snapshot;\n var player = this;\n var vast = new VASTClient();\n var adsCanceled = false;\n var defaultOpts = {\n // maximum amount of time in ms to wait to receive `adsready` from the ad\n // implementation after play has been requested. Ad implementations are\n // expected to load any dynamic libraries and make any requests to determine\n // ad policies for a video during this time.\n timeout: 500,\n\n //TODO:finish this IOS FIX\n //Whenever you play an add on IOS, the native player kicks in and we loose control of it. On very heavy pages the 'play' event\n // May occur after the video content has already started. This is wrong if you want to play a preroll ad that needs to happen before the user\n // starts watching the content. To prevent this usec\n iosPrerollCancelTimeout: 2000,\n\n // maximun amount of time for the ad to actually start playing. If this timeout gets\n // triggered the ads will be cancelled\n adCancelTimeout: 3000,\n\n // Boolean flag that configures the player to play a new ad before the user sees the video again\n // the current video\n playAdAlways: false,\n\n // Flag to enable or disable the ads by default.\n adsEnabled: true,\n\n // Boolean flag to enable or disable the resize with window.resize or orientationchange\n autoResize: true,\n\n // Path to the VPAID flash ad's loader\n vpaidFlashLoaderPath: '/VPAIDFlash.swf'\n };\n\n var settings = utilities.extend({}, defaultOpts, options || {});\n\n if(utilities.isUndefined(settings.adTagUrl) && utilities.isDefined(settings.url)){\n settings.adTagUrl = settings.url;\n }\n\n if (utilities.isString(settings.adTagUrl)) {\n settings.adTagUrl = utilities.echoFn(settings.adTagUrl);\n }\n\n if (utilities.isDefined(settings.adTagXML) && !utilities.isFunction(settings.adTagXML)) {\n return trackAdError(new VASTError('on VideoJS VAST plugin, the passed adTagXML option does not contain a function'));\n }\n\n if (!utilities.isDefined(settings.adTagUrl) && !utilities.isFunction(settings.adTagXML)) {\n return trackAdError(new VASTError('on VideoJS VAST plugin, missing adTagUrl on options object'));\n }\n\n playerUtils.prepareForAds(player);\n\n if (settings.playAdAlways) {\n // No matter what happens we play a new ad before the user sees the video again.\n player.on('vast.contentEnd', function () {\n setTimeout(function () {\n player.trigger('vast.reset');\n }, 0);\n });\n }\n\n player.on('vast.firstPlay', tryToPlayPrerollAd);\n\n player.on('vast.reset', function () {\n //If we are reseting the plugin, we don't want to restore the content\n snapshot = null;\n cancelAds();\n });\n\n player.vast = {\n isEnabled: function () {\n return settings.adsEnabled;\n },\n\n enable: function () {\n settings.adsEnabled = true;\n },\n\n disable: function () {\n settings.adsEnabled = false;\n }\n };\n\n return player.vast;\n\n /**** Local functions ****/\n function tryToPlayPrerollAd() {\n //We remove the poster to prevent flickering whenever the content starts playing\n playerUtils.removeNativePoster(player);\n\n playerUtils.once(player, ['vast.adsCancel', 'vast.adEnd'], function () {\n removeAdUnit();\n restoreVideoContent();\n });\n\n async.waterfall([\n checkAdsEnabled,\n preparePlayerForAd,\n startAdCancelTimeout,\n playPrerollAd\n ], function (error, response) {\n if (error) {\n trackAdError(error, response);\n } else {\n player.trigger('vast.adEnd');\n }\n });\n\n /*** Local functions ***/\n\n function removeAdUnit() {\n if (player.vast && player.vast.adUnit) {\n player.vast.adUnit = null; //We remove the adUnit\n }\n }\n\n function restoreVideoContent() {\n setupContentEvents();\n if (snapshot) {\n playerUtils.restorePlayerSnapshot(player, snapshot);\n snapshot = null;\n }\n }\n\n function setupContentEvents() {\n playerUtils.once(player, ['playing', 'vast.reset', 'vast.firstPlay'], function (evt) {\n if (evt.type !== 'playing') {\n return;\n }\n\n player.trigger('vast.contentStart');\n\n playerUtils.once(player, ['ended', 'vast.reset', 'vast.firstPlay'], function (evt) {\n if (evt.type === 'ended') {\n player.trigger('vast.contentEnd');\n }\n });\n });\n }\n\n function checkAdsEnabled(next) {\n if (settings.adsEnabled) {\n return next(null);\n }\n next(new VASTError('Ads are not enabled'));\n }\n\n function preparePlayerForAd(next) {\n if (canPlayPrerollAd()) {\n snapshot = playerUtils.getPlayerSnapshot(player);\n player.pause();\n addSpinnerIcon();\n\n if(player.paused()) {\n next(null);\n } else {\n playerUtils.once(player, ['playing'], function() {\n player.pause();\n next(null);\n });\n }\n } else {\n next(new VASTError('video content has been playing before preroll ad'));\n }\n }\n\n function canPlayPrerollAd() {\n return !utilities.isIPhone() || player.currentTime() <= settings.iosPrerollCancelTimeout;\n }\n\n function startAdCancelTimeout(next) {\n var adCancelTimeoutId;\n adsCanceled = false;\n\n adCancelTimeoutId = setTimeout(function () {\n trackAdError(new VASTError('timeout while waiting for the video to start playing', 402));\n }, settings.adCancelTimeout);\n\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], clearAdCancelTimeout);\n\n /*** local functions ***/\n function clearAdCancelTimeout() {\n if (adCancelTimeoutId) {\n clearTimeout(adCancelTimeoutId);\n adCancelTimeoutId = null;\n }\n }\n\n next(null);\n }\n\n function addSpinnerIcon() {\n dom.addClass(player.el(), 'vjs-vast-ad-loading');\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], removeSpinnerIcon);\n }\n\n function removeSpinnerIcon() {\n //IMPORTANT NOTE: We remove the spinnerIcon asynchronously to give time to the browser to start the video.\n // If we remove it synchronously we see a flash of the content video before the ad starts playing.\n setTimeout(function () {\n dom.removeClass(player.el(), 'vjs-vast-ad-loading');\n }, 100);\n }\n\n }\n\n function cancelAds() {\n player.trigger('vast.adsCancel');\n adsCanceled = true;\n }\n\n function playPrerollAd(callback) {\n async.waterfall([\n getVastResponse,\n playAd\n ], callback);\n }\n\n function getVastResponse(callback) {\n vast.getVASTResponse(settings.adTagUrl ? settings.adTagUrl() : settings.adTagXML, callback);\n }\n\n function playAd(vastResponse, callback) {\n //TODO: Find a better way to stop the play. The 'playPrerollWaterfall' ends in an inconsistent situation\n //If the state is not 'preroll?' it means the ads were canceled therefore, we break the waterfall\n if (adsCanceled) {\n return;\n }\n\n var adIntegrator = isVPAID(vastResponse) ? new VPAIDIntegrator(player, settings) : new VASTIntegrator(player);\n var adFinished = false;\n\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], function (evt) {\n if (evt.type === 'vast.adStart') {\n addAdsLabel();\n }\n });\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeAdsLabel);\n\n if (utilities.isIDevice()) {\n preventManualProgress();\n }\n\n player.vast.vastResponse = vastResponse;\n player.vast.adUnit = adIntegrator.playAd(vastResponse, callback);\n\n /*** Local functions ****/\n function addAdsLabel() {\n if (adFinished || player.controlBar.getChild('AdsLabel')) {\n return;\n }\n\n player.controlBar.addChild('AdsLabel');\n }\n\n function removeAdsLabel() {\n player.controlBar.removeChild('AdsLabel');\n adFinished = true;\n }\n\n function preventManualProgress() {\n //IOS video clock is very unreliable and we need a 3 seconds threshold to ensure that the user forwarded/rewound the ad\n var PROGRESS_THRESHOLD = 3;\n var previousTime = 0;\n var skipad_attempts = 0;\n\n player.on('timeupdate', adTimeupdateHandler);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel', 'vast.adError'], stopPreventManualProgress);\n\n /*** Local functions ***/\n function adTimeupdateHandler() {\n var currentTime = player.currentTime();\n var progressDelta = Math.abs(currentTime - previousTime);\n\n if (progressDelta > PROGRESS_THRESHOLD) {\n skipad_attempts += 1;\n if (skipad_attempts >= 2) {\n player.pause();\n }\n player.currentTime(previousTime);\n } else {\n previousTime = currentTime;\n }\n }\n\n function stopPreventManualProgress() {\n player.off('timeupdate', adTimeupdateHandler);\n }\n }\n }\n\n function trackAdError(error, vastResponse) {\n player.trigger({type: 'vast.adError', error: error});\n cancelAds();\n if (console && console.log) {\n console.log('AD ERROR:', error.message, error, vastResponse);\n }\n }\n\n function isVPAID(vastResponse) {\n var i, len;\n var mediaFiles = vastResponse.mediaFiles;\n for (i = 0, len = mediaFiles.length; i < len; i++) {\n if (vastUtil.isVPAID(mediaFiles[i])) {\n return true;\n }\n }\n return false;\n }\n};\n},{\"../ads/vast/VASTClient\":20,\"../ads/vast/VASTError\":21,\"../ads/vast/VASTIntegrator\":22,\"../ads/vast/vastUtil\":28,\"../ads/vpaid/VPAIDIntegrator\":32,\"../utils/async\":38,\"../utils/dom\":39,\"../utils/playerUtils\":41,\"../utils/utilityFunctions\":43}],38:[function(require,module,exports){\n//Small subset of async\n\nvar utilities = require('./utilityFunctions');\n\nvar async = {};\n\nasync.setImmediate = function (fn) {\n setTimeout(fn, 0);\n};\n\nasync.iterator = function (tasks) {\n var makeCallback = function (index) {\n var fn = function () {\n if (tasks.length) {\n tasks[index].apply(null, arguments);\n }\n return fn.next();\n };\n fn.next = function () {\n return (index < tasks.length - 1) ? makeCallback(index + 1) : null;\n };\n return fn;\n };\n return makeCallback(0);\n};\n\n\nasync.waterfall = function (tasks, callback) {\n callback = callback || function () { };\n if (!utilities.isArray(tasks)) {\n var err = new Error('First argument to waterfall must be an array of functions');\n return callback(err);\n }\n if (!tasks.length) {\n return callback();\n }\n var wrapIterator = function (iterator) {\n return function (err) {\n if (err) {\n callback.apply(null, arguments);\n callback = function () {\n };\n }\n else {\n var args = Array.prototype.slice.call(arguments, 1);\n var next = iterator.next();\n if (next) {\n args.push(wrapIterator(next));\n }\n else {\n args.push(callback);\n }\n async.setImmediate(function () {\n iterator.apply(null, args);\n });\n }\n };\n };\n wrapIterator(async.iterator(tasks))();\n};\n\nasync.when = function (condition, callback) {\n if (!utilities.isFunction(callback)) {\n throw new Error(\"async.when error: missing callback argument\");\n }\n\n var isAllowed = utilities.isFunction(condition) ? condition : function () {\n return !!condition;\n };\n\n return function () {\n var args = utilities.arrayLikeObjToArray(arguments);\n var next = args.pop();\n\n if (isAllowed.apply(null, args)) {\n return callback.apply(this, arguments);\n }\n\n args.unshift(null);\n return next.apply(null, args);\n };\n};\n\nmodule.exports = async;\n\n\n},{\"./utilityFunctions\":43}],39:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('./utilityFunctions');\n\nvar dom = {};\n\ndom.isVisible = function isVisible(el) {\n var style = window.getComputedStyle(el);\n return style.visibility !== 'hidden';\n};\n\ndom.isHidden = function isHidden(el) {\n var style = window.getComputedStyle(el);\n return style.display === 'none';\n};\n\ndom.isShown = function isShown(el) {\n return !dom.isHidden(el);\n};\n\ndom.hide = function hide(el) {\n el.__prev_style_display_ = el.style.display;\n el.style.display = 'none';\n};\n\ndom.show = function show(el) {\n if (dom.isHidden(el)) {\n el.style.display = el.__prev_style_display_;\n }\n el.__prev_style_display_ = undefined;\n};\n\ndom.hasClass = function hasClass(el, cssClass) {\n var classes, i, len;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.contains(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n cssClass = (cssClass || '');\n\n for (i = 0, len = classes.length; i < len; i += 1) {\n if (classes[i] === cssClass) {\n return true;\n }\n }\n }\n return false;\n};\n\ndom.addClass = function (el, cssClass) {\n var classes;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.add(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n if (utilities.isString(cssClass) && utilities.isNotEmptyString(cssClass.replace(/\\s+/, ''))) {\n classes.push(cssClass);\n el.setAttribute('class', classes.join(' '));\n }\n }\n};\n\ndom.removeClass = function (el, cssClass) {\n var classes;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.remove(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n var newClasses = [];\n var i, len;\n if (utilities.isString(cssClass) && utilities.isNotEmptyString(cssClass.replace(/\\s+/, ''))) {\n\n for (i = 0, len = classes.length; i < len; i += 1) {\n if (cssClass !== classes[i]) {\n newClasses.push(classes[i]);\n }\n }\n el.setAttribute('class', newClasses.join(' '));\n }\n }\n};\n\ndom.addEventListener = function addEventListener(el, type, handler) {\n if(utilities.isArray(el)){\n utilities.forEach(el, function(e) {\n dom.addEventListener(e, type, handler);\n });\n return;\n }\n\n if(utilities.isArray(type)){\n utilities.forEach(type, function(t) {\n dom.addEventListener(el, t, handler);\n });\n return;\n }\n\n if (el.addEventListener) {\n el.addEventListener(type, handler, false);\n } else if (el.attachEvent) {\n // WARNING!!! this is a very naive implementation !\n // the event object that should be passed to the handler\n // would not be there for IE8\n // we should use \"window.event\" and then \"event.srcElement\"\n // instead of \"event.target\"\n el.attachEvent(\"on\" + type, handler);\n }\n};\n\ndom.removeEventListener = function removeEventListener(el, type, handler) {\n if(utilities.isArray(el)){\n utilities.forEach(el, function(e) {\n dom.removeEventListener(e, type, handler);\n });\n return;\n }\n\n if(utilities.isArray(type)){\n utilities.forEach(type, function(t) {\n dom.removeEventListener(el, t, handler);\n });\n return;\n }\n\n if (el.removeEventListener) {\n el.removeEventListener(type, handler, false);\n } else if (el.detachEvent) {\n el.detachEvent(\"on\" + type, handler);\n } else {\n el[\"on\" + type] = null;\n }\n};\n\ndom.dispatchEvent = function dispatchEvent(el, event) {\n if (el.dispatchEvent) {\n el.dispatchEvent(event);\n } else {\n el.fireEvent(\"on\" + event.eventType, event);\n }\n};\n\ndom.isDescendant = function isDescendant(parent, child) {\n var node = child.parentNode;\n while (node !== null) {\n if (node === parent) {\n return true;\n }\n node = node.parentNode;\n }\n return false;\n};\n\ndom.getTextContent = function getTextContent(el){\n return el.textContent || el.text;\n};\n\ndom.prependChild = function prependChild(parent, child) {\n if(child.parentNode){\n child.parentNode.removeChild(child);\n }\n return parent.insertBefore(child, parent.firstChild);\n};\n\ndom.remove = function removeNode(node){\n if(node && node.parentNode){\n node.parentNode.removeChild(node);\n }\n};\n\ndom.isDomElement = function isDomElement(o) {\n return o instanceof Element;\n};\n\ndom.click = function(el, handler) {\n dom.addEventListener(el, 'click', handler);\n};\n\ndom.once = function(el, type, handler) {\n function handlerWrap() {\n handler.apply(null, arguments);\n dom.removeEventListener(el, type, handlerWrap);\n }\n\n dom.addEventListener(el, type, handlerWrap);\n};\n\n//Note: there is no getBoundingClientRect on iPad so we need a fallback\ndom.getDimension = function getDimension(element) {\n var rect;\n\n //On IE9 and below getBoundingClientRect does not work consistently\n if(!utilities.isOldIE() && element.getBoundingClientRect) {\n rect = element.getBoundingClientRect();\n return {\n width: rect.width,\n height: rect.height\n };\n }\n\n return {\n width: element.offsetWidth,\n height: element.offsetHeight\n };\n};\n\nmodule.exports = dom;\n},{\"./utilityFunctions\":43}],40:[function(require,module,exports){\n'use strict';\n\nvar urlUtils = require('./urlUtils');\nvar utilities = require('./utilityFunctions');\n\nfunction HttpRequestError(message) {\n this.message = 'HttpRequest Error: ' + (message || '');\n}\nHttpRequestError.prototype = new Error();\nHttpRequestError.prototype.name = \"HttpRequest Error\";\n\nfunction HttpRequest(createXhr) {\n if (!utilities.isFunction(createXhr)) {\n throw new HttpRequestError('Missing XMLHttpRequest factory method');\n }\n\n this.createXhr = createXhr;\n}\n\nHttpRequest.prototype.run = function (method, url, callback, options) {\n sanityCheck(url, callback, options);\n var timeout, timeoutId;\n var xhr = this.createXhr();\n options = options || {};\n timeout = utilities.isNumber(options.timeout) ? options.timeout : 0;\n\n xhr.open(method, urlUtils.urlParts(url).href, true);\n\n if (options.headers) {\n setHeaders(xhr, options.headers);\n }\n\n if (options.withCredentials) {\n xhr.withCredentials = true;\n }\n\n xhr.onload = function () {\n var statusText, response, status;\n\n /**\n * The only way to do a secure request on IE8 and IE9 is with the XDomainRequest object. Unfortunately, microsoft is\n * so nice that decided that the status property and the 'getAllResponseHeaders' method where not needed so we have to\n * fake them. If the request gets done with an XDomainRequest instance, we will assume that there are no headers and\n * the status will always be 200. If you don't like it, DO NOT USE ANCIENT BROWSERS!!!\n *\n * For mor info go to: https://msdn.microsoft.com/en-us/library/cc288060(v=vs.85).aspx\n */\n if (!xhr.getAllResponseHeaders) {\n xhr.getAllResponseHeaders = function () {\n return null;\n };\n }\n\n if (!xhr.status) {\n xhr.status = 200;\n }\n\n if (utilities.isDefined(timeoutId)) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n\n statusText = xhr.statusText || '';\n\n // responseText is the old-school way of retrieving response (supported by IE8 & 9)\n // response/responseType properties were introduced in XHR Level2 spec (supported by IE10)\n response = ('response' in xhr) ? xhr.response : xhr.responseText;\n\n // normalize IE9 bug (http://bugs.jquery.com/ticket/1450)\n status = xhr.status === 1223 ? 204 : xhr.status;\n\n callback(\n status,\n response,\n xhr.getAllResponseHeaders(),\n statusText);\n };\n\n xhr.onerror = requestError;\n xhr.onabort = requestError;\n\n xhr.send();\n\n if (timeout > 0) {\n timeoutId = setTimeout(function () {\n xhr && xhr.abort();\n }, timeout);\n }\n\n function sanityCheck(url, callback, options) {\n if (!utilities.isString(url) || utilities.isEmptyString(url)) {\n throw new HttpRequestError(\"Invalid url '\" + url + \"'\");\n }\n\n if (!utilities.isFunction(callback)) {\n throw new HttpRequestError(\"Invalid handler '\" + callback + \"' for the http request\");\n }\n\n if (utilities.isDefined(options) && !utilities.isObject(options)) {\n throw new HttpRequestError(\"Invalid options map '\" + options + \"'\");\n }\n }\n\n function setHeaders(xhr, headers) {\n utilities.forEach(headers, function (value, key) {\n if (utilities.isDefined(value)) {\n xhr.setRequestHeader(key, value);\n }\n });\n }\n\n function requestError() {\n callback(-1, null, null, '');\n }\n};\n\nHttpRequest.prototype.get = function (url, callback, options) {\n this.run('GET', url, processResponse, options);\n\n function processResponse(status, response, headersString, statusText) {\n if (isSuccess(status)) {\n callback(null, response, status, headersString, statusText);\n } else {\n callback(new HttpRequestError(statusText), response, status, headersString, statusText);\n }\n }\n\n function isSuccess(status) {\n return 200 <= status && status < 300;\n }\n};\n\nfunction createXhr() {\n var xhr = new XMLHttpRequest();\n if (!(\"withCredentials\" in xhr)) {\n // XDomainRequest for IE.\n xhr = new XDomainRequest();\n }\n return xhr;\n}\n\nvar http = new HttpRequest(createXhr);\n\nmodule.exports = {\n http: http,\n HttpRequest: HttpRequest,\n HttpRequestError: HttpRequestError,\n createXhr: createXhr\n};\n\n},{\"./urlUtils\":42,\"./utilityFunctions\":43}],41:[function(require,module,exports){\n'use strict';\n\nvar dom = require('./dom');\nvar utilities = require('./utilityFunctions');\n\nvar playerUtils = {};\n\n/**\n * Returns an object that captures the portions of player state relevant to\n * video playback. The result of this function can be passed to\n * restorePlayerSnapshot with a player to return the player to the state it\n * was in when this function was invoked.\n * @param {object} player The videojs player object\n */\nplayerUtils.getPlayerSnapshot = function getPlayerSnapshot(player) {\n var tech = player.el().querySelector('.vjs-tech');\n\n var snapshot = {\n ended: player.ended(),\n src: player.currentSrc(),\n currentTime: player.currentTime(),\n type: player.currentType(),\n playing: !player.paused(),\n suppressedTracks: getSuppressedTracks(player)\n };\n\n if (tech) {\n snapshot.nativePoster = tech.poster;\n snapshot.style = tech.getAttribute('style');\n }\n return snapshot;\n\n /**** Local Functions ****/\n function getSuppressedTracks(player) {\n var tracks = player.remoteTextTracks ? player.remoteTextTracks() : [];\n\n if (tracks && utilities.isArray(tracks.tracks_)) {\n tracks = tracks.tracks_;\n }\n\n if (!utilities.isArray(tracks)) {\n tracks = [];\n }\n\n var suppressedTracks = [];\n tracks.forEach(function (track) {\n suppressedTracks.push({\n track: track,\n mode: track.mode\n });\n track.mode = 'disabled';\n });\n\n return suppressedTracks;\n }\n};\n\n/**\n * Attempts to modify the specified player so that its state is equivalent to\n * the state of the snapshot.\n * @param {object} snapshot - the player state to apply\n */\nplayerUtils.restorePlayerSnapshot = function restorePlayerSnapshot(player, snapshot) {\n var tech = player.el().querySelector('.vjs-tech');\n var attempts = 20; // the number of remaining attempts to restore the snapshot\n\n if (snapshot.nativePoster) {\n tech.poster = snapshot.nativePoster;\n }\n\n if ('style' in snapshot) {\n // overwrite all css style properties to restore state precisely\n tech.setAttribute('style', snapshot.style || '');\n }\n\n if (hasSrcChanged(player, snapshot)) {\n\n // on ios7, fiddling with textTracks too early will cause safari to crash\n player.one('contentloadedmetadata', restoreTracks);\n\n player.one('canplay', tryToResume);\n ensureCanplayEvtGetsFired();\n\n // if the src changed for ad playback, reset it\n player.src({src: snapshot.src, type: snapshot.type});\n\n // safari requires a call to `load` to pick up a changed source\n player.load();\n\n } else {\n restoreTracks();\n\n if (snapshot.playing) {\n player.play();\n }\n }\n\n /*** Local Functions ***/\n\n /**\n * Sometimes firefox does not trigger the 'canplay' evt.\n * This code ensure that it always gets triggered triggered.\n */\n function ensureCanplayEvtGetsFired() {\n var timeoutId = setTimeout(function() {\n player.trigger('canplay');\n }, 1000);\n\n player.one('canplay', function(){\n clearTimeout(timeoutId);\n });\n }\n\n /**\n * Determine whether the player needs to be restored to its state\n * before ad playback began. With a custom ad display or burned-in\n * ads, the content player state hasn't been modified and so no\n * restoration is required\n */\n function hasSrcChanged(player, snapshot) {\n if (player.src()) {\n return player.src() !== snapshot.src;\n }\n // the player was configured through source element children\n return player.currentSrc() !== snapshot.src;\n }\n\n function restoreTracks() {\n var suppressedTracks = snapshot.suppressedTracks;\n suppressedTracks.forEach(function (trackSnapshot) {\n trackSnapshot.track.mode = trackSnapshot.mode;\n });\n }\n\n /**\n * Determine if the video element has loaded enough of the snapshot source\n * to be ready to apply the rest of the state\n */\n function tryToResume() {\n\n // if some period of the video is seekable, resume playback\n // otherwise delay a bit and then check again unless we're out of attempts\n\n if (!playerUtils.isReadyToResume(player) && attempts--) {\n setTimeout(tryToResume, 50);\n } else {\n try {\n if(player.currentTime() !== snapshot.currentTime) {\n if (snapshot.playing) { // if needed restore playing status after seek completes\n player.one('seeked', function() {\n player.play();\n });\n }\n player.currentTime(snapshot.currentTime);\n\n } else if (snapshot.playing) {\n // if needed and no seek has been performed, restore playing status immediately\n player.play();\n }\n\n } catch (e) {\n videojs.log.warn('Failed to resume the content after an advertisement', e);\n }\n }\n }\n};\n\nplayerUtils.isReadyToResume = function (player) {\n\n if (player.readyState() > 1) {\n // some browsers and media aren't \"seekable\".\n // readyState greater than 1 allows for seeking without exceptions\n return true;\n }\n\n if (player.seekable() === undefined) {\n // if the player doesn't expose the seekable time ranges, try to\n // resume playback immediately\n return true;\n }\n\n if (player.seekable().length > 0) {\n // if some period of the video is seekable, resume playback\n return true;\n }\n\n return false;\n};\n\n/**\n * This function prepares the player to display ads.\n * Adding convenience events like the 'vast.firsPlay' that gets fired when the video is first played\n * and ads the blackPoster to the player to prevent content from being displayed before the preroll ad.\n *\n * @param player\n */\nplayerUtils.prepareForAds = function (player) {\n var blackPoster = player.addChild('blackPoster');\n var _firstPlay = true;\n var volumeSnapshot;\n\n\n monkeyPatchPlayerApi();\n\n player.on('play', tryToTriggerFirstPlay);\n player.on('vast.reset', resetFirstPlay);//Every time we change the sources we reset the first play.\n player.on('vast.firstPlay', restoreContentVolume);\n player.on('error', hideBlackPoster);//If there is an error in the player we remove the blackposter to show the err msg\n player.on('vast.adStart', hideBlackPoster);\n player.on('vast.adsCancel', hideBlackPoster);\n player.on('vast.adError', hideBlackPoster);\n player.on('vast.adStart', addStyles);\n player.on('vast.adEnd', removeStyles);\n player.on('vast.adsCancel', removeStyles);\n\n /*** Local Functions ***/\n\n /**\n What this function does is ugly and horrible and I should think twice before calling myself a good developer. With that said,\n it is the best solution I could find to mute the video until the 'play' event happens (on mobile devices) and the plugin can decide whether\n to play the ad or not.\n\n We also need this monkeypatch to be able to pause and resume an ad using the player's API\n\n If you have a better solution please do tell me.\n */\n function monkeyPatchPlayerApi() {\n\n /**\n * Monkey patch needed to handle firstPlay and resume of playing ad.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are restoring a VAST ad.\n * @returns {player}\n */\n var origPlay = player.play;\n player.play = function (callOrigPlay) {\n var that = this;\n\n if (isFirstPlay()) {\n firstPlay();\n } else {\n resume(callOrigPlay);\n }\n\n return this;\n\n /*** local functions ***/\n function firstPlay() {\n if (!utilities.isIPhone()) {\n volumeSnapshot = saveVolumeSnapshot();\n player.muted(true);\n }\n\n origPlay.apply(that, arguments);\n }\n\n function resume(callOrigPlay) {\n if (isAdPlaying() && !callOrigPlay) {\n player.vast.adUnit.resumeAd();\n } else {\n origPlay.apply(that, arguments);\n }\n }\n };\n\n\n /**\n * Needed monkey patch to handle pause of playing ad.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are pausing a VAST ad.\n * @returns {player}\n */\n var origPause = player.pause;\n player.pause = function (callOrigPause) {\n if (isAdPlaying() && !callOrigPause) {\n player.vast.adUnit.pauseAd();\n } else {\n origPause.apply(this, arguments);\n }\n return this;\n };\n\n\n /**\n * Needed monkey patch to handle paused state of the player when ads are playing.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are pausing a VAST ad.\n * @returns {player}\n */\n var origPaused = player.paused;\n player.paused = function (callOrigPaused) {\n if (isAdPlaying() && !callOrigPaused) {\n return player.vast.adUnit.isPaused();\n }\n return origPaused.apply(this, arguments);\n };\n }\n\n function isAdPlaying() {\n return player.vast && player.vast.adUnit;\n }\n\n function tryToTriggerFirstPlay() {\n if (isFirstPlay()) {\n _firstPlay = false;\n player.trigger('vast.firstPlay');\n }\n }\n\n function resetFirstPlay() {\n _firstPlay = true;\n blackPoster.show();\n restoreContentVolume();\n }\n\n function isFirstPlay() {\n return _firstPlay;\n }\n\n function saveVolumeSnapshot() {\n return {\n muted: player.muted(),\n volume: player.volume()\n };\n }\n\n function restoreContentVolume() {\n if (volumeSnapshot) {\n player.currentTime(0);\n restoreVolumeSnapshot(volumeSnapshot);\n volumeSnapshot = null;\n }\n }\n\n function restoreVolumeSnapshot(snapshot) {\n if (utilities.isObject(snapshot)) {\n player.volume(snapshot.volume);\n player.muted(snapshot.muted);\n }\n }\n\n function hideBlackPoster() {\n if (!dom.hasClass(blackPoster.el(), 'vjs-hidden')) {\n blackPoster.hide();\n }\n }\n\n function addStyles() {\n dom.addClass(player.el(), 'vjs-ad-playing');\n }\n\n function removeStyles() {\n dom.removeClass(player.el(), 'vjs-ad-playing');\n }\n};\n\n/**\n * Remove the poster attribute from the video element tech, if present. When\n * reusing a video element for multiple videos, the poster image will briefly\n * reappear while the new source loads. Removing the attribute ahead of time\n * prevents the poster from showing up between videos.\n * @param {object} player The videojs player object\n */\nplayerUtils.removeNativePoster = function (player) {\n var tech = player.el().querySelector('.vjs-tech');\n if (tech) {\n tech.removeAttribute('poster');\n }\n};\n\n/**\n * Helper function to listen to many events until one of them gets fired, then we\n * execute the handler and unsubscribe all the event listeners;\n *\n * @param player specific player from where to listen for the events\n * @param events array of events\n * @param handler function to execute once one of the events fires\n */\nplayerUtils.once = function once(player, events, handler) {\n function listener() {\n handler.apply(null, arguments);\n\n events.forEach(function (event) {\n player.off(event, listener);\n });\n }\n\n events.forEach(function (event) {\n player.on(event, listener);\n });\n};\n\n\nmodule.exports = playerUtils;\n},{\"./dom\":39,\"./utilityFunctions\":43}],42:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('./utilityFunctions');\n\n/**\n *\n * IMPORTANT NOTE: This function comes from angularJs and was originally called urlResolve\n * you can take a look at the original code here https://github.com/angular/angular.js/blob/master/src/ng/urlUtils.js\n *\n * Implementation Notes for non-IE browsers\n * ----------------------------------------\n * Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM,\n * results both in the normalizing and parsing of the URL. Normalizing means that a relative\n * URL will be resolved into an absolute URL in the context of the application document.\n * Parsing means that the anchor node's host, hostname, protocol, port, pathname and related\n * properties are all populated to reflect the normalized URL. This approach has wide\n * compatibility - Safari 1+, Mozilla 1+, Opera 7+,e etc. See\n * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n *\n * Implementation Notes for IE\n * ---------------------------\n * IE >= 8 and <= 10 normalizes the URL when assigned to the anchor node similar to the other\n * browsers. However, the parsed components will not be set if the URL assigned did not specify\n * them. (e.g. if you assign a.href = \"foo\", then a.protocol, a.host, etc. will be empty.) We\n * work around that by performing the parsing in a 2nd step by taking a previously normalized\n * URL (e.g. by assigning to a.href) and assigning it a.href again. This correctly populates the\n * properties such as protocol, hostname, port, etc.\n *\n * IE7 does not normalize the URL when assigned to an anchor node. (Apparently, it does, if one\n * uses the inner HTML approach to assign the URL as part of an HTML snippet -\n * http://stackoverflow.com/a/472729) However, setting img[src] does normalize the URL.\n * Unfortunately, setting img[src] to something like \"javascript:foo\" on IE throws an exception.\n * Since the primary usage for normalizing URLs is to sanitize such URLs, we can't use that\n * method and IE < 8 is unsupported.\n *\n * References:\n * http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement\n * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n * http://url.spec.whatwg.org/#urlutils\n * https://github.com/angular/angular.js/pull/2902\n * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/\n *\n * @kind function\n * @param {string} url The URL to be parsed.\n * @description Normalizes and parses a URL.\n * @returns {object} Returns the normalized URL as a dictionary.\n *\n * | member name | Description |\n * |---------------|----------------|\n * | href | A normalized version of the provided URL if it was not an absolute URL |\n * | protocol | The protocol including the trailing colon |\n * | host | The host and port (if the port is non-default) of the normalizedUrl |\n * | search | The search params, minus the question mark |\n * | hash | The hash string, minus the hash symbol\n * | hostname | The hostname\n * | port | The port, without \":\"\n * | pathname | The pathname, beginning with \"/\"\n *\n */\n\nvar urlParsingNode = document.createElement(\"a\");\n/**\n * documentMode is an IE-only property\n * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx\n */\nvar msie = document.documentMode;\n\nfunction urlParts(url) {\n var href = url;\n\n if (msie) {\n // Normalize before parse. Refer Implementation Notes on why this is\n // done in two steps on IE.\n urlParsingNode.setAttribute(\"href\", href);\n href = urlParsingNode.href;\n }\n\n urlParsingNode.setAttribute('href', href);\n\n // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n return {\n href: urlParsingNode.href,\n protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n host: urlParsingNode.host,\n search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n hostname: urlParsingNode.hostname,\n port: utilities.isNotEmptyString(urlParsingNode.port)? urlParsingNode.port: 80,\n pathname: (urlParsingNode.pathname.charAt(0) === '/')\n ? urlParsingNode.pathname\n : '/' + urlParsingNode.pathname\n };\n}\n\n\n/**\n * This function accepts a query string (search part of a url) and returns a dictionary with\n * the different key value pairs\n * @param {string} qs queryString\n */\nfunction queryStringToObj(qs, cond) {\n var pairs, qsObj;\n\n cond = utilities.isFunction(cond)? cond : function() {\n return true;\n };\n\n qs = qs.trim().replace(/^\\?/, '');\n pairs = qs.split('&');\n qsObj = {};\n\n utilities.forEach(pairs, function (pair) {\n var keyValue, key, value;\n if (pair !== '') {\n keyValue = pair.split('=');\n key = keyValue[0];\n value = keyValue[1];\n if(cond(key, value)){\n qsObj[key] = value;\n }\n }\n });\n\n return qsObj;\n}\n\n/**\n * This function accepts an object and serializes it into a query string without the leading '?'\n * @param obj\n * @returns {string}\n */\nfunction objToQueryString(obj) {\n var pairs = [];\n utilities.forEach(obj, function (value, key) {\n pairs.push(key + '=' + value);\n });\n return pairs.join('&');\n}\n\nmodule.exports = {\n urlParts: urlParts,\n queryStringToObj: queryStringToObj,\n objToQueryString: objToQueryString\n};\n\n},{\"./utilityFunctions\":43}],43:[function(require,module,exports){\n/*jshint unused:false */\n\"use strict\";\n\nvar NODE_TYPE_ELEMENT = 1;\nvar SNAKE_CASE_REGEXP = /[A-Z]/g;\nvar EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/i;\n/*jslint maxlen: 500 */\nvar ISO8086_REGEXP = /^([\\+-]?\\d{4}(?!\\d{2}\\b))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))([T\\s]((([01]\\d|2[0-3])((:?)[0-5]\\d)?|24\\:?00)([\\.,]\\d+(?!:))?)?(\\17[0-5]\\d([\\.,]\\d+)?)?([zZ]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)?$/;\n\n\nfunction noop(){ }\n\nfunction isNull(o) {\n return o === null;\n}\n\nfunction isDefined(o){\n return o !== undefined;\n}\n\nfunction isUndefined(o){\n return o === undefined;\n}\n\nfunction isObject(obj) {\n return typeof obj === 'object';\n}\n\nfunction isFunction(str){\n return typeof str === 'function';\n}\n\nfunction isNumber(num){\n return typeof num === 'number';\n}\n\nfunction isWindow(obj) {\n return utilities.isObject(obj) && obj.window === obj;\n}\n\nfunction isArray(array){\n return Object.prototype.toString.call( array ) === '[object Array]';\n}\n\nfunction isArrayLike(obj) {\n if (obj === null || utilities.isWindow(obj) || utilities.isFunction(obj) || utilities.isUndefined(obj)) {\n return false;\n }\n\n var length = obj.length;\n\n if (obj.nodeType === NODE_TYPE_ELEMENT && length) {\n return true;\n }\n\n return utilities.isString(obj) || utilities.isArray(obj) || length === 0 ||\n typeof length === 'number' && length > 0 && (length - 1) in obj;\n}\n\nfunction isString(str){\n return typeof str === 'string';\n}\n\nfunction isEmptyString(str) {\n return utilities.isString(str) && str.length === 0;\n}\n\nfunction isNotEmptyString(str) {\n return utilities.isString(str) && str.length !== 0;\n}\n\nfunction arrayLikeObjToArray(args) {\n return Array.prototype.slice.call(args);\n}\n\nfunction forEach(obj, iterator, context) {\n var key, length;\n if (obj) {\n if (isFunction(obj)) {\n for (key in obj) {\n // Need to check if hasOwnProperty exists,\n // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function\n if (key !== 'prototype' && key !== 'length' && key !== 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n } else if (isArray(obj)) {\n var isPrimitive = typeof obj !== 'object';\n for (key = 0, length = obj.length; key < length; key++) {\n if (isPrimitive || key in obj) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n } else if (obj.forEach && obj.forEach !== forEach) {\n obj.forEach(iterator, context, obj);\n } else {\n for (key in obj) {\n if (obj.hasOwnProperty(key)) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n }\n }\n return obj;\n}\n\nfunction snake_case(name, separator) {\n separator = separator || '_';\n return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {\n return (pos ? separator : '') + letter.toLowerCase();\n });\n}\n\nfunction isValidEmail(email){\n if(!utilities.isString(email)){\n return false;\n }\n\n return EMAIL_REGEXP.test(email.trim());\n}\n\nfunction extend (obj) {\n var arg, i, k;\n for (i = 1; i < arguments.length; i++) {\n arg = arguments[i];\n for (k in arg) {\n if (arg.hasOwnProperty(k)) {\n if(isObject(obj[k]) && !isNull(obj[k]) && isObject(arg[k])){\n obj[k] = extend({}, obj[k], arg[k]);\n }else {\n obj[k] = arg[k];\n }\n }\n }\n }\n return obj;\n}\n\nfunction capitalize(s){\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nfunction decapitalize(s) {\n return s.charAt(0).toLowerCase() + s.slice(1);\n}\n\n/**\n * This method works the same way array.prototype.map works but if the transformer returns undefine, then\n * it won't be added to the transformed Array.\n */\nfunction transformArray(array, transformer) {\n var transformedArray = [];\n\n array.forEach(function(item, index){\n var transformedItem = transformer(item, index);\n if(utilities.isDefined(transformedItem)) {\n transformedArray.push(transformedItem);\n }\n });\n\n return transformedArray;\n}\n\nfunction toFixedDigits(num, digits) {\n var formattedNum = num + '';\n digits = utilities.isNumber(digits) ? digits : 0;\n num = utilities.isNumber(num) ? num : parseInt(num, 10);\n if(utilities.isNumber(num) && !isNaN(num)){\n formattedNum = num + '';\n while(formattedNum.length < digits) {\n formattedNum = '0' + formattedNum;\n }\n return formattedNum;\n }\n return NaN + '';\n}\n\nfunction throttle(callback, delay) {\n var previousCall = new Date().getTime() - (delay + 1);\n return function() {\n var time = new Date().getTime();\n if ((time - previousCall) >= delay) {\n previousCall = time;\n callback.apply(this, arguments);\n }\n };\n}\n\nfunction debounce (callback, wait) {\n var timeoutId;\n\n return function (){\n if(timeoutId) {\n clearTimeout(timeoutId);\n }\n timeoutId = setTimeout(function(){\n callback.apply(this, arguments);\n timeoutId = undefined;\n }, wait);\n };\n}\n\n// a function designed to blow up the stack in a naive way\n// but it is ok for videoJs children components\nfunction treeSearch(root, getChildren, found){\n var children = getChildren(root);\n for (var i = 0; i < children.length; i++){\n if (found(children[i])) {\n return children[i];\n }\n else {\n var el = treeSearch(children[i], getChildren, found);\n if (el){\n return el;\n }\n }\n }\n}\n\nfunction echoFn(val) {\n return function () {\n return val;\n };\n}\n\n//Note: Supported formats come from http://www.w3.org/TR/NOTE-datetime\n// and the iso8601 regex comes from http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/\nfunction isISO8601(value) {\n if(utilities.isNumber(value)){\n value = value + ''; //we make sure that we are working with strings\n }\n\n if(!utilities.isString(value)){\n return false;\n }\n\n return ISO8086_REGEXP.test(value.trim());\n}\n\n/**\n * Checks if the Browser is IE9 and below\n * @returns {boolean}\n */\nfunction isOldIE() {\n var version = utilities.getInternetExplorerVersion(navigator);\n if (version === -1) {\n return false;\n }\n\n return version < 10;\n}\n\n/**\n * Returns the version of Internet Explorer or a -1 (indicating the use of another browser).\n * Source: https://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx\n * @returns {number} the version of Internet Explorer or a -1 (indicating the use of another browser).\n */\nfunction getInternetExplorerVersion(navigator) {\n var rv = -1;\n\n if (navigator.appName == 'Microsoft Internet Explorer') {\n var ua = navigator.userAgent;\n var re = new RegExp(\"MSIE ([0-9]{1,}[\\.0-9]{0,})\");\n var res = re.exec(ua);\n if (res !== null) {\n rv = parseFloat(res[1]);\n }\n }\n\n return rv;\n}\n\n/*** Mobile Utility functions ***/\nfunction isIDevice() {\n return /iP(hone|ad)/.test(utilities._UA);\n}\n\nfunction isMobile() {\n return /iP(hone|ad|od)|Android|Windows Phone/.test(utilities._UA);\n}\n\nfunction isIPhone() {\n return /iP(hone|od)/.test(utilities._UA);\n}\n\nfunction isAndroid() {\n return /Android/.test(utilities._UA);\n}\n\nvar utilities = {\n _UA: navigator.userAgent,\n noop: noop,\n isNull: isNull,\n isDefined: isDefined,\n isUndefined: isUndefined,\n isObject: isObject,\n isFunction: isFunction,\n isNumber: isNumber,\n isWindow: isWindow,\n isArray: isArray,\n isArrayLike: isArrayLike,\n isString: isString,\n isEmptyString: isEmptyString,\n isNotEmptyString: isNotEmptyString,\n arrayLikeObjToArray: arrayLikeObjToArray,\n forEach: forEach,\n snake_case: snake_case,\n isValidEmail: isValidEmail,\n extend: extend,\n capitalize: capitalize,\n decapitalize: decapitalize,\n transformArray: transformArray,\n toFixedDigits: toFixedDigits,\n throttle: throttle,\n debounce: debounce,\n treeSearch: treeSearch,\n echoFn: echoFn,\n isISO8601: isISO8601,\n isOldIE: isOldIE,\n getInternetExplorerVersion: getInternetExplorerVersion,\n isIDevice: isIDevice,\n isMobile: isMobile,\n isIPhone: isIPhone,\n isAndroid: isAndroid\n};\n\nmodule.exports = utilities;\n},{}],44:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('./utilityFunctions');\n\nvar xml = {};\n\nxml.strToXMLDoc = function strToXMLDoc(stringContainingXMLSource){\n //IE 8\n if(typeof window.DOMParser === 'undefined'){\n var xmlDocument = new ActiveXObject('Microsoft.XMLDOM');\n xmlDocument.async = false;\n xmlDocument.loadXML(stringContainingXMLSource);\n return xmlDocument;\n }\n\n return parseString(stringContainingXMLSource);\n\n function parseString(stringContainingXMLSource){\n var parser = new DOMParser();\n var parsedDocument;\n\n //Note: This try catch is to deal with the fact that on IE parser.parseFromString does throw an error but the rest of the browsers don't.\n try {\n parsedDocument = parser.parseFromString(stringContainingXMLSource, \"application/xml\");\n\n if(isParseError(parsedDocument) || utilities.isEmptyString(stringContainingXMLSource)){\n throw new Error();\n }\n }catch(e){\n throw new Error(\"xml.strToXMLDOC: Error parsing the string: '\" + stringContainingXMLSource + \"'\");\n }\n\n return parsedDocument;\n }\n\n function isParseError(parsedDocument) {\n try { // parser and parsererrorNS could be cached on startup for efficiency\n var parser = new DOMParser(),\n erroneousParse = parser.parseFromString('INVALID', 'text/xml'),\n parsererrorNS = erroneousParse.getElementsByTagName(\"parsererror\")[0].namespaceURI;\n\n if (parsererrorNS === 'http://www.w3.org/1999/xhtml') {\n // In PhantomJS the parseerror element doesn't seem to have a special namespace, so we are just guessing here :(\n return parsedDocument.getElementsByTagName(\"parsererror\").length > 0;\n }\n\n return parsedDocument.getElementsByTagNameNS(parsererrorNS, 'parsererror').length > 0;\n } catch (e) {\n //Note on IE parseString throws an error by itself and it will never reach this code. Because it will have failed before\n }\n }\n};\n\nxml.parseText = function parseText (sValue) {\n if (/^\\s*$/.test(sValue)) { return null; }\n if (/^(?:true|false)$/i.test(sValue)) { return sValue.toLowerCase() === \"true\"; }\n if (isFinite(sValue)) { return parseFloat(sValue); }\n if (utilities.isISO8601(sValue)) { return new Date(sValue); }\n return sValue.trim();\n};\n\nxml.JXONTree = function JXONTree (oXMLParent) {\n var parseText = xml.parseText;\n\n //The document object is an especial object that it may miss some functions or attrs depending on the browser.\n //To prevent this problem with create the JXONTree using the root childNode which is a fully fleshed node on all supported\n //browsers.\n if(oXMLParent.documentElement){\n return new xml.JXONTree(oXMLParent.documentElement);\n }\n\n if (oXMLParent.hasChildNodes()) {\n var sCollectedTxt = \"\";\n for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {\n oNode = oXMLParent.childNodes.item(nItem);\n /*jshint bitwise: false*/\n if ((oNode.nodeType - 1 | 1) === 3) { sCollectedTxt += oNode.nodeType === 3 ? oNode.nodeValue.trim() : oNode.nodeValue; }\n else if (oNode.nodeType === 1 && !oNode.prefix) {\n sProp = utilities.decapitalize(oNode.nodeName);\n vContent = new xml.JXONTree(oNode);\n if (this.hasOwnProperty(sProp)) {\n if (this[sProp].constructor !== Array) { this[sProp] = [this[sProp]]; }\n this[sProp].push(vContent);\n } else { this[sProp] = vContent; }\n }\n }\n if (sCollectedTxt) { this.keyValue = parseText(sCollectedTxt); }\n }\n\n //IE8 Stupid fix\n var hasAttr = typeof oXMLParent.hasAttributes === 'undefined'? oXMLParent.attributes.length > 0: oXMLParent.hasAttributes();\n if (hasAttr) {\n var oAttrib;\n for (var nAttrib = 0; nAttrib < oXMLParent.attributes.length; nAttrib++) {\n oAttrib = oXMLParent.attributes.item(nAttrib);\n this[\"@\" + utilities.decapitalize(oAttrib.name)] = parseText(oAttrib.value.trim());\n }\n }\n};\n\nxml.JXONTree.prototype.attr = function(attr) {\n return this['@' + utilities.decapitalize(attr)];\n};\n\nxml.toJXONTree = function toJXONTree(xmlString){\n var xmlDoc = xml.strToXMLDoc(xmlString);\n return new xml.JXONTree(xmlDoc);\n};\n\n/**\n * Helper function to extract the keyvalue of a JXONTree obj\n *\n * @param xmlObj {JXONTree}\n * return the key value or undefined;\n */\nxml.keyValue = function getKeyValue(xmlObj) {\n if(xmlObj){\n return xmlObj.keyValue;\n }\n return undefined;\n};\n\nxml.attr = function getAttrValue(xmlObj, attr) {\n if(xmlObj) {\n return xmlObj['@' + utilities.decapitalize(attr)];\n }\n return undefined;\n};\n\nxml.encode = function encodeXML(str) {\n return str.replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n};\n\nxml.decode = function decodeXML(str) {\n return str.replace(/'/g, \"'\")\n .replace(/"/g, '\"')\n .replace(/>/g, '>')\n .replace(/</g, '<')\n .replace(/&/g, '&');\n};\n\nmodule.exports = xml;\n},{\"./utilityFunctions\":43}],45:[function(require,module,exports){\n'use strict';\n\nrequire('./plugin/components/ads-label_4');\nrequire('./plugin/components/black-poster_4');\n\nvar videoJsVAST = require('./plugin/videojs.vast.vpaid');\n\nvideojs.plugin('vastClient', videoJsVAST);\n\n\n},{\"./plugin/components/ads-label_4\":34,\"./plugin/components/black-poster_4\":36,\"./plugin/videojs.vast.vpaid\":37}]},{},[45])\n\n","'use strict';\n\nlet IVPAIDAdUnit = require('./IVPAIDAdUnit').IVPAIDAdUnit;\nlet ALL_VPAID_METHODS = Object.getOwnPropertyNames(IVPAIDAdUnit.prototype).filter(function (property) {\n return ['constructor'].indexOf(property) === -1;\n});\n\nexport class VPAIDAdUnit extends IVPAIDAdUnit {\n constructor (flash) {\n super();\n this._destroyed = false;\n this._flash = flash;\n }\n\n _destroy() {\n this._destroyed = true;\n ALL_VPAID_METHODS.forEach((methodName) => {\n this._flash.removeCallbackByMethodName(methodName);\n });\n IVPAIDAdUnit.EVENTS.forEach((event) => {\n this._flash.offEvent(event);\n });\n\n this._flash = null;\n }\n\n isDestroyed () {\n return this._destroyed;\n }\n\n on(eventName, callback) {\n this._flash.on(eventName, callback);\n }\n\n off(eventName, callback) {\n this._flash.off(eventName, callback);\n }\n\n //VPAID interface\n handshakeVersion(playerVPAIDVersion = '2.0', callback = undefined) {\n this._flash.callFlashMethod('handshakeVersion', [playerVPAIDVersion], callback);\n }\n initAd (width, height, viewMode, desiredBitrate, creativeData = {AdParameters: ''}, environmentVars = {flashVars: ''}, callback = undefined) {\n //resize element that has the flash object\n this._flash.setSize(width, height);\n creativeData = creativeData || {AdParameters: ''};\n environmentVars = environmentVars || {flashVars: ''};\n\n this._flash.callFlashMethod('initAd', [this._flash.getWidth(), this._flash.getHeight(), viewMode, desiredBitrate, creativeData.AdParameters || '', environmentVars.flashVars || ''], callback);\n }\n resizeAd(width, height, viewMode, callback = undefined) {\n //resize element that has the flash object\n this._flash.setSize(width, height);\n\n //resize ad inside the flash\n this._flash.callFlashMethod('resizeAd', [this._flash.getWidth(), this._flash.getHeight(), viewMode], callback);\n }\n startAd(callback = undefined) {\n this._flash.callFlashMethod('startAd', [], callback);\n }\n stopAd(callback = undefined) {\n this._flash.callFlashMethod('stopAd', [], callback);\n }\n pauseAd(callback = undefined) {\n this._flash.callFlashMethod('pauseAd', [], callback);\n }\n resumeAd(callback = undefined) {\n this._flash.callFlashMethod('resumeAd', [], callback);\n }\n expandAd(callback = undefined) {\n this._flash.callFlashMethod('expandAd', [], callback);\n }\n collapseAd(callback = undefined) {\n this._flash.callFlashMethod('collapseAd', [], callback);\n }\n skipAd(callback = undefined) {\n this._flash.callFlashMethod('skipAd', [], callback);\n }\n\n //properties that will be treat as async methods\n getAdLinear(callback) {\n this._flash.callFlashMethod('getAdLinear', [], callback);\n }\n getAdWidth(callback) {\n this._flash.callFlashMethod('getAdWidth', [], callback);\n }\n getAdHeight(callback) {\n this._flash.callFlashMethod('getAdHeight', [], callback);\n }\n getAdExpanded(callback) {\n this._flash.callFlashMethod('getAdExpanded', [], callback);\n }\n getAdSkippableState(callback) {\n this._flash.callFlashMethod('getAdSkippableState', [], callback);\n }\n getAdRemainingTime(callback) {\n this._flash.callFlashMethod('getAdRemainingTime', [], callback);\n }\n getAdDuration(callback) {\n this._flash.callFlashMethod('getAdDuration', [], callback);\n }\n setAdVolume(volume, callback = undefined) {\n this._flash.callFlashMethod('setAdVolume', [volume], callback);\n }\n getAdVolume(callback) {\n this._flash.callFlashMethod('getAdVolume', [], callback);\n }\n getAdCompanions(callback) {\n this._flash.callFlashMethod('getAdCompanions', [], callback);\n }\n getAdIcons(callback) {\n this._flash.callFlashMethod('getAdIcons', [], callback);\n }\n}\n\n","'use strict';\n\nlet JSFlashBridge = require('./jsFlashBridge').JSFlashBridge;\nlet VPAIDAdUnit = require('./VPAIDAdUnit').VPAIDAdUnit;\n\nlet noop = require('./utils').noop;\nlet callbackTimeout = require('./utils').callbackTimeout;\nlet isPositiveInt = require('./utils').isPositiveInt;\nlet createElementWithID = require('./utils').createElementWithID;\nlet uniqueVPAID = require('./utils').unique('vpaid');\n\nconst ERROR = 'error';\nconst FLASH_VERSION = '10.1.0';\n\nclass VPAIDFLASHClient {\n constructor (vpaidParentEl, callback, swfConfig = {data: 'VPAIDFlash.swf', width: 800, height: 400}, params = { wmode: 'transparent', salign: 'tl', align: 'left', allowScriptAccess: 'always', scale: 'noScale', allowFullScreen: 'true', quality: 'high'}, vpaidOptions = { debug: false, timeout: 10000 }) {\n\n if (!VPAIDFLASHClient.hasExternalDependencies()) {\n return onError('no swfobject in global scope. check: https://github.com/swfobject/swfobject or https://code.google.com/p/swfobject/');\n }\n\n this._vpaidParentEl = vpaidParentEl;\n this._flashID = uniqueVPAID();\n this._destroyed = false;\n callback = callback || noop;\n\n swfConfig.width = isPositiveInt(swfConfig.width, 800);\n swfConfig.height = isPositiveInt(swfConfig.height, 400);\n\n createElementWithID(vpaidParentEl, this._flashID);\n\n params.movie = swfConfig.data;\n params.FlashVars = `flashid=${this._flashID}&handler=${JSFlashBridge.VPAID_FLASH_HANDLER}&debug=${vpaidOptions.debug}&salign=${params.salign}`;\n\n if (!VPAIDFLASHClient.isSupported()) {\n return onError('user don\\'t support flash or doesn\\'t have the minimum required version of flash ' + FLASH_VERSION);\n }\n\n this.el = swfobject.createSWF(swfConfig, params, this._flashID);\n\n if (!this.el) {\n return onError( 'swfobject failed to create object in element' );\n }\n\n var handler = callbackTimeout(vpaidOptions.timeout,\n (err, data) => {\n $loadPendedAdUnit.call(this);\n callback(err, data);\n }, () => {\n callback( 'vpaid flash load timeout ' + vpaidOptions.timeout );\n }\n );\n\n this._flash = new JSFlashBridge(this.el, swfConfig.data, this._flashID, swfConfig.width, swfConfig.height, handler);\n\n function onError(error) {\n setTimeout(() => {\n callback(new Error(error));\n }, 0);\n return this;\n }\n\n }\n\n destroy () {\n this._destroyAdUnit();\n\n if (this._flash) {\n this._flash.destroy();\n this._flash = null;\n }\n this.el = null;\n this._destroyed = true;\n }\n\n isDestroyed () {\n return this._destroyed;\n }\n\n _destroyAdUnit() {\n delete this._loadLater;\n\n if (this._adUnitLoad) {\n this._adUnitLoad = null;\n this._flash.removeCallback(this._adUnitLoad);\n }\n\n if (this._adUnit) {\n this._adUnit._destroy();\n this._adUnit = null;\n }\n }\n\n loadAdUnit(adURL, callback) {\n $throwIfDestroyed.call(this);\n\n if (this._adUnit) {\n this._destroyAdUnit();\n }\n\n if (this._flash.isReady()) {\n this._adUnitLoad = (err, message) => {\n if (!err) {\n this._adUnit = new VPAIDAdUnit(this._flash);\n }\n this._adUnitLoad = null;\n callback(err, this._adUnit);\n };\n\n this._flash.callFlashMethod('loadAdUnit', [adURL], this._adUnitLoad);\n }else {\n this._loadLater = {url: adURL, callback};\n }\n }\n\n unloadAdUnit(callback = undefined) {\n $throwIfDestroyed.call(this);\n\n this._destroyAdUnit();\n this._flash.callFlashMethod('unloadAdUnit', [], callback);\n }\n getFlashID() {\n $throwIfDestroyed.call(this);\n return this._flash.getFlashID();\n }\n getFlashURL() {\n $throwIfDestroyed.call(this);\n return this._flash.getFlashURL();\n }\n}\n\nsetStaticProperty('isSupported', () => {\n return VPAIDFLASHClient.hasExternalDependencies() && swfobject.hasFlashPlayerVersion(FLASH_VERSION);\n});\n\nsetStaticProperty('hasExternalDependencies', () => {\n return !!window.swfobject;\n});\n\nfunction $throwIfDestroyed() {\n if(this._destroyed) {\n throw new error('VPAIDFlashToJS is destroyed!');\n }\n}\n\nfunction $loadPendedAdUnit() {\n if (this._loadLater) {\n this.loadAdUnit(this._loadLater.url, this._loadLater.callback);\n delete this._loadLater;\n }\n}\n\nfunction setStaticProperty(propertyName, value) {\n Object.defineProperty(VPAIDFLASHClient, propertyName, {\n writable: false,\n configurable: false,\n value: value\n });\n}\n\nwindow.VPAIDFLASHClient = VPAIDFLASHClient;\nmodule.exports = VPAIDFLASHClient;\n\n","'use strict';\n\nlet unique = require('./utils').unique;\nlet isPositiveInt = require('./utils').isPositiveInt;\nlet stringEndsWith = require('./utils').stringEndsWith;\nlet SingleValueRegistry = require('./registry').SingleValueRegistry;\nlet MultipleValuesRegistry = require('./registry').MultipleValuesRegistry;\nconst registry = require('./jsFlashBridgeRegistry');\nconst VPAID_FLASH_HANDLER = 'vpaid_video_flash_handler';\nconst ERROR = 'AdError';\n\nexport class JSFlashBridge {\n constructor (el, flashURL, flashID, width, height, loadHandShake) {\n this._el = el;\n this._flashID = flashID;\n this._flashURL = flashURL;\n this._width = width;\n this._height = height;\n this._handlers = new MultipleValuesRegistry();\n this._callbacks = new SingleValueRegistry();\n this._uniqueMethodIdentifier = unique(this._flashID);\n this._ready = false;\n this._handShakeHandler = loadHandShake;\n\n registry.addInstance(this._flashID, this);\n }\n\n on(eventName, callback) {\n this._handlers.add(eventName, callback);\n }\n\n off(eventName, callback) {\n return this._handlers.remove(eventName, callback);\n }\n\n offEvent(eventName) {\n return this._handlers.removeByKey(eventName);\n }\n\n offAll() {\n return this._handlers.removeAll();\n }\n\n callFlashMethod(methodName, args = [], callback = undefined) {\n var callbackID = '';\n // if no callback, some methods the return is void so they don't need callback\n if (callback) {\n callbackID = `${this._uniqueMethodIdentifier()}_${methodName}`;\n this._callbacks.add(callbackID, callback);\n }\n\n\n try {\n //methods are created by ExternalInterface.addCallback in as3 code, if for some reason it failed\n //this code will throw an error\n this._el[methodName]([callbackID].concat(args));\n\n } catch (e) {\n if (callback) {\n $asyncCallback.call(this, callbackID, e);\n } else {\n\n //if there isn't any callback to return error use error event handler\n this._trigger(ERROR, e);\n }\n }\n }\n\n removeCallback(callback) {\n return this._callbacks.removeByValue(callback);\n }\n\n removeCallbackByMethodName(suffix) {\n this._callbacks.filterKeys((key) => {\n return stringEndsWith(key, suffix);\n }).forEach((key) => {\n this._callbacks.remove(key);\n });\n }\n\n removeAllCallbacks() {\n return this._callbacks.removeAll();\n }\n\n _trigger(eventName, event) {\n this._handlers.get(eventName).forEach((callback) => {\n //clickThru has to be sync, if not will be block by the popupblocker\n if (eventName === 'AdClickThru') {\n callback(event);\n } else {\n setTimeout(() => {\n if (this._handlers.get(eventName).length > 0) {\n callback(event);\n }\n }, 0);\n }\n });\n }\n\n _callCallback(methodName, callbackID, err, result) {\n\n let callback = this._callbacks.get(callbackID);\n\n //not all methods callback's are mandatory\n //but if there exist an error, fire the error event\n if (!callback) {\n if (err && callbackID === '') {\n this.trigger(ERROR, err);\n }\n return;\n }\n\n $asyncCallback.call(this, callbackID, err, result);\n\n }\n\n _handShake(err, data) {\n this._ready = true;\n if (this._handShakeHandler) {\n this._handShakeHandler(err, data);\n delete this._handShakeHandler;\n }\n }\n\n //methods like properties specific to this implementation of VPAID\n getSize() {\n return {width: this._width, height: this._height};\n }\n setSize(newWidth, newHeight) {\n this._width = isPositiveInt(newWidth, this._width);\n this._height = isPositiveInt(newHeight, this._height);\n this._el.setAttribute('width', this._width);\n this._el.setAttribute('height', this._height);\n }\n getWidth() {\n return this._width;\n }\n setWidth(newWidth) {\n this.setSize(newWidth, this._height);\n }\n getHeight() {\n return this._height;\n }\n setHeight(newHeight) {\n this.setSize(this._width, newHeight);\n }\n getFlashID() {\n return this._flashID;\n }\n getFlashURL() {\n return this._flashURL;\n }\n isReady() {\n return this._ready;\n }\n destroy() {\n this.offAll();\n this.removeAllCallbacks();\n registry.removeInstanceByID(this._flashID);\n if (this._el.parentElement) {\n this._el.parentElement.removeChild(this._el);\n }\n }\n}\n\nfunction $asyncCallback(callbackID, err, result) {\n setTimeout(() => {\n let callback = this._callbacks.get(callbackID);\n if (callback) {\n this._callbacks.remove(callbackID);\n callback(err, result);\n }\n }, 0);\n}\n\nObject.defineProperty(JSFlashBridge, 'VPAID_FLASH_HANDLER', {\n writable: false,\n configurable: false,\n value: VPAID_FLASH_HANDLER\n});\n\n/**\n * External interface handler\n *\n * @param {string} flashID identifier of the flash who call this\n * @param {string} typeID what type of message is, can be 'event' or 'callback'\n * @param {string} typeName if the typeID is a event the typeName will be the eventName, if is a callback the typeID is the methodName that is related this callback\n * @param {string} callbackID only applies when the typeID is 'callback', identifier of the callback to call\n * @param {object} error error object\n * @param {object} data\n */\nwindow[VPAID_FLASH_HANDLER] = (flashID, typeID, typeName, callbackID, error, data) => {\n let instance = registry.getInstanceByID(flashID);\n if (!instance) return;\n if (typeName === 'handShake') {\n instance._handShake(error, data);\n } else {\n if (typeID !== 'event') {\n instance._callCallback(typeName, callbackID, error, data);\n } else {\n instance._trigger(typeName, data);\n }\n }\n};\n\n","'use strict';\n\nlet SingleValueRegistry = require('./registry').SingleValueRegistry;\nlet instances = new SingleValueRegistry();\n\nconst JSFlashBridgeRegistry = {};\nObject.defineProperty(JSFlashBridgeRegistry, 'addInstance', {\n writable: false,\n configurable: false,\n value: function (id, instance) {\n instances.add(id, instance);\n }\n});\n\nObject.defineProperty(JSFlashBridgeRegistry, 'getInstanceByID', {\n writable: false,\n configurable: false,\n value: function (id) {\n return instances.get(id);\n }\n});\n\nObject.defineProperty(JSFlashBridgeRegistry, 'removeInstanceByID', {\n writable: false,\n configurable: false,\n value: function (id) {\n return instances.remove(id);\n }\n});\n\nmodule.exports = JSFlashBridgeRegistry;\n\n","'use strict';\n\nexport class MultipleValuesRegistry {\n constructor () {\n this._registries = {};\n }\n add (id, value) {\n if (!this._registries[id]) {\n this._registries[id] = [];\n }\n if (this._registries[id].indexOf(value) === -1) {\n this._registries[id].push(value);\n }\n }\n get (id) {\n return this._registries[id] || [];\n }\n filterKeys (handler) {\n return Object.keys(this._registries).filter(handler);\n }\n findByValue (value) {\n var keys = Object.keys(this._registries).filter((key) => {\n return this._registries[key].indexOf(value) !== -1;\n });\n\n return keys;\n }\n remove(key, value) {\n if (!this._registries[key]) { return; }\n\n var index = this._registries[key].indexOf(value);\n\n if (index < 0) { return; }\n return this._registries[key].splice(index, 1);\n }\n removeByKey (id) {\n let old = this._registries[id];\n delete this._registries[id];\n return old;\n }\n removeByValue (value) {\n let keys = this.findByValue(value);\n return keys.map((key) => {\n return this.remove(key, value);\n });\n }\n removeAll() {\n let old = this._registries;\n this._registries = {};\n return old;\n }\n size() {\n return Object.keys(this._registries).length;\n }\n}\n\nexport class SingleValueRegistry {\n constructor () {\n this._registries = {};\n }\n add (id, value) {\n this._registries[id] = value;\n }\n get (id) {\n return this._registries[id];\n }\n filterKeys (handler) {\n return Object.keys(this._registries).filter(handler);\n }\n findByValue (value) {\n var keys = Object.keys(this._registries).filter((key) => {\n return this._registries[key] === value;\n });\n\n return keys;\n }\n remove (id) {\n let old = this._registries[id];\n delete this._registries[id];\n return old;\n }\n removeByValue (value) {\n let keys = this.findByValue(value);\n return keys.map((key) => {\n return this.remove(key);\n });\n }\n removeAll() {\n let old = this._registries;\n this._registries = {};\n return old;\n }\n size() {\n return Object.keys(this._registries).length;\n }\n}\n\n","'use strict';\n\nexport function unique(prefix) {\n let count = -1;\n return f => {\n return `${prefix}_${++count}`;\n };\n}\n\nexport function noop() {\n}\n\n\nexport function callbackTimeout(timer, onSuccess, onTimeout) {\n\n let timeout = setTimeout(() => {\n\n onSuccess = noop;\n onTimeout();\n\n }, timer);\n\n return function () {\n clearTimeout(timeout);\n onSuccess.apply(this, arguments);\n };\n}\n\n\nexport function createElementWithID(parent, id) {\n var nEl = document.createElement('div');\n nEl.id = id;\n parent.innerHTML = '';\n parent.appendChild(nEl);\n return nEl;\n}\n\nexport function isPositiveInt(newVal, oldVal) {\n return !isNaN(parseFloat(newVal)) && isFinite(newVal) && newVal > 0 ? newVal : oldVal;\n}\n\nlet endsWith = (function () {\n if (String.prototype.endsWith) return String.prototype.endsWith;\n return function endsWith (searchString, position) {\n var subjectString = this.toString();\n if (position === undefined || position > subjectString.length) {\n position = subjectString.length;\n }\n position -= searchString.length;\n var lastIndex = subjectString.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n }\n})();\n\nexport function stringEndsWith(string, search) {\n return endsWith.call(string, search);\n}\n\n\n","'use strict';\n\nvar METHODS = [\n 'handshakeVersion',\n 'initAd',\n 'startAd',\n 'stopAd',\n 'skipAd', // VPAID 2.0 new method\n 'resizeAd',\n 'pauseAd',\n 'resumeAd',\n 'expandAd',\n 'collapseAd',\n 'subscribe',\n 'unsubscribe'\n];\n\nvar EVENTS = [\n 'AdLoaded',\n 'AdStarted',\n 'AdStopped',\n 'AdSkipped',\n 'AdSkippableStateChange', // VPAID 2.0 new event\n 'AdSizeChange', // VPAID 2.0 new event\n 'AdLinearChange',\n 'AdDurationChange', // VPAID 2.0 new event\n 'AdExpandedChange',\n 'AdRemainingTimeChange', // [Deprecated in 2.0] but will be still fired for backwards compatibility\n 'AdVolumeChange',\n 'AdImpression',\n 'AdVideoStart',\n 'AdVideoFirstQuartile',\n 'AdVideoMidpoint',\n 'AdVideoThirdQuartile',\n 'AdVideoComplete',\n 'AdClickThru',\n 'AdInteraction', // VPAID 2.0 new event\n 'AdUserAcceptInvitation',\n 'AdUserMinimize',\n 'AdUserClose',\n 'AdPaused',\n 'AdPlaying',\n 'AdLog',\n 'AdError'\n];\n\nvar GETTERS = [\n 'getAdLinear',\n 'getAdWidth', // VPAID 2.0 new getter\n 'getAdHeight', // VPAID 2.0 new getter\n 'getAdExpanded',\n 'getAdSkippableState', // VPAID 2.0 new getter\n 'getAdRemainingTime',\n 'getAdDuration', // VPAID 2.0 new getter\n 'getAdVolume',\n 'getAdCompanions', // VPAID 2.0 new getter\n 'getAdIcons' // VPAID 2.0 new getter\n];\n\nvar SETTERS = [\n 'setAdVolume'\n];\n\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n\n/**\n * IVPAIDAdUnit\n *\n * @class\n *\n * @param {object} creative\n * @param {HTMLElement} el\n * @param {HTMLVideoElement} video\n */\nfunction IVPAIDAdUnit(creative, el, video) {}\n\n\n/**\n * handshakeVersion\n *\n * @param {string} VPAIDVersion\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.handshakeVersion = function (VPAIDVersion, callback) {};\n\n/**\n * initAd\n *\n * @param {number} width\n * @param {number} height\n * @param {string} viewMode can be 'normal', 'thumbnail' or 'fullscreen'\n * @param {number} desiredBitrate indicates the desired bitrate in kbps\n * @param {object} [creativeData] used for additional initialization data\n * @param {object} [environmentVars] used for passing implementation-specific of js version\n * @param {NodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.initAd = function(width, height, viewMode, desiredBitrate, creativeData, environmentVars, callback) {};\n\n/**\n * startAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.startAd = function(callback) {};\n\n/**\n * stopAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.stopAd = function(callback) {};\n\n/**\n * skipAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.skipAd = function(callback) {};\n\n/**\n * resizeAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.resizeAd = function(width, height, viewMode, callback) {};\n\n/**\n * pauseAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.pauseAd = function(callback) {};\n\n/**\n * resumeAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.resumeAd = function(callback) {};\n\n/**\n * expandAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.expandAd = function(callback) {};\n\n/**\n * collapseAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.collapseAd = function(callback) {};\n\n/**\n * subscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n * @param {object} context\n */\nIVPAIDAdUnit.prototype.subscribe = function(event, handler, context) {};\n\n/**\n * startAd\n *\n * @param {string} event\n * @param {function} handler\n */\nIVPAIDAdUnit.prototype.unsubscribe = function(event, handler) {};\n\n\n\n/**\n * getAdLinear\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdLinear = function(callback) {};\n\n/**\n * getAdWidth\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdWidth = function(callback) {};\n\n/**\n * getAdHeight\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdHeight = function(callback) {};\n\n/**\n * getAdExpanded\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdExpanded = function(callback) {};\n\n/**\n * getAdSkippableState\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdSkippableState = function(callback) {};\n\n/**\n * getAdRemainingTime\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdRemainingTime = function(callback) {};\n\n/**\n * getAdDuration\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdDuration = function(callback) {};\n\n/**\n * getAdVolume\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdVolume = function(callback) {};\n\n/**\n * getAdCompanions\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdCompanions = function(callback) {};\n\n/**\n * getAdIcons\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdIcons = function(callback) {};\n\n/**\n * setAdVolume\n *\n * @param {number} volume\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.setAdVolume = function(volume, callback) {};\n\naddStaticToInterface(IVPAIDAdUnit, 'METHODS', METHODS);\naddStaticToInterface(IVPAIDAdUnit, 'GETTERS', GETTERS);\naddStaticToInterface(IVPAIDAdUnit, 'SETTERS', SETTERS);\naddStaticToInterface(IVPAIDAdUnit, 'EVENTS', EVENTS);\n\n\nvar VPAID1_METHODS = METHODS.filter(function(method) {\n return ['skipAd'].indexOf(method) === -1;\n});\n\naddStaticToInterface(IVPAIDAdUnit, 'checkVPAIDInterface', function checkVPAIDInterface (creative) {\n var result = VPAID1_METHODS.every(function(key) {\n return typeof creative[key] === 'function';\n });\n return result;\n});\n\nmodule.exports = IVPAIDAdUnit;\n\nfunction addStaticToInterface(Interface, name, value) {\n Object.defineProperty(Interface, name, {\n writable: false,\n configurable: false,\n value: value\n });\n}\n\n","'use strict';\n\nvar IVPAIDAdUnit = require('./IVPAIDAdUnit');\nvar Subscriber = require('./subscriber');\nvar checkVPAIDInterface = IVPAIDAdUnit.checkVPAIDInterface;\nvar utils = require('./utils');\nvar METHODS = IVPAIDAdUnit.METHODS;\nvar ERROR = 'AdError';\nvar AD_CLICK = 'AdClickThru';\nvar FILTERED_EVENTS = IVPAIDAdUnit.EVENTS.filter(function (event) {\n return event != AD_CLICK;\n});\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n\n/**\n * VPAIDAdUnit\n * @class\n *\n * @param VPAIDCreative\n * @param {HTMLElement} [el] this will be used in initAd environmentVars.slot if defined\n * @param {HTMLVideoElement} [video] this will be used in initAd environmentVars.videoSlot if defined\n */\nfunction VPAIDAdUnit(VPAIDCreative, el, video, iframe) {\n this._isValid = checkVPAIDInterface(VPAIDCreative);\n if (this._isValid) {\n this._creative = VPAIDCreative;\n this._el = el;\n this._videoEl = video;\n this._iframe = iframe;\n this._subscribers = new Subscriber();\n $addEventsSubscribers.call(this);\n }\n}\n\nVPAIDAdUnit.prototype = Object.create(IVPAIDAdUnit.prototype);\n\n/**\n * isValidVPAIDAd will return if the VPAIDCreative passed in constructor is valid or not\n *\n * @return {boolean}\n */\nVPAIDAdUnit.prototype.isValidVPAIDAd = function isValidVPAIDAd() {\n return this._isValid;\n};\n\nIVPAIDAdUnit.METHODS.forEach(function(method) {\n //NOTE: this methods arguments order are implemented differently from the spec\n var ignores = [\n 'subscribe',\n 'unsubscribe',\n 'initAd'\n ];\n\n if (ignores.indexOf(method) !== -1) return;\n\n VPAIDAdUnit.prototype[method] = function () {\n var ariaty = IVPAIDAdUnit.prototype[method].length;\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n var args = Array.prototype.slice.call(arguments);\n var callback = (ariaty === args.length) ? args.pop() : undefined;\n\n setTimeout(function () {\n var result, error = null;\n try {\n result = this._creative[method].apply(this._creative, args);\n } catch(e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n };\n});\n\n\n/**\n * initAd concreate implementation\n *\n * @param {number} width\n * @param {number} height\n * @param {string} viewMode can be 'normal', 'thumbnail' or 'fullscreen'\n * @param {number} desiredBitrate indicates the desired bitrate in kbps\n * @param {object} [creativeData] used for additional initialization data\n * @param {object} [environmentVars] used for passing implementation-specific of js version, if el & video was used in constructor slot & videoSlot will be added to the object\n * @param {NodeStyleCallback} callback\n */\nVPAIDAdUnit.prototype.initAd = function initAd(width, height, viewMode, desiredBitrate, creativeData, environmentVars, callback) {\n creativeData = creativeData || {};\n environmentVars = utils.extend({\n slot: this._el,\n videoSlot: this._videoEl\n }, environmentVars || {});\n\n setTimeout(function () {\n var error;\n try {\n this._creative.initAd(width, height, viewMode, desiredBitrate, creativeData, environmentVars);\n } catch (e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error);\n }.bind(this), 0);\n};\n\n/**\n * subscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n * @param {object} context\n */\nVPAIDAdUnit.prototype.subscribe = function subscribe(event, handler, context) {\n this._subscribers.subscribe(handler, event, context);\n};\n\n\n/**\n * unsubscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n */\nVPAIDAdUnit.prototype.unsubscribe = function unsubscribe(event, handler) {\n this._subscribers.unsubscribe(handler, event);\n};\n\n//alias\nVPAIDAdUnit.prototype.on = VPAIDAdUnit.prototype.subscribe;\nVPAIDAdUnit.prototype.off = VPAIDAdUnit.prototype.unsubscribe;\n\nIVPAIDAdUnit.GETTERS.forEach(function(getter) {\n VPAIDAdUnit.prototype[getter] = function (callback) {\n setTimeout(function () {\n\n var result, error = null;\n try {\n result = this._creative[getter]();\n } catch(e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n };\n});\n\n/**\n * setAdVolume\n *\n * @param volume\n * @param {nodeStyleCallback} callback\n */\nVPAIDAdUnit.prototype.setAdVolume = function setAdVolume(volume, callback) {\n setTimeout(function () {\n\n var result, error = null;\n try {\n this._creative.setAdVolume(volume);\n result = this._creative.getAdVolume();\n } catch(e) {\n error = e;\n }\n\n if (!error) {\n error = utils.validate(result === volume, 'failed to apply volume: ' + volume);\n }\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n};\n\nVPAIDAdUnit.prototype._destroy = function destroy() {\n this.stopAd();\n this._subscribers.unsubscribeAll();\n};\n\nfunction $addEventsSubscribers() {\n // some ads implement\n // so they only handle one subscriber\n // to handle this we create our one\n FILTERED_EVENTS.forEach(function (event) {\n this._creative.subscribe($trigger.bind(this, event), event);\n }.bind(this));\n\n // map the click event to be an object instead of depending of the order of the arguments\n // and to be consistent with the flash\n this._creative.subscribe($clickThruHook.bind(this), AD_CLICK);\n\n // because we are adding the element inside the iframe\n // the user is not able to click in the video\n if (this._videoEl) {\n var documentElement = this._iframe.contentDocument.documentElement;\n var videoEl = this._videoEl;\n documentElement.addEventListener('click', function(e) {\n if (e.target === documentElement) {\n videoEl.click();\n }\n });\n }\n}\n\nfunction $clickThruHook(url, id, playerHandles) {\n this._subscribers.triggerSync(AD_CLICK, {url: url, id: id, playerHandles: playerHandles});\n}\n\nfunction $trigger(event) {\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n this._subscribers.trigger(event, Array.prototype.slice(arguments, 1));\n}\n\nfunction callOrTriggerEvent(callback, subscribers, error, result) {\n if (callback) {\n callback(error, result);\n } else if (error) {\n subscribers.trigger(ERROR, error);\n }\n}\n\nmodule.exports = VPAIDAdUnit;\n\n","'use strict';\n\nvar utils = require('./utils');\nvar unique = utils.unique('vpaidIframe');\nvar VPAIDAdUnit = require('./VPAIDAdUnit');\n\nvar defaultTemplate = '';\ndefaultTemplate += '
';\n\nvar AD_STOPPED = 'AdStopped';\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n/**\n * VPAIDHTML5Client\n * @class\n *\n * @param {HTMLElement} el that will contain the iframe to load adUnit and a el to add to adUnit slot\n * @param {HTMLVideoElement} video default video element to be used by adUnit\n * @param {object} [templateConfig] template: html template to be used instead of the default, extraOptions: to be used when rendering the template\n * @param {object} [vpaidOptions] timeout: when loading adUnit\n */\nfunction VPAIDHTML5Client(el, video, templateConfig, vpaidOptions) {\n templateConfig = templateConfig || {};\n\n this._id = unique();\n this._destroyed = false;\n\n this._frameContainer = utils.createElementInEl(el, 'div');\n this._videoEl = video;\n this._vpaidOptions = vpaidOptions || {timeout: 10000};\n\n this._templateConfig = {\n template: templateConfig.template || defaultTemplate,\n extraOptions: templateConfig.extraOptions || {}\n };\n\n}\n\n/**\n * destroy\n *\n */\nVPAIDHTML5Client.prototype.destroy = function destroy() {\n if (this._destroyed) {\n return;\n }\n this._destroyed = true;\n $unloadPreviousAdUnit.call(this);\n};\n\n/**\n * isDestroyed\n *\n * @return {boolean}\n */\nVPAIDHTML5Client.prototype.isDestroyed = function isDestroyed() {\n return this._destroyed;\n};\n\n/**\n * loadAdUnit\n *\n * @param {string} adURL url of the js of the adUnit\n * @param {nodeStyleCallback} callback\n */\nVPAIDHTML5Client.prototype.loadAdUnit = function loadAdUnit(adURL, callback) {\n $throwIfDestroyed.call(this);\n $unloadPreviousAdUnit.call(this);\n\n var frame = utils.createIframeWithContent(\n this._frameContainer,\n this._templateConfig.template,\n utils.extend({\n iframeURL_JS: adURL,\n iframeID: this.getID()\n }, this._templateConfig.extraOptions)\n );\n this._frame = frame;\n\n this._onLoad = utils.callbackTimeout(\n this._vpaidOptions.timeout,\n onLoad.bind(this),\n onTimeout.bind(this)\n );\n\n window.addEventListener('message', this._onLoad);\n\n function onLoad (e) {\n /*jshint validthis: false */\n //don't clear timeout\n if (e.origin !== window.location.origin) return;\n var result = JSON.parse(e.data);\n\n //don't clear timeout\n if (result.id !== this.getID()) return;\n\n var adUnit, error, createAd;\n if (!this._frame.contentWindow) {\n\n error = 'the iframe is not anymore in the DOM tree';\n\n } else {\n createAd = this._frame.contentWindow.getVPAIDAd;\n error = utils.validate(typeof createAd === 'function', 'the ad didn\\'t return a function to create an ad');\n }\n\n if (!error) {\n var adEl = this._frame.contentWindow.document.querySelector('.ad-element');\n adUnit = new VPAIDAdUnit(createAd(), adEl, this._videoEl, this._frame);\n adUnit.subscribe(AD_STOPPED, $adDestroyed.bind(this));\n error = utils.validate(adUnit.isValidVPAIDAd(), 'the add is not fully complaint with VPAID specification');\n }\n\n this._adUnit = adUnit;\n $destroyLoadListener.call(this);\n callback(error, error ? null : adUnit);\n\n //clear timeout\n return true;\n }\n\n function onTimeout() {\n callback('timeout', null);\n }\n};\n\n/**\n * unloadAdUnit\n *\n */\nVPAIDHTML5Client.prototype.unloadAdUnit = function unloadAdUnit() {\n $unloadPreviousAdUnit.call(this);\n};\n\n/**\n * getID will return the unique id\n *\n * @return {string}\n */\nVPAIDHTML5Client.prototype.getID = function () {\n return this._id;\n};\n\n\n/**\n * $removeEl\n *\n * @param {string} key\n */\nfunction $removeEl(key) {\n var el = this[key];\n if (el) {\n el.remove();\n delete this[key];\n }\n}\n\nfunction $adDestroyed() {\n $removeAdElements.call(this);\n delete this._adUnit;\n}\n\nfunction $unloadPreviousAdUnit() {\n $removeAdElements.call(this);\n $destroyAdUnit.call(this);\n}\n\nfunction $removeAdElements() {\n $removeEl.call(this, '_frame');\n $destroyLoadListener.call(this);\n}\n\n/**\n * $destroyLoadListener\n *\n */\nfunction $destroyLoadListener() {\n if (this._onLoad) {\n window.removeEventListener('message', this._onLoad);\n utils.clearCallbackTimeout(this._onLoad);\n delete this._onLoad;\n }\n}\n\n\nfunction $destroyAdUnit() {\n if (this._adUnit) {\n this._adUnit.stopAd();\n delete this._adUnit;\n }\n}\n\n/**\n * $throwIfDestroyed\n *\n */\nfunction $throwIfDestroyed() {\n if (this._destroyed) {\n throw new Error ('VPAIDHTML5Client already destroyed!');\n }\n}\n\nmodule.exports = VPAIDHTML5Client;\nwindow.VPAIDHTML5Client = VPAIDHTML5Client;\n\n","'use strict';\n\nfunction Subscriber() {\n this._subscribers = {};\n}\n\nSubscriber.prototype.subscribe = function subscribe(handler, eventName, context) {\n this.get(eventName).push({handler: handler, context: context});\n};\n\nSubscriber.prototype.unsubscribe = function unsubscribe(handler, eventName) {\n this._subscribers[eventName] = this.get(eventName).filter(function (subscriber) {\n return handler === subscriber.handler;\n });\n};\n\nSubscriber.prototype.unsubscribeAll = function unsubscribeAll() {\n this._subscribers = {};\n};\n\nSubscriber.prototype.trigger = function(eventName, data) {\n var that = this;\n that.get(eventName).forEach(function (subscriber) {\n setTimeout(function () {\n if (that.get(eventName)) {\n subscriber.handler.call(subscriber.context, data);\n }\n }, 0);\n });\n};\n\nSubscriber.prototype.triggerSync = function(eventName, data) {\n this.get(eventName).forEach(function (subscriber) {\n subscriber.handler.call(subscriber.context, data);\n });\n};\n\nSubscriber.prototype.get = function get(eventName) {\n if (!this._subscribers[eventName]) {\n this._subscribers[eventName] = [];\n }\n return this._subscribers[eventName];\n};\n\nmodule.exports = Subscriber;\n\n","'use strict';\n\n/**\n * noop a empty function\n */\nfunction noop() {}\n\n/**\n * validate if is not validate will return an Error with the message\n *\n * @param {boolean} isValid\n * @param {string} message\n */\nfunction validate(isValid, message) {\n return isValid ? null : new Error(message);\n}\n\nvar timeouts = {};\n/**\n * clearCallbackTimeout\n *\n * @param {function} func handler to remove\n */\nfunction clearCallbackTimeout(func) {\n var timeout = timeouts[func];\n if (timeout) {\n clearTimeout(timeout);\n delete timeouts[func];\n }\n}\n\n/**\n * callbackTimeout if the onSuccess is not called and returns true in the timelimit then onTimeout will be called\n *\n * @param {number} timer\n * @param {function} onSuccess\n * @param {function} onTimeout\n */\nfunction callbackTimeout(timer, onSuccess, onTimeout) {\n var callback, timeout;\n\n timeout = setTimeout(function () {\n onSuccess = noop;\n delete timeout[callback];\n onTimeout();\n }, timer);\n\n callback = function () {\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n if (onSuccess.apply(this, arguments)) {\n clearCallbackTimeout(callback);\n }\n };\n\n timeouts[callback] = timeout;\n\n return callback;\n}\n\n\n/**\n * createElementInEl\n *\n * @param {HTMLElement} parent\n * @param {string} tagName\n * @param {string} id\n */\nfunction createElementInEl(parent, tagName, id) {\n var nEl = document.createElement(tagName);\n if (id) nEl.id = id;\n parent.appendChild(nEl);\n return nEl;\n}\n\n/**\n * createIframeWithContent\n *\n * @param {HTMLElement} parent\n * @param {string} template simple template using {{var}}\n * @param {object} data\n */\nfunction createIframeWithContent(parent, template, data) {\n var iframe = createIframe(parent);\n if (!setIframeContent(iframe, simpleTemplate(template, data))) return;\n return iframe;\n}\n\n/**\n * createIframe\n *\n * @param {HTMLElement} parent\n * @param {string} url\n */\nfunction createIframe(parent, url) {\n var nEl = document.createElement('iframe');\n nEl.src = url || 'about:blank';\n nEl.marginWidth = '0';\n nEl.marginHeight = '0';\n nEl.frameBorder = '0';\n nEl.width = '100%';\n nEl.height = '100%';\n nEl.style.position = 'absolute';\n nEl.style.left = '0';\n nEl.style.top = '0';\n nEl.style.margin = '0px';\n nEl.style.padding = '0px';\n nEl.style.border = 'none';\n nEl.setAttribute('SCROLLING','NO');\n parent.innerHTML = '';\n parent.appendChild(nEl);\n return nEl;\n}\n\n/**\n * simpleTemplate\n *\n * @param {string} template\n * @param {object} data\n */\nfunction simpleTemplate(template, data) {\n Object.keys(data).forEach(function (key) {\n var value = (typeof value === 'object') ? JSON.stringify(data[key]) : data[key];\n template = template.replace(new RegExp('{{' + key + '}}', 'g'), value);\n });\n return template;\n}\n\n/**\n * setIframeContent\n *\n * @param {HTMLIframeElement} iframeEl\n * @param content\n */\nfunction setIframeContent(iframeEl, content) {\n var iframeDoc = iframeEl.contentWindow && iframeEl.contentWindow.document;\n if (!iframeDoc) return false;\n\n iframeDoc.write(content);\n\n return true;\n}\n\n\n/**\n * extend object with keys from another object\n *\n * @param {object} toExtend\n * @param {object} fromSource\n */\nfunction extend(toExtend, fromSource) {\n Object.keys(fromSource).forEach(function(key) {\n toExtend[key] = fromSource[key];\n });\n return toExtend;\n}\n\n\n/**\n * unique will create a unique string everytime is called, sequentially and prefixed\n *\n * @param {string} prefix\n */\nfunction unique(prefix) {\n var count = -1;\n return function () {\n return prefix + '_' + (++count);\n };\n}\n\nmodule.exports = {\n noop: noop,\n validate: validate,\n clearCallbackTimeout: clearCallbackTimeout,\n callbackTimeout: callbackTimeout,\n createElementInEl: createElementInEl,\n createIframeWithContent: createIframeWithContent,\n createIframe: createIframe,\n simpleTemplate: simpleTemplate,\n setIframeContent: setIframeContent,\n extend: extend,\n unique: unique\n};\n\n","'use strict';\n\nvar InLine = require('./InLine');\nvar Wrapper = require('./Wrapper');\n\nfunction Ad(adJTree) {\n if (!(this instanceof Ad)) {\n return new Ad(adJTree);\n }\n this.initialize(adJTree);\n}\n\nAd.prototype.initialize = function(adJTree) {\n this.id = adJTree.attr('id');\n this.sequence = adJTree.attr('sequence');\n\n if(adJTree.inLine) {\n this.inLine = new InLine(adJTree.inLine);\n }\n\n if(adJTree.wrapper){\n this.wrapper = new Wrapper(adJTree.wrapper);\n }\n};\n\nmodule.exports = Ad;","'use strict';\n\nvar TrackingEvent = require('./TrackingEvent');\n\nvar utilities = require('../../utils/utilityFunctions');\n\nvar xml = require('../../utils/xml');\n\n\nfunction Companion(companionJTree) {\n if (!(this instanceof Companion)) {\n return new Companion(companionJTree);\n }\n\n //Required Elements\n this.creativeType = xml.attr(companionJTree.staticResource, 'creativeType');\n this.staticResource = xml.keyValue(companionJTree.staticResource);\n\n // Weird bug when the JXON tree is built it doesn't handle casing properly in this situation...\n var htmlResource = null;\n if (xml.keyValue(companionJTree.HTMLResource)) {\n htmlResource = xml.keyValue(companionJTree.HTMLResource);\n } else if (xml.keyValue(companionJTree.hTMLResource)) {\n htmlResource = xml.keyValue(companionJTree.hTMLResource);\n }\n this.htmlResource = htmlResource;\n\n var iframeResource = null;\n if (xml.keyValue(companionJTree.IFrameResource)) {\n iframeResource = xml.keyValue(companionJTree.IFrameResource);\n } else if (xml.keyValue(companionJTree.iFrameresource)) {\n iframeResource = xml.keyValue(companionJTree.iFrameresource);\n }\n this.iframeResource = iframeResource;\n\n //Optional fields\n this.id = xml.attr(companionJTree, 'id');\n this.width = xml.attr(companionJTree, 'width');\n this.height = xml.attr(companionJTree, 'height');\n this.expandedWidth = xml.attr(companionJTree, 'expandedWidth');\n this.expandedHeight = xml.attr(companionJTree, 'expandedHeight');\n this.scalable = xml.attr(companionJTree, 'scalable');\n this.maintainAspectRatio = xml.attr(companionJTree, 'maintainAspectRatio');\n this.minSuggestedDuration = xml.attr(companionJTree, 'minSuggestedDuration');\n this.apiFramework = xml.attr(companionJTree, 'apiFramework');\n this.companionClickThrough = xml.keyValue(companionJTree.companionClickThrough);\n this.trackingEvents = parseTrackingEvents(companionJTree.trackingEvents && companionJTree.trackingEvents.tracking);\n\n /*** Local functions ***/\n function parseTrackingEvents(trackingEvents) {\n var trackings = [];\n if (utilities.isDefined(trackingEvents)) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingData) {\n trackings.push(new TrackingEvent(trackingData));\n });\n }\n return trackings;\n }\n}\n\nmodule.exports = Companion;","'use strict';\n\nvar Linear = require('./Linear');\nvar Companion = require('./Companion');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction Creative(creativeJTree) {\n if(!(this instanceof Creative)) {\n return new Creative(creativeJTree);\n }\n\n this.id = creativeJTree.attr('id');\n this.sequence = creativeJTree.attr('sequence');\n this.adId = creativeJTree.attr('adId');\n this.apiFramework = creativeJTree.attr('apiFramework');\n\n if(creativeJTree.linear) {\n this.linear = new Linear(creativeJTree.linear);\n }\n\n if (creativeJTree.companionAds) {\n var companions = [];\n var companionAds = creativeJTree.companionAds && creativeJTree.companionAds.companion;\n companionAds = utilities.isArray(companionAds) ? companionAds : [companionAds];\n companionAds.forEach(function (companionData) {\n companions.push(new Companion(companionData));\n });\n\n this.companionAds = companions;\n }\n}\n\nmodule.exports = Creative;","'use strict';\n\nvar vastUtil = require('./vastUtil');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction InLine(inlineJTree) {\n if (!(this instanceof InLine)) {\n return new InLine(inlineJTree);\n }\n\n //Required Fields\n this.adTitle = xml.keyValue(inlineJTree.adTitle);\n this.adSystem = xml.keyValue(inlineJTree.adSystem);\n this.impressions = vastUtil.parseImpressions(inlineJTree.impression);\n this.creatives = vastUtil.parseCreatives(inlineJTree.creatives);\n\n //Optional Fields\n this.description = xml.keyValue(inlineJTree.description);\n this.advertiser = xml.keyValue(inlineJTree.advertiser);\n this.surveys = parseSurveys(inlineJTree.survey);\n this.error = xml.keyValue(inlineJTree.error);\n this.pricing = xml.keyValue(inlineJTree.pricing);\n this.extensions = inlineJTree.extensions;\n\n /*** Local Functions ***/\n function parseSurveys(inlineSurveys) {\n if (inlineSurveys) {\n return utilities.transformArray(utilities.isArray(inlineSurveys) ? inlineSurveys : [inlineSurveys], function (survey) {\n if(utilities.isNotEmptyString(survey.keyValue)){\n return {\n uri: survey.keyValue,\n type: survey.attr('type')\n };\n }\n\n return undefined;\n });\n }\n return [];\n }\n}\n\nmodule.exports = InLine;","'use strict';\n\nvar TrackingEvent = require('./TrackingEvent');\nvar MediaFile = require('./MediaFile');\nvar VideoClicks = require('./VideoClicks');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar parsers = require('./parsers');\n\nvar xml = require('../../utils/xml');\n\n\nfunction Linear(linearJTree) {\n if (!(this instanceof Linear)) {\n return new Linear(linearJTree);\n }\n\n //Required Elements\n this.duration = parsers.duration(xml.keyValue(linearJTree.duration));\n this.mediaFiles = parseMediaFiles(linearJTree.mediaFiles && linearJTree.mediaFiles.mediaFile);\n\n //Optional fields\n this.trackingEvents = parseTrackingEvents(linearJTree.trackingEvents && linearJTree.trackingEvents.tracking, this.duration);\n this.skipoffset = parsers.offset(xml.attr(linearJTree, 'skipoffset'), this.duration);\n\n if (linearJTree.videoClicks) {\n this.videoClicks = new VideoClicks(linearJTree.videoClicks);\n }\n\n if(linearJTree.adParameters) {\n this.adParameters = xml.keyValue(linearJTree.adParameters);\n\n if(xml.attr(linearJTree.adParameters, 'xmlEncoded')){\n this.adParameters = xml.decode(this.adParameters);\n }\n }\n\n /*** Local functions ***/\n function parseTrackingEvents(trackingEvents, duration) {\n var trackings = [];\n if (utilities.isDefined(trackingEvents)) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingData) {\n trackings.push(new TrackingEvent(trackingData, duration));\n });\n }\n return trackings;\n }\n\n function parseMediaFiles(mediaFilesJxonTree) {\n var mediaFiles = [];\n if (utilities.isDefined(mediaFilesJxonTree)) {\n mediaFilesJxonTree = utilities.isArray(mediaFilesJxonTree) ? mediaFilesJxonTree : [mediaFilesJxonTree];\n\n mediaFilesJxonTree.forEach(function (mfData) {\n mediaFiles.push(new MediaFile(mfData));\n });\n }\n return mediaFiles;\n }\n}\n\nmodule.exports = Linear;","'use strict';\n\nvar xml = require('../../utils/xml');\n\nvar attributesList = [\n //Required attributes\n 'delivery',\n 'type',\n 'width',\n 'height',\n //Optional attributes\n 'codec',\n 'id',\n 'bitrate',\n 'minBitrate',\n 'maxBitrate',\n 'scalable',\n 'maintainAspectRatio',\n 'apiFramework'\n];\n\nfunction MediaFile(mediaFileJTree) {\n if (!(this instanceof MediaFile)) {\n return new MediaFile(mediaFileJTree);\n }\n\n //Required attributes\n this.src = xml.keyValue(mediaFileJTree);\n\n for(var x=0; x 0) {\n getAd(waterfallAds.shift(),[], waterfallHandler);\n } else {\n callback(error, adChain);\n }\n } else {\n callback(null, adChain);\n }\n }\n });\n\n /*** Local functions ***/\n function getAdWaterfall(adTagUrl, callback) {\n var requestVastXML = that._requestVASTXml.bind(that, adTagUrl);\n async.waterfall([\n requestVastXML,\n buildVastWaterfall\n ], callback);\n }\n\n function buildVastWaterfall(xmlStr, callback) {\n var vastTree;\n try {\n vastTree = xml.toJXONTree(xmlStr);\n\n if(utilities.isArray(vastTree.ad)) {\n vastTree.ads = vastTree.ad;\n } else if(vastTree.ad){\n vastTree.ads = [vastTree.ad];\n } else {\n vastTree.ads = [];\n }\n callback(validateVASTTree(vastTree), vastTree);\n\n } catch (e) {\n callback(new VASTError(\"on VASTClient.getVASTAd.buildVastWaterfall, error parsing xml\", 100), null);\n }\n }\n\n function validateVASTTree(vastTree) {\n var vastVersion = xml.attr(vastTree, 'version');\n\n if (!vastTree.ad) {\n return new VASTError('on VASTClient.getVASTAd.validateVASTTree, no Ad in VAST tree', 303);\n }\n\n if (vastVersion && (vastVersion != 3 && vastVersion != 2)) {\n return new VASTError('on VASTClient.getVASTAd.validateVASTTree, not supported VAST version \"' + vastVersion + '\"', 102);\n }\n\n return null;\n }\n\n function getAd(adTagUrl, adChain, callback) {\n if (adChain.length >= that.WRAPPER_LIMIT) {\n return callback(new VASTError(\"on VASTClient.getVASTAd.getAd, players wrapper limit reached (the limit is \" + that.WRAPPER_LIMIT + \")\", 302), adChain);\n }\n\n async.waterfall([\n function (next) {\n if (utilities.isString(adTagUrl)) {\n requestVASTAd(adTagUrl, next);\n } else {\n next(null, adTagUrl);\n }\n },\n buildAd\n ], function (error, ad) {\n if (ad) {\n adChain.push(ad);\n }\n\n if (error) {\n return callback(error, adChain);\n }\n\n if (ad.wrapper) {\n return getAd(ad.wrapper.VASTAdTagURI, adChain, callback);\n }\n\n return callback(null, adChain);\n });\n }\n\n function buildAd(adJxonTree, callback) {\n try {\n var ad = new Ad(adJxonTree);\n callback(validateAd(ad), ad);\n } catch (e) {\n callback(new VASTError('on VASTClient.getVASTAd.buildAd, error parsing xml', 100), null);\n }\n }\n\n function validateAd(ad) {\n var wrapper = ad.wrapper;\n var inLine = ad.inLine;\n var errMsgPrefix = 'on VASTClient.getVASTAd.validateAd, ';\n\n if (inLine && wrapper) {\n return new VASTError(errMsgPrefix +\"InLine and Wrapper both found on the same Ad\", 101);\n }\n\n if (!inLine && !wrapper) {\n return new VASTError(errMsgPrefix + \"nor wrapper nor inline elements found on the Ad\", 101);\n }\n\n if (inLine && inLine.creatives.length === 0) {\n return new VASTError(errMsgPrefix + \"missing creative in InLine element\", 101);\n }\n\n if (wrapper && !wrapper.VASTAdTagURI) {\n return new VASTError(errMsgPrefix + \"missing 'VASTAdTagURI' in wrapper\", 101);\n }\n }\n\n function requestVASTAd(adTagUrl, callback) {\n that._requestVASTXml(adTagUrl, function (error, xmlStr) {\n if (error) {\n return callback(error);\n }\n try {\n var vastTree = xml.toJXONTree(xmlStr);\n callback(validateVASTTree(vastTree), vastTree.ad);\n } catch (e) {\n callback(new VASTError(\"on VASTClient.getVASTAd.requestVASTAd, error parsing xml\", 100));\n }\n });\n }\n};\n\nVASTClient.prototype._requestVASTXml = function requestVASTXml(adTagUrl, callback) {\n try {\n if (utilities.isFunction(adTagUrl)) {\n adTagUrl(requestHandler);\n } else {\n http.get(adTagUrl, requestHandler, {\n withCredentials: true\n });\n }\n } catch (e) {\n callback(e);\n }\n\n /*** Local functions ***/\n function requestHandler(error, response, status) {\n if (error) {\n var errMsg = utilities.isDefined(status) ?\n \"on VASTClient.requestVastXML, HTTP request error with status '\" + status + \"'\" :\n \"on VASTClient.requestVastXML, Error getting the the VAST XML with he passed adTagXML fn\";\n return callback(new VASTError(errMsg, 301), null);\n }\n\n callback(null, response);\n }\n};\n\nVASTClient.prototype._buildVASTResponse = function buildVASTResponse(adsChain) {\n var response = new VASTResponse();\n addAdsToResponse(response, adsChain);\n validateResponse(response);\n\n return response;\n\n //*** Local function ****\n function addAdsToResponse(response, ads) {\n ads.forEach(function (ad) {\n response.addAd(ad);\n });\n }\n\n function validateResponse(response) {\n var progressEvents = response.trackingEvents.progress;\n\n if (!response.hasLinear()) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, Received an Ad type that is not supported\", 200);\n }\n\n if (response.duration === undefined) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, Missing duration field in VAST response\", 101);\n }\n\n if (progressEvents) {\n progressEvents.forEach(function (progressEvent) {\n if (!utilities.isNumber(progressEvent.offset)) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, missing or wrong offset attribute on progress tracking event\", 101);\n }\n });\n }\n }\n};\n\nVASTClient.prototype._trackError = function (error, adChain) {\n if (!utilities.isArray(adChain) || adChain.length === 0) { //There is nothing to track\n return;\n }\n\n var errorURLMacros = [];\n adChain.forEach(addErrorUrlMacros);\n vastUtil.track(errorURLMacros, {ERRORCODE: error.code || 900}); //900 <== Undefined error\n\n /*** Local functions ***/\n function addErrorUrlMacros(ad) {\n if (ad.wrapper && ad.wrapper.error) {\n errorURLMacros.push(ad.wrapper.error);\n }\n\n if (ad.inLine && ad.inLine.error) {\n errorURLMacros.push(ad.inLine.error);\n }\n }\n};\n\nmodule.exports = VASTClient;\n","'use strict';\n\nfunction VASTError(message, code) {\n this.message = 'VAST Error: ' + (message || '');\n if (code) {\n this.code = code;\n }\n}\n\nVASTError.prototype = new Error();\nVASTError.prototype.name = \"VAST Error\";\n\nmodule.exports = VASTError;","'use strict';\n\n/**\n * Inner helper class that deals with the logic of the individual steps needed to setup an ad in the player.\n *\n * @param player {object} instance of the player that will play the ad. It assumes that the videojs-contrib-ads plugin\n * has been initialized when you use its utility functions.\n *\n * @constructor\n */\n\nvar VASTResponse = require('./VASTResponse');\nvar VASTError = require('./VASTError');\nvar VASTTracker = require('./VASTTracker');\nvar vastUtil = require('./vastUtil');\n\nvar async = require('../../utils/async');\nvar dom = require('../../utils/dom');\nvar playerUtils = require('../../utils/playerUtils');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VASTIntegrator(player) {\n if (!(this instanceof VASTIntegrator)) {\n return new VASTIntegrator(player);\n }\n\n this.player = player;\n}\n\nVASTIntegrator.prototype.playAd = function playAd(vastResponse, callback) {\n var that = this;\n callback = callback || utilities.noop;\n\n if (!(vastResponse instanceof VASTResponse)) {\n return callback(new VASTError('On VASTIntegrator, missing required VASTResponse'));\n }\n\n async.waterfall([\n function (next) {\n next(null, vastResponse);\n },\n this._selectAdSource.bind(this),\n this._createVASTTracker.bind(this),\n this._addClickThrough.bind(this),\n this._addSkipButton.bind(this),\n this._setupEvents.bind(this),\n this._playSelectedAd.bind(this)\n ], function (error, response) {\n if (error && response) {\n that._trackError(error, response);\n }\n callback(error, response);\n });\n\n this._adUnit = {\n _src: null,\n type: 'VAST',\n pauseAd: function () {\n that.player.pause(true);\n },\n\n resumeAd: function () {\n that.player.play(true);\n },\n\n isPaused: function () {\n return that.player.paused(true);\n },\n\n getSrc: function () {\n return this._src;\n }\n };\n\n return this._adUnit;\n};\n\nVASTIntegrator.prototype._selectAdSource = function selectAdSource(response, callback) {\n var source;\n\n var playerWidth = dom.getDimension(this.player.el()).width;\n response.mediaFiles.sort(function compareTo(a, b) {\n var deltaA = Math.abs(playerWidth - a.width);\n var deltaB = Math.abs(playerWidth - b.width);\n return deltaA - deltaB;\n });\n\n source = this.player.selectSource(response.mediaFiles).source;\n\n if (source) {\n if (this._adUnit) {\n this._adUnit._src = source;\n }\n return callback(null, source, response);\n }\n\n // code 403 <== Couldn't find MediaFile that is supported by this video player\n callback(new VASTError(\"Could not find Ad mediafile supported by this player\", 403), response);\n};\n\nVASTIntegrator.prototype._createVASTTracker = function createVASTTracker(adMediaFile, response, callback) {\n try {\n callback(null, adMediaFile, new VASTTracker(adMediaFile.src, response), response);\n } catch (e) {\n callback(e, response);\n }\n};\n\nVASTIntegrator.prototype._setupEvents = function setupEvents(adMediaFile, tracker, response, callback) {\n var previouslyMuted;\n var player = this.player;\n player.on('fullscreenchange', trackFullscreenChange);\n player.on('vast.adStart', trackImpressions);\n player.on('pause', trackPause);\n player.on('timeupdate', trackProgress);\n player.on('volumechange', trackVolumeChange);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], unbindEvents);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel', 'vast.adSkip'], function(evt){\n if(evt.type === 'vast.adEnd'){\n tracker.trackComplete();\n }\n });\n\n return callback(null, adMediaFile, response);\n\n /*** Local Functions ***/\n function unbindEvents() {\n player.off('fullscreenchange', trackFullscreenChange);\n player.off('vast.adStart', trackImpressions);\n player.off('pause', trackPause);\n player.off('timeupdate', trackProgress);\n player.off('volumechange', trackVolumeChange);\n }\n\n function trackFullscreenChange() {\n if (player.isFullscreen()) {\n tracker.trackFullscreen();\n } else {\n tracker.trackExitFullscreen();\n }\n }\n\n function trackPause() {\n //NOTE: whenever a video ends the video Element triggers a 'pause' event before the 'ended' event.\n // We should not track this pause event because it makes the VAST tracking confusing again we use a\n // Threshold of 2 seconds to prevent false positives on IOS.\n if (Math.abs(player.duration() - player.currentTime()) < 2) {\n return;\n }\n\n tracker.trackPause();\n playerUtils.once(player, ['play', 'vast.adEnd', 'vast.adsCancel'], function (evt) {\n if(evt.type === 'play'){\n tracker.trackResume();\n }\n });\n }\n\n function trackProgress() {\n var currentTimeInMs = player.currentTime() * 1000;\n tracker.trackProgress(currentTimeInMs);\n }\n\n function trackImpressions() {\n tracker.trackImpressions();\n tracker.trackCreativeView();\n }\n\n function trackVolumeChange() {\n var muted = player.muted();\n if (muted) {\n tracker.trackMute();\n } else if (previouslyMuted) {\n tracker.trackUnmute();\n }\n previouslyMuted = muted;\n }\n};\n\nVASTIntegrator.prototype._addSkipButton = function addSkipButton(source, tracker, response, callback) {\n var skipOffsetInSec;\n var that = this;\n\n if (utilities.isNumber(response.skipoffset)) {\n skipOffsetInSec = response.skipoffset / 1000;\n addSkipButtonToPlayer(this.player, skipOffsetInSec);\n }\n callback(null, source, tracker, response);\n\n /*** Local function ***/\n function addSkipButtonToPlayer(player, skipOffset) {\n var skipButton = createSkipButton(player);\n var updateSkipButton = updateSkipButtonState.bind(that, skipButton, skipOffset, player);\n\n player.el().appendChild(skipButton);\n player.on('timeupdate', updateSkipButton);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeSkipButton);\n\n function removeSkipButton() {\n player.off('timeupdate', updateSkipButton);\n dom.remove(skipButton);\n }\n }\n\n function createSkipButton(player) {\n var skipButton = window.document.createElement(\"div\");\n dom.addClass(skipButton, \"vast-skip-button\");\n\n skipButton.onclick = function (e) {\n if (dom.hasClass(skipButton, 'enabled')) {\n tracker.trackSkip();\n player.trigger('vast.adSkip');\n }\n\n //We prevent event propagation to avoid problems with the clickThrough and so on\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n } else {\n return false;\n }\n };\n\n return skipButton;\n }\n\n function updateSkipButtonState(skipButton, skipOffset, player) {\n var timeLeft = Math.ceil(skipOffset - player.currentTime());\n if (timeLeft > 0) {\n skipButton.innerHTML = \"Skip in \" + utilities.toFixedDigits(timeLeft, 2) + \"...\";\n } else {\n if (!dom.hasClass(skipButton, 'enabled')) {\n dom.addClass(skipButton, 'enabled');\n skipButton.innerHTML = \"Skip ad\";\n }\n }\n }\n};\n\nVASTIntegrator.prototype._addClickThrough = function addClickThrough(mediaFile, tracker, response, callback) {\n var player = this.player;\n var blocker = createClickThroughBlocker(player, tracker, response);\n var updateBlocker = updateBlockerURL.bind(this, blocker, response, player);\n\n player.el().insertBefore(blocker, player.controlBar.el());\n player.on('timeupdate', updateBlocker);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeBlocker);\n\n return callback(null, mediaFile, tracker, response);\n\n /*** Local Functions ***/\n\n function createClickThroughBlocker(player, tracker, response) {\n var blocker = window.document.createElement(\"a\");\n var clickThroughMacro = response.clickThrough;\n\n dom.addClass(blocker, 'vast-blocker');\n blocker.href = generateClickThroughURL(clickThroughMacro, player);\n\n if (utilities.isString(clickThroughMacro)) {\n blocker.target = \"_blank\";\n }\n\n blocker.onclick = function (e) {\n if (player.paused()) {\n player.play();\n\n //We prevent event propagation to avoid problems with the player's normal pause mechanism\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n }\n return false;\n }\n\n player.pause();\n tracker.trackClick();\n };\n\n return blocker;\n }\n\n function updateBlockerURL(blocker, response, player) {\n blocker.href = generateClickThroughURL(response.clickThrough, player);\n }\n\n function generateClickThroughURL(clickThroughMacro, player) {\n var variables = {\n ASSETURI: mediaFile.src,\n CONTENTPLAYHEAD: vastUtil.formatProgress(player.currentTime() * 1000)\n };\n\n return clickThroughMacro ? vastUtil.parseURLMacro(clickThroughMacro, variables) : '#';\n }\n\n function removeBlocker() {\n player.off('timeupdate', updateBlocker);\n dom.remove(blocker);\n }\n};\n\nVASTIntegrator.prototype._playSelectedAd = function playSelectedAd(source, response, callback) {\n var player = this.player;\n\n player.preload(\"auto\"); //without preload=auto the durationchange event is never fired\n player.src(source);\n\n playerUtils.once(player, ['durationchange', 'error', 'vast.adsCancel'], function (evt) {\n if (evt.type === 'durationchange') {\n playAd();\n } else if(evt.type === 'error') {\n callback(new VASTError(\"on VASTIntegrator, Player is unable to play the Ad\", 400), response);\n }\n //NOTE: If the ads get canceled we do nothing/\n });\n\n /**** local functions ******/\n function playAd() {\n playerUtils.once(player, ['playing', 'vast.adsCancel'], function (evt) {\n if(evt.type === 'vast.adsCancel'){\n return;\n }\n\n player.trigger('vast.adStart');\n\n playerUtils.once(player, ['ended', 'vast.adsCancel', 'vast.adSkip'], function (evt) {\n if(evt.type === 'ended' || evt.type === 'vast.adSkip'){\n callback(null, response);\n }\n //NOTE: if the ads get cancel we do nothing\n });\n });\n player.play();\n }\n};\n\nVASTIntegrator.prototype._trackError = function trackError(error, response) {\n vastUtil.track(response.errorURLMacros, {ERRORCODE: error.code || 900});\n};\n\nmodule.exports = VASTIntegrator;","'use strict';\n\nvar Ad = require('./Ad');\nvar VideoClicks = require('./VideoClicks');\nvar Linear = require('./Linear');\nvar InLine = require('./InLine');\nvar Wrapper = require('./Wrapper');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nwindow.InLine__A = InLine;\nfunction VASTResponse() {\n if (!(this instanceof VASTResponse)) {\n return new VASTResponse();\n }\n\n this._linearAdded = false;\n this.ads = [];\n this.errorURLMacros = [];\n this.impressions = [];\n this.clickTrackings = [];\n this.customClicks = [];\n this.trackingEvents = {};\n this.mediaFiles = [];\n this.clickThrough = undefined;\n this.adTitle = '';\n this.duration = undefined;\n this.skipoffset = undefined;\n}\n\nVASTResponse.prototype.addAd = function (ad) {\n var inLine, wrapper;\n if (ad instanceof Ad) {\n inLine = ad.inLine;\n wrapper = ad.wrapper;\n\n this.ads.push(ad);\n\n if (inLine) {\n this._addInLine(inLine);\n }\n\n if (wrapper) {\n this._addWrapper(wrapper);\n }\n }\n};\n\nVASTResponse.prototype._addErrorTrackUrl = function (error) {\n var errorURL = error instanceof xml.JXONTree ? xml.keyValue(error) : error;\n if (errorURL) {\n this.errorURLMacros.push(errorURL);\n }\n};\n\nVASTResponse.prototype._addImpressions = function (impressions) {\n utilities.isArray(impressions) && appendToArray(this.impressions, impressions);\n};\n\nVASTResponse.prototype._addClickThrough = function (clickThrough) {\n if (utilities.isNotEmptyString(clickThrough)) {\n this.clickThrough = clickThrough;\n }\n};\n\nVASTResponse.prototype._addClickTrackings = function (clickTrackings) {\n utilities.isArray(clickTrackings) && appendToArray(this.clickTrackings, clickTrackings);\n};\n\nVASTResponse.prototype._addCustomClicks = function (customClicks) {\n utilities.isArray(customClicks) && appendToArray(this.customClicks, customClicks);\n};\n\nVASTResponse.prototype._addTrackingEvents = function (trackingEvents) {\n var eventsMap = this.trackingEvents;\n\n if (trackingEvents) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingEvent) {\n if (!eventsMap[trackingEvent.name]) {\n eventsMap[trackingEvent.name] = [];\n }\n eventsMap[trackingEvent.name].push(trackingEvent);\n });\n }\n};\n\nVASTResponse.prototype._addTitle = function (title) {\n if (utilities.isNotEmptyString(title)) {\n this.adTitle = title;\n }\n};\n\nVASTResponse.prototype._addDuration = function (duration) {\n if (utilities.isNumber(duration)) {\n this.duration = duration;\n }\n};\n\nVASTResponse.prototype._addVideoClicks = function (videoClicks) {\n if (videoClicks instanceof VideoClicks) {\n this._addClickThrough(videoClicks.clickThrough);\n this._addClickTrackings(videoClicks.clickTrackings);\n this._addCustomClicks(videoClicks.customClicks);\n }\n};\n\nVASTResponse.prototype._addMediaFiles = function (mediaFiles) {\n utilities.isArray(mediaFiles) && appendToArray(this.mediaFiles, mediaFiles);\n};\n\nVASTResponse.prototype._addSkipoffset = function (offset) {\n if (offset) {\n this.skipoffset = offset;\n }\n};\n\nVASTResponse.prototype._addAdParameters = function (adParameters) {\n if (adParameters) {\n this.adParameters = adParameters;\n }\n};\n\nVASTResponse.prototype._addLinear = function (linear) {\n if (linear instanceof Linear) {\n this._addDuration(linear.duration);\n this._addTrackingEvents(linear.trackingEvents);\n this._addVideoClicks(linear.videoClicks);\n this._addMediaFiles(linear.mediaFiles);\n this._addSkipoffset(linear.skipoffset);\n this._addAdParameters(linear.adParameters);\n this._linearAdded = true;\n }\n};\n\nVASTResponse.prototype._addInLine = function (inLine) {\n var that = this;\n\n if (inLine instanceof InLine) {\n this._addTitle(inLine.adTitle);\n this._addErrorTrackUrl(inLine.error);\n this._addImpressions(inLine.impressions);\n\n inLine.creatives.forEach(function (creative) {\n if (creative.linear) {\n that._addLinear(creative.linear);\n }\n });\n }\n};\n\nVASTResponse.prototype._addWrapper = function (wrapper) {\n var that = this;\n\n if (wrapper instanceof Wrapper) {\n this._addErrorTrackUrl(wrapper.error);\n this._addImpressions(wrapper.impressions);\n\n wrapper.creatives.forEach(function (creative) {\n var linear = creative.linear;\n if (linear) {\n that._addVideoClicks(linear.videoClicks);\n that.clickThrough = undefined;//We ensure that no clickThrough has been added\n that._addTrackingEvents(linear.trackingEvents);\n }\n });\n }\n};\n\nVASTResponse.prototype.hasLinear = function(){\n return this._linearAdded;\n};\n\nfunction appendToArray(array, items) {\n items.forEach(function (item) {\n array.push(item);\n });\n}\n\nmodule.exports = VASTResponse;\n\n","'use strict';\n\nvar VASTError = require('./VASTError');\nvar VASTResponse = require('./VASTResponse');\nvar vastUtil = require('./vastUtil');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VASTTracker(assetURI, vastResponse) {\n if (!(this instanceof VASTTracker)) {\n return new VASTTracker(assetURI, vastResponse);\n }\n\n this.sanityCheck(assetURI, vastResponse);\n this.initialize(assetURI, vastResponse);\n\n}\n\nVASTTracker.prototype.initialize = function(assetURI, vastResponse) {\n this.response = vastResponse;\n this.assetURI = assetURI;\n this.progress = 0;\n this.quartiles = {\n firstQuartile: {tracked: false, time: Math.round(25 * vastResponse.duration) / 100},\n midpoint: {tracked: false, time: Math.round(50 * vastResponse.duration) / 100},\n thirdQuartile: {tracked: false, time: Math.round(75 * vastResponse.duration) / 100}\n };\n};\n\nVASTTracker.prototype.sanityCheck = function(assetURI, vastResponse) {\n if (!utilities.isString(assetURI) || utilities.isEmptyString(assetURI)) {\n throw new VASTError('on VASTTracker constructor, missing required the URI of the ad asset being played');\n }\n\n if (!(vastResponse instanceof VASTResponse)) {\n throw new VASTError('on VASTTracker constructor, missing required VAST response');\n }\n};\n\nVASTTracker.prototype.trackURLs = function trackURLs(urls, variables) {\n if (utilities.isArray(urls) && urls.length > 0) {\n variables = utilities.extend({\n ASSETURI: this.assetURI,\n CONTENTPLAYHEAD: vastUtil.formatProgress(this.progress)\n }, variables || {});\n\n vastUtil.track(urls, variables);\n }\n};\n\nVASTTracker.prototype.trackEvent = function trackEvent(eventName, trackOnce) {\n this.trackURLs(getEventUris(this.response.trackingEvents[eventName]));\n if (trackOnce) {\n this.response.trackingEvents[eventName] = undefined;\n }\n\n /*** Local function ***/\n function getEventUris(trackingEvents) {\n var uris;\n\n if (trackingEvents) {\n uris = [];\n trackingEvents.forEach(function (event) {\n uris.push(event.uri);\n });\n }\n return uris;\n }\n};\n\nVASTTracker.prototype.trackProgress = function trackProgress(newProgressInMs) {\n var that = this;\n var events = [];\n var ONCE = true;\n var ALWAYS = false;\n var trackingEvents = this.response.trackingEvents;\n\n if (utilities.isNumber(newProgressInMs)) {\n addTrackEvent('start', ONCE, newProgressInMs > 0);\n addTrackEvent('rewind', ALWAYS, hasRewound(this.progress, newProgressInMs));\n addQuartileEvents(newProgressInMs);\n trackProgressEvents(newProgressInMs);\n trackEvents();\n this.progress = newProgressInMs;\n }\n\n /*** Local function ***/\n function hasRewound(currentProgress, newProgress) {\n var REWIND_THRESHOLD = 3000; //IOS video clock is very unreliable and we need a 3 seconds threshold to ensure that there was a rewind an that it was on purpose.\n return currentProgress > newProgressInMs && Math.abs(newProgress - currentProgress) > REWIND_THRESHOLD;\n }\n\n function addTrackEvent(eventName, trackOnce, canBeAdded) {\n if (trackingEvents[eventName] && canBeAdded) {\n events.push({\n name: eventName,\n trackOnce: !!trackOnce\n });\n }\n }\n\n function addQuartileEvents(progress) {\n var quartiles = that.quartiles;\n var firstQuartile = that.quartiles.firstQuartile;\n var midpoint = that.quartiles.midpoint;\n var thirdQuartile = that.quartiles.thirdQuartile;\n\n if (!firstQuartile.tracked) {\n trackQuartile('firstQuartile', progress);\n } else if (!midpoint.tracked) {\n trackQuartile('midpoint', progress);\n } else if (!thirdQuartile.tracked){\n trackQuartile('thirdQuartile', progress);\n }\n\n /*** Local function ***/\n function trackQuartile(quartileName, progress){\n var quartile = quartiles[quartileName];\n if(canBeTracked(quartile, progress)){\n quartile.tracked = true;\n addTrackEvent(quartileName, ONCE, true);\n }\n }\n }\n\n function canBeTracked(quartile, progress) {\n var quartileTime = quartile.time;\n //We only fire the quartile event if the progress is bigger than the quartile time by 5 seconds at most.\n return progress >= quartileTime && progress <= (quartileTime + 5000);\n }\n\n function trackProgressEvents(progress) {\n if (!utilities.isArray(trackingEvents.progress)) {\n return; //Nothing to track\n }\n\n var pendingProgressEvts = [];\n\n trackingEvents.progress.forEach(function (evt) {\n if (evt.offset <= progress) {\n that.trackURLs([evt.uri]);\n } else {\n pendingProgressEvts.push(evt);\n }\n });\n trackingEvents.progress = pendingProgressEvts;\n }\n\n function trackEvents() {\n events.forEach(function (event) {\n that.trackEvent(event.name, event.trackOnce);\n });\n }\n};\n\n[\n 'rewind',\n 'fullscreen',\n 'exitFullscreen',\n 'pause',\n 'resume',\n 'mute',\n 'unmute',\n 'acceptInvitation',\n 'acceptInvitationLinear',\n 'collapse',\n 'expand'\n].forEach(function (eventName) {\n VASTTracker.prototype['track' + utilities.capitalize(eventName)] = function () {\n this.trackEvent(eventName);\n };\n });\n\n[\n 'start',\n 'skip',\n 'close',\n 'closeLinear'\n].forEach(function (eventName) {\n VASTTracker.prototype['track' + utilities.capitalize(eventName)] = function () {\n this.trackEvent(eventName, true);\n };\n });\n\n[\n 'firstQuartile',\n 'midpoint',\n 'thirdQuartile'\n].forEach(function (quartile) {\n VASTTracker.prototype['track' + utilities.capitalize(quartile)] = function () {\n this.quartiles[quartile].tracked = true;\n this.trackEvent(quartile, true);\n };\n });\n\nVASTTracker.prototype.trackComplete = function () {\n if(this.quartiles.thirdQuartile.tracked){\n this.trackEvent('complete', true);\n }\n};\n\nVASTTracker.prototype.trackErrorWithCode = function trackErrorWithCode(errorcode) {\n if (utilities.isNumber(errorcode)) {\n this.trackURLs(this.response.errorURLMacros, {ERRORCODE: errorcode});\n }\n};\n\nVASTTracker.prototype.trackImpressions = function trackImpressions() {\n this.trackURLs(this.response.impressions);\n};\n\nVASTTracker.prototype.trackCreativeView = function trackCreativeView() {\n this.trackEvent('creativeView');\n};\n\nVASTTracker.prototype.trackClick = function trackClick() {\n this.trackURLs(this.response.clickTrackings);\n};\n\nmodule.exports = VASTTracker;\n","'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction VideoClicks(videoClickJTree) {\n if (!(this instanceof VideoClicks)) {\n return new VideoClicks(videoClickJTree);\n }\n\n this.clickThrough = xml.keyValue(videoClickJTree.clickThrough);\n this.clickTrackings = parseClickTrackings(videoClickJTree.clickTracking);\n this.customClicks = parseClickTrackings(videoClickJTree.customClick);\n\n /*** Local functions ***/\n function parseClickTrackings(trackingData) {\n var clickTrackings = [];\n if (trackingData) {\n trackingData = utilities.isArray(trackingData) ? trackingData : [trackingData];\n trackingData.forEach(function (clickTrackingData) {\n clickTrackings.push(xml.keyValue(clickTrackingData));\n });\n }\n return clickTrackings;\n }\n}\n\nmodule.exports = VideoClicks;","'use strict';\n\nvar vastUtil = require('./vastUtil');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction Wrapper(wrapperJTree) {\n if(!(this instanceof Wrapper)) {\n return new Wrapper(wrapperJTree);\n }\n\n //Required elements\n this.adSystem = xml.keyValue(wrapperJTree.adSystem);\n this.impressions = vastUtil.parseImpressions(wrapperJTree.impression);\n this.VASTAdTagURI = xml.keyValue(wrapperJTree.vASTAdTagURI);\n\n //Optional elements\n this.creatives = vastUtil.parseCreatives(wrapperJTree.creatives);\n this.error = xml.keyValue(wrapperJTree.error);\n this.extensions = wrapperJTree.extensions;\n\n //Optional attrs\n this.followAdditionalWrappers = utilities.isDefined(xml.attr(wrapperJTree, 'followAdditionalWrappers'))? xml.attr(wrapperJTree, 'followAdditionalWrappers'): true;\n this.allowMultipleAds = xml.attr(wrapperJTree, 'allowMultipleAds');\n this.fallbackOnNoAd = xml.attr(wrapperJTree, 'fallbackOnNoAd');\n}\n\nmodule.exports = Wrapper;","'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\n\nvar durationRegex = /(\\d\\d):(\\d\\d):(\\d\\d)(\\.(\\d\\d\\d))?/;\n\nvar parsers = {\n\n duration: function parseDuration(durationStr) {\n\n var match, durationInMs;\n\n if (utilities.isString(durationStr)) {\n match = durationStr.match(durationRegex);\n if (match) {\n durationInMs = parseHoursToMs(match[1]) + parseMinToMs(match[2]) + parseSecToMs(match[3]) + parseInt(match[5] || 0);\n }\n }\n\n return isNaN(durationInMs) ? null : durationInMs;\n\n /*** local functions ***/\n function parseHoursToMs(hourStr) {\n return parseInt(hourStr, 10) * 60 * 60 * 1000;\n }\n\n function parseMinToMs(minStr) {\n return parseInt(minStr, 10) * 60 * 1000;\n }\n\n function parseSecToMs(secStr) {\n return parseInt(secStr, 10) * 1000;\n }\n },\n\n offset: function parseOffset(offset, duration) {\n if(isPercentage(offset)){\n return calculatePercentage(offset, duration);\n }\n return parsers.duration(offset);\n\n /*** Local function ***/\n function isPercentage(offset) {\n var percentageRegex = /^\\d+(\\.\\d+)?%$/g;\n return percentageRegex.test(offset);\n }\n\n function calculatePercentage(percentStr, duration) {\n if(duration) {\n return calcPercent(duration, parseFloat(percentStr.replace('%', '')));\n }\n return null;\n }\n\n function calcPercent(quantity, percent){\n return quantity * percent / 100;\n }\n }\n\n};\n\n\nmodule.exports = parsers;","'use strict';\n\nvar Creative = require('./Creative');\nvar utilities = require('../../utils/utilityFunctions');\n\nvar vastUtil = {\n\n track: function track(URLMacros, variables) {\n var sources = vastUtil.parseURLMacros(URLMacros, variables);\n var trackImgs = [];\n sources.forEach(function (src) {\n var img = new Image();\n img.src = src;\n trackImgs.push(img);\n });\n return trackImgs;\n },\n\n parseURLMacros: function parseMacros(URLMacros, variables) {\n var parsedURLs = [];\n\n variables = variables || {};\n\n if (!(variables[\"CACHEBUSTING\"])) {\n variables[\"CACHEBUSTING\"] = Math.round(Math.random() * 1.0e+10);\n }\n\n URLMacros.forEach(function (URLMacro) {\n parsedURLs.push(vastUtil._parseURLMacro(URLMacro, variables));\n });\n\n return parsedURLs;\n },\n\n parseURLMacro: function parseMacro(URLMacro, variables) {\n variables = variables || {};\n\n if (!(variables[\"CACHEBUSTING\"])) {\n variables[\"CACHEBUSTING\"] = Math.round(Math.random() * 1.0e+10);\n }\n\n return vastUtil._parseURLMacro(URLMacro, variables);\n },\n\n _parseURLMacro: function parseMacro(URLMacro, variables) {\n variables = variables || {};\n\n utilities.forEach(variables, function (value, key) {\n URLMacro = URLMacro.replace(new RegExp(\"\\\\[\" + key + \"\\\\\\]\", 'gm'), value);\n });\n\n return URLMacro;\n },\n\n parseDuration: function parseDuration(durationStr) {\n var durationRegex = /(\\d\\d):(\\d\\d):(\\d\\d)(\\.(\\d\\d\\d))?/;\n var match, durationInMs;\n\n if (utilities.isString(durationStr)) {\n match = durationStr.match(durationRegex);\n if (match) {\n durationInMs = parseHoursToMs(match[1]) + parseMinToMs(match[2]) + parseSecToMs(match[3]) + parseInt(match[5] || 0);\n }\n }\n\n return isNaN(durationInMs) ? null : durationInMs;\n\n /*** local functions ***/\n function parseHoursToMs(hourStr) {\n return parseInt(hourStr, 10) * 60 * 60 * 1000;\n }\n\n function parseMinToMs(minStr) {\n return parseInt(minStr, 10) * 60 * 1000;\n }\n\n function parseSecToMs(secStr) {\n return parseInt(secStr, 10) * 1000;\n }\n },\n\n parseImpressions: function parseImpressions(impressions) {\n if (impressions) {\n impressions = utilities.isArray(impressions) ? impressions : [impressions];\n return utilities.transformArray(impressions, function (impression) {\n if (utilities.isNotEmptyString(impression.keyValue)) {\n return impression.keyValue;\n }\n return undefined;\n });\n }\n return [];\n },\n\n parseCreatives: function parseCreatives(creativesJTree) {\n var creatives = [];\n var creativesData;\n if (utilities.isDefined(creativesJTree) && utilities.isDefined(creativesJTree.creative)) {\n creativesData = utilities.isArray(creativesJTree.creative) ? creativesJTree.creative : [creativesJTree.creative];\n creativesData.forEach(function (creative) {\n creatives.push(new Creative(creative));\n });\n }\n return creatives;\n },\n\n //We assume that the progress is going to arrive in milliseconds\n formatProgress: function formatProgress(progress) {\n var hours, minutes, seconds, milliseconds;\n hours = progress / (60 * 60 * 1000);\n hours = Math.floor(hours);\n minutes = (progress / (60 * 1000)) % 60;\n minutes = Math.floor(minutes);\n seconds = (progress / 1000) % 60;\n seconds = Math.floor(seconds);\n milliseconds = progress % 1000;\n return utilities.toFixedDigits(hours, 2) + ':' + utilities.toFixedDigits(minutes, 2) + ':' + utilities.toFixedDigits(seconds, 2) + '.' + utilities.toFixedDigits(milliseconds, 3);\n },\n\n parseOffset: function parseOffset(offset, duration) {\n if(isPercentage(offset)){\n return calculatePercentage(offset, duration);\n }\n return vastUtil.parseDuration(offset);\n\n /*** Local function ***/\n function isPercentage(offset) {\n var percentageRegex = /^\\d+(\\.\\d+)?%$/g;\n return percentageRegex.test(offset);\n }\n\n function calculatePercentage(percentStr, duration) {\n if(duration) {\n return calcPercent(duration, parseFloat(percentStr.replace('%', '')));\n }\n return null;\n }\n\n function calcPercent(quantity, percent){\n return quantity * percent / 100;\n }\n },\n\n isVPAID: function isVPAIDMediaFile(mediaFile) {\n return !!mediaFile && mediaFile.apiFramework === 'VPAID';\n }\n};\n\n\nmodule.exports = vastUtil;","'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VPAIDAdUnitWrapper(vpaidAdUnit, opts) {\n if (!(this instanceof VPAIDAdUnitWrapper)) {\n return new VPAIDAdUnitWrapper(vpaidAdUnit, opts);\n }\n sanityCheck(vpaidAdUnit, opts);\n\n this.options = utilities.extend({}, opts);\n\n this._adUnit = vpaidAdUnit;\n\n /*** Local Functions ***/\n function sanityCheck(adUnit, opts) {\n if (!adUnit || !VPAIDAdUnitWrapper.checkVPAIDInterface(adUnit)) {\n throw new VASTError('on VPAIDAdUnitWrapper, the passed VPAID adUnit does not fully implement the VPAID interface');\n }\n\n if (!utilities.isObject(opts)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper, expected options hash but got '\" + opts + \"'\");\n }\n\n if (!(\"responseTimeout\" in opts) || !utilities.isNumber(opts.responseTimeout) ){\n throw new VASTError(\"on VPAIDAdUnitWrapper, expected responseTimeout in options\");\n }\n }\n}\n\nVPAIDAdUnitWrapper.checkVPAIDInterface = function checkVPAIDInterface(VPAIDAdUnit) {\n //NOTE: skipAd is not part of the method list because it only appears in VPAID 2.0 and we support VPAID 1.0\n var VPAIDInterfaceMethods = [\n 'handshakeVersion', 'initAd', 'startAd', 'stopAd', 'resizeAd', 'pauseAd', 'expandAd', 'collapseAd'\n ];\n\n for (var i = 0, len = VPAIDInterfaceMethods.length; i < len; i++) {\n if (!VPAIDAdUnit || !utilities.isFunction(VPAIDAdUnit[VPAIDInterfaceMethods[i]])) {\n return false;\n }\n }\n\n\n return canSubscribeToEvents(VPAIDAdUnit) && canUnsubscribeFromEvents(VPAIDAdUnit);\n\n /*** Local Functions ***/\n\n function canSubscribeToEvents(adUnit) {\n return utilities.isFunction(adUnit.subscribe) || utilities.isFunction(adUnit.addEventListener) || utilities.isFunction(adUnit.on);\n }\n\n function canUnsubscribeFromEvents(adUnit) {\n return utilities.isFunction(adUnit.unsubscribe) || utilities.isFunction(adUnit.removeEventListener) || utilities.isFunction(adUnit.off);\n\n }\n};\n\nVPAIDAdUnitWrapper.prototype.adUnitAsyncCall = function () {\n var args = utilities.arrayLikeObjToArray(arguments);\n var method = args.shift();\n var cb = args.pop();\n var timeoutId;\n\n sanityCheck(method, cb, this._adUnit);\n args.push(wrapCallback());\n\n this._adUnit[method].apply(this._adUnit, args);\n timeoutId = setTimeout(function () {\n timeoutId = null;\n cb(new VASTError(\"on VPAIDAdUnitWrapper, timeout while waiting for a response on call '\" + method + \"'\"));\n cb = utilities.noop;\n }, this.options.responseTimeout);\n\n /*** Local functions ***/\n function sanityCheck(method, cb, adUnit) {\n if (!utilities.isString(method) || !utilities.isFunction(adUnit[method])) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.adUnitAsyncCall, invalid method name\");\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.adUnitAsyncCall, missing callback\");\n }\n }\n\n function wrapCallback() {\n return function () {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n cb.apply(this, arguments);\n };\n }\n};\n\nVPAIDAdUnitWrapper.prototype.on = function (evtName, handler) {\n var addEventListener = this._adUnit.addEventListener || this._adUnit.subscribe || this._adUnit.on;\n addEventListener.call(this._adUnit, evtName, handler);\n};\n\nVPAIDAdUnitWrapper.prototype.off = function (evtName, handler) {\n var removeEventListener = this._adUnit.removeEventListener || this._adUnit.unsubscribe || this._adUnit.off;\n removeEventListener.call(this._adUnit, evtName, handler);\n};\n\nVPAIDAdUnitWrapper.prototype.waitForEvent = function (evtName, cb, context) {\n var timeoutId;\n sanityCheck(evtName, cb);\n context = context || null;\n\n this.on(evtName, responseListener);\n\n timeoutId = setTimeout(function () {\n cb(new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, timeout while waiting for event '\" + evtName + \"'\"));\n timeoutId = null;\n cb = utilities.noop;\n }, this.options.responseTimeout);\n\n /*** Local functions ***/\n function sanityCheck(evtName, cb) {\n if (!utilities.isString(evtName)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, missing evt name\");\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, missing callback\");\n }\n }\n\n function responseListener() {\n var args = utilities.arrayLikeObjToArray(arguments);\n\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n\n args.unshift(null);\n cb.apply(context, args);\n }\n};\n\n// VPAID METHODS\nVPAIDAdUnitWrapper.prototype.handshakeVersion = function (version, cb) {\n this.adUnitAsyncCall('handshakeVersion', version, cb);\n};\n\n/* jshint maxparams:6 */\nVPAIDAdUnitWrapper.prototype.initAd = function (width, height, viewMode, desiredBitrate, adUnitData, cb) {\n this.waitForEvent('AdLoaded', cb);\n this._adUnit.initAd(width, height, viewMode, desiredBitrate, adUnitData);\n};\n\nVPAIDAdUnitWrapper.prototype.resizeAd = function (width, height, viewMode, cb) {\n // NOTE: AdSizeChange event is only supported on VPAID 2.0 so for the moment we are not going to use it\n // and will assume that everything is fine after the async call\n this.adUnitAsyncCall('resizeAd', width, height, viewMode, cb);\n};\n\nVPAIDAdUnitWrapper.prototype.startAd = function (cb) {\n this.waitForEvent('AdStarted', cb);\n this._adUnit.startAd();\n};\n\nVPAIDAdUnitWrapper.prototype.stopAd = function (cb) {\n this.waitForEvent('AdStopped', cb);\n this._adUnit.stopAd();\n};\n\nVPAIDAdUnitWrapper.prototype.pauseAd = function (cb) {\n this.waitForEvent('AdPaused', cb);\n this._adUnit.pauseAd();\n};\n\nVPAIDAdUnitWrapper.prototype.resumeAd = function (cb) {\n this.waitForEvent('AdPlaying', cb);\n this._adUnit.resumeAd();\n};\n\nVPAIDAdUnitWrapper.prototype.expandAd = function (cb) {\n this.waitForEvent('AdExpandedChange', cb);\n this._adUnit.expandAd();\n};\n\nVPAIDAdUnitWrapper.prototype.collapseAd = function (cb) {\n this.waitForEvent('AdExpandedChange', cb);\n this._adUnit.collapseAd();\n};\n\nVPAIDAdUnitWrapper.prototype.skipAd = function (cb) {\n this.waitForEvent('AdSkipped', cb);\n this._adUnit.skipAd();\n};\n\n//VPAID property getters\n[\n 'adLinear',\n 'adWidth',\n 'adHeight',\n 'adExpanded',\n 'adSkippableState',\n 'adRemainingTime',\n 'adDuration',\n 'adVolume',\n 'adCompanions',\n 'adIcons'\n].forEach(function (property) {\n var getterName = 'get' + utilities.capitalize(property);\n\n VPAIDAdUnitWrapper.prototype[getterName] = function (cb) {\n this.adUnitAsyncCall(getterName, cb);\n };\n});\n\n//VPAID property setters\nVPAIDAdUnitWrapper.prototype.setAdVolume = function(volume, cb){\n this.adUnitAsyncCall('setAdVolume',volume, cb);\n};\n\nmodule.exports = VPAIDAdUnitWrapper;\n","'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar VPAIDFLASHClient = require('VPAIDFLASHClient/js/VPAIDFLASHClient');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar dom = require('../../utils/dom');\n\nfunction VPAIDFlashTech(mediaFile, settings) {\n if (!(this instanceof VPAIDFlashTech)) {\n return new VPAIDFlashTech(mediaFile);\n }\n sanityCheck(mediaFile);\n this.name = 'vpaid-flash';\n this.mediaFile = mediaFile;\n this.containerEl = null;\n this.vpaidFlashClient = null;\n this.settings = settings;\n\n /*** local functions ***/\n function sanityCheck(mediaFile) {\n if (!mediaFile || !utilities.isString(mediaFile.src)) {\n throw new VASTError('on VPAIDFlashTech, invalid MediaFile');\n }\n }\n}\n\nVPAIDFlashTech.VPAIDFLASHClient = VPAIDFLASHClient;\n\nVPAIDFlashTech.supports = function (type) {\n return type === 'application/x-shockwave-flash' && VPAIDFlashTech.VPAIDFLASHClient.isSupported();\n};\n\nVPAIDFlashTech.prototype.loadAdUnit = function loadFlashCreative(containerEl, objectEl, callback) {\n var that = this;\n var flashClientOpts = this.settings && this.settings.vpaidFlashLoaderPath ? {data: this.settings.vpaidFlashLoaderPath} : undefined;\n sanityCheck(containerEl, callback);\n\n this.containerEl = containerEl;\n this.vpaidFlashClient = new VPAIDFlashTech.VPAIDFLASHClient(containerEl, function (error) {\n if (error) {\n return callback(error);\n }\n\n that.vpaidFlashClient.loadAdUnit(that.mediaFile.src, callback);\n }, flashClientOpts);\n\n /*** Local Functions ***/\n function sanityCheck(container, cb) {\n\n if (!dom.isDomElement(container)) {\n throw new VASTError('on VPAIDFlashTech.loadAdUnit, invalid dom container element');\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError('on VPAIDFlashTech.loadAdUnit, missing valid callback');\n }\n }\n};\n\nVPAIDFlashTech.prototype.unloadAdUnit = function () {\n if (this.vpaidFlashClient) {\n try{\n this.vpaidFlashClient.destroy();\n } catch(e){\n if(console && utilities.isFunction(console.log)){\n console.log('VAST ERROR: trying to unload the VPAID adunit');\n }\n }\n this.vpaidFlashClient = null;\n }\n\n if (this.containerEl) {\n dom.remove(this.containerEl);\n this.containerEl = null;\n }\n};\n\nmodule.exports = VPAIDFlashTech;","'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar VPAIDHTML5Client = require('VPAIDHTML5Client/js/VPAIDHTML5Client');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar dom = require('../../utils/dom');\n\nfunction VPAIDHTML5Tech(mediaFile) {\n\n if(!(this instanceof VPAIDHTML5Tech)) {\n return new VPAIDHTML5Tech(mediaFile);\n }\n\n sanityCheck(mediaFile);\n\n this.name = 'vpaid-html5';\n this.containerEl = null;\n this.videoEl = null;\n this.vpaidHTMLClient = null;\n\n this.mediaFile = mediaFile;\n\n function sanityCheck(mediaFile) {\n if (!mediaFile || !utilities.isString(mediaFile.src)) {\n throw new VASTError(VPAIDHTML5Tech.INVALID_MEDIA_FILE);\n }\n }\n}\n\nVPAIDHTML5Tech.VPAIDHTML5Client = VPAIDHTML5Client;\n\nVPAIDHTML5Tech.supports = function (type) {\n return !utilities.isOldIE() && type === 'application/javascript';\n};\n\nVPAIDHTML5Tech.prototype.loadAdUnit = function loadAdUnit(containerEl, videoEl, callback) {\n sanityCheck(containerEl, videoEl, callback);\n\n this.containerEl = containerEl;\n this.videoEl = videoEl;\n this.vpaidHTMLClient = new VPAIDHTML5Tech.VPAIDHTML5Client(containerEl, videoEl, {});\n this.vpaidHTMLClient.loadAdUnit(this.mediaFile.src, callback);\n\n function sanityCheck(container, video, cb) {\n if (!dom.isDomElement(container)) {\n throw new VASTError(VPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL);\n }\n\n if (!dom.isDomElement(video) || video.tagName.toLowerCase() !== 'video') {\n throw new VASTError(VPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL);\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(VPAIDHTML5Tech.MISSING_CALLBACK);\n }\n }\n};\n\nVPAIDHTML5Tech.prototype.unloadAdUnit = function unloadAdUnit() {\n if (this.vpaidHTMLClient) {\n try {\n this.vpaidHTMLClient.destroy();\n } catch(e) {\n if (console && utilities.isFunction(console.log)) {\n console.log('VAST ERROR: trying to unload the VPAID adunit');\n }\n }\n\n this.vpaidHTMLClient = null;\n }\n\n if (this.containerEl) {\n dom.remove(this.containerEl);\n this.containerEl = null;\n }\n};\n\nvar PREFIX = 'on VPAIDHTML5Tech';\nVPAIDHTML5Tech.INVALID_MEDIA_FILE = PREFIX + ', invalid MediaFile';\nVPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL = PREFIX + ', invalid container HtmlElement';\nVPAIDHTML5Tech.INVALID_DOM_VIDEO_EL = PREFIX + ', invalid HTMLVideoElement';\nVPAIDHTML5Tech.MISSING_CALLBACK = PREFIX + ', missing valid callback';\n\nmodule.exports = VPAIDHTML5Tech;","'use strict';\n\nvar VASTError = require('../vast/VASTError');\nvar VASTResponse = require('../vast/VASTResponse');\nvar VASTTracker = require('../vast/VASTTracker');\nvar vastUtil = require('../vast/vastUtil');\n\nvar VPAIDAdUnitWrapper = require('./VPAIDAdUnitWrapper');\nvar VPAIDHTML5Tech = require('./VPAIDHTML5Tech');\nvar VPAIDFlashTech = require('./VPAIDFlashTech');\n\nvar async = require('../../utils/async');\nvar dom = require('../../utils/dom');\nvar playerUtils = require('../../utils/playerUtils');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VPAIDIntegrator(player, settings) {\n if (!(this instanceof VPAIDIntegrator)) {\n return new VPAIDIntegrator(player);\n }\n\n this.VIEW_MODE = {\n NORMAL: 'normal',\n FULLSCREEN: \"fullscreen\",\n THUMBNAIL: \"thumbnail\"\n };\n this.player = player;\n this.containerEl = createVPAIDContainerEl(player);\n this.options = {\n responseTimeout: 5000,\n VPAID_VERSION: '2.0'\n };\n this.settings = settings;\n\n /*** Local functions ***/\n\n function createVPAIDContainerEl() {\n var containerEl = document.createElement('div');\n dom.addClass(containerEl, 'VPAID-container');\n player.el().insertBefore(containerEl, player.controlBar.el());\n return containerEl;\n\n }\n}\n\n//List of supported VPAID technologies\nVPAIDIntegrator.techs = [\n VPAIDFlashTech,\n VPAIDHTML5Tech\n];\n\nVPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) {\n var that = this;\n var tech;\n var player = this.player;\n\n callback = callback || utilities.noop;\n if (!(vastResponse instanceof VASTResponse)) {\n return callback(new VASTError('on VASTIntegrator.playAd, missing required VASTResponse'));\n }\n\n tech = this._findSupportedTech(vastResponse, this.settings);\n dom.addClass(player.el(), 'vjs-vpaid-ad');\n\n player.on('vast.adsCancel', triggerVpaidAdEnd);\n player.one('vpaid.adEnd', function(){\n player.off('vast.adsCancel', triggerVpaidAdEnd);\n removeAdUnit();\n });\n\n if (tech) {\n async.waterfall([\n function (next) {\n next(null, tech, vastResponse);\n },\n this._loadAdUnit.bind(this),\n this._playAdUnit.bind(this),\n this._finishPlaying.bind(this)\n\n ], function (error, adUnit, vastResponse) {\n if (error) {\n that._trackError(vastResponse);\n }\n player.trigger('vpaid.adEnd');\n callback(error, vastResponse);\n });\n\n this._adUnit = {\n _paused: true,\n type: 'VPAID',\n pauseAd: function() {\n player.trigger('vpaid.pauseAd');\n player.pause(true);//we make sure that the video content gets stopped.\n },\n resumeAd: function() {\n player.trigger('vpaid.resumeAd');\n },\n isPaused: function() {\n return this._paused;\n },\n getSrc: function() {\n return tech.mediaFile;\n }\n };\n\n return this._adUnit;\n }\n\n callback(new VASTError('on VPAIDIntegrator.playAd, could not find a supported mediaFile'));\n\n return null;\n /*** Local functions ***/\n function triggerVpaidAdEnd(){\n player.trigger('vpaid.adEnd');\n }\n\n function removeAdUnit() {\n if (tech) {\n tech.unloadAdUnit();\n }\n dom.removeClass(player.el(), 'vjs-vpaid-ad');\n }\n};\n\nVPAIDIntegrator.prototype._findSupportedTech = function (vastResponse, settings) {\n if (!(vastResponse instanceof VASTResponse)) {\n return null;\n }\n\n var vpaidMediaFiles = vastResponse.mediaFiles.filter(vastUtil.isVPAID);\n var i, len, mediaFile, VPAIDTech;\n\n for (i = 0, len = vpaidMediaFiles.length; i < len; i += 1) {\n mediaFile = vpaidMediaFiles[i];\n VPAIDTech = findSupportedTech(mediaFile);\n if (VPAIDTech) {\n return new VPAIDTech(mediaFile, settings);\n }\n }\n return null;\n\n /*** Local functions ***/\n function findSupportedTech(mediafile) {\n var type = mediafile.type;\n var i, len, VPAIDTech;\n for (i = 0, len = VPAIDIntegrator.techs.length; i < len; i += 1) {\n VPAIDTech = VPAIDIntegrator.techs[i];\n if (VPAIDTech.supports(type)) {\n return VPAIDTech;\n }\n }\n return null;\n }\n};\n\nVPAIDIntegrator.prototype._createVPAIDAdUnitWrapper = function(adUnit, src, responseTimeout) {\n return new VPAIDAdUnitWrapper(adUnit, {src: src, responseTimeout: responseTimeout});\n};\n\nVPAIDIntegrator.prototype._loadAdUnit = function (tech, vastResponse, next) {\n var that = this;\n var player = this.player;\n var vjsTechEl = player.el().querySelector('.vjs-tech');\n var responseTimeout = this.settings.responseTimeout || this.options.responseTimeout;\n tech.loadAdUnit(this.containerEl, vjsTechEl, function (error, adUnit) {\n if (error) {\n return next(error, adUnit, vastResponse);\n }\n\n try {\n var WrappedAdUnit = that._createVPAIDAdUnitWrapper(adUnit, tech.mediaFile.src, responseTimeout);\n var techClass = 'vjs-' + tech.name + '-ad';\n dom.addClass(player.el(), techClass);\n player.one('vpaid.adEnd', function() {\n dom.removeClass(player.el(),techClass);\n });\n next(null, WrappedAdUnit, vastResponse);\n } catch (e) {\n next(e, adUnit, vastResponse);\n }\n });\n};\n\nVPAIDIntegrator.prototype._playAdUnit = function (adUnit, vastResponse, callback) {\n async.waterfall([\n function (next) {\n next(null, adUnit, vastResponse);\n },\n this._handshake.bind(this),\n this._initAd.bind(this),\n this._setupEvents.bind(this),\n this._addSkipButton.bind(this),\n this._linkPlayerControls.bind(this),\n this._startAd.bind(this)\n ], callback);\n};\n\nVPAIDIntegrator.prototype._handshake = function handshake(adUnit, vastResponse, next) {\n adUnit.handshakeVersion(this.options.VPAID_VERSION, function (error, version) {\n if (error) {\n return next(error, adUnit, vastResponse);\n }\n\n if (version && isSupportedVersion(version)) {\n return next(null, adUnit, vastResponse);\n }\n\n return next(new VASTError('on VPAIDIntegrator._handshake, unsupported version \"' + version + '\"'), adUnit, vastResponse);\n });\n\n function isSupportedVersion(version) {\n var majorNum = major(version);\n return majorNum >= 1 && majorNum <= 2;\n }\n\n function major(version) {\n var parts = version.split('.');\n return parseInt(parts[0], 10);\n }\n};\n\nVPAIDIntegrator.prototype._initAd = function (adUnit, vastResponse, next) {\n var tech = this.player.el().querySelector('.vjs-tech');\n var dimension = dom.getDimension(tech);\n adUnit.initAd(dimension.width, dimension.height, this.VIEW_MODE.NORMAL, -1, {AdParameters: vastResponse.adParameters || ''}, function (error) {\n next(error, adUnit, vastResponse);\n });\n};\n\nVPAIDIntegrator.prototype._createVASTTracker = function(adUnitSrc, vastResponse) {\n return new VASTTracker(adUnitSrc, vastResponse);\n};\n\nVPAIDIntegrator.prototype._setupEvents = function (adUnit, vastResponse, next) {\n var adUnitSrc = adUnit.options.src;\n var tracker = this._createVASTTracker(adUnitSrc, vastResponse);\n var player = this.player;\n var that = this;\n\n adUnit.on('AdSkipped', function () {\n player.trigger('vpaid.AdSkipped');\n tracker.trackSkip();\n });\n\n adUnit.on('AdImpression', function () {\n player.trigger('vpaid.AdImpression');\n tracker.trackImpressions();\n });\n\n adUnit.on('AdStarted', function () {\n player.trigger('vpaid.AdStarted');\n tracker.trackCreativeView();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdVideoStart', function () {\n player.trigger('vpaid.AdVideoStart');\n tracker.trackStart();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdPlaying', function () {\n player.trigger('vpaid.AdPlaying');\n tracker.trackResume();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdPaused', function () {\n player.trigger('vpaid.AdPaused');\n tracker.trackPause();\n notifyPauseToPlayer();\n });\n\n function notifyPlayToPlayer(){\n if(that._adUnit && that._adUnit.isPaused()){\n that._adUnit._paused = false;\n }\n player.trigger('play');\n\n }\n\n function notifyPauseToPlayer() {\n if(that._adUnit){\n that._adUnit._paused = true;\n }\n player.trigger('pause');\n }\n\n adUnit.on('AdVideoFirstQuartile', function () {\n player.trigger('vpaid.AdVideoFirstQuartile');\n tracker.trackFirstQuartile();\n });\n\n adUnit.on('AdVideoMidpoint', function () {\n player.trigger('vpaid.AdVideoMidpoint');\n tracker.trackMidpoint();\n });\n\n adUnit.on('AdVideoThirdQuartile', function () {\n player.trigger('vpaid.AdVideoThirdQuartile');\n tracker.trackThirdQuartile();\n });\n\n adUnit.on('AdVideoComplete', function () {\n player.trigger('vpaid.AdVideoComplete');\n tracker.trackComplete();\n });\n\n adUnit.on('AdClickThru', function (data) {\n player.trigger('vpaid.AdClickThru');\n var url = data.url;\n var playerHandles = data.playerHandles;\n var clickThruUrl = utilities.isNotEmptyString(url) ? url : generateClickThroughURL(vastResponse.clickThrough);\n\n tracker.trackClick();\n if (playerHandles && clickThruUrl) {\n window.open(clickThruUrl, '_blank');\n }\n\n function generateClickThroughURL(clickThroughMacro) {\n var variables = {\n ASSETURI: adUnit.options.src,\n CONTENTPLAYHEAD: 0 //In VPAID there is no method to know the current time from the adUnit\n };\n\n return clickThroughMacro ? vastUtil.parseURLMacro(clickThroughMacro, variables) : null;\n }\n });\n\n adUnit.on('AdUserAcceptInvitation', function () {\n player.trigger('vpaid.AdUserAcceptInvitation');\n tracker.trackAcceptInvitation();\n tracker.trackAcceptInvitationLinear();\n });\n\n adUnit.on('AdUserClose', function () {\n player.trigger('vpaid.AdUserClose');\n tracker.trackClose();\n tracker.trackCloseLinear();\n });\n\n adUnit.on('AdUserMinimize', function () {\n player.trigger('vpaid.AdUserMinimize');\n tracker.trackCollapse();\n });\n\n adUnit.on('AdError', function () {\n player.trigger('vpaid.AdError');\n //NOTE: we track errors code 901, as noted in VAST 3.0\n tracker.trackErrorWithCode(901);\n });\n\n adUnit.on('AdVolumeChange', function () {\n player.trigger('vpaid.AdVolumeChange');\n var lastVolume = player.volume();\n adUnit.getAdVolume(function (error, currentVolume) {\n if (currentVolume === 0 && lastVolume > 0) {\n tracker.trackMute();\n }\n\n if (currentVolume > 0 && lastVolume === 0) {\n tracker.trackUnmute();\n }\n\n player.volume(currentVolume);\n });\n });\n\n var updateViewSize = resizeAd.bind(this, player, adUnit, this.VIEW_MODE);\n var updateViewSizeThrottled = utilities.throttle(updateViewSize, 100);\n var autoResize = this.settings.autoResize;\n\n if (autoResize) {\n dom.addEventListener(window, 'resize', updateViewSizeThrottled);\n dom.addEventListener(window, 'orientationchange', updateViewSizeThrottled);\n }\n\n player.on('vast.resize', updateViewSize);\n player.on('vpaid.pauseAd', pauseAdUnit);\n player.on('vpaid.resumeAd', resumeAdUnit);\n\n player.one('vpaid.adEnd', function () {\n player.off('vast.resize', updateViewSize);\n player.off('vpaid.pauseAd', pauseAdUnit);\n player.off('vpaid.resumeAd', resumeAdUnit);\n\n if (autoResize) {\n dom.removeEventListener(window, 'resize', updateViewSizeThrottled);\n dom.removeEventListener(window, 'orientationchange', updateViewSizeThrottled);\n }\n });\n\n next(null, adUnit, vastResponse);\n\n /*** Local Functions ***/\n function pauseAdUnit() {\n adUnit.pauseAd(utilities.noop);\n }\n\n function resumeAdUnit() {\n adUnit.resumeAd(utilities.noop);\n }\n};\n\nVPAIDIntegrator.prototype._addSkipButton = function (adUnit, vastResponse, next) {\n var skipButton;\n var player = this.player;\n\n adUnit.on('AdSkippableStateChange', updateSkipButtonState);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeSkipButton);\n\n next(null, adUnit, vastResponse);\n\n /*** Local function ***/\n function updateSkipButtonState() {\n player.trigger('vpaid.AdSkippableStateChange');\n adUnit.getAdSkippableState(function (error, isSkippable) {\n if (isSkippable) {\n if (!skipButton) {\n addSkipButton(player);\n }\n } else {\n removeSkipButton(player);\n }\n });\n }\n\n function addSkipButton(player) {\n skipButton = createSkipButton(player);\n player.el().appendChild(skipButton);\n }\n\n function removeSkipButton() {\n dom.remove(skipButton);\n skipButton = null;\n }\n\n function createSkipButton() {\n var skipButton = window.document.createElement(\"div\");\n dom.addClass(skipButton, \"vast-skip-button\");\n dom.addClass(skipButton, \"enabled\");\n skipButton.innerHTML = \"Skip ad\";\n\n skipButton.onclick = function (e) {\n adUnit.skipAd(utilities.noop);//We skip the adUnit\n\n //We prevent event propagation to avoid problems with the clickThrough and so on\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n } else {\n return false;\n }\n };\n\n return skipButton;\n }\n};\n\nVPAIDIntegrator.prototype._linkPlayerControls = function (adUnit, vastResponse, next) {\n var that = this;\n linkVolumeControl(this.player, adUnit);\n linkFullScreenControl(this.player, adUnit, this.VIEW_MODE);\n\n next(null, adUnit, vastResponse);\n\n /*** Local functions ***/\n function linkVolumeControl(player, adUnit) {\n player.on('volumechange', updateAdUnitVolume);\n adUnit.on('AdVolumeChange', updatePlayerVolume);\n\n player.one('vpaid.adEnd', function () {\n player.off('volumechange', updateAdUnitVolume);\n });\n\n\n /*** local functions ***/\n function updateAdUnitVolume() {\n var vol = player.muted() ? 0 : player.volume();\n adUnit.setAdVolume(vol, logError);\n }\n\n function updatePlayerVolume() {\n player.trigger('vpaid.AdVolumeChange');\n adUnit.getAdVolume(function (error, vol) {\n if (error) {\n logError(error);\n } else {\n player.volume(vol);\n }\n });\n }\n }\n\n function linkFullScreenControl(player, adUnit, VIEW_MODE) {\n var updateViewSize = resizeAd.bind(that, player, adUnit, VIEW_MODE);\n\n player.on('fullscreenchange', updateViewSize);\n\n player.one('vpaid.adEnd', function () {\n player.off('fullscreenchange', updateViewSize);\n });\n }\n};\n\nVPAIDIntegrator.prototype._startAd = function (adUnit, vastResponse, next) {\n var player = this.player;\n\n adUnit.startAd(function (error) {\n if (!error) {\n player.trigger('vast.adStart');\n }\n next(error, adUnit, vastResponse);\n });\n};\n\nVPAIDIntegrator.prototype._finishPlaying = function (adUnit, vastResponse, next) {\n var player = this.player;\n adUnit.on('AdStopped', function () {\n player.trigger('vpaid.AdStopped');\n finishPlayingAd(null);\n });\n\n adUnit.on('AdError', function (error) {\n var errMsg = error? error.message : 'on VPAIDIntegrator, error while waiting for the adUnit to finish playing';\n finishPlayingAd(new VASTError(errMsg));\n });\n\n /*** local functions ***/\n function finishPlayingAd(error) {\n next(error, adUnit, vastResponse);\n }\n};\n\nVPAIDIntegrator.prototype._trackError = function trackError(response) {\n vastUtil.track(response.errorURLMacros, {ERRORCODE: 901});\n};\n\nfunction resizeAd(player, adUnit, VIEW_MODE) {\n var tech = player.el().querySelector('.vjs-tech');\n var dimension = dom.getDimension(tech);\n var MODE = player.isFullscreen() ? VIEW_MODE.FULLSCREEN : VIEW_MODE.NORMAL;\n adUnit.resizeAd(dimension.width, dimension.height, MODE, logError);\n}\n\nfunction logError(error) {\n if (error && console && console.log) {\n console.log('ERROR: ' + error.message, error);\n }\n}\n\nmodule.exports = VPAIDIntegrator;","'use strict';\n\nvar dom = require('../../utils/dom');\n\nvar element = document.createElement('div');\nelement.className = 'vjs-ads-label vjs-control vjs-label-hidden';\nelement.innerHTML = 'Advertisement';\n\nvar AdsLabelFactory = function(baseComponent) {\n return {\n /** @constructor */\n init: function init(player, options) {\n options.el = element;\n baseComponent.call(this, player, options);\n\n // We asynchronously reposition the ads label element\n setTimeout(function () {\n var currentTimeComp = player.controlBar &&( player.controlBar.getChild(\"timerControls\") || player.controlBar.getChild(\"currentTimeDisplay\") );\n if(currentTimeComp) {\n player.controlBar.el().insertBefore(element, currentTimeComp.el());\n }\n dom.removeClass(element, 'vjs-label-hidden');\n }, 0);\n },\n\n el: function getElement() {\n return element;\n }\n };\n};\n\nmodule.exports = AdsLabelFactory;","'use strict';\n\nvar baseVideoJsComponent = videojs.Component;\n\nvar AdsLabel = require('./ads-label')(baseVideoJsComponent);\n\nvideojs.AdsLabel = videojs.Component.extend(AdsLabel);\n","'use strict';\n\n/**\n * The component that shows a black screen until the ads plugin has decided if it can or it can not play the ad.\n *\n * Note: In case you wonder why instead of this black poster we don't just show the spinner loader.\n * IOS devices do not work well with animations and the browser chrashes from time to time That is why we chose to\n * have a secondary black poster.\n *\n * It also makes it much more easier for the users of the plugin since it does not change the default behaviour of the\n * spinner and the player works the same way with and without the plugin.\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvar element = document.createElement('div');\n\nvar BlackPosterFactory = function(baseComponent) {\n return {\n /** @constructor */\n init: function init(player, options) {\n options.el = element;\n element.className = 'vjs-black-poster';\n baseComponent.call(this, player, options);\n\n var posterImg = player.getChild('posterImage');\n\n //We need to do it asynchronously to be sure that the black poster el is on the dom.\n setTimeout(function() {\n if(posterImg && player && player.el()) {\n player.el().insertBefore(element, posterImg.el());\n }\n }, 0);\n },\n el: function getElement() {\n return element;\n }\n };\n};\n\nmodule.exports = BlackPosterFactory;","'use strict';\n\nvar baseVideoJsComponent = videojs.Component;\n\nvar BlackPoster = require('./black-poster')(baseVideoJsComponent);\n\nvideojs.BlackPoster = videojs.Component.extend(BlackPoster);\n","'use strict';\n\nvar VASTClient = require('../ads/vast/VASTClient');\nvar VASTError = require('../ads/vast/VASTError');\nvar vastUtil = require('../ads/vast/vastUtil');\n\nvar VASTIntegrator = require('../ads/vast/VASTIntegrator');\nvar VPAIDIntegrator = require('../ads/vpaid/VPAIDIntegrator');\n\nvar async = require('../utils/async');\nvar dom = require('../utils/dom');\nvar playerUtils = require('../utils/playerUtils');\nvar utilities = require('../utils/utilityFunctions');\n\nmodule.exports = function VASTPlugin(options) {\n var snapshot;\n var player = this;\n var vast = new VASTClient();\n var adsCanceled = false;\n var defaultOpts = {\n // maximum amount of time in ms to wait to receive `adsready` from the ad\n // implementation after play has been requested. Ad implementations are\n // expected to load any dynamic libraries and make any requests to determine\n // ad policies for a video during this time.\n timeout: 500,\n\n //TODO:finish this IOS FIX\n //Whenever you play an add on IOS, the native player kicks in and we loose control of it. On very heavy pages the 'play' event\n // May occur after the video content has already started. This is wrong if you want to play a preroll ad that needs to happen before the user\n // starts watching the content. To prevent this usec\n iosPrerollCancelTimeout: 2000,\n\n // maximun amount of time for the ad to actually start playing. If this timeout gets\n // triggered the ads will be cancelled\n adCancelTimeout: 3000,\n\n // Boolean flag that configures the player to play a new ad before the user sees the video again\n // the current video\n playAdAlways: false,\n\n // Flag to enable or disable the ads by default.\n adsEnabled: true,\n\n // Boolean flag to enable or disable the resize with window.resize or orientationchange\n autoResize: true,\n\n // Path to the VPAID flash ad's loader\n vpaidFlashLoaderPath: '/VPAIDFlash.swf'\n };\n\n var settings = utilities.extend({}, defaultOpts, options || {});\n\n if(utilities.isUndefined(settings.adTagUrl) && utilities.isDefined(settings.url)){\n settings.adTagUrl = settings.url;\n }\n\n if (utilities.isString(settings.adTagUrl)) {\n settings.adTagUrl = utilities.echoFn(settings.adTagUrl);\n }\n\n if (utilities.isDefined(settings.adTagXML) && !utilities.isFunction(settings.adTagXML)) {\n return trackAdError(new VASTError('on VideoJS VAST plugin, the passed adTagXML option does not contain a function'));\n }\n\n if (!utilities.isDefined(settings.adTagUrl) && !utilities.isFunction(settings.adTagXML)) {\n return trackAdError(new VASTError('on VideoJS VAST plugin, missing adTagUrl on options object'));\n }\n\n playerUtils.prepareForAds(player);\n\n if (settings.playAdAlways) {\n // No matter what happens we play a new ad before the user sees the video again.\n player.on('vast.contentEnd', function () {\n setTimeout(function () {\n player.trigger('vast.reset');\n }, 0);\n });\n }\n\n player.on('vast.firstPlay', tryToPlayPrerollAd);\n\n player.on('vast.reset', function () {\n //If we are reseting the plugin, we don't want to restore the content\n snapshot = null;\n cancelAds();\n });\n\n player.vast = {\n isEnabled: function () {\n return settings.adsEnabled;\n },\n\n enable: function () {\n settings.adsEnabled = true;\n },\n\n disable: function () {\n settings.adsEnabled = false;\n }\n };\n\n return player.vast;\n\n /**** Local functions ****/\n function tryToPlayPrerollAd() {\n //We remove the poster to prevent flickering whenever the content starts playing\n playerUtils.removeNativePoster(player);\n\n playerUtils.once(player, ['vast.adsCancel', 'vast.adEnd'], function () {\n removeAdUnit();\n restoreVideoContent();\n });\n\n async.waterfall([\n checkAdsEnabled,\n preparePlayerForAd,\n startAdCancelTimeout,\n playPrerollAd\n ], function (error, response) {\n if (error) {\n trackAdError(error, response);\n } else {\n player.trigger('vast.adEnd');\n }\n });\n\n /*** Local functions ***/\n\n function removeAdUnit() {\n if (player.vast && player.vast.adUnit) {\n player.vast.adUnit = null; //We remove the adUnit\n }\n }\n\n function restoreVideoContent() {\n setupContentEvents();\n if (snapshot) {\n playerUtils.restorePlayerSnapshot(player, snapshot);\n snapshot = null;\n }\n }\n\n function setupContentEvents() {\n playerUtils.once(player, ['playing', 'vast.reset', 'vast.firstPlay'], function (evt) {\n if (evt.type !== 'playing') {\n return;\n }\n\n player.trigger('vast.contentStart');\n\n playerUtils.once(player, ['ended', 'vast.reset', 'vast.firstPlay'], function (evt) {\n if (evt.type === 'ended') {\n player.trigger('vast.contentEnd');\n }\n });\n });\n }\n\n function checkAdsEnabled(next) {\n if (settings.adsEnabled) {\n return next(null);\n }\n next(new VASTError('Ads are not enabled'));\n }\n\n function preparePlayerForAd(next) {\n if (canPlayPrerollAd()) {\n snapshot = playerUtils.getPlayerSnapshot(player);\n player.pause();\n addSpinnerIcon();\n\n if(player.paused()) {\n next(null);\n } else {\n playerUtils.once(player, ['playing'], function() {\n player.pause();\n next(null);\n });\n }\n } else {\n next(new VASTError('video content has been playing before preroll ad'));\n }\n }\n\n function canPlayPrerollAd() {\n return !utilities.isIPhone() || player.currentTime() <= settings.iosPrerollCancelTimeout;\n }\n\n function startAdCancelTimeout(next) {\n var adCancelTimeoutId;\n adsCanceled = false;\n\n adCancelTimeoutId = setTimeout(function () {\n trackAdError(new VASTError('timeout while waiting for the video to start playing', 402));\n }, settings.adCancelTimeout);\n\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], clearAdCancelTimeout);\n\n /*** local functions ***/\n function clearAdCancelTimeout() {\n if (adCancelTimeoutId) {\n clearTimeout(adCancelTimeoutId);\n adCancelTimeoutId = null;\n }\n }\n\n next(null);\n }\n\n function addSpinnerIcon() {\n dom.addClass(player.el(), 'vjs-vast-ad-loading');\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], removeSpinnerIcon);\n }\n\n function removeSpinnerIcon() {\n //IMPORTANT NOTE: We remove the spinnerIcon asynchronously to give time to the browser to start the video.\n // If we remove it synchronously we see a flash of the content video before the ad starts playing.\n setTimeout(function () {\n dom.removeClass(player.el(), 'vjs-vast-ad-loading');\n }, 100);\n }\n\n }\n\n function cancelAds() {\n player.trigger('vast.adsCancel');\n adsCanceled = true;\n }\n\n function playPrerollAd(callback) {\n async.waterfall([\n getVastResponse,\n playAd\n ], callback);\n }\n\n function getVastResponse(callback) {\n vast.getVASTResponse(settings.adTagUrl ? settings.adTagUrl() : settings.adTagXML, callback);\n }\n\n function playAd(vastResponse, callback) {\n //TODO: Find a better way to stop the play. The 'playPrerollWaterfall' ends in an inconsistent situation\n //If the state is not 'preroll?' it means the ads were canceled therefore, we break the waterfall\n if (adsCanceled) {\n return;\n }\n\n var adIntegrator = isVPAID(vastResponse) ? new VPAIDIntegrator(player, settings) : new VASTIntegrator(player);\n var adFinished = false;\n\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], function (evt) {\n if (evt.type === 'vast.adStart') {\n addAdsLabel();\n }\n });\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeAdsLabel);\n\n if (utilities.isIDevice()) {\n preventManualProgress();\n }\n\n player.vast.vastResponse = vastResponse;\n player.vast.adUnit = adIntegrator.playAd(vastResponse, callback);\n\n /*** Local functions ****/\n function addAdsLabel() {\n if (adFinished || player.controlBar.getChild('AdsLabel')) {\n return;\n }\n\n player.controlBar.addChild('AdsLabel');\n }\n\n function removeAdsLabel() {\n player.controlBar.removeChild('AdsLabel');\n adFinished = true;\n }\n\n function preventManualProgress() {\n //IOS video clock is very unreliable and we need a 3 seconds threshold to ensure that the user forwarded/rewound the ad\n var PROGRESS_THRESHOLD = 3;\n var previousTime = 0;\n var skipad_attempts = 0;\n\n player.on('timeupdate', adTimeupdateHandler);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel', 'vast.adError'], stopPreventManualProgress);\n\n /*** Local functions ***/\n function adTimeupdateHandler() {\n var currentTime = player.currentTime();\n var progressDelta = Math.abs(currentTime - previousTime);\n\n if (progressDelta > PROGRESS_THRESHOLD) {\n skipad_attempts += 1;\n if (skipad_attempts >= 2) {\n player.pause();\n }\n player.currentTime(previousTime);\n } else {\n previousTime = currentTime;\n }\n }\n\n function stopPreventManualProgress() {\n player.off('timeupdate', adTimeupdateHandler);\n }\n }\n }\n\n function trackAdError(error, vastResponse) {\n player.trigger({type: 'vast.adError', error: error});\n cancelAds();\n if (console && console.log) {\n console.log('AD ERROR:', error.message, error, vastResponse);\n }\n }\n\n function isVPAID(vastResponse) {\n var i, len;\n var mediaFiles = vastResponse.mediaFiles;\n for (i = 0, len = mediaFiles.length; i < len; i++) {\n if (vastUtil.isVPAID(mediaFiles[i])) {\n return true;\n }\n }\n return false;\n }\n};","//Small subset of async\n\nvar utilities = require('./utilityFunctions');\n\nvar async = {};\n\nasync.setImmediate = function (fn) {\n setTimeout(fn, 0);\n};\n\nasync.iterator = function (tasks) {\n var makeCallback = function (index) {\n var fn = function () {\n if (tasks.length) {\n tasks[index].apply(null, arguments);\n }\n return fn.next();\n };\n fn.next = function () {\n return (index < tasks.length - 1) ? makeCallback(index + 1) : null;\n };\n return fn;\n };\n return makeCallback(0);\n};\n\n\nasync.waterfall = function (tasks, callback) {\n callback = callback || function () { };\n if (!utilities.isArray(tasks)) {\n var err = new Error('First argument to waterfall must be an array of functions');\n return callback(err);\n }\n if (!tasks.length) {\n return callback();\n }\n var wrapIterator = function (iterator) {\n return function (err) {\n if (err) {\n callback.apply(null, arguments);\n callback = function () {\n };\n }\n else {\n var args = Array.prototype.slice.call(arguments, 1);\n var next = iterator.next();\n if (next) {\n args.push(wrapIterator(next));\n }\n else {\n args.push(callback);\n }\n async.setImmediate(function () {\n iterator.apply(null, args);\n });\n }\n };\n };\n wrapIterator(async.iterator(tasks))();\n};\n\nasync.when = function (condition, callback) {\n if (!utilities.isFunction(callback)) {\n throw new Error(\"async.when error: missing callback argument\");\n }\n\n var isAllowed = utilities.isFunction(condition) ? condition : function () {\n return !!condition;\n };\n\n return function () {\n var args = utilities.arrayLikeObjToArray(arguments);\n var next = args.pop();\n\n if (isAllowed.apply(null, args)) {\n return callback.apply(this, arguments);\n }\n\n args.unshift(null);\n return next.apply(null, args);\n };\n};\n\nmodule.exports = async;\n\n","'use strict';\n\nvar utilities = require('./utilityFunctions');\n\nvar dom = {};\n\ndom.isVisible = function isVisible(el) {\n var style = window.getComputedStyle(el);\n return style.visibility !== 'hidden';\n};\n\ndom.isHidden = function isHidden(el) {\n var style = window.getComputedStyle(el);\n return style.display === 'none';\n};\n\ndom.isShown = function isShown(el) {\n return !dom.isHidden(el);\n};\n\ndom.hide = function hide(el) {\n el.__prev_style_display_ = el.style.display;\n el.style.display = 'none';\n};\n\ndom.show = function show(el) {\n if (dom.isHidden(el)) {\n el.style.display = el.__prev_style_display_;\n }\n el.__prev_style_display_ = undefined;\n};\n\ndom.hasClass = function hasClass(el, cssClass) {\n var classes, i, len;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.contains(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n cssClass = (cssClass || '');\n\n for (i = 0, len = classes.length; i < len; i += 1) {\n if (classes[i] === cssClass) {\n return true;\n }\n }\n }\n return false;\n};\n\ndom.addClass = function (el, cssClass) {\n var classes;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.add(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n if (utilities.isString(cssClass) && utilities.isNotEmptyString(cssClass.replace(/\\s+/, ''))) {\n classes.push(cssClass);\n el.setAttribute('class', classes.join(' '));\n }\n }\n};\n\ndom.removeClass = function (el, cssClass) {\n var classes;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.remove(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n var newClasses = [];\n var i, len;\n if (utilities.isString(cssClass) && utilities.isNotEmptyString(cssClass.replace(/\\s+/, ''))) {\n\n for (i = 0, len = classes.length; i < len; i += 1) {\n if (cssClass !== classes[i]) {\n newClasses.push(classes[i]);\n }\n }\n el.setAttribute('class', newClasses.join(' '));\n }\n }\n};\n\ndom.addEventListener = function addEventListener(el, type, handler) {\n if(utilities.isArray(el)){\n utilities.forEach(el, function(e) {\n dom.addEventListener(e, type, handler);\n });\n return;\n }\n\n if(utilities.isArray(type)){\n utilities.forEach(type, function(t) {\n dom.addEventListener(el, t, handler);\n });\n return;\n }\n\n if (el.addEventListener) {\n el.addEventListener(type, handler, false);\n } else if (el.attachEvent) {\n // WARNING!!! this is a very naive implementation !\n // the event object that should be passed to the handler\n // would not be there for IE8\n // we should use \"window.event\" and then \"event.srcElement\"\n // instead of \"event.target\"\n el.attachEvent(\"on\" + type, handler);\n }\n};\n\ndom.removeEventListener = function removeEventListener(el, type, handler) {\n if(utilities.isArray(el)){\n utilities.forEach(el, function(e) {\n dom.removeEventListener(e, type, handler);\n });\n return;\n }\n\n if(utilities.isArray(type)){\n utilities.forEach(type, function(t) {\n dom.removeEventListener(el, t, handler);\n });\n return;\n }\n\n if (el.removeEventListener) {\n el.removeEventListener(type, handler, false);\n } else if (el.detachEvent) {\n el.detachEvent(\"on\" + type, handler);\n } else {\n el[\"on\" + type] = null;\n }\n};\n\ndom.dispatchEvent = function dispatchEvent(el, event) {\n if (el.dispatchEvent) {\n el.dispatchEvent(event);\n } else {\n el.fireEvent(\"on\" + event.eventType, event);\n }\n};\n\ndom.isDescendant = function isDescendant(parent, child) {\n var node = child.parentNode;\n while (node !== null) {\n if (node === parent) {\n return true;\n }\n node = node.parentNode;\n }\n return false;\n};\n\ndom.getTextContent = function getTextContent(el){\n return el.textContent || el.text;\n};\n\ndom.prependChild = function prependChild(parent, child) {\n if(child.parentNode){\n child.parentNode.removeChild(child);\n }\n return parent.insertBefore(child, parent.firstChild);\n};\n\ndom.remove = function removeNode(node){\n if(node && node.parentNode){\n node.parentNode.removeChild(node);\n }\n};\n\ndom.isDomElement = function isDomElement(o) {\n return o instanceof Element;\n};\n\ndom.click = function(el, handler) {\n dom.addEventListener(el, 'click', handler);\n};\n\ndom.once = function(el, type, handler) {\n function handlerWrap() {\n handler.apply(null, arguments);\n dom.removeEventListener(el, type, handlerWrap);\n }\n\n dom.addEventListener(el, type, handlerWrap);\n};\n\n//Note: there is no getBoundingClientRect on iPad so we need a fallback\ndom.getDimension = function getDimension(element) {\n var rect;\n\n //On IE9 and below getBoundingClientRect does not work consistently\n if(!utilities.isOldIE() && element.getBoundingClientRect) {\n rect = element.getBoundingClientRect();\n return {\n width: rect.width,\n height: rect.height\n };\n }\n\n return {\n width: element.offsetWidth,\n height: element.offsetHeight\n };\n};\n\nmodule.exports = dom;","'use strict';\n\nvar urlUtils = require('./urlUtils');\nvar utilities = require('./utilityFunctions');\n\nfunction HttpRequestError(message) {\n this.message = 'HttpRequest Error: ' + (message || '');\n}\nHttpRequestError.prototype = new Error();\nHttpRequestError.prototype.name = \"HttpRequest Error\";\n\nfunction HttpRequest(createXhr) {\n if (!utilities.isFunction(createXhr)) {\n throw new HttpRequestError('Missing XMLHttpRequest factory method');\n }\n\n this.createXhr = createXhr;\n}\n\nHttpRequest.prototype.run = function (method, url, callback, options) {\n sanityCheck(url, callback, options);\n var timeout, timeoutId;\n var xhr = this.createXhr();\n options = options || {};\n timeout = utilities.isNumber(options.timeout) ? options.timeout : 0;\n\n xhr.open(method, urlUtils.urlParts(url).href, true);\n\n if (options.headers) {\n setHeaders(xhr, options.headers);\n }\n\n if (options.withCredentials) {\n xhr.withCredentials = true;\n }\n\n xhr.onload = function () {\n var statusText, response, status;\n\n /**\n * The only way to do a secure request on IE8 and IE9 is with the XDomainRequest object. Unfortunately, microsoft is\n * so nice that decided that the status property and the 'getAllResponseHeaders' method where not needed so we have to\n * fake them. If the request gets done with an XDomainRequest instance, we will assume that there are no headers and\n * the status will always be 200. If you don't like it, DO NOT USE ANCIENT BROWSERS!!!\n *\n * For mor info go to: https://msdn.microsoft.com/en-us/library/cc288060(v=vs.85).aspx\n */\n if (!xhr.getAllResponseHeaders) {\n xhr.getAllResponseHeaders = function () {\n return null;\n };\n }\n\n if (!xhr.status) {\n xhr.status = 200;\n }\n\n if (utilities.isDefined(timeoutId)) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n\n statusText = xhr.statusText || '';\n\n // responseText is the old-school way of retrieving response (supported by IE8 & 9)\n // response/responseType properties were introduced in XHR Level2 spec (supported by IE10)\n response = ('response' in xhr) ? xhr.response : xhr.responseText;\n\n // normalize IE9 bug (http://bugs.jquery.com/ticket/1450)\n status = xhr.status === 1223 ? 204 : xhr.status;\n\n callback(\n status,\n response,\n xhr.getAllResponseHeaders(),\n statusText);\n };\n\n xhr.onerror = requestError;\n xhr.onabort = requestError;\n\n xhr.send();\n\n if (timeout > 0) {\n timeoutId = setTimeout(function () {\n xhr && xhr.abort();\n }, timeout);\n }\n\n function sanityCheck(url, callback, options) {\n if (!utilities.isString(url) || utilities.isEmptyString(url)) {\n throw new HttpRequestError(\"Invalid url '\" + url + \"'\");\n }\n\n if (!utilities.isFunction(callback)) {\n throw new HttpRequestError(\"Invalid handler '\" + callback + \"' for the http request\");\n }\n\n if (utilities.isDefined(options) && !utilities.isObject(options)) {\n throw new HttpRequestError(\"Invalid options map '\" + options + \"'\");\n }\n }\n\n function setHeaders(xhr, headers) {\n utilities.forEach(headers, function (value, key) {\n if (utilities.isDefined(value)) {\n xhr.setRequestHeader(key, value);\n }\n });\n }\n\n function requestError() {\n callback(-1, null, null, '');\n }\n};\n\nHttpRequest.prototype.get = function (url, callback, options) {\n this.run('GET', url, processResponse, options);\n\n function processResponse(status, response, headersString, statusText) {\n if (isSuccess(status)) {\n callback(null, response, status, headersString, statusText);\n } else {\n callback(new HttpRequestError(statusText), response, status, headersString, statusText);\n }\n }\n\n function isSuccess(status) {\n return 200 <= status && status < 300;\n }\n};\n\nfunction createXhr() {\n var xhr = new XMLHttpRequest();\n if (!(\"withCredentials\" in xhr)) {\n // XDomainRequest for IE.\n xhr = new XDomainRequest();\n }\n return xhr;\n}\n\nvar http = new HttpRequest(createXhr);\n\nmodule.exports = {\n http: http,\n HttpRequest: HttpRequest,\n HttpRequestError: HttpRequestError,\n createXhr: createXhr\n};\n","'use strict';\n\nvar dom = require('./dom');\nvar utilities = require('./utilityFunctions');\n\nvar playerUtils = {};\n\n/**\n * Returns an object that captures the portions of player state relevant to\n * video playback. The result of this function can be passed to\n * restorePlayerSnapshot with a player to return the player to the state it\n * was in when this function was invoked.\n * @param {object} player The videojs player object\n */\nplayerUtils.getPlayerSnapshot = function getPlayerSnapshot(player) {\n var tech = player.el().querySelector('.vjs-tech');\n\n var snapshot = {\n ended: player.ended(),\n src: player.currentSrc(),\n currentTime: player.currentTime(),\n type: player.currentType(),\n playing: !player.paused(),\n suppressedTracks: getSuppressedTracks(player)\n };\n\n if (tech) {\n snapshot.nativePoster = tech.poster;\n snapshot.style = tech.getAttribute('style');\n }\n return snapshot;\n\n /**** Local Functions ****/\n function getSuppressedTracks(player) {\n var tracks = player.remoteTextTracks ? player.remoteTextTracks() : [];\n\n if (tracks && utilities.isArray(tracks.tracks_)) {\n tracks = tracks.tracks_;\n }\n\n if (!utilities.isArray(tracks)) {\n tracks = [];\n }\n\n var suppressedTracks = [];\n tracks.forEach(function (track) {\n suppressedTracks.push({\n track: track,\n mode: track.mode\n });\n track.mode = 'disabled';\n });\n\n return suppressedTracks;\n }\n};\n\n/**\n * Attempts to modify the specified player so that its state is equivalent to\n * the state of the snapshot.\n * @param {object} snapshot - the player state to apply\n */\nplayerUtils.restorePlayerSnapshot = function restorePlayerSnapshot(player, snapshot) {\n var tech = player.el().querySelector('.vjs-tech');\n var attempts = 20; // the number of remaining attempts to restore the snapshot\n\n if (snapshot.nativePoster) {\n tech.poster = snapshot.nativePoster;\n }\n\n if ('style' in snapshot) {\n // overwrite all css style properties to restore state precisely\n tech.setAttribute('style', snapshot.style || '');\n }\n\n if (hasSrcChanged(player, snapshot)) {\n\n // on ios7, fiddling with textTracks too early will cause safari to crash\n player.one('contentloadedmetadata', restoreTracks);\n\n player.one('canplay', tryToResume);\n ensureCanplayEvtGetsFired();\n\n // if the src changed for ad playback, reset it\n player.src({src: snapshot.src, type: snapshot.type});\n\n // safari requires a call to `load` to pick up a changed source\n player.load();\n\n } else {\n restoreTracks();\n\n if (snapshot.playing) {\n player.play();\n }\n }\n\n /*** Local Functions ***/\n\n /**\n * Sometimes firefox does not trigger the 'canplay' evt.\n * This code ensure that it always gets triggered triggered.\n */\n function ensureCanplayEvtGetsFired() {\n var timeoutId = setTimeout(function() {\n player.trigger('canplay');\n }, 1000);\n\n player.one('canplay', function(){\n clearTimeout(timeoutId);\n });\n }\n\n /**\n * Determine whether the player needs to be restored to its state\n * before ad playback began. With a custom ad display or burned-in\n * ads, the content player state hasn't been modified and so no\n * restoration is required\n */\n function hasSrcChanged(player, snapshot) {\n if (player.src()) {\n return player.src() !== snapshot.src;\n }\n // the player was configured through source element children\n return player.currentSrc() !== snapshot.src;\n }\n\n function restoreTracks() {\n var suppressedTracks = snapshot.suppressedTracks;\n suppressedTracks.forEach(function (trackSnapshot) {\n trackSnapshot.track.mode = trackSnapshot.mode;\n });\n }\n\n /**\n * Determine if the video element has loaded enough of the snapshot source\n * to be ready to apply the rest of the state\n */\n function tryToResume() {\n\n // if some period of the video is seekable, resume playback\n // otherwise delay a bit and then check again unless we're out of attempts\n\n if (!playerUtils.isReadyToResume(player) && attempts--) {\n setTimeout(tryToResume, 50);\n } else {\n try {\n if(player.currentTime() !== snapshot.currentTime) {\n if (snapshot.playing) { // if needed restore playing status after seek completes\n player.one('seeked', function() {\n player.play();\n });\n }\n player.currentTime(snapshot.currentTime);\n\n } else if (snapshot.playing) {\n // if needed and no seek has been performed, restore playing status immediately\n player.play();\n }\n\n } catch (e) {\n videojs.log.warn('Failed to resume the content after an advertisement', e);\n }\n }\n }\n};\n\nplayerUtils.isReadyToResume = function (player) {\n\n if (player.readyState() > 1) {\n // some browsers and media aren't \"seekable\".\n // readyState greater than 1 allows for seeking without exceptions\n return true;\n }\n\n if (player.seekable() === undefined) {\n // if the player doesn't expose the seekable time ranges, try to\n // resume playback immediately\n return true;\n }\n\n if (player.seekable().length > 0) {\n // if some period of the video is seekable, resume playback\n return true;\n }\n\n return false;\n};\n\n/**\n * This function prepares the player to display ads.\n * Adding convenience events like the 'vast.firsPlay' that gets fired when the video is first played\n * and ads the blackPoster to the player to prevent content from being displayed before the preroll ad.\n *\n * @param player\n */\nplayerUtils.prepareForAds = function (player) {\n var blackPoster = player.addChild('blackPoster');\n var _firstPlay = true;\n var volumeSnapshot;\n\n\n monkeyPatchPlayerApi();\n\n player.on('play', tryToTriggerFirstPlay);\n player.on('vast.reset', resetFirstPlay);//Every time we change the sources we reset the first play.\n player.on('vast.firstPlay', restoreContentVolume);\n player.on('error', hideBlackPoster);//If there is an error in the player we remove the blackposter to show the err msg\n player.on('vast.adStart', hideBlackPoster);\n player.on('vast.adsCancel', hideBlackPoster);\n player.on('vast.adError', hideBlackPoster);\n player.on('vast.adStart', addStyles);\n player.on('vast.adEnd', removeStyles);\n player.on('vast.adsCancel', removeStyles);\n\n /*** Local Functions ***/\n\n /**\n What this function does is ugly and horrible and I should think twice before calling myself a good developer. With that said,\n it is the best solution I could find to mute the video until the 'play' event happens (on mobile devices) and the plugin can decide whether\n to play the ad or not.\n\n We also need this monkeypatch to be able to pause and resume an ad using the player's API\n\n If you have a better solution please do tell me.\n */\n function monkeyPatchPlayerApi() {\n\n /**\n * Monkey patch needed to handle firstPlay and resume of playing ad.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are restoring a VAST ad.\n * @returns {player}\n */\n var origPlay = player.play;\n player.play = function (callOrigPlay) {\n var that = this;\n\n if (isFirstPlay()) {\n firstPlay();\n } else {\n resume(callOrigPlay);\n }\n\n return this;\n\n /*** local functions ***/\n function firstPlay() {\n if (!utilities.isIPhone()) {\n volumeSnapshot = saveVolumeSnapshot();\n player.muted(true);\n }\n\n origPlay.apply(that, arguments);\n }\n\n function resume(callOrigPlay) {\n if (isAdPlaying() && !callOrigPlay) {\n player.vast.adUnit.resumeAd();\n } else {\n origPlay.apply(that, arguments);\n }\n }\n };\n\n\n /**\n * Needed monkey patch to handle pause of playing ad.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are pausing a VAST ad.\n * @returns {player}\n */\n var origPause = player.pause;\n player.pause = function (callOrigPause) {\n if (isAdPlaying() && !callOrigPause) {\n player.vast.adUnit.pauseAd();\n } else {\n origPause.apply(this, arguments);\n }\n return this;\n };\n\n\n /**\n * Needed monkey patch to handle paused state of the player when ads are playing.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are pausing a VAST ad.\n * @returns {player}\n */\n var origPaused = player.paused;\n player.paused = function (callOrigPaused) {\n if (isAdPlaying() && !callOrigPaused) {\n return player.vast.adUnit.isPaused();\n }\n return origPaused.apply(this, arguments);\n };\n }\n\n function isAdPlaying() {\n return player.vast && player.vast.adUnit;\n }\n\n function tryToTriggerFirstPlay() {\n if (isFirstPlay()) {\n _firstPlay = false;\n player.trigger('vast.firstPlay');\n }\n }\n\n function resetFirstPlay() {\n _firstPlay = true;\n blackPoster.show();\n restoreContentVolume();\n }\n\n function isFirstPlay() {\n return _firstPlay;\n }\n\n function saveVolumeSnapshot() {\n return {\n muted: player.muted(),\n volume: player.volume()\n };\n }\n\n function restoreContentVolume() {\n if (volumeSnapshot) {\n player.currentTime(0);\n restoreVolumeSnapshot(volumeSnapshot);\n volumeSnapshot = null;\n }\n }\n\n function restoreVolumeSnapshot(snapshot) {\n if (utilities.isObject(snapshot)) {\n player.volume(snapshot.volume);\n player.muted(snapshot.muted);\n }\n }\n\n function hideBlackPoster() {\n if (!dom.hasClass(blackPoster.el(), 'vjs-hidden')) {\n blackPoster.hide();\n }\n }\n\n function addStyles() {\n dom.addClass(player.el(), 'vjs-ad-playing');\n }\n\n function removeStyles() {\n dom.removeClass(player.el(), 'vjs-ad-playing');\n }\n};\n\n/**\n * Remove the poster attribute from the video element tech, if present. When\n * reusing a video element for multiple videos, the poster image will briefly\n * reappear while the new source loads. Removing the attribute ahead of time\n * prevents the poster from showing up between videos.\n * @param {object} player The videojs player object\n */\nplayerUtils.removeNativePoster = function (player) {\n var tech = player.el().querySelector('.vjs-tech');\n if (tech) {\n tech.removeAttribute('poster');\n }\n};\n\n/**\n * Helper function to listen to many events until one of them gets fired, then we\n * execute the handler and unsubscribe all the event listeners;\n *\n * @param player specific player from where to listen for the events\n * @param events array of events\n * @param handler function to execute once one of the events fires\n */\nplayerUtils.once = function once(player, events, handler) {\n function listener() {\n handler.apply(null, arguments);\n\n events.forEach(function (event) {\n player.off(event, listener);\n });\n }\n\n events.forEach(function (event) {\n player.on(event, listener);\n });\n};\n\n\nmodule.exports = playerUtils;","'use strict';\n\nvar utilities = require('./utilityFunctions');\n\n/**\n *\n * IMPORTANT NOTE: This function comes from angularJs and was originally called urlResolve\n * you can take a look at the original code here https://github.com/angular/angular.js/blob/master/src/ng/urlUtils.js\n *\n * Implementation Notes for non-IE browsers\n * ----------------------------------------\n * Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM,\n * results both in the normalizing and parsing of the URL. Normalizing means that a relative\n * URL will be resolved into an absolute URL in the context of the application document.\n * Parsing means that the anchor node's host, hostname, protocol, port, pathname and related\n * properties are all populated to reflect the normalized URL. This approach has wide\n * compatibility - Safari 1+, Mozilla 1+, Opera 7+,e etc. See\n * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n *\n * Implementation Notes for IE\n * ---------------------------\n * IE >= 8 and <= 10 normalizes the URL when assigned to the anchor node similar to the other\n * browsers. However, the parsed components will not be set if the URL assigned did not specify\n * them. (e.g. if you assign a.href = \"foo\", then a.protocol, a.host, etc. will be empty.) We\n * work around that by performing the parsing in a 2nd step by taking a previously normalized\n * URL (e.g. by assigning to a.href) and assigning it a.href again. This correctly populates the\n * properties such as protocol, hostname, port, etc.\n *\n * IE7 does not normalize the URL when assigned to an anchor node. (Apparently, it does, if one\n * uses the inner HTML approach to assign the URL as part of an HTML snippet -\n * http://stackoverflow.com/a/472729) However, setting img[src] does normalize the URL.\n * Unfortunately, setting img[src] to something like \"javascript:foo\" on IE throws an exception.\n * Since the primary usage for normalizing URLs is to sanitize such URLs, we can't use that\n * method and IE < 8 is unsupported.\n *\n * References:\n * http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement\n * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n * http://url.spec.whatwg.org/#urlutils\n * https://github.com/angular/angular.js/pull/2902\n * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/\n *\n * @kind function\n * @param {string} url The URL to be parsed.\n * @description Normalizes and parses a URL.\n * @returns {object} Returns the normalized URL as a dictionary.\n *\n * | member name | Description |\n * |---------------|----------------|\n * | href | A normalized version of the provided URL if it was not an absolute URL |\n * | protocol | The protocol including the trailing colon |\n * | host | The host and port (if the port is non-default) of the normalizedUrl |\n * | search | The search params, minus the question mark |\n * | hash | The hash string, minus the hash symbol\n * | hostname | The hostname\n * | port | The port, without \":\"\n * | pathname | The pathname, beginning with \"/\"\n *\n */\n\nvar urlParsingNode = document.createElement(\"a\");\n/**\n * documentMode is an IE-only property\n * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx\n */\nvar msie = document.documentMode;\n\nfunction urlParts(url) {\n var href = url;\n\n if (msie) {\n // Normalize before parse. Refer Implementation Notes on why this is\n // done in two steps on IE.\n urlParsingNode.setAttribute(\"href\", href);\n href = urlParsingNode.href;\n }\n\n urlParsingNode.setAttribute('href', href);\n\n // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n return {\n href: urlParsingNode.href,\n protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n host: urlParsingNode.host,\n search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n hostname: urlParsingNode.hostname,\n port: utilities.isNotEmptyString(urlParsingNode.port)? urlParsingNode.port: 80,\n pathname: (urlParsingNode.pathname.charAt(0) === '/')\n ? urlParsingNode.pathname\n : '/' + urlParsingNode.pathname\n };\n}\n\n\n/**\n * This function accepts a query string (search part of a url) and returns a dictionary with\n * the different key value pairs\n * @param {string} qs queryString\n */\nfunction queryStringToObj(qs, cond) {\n var pairs, qsObj;\n\n cond = utilities.isFunction(cond)? cond : function() {\n return true;\n };\n\n qs = qs.trim().replace(/^\\?/, '');\n pairs = qs.split('&');\n qsObj = {};\n\n utilities.forEach(pairs, function (pair) {\n var keyValue, key, value;\n if (pair !== '') {\n keyValue = pair.split('=');\n key = keyValue[0];\n value = keyValue[1];\n if(cond(key, value)){\n qsObj[key] = value;\n }\n }\n });\n\n return qsObj;\n}\n\n/**\n * This function accepts an object and serializes it into a query string without the leading '?'\n * @param obj\n * @returns {string}\n */\nfunction objToQueryString(obj) {\n var pairs = [];\n utilities.forEach(obj, function (value, key) {\n pairs.push(key + '=' + value);\n });\n return pairs.join('&');\n}\n\nmodule.exports = {\n urlParts: urlParts,\n queryStringToObj: queryStringToObj,\n objToQueryString: objToQueryString\n};\n","/*jshint unused:false */\n\"use strict\";\n\nvar NODE_TYPE_ELEMENT = 1;\nvar SNAKE_CASE_REGEXP = /[A-Z]/g;\nvar EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/i;\n/*jslint maxlen: 500 */\nvar ISO8086_REGEXP = /^([\\+-]?\\d{4}(?!\\d{2}\\b))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))([T\\s]((([01]\\d|2[0-3])((:?)[0-5]\\d)?|24\\:?00)([\\.,]\\d+(?!:))?)?(\\17[0-5]\\d([\\.,]\\d+)?)?([zZ]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)?$/;\n\n\nfunction noop(){ }\n\nfunction isNull(o) {\n return o === null;\n}\n\nfunction isDefined(o){\n return o !== undefined;\n}\n\nfunction isUndefined(o){\n return o === undefined;\n}\n\nfunction isObject(obj) {\n return typeof obj === 'object';\n}\n\nfunction isFunction(str){\n return typeof str === 'function';\n}\n\nfunction isNumber(num){\n return typeof num === 'number';\n}\n\nfunction isWindow(obj) {\n return utilities.isObject(obj) && obj.window === obj;\n}\n\nfunction isArray(array){\n return Object.prototype.toString.call( array ) === '[object Array]';\n}\n\nfunction isArrayLike(obj) {\n if (obj === null || utilities.isWindow(obj) || utilities.isFunction(obj) || utilities.isUndefined(obj)) {\n return false;\n }\n\n var length = obj.length;\n\n if (obj.nodeType === NODE_TYPE_ELEMENT && length) {\n return true;\n }\n\n return utilities.isString(obj) || utilities.isArray(obj) || length === 0 ||\n typeof length === 'number' && length > 0 && (length - 1) in obj;\n}\n\nfunction isString(str){\n return typeof str === 'string';\n}\n\nfunction isEmptyString(str) {\n return utilities.isString(str) && str.length === 0;\n}\n\nfunction isNotEmptyString(str) {\n return utilities.isString(str) && str.length !== 0;\n}\n\nfunction arrayLikeObjToArray(args) {\n return Array.prototype.slice.call(args);\n}\n\nfunction forEach(obj, iterator, context) {\n var key, length;\n if (obj) {\n if (isFunction(obj)) {\n for (key in obj) {\n // Need to check if hasOwnProperty exists,\n // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function\n if (key !== 'prototype' && key !== 'length' && key !== 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n } else if (isArray(obj)) {\n var isPrimitive = typeof obj !== 'object';\n for (key = 0, length = obj.length; key < length; key++) {\n if (isPrimitive || key in obj) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n } else if (obj.forEach && obj.forEach !== forEach) {\n obj.forEach(iterator, context, obj);\n } else {\n for (key in obj) {\n if (obj.hasOwnProperty(key)) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n }\n }\n return obj;\n}\n\nfunction snake_case(name, separator) {\n separator = separator || '_';\n return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {\n return (pos ? separator : '') + letter.toLowerCase();\n });\n}\n\nfunction isValidEmail(email){\n if(!utilities.isString(email)){\n return false;\n }\n\n return EMAIL_REGEXP.test(email.trim());\n}\n\nfunction extend (obj) {\n var arg, i, k;\n for (i = 1; i < arguments.length; i++) {\n arg = arguments[i];\n for (k in arg) {\n if (arg.hasOwnProperty(k)) {\n if(isObject(obj[k]) && !isNull(obj[k]) && isObject(arg[k])){\n obj[k] = extend({}, obj[k], arg[k]);\n }else {\n obj[k] = arg[k];\n }\n }\n }\n }\n return obj;\n}\n\nfunction capitalize(s){\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nfunction decapitalize(s) {\n return s.charAt(0).toLowerCase() + s.slice(1);\n}\n\n/**\n * This method works the same way array.prototype.map works but if the transformer returns undefine, then\n * it won't be added to the transformed Array.\n */\nfunction transformArray(array, transformer) {\n var transformedArray = [];\n\n array.forEach(function(item, index){\n var transformedItem = transformer(item, index);\n if(utilities.isDefined(transformedItem)) {\n transformedArray.push(transformedItem);\n }\n });\n\n return transformedArray;\n}\n\nfunction toFixedDigits(num, digits) {\n var formattedNum = num + '';\n digits = utilities.isNumber(digits) ? digits : 0;\n num = utilities.isNumber(num) ? num : parseInt(num, 10);\n if(utilities.isNumber(num) && !isNaN(num)){\n formattedNum = num + '';\n while(formattedNum.length < digits) {\n formattedNum = '0' + formattedNum;\n }\n return formattedNum;\n }\n return NaN + '';\n}\n\nfunction throttle(callback, delay) {\n var previousCall = new Date().getTime() - (delay + 1);\n return function() {\n var time = new Date().getTime();\n if ((time - previousCall) >= delay) {\n previousCall = time;\n callback.apply(this, arguments);\n }\n };\n}\n\nfunction debounce (callback, wait) {\n var timeoutId;\n\n return function (){\n if(timeoutId) {\n clearTimeout(timeoutId);\n }\n timeoutId = setTimeout(function(){\n callback.apply(this, arguments);\n timeoutId = undefined;\n }, wait);\n };\n}\n\n// a function designed to blow up the stack in a naive way\n// but it is ok for videoJs children components\nfunction treeSearch(root, getChildren, found){\n var children = getChildren(root);\n for (var i = 0; i < children.length; i++){\n if (found(children[i])) {\n return children[i];\n }\n else {\n var el = treeSearch(children[i], getChildren, found);\n if (el){\n return el;\n }\n }\n }\n}\n\nfunction echoFn(val) {\n return function () {\n return val;\n };\n}\n\n//Note: Supported formats come from http://www.w3.org/TR/NOTE-datetime\n// and the iso8601 regex comes from http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/\nfunction isISO8601(value) {\n if(utilities.isNumber(value)){\n value = value + ''; //we make sure that we are working with strings\n }\n\n if(!utilities.isString(value)){\n return false;\n }\n\n return ISO8086_REGEXP.test(value.trim());\n}\n\n/**\n * Checks if the Browser is IE9 and below\n * @returns {boolean}\n */\nfunction isOldIE() {\n var version = utilities.getInternetExplorerVersion(navigator);\n if (version === -1) {\n return false;\n }\n\n return version < 10;\n}\n\n/**\n * Returns the version of Internet Explorer or a -1 (indicating the use of another browser).\n * Source: https://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx\n * @returns {number} the version of Internet Explorer or a -1 (indicating the use of another browser).\n */\nfunction getInternetExplorerVersion(navigator) {\n var rv = -1;\n\n if (navigator.appName == 'Microsoft Internet Explorer') {\n var ua = navigator.userAgent;\n var re = new RegExp(\"MSIE ([0-9]{1,}[\\.0-9]{0,})\");\n var res = re.exec(ua);\n if (res !== null) {\n rv = parseFloat(res[1]);\n }\n }\n\n return rv;\n}\n\n/*** Mobile Utility functions ***/\nfunction isIDevice() {\n return /iP(hone|ad)/.test(utilities._UA);\n}\n\nfunction isMobile() {\n return /iP(hone|ad|od)|Android|Windows Phone/.test(utilities._UA);\n}\n\nfunction isIPhone() {\n return /iP(hone|od)/.test(utilities._UA);\n}\n\nfunction isAndroid() {\n return /Android/.test(utilities._UA);\n}\n\nvar utilities = {\n _UA: navigator.userAgent,\n noop: noop,\n isNull: isNull,\n isDefined: isDefined,\n isUndefined: isUndefined,\n isObject: isObject,\n isFunction: isFunction,\n isNumber: isNumber,\n isWindow: isWindow,\n isArray: isArray,\n isArrayLike: isArrayLike,\n isString: isString,\n isEmptyString: isEmptyString,\n isNotEmptyString: isNotEmptyString,\n arrayLikeObjToArray: arrayLikeObjToArray,\n forEach: forEach,\n snake_case: snake_case,\n isValidEmail: isValidEmail,\n extend: extend,\n capitalize: capitalize,\n decapitalize: decapitalize,\n transformArray: transformArray,\n toFixedDigits: toFixedDigits,\n throttle: throttle,\n debounce: debounce,\n treeSearch: treeSearch,\n echoFn: echoFn,\n isISO8601: isISO8601,\n isOldIE: isOldIE,\n getInternetExplorerVersion: getInternetExplorerVersion,\n isIDevice: isIDevice,\n isMobile: isMobile,\n isIPhone: isIPhone,\n isAndroid: isAndroid\n};\n\nmodule.exports = utilities;","'use strict';\n\nvar utilities = require('./utilityFunctions');\n\nvar xml = {};\n\nxml.strToXMLDoc = function strToXMLDoc(stringContainingXMLSource){\n //IE 8\n if(typeof window.DOMParser === 'undefined'){\n var xmlDocument = new ActiveXObject('Microsoft.XMLDOM');\n xmlDocument.async = false;\n xmlDocument.loadXML(stringContainingXMLSource);\n return xmlDocument;\n }\n\n return parseString(stringContainingXMLSource);\n\n function parseString(stringContainingXMLSource){\n var parser = new DOMParser();\n var parsedDocument;\n\n //Note: This try catch is to deal with the fact that on IE parser.parseFromString does throw an error but the rest of the browsers don't.\n try {\n parsedDocument = parser.parseFromString(stringContainingXMLSource, \"application/xml\");\n\n if(isParseError(parsedDocument) || utilities.isEmptyString(stringContainingXMLSource)){\n throw new Error();\n }\n }catch(e){\n throw new Error(\"xml.strToXMLDOC: Error parsing the string: '\" + stringContainingXMLSource + \"'\");\n }\n\n return parsedDocument;\n }\n\n function isParseError(parsedDocument) {\n try { // parser and parsererrorNS could be cached on startup for efficiency\n var parser = new DOMParser(),\n erroneousParse = parser.parseFromString('INVALID', 'text/xml'),\n parsererrorNS = erroneousParse.getElementsByTagName(\"parsererror\")[0].namespaceURI;\n\n if (parsererrorNS === 'http://www.w3.org/1999/xhtml') {\n // In PhantomJS the parseerror element doesn't seem to have a special namespace, so we are just guessing here :(\n return parsedDocument.getElementsByTagName(\"parsererror\").length > 0;\n }\n\n return parsedDocument.getElementsByTagNameNS(parsererrorNS, 'parsererror').length > 0;\n } catch (e) {\n //Note on IE parseString throws an error by itself and it will never reach this code. Because it will have failed before\n }\n }\n};\n\nxml.parseText = function parseText (sValue) {\n if (/^\\s*$/.test(sValue)) { return null; }\n if (/^(?:true|false)$/i.test(sValue)) { return sValue.toLowerCase() === \"true\"; }\n if (isFinite(sValue)) { return parseFloat(sValue); }\n if (utilities.isISO8601(sValue)) { return new Date(sValue); }\n return sValue.trim();\n};\n\nxml.JXONTree = function JXONTree (oXMLParent) {\n var parseText = xml.parseText;\n\n //The document object is an especial object that it may miss some functions or attrs depending on the browser.\n //To prevent this problem with create the JXONTree using the root childNode which is a fully fleshed node on all supported\n //browsers.\n if(oXMLParent.documentElement){\n return new xml.JXONTree(oXMLParent.documentElement);\n }\n\n if (oXMLParent.hasChildNodes()) {\n var sCollectedTxt = \"\";\n for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {\n oNode = oXMLParent.childNodes.item(nItem);\n /*jshint bitwise: false*/\n if ((oNode.nodeType - 1 | 1) === 3) { sCollectedTxt += oNode.nodeType === 3 ? oNode.nodeValue.trim() : oNode.nodeValue; }\n else if (oNode.nodeType === 1 && !oNode.prefix) {\n sProp = utilities.decapitalize(oNode.nodeName);\n vContent = new xml.JXONTree(oNode);\n if (this.hasOwnProperty(sProp)) {\n if (this[sProp].constructor !== Array) { this[sProp] = [this[sProp]]; }\n this[sProp].push(vContent);\n } else { this[sProp] = vContent; }\n }\n }\n if (sCollectedTxt) { this.keyValue = parseText(sCollectedTxt); }\n }\n\n //IE8 Stupid fix\n var hasAttr = typeof oXMLParent.hasAttributes === 'undefined'? oXMLParent.attributes.length > 0: oXMLParent.hasAttributes();\n if (hasAttr) {\n var oAttrib;\n for (var nAttrib = 0; nAttrib < oXMLParent.attributes.length; nAttrib++) {\n oAttrib = oXMLParent.attributes.item(nAttrib);\n this[\"@\" + utilities.decapitalize(oAttrib.name)] = parseText(oAttrib.value.trim());\n }\n }\n};\n\nxml.JXONTree.prototype.attr = function(attr) {\n return this['@' + utilities.decapitalize(attr)];\n};\n\nxml.toJXONTree = function toJXONTree(xmlString){\n var xmlDoc = xml.strToXMLDoc(xmlString);\n return new xml.JXONTree(xmlDoc);\n};\n\n/**\n * Helper function to extract the keyvalue of a JXONTree obj\n *\n * @param xmlObj {JXONTree}\n * return the key value or undefined;\n */\nxml.keyValue = function getKeyValue(xmlObj) {\n if(xmlObj){\n return xmlObj.keyValue;\n }\n return undefined;\n};\n\nxml.attr = function getAttrValue(xmlObj, attr) {\n if(xmlObj) {\n return xmlObj['@' + utilities.decapitalize(attr)];\n }\n return undefined;\n};\n\nxml.encode = function encodeXML(str) {\n return str.replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n};\n\nxml.decode = function decodeXML(str) {\n return str.replace(/'/g, \"'\")\n .replace(/"/g, '\"')\n .replace(/>/g, '>')\n .replace(/</g, '<')\n .replace(/&/g, '&');\n};\n\nmodule.exports = xml;","'use strict';\n\nrequire('./plugin/components/ads-label_4');\nrequire('./plugin/components/black-poster_4');\n\nvar videoJsVAST = require('./plugin/videojs.vast.vpaid');\n\nvideojs.plugin('vastClient', videoJsVAST);\n\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/bin/videojs_5.vast.vpaid.js b/bin/videojs_5.vast.vpaid.js index ea0e1c21..3ae7eca3 100644 --- a/bin/videojs_5.vast.vpaid.js +++ b/bin/videojs_5.vast.vpaid.js @@ -3,25 +3,13 @@ //simple representation of the API -var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); - } - }return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; - }; -}(); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); Object.defineProperty(exports, "__esModule", { value: true }); -function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -} +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var IVPAIDAdUnit = exports.IVPAIDAdUnit = function () { function IVPAIDAdUnit() { @@ -144,39 +132,17 @@ Object.defineProperty(IVPAIDAdUnit, 'EVENTS', { },{}],2:[function(require,module,exports){ 'use strict'; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; - -var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); - } - }return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; - }; -}(); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); Object.defineProperty(exports, "__esModule", { value: true }); -function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -} +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -function _possibleConstructorReturn(self, call) { - if (!self) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); - }return call && ((typeof call === "undefined" ? "undefined" : _typeof(call)) === "object" || typeof call === "function") ? call : self; -} +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } -function _inherits(subClass, superClass) { - if (typeof superClass !== "function" && superClass !== null) { - throw new TypeError("Super expression must either be null or a function, not " + (typeof superClass === "undefined" ? "undefined" : _typeof(superClass))); - }subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; -} +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var IVPAIDAdUnit = require('./IVPAIDAdUnit').IVPAIDAdUnit; var ALL_VPAID_METHODS = Object.getOwnPropertyNames(IVPAIDAdUnit.prototype).filter(function (property) { @@ -379,23 +345,9 @@ var VPAIDAdUnit = exports.VPAIDAdUnit = function (_IVPAIDAdUnit) { },{"./IVPAIDAdUnit":1}],3:[function(require,module,exports){ 'use strict'; -var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); - } - }return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; - }; -}(); - -function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -} +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -var swfobject = require('swfobject'); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var JSFlashBridge = require('./jsFlashBridge').JSFlashBridge; var VPAIDAdUnit = require('./VPAIDAdUnit').VPAIDAdUnit; @@ -405,15 +357,10 @@ var callbackTimeout = require('./utils').callbackTimeout; var isPositiveInt = require('./utils').isPositiveInt; var createElementWithID = require('./utils').createElementWithID; var uniqueVPAID = require('./utils').unique('vpaid'); -var createFlashTester = require('./flashTester.js').createFlashTester; var ERROR = 'error'; var FLASH_VERSION = '10.1.0'; -var flashTester = { isSupported: function isSupported() { - return true; - } }; // if the runFlashTest is not run the flashTester will always return true - var VPAIDFLASHClient = function () { function VPAIDFLASHClient(vpaidParentEl, callback) { var swfConfig = arguments.length <= 2 || arguments[2] === undefined ? { data: 'VPAIDFlash.swf', width: 800, height: 400 } : arguments[2]; @@ -425,7 +372,9 @@ var VPAIDFLASHClient = function () { _classCallCheck(this, VPAIDFLASHClient); - var me = this; + if (!VPAIDFLASHClient.hasExternalDependencies()) { + return onError('no swfobject in global scope. check: https://github.com/swfobject/swfobject or https://code.google.com/p/swfobject/'); + } this._vpaidParentEl = vpaidParentEl; this._flashID = uniqueVPAID(); @@ -435,7 +384,7 @@ var VPAIDFLASHClient = function () { swfConfig.width = isPositiveInt(swfConfig.width, 800); swfConfig.height = isPositiveInt(swfConfig.height, 400); - createElementWithID(vpaidParentEl, this._flashID, true); + createElementWithID(vpaidParentEl, this._flashID); params.movie = swfConfig.data; params.FlashVars = 'flashid=' + this._flashID + '&handler=' + JSFlashBridge.VPAID_FLASH_HANDLER + '&debug=' + vpaidOptions.debug + '&salign=' + params.salign; @@ -463,7 +412,7 @@ var VPAIDFLASHClient = function () { setTimeout(function () { callback(new Error(error)); }, 0); - return me; + return this; } } @@ -552,16 +501,16 @@ var VPAIDFLASHClient = function () { }(); setStaticProperty('isSupported', function () { - return swfobject.hasFlashPlayerVersion(FLASH_VERSION) && flashTester.isSupported(); -}, true); + return VPAIDFLASHClient.hasExternalDependencies() && swfobject.hasFlashPlayerVersion(FLASH_VERSION); +}); -setStaticProperty('runFlashTest', function (swfConfig) { - flashTester = createFlashTester(document.body, swfConfig); +setStaticProperty('hasExternalDependencies', function () { + return !!window.swfobject; }); function $throwIfDestroyed() { if (this._destroyed) { - throw new Error('VPAIDFlashToJS is destroyed!'); + throw new error('VPAIDFlashToJS is destroyed!'); } } @@ -573,125 +522,26 @@ function $loadPendedAdUnit() { } function setStaticProperty(propertyName, value) { - var writable = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2]; - Object.defineProperty(VPAIDFLASHClient, propertyName, { - writable: writable, + writable: false, configurable: false, value: value }); } -VPAIDFLASHClient.swfobject = swfobject; - +window.VPAIDFLASHClient = VPAIDFLASHClient; module.exports = VPAIDFLASHClient; -},{"./VPAIDAdUnit":2,"./flashTester.js":4,"./jsFlashBridge":5,"./utils":8,"swfobject":14}],4:[function(require,module,exports){ +},{"./VPAIDAdUnit":2,"./jsFlashBridge":4,"./utils":7}],4:[function(require,module,exports){ 'use strict'; -var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); - } - }return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; - }; -}(); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); Object.defineProperty(exports, "__esModule", { value: true }); -function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -} - -var swfobject = require('swfobject'); - -var FLASH_TEST = 'vpaid_video_flash_tester'; -var FLASH_TEST_EL = 'vpaid_video_flash_tester_el'; -var JSFlashBridge = require('./jsFlashBridge').JSFlashBridge; -var utils = require('./utils'); -var MultipleValuesRegistry = require('./registry').MultipleValuesRegistry; - -var FlashTester = function () { - function FlashTester(parent) { - var _this = this; - - var swfConfig = arguments.length <= 1 || arguments[1] === undefined ? { data: 'VPAIDFlash.swf', width: 800, height: 400 } : arguments[1]; - - _classCallCheck(this, FlashTester); - - this.parentEl = utils.createElementWithID(parent, FLASH_TEST_EL); // some browsers create global variables using the element id http://stackoverflow.com/questions/3434278/do-dom-tree-elements-with-ids-become-global-variables - utils.hideFlashEl(this.parentEl); - var params = {}; - params.movie = swfConfig.data; - params.FlashVars = 'flashid=' + FLASH_TEST_EL + '&handler=' + JSFlashBridge.VPAID_FLASH_HANDLER; - - this.el = swfobject.createSWF(swfConfig, params, FLASH_TEST_EL); - this._handlers = new MultipleValuesRegistry(); - this._isSupported = false; - if (this.el) { - utils.hideFlashEl(this.el); - this._flash = new JSFlashBridge(this.el, swfConfig.data, FLASH_TEST_EL, 400, 400, function () { - var support = true; - _this._isSupported = support; - _this._handlers.get('change').forEach(function (callback) { - setTimeout(function () { - callback('change', support); - }, 0); - }); - }); - } - } - - _createClass(FlashTester, [{ - key: 'isSupported', - value: function isSupported() { - return this._isSupported; - } - }, { - key: 'on', - value: function on(eventName, callback) { - this._handlers.add(eventName, callback); - } - }]); - - return FlashTester; -}(); - -var createFlashTester = exports.createFlashTester = function createFlashTester(el, swfConfig) { - if (!window[FLASH_TEST]) { - window[FLASH_TEST] = new FlashTester(el, swfConfig); - } - return window[FLASH_TEST]; -}; - -},{"./jsFlashBridge":5,"./registry":7,"./utils":8,"swfobject":14}],5:[function(require,module,exports){ -'use strict'; - -var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); - } - }return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; - }; -}(); - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -} +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var unique = require('./utils').unique; var isPositiveInt = require('./utils').isPositiveInt; @@ -940,7 +790,7 @@ window[VPAID_FLASH_HANDLER] = function (flashID, typeID, typeName, callbackID, e } }; -},{"./jsFlashBridgeRegistry":6,"./registry":7,"./utils":8}],6:[function(require,module,exports){ +},{"./jsFlashBridgeRegistry":5,"./registry":6,"./utils":7}],5:[function(require,module,exports){ 'use strict'; var SingleValueRegistry = require('./registry').SingleValueRegistry; @@ -973,28 +823,16 @@ Object.defineProperty(JSFlashBridgeRegistry, 'removeInstanceByID', { module.exports = JSFlashBridgeRegistry; -},{"./registry":7}],7:[function(require,module,exports){ +},{"./registry":6}],6:[function(require,module,exports){ 'use strict'; -var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); - } - }return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; - }; -}(); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); Object.defineProperty(exports, "__esModule", { value: true }); -function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -} +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var MultipleValuesRegistry = exports.MultipleValuesRegistry = function () { function MultipleValuesRegistry() { @@ -1149,7 +987,7 @@ var SingleValueRegistry = exports.SingleValueRegistry = function () { return SingleValueRegistry; }(); -},{}],8:[function(require,module,exports){ +},{}],7:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { @@ -1161,7 +999,6 @@ exports.callbackTimeout = callbackTimeout; exports.createElementWithID = createElementWithID; exports.isPositiveInt = isPositiveInt; exports.stringEndsWith = stringEndsWith; -exports.hideFlashEl = hideFlashEl; function unique(prefix) { var count = -1; return function (f) { @@ -1186,13 +1023,9 @@ function callbackTimeout(timer, onSuccess, onTimeout) { } function createElementWithID(parent, id) { - var cleanContent = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2]; - var nEl = document.createElement('div'); nEl.id = id; - if (cleanContent) { - parent.innerHTML = ''; - } + parent.innerHTML = ''; parent.appendChild(nEl); return nEl; } @@ -1218,16 +1051,7 @@ function stringEndsWith(string, search) { return endsWith.call(string, search); } -function hideFlashEl(el) { - // can't use display none or visibility none because will block flash in some browsers - el.style.position = 'absolute'; - el.style.left = '-1px'; - el.style.top = '-1px'; - el.style.width = '1px'; - el.style.height = '1px'; -} - -},{}],9:[function(require,module,exports){ +},{}],8:[function(require,module,exports){ 'use strict'; var METHODS = [ @@ -1514,7 +1338,7 @@ function addStaticToInterface(Interface, name, value) { } -},{}],10:[function(require,module,exports){ +},{}],9:[function(require,module,exports){ 'use strict'; var IVPAIDAdUnit = require('./IVPAIDAdUnit'); @@ -1745,23 +1569,17 @@ function callOrTriggerEvent(callback, subscribers, error, result) { module.exports = VPAIDAdUnit; -},{"./IVPAIDAdUnit":9,"./subscriber":12,"./utils":13}],11:[function(require,module,exports){ +},{"./IVPAIDAdUnit":8,"./subscriber":11,"./utils":12}],10:[function(require,module,exports){ 'use strict'; var utils = require('./utils'); var unique = utils.unique('vpaidIframe'); var VPAIDAdUnit = require('./VPAIDAdUnit'); -var defaultTemplate = '' + - '' + - '' + - '
' + - '' + - '' + - '' + - ''; +var defaultTemplate = ''; +defaultTemplate += '
'; var AD_STOPPED = 'AdStopped'; @@ -1795,6 +1613,7 @@ function VPAIDHTML5Client(el, video, templateConfig, vpaidOptions) { template: templateConfig.template || defaultTemplate, extraOptions: templateConfig.extraOptions || {} }; + } /** @@ -1827,18 +1646,15 @@ VPAIDHTML5Client.prototype.isDestroyed = function isDestroyed() { VPAIDHTML5Client.prototype.loadAdUnit = function loadAdUnit(adURL, callback) { $throwIfDestroyed.call(this); $unloadPreviousAdUnit.call(this); - var that = this; var frame = utils.createIframeWithContent( this._frameContainer, this._templateConfig.template, utils.extend({ iframeURL_JS: adURL, - iframeID: this.getID(), - origin: getOrigin() + iframeID: this.getID() }, this._templateConfig.extraOptions) ); - this._frame = frame; this._onLoad = utils.callbackTimeout( @@ -1852,31 +1668,31 @@ VPAIDHTML5Client.prototype.loadAdUnit = function loadAdUnit(adURL, callback) { function onLoad (e) { /*jshint validthis: false */ //don't clear timeout - if (e.origin !== getOrigin()) return; + if (e.origin !== window.location.origin) return; var result = JSON.parse(e.data); //don't clear timeout - if (result.id !== that.getID()) return; + if (result.id !== this.getID()) return; var adUnit, error, createAd; - if (!that._frame.contentWindow) { + if (!this._frame.contentWindow) { error = 'the iframe is not anymore in the DOM tree'; } else { - createAd = that._frame.contentWindow.getVPAIDAd; + createAd = this._frame.contentWindow.getVPAIDAd; error = utils.validate(typeof createAd === 'function', 'the ad didn\'t return a function to create an ad'); } if (!error) { - var adEl = that._frame.contentWindow.document.querySelector('.ad-element'); - adUnit = new VPAIDAdUnit(createAd(), adEl, that._videoEl, that._frame); - adUnit.subscribe(AD_STOPPED, $adDestroyed.bind(that)); + var adEl = this._frame.contentWindow.document.querySelector('.ad-element'); + adUnit = new VPAIDAdUnit(createAd(), adEl, this._videoEl, this._frame); + adUnit.subscribe(AD_STOPPED, $adDestroyed.bind(this)); error = utils.validate(adUnit.isValidVPAIDAd(), 'the add is not fully complaint with VPAID specification'); } - that._adUnit = adUnit; - $destroyLoadListener.call(that); + this._adUnit = adUnit; + $destroyLoadListener.call(this); callback(error, error ? null : adUnit); //clear timeout @@ -1964,22 +1780,11 @@ function $throwIfDestroyed() { } } -function getOrigin() { - if( window.location.origin ) { - return window.location.origin; - } - else { - return window.location.protocol + "//" + - window.location.hostname + - (window.location.port ? ':' + window.location.port: ''); - } -} - module.exports = VPAIDHTML5Client; window.VPAIDHTML5Client = VPAIDHTML5Client; -},{"./VPAIDAdUnit":10,"./utils":13}],12:[function(require,module,exports){ +},{"./VPAIDAdUnit":9,"./utils":12}],11:[function(require,module,exports){ 'use strict'; function Subscriber() { @@ -1987,14 +1792,12 @@ function Subscriber() { } Subscriber.prototype.subscribe = function subscribe(handler, eventName, context) { - if (!this.isHandlerAttached(handler, eventName)) { - this.get(eventName).push({handler: handler, context: context, eventName: eventName}); - } + this.get(eventName).push({handler: handler, context: context}); }; Subscriber.prototype.unsubscribe = function unsubscribe(handler, eventName) { this._subscribers[eventName] = this.get(eventName).filter(function (subscriber) { - return handler !== subscriber.handler; + return handler === subscriber.handler; }); }; @@ -2004,12 +1807,9 @@ Subscriber.prototype.unsubscribeAll = function unsubscribeAll() { Subscriber.prototype.trigger = function(eventName, data) { var that = this; - var subscribers = this.get(eventName) - .concat(this.get('*')); - - subscribers.forEach(function (subscriber) { + that.get(eventName).forEach(function (subscriber) { setTimeout(function () { - if (that.isHandlerAttached(subscriber.handler, subscriber.eventName)) { + if (that.get(eventName)) { subscriber.handler.call(subscriber.context, data); } }, 0); @@ -2017,10 +1817,7 @@ Subscriber.prototype.trigger = function(eventName, data) { }; Subscriber.prototype.triggerSync = function(eventName, data) { - var subscribers = this.get(eventName) - .concat(this.get('*')); - - subscribers.forEach(function (subscriber) { + this.get(eventName).forEach(function (subscriber) { subscriber.handler.call(subscriber.context, data); }); }; @@ -2032,16 +1829,10 @@ Subscriber.prototype.get = function get(eventName) { return this._subscribers[eventName]; }; -Subscriber.prototype.isHandlerAttached = function isHandlerAttached(handler, eventName) { - return this.get(eventName).some(function(subscriber) { - return handler === subscriber.handler; - }) -}; - module.exports = Subscriber; -},{}],13:[function(require,module,exports){ +},{}],12:[function(require,module,exports){ 'use strict'; /** @@ -2125,7 +1916,7 @@ function createElementInEl(parent, tagName, id) { * @param {object} data */ function createIframeWithContent(parent, template, data) { - var iframe = createIframe(parent, null, data.zIndex); + var iframe = createIframe(parent); if (!setIframeContent(iframe, simpleTemplate(template, data))) return; return iframe; } @@ -2136,7 +1927,7 @@ function createIframeWithContent(parent, template, data) { * @param {HTMLElement} parent * @param {string} url */ -function createIframe(parent, url, zIndex) { +function createIframe(parent, url) { var nEl = document.createElement('iframe'); nEl.src = url || 'about:blank'; nEl.marginWidth = '0'; @@ -2150,11 +1941,6 @@ function createIframe(parent, url, zIndex) { nEl.style.margin = '0px'; nEl.style.padding = '0px'; nEl.style.border = 'none'; - - if(zIndex){ - nEl.style.zIndex = zIndex; - } - nEl.setAttribute('SCROLLING','NO'); parent.innerHTML = ''; parent.appendChild(nEl); @@ -2232,838 +2018,7 @@ module.exports = { }; -},{}],14:[function(require,module,exports){ -/*! SWFObject v2.3.20130521 - is released under the MIT License -*/ - -/* global ActiveXObject: false */ - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - // AMD - define(factory); - } else if (typeof module === 'object' && module.exports) { - // Node, CommonJS-like - module.exports = factory(); - } else { - // Browser globals (root is window) - root.swfobject = factory(); - } -}(this, function () { - - var UNDEF = "undefined", - OBJECT = "object", - SHOCKWAVE_FLASH = "Shockwave Flash", - SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash", - FLASH_MIME_TYPE = "application/x-shockwave-flash", - EXPRESS_INSTALL_ID = "SWFObjectExprInst", - ON_READY_STATE_CHANGE = "onreadystatechange", - - win = window, - doc = document, - nav = navigator, - - plugin = false, - domLoadFnArr = [], - regObjArr = [], - objIdArr = [], - listenersArr = [], - storedFbContent, - storedFbContentId, - storedCallbackFn, - storedCallbackObj, - isDomLoaded = false, - isExpressInstallActive = false, - dynamicStylesheet, - dynamicStylesheetMedia, - autoHideShow = true, - encodeURIEnabled = false, - - /* Centralized function for browser feature detection - - User agent string detection is only used when no good alternative is possible - - Is executed directly for optimal performance - */ - ua = function () { - var w3cdom = typeof doc.getElementById !== UNDEF && typeof doc.getElementsByTagName !== UNDEF && typeof doc.createElement !== UNDEF, - u = nav.userAgent.toLowerCase(), - p = nav.platform.toLowerCase(), - windows = p ? /win/.test(p) : /win/.test(u), - mac = p ? /mac/.test(p) : /mac/.test(u), - webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, // returns either the webkit version or false if not webkit - ie = nav.appName === "Microsoft Internet Explorer", - playerVersion = [0, 0, 0], - d = null; - if (typeof nav.plugins !== UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] === OBJECT) { - d = nav.plugins[SHOCKWAVE_FLASH].description; - // nav.mimeTypes["application/x-shockwave-flash"].enabledPlugin indicates whether plug-ins are enabled or disabled in Safari 3+ - if (d && (typeof nav.mimeTypes !== UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { - plugin = true; - ie = false; // cascaded feature detection for Internet Explorer - d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1"); - playerVersion[0] = toInt(d.replace(/^(.*)\..*$/, "$1")); - playerVersion[1] = toInt(d.replace(/^.*\.(.*)\s.*$/, "$1")); - playerVersion[2] = /[a-zA-Z]/.test(d) ? toInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1")) : 0; - } - } - else if (typeof win.ActiveXObject !== UNDEF) { - try { - var a = new ActiveXObject(SHOCKWAVE_FLASH_AX); - if (a) { // a will return null when ActiveX is disabled - d = a.GetVariable("$version"); - if (d) { - ie = true; // cascaded feature detection for Internet Explorer - d = d.split(" ")[1].split(","); - playerVersion = [toInt(d[0]), toInt(d[1]), toInt(d[2])]; - } - } - } - catch (e) {} - } - return {w3: w3cdom, pv: playerVersion, wk: webkit, ie: ie, win: windows, mac: mac}; - }(), - - /* Cross-browser onDomLoad - - Will fire an event as soon as the DOM of a web page is loaded - - Internet Explorer workaround based on Diego Perini's solution: http://javascript.nwbox.com/IEContentLoaded/ - - Regular onload serves as fallback - */ - onDomLoad = function () { - if (!ua.w3) { return; } - if ((typeof doc.readyState !== UNDEF && (doc.readyState === "complete" || doc.readyState === "interactive")) || (typeof doc.readyState === UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) { // function is fired after onload, e.g. when script is inserted dynamically - callDomLoadFunctions(); - } - if (!isDomLoaded) { - if (typeof doc.addEventListener !== UNDEF) { - doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false); - } - if (ua.ie) { - doc.attachEvent(ON_READY_STATE_CHANGE, function detach() { - if (doc.readyState === "complete") { - doc.detachEvent(ON_READY_STATE_CHANGE, detach); - callDomLoadFunctions(); - } - }); - if (win == top) { // if not inside an iframe - (function checkDomLoadedIE() { - if (isDomLoaded) { return; } - try { - doc.documentElement.doScroll("left"); - } - catch (e) { - setTimeout(checkDomLoadedIE, 0); - return; - } - callDomLoadFunctions(); - }()); - } - } - if (ua.wk) { - (function checkDomLoadedWK() { - if (isDomLoaded) { return; } - if (!/loaded|complete/.test(doc.readyState)) { - setTimeout(checkDomLoadedWK, 0); - return; - } - callDomLoadFunctions(); - }()); - } - } - }(); - - function callDomLoadFunctions() { - if (isDomLoaded || !document.getElementsByTagName("body")[0]) { return; } - try { // test if we can really add/remove elements to/from the DOM; we don't want to fire it too early - var t, span = createElement("span"); - span.style.display = "none"; //hide the span in case someone has styled spans via CSS - t = doc.getElementsByTagName("body")[0].appendChild(span); - t.parentNode.removeChild(t); - t = null; //clear the variables - span = null; - } - catch (e) { return; } - isDomLoaded = true; - var dl = domLoadFnArr.length; - for (var i = 0; i < dl; i++) { - domLoadFnArr[i](); - } - } - - function addDomLoadEvent(fn) { - if (isDomLoaded) { - fn(); - } - else { - domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+ - } - } - - /* Cross-browser onload - - Based on James Edwards' solution: http://brothercake.com/site/resources/scripts/onload/ - - Will fire an event as soon as a web page including all of its assets are loaded - */ - function addLoadEvent(fn) { - if (typeof win.addEventListener !== UNDEF) { - win.addEventListener("load", fn, false); - } - else if (typeof doc.addEventListener !== UNDEF) { - doc.addEventListener("load", fn, false); - } - else if (typeof win.attachEvent !== UNDEF) { - addListener(win, "onload", fn); - } - else if (typeof win.onload === "function") { - var fnOld = win.onload; - win.onload = function () { - fnOld(); - fn(); - }; - } - else { - win.onload = fn; - } - } - - /* Detect the Flash Player version for non-Internet Explorer browsers - - Detecting the plug-in version via the object element is more precise than using the plugins collection item's description: - a. Both release and build numbers can be detected - b. Avoid wrong descriptions by corrupt installers provided by Adobe - c. Avoid wrong descriptions by multiple Flash Player entries in the plugin Array, caused by incorrect browser imports - - Disadvantage of this method is that it depends on the availability of the DOM, while the plugins collection is immediately available - */ - function testPlayerVersion() { - var b = doc.getElementsByTagName("body")[0]; - var o = createElement(OBJECT); - o.setAttribute("style", "visibility: hidden;"); - o.setAttribute("type", FLASH_MIME_TYPE); - var t = b.appendChild(o); - if (t) { - var counter = 0; - (function checkGetVariable() { - if (typeof t.GetVariable !== UNDEF) { - try { - var d = t.GetVariable("$version"); - if (d) { - d = d.split(" ")[1].split(","); - ua.pv = [toInt(d[0]), toInt(d[1]), toInt(d[2])]; - } - } catch (e) { - //t.GetVariable("$version") is known to fail in Flash Player 8 on Firefox - //If this error is encountered, assume FP8 or lower. Time to upgrade. - ua.pv = [8, 0, 0]; - } - } - else if (counter < 10) { - counter++; - setTimeout(checkGetVariable, 10); - return; - } - b.removeChild(o); - t = null; - matchVersions(); - }()); - } - else { - matchVersions(); - } - } - - /* Perform Flash Player and SWF version matching; static publishing only - */ - function matchVersions() { - var rl = regObjArr.length; - if (rl > 0) { - for (var i = 0; i < rl; i++) { // for each registered object element - var id = regObjArr[i].id; - var cb = regObjArr[i].callbackFn; - var cbObj = {success: false, id: id}; - if (ua.pv[0] > 0) { - var obj = getElementById(id); - if (obj) { - if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { // Flash Player version >= published SWF version: Houston, we have a match! - setVisibility(id, true); - if (cb) { - cbObj.success = true; - cbObj.ref = getObjectById(id); - cbObj.id = id; - cb(cbObj); - } - } - else if (regObjArr[i].expressInstall && canExpressInstall()) { // show the Adobe Express Install dialog if set by the web page author and if supported - var att = {}; - att.data = regObjArr[i].expressInstall; - att.width = obj.getAttribute("width") || "0"; - att.height = obj.getAttribute("height") || "0"; - if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); } - if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); } - // parse HTML object param element's name-value pairs - var par = {}; - var p = obj.getElementsByTagName("param"); - var pl = p.length; - for (var j = 0; j < pl; j++) { - if (p[j].getAttribute("name").toLowerCase() !== "movie") { - par[p[j].getAttribute("name")] = p[j].getAttribute("value"); - } - } - showExpressInstall(att, par, id, cb); - } - else { // Flash Player and SWF version mismatch or an older Webkit engine that ignores the HTML object element's nested param elements: display fallback content instead of SWF - displayFbContent(obj); - if (cb) { cb(cbObj); } - } - } - } - else { // if no Flash Player is installed or the fp version cannot be detected we let the HTML object element do its job (either show a SWF or fallback content) - setVisibility(id, true); - if (cb) { - var o = getObjectById(id); // test whether there is an HTML object element or not - if (o && typeof o.SetVariable !== UNDEF) { - cbObj.success = true; - cbObj.ref = o; - cbObj.id = o.id; - } - cb(cbObj); - } - } - } - } - } - - /* Main function - - Will preferably execute onDomLoad, otherwise onload (as a fallback) - */ - domLoadFnArr[0] = function () { - if (plugin) { - testPlayerVersion(); - } - else { - matchVersions(); - } - }; - - function getObjectById(objectIdStr) { - var r = null, - o = getElementById(objectIdStr); - - if (o && o.nodeName.toUpperCase() === "OBJECT") { - //If targeted object is valid Flash file - if (typeof o.SetVariable !== UNDEF) { - r = o; - } else { - //If SetVariable is not working on targeted object but a nested object is - //available, assume classic nested object markup. Return nested object. - - //If SetVariable is not working on targeted object and there is no nested object, - //return the original object anyway. This is probably new simplified markup. - - r = o.getElementsByTagName(OBJECT)[0] || o; - } - } - - return r; - } - - /* Requirements for Adobe Express Install - - only one instance can be active at a time - - fp 6.0.65 or higher - - Win/Mac OS only - - no Webkit engines older than version 312 - */ - function canExpressInstall() { - return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312); - } - - /* Show the Adobe Express Install dialog - - Reference: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75 - */ - function showExpressInstall(att, par, replaceElemIdStr, callbackFn) { - - var obj = getElementById(replaceElemIdStr); - - //Ensure that replaceElemIdStr is really a string and not an element - replaceElemIdStr = getId(replaceElemIdStr); - - isExpressInstallActive = true; - storedCallbackFn = callbackFn || null; - storedCallbackObj = {success: false, id: replaceElemIdStr}; - - if (obj) { - if (obj.nodeName.toUpperCase() === "OBJECT") { // static publishing - storedFbContent = abstractFbContent(obj); - storedFbContentId = null; - } - else { // dynamic publishing - storedFbContent = obj; - storedFbContentId = replaceElemIdStr; - } - att.id = EXPRESS_INSTALL_ID; - if (typeof att.width === UNDEF || (!/%$/.test(att.width) && toInt(att.width) < 310)) { att.width = "310"; } - if (typeof att.height === UNDEF || (!/%$/.test(att.height) && toInt(att.height) < 137)) { att.height = "137"; } - var pt = ua.ie ? "ActiveX" : "PlugIn", - fv = "MMredirectURL=" + encodeURIComponent(win.location.toString().replace(/&/g, "%26")) + "&MMplayerType=" + pt + "&MMdoctitle=" + encodeURIComponent(doc.title.slice(0, 47) + " - Flash Player Installation"); - if (typeof par.flashvars !== UNDEF) { - par.flashvars += "&" + fv; - } - else { - par.flashvars = fv; - } - // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it, - // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work - if (ua.ie && obj.readyState != 4) { - var newObj = createElement("div"); - replaceElemIdStr += "SWFObjectNew"; - newObj.setAttribute("id", replaceElemIdStr); - obj.parentNode.insertBefore(newObj, obj); // insert placeholder div that will be replaced by the object element that loads expressinstall.swf - obj.style.display = "none"; - removeSWF(obj); //removeSWF accepts elements now - } - createSWF(att, par, replaceElemIdStr); - } - } - - /* Functions to abstract and display fallback content - */ - function displayFbContent(obj) { - if (ua.ie && obj.readyState != 4) { - // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it, - // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work - obj.style.display = "none"; - var el = createElement("div"); - obj.parentNode.insertBefore(el, obj); // insert placeholder div that will be replaced by the fallback content - el.parentNode.replaceChild(abstractFbContent(obj), el); - removeSWF(obj); //removeSWF accepts elements now - } - else { - obj.parentNode.replaceChild(abstractFbContent(obj), obj); - } - } - - function abstractFbContent(obj) { - var ac = createElement("div"); - if (ua.win && ua.ie) { - ac.innerHTML = obj.innerHTML; - } - else { - var nestedObj = obj.getElementsByTagName(OBJECT)[0]; - if (nestedObj) { - var c = nestedObj.childNodes; - if (c) { - var cl = c.length; - for (var i = 0; i < cl; i++) { - if (!(c[i].nodeType == 1 && c[i].nodeName === "PARAM") && !(c[i].nodeType == 8)) { - ac.appendChild(c[i].cloneNode(true)); - } - } - } - } - } - return ac; - } - - function createIeObject(url, paramStr) { - var div = createElement("div"); - div.innerHTML = "" + paramStr + ""; - return div.firstChild; - } - - /* Cross-browser dynamic SWF creation - */ - function createSWF(attObj, parObj, id) { - var r, el = getElementById(id); - id = getId(id); // ensure id is truly an ID and not an element - - if (ua.wk && ua.wk < 312) { return r; } - - if (el) { - var o = (ua.ie) ? createElement("div") : createElement(OBJECT), - attr, - attrLower, - param; - - if (typeof attObj.id === UNDEF) { // if no 'id' is defined for the object element, it will inherit the 'id' from the fallback content - attObj.id = id; - } - - //Add params - for (param in parObj) { - //filter out prototype additions from other potential libraries and IE specific param element - if (parObj.hasOwnProperty(param) && param.toLowerCase() !== "movie") { - createObjParam(o, param, parObj[param]); - } - } - - //Create IE object, complete with param nodes - if (ua.ie) { o = createIeObject(attObj.data, o.innerHTML); } - - //Add attributes to object - for (attr in attObj) { - if (attObj.hasOwnProperty(attr)) { // filter out prototype additions from other potential libraries - attrLower = attr.toLowerCase(); - - // 'class' is an ECMA4 reserved keyword - if (attrLower === "styleclass") { - o.setAttribute("class", attObj[attr]); - } else if (attrLower !== "classid" && attrLower !== "data") { - o.setAttribute(attr, attObj[attr]); - } - } - } - - if (ua.ie) { - objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on unload (dynamic publishing only) - } else { - o.setAttribute("type", FLASH_MIME_TYPE); - o.setAttribute("data", attObj.data); - } - - el.parentNode.replaceChild(o, el); - r = o; - } - - return r; - } - - function createObjParam(el, pName, pValue) { - var p = createElement("param"); - p.setAttribute("name", pName); - p.setAttribute("value", pValue); - el.appendChild(p); - } - - /* Cross-browser SWF removal - - Especially needed to safely and completely remove a SWF in Internet Explorer - */ - function removeSWF(id) { - var obj = getElementById(id); - if (obj && obj.nodeName.toUpperCase() === "OBJECT") { - if (ua.ie) { - obj.style.display = "none"; - (function removeSWFInIE() { - if (obj.readyState == 4) { - //This step prevents memory leaks in Internet Explorer - for (var i in obj) { - if (typeof obj[i] === "function") { - obj[i] = null; - } - } - obj.parentNode.removeChild(obj); - } else { - setTimeout(removeSWFInIE, 10); - } - }()); - } - else { - obj.parentNode.removeChild(obj); - } - } - } - - function isElement(id) { - return (id && id.nodeType && id.nodeType === 1); - } - - function getId(thing) { - return (isElement(thing)) ? thing.id : thing; - } - - /* Functions to optimize JavaScript compression - */ - function getElementById(id) { - - //Allow users to pass an element OR an element's ID - if (isElement(id)) { return id; } - - var el = null; - try { - el = doc.getElementById(id); - } - catch (e) {} - return el; - } - - function createElement(el) { - return doc.createElement(el); - } - - //To aid compression; replaces 14 instances of pareseInt with radix - function toInt(str) { - return parseInt(str, 10); - } - - /* Updated attachEvent function for Internet Explorer - - Stores attachEvent information in an Array, so on unload the detachEvent functions can be called to avoid memory leaks - */ - function addListener(target, eventType, fn) { - target.attachEvent(eventType, fn); - listenersArr[listenersArr.length] = [target, eventType, fn]; - } - - /* Flash Player and SWF content version matching - */ - function hasPlayerVersion(rv) { - rv += ""; //Coerce number to string, if needed. - var pv = ua.pv, v = rv.split("."); - v[0] = toInt(v[0]); - v[1] = toInt(v[1]) || 0; // supports short notation, e.g. "9" instead of "9.0.0" - v[2] = toInt(v[2]) || 0; - return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false; - } - - /* Cross-browser dynamic CSS creation - - Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php - */ - function createCSS(sel, decl, media, newStyle) { - var h = doc.getElementsByTagName("head")[0]; - if (!h) { return; } // to also support badly authored HTML pages that lack a head element - var m = (typeof media === "string") ? media : "screen"; - if (newStyle) { - dynamicStylesheet = null; - dynamicStylesheetMedia = null; - } - if (!dynamicStylesheet || dynamicStylesheetMedia != m) { - // create dynamic stylesheet + get a global reference to it - var s = createElement("style"); - s.setAttribute("type", "text/css"); - s.setAttribute("media", m); - dynamicStylesheet = h.appendChild(s); - if (ua.ie && typeof doc.styleSheets !== UNDEF && doc.styleSheets.length > 0) { - dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1]; - } - dynamicStylesheetMedia = m; - } - // add style rule - if (dynamicStylesheet) { - if (typeof dynamicStylesheet.addRule !== UNDEF) { - dynamicStylesheet.addRule(sel, decl); - } else if (typeof doc.createTextNode !== UNDEF) { - dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}")); - } - } - } - - function setVisibility(id, isVisible) { - if (!autoHideShow) { return; } - var v = isVisible ? "visible" : "hidden", - el = getElementById(id); - if (isDomLoaded && el) { - el.style.visibility = v; - } else if (typeof id === "string") { - createCSS("#" + id, "visibility:" + v); - } - } - - /* Filter to avoid XSS attacks - */ - function urlEncodeIfNecessary(s) { - var regex = /[\\\"<>\.;]/; - var hasBadChars = regex.exec(s) !== null; - return hasBadChars && typeof encodeURIComponent !== UNDEF ? encodeURIComponent(s) : s; - } - - /* Release memory to avoid memory leaks caused by closures, fix hanging audio/video threads and force open sockets/NetConnections to disconnect (Internet Explorer only) - */ - var cleanup = function () { - if (ua.ie) { - window.attachEvent("onunload", function () { - // remove listeners to avoid memory leaks - var ll = listenersArr.length; - for (var i = 0; i < ll; i++) { - listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]); - } - // cleanup dynamically embedded objects to fix audio/video threads and force open sockets and NetConnections to disconnect - var il = objIdArr.length; - for (var j = 0; j < il; j++) { - removeSWF(objIdArr[j]); - } - // cleanup library's main closures to avoid memory leaks - for (var k in ua) { - ua[k] = null; - } - ua = null; - for (var l in swfobject) { - swfobject[l] = null; - } - swfobject = null; - }); - } - }(); - - return { - /* Public API - - Reference: http://code.google.com/p/swfobject/wiki/documentation - */ - registerObject: function (objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) { - if (ua.w3 && objectIdStr && swfVersionStr) { - var regObj = {}; - regObj.id = objectIdStr; - regObj.swfVersion = swfVersionStr; - regObj.expressInstall = xiSwfUrlStr; - regObj.callbackFn = callbackFn; - regObjArr[regObjArr.length] = regObj; - setVisibility(objectIdStr, false); - } - else if (callbackFn) { - callbackFn({success: false, id: objectIdStr}); - } - }, - - getObjectById: function (objectIdStr) { - if (ua.w3) { - return getObjectById(objectIdStr); - } - }, - - embedSWF: function (swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) { - - var id = getId(replaceElemIdStr), - callbackObj = {success: false, id: id}; - - if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) { - setVisibility(id, false); - addDomLoadEvent(function () { - widthStr += ""; // auto-convert to string - heightStr += ""; - var att = {}; - if (attObj && typeof attObj === OBJECT) { - for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs - att[i] = attObj[i]; - } - } - att.data = swfUrlStr; - att.width = widthStr; - att.height = heightStr; - var par = {}; - if (parObj && typeof parObj === OBJECT) { - for (var j in parObj) { // copy object to avoid the use of references, because web authors often reuse parObj for multiple SWFs - par[j] = parObj[j]; - } - } - if (flashvarsObj && typeof flashvarsObj === OBJECT) { - for (var k in flashvarsObj) { // copy object to avoid the use of references, because web authors often reuse flashvarsObj for multiple SWFs - if (flashvarsObj.hasOwnProperty(k)) { - - var key = (encodeURIEnabled) ? encodeURIComponent(k) : k, - value = (encodeURIEnabled) ? encodeURIComponent(flashvarsObj[k]) : flashvarsObj[k]; - - if (typeof par.flashvars !== UNDEF) { - par.flashvars += "&" + key + "=" + value; - } - else { - par.flashvars = key + "=" + value; - } - - } - } - } - if (hasPlayerVersion(swfVersionStr)) { // create SWF - var obj = createSWF(att, par, replaceElemIdStr); - if (att.id == id) { - setVisibility(id, true); - } - callbackObj.success = true; - callbackObj.ref = obj; - callbackObj.id = obj.id; - } - else if (xiSwfUrlStr && canExpressInstall()) { // show Adobe Express Install - att.data = xiSwfUrlStr; - showExpressInstall(att, par, replaceElemIdStr, callbackFn); - return; - } - else { // show fallback content - setVisibility(id, true); - } - if (callbackFn) { callbackFn(callbackObj); } - }); - } - else if (callbackFn) { callbackFn(callbackObj); } - }, - - switchOffAutoHideShow: function () { - autoHideShow = false; - }, - - enableUriEncoding: function (bool) { - encodeURIEnabled = (typeof bool === UNDEF) ? true : bool; - }, - - ua: ua, - - getFlashPlayerVersion: function () { - return {major: ua.pv[0], minor: ua.pv[1], release: ua.pv[2]}; - }, - - hasFlashPlayerVersion: hasPlayerVersion, - - createSWF: function (attObj, parObj, replaceElemIdStr) { - if (ua.w3) { - return createSWF(attObj, parObj, replaceElemIdStr); - } - else { - return undefined; - } - }, - - showExpressInstall: function (att, par, replaceElemIdStr, callbackFn) { - if (ua.w3 && canExpressInstall()) { - showExpressInstall(att, par, replaceElemIdStr, callbackFn); - } - }, - - removeSWF: function (objElemIdStr) { - if (ua.w3) { - removeSWF(objElemIdStr); - } - }, - - createCSS: function (selStr, declStr, mediaStr, newStyleBoolean) { - if (ua.w3) { - createCSS(selStr, declStr, mediaStr, newStyleBoolean); - } - }, - - addDomLoadEvent: addDomLoadEvent, - - addLoadEvent: addLoadEvent, - - getQueryParamValue: function (param) { - var q = doc.location.search || doc.location.hash; - if (q) { - if (/\?/.test(q)) { q = q.split("?")[1]; } // strip question mark - if (!param) { - return urlEncodeIfNecessary(q); - } - var pairs = q.split("&"); - for (var i = 0; i < pairs.length; i++) { - if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) { - return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1))); - } - } - } - return ""; - }, - - // For internal usage only - expressInstallCallback: function () { - if (isExpressInstallActive) { - var obj = getElementById(EXPRESS_INSTALL_ID); - if (obj && storedFbContent) { - obj.parentNode.replaceChild(storedFbContent, obj); - if (storedFbContentId) { - setVisibility(storedFbContentId, true); - if (ua.ie) { storedFbContent.style.display = "block"; } - } - if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); } - } - isExpressInstallActive = false; - } - }, - - version: "2.3" - - }; -})); - -},{}],15:[function(require,module,exports){ +},{}],13:[function(require,module,exports){ 'use strict'; var InLine = require('./InLine'); @@ -3090,7 +2045,7 @@ Ad.prototype.initialize = function(adJTree) { }; module.exports = Ad; -},{"./InLine":18,"./Wrapper":28}],16:[function(require,module,exports){ +},{"./InLine":16,"./Wrapper":26}],14:[function(require,module,exports){ 'use strict'; var TrackingEvent = require('./TrackingEvent'); @@ -3153,7 +2108,7 @@ function Companion(companionJTree) { } module.exports = Companion; -},{"../../utils/utilityFunctions":45,"../../utils/xml":46,"./TrackingEvent":21}],17:[function(require,module,exports){ +},{"../../utils/utilityFunctions":43,"../../utils/xml":44,"./TrackingEvent":19}],15:[function(require,module,exports){ 'use strict'; var Linear = require('./Linear'); @@ -3177,46 +2132,20 @@ function Creative(creativeJTree) { if (creativeJTree.companionAds) { var companions = []; var companionAds = creativeJTree.companionAds && creativeJTree.companionAds.companion; - if (utilities.isDefined(companionAds)) { - companionAds = utilities.isArray(companionAds) ? companionAds : [companionAds]; - companionAds.forEach(function (companionData) { - companions.push(new Companion(companionData)); - }); - } + companionAds = utilities.isArray(companionAds) ? companionAds : [companionAds]; + companionAds.forEach(function (companionData) { + companions.push(new Companion(companionData)); + }); + this.companionAds = companions; } } -/** - * Returns true if the browser supports at the creative. - */ -Creative.prototype.isSupported = function(){ - if(this.linear) { - return this.linear.isSupported(); - } - - return true; -}; - -Creative.parseCreatives = function parseCreatives(creativesJTree) { - var creatives = []; - var creativesData; - if (utilities.isDefined(creativesJTree) && utilities.isDefined(creativesJTree.creative)) { - creativesData = utilities.isArray(creativesJTree.creative) ? creativesJTree.creative : [creativesJTree.creative]; - creativesData.forEach(function (creative) { - creatives.push(new Creative(creative)); - }); - } - return creatives; -}; - module.exports = Creative; - -},{"../../utils/utilityFunctions":45,"./Companion":16,"./Linear":19}],18:[function(require,module,exports){ +},{"../../utils/utilityFunctions":43,"./Companion":14,"./Linear":17}],16:[function(require,module,exports){ 'use strict'; var vastUtil = require('./vastUtil'); -var Creative = require('./Creative'); var utilities = require('../../utils/utilityFunctions'); var xml = require('../../utils/xml'); @@ -3230,7 +2159,7 @@ function InLine(inlineJTree) { this.adTitle = xml.keyValue(inlineJTree.adTitle); this.adSystem = xml.keyValue(inlineJTree.adSystem); this.impressions = vastUtil.parseImpressions(inlineJTree.impression); - this.creatives = Creative.parseCreatives(inlineJTree.creatives); + this.creatives = vastUtil.parseCreatives(inlineJTree.creatives); //Optional Fields this.description = xml.keyValue(inlineJTree.description); @@ -3258,28 +2187,8 @@ function InLine(inlineJTree) { } } - -/** - * Returns true if the browser supports all the creatives. - */ -InLine.prototype.isSupported = function(){ - var i,len; - - if(this.creatives.length === 0) { - return false; - } - - for(i = 0, len = this.creatives.length; i< len; i+=1){ - if(!this.creatives[i].isSupported()){ - return false; - } - } - return true; -}; - module.exports = InLine; - -},{"../../utils/utilityFunctions":45,"../../utils/xml":46,"./Creative":17,"./vastUtil":30}],19:[function(require,module,exports){ +},{"../../utils/utilityFunctions":43,"../../utils/xml":44,"./vastUtil":28}],17:[function(require,module,exports){ 'use strict'; var TrackingEvent = require('./TrackingEvent'); @@ -3342,26 +2251,11 @@ function Linear(linearJTree) { } } -/** - * Must return true if at least one of the MediaFiles' type is supported - */ -Linear.prototype.isSupported = function () { - var i, len; - for(i=0, len=this.mediaFiles.length; i 3 ) { - // Ignore ended event if the Ad time was not 'near' the end - // avoids issues where IOS controls could skip the Ad - return; - } - - player.off('ended', proceed); - player.off('vast.adsCancel', proceed); - player.off('vast.adSkip', proceed); - - //NOTE: if the ads get cancel we do nothing apart removing the listners + playerUtils.once(player, ['ended', 'vast.adsCancel', 'vast.adSkip'], function (evt) { if(evt.type === 'ended' || evt.type === 'vast.adSkip'){ callback(null, response); } - } + //NOTE: if the ads get cancel we do nothing + }); }); - player.play(); } }; @@ -4098,7 +2960,7 @@ VASTIntegrator.prototype._trackError = function trackError(error, response) { }; module.exports = VASTIntegrator; -},{"../../utils/async":40,"../../utils/dom":41,"../../utils/playerUtils":43,"../../utils/utilityFunctions":45,"./VASTError":23,"./VASTResponse":25,"./VASTTracker":26,"./vastUtil":30}],25:[function(require,module,exports){ +},{"../../utils/async":38,"../../utils/dom":39,"../../utils/playerUtils":41,"../../utils/utilityFunctions":43,"./VASTError":21,"./VASTResponse":23,"./VASTTracker":24,"./vastUtil":28}],23:[function(require,module,exports){ 'use strict'; var Ad = require('./Ad'); @@ -4282,7 +3144,7 @@ function appendToArray(array, items) { module.exports = VASTResponse; -},{"../../utils/utilityFunctions":45,"../../utils/xml":46,"./Ad":15,"./InLine":18,"./Linear":19,"./VideoClicks":27,"./Wrapper":28}],26:[function(require,module,exports){ +},{"../../utils/utilityFunctions":43,"../../utils/xml":44,"./Ad":13,"./InLine":16,"./Linear":17,"./VideoClicks":25,"./Wrapper":26}],24:[function(require,module,exports){ 'use strict'; var VASTError = require('./VASTError'); @@ -4503,7 +3365,7 @@ VASTTracker.prototype.trackClick = function trackClick() { module.exports = VASTTracker; -},{"../../utils/utilityFunctions":45,"./VASTError":23,"./VASTResponse":25,"./vastUtil":30}],27:[function(require,module,exports){ +},{"../../utils/utilityFunctions":43,"./VASTError":21,"./VASTResponse":23,"./vastUtil":28}],25:[function(require,module,exports){ 'use strict'; var utilities = require('../../utils/utilityFunctions'); @@ -4532,11 +3394,10 @@ function VideoClicks(videoClickJTree) { } module.exports = VideoClicks; -},{"../../utils/utilityFunctions":45,"../../utils/xml":46}],28:[function(require,module,exports){ +},{"../../utils/utilityFunctions":43,"../../utils/xml":44}],26:[function(require,module,exports){ 'use strict'; var vastUtil = require('./vastUtil'); -var Creative = require('./Creative'); var utilities = require('../../utils/utilityFunctions'); var xml = require('../../utils/xml'); @@ -4552,7 +3413,7 @@ function Wrapper(wrapperJTree) { this.VASTAdTagURI = xml.keyValue(wrapperJTree.vASTAdTagURI); //Optional elements - this.creatives = Creative.parseCreatives(wrapperJTree.creatives); + this.creatives = vastUtil.parseCreatives(wrapperJTree.creatives); this.error = xml.keyValue(wrapperJTree.error); this.extensions = wrapperJTree.extensions; @@ -4563,8 +3424,7 @@ function Wrapper(wrapperJTree) { } module.exports = Wrapper; - -},{"../../utils/utilityFunctions":45,"../../utils/xml":46,"./Creative":17,"./vastUtil":30}],29:[function(require,module,exports){ +},{"../../utils/utilityFunctions":43,"../../utils/xml":44,"./vastUtil":28}],27:[function(require,module,exports){ 'use strict'; var utilities = require('../../utils/utilityFunctions'); @@ -4628,13 +3488,11 @@ var parsers = { module.exports = parsers; -},{"../../utils/utilityFunctions":45}],30:[function(require,module,exports){ +},{"../../utils/utilityFunctions":43}],28:[function(require,module,exports){ 'use strict'; +var Creative = require('./Creative'); var utilities = require('../../utils/utilityFunctions'); -var VPAIDHTML5Tech = require('../vpaid/VPAIDHTML5Tech'); -var VPAIDFlashTech = require('../vpaid/VPAIDFlashTech'); -var VPAIDFLASHClient = require('VPAIDFLASHClient/js/VPAIDFLASHClient'); var vastUtil = { @@ -4725,6 +3583,17 @@ var vastUtil = { return []; }, + parseCreatives: function parseCreatives(creativesJTree) { + var creatives = []; + var creativesData; + if (utilities.isDefined(creativesJTree) && utilities.isDefined(creativesJTree.creative)) { + creativesData = utilities.isArray(creativesJTree.creative) ? creativesJTree.creative : [creativesJTree.creative]; + creativesData.forEach(function (creative) { + creatives.push(new Creative(creative)); + }); + } + return creatives; + }, //We assume that the progress is going to arrive in milliseconds formatProgress: function formatProgress(progress) { @@ -4739,8 +3608,8 @@ var vastUtil = { return utilities.toFixedDigits(hours, 2) + ':' + utilities.toFixedDigits(minutes, 2) + ':' + utilities.toFixedDigits(seconds, 2) + '.' + utilities.toFixedDigits(milliseconds, 3); }, - parseOffset: function parseOffset(offset, duration) { - if (isPercentage(offset)) { + parseOffset: function parseOffset(offset, duration) { + if(isPercentage(offset)){ return calculatePercentage(offset, duration); } return vastUtil.parseDuration(offset); @@ -4752,59 +3621,25 @@ var vastUtil = { } function calculatePercentage(percentStr, duration) { - if (duration) { + if(duration) { return calcPercent(duration, parseFloat(percentStr.replace('%', ''))); } return null; } - function calcPercent(quantity, percent) { + function calcPercent(quantity, percent){ return quantity * percent / 100; } }, - - //List of supported VPAID technologies - VPAID_techs: [ - VPAIDFlashTech, - VPAIDHTML5Tech - ], - isVPAID: function isVPAIDMediaFile(mediaFile) { return !!mediaFile && mediaFile.apiFramework === 'VPAID'; - }, - - findSupportedVPAIDTech: function findSupportedVPAIDTech(mimeType) { - var i, len, VPAIDTech; - - for (i = 0, len = this.VPAID_techs.length; i < len; i += 1) { - VPAIDTech = this.VPAID_techs[i]; - if (VPAIDTech.supports(mimeType)) { - return VPAIDTech; - } - } - return null; - }, - - isFlashSupported: function isFlashSupported() { - return VPAIDFLASHClient.isSupported(); - }, - - /** - * Necessary step for VPAIDFLAShClient to know if flash is supported and not blocked. - * IMPORTANT NOTE: This is an async test and needs to be run as soon as possible. - * - * @param vpaidFlashLoaderPath the path to the vpaidFlashLoader swf obj. - */ - runFlashSupportCheck: function runFlashSupportCheck(vpaidFlashLoaderPath) { - VPAIDFLASHClient.runFlashTest({data: vpaidFlashLoaderPath}); } - }; -module.exports = vastUtil; -},{"../../utils/utilityFunctions":45,"../vpaid/VPAIDFlashTech":32,"../vpaid/VPAIDHTML5Tech":33,"VPAIDFLASHClient/js/VPAIDFLASHClient":3}],31:[function(require,module,exports){ +module.exports = vastUtil; +},{"../../utils/utilityFunctions":43,"./Creative":15}],29:[function(require,module,exports){ 'use strict'; var VASTError = require('../vast/VASTError'); @@ -5027,7 +3862,7 @@ VPAIDAdUnitWrapper.prototype.setAdVolume = function(volume, cb){ module.exports = VPAIDAdUnitWrapper; -},{"../../utils/utilityFunctions":45,"../vast/VASTError":23}],32:[function(require,module,exports){ +},{"../../utils/utilityFunctions":43,"../vast/VASTError":21}],30:[function(require,module,exports){ 'use strict'; var VASTError = require('../vast/VASTError'); @@ -5108,8 +3943,7 @@ VPAIDFlashTech.prototype.unloadAdUnit = function () { }; module.exports = VPAIDFlashTech; - -},{"../../utils/dom":41,"../../utils/utilityFunctions":45,"../vast/VASTError":23,"VPAIDFLASHClient/js/VPAIDFLASHClient":3}],33:[function(require,module,exports){ +},{"../../utils/dom":39,"../../utils/utilityFunctions":43,"../vast/VASTError":21,"VPAIDFLASHClient/js/VPAIDFLASHClient":3}],31:[function(require,module,exports){ 'use strict'; var VASTError = require('../vast/VASTError'); @@ -5196,7 +4030,7 @@ VPAIDHTML5Tech.INVALID_DOM_VIDEO_EL = PREFIX + ', invalid HTMLVideoElement'; VPAIDHTML5Tech.MISSING_CALLBACK = PREFIX + ', missing valid callback'; module.exports = VPAIDHTML5Tech; -},{"../../utils/dom":41,"../../utils/utilityFunctions":45,"../vast/VASTError":23,"VPAIDHTML5Client/js/VPAIDHTML5Client":11}],34:[function(require,module,exports){ +},{"../../utils/dom":39,"../../utils/utilityFunctions":43,"../vast/VASTError":21,"VPAIDHTML5Client/js/VPAIDHTML5Client":10}],32:[function(require,module,exports){ 'use strict'; var VASTError = require('../vast/VASTError'); @@ -5205,6 +4039,8 @@ var VASTTracker = require('../vast/VASTTracker'); var vastUtil = require('../vast/vastUtil'); var VPAIDAdUnitWrapper = require('./VPAIDAdUnitWrapper'); +var VPAIDHTML5Tech = require('./VPAIDHTML5Tech'); +var VPAIDFlashTech = require('./VPAIDFlashTech'); var async = require('../../utils/async'); var dom = require('../../utils/dom'); @@ -5240,19 +4076,23 @@ function VPAIDIntegrator(player, settings) { } } -VPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) { - if (!(vastResponse instanceof VASTResponse)) { - return callback(new VASTError('on VASTIntegrator.playAd, missing required VASTResponse')); - } +//List of supported VPAID technologies +VPAIDIntegrator.techs = [ + VPAIDFlashTech, + VPAIDHTML5Tech +]; +VPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) { var that = this; + var tech; var player = this.player; - var tech = this._findSupportedTech(vastResponse, this.settings); callback = callback || utilities.noop; + if (!(vastResponse instanceof VASTResponse)) { + return callback(new VASTError('on VASTIntegrator.playAd, missing required VASTResponse')); + } - this._adUnit = null; - + tech = this._findSupportedTech(vastResponse, this.settings); dom.addClass(player.el(), 'vjs-vpaid-ad'); player.on('vast.adsCancel', triggerVpaidAdEnd); @@ -5270,7 +4110,13 @@ VPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) this._playAdUnit.bind(this), this._finishPlaying.bind(this) - ], adComplete); + ], function (error, adUnit, vastResponse) { + if (error) { + that._trackError(vastResponse); + } + player.trigger('vpaid.adEnd'); + callback(error, vastResponse); + }); this._adUnit = { _paused: true, @@ -5290,22 +4136,13 @@ VPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) } }; - } else { - var error = new VASTError('on VPAIDIntegrator.playAd, could not find a supported mediaFile', 403); - adComplete(error, this._adUnit, vastResponse); + return this._adUnit; } - return this._adUnit; + callback(new VASTError('on VPAIDIntegrator.playAd, could not find a supported mediaFile')); + return null; /*** Local functions ***/ - function adComplete(error, adUnit, vastResponse) { - if (error && vastResponse) { - that._trackError(vastResponse, error.code); - } - player.trigger('vpaid.adEnd'); - callback(error, vastResponse); - } - function triggerVpaidAdEnd(){ player.trigger('vpaid.adEnd'); } @@ -5328,12 +4165,25 @@ VPAIDIntegrator.prototype._findSupportedTech = function (vastResponse, settings) for (i = 0, len = vpaidMediaFiles.length; i < len; i += 1) { mediaFile = vpaidMediaFiles[i]; - VPAIDTech = vastUtil.findSupportedVPAIDTech(mediaFile.type); + VPAIDTech = findSupportedTech(mediaFile); if (VPAIDTech) { return new VPAIDTech(mediaFile, settings); } } return null; + + /*** Local functions ***/ + function findSupportedTech(mediafile) { + var type = mediafile.type; + var i, len, VPAIDTech; + for (i = 0, len = VPAIDIntegrator.techs.length; i < len; i += 1) { + VPAIDTech = VPAIDIntegrator.techs[i]; + if (VPAIDTech.supports(type)) { + return VPAIDTech; + } + } + return null; + } }; VPAIDIntegrator.prototype._createVPAIDAdUnitWrapper = function(adUnit, src, responseTimeout) { @@ -5715,8 +4565,8 @@ VPAIDIntegrator.prototype._finishPlaying = function (adUnit, vastResponse, next) } }; -VPAIDIntegrator.prototype._trackError = function trackError(response, errorCode) { - vastUtil.track(response.errorURLMacros, {ERRORCODE: errorCode || 901}); +VPAIDIntegrator.prototype._trackError = function trackError(response) { + vastUtil.track(response.errorURLMacros, {ERRORCODE: 901}); }; function resizeAd(player, adUnit, VIEW_MODE) { @@ -5733,7 +4583,7 @@ function logError(error) { } module.exports = VPAIDIntegrator; -},{"../../utils/async":40,"../../utils/dom":41,"../../utils/playerUtils":43,"../../utils/utilityFunctions":45,"../vast/VASTError":23,"../vast/VASTResponse":25,"../vast/VASTTracker":26,"../vast/vastUtil":30,"./VPAIDAdUnitWrapper":31}],35:[function(require,module,exports){ +},{"../../utils/async":38,"../../utils/dom":39,"../../utils/playerUtils":41,"../../utils/utilityFunctions":43,"../vast/VASTError":21,"../vast/VASTResponse":23,"../vast/VASTTracker":24,"../vast/vastUtil":28,"./VPAIDAdUnitWrapper":29,"./VPAIDFlashTech":30,"./VPAIDHTML5Tech":31}],33:[function(require,module,exports){ 'use strict'; var dom = require('../../utils/dom'); @@ -5766,7 +4616,7 @@ var AdsLabelFactory = function(baseComponent) { }; module.exports = AdsLabelFactory; -},{"../../utils/dom":41}],36:[function(require,module,exports){ +},{"../../utils/dom":39}],34:[function(require,module,exports){ 'use strict'; var baseVideoJsComponent = videojs.getComponent('Component'); @@ -5775,7 +4625,7 @@ var AdsLabel = require('./ads-label')(baseVideoJsComponent); videojs.registerComponent('AdsLabel', videojs.extend(baseVideoJsComponent, AdsLabel)); -},{"./ads-label":35}],37:[function(require,module,exports){ +},{"./ads-label":33}],35:[function(require,module,exports){ 'use strict'; /** @@ -5818,7 +4668,7 @@ var BlackPosterFactory = function(baseComponent) { }; module.exports = BlackPosterFactory; -},{}],38:[function(require,module,exports){ +},{}],36:[function(require,module,exports){ 'use strict'; var baseVideoJsComponent = videojs.getComponent('Component'); @@ -5827,7 +4677,7 @@ var BlackPoster = require('./black-poster')(baseVideoJsComponent); videojs.registerComponent('BlackPoster', videojs.extend(baseVideoJsComponent, BlackPoster)); -},{"./black-poster":37}],39:[function(require,module,exports){ +},{"./black-poster":35}],37:[function(require,module,exports){ 'use strict'; var VASTClient = require('../ads/vast/VASTClient'); @@ -5896,8 +4746,6 @@ module.exports = function VASTPlugin(options) { return trackAdError(new VASTError('on VideoJS VAST plugin, missing adTagUrl on options object')); } - vastUtil.runFlashSupportCheck(settings.vpaidFlashLoaderPath);// Necessary step for VPAIDFLASHClient to work. - playerUtils.prepareForAds(player); if (settings.playAdAlways) { @@ -6115,29 +4963,18 @@ module.exports = function VASTPlugin(options) { var previousTime = 0; var skipad_attempts = 0; - player.on('timeupdate', preventAdSeek); - player.on('ended', preventAdSkip); - + player.on('timeupdate', adTimeupdateHandler); playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel', 'vast.adError'], stopPreventManualProgress); /*** Local functions ***/ - function preventAdSkip() { - // Ignore ended event if the Ad time was not 'near' the end - // and revert time to the previous 'valid' time - if ((player.duration() - previousTime) > PROGRESS_THRESHOLD) { - player.pause(true); // this reduce the video jitter if the IOS skip button is pressed - player.play(true); // we need to trigger the play to put the video element back in a valid state - player.currentTime(previousTime); - } - } - - function preventAdSeek() { + function adTimeupdateHandler() { var currentTime = player.currentTime(); var progressDelta = Math.abs(currentTime - previousTime); + if (progressDelta > PROGRESS_THRESHOLD) { skipad_attempts += 1; if (skipad_attempts >= 2) { - player.pause(true); + player.pause(); } player.currentTime(previousTime); } else { @@ -6146,8 +4983,7 @@ module.exports = function VASTPlugin(options) { } function stopPreventManualProgress() { - player.off('timeupdate', preventAdSeek); - player.off('ended', preventAdSkip); + player.off('timeupdate', adTimeupdateHandler); } } } @@ -6171,8 +5007,7 @@ module.exports = function VASTPlugin(options) { return false; } }; - -},{"../ads/vast/VASTClient":22,"../ads/vast/VASTError":23,"../ads/vast/VASTIntegrator":24,"../ads/vast/vastUtil":30,"../ads/vpaid/VPAIDIntegrator":34,"../utils/async":40,"../utils/dom":41,"../utils/playerUtils":43,"../utils/utilityFunctions":45}],40:[function(require,module,exports){ +},{"../ads/vast/VASTClient":20,"../ads/vast/VASTError":21,"../ads/vast/VASTIntegrator":22,"../ads/vast/vastUtil":28,"../ads/vpaid/VPAIDIntegrator":32,"../utils/async":38,"../utils/dom":39,"../utils/playerUtils":41,"../utils/utilityFunctions":43}],38:[function(require,module,exports){ //Small subset of async var utilities = require('./utilityFunctions'); @@ -6259,7 +5094,7 @@ async.when = function (condition, callback) { module.exports = async; -},{"./utilityFunctions":45}],41:[function(require,module,exports){ +},{"./utilityFunctions":43}],39:[function(require,module,exports){ 'use strict'; var utilities = require('./utilityFunctions'); @@ -6475,7 +5310,7 @@ dom.getDimension = function getDimension(element) { }; module.exports = dom; -},{"./utilityFunctions":45}],42:[function(require,module,exports){ +},{"./utilityFunctions":43}],40:[function(require,module,exports){ 'use strict'; var urlUtils = require('./urlUtils'); @@ -6626,7 +5461,7 @@ module.exports = { createXhr: createXhr }; -},{"./urlUtils":44,"./utilityFunctions":45}],43:[function(require,module,exports){ +},{"./urlUtils":42,"./utilityFunctions":43}],41:[function(require,module,exports){ 'use strict'; var dom = require('./dom'); @@ -7021,7 +5856,7 @@ playerUtils.once = function once(player, events, handler) { module.exports = playerUtils; -},{"./dom":41,"./utilityFunctions":45}],44:[function(require,module,exports){ +},{"./dom":39,"./utilityFunctions":43}],42:[function(require,module,exports){ 'use strict'; var utilities = require('./utilityFunctions'); @@ -7167,7 +6002,7 @@ module.exports = { objToQueryString: objToQueryString }; -},{"./utilityFunctions":45}],45:[function(require,module,exports){ +},{"./utilityFunctions":43}],43:[function(require,module,exports){ /*jshint unused:false */ "use strict"; @@ -7495,7 +6330,7 @@ var utilities = { }; module.exports = utilities; -},{}],46:[function(require,module,exports){ +},{}],44:[function(require,module,exports){ 'use strict'; var utilities = require('./utilityFunctions'); @@ -7642,7 +6477,7 @@ xml.decode = function decodeXML(str) { }; module.exports = xml; -},{"./utilityFunctions":45}],47:[function(require,module,exports){ +},{"./utilityFunctions":43}],45:[function(require,module,exports){ 'use strict'; require('./plugin/components/ads-label_5'); @@ -7652,5 +6487,5 @@ var videoJsVAST = require('./plugin/videojs.vast.vpaid'); videojs.plugin('vastClient', videoJsVAST); -},{"./plugin/components/ads-label_5":36,"./plugin/components/black-poster_5":38,"./plugin/videojs.vast.vpaid":39}]},{},[47]) -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlERkxBU0hDbGllbnQvanMvSVZQQUlEQWRVbml0LmpzIiwiYm93ZXJfY29tcG9uZW50cy9WUEFJREZMQVNIQ2xpZW50L2pzL1ZQQUlEQWRVbml0LmpzIiwiYm93ZXJfY29tcG9uZW50cy9WUEFJREZMQVNIQ2xpZW50L2pzL1ZQQUlERkxBU0hDbGllbnQuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlERkxBU0hDbGllbnQvanMvZmxhc2hUZXN0ZXIuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlERkxBU0hDbGllbnQvanMvanNGbGFzaEJyaWRnZS5qcyIsImJvd2VyX2NvbXBvbmVudHMvVlBBSURGTEFTSENsaWVudC9qcy9qc0ZsYXNoQnJpZGdlUmVnaXN0cnkuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlERkxBU0hDbGllbnQvanMvcmVnaXN0cnkuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlERkxBU0hDbGllbnQvanMvdXRpbHMuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlESFRNTDVDbGllbnQvanMvSVZQQUlEQWRVbml0LmpzIiwiYm93ZXJfY29tcG9uZW50cy9WUEFJREhUTUw1Q2xpZW50L2pzL1ZQQUlEQWRVbml0LmpzIiwiYm93ZXJfY29tcG9uZW50cy9WUEFJREhUTUw1Q2xpZW50L2pzL1ZQQUlESFRNTDVDbGllbnQuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlESFRNTDVDbGllbnQvanMvc3Vic2NyaWJlci5qcyIsImJvd2VyX2NvbXBvbmVudHMvVlBBSURIVE1MNUNsaWVudC9qcy91dGlscy5qcyIsImJvd2VyX2NvbXBvbmVudHMvc3dmb2JqZWN0L3N3Zm9iamVjdC9zcmMvc3dmb2JqZWN0LmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvQWQuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9Db21wYW5pb24uanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9DcmVhdGl2ZS5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L0luTGluZS5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L0xpbmVhci5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L01lZGlhRmlsZS5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L1RyYWNraW5nRXZlbnQuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9WQVNUQ2xpZW50LmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvVkFTVEVycm9yLmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvVkFTVEludGVncmF0b3IuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9WQVNUUmVzcG9uc2UuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9WQVNUVHJhY2tlci5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L1ZpZGVvQ2xpY2tzLmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvV3JhcHBlci5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L3BhcnNlcnMuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC92YXN0VXRpbC5qcyIsInNyYy9zY3JpcHRzL2Fkcy92cGFpZC9WUEFJREFkVW5pdFdyYXBwZXIuanMiLCJzcmMvc2NyaXB0cy9hZHMvdnBhaWQvVlBBSURGbGFzaFRlY2guanMiLCJzcmMvc2NyaXB0cy9hZHMvdnBhaWQvVlBBSURIVE1MNVRlY2guanMiLCJzcmMvc2NyaXB0cy9hZHMvdnBhaWQvVlBBSURJbnRlZ3JhdG9yLmpzIiwic3JjL3NjcmlwdHMvcGx1Z2luL2NvbXBvbmVudHMvYWRzLWxhYmVsLmpzIiwic3JjL3NjcmlwdHMvcGx1Z2luL2NvbXBvbmVudHMvYWRzLWxhYmVsXzUuanMiLCJzcmMvc2NyaXB0cy9wbHVnaW4vY29tcG9uZW50cy9ibGFjay1wb3N0ZXIuanMiLCJzcmMvc2NyaXB0cy9wbHVnaW4vY29tcG9uZW50cy9ibGFjay1wb3N0ZXJfNS5qcyIsInNyYy9zY3JpcHRzL3BsdWdpbi92aWRlb2pzLnZhc3QudnBhaWQuanMiLCJzcmMvc2NyaXB0cy91dGlscy9hc3luYy5qcyIsInNyYy9zY3JpcHRzL3V0aWxzL2RvbS5qcyIsInNyYy9zY3JpcHRzL3V0aWxzL2h0dHAuanMiLCJzcmMvc2NyaXB0cy91dGlscy9wbGF5ZXJVdGlscy5qcyIsInNyYy9zY3JpcHRzL3V0aWxzL3VybFV0aWxzLmpzIiwic3JjL3NjcmlwdHMvdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucy5qcyIsInNyYy9zY3JpcHRzL3V0aWxzL3htbC5qcyIsInNyYy9zY3JpcHRzL3ZpZGVvanNfNS52YXN0LnZwYWlkLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQUdhOzs7Ozs7Ozs7OzJDQUkwRDtnQkFBbEQsMkVBQXFCLGtCQUE2QjtnQkFBdEIsaUVBQVcsc0JBQVc7Ozs7Ozs7K0JBRzNELE9BQU8sUUFBUSxVQUFVLGdCQUEyRztnQkFBM0YscUVBQWUsRUFBQyxjQUFBLEFBQWEsaUJBQThEO2dCQUF6RCx3RUFBa0IsRUFBQyxXQUFBLEFBQVcsaUJBQTJCO2dCQUF0QixpRUFBVyxzQkFBVzs7OztpQ0FDbkksT0FBTyxRQUFRLFVBQWdDO2dCQUF0QixpRUFBVyxzQkFBVzs7OztrQ0FFMUI7Z0JBQXRCLGlFQUFXLHNCQUFXOzs7O2lDQUNEO2dCQUF0QixpRUFBVyxzQkFBVzs7OztrQ0FDQztnQkFBdEIsaUVBQVcsc0JBQVc7Ozs7bUNBQ0M7Z0JBQXRCLGlFQUFXLHNCQUFXOzs7O21DQUNBO2dCQUF0QixpRUFBVyxzQkFBVzs7OztxQ0FDRTtnQkFBdEIsaUVBQVcsc0JBQVc7Ozs7aUNBQ0o7Z0JBQXRCLGlFQUFXLHNCQUFXOzs7Ozs7O29DQUdqQixVQUFVOzs7bUNBQ1gsVUFBVTs7O29DQUNULFVBQVU7OztzQ0FDUixVQUFVOzs7NENBQ0osVUFBVTs7OzJDQUNYLFVBQVU7OztzQ0FDZixVQUFVOzs7b0NBQ1osYUFBbUM7Z0JBQXRCLGlFQUFXLHNCQUFXOzs7O29DQUNuQyxVQUFVOzs7d0NB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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3UkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4T0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzd6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdFNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JXQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdExBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2VkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6WUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0VUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIid1c2Ugc3RyaWN0JztcblxuLy9zaW1wbGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIEFQSVxuZXhwb3J0IGNsYXNzIElWUEFJREFkVW5pdCB7XG5cbiAgICAvL2FsbCBtZXRob2RzIGJlbG93XG4gICAgLy9hcmUgYXN5bmMgbWV0aG9kc1xuICAgIGhhbmRzaGFrZVZlcnNpb24ocGxheWVyVlBBSURWZXJzaW9uID0gJzIuMCcsIGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7fVxuXG4gICAgLy9jcmVhdGl2ZURhdGEgaXMgYW4gb2JqZWN0IHRvIGJlIGNvbnNpc3RlbnQgd2l0aCBWUEFJREhUTUxcbiAgICBpbml0QWQgKHdpZHRoLCBoZWlnaHQsIHZpZXdNb2RlLCBkZXNpcmVkQml0cmF0ZSwgY3JlYXRpdmVEYXRhID0ge0FkUGFyYW1ldGVyczonJ30sIGVudmlyb25tZW50VmFycyA9IHtmbGFzaFZhcnM6ICcnfSwgY2FsbGJhY2sgPSB1bmRlZmluZWQpIHt9XG4gICAgcmVzaXplQWQod2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7fVxuXG4gICAgc3RhcnRBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge31cbiAgICBzdG9wQWQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHt9XG4gICAgcGF1c2VBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge31cbiAgICByZXN1bWVBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge31cbiAgICBleHBhbmRBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge31cbiAgICBjb2xsYXBzZUFkKGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7fVxuICAgIHNraXBBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge31cblxuICAgIC8vcHJvcGVydGllcyB0aGF0IHdpbGwgYmUgdHJlYXQgYXMgYXN5bmMgbWV0aG9kc1xuICAgIGdldEFkTGluZWFyKGNhbGxiYWNrKSB7fVxuICAgIGdldEFkV2lkdGgoY2FsbGJhY2spIHt9XG4gICAgZ2V0QWRIZWlnaHQoY2FsbGJhY2spIHt9XG4gICAgZ2V0QWRFeHBhbmRlZChjYWxsYmFjaykge31cbiAgICBnZXRBZFNraXBwYWJsZVN0YXRlKGNhbGxiYWNrKSB7fVxuICAgIGdldEFkUmVtYWluaW5nVGltZShjYWxsYmFjaykge31cbiAgICBnZXRBZER1cmF0aW9uKGNhbGxiYWNrKSB7fVxuICAgIHNldEFkVm9sdW1lKHNvdW5kVm9sdW1lLCBjYWxsYmFjayA9IHVuZGVmaW5lZCkge31cbiAgICBnZXRBZFZvbHVtZShjYWxsYmFjaykge31cbiAgICBnZXRBZENvbXBhbmlvbnMoY2FsbGJhY2spIHt9XG4gICAgZ2V0QWRJY29ucyhjYWxsYmFjaykge31cbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KElWUEFJREFkVW5pdCwgJ0VWRU5UUycsIHtcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICB2YWx1ZTogW1xuICAgICAgICAnQWRMb2FkZWQnLFxuICAgICAgICAnQWRTdGFydGVkJyxcbiAgICAgICAgJ0FkU3RvcHBlZCcsXG4gICAgICAgICdBZFNraXBwZWQnLFxuICAgICAgICAnQWRTa2lwcGFibGVTdGF0ZUNoYW5nZScsIC8vIFZQQUlEIDIuMCBuZXcgZXZlbnRcbiAgICAgICAgJ0FkU2l6ZUNoYW5nZScsIC8vIFZQQUlEIDIuMCBuZXcgZXZlbnRcbiAgICAgICAgJ0FkTGluZWFyQ2hhbmdlJyxcbiAgICAgICAgJ0FkRHVyYXRpb25DaGFuZ2UnLCAvLyBWUEFJRCAyLjAgbmV3IGV2ZW50XG4gICAgICAgICdBZEV4cGFuZGVkQ2hhbmdlJyxcbiAgICAgICAgJ0FkUmVtYWluaW5nVGltZUNoYW5nZScsIC8vIFtEZXByZWNhdGVkIGluIDIuMF0gYnV0IHdpbGwgYmUgc3RpbGwgZmlyZWQgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG4gICAgICAgICdBZFZvbHVtZUNoYW5nZScsXG4gICAgICAgICdBZEltcHJlc3Npb24nLFxuICAgICAgICAnQWRWaWRlb1N0YXJ0JyxcbiAgICAgICAgJ0FkVmlkZW9GaXJzdFF1YXJ0aWxlJyxcbiAgICAgICAgJ0FkVmlkZW9NaWRwb2ludCcsXG4gICAgICAgICdBZFZpZGVvVGhpcmRRdWFydGlsZScsXG4gICAgICAgICdBZFZpZGVvQ29tcGxldGUnLFxuICAgICAgICAnQWRDbGlja1RocnUnLFxuICAgICAgICAnQWRJbnRlcmFjdGlvbicsIC8vIFZQQUlEIDIuMCBuZXcgZXZlbnRcbiAgICAgICAgJ0FkVXNlckFjY2VwdEludml0YXRpb24nLFxuICAgICAgICAnQWRVc2VyTWluaW1pemUnLFxuICAgICAgICAnQWRVc2VyQ2xvc2UnLFxuICAgICAgICAnQWRQYXVzZWQnLFxuICAgICAgICAnQWRQbGF5aW5nJyxcbiAgICAgICAgJ0FkTG9nJyxcbiAgICAgICAgJ0FkRXJyb3InXG4gICAgXVxufSk7XG5cbiIsIid1c2Ugc3RyaWN0JztcblxubGV0IElWUEFJREFkVW5pdCA9IHJlcXVpcmUoJy4vSVZQQUlEQWRVbml0JykuSVZQQUlEQWRVbml0O1xubGV0IEFMTF9WUEFJRF9NRVRIT0RTID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoSVZQQUlEQWRVbml0LnByb3RvdHlwZSkuZmlsdGVyKGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuICAgIHJldHVybiBbJ2NvbnN0cnVjdG9yJ10uaW5kZXhPZihwcm9wZXJ0eSkgPT09IC0xO1xufSk7XG5cbmV4cG9ydCBjbGFzcyBWUEFJREFkVW5pdCBleHRlbmRzIElWUEFJREFkVW5pdCB7XG4gICAgY29uc3RydWN0b3IgKGZsYXNoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuX2Rlc3Ryb3llZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9mbGFzaCA9IGZsYXNoO1xuICAgIH1cblxuICAgIF9kZXN0cm95KCkge1xuICAgICAgICB0aGlzLl9kZXN0cm95ZWQgPSB0cnVlO1xuICAgICAgICBBTExfVlBBSURfTUVUSE9EUy5mb3JFYWNoKChtZXRob2ROYW1lKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9mbGFzaC5yZW1vdmVDYWxsYmFja0J5TWV0aG9kTmFtZShtZXRob2ROYW1lKTtcbiAgICAgICAgfSk7XG4gICAgICAgIElWUEFJREFkVW5pdC5FVkVOVFMuZm9yRWFjaCgoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2ZsYXNoLm9mZkV2ZW50KGV2ZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5fZmxhc2ggPSBudWxsO1xuICAgIH1cblxuICAgIGlzRGVzdHJveWVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rlc3Ryb3llZDtcbiAgICB9XG5cbiAgICBvbihldmVudE5hbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLm9uKGV2ZW50TmFtZSwgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIG9mZihldmVudE5hbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLm9mZihldmVudE5hbWUsIGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICAvL1ZQQUlEIGludGVyZmFjZVxuICAgIGhhbmRzaGFrZVZlcnNpb24ocGxheWVyVlBBSURWZXJzaW9uID0gJzIuMCcsIGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnaGFuZHNoYWtlVmVyc2lvbicsIFtwbGF5ZXJWUEFJRFZlcnNpb25dLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGluaXRBZCAod2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGRlc2lyZWRCaXRyYXRlLCBjcmVhdGl2ZURhdGEgPSB7QWRQYXJhbWV0ZXJzOiAnJ30sIGVudmlyb25tZW50VmFycyA9IHtmbGFzaFZhcnM6ICcnfSwgY2FsbGJhY2sgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy9yZXNpemUgZWxlbWVudCB0aGF0IGhhcyB0aGUgZmxhc2ggb2JqZWN0XG4gICAgICAgIHRoaXMuX2ZsYXNoLnNldFNpemUod2lkdGgsIGhlaWdodCk7XG4gICAgICAgIGNyZWF0aXZlRGF0YSA9IGNyZWF0aXZlRGF0YSB8fCB7QWRQYXJhbWV0ZXJzOiAnJ307XG4gICAgICAgIGVudmlyb25tZW50VmFycyA9IGVudmlyb25tZW50VmFycyB8fCB7Zmxhc2hWYXJzOiAnJ307XG5cbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdpbml0QWQnLCBbdGhpcy5fZmxhc2guZ2V0V2lkdGgoKSwgdGhpcy5fZmxhc2guZ2V0SGVpZ2h0KCksIHZpZXdNb2RlLCBkZXNpcmVkQml0cmF0ZSwgY3JlYXRpdmVEYXRhLkFkUGFyYW1ldGVycyB8fCAnJywgZW52aXJvbm1lbnRWYXJzLmZsYXNoVmFycyB8fCAnJ10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgcmVzaXplQWQod2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vcmVzaXplIGVsZW1lbnQgdGhhdCBoYXMgdGhlIGZsYXNoIG9iamVjdFxuICAgICAgICB0aGlzLl9mbGFzaC5zZXRTaXplKHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgICAgIC8vcmVzaXplIGFkIGluc2lkZSB0aGUgZmxhc2hcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdyZXNpemVBZCcsIFt0aGlzLl9mbGFzaC5nZXRXaWR0aCgpLCB0aGlzLl9mbGFzaC5nZXRIZWlnaHQoKSwgdmlld01vZGVdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIHN0YXJ0QWQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdzdGFydEFkJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgc3RvcEFkKGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnc3RvcEFkJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgcGF1c2VBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ3BhdXNlQWQnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICByZXN1bWVBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ3Jlc3VtZUFkJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgZXhwYW5kQWQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdleHBhbmRBZCcsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGNvbGxhcHNlQWQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdjb2xsYXBzZUFkJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgc2tpcEFkKGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnc2tpcEFkJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICAvL3Byb3BlcnRpZXMgdGhhdCB3aWxsIGJlIHRyZWF0IGFzIGFzeW5jIG1ldGhvZHNcbiAgICBnZXRBZExpbmVhcihjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2dldEFkTGluZWFyJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgZ2V0QWRXaWR0aChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2dldEFkV2lkdGgnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBnZXRBZEhlaWdodChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2dldEFkSGVpZ2h0JywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgZ2V0QWRFeHBhbmRlZChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2dldEFkRXhwYW5kZWQnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBnZXRBZFNraXBwYWJsZVN0YXRlKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnZ2V0QWRTa2lwcGFibGVTdGF0ZScsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGdldEFkUmVtYWluaW5nVGltZShjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2dldEFkUmVtYWluaW5nVGltZScsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGdldEFkRHVyYXRpb24oY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdnZXRBZER1cmF0aW9uJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgc2V0QWRWb2x1bWUodm9sdW1lLCBjYWxsYmFjayA9IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ3NldEFkVm9sdW1lJywgW3ZvbHVtZV0sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgZ2V0QWRWb2x1bWUoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdnZXRBZFZvbHVtZScsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGdldEFkQ29tcGFuaW9ucyhjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2dldEFkQ29tcGFuaW9ucycsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGdldEFkSWNvbnMoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdnZXRBZEljb25zJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG59XG5cbiIsIid1c2Ugc3RyaWN0JztcblxuY29uc3Qgc3dmb2JqZWN0ID0gcmVxdWlyZSgnc3dmb2JqZWN0Jyk7XG5cbmNvbnN0IEpTRmxhc2hCcmlkZ2UgPSByZXF1aXJlKCcuL2pzRmxhc2hCcmlkZ2UnKS5KU0ZsYXNoQnJpZGdlO1xuY29uc3QgVlBBSURBZFVuaXQgPSByZXF1aXJlKCcuL1ZQQUlEQWRVbml0JykuVlBBSURBZFVuaXQ7XG5cbmNvbnN0IG5vb3AgPSByZXF1aXJlKCcuL3V0aWxzJykubm9vcDtcbmNvbnN0IGNhbGxiYWNrVGltZW91dCA9IHJlcXVpcmUoJy4vdXRpbHMnKS5jYWxsYmFja1RpbWVvdXQ7XG5jb25zdCBpc1Bvc2l0aXZlSW50ID0gcmVxdWlyZSgnLi91dGlscycpLmlzUG9zaXRpdmVJbnQ7XG5jb25zdCBjcmVhdGVFbGVtZW50V2l0aElEID0gcmVxdWlyZSgnLi91dGlscycpLmNyZWF0ZUVsZW1lbnRXaXRoSUQ7XG5jb25zdCB1bmlxdWVWUEFJRCA9IHJlcXVpcmUoJy4vdXRpbHMnKS51bmlxdWUoJ3ZwYWlkJyk7XG5jb25zdCBjcmVhdGVGbGFzaFRlc3RlciA9IHJlcXVpcmUoJy4vZmxhc2hUZXN0ZXIuanMnKS5jcmVhdGVGbGFzaFRlc3RlcjtcblxuY29uc3QgRVJST1IgPSAnZXJyb3InO1xuY29uc3QgRkxBU0hfVkVSU0lPTiA9ICcxMC4xLjAnO1xuXG5sZXQgZmxhc2hUZXN0ZXIgPSB7aXNTdXBwb3J0ZWQ6ICgpPT4gdHJ1ZX07IC8vIGlmIHRoZSBydW5GbGFzaFRlc3QgaXMgbm90IHJ1biB0aGUgZmxhc2hUZXN0ZXIgd2lsbCBhbHdheXMgcmV0dXJuIHRydWVcblxuY2xhc3MgVlBBSURGTEFTSENsaWVudCB7XG4gICAgY29uc3RydWN0b3IgKHZwYWlkUGFyZW50RWwsIGNhbGxiYWNrLCBzd2ZDb25maWcgPSB7ZGF0YTogJ1ZQQUlERmxhc2guc3dmJywgd2lkdGg6IDgwMCwgaGVpZ2h0OiA0MDB9LCBwYXJhbXMgPSB7IHdtb2RlOiAndHJhbnNwYXJlbnQnLCBzYWxpZ246ICd0bCcsIGFsaWduOiAnbGVmdCcsIGFsbG93U2NyaXB0QWNjZXNzOiAnYWx3YXlzJywgc2NhbGU6ICdub1NjYWxlJywgYWxsb3dGdWxsU2NyZWVuOiAndHJ1ZScsIHF1YWxpdHk6ICdoaWdoJ30sIHZwYWlkT3B0aW9ucyA9IHsgZGVidWc6IGZhbHNlLCB0aW1lb3V0OiAxMDAwMCB9KSB7XG5cbiAgICAgICAgdmFyIG1lID0gdGhpcztcblxuICAgICAgICB0aGlzLl92cGFpZFBhcmVudEVsID0gdnBhaWRQYXJlbnRFbDtcbiAgICAgICAgdGhpcy5fZmxhc2hJRCA9IHVuaXF1ZVZQQUlEKCk7XG4gICAgICAgIHRoaXMuX2Rlc3Ryb3llZCA9IGZhbHNlO1xuICAgICAgICBjYWxsYmFjayA9IGNhbGxiYWNrIHx8IG5vb3A7XG5cbiAgICAgICAgc3dmQ29uZmlnLndpZHRoID0gaXNQb3NpdGl2ZUludChzd2ZDb25maWcud2lkdGgsIDgwMCk7XG4gICAgICAgIHN3ZkNvbmZpZy5oZWlnaHQgPSBpc1Bvc2l0aXZlSW50KHN3ZkNvbmZpZy5oZWlnaHQsIDQwMCk7XG5cbiAgICAgICAgY3JlYXRlRWxlbWVudFdpdGhJRCh2cGFpZFBhcmVudEVsLCB0aGlzLl9mbGFzaElELCB0cnVlKTtcblxuICAgICAgICBwYXJhbXMubW92aWUgPSBzd2ZDb25maWcuZGF0YTtcbiAgICAgICAgcGFyYW1zLkZsYXNoVmFycyA9IGBmbGFzaGlkPSR7dGhpcy5fZmxhc2hJRH0maGFuZGxlcj0ke0pTRmxhc2hCcmlkZ2UuVlBBSURfRkxBU0hfSEFORExFUn0mZGVidWc9JHt2cGFpZE9wdGlvbnMuZGVidWd9JnNhbGlnbj0ke3BhcmFtcy5zYWxpZ259YDtcblxuICAgICAgICBpZiAoIVZQQUlERkxBU0hDbGllbnQuaXNTdXBwb3J0ZWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIG9uRXJyb3IoJ3VzZXIgZG9uXFwndCBzdXBwb3J0IGZsYXNoIG9yIGRvZXNuXFwndCBoYXZlIHRoZSBtaW5pbXVtIHJlcXVpcmVkIHZlcnNpb24gb2YgZmxhc2ggJyArIEZMQVNIX1ZFUlNJT04pO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5lbCA9IHN3Zm9iamVjdC5jcmVhdGVTV0Yoc3dmQ29uZmlnLCBwYXJhbXMsIHRoaXMuX2ZsYXNoSUQpO1xuXG4gICAgICAgIGlmICghdGhpcy5lbCkge1xuICAgICAgICAgICAgcmV0dXJuIG9uRXJyb3IoICdzd2ZvYmplY3QgZmFpbGVkIHRvIGNyZWF0ZSBvYmplY3QgaW4gZWxlbWVudCcgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBoYW5kbGVyID0gY2FsbGJhY2tUaW1lb3V0KHZwYWlkT3B0aW9ucy50aW1lb3V0LFxuICAgICAgICAgICAgKGVyciwgZGF0YSkgPT4ge1xuICAgICAgICAgICAgICAgICRsb2FkUGVuZGVkQWRVbml0LmNhbGwodGhpcyk7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyLCBkYXRhKTtcbiAgICAgICAgICAgIH0sICgpID0+IHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygndnBhaWQgZmxhc2ggbG9hZCB0aW1lb3V0ICcgKyB2cGFpZE9wdGlvbnMudGltZW91dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5fZmxhc2ggPSBuZXcgSlNGbGFzaEJyaWRnZSh0aGlzLmVsLCBzd2ZDb25maWcuZGF0YSwgdGhpcy5fZmxhc2hJRCwgc3dmQ29uZmlnLndpZHRoLCBzd2ZDb25maWcuaGVpZ2h0LCBoYW5kbGVyKTtcblxuICAgICAgICBmdW5jdGlvbiBvbkVycm9yKGVycm9yKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhuZXcgRXJyb3IoZXJyb3IpKTtcbiAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgcmV0dXJuIG1lO1xuICAgICAgICB9XG5cbiAgICB9XG5cbiAgICBkZXN0cm95ICgpIHtcbiAgICAgICAgdGhpcy5fZGVzdHJveUFkVW5pdCgpO1xuXG4gICAgICAgIGlmICh0aGlzLl9mbGFzaCkge1xuICAgICAgICAgICAgdGhpcy5fZmxhc2guZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy5fZmxhc2ggPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZWwgPSBudWxsO1xuICAgICAgICB0aGlzLl9kZXN0cm95ZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGlzRGVzdHJveWVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rlc3Ryb3llZDtcbiAgICB9XG5cbiAgICBfZGVzdHJveUFkVW5pdCgpIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuX2xvYWRMYXRlcjtcblxuICAgICAgICBpZiAodGhpcy5fYWRVbml0TG9hZCkge1xuICAgICAgICAgICAgdGhpcy5fYWRVbml0TG9hZCA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9mbGFzaC5yZW1vdmVDYWxsYmFjayh0aGlzLl9hZFVuaXRMb2FkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl9hZFVuaXQpIHtcbiAgICAgICAgICAgIHRoaXMuX2FkVW5pdC5fZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy5fYWRVbml0ID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGxvYWRBZFVuaXQoYWRVUkwsIGNhbGxiYWNrKSB7XG4gICAgICAgICR0aHJvd0lmRGVzdHJveWVkLmNhbGwodGhpcyk7XG5cbiAgICAgICAgaWYgKHRoaXMuX2FkVW5pdCkge1xuICAgICAgICAgICAgdGhpcy5fZGVzdHJveUFkVW5pdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuX2ZsYXNoLmlzUmVhZHkoKSkge1xuICAgICAgICAgICAgdGhpcy5fYWRVbml0TG9hZCA9IChlcnIsIG1lc3NhZ2UpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIWVycikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9hZFVuaXQgPSBuZXcgVlBBSURBZFVuaXQodGhpcy5fZmxhc2gpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLl9hZFVuaXRMb2FkID0gbnVsbDtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnIsIHRoaXMuX2FkVW5pdCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2xvYWRBZFVuaXQnLCBbYWRVUkxdLCB0aGlzLl9hZFVuaXRMb2FkKTtcbiAgICAgICAgfWVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fbG9hZExhdGVyID0ge3VybDogYWRVUkwsIGNhbGxiYWNrfTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVubG9hZEFkVW5pdChjYWxsYmFjayA9IHVuZGVmaW5lZCkge1xuICAgICAgICAkdGhyb3dJZkRlc3Ryb3llZC5jYWxsKHRoaXMpO1xuXG4gICAgICAgIHRoaXMuX2Rlc3Ryb3lBZFVuaXQoKTtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCd1bmxvYWRBZFVuaXQnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBnZXRGbGFzaElEKCkge1xuICAgICAgICAkdGhyb3dJZkRlc3Ryb3llZC5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdGhpcy5fZmxhc2guZ2V0Rmxhc2hJRCgpO1xuICAgIH1cbiAgICBnZXRGbGFzaFVSTCgpIHtcbiAgICAgICAgJHRocm93SWZEZXN0cm95ZWQuY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZsYXNoLmdldEZsYXNoVVJMKCk7XG4gICAgfVxufVxuXG5zZXRTdGF0aWNQcm9wZXJ0eSgnaXNTdXBwb3J0ZWQnLCAoKSA9PiB7XG4gICAgcmV0dXJuIHN3Zm9iamVjdC5oYXNGbGFzaFBsYXllclZlcnNpb24oRkxBU0hfVkVSU0lPTikgJiYgZmxhc2hUZXN0ZXIuaXNTdXBwb3J0ZWQoKTtcbn0sIHRydWUpO1xuXG5zZXRTdGF0aWNQcm9wZXJ0eSgncnVuRmxhc2hUZXN0JywgKHN3ZkNvbmZpZykgPT4ge1xuICAgIGZsYXNoVGVzdGVyID0gY3JlYXRlRmxhc2hUZXN0ZXIoZG9jdW1lbnQuYm9keSwgc3dmQ29uZmlnKTtcbn0pO1xuXG5mdW5jdGlvbiAkdGhyb3dJZkRlc3Ryb3llZCgpIHtcbiAgICBpZih0aGlzLl9kZXN0cm95ZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdWUEFJREZsYXNoVG9KUyBpcyBkZXN0cm95ZWQhJyk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiAkbG9hZFBlbmRlZEFkVW5pdCgpIHtcbiAgICBpZiAodGhpcy5fbG9hZExhdGVyKSB7XG4gICAgICAgIHRoaXMubG9hZEFkVW5pdCh0aGlzLl9sb2FkTGF0ZXIudXJsLCB0aGlzLl9sb2FkTGF0ZXIuY2FsbGJhY2spO1xuICAgICAgICBkZWxldGUgdGhpcy5fbG9hZExhdGVyO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gc2V0U3RhdGljUHJvcGVydHkocHJvcGVydHlOYW1lLCB2YWx1ZSwgd3JpdGFibGUgPSBmYWxzZSkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShWUEFJREZMQVNIQ2xpZW50LCBwcm9wZXJ0eU5hbWUsIHtcbiAgICAgICAgd3JpdGFibGU6IHdyaXRhYmxlLFxuICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICB2YWx1ZTogdmFsdWVcbiAgICB9KTtcbn1cblxuVlBBSURGTEFTSENsaWVudC5zd2ZvYmplY3QgPSBzd2ZvYmplY3Q7XG5cbm1vZHVsZS5leHBvcnRzID0gVlBBSURGTEFTSENsaWVudDtcbiIsIid1c2Ugc3RyaWN0JztcblxuY29uc3Qgc3dmb2JqZWN0ID0gcmVxdWlyZSgnc3dmb2JqZWN0Jyk7XG5cbmNvbnN0IEZMQVNIX1RFU1QgPSAndnBhaWRfdmlkZW9fZmxhc2hfdGVzdGVyJztcbmNvbnN0IEZMQVNIX1RFU1RfRUwgPSAndnBhaWRfdmlkZW9fZmxhc2hfdGVzdGVyX2VsJztcbmNvbnN0IEpTRmxhc2hCcmlkZ2UgPSByZXF1aXJlKCcuL2pzRmxhc2hCcmlkZ2UnKS5KU0ZsYXNoQnJpZGdlO1xuY29uc3QgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG5jb25zdCBNdWx0aXBsZVZhbHVlc1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9yZWdpc3RyeScpLk11bHRpcGxlVmFsdWVzUmVnaXN0cnk7XG5cbmNsYXNzIEZsYXNoVGVzdGVyIHtcbiAgICBjb25zdHJ1Y3RvcihwYXJlbnQsIHN3ZkNvbmZpZyA9IHtkYXRhOiAnVlBBSURGbGFzaC5zd2YnLCB3aWR0aDogODAwLCBoZWlnaHQ6IDQwMH0pIHtcbiAgICAgICAgdGhpcy5wYXJlbnRFbCA9IHV0aWxzLmNyZWF0ZUVsZW1lbnRXaXRoSUQocGFyZW50LCBGTEFTSF9URVNUX0VMKTsgLy8gc29tZSBicm93c2VycyBjcmVhdGUgZ2xvYmFsIHZhcmlhYmxlcyB1c2luZyB0aGUgZWxlbWVudCBpZCBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzM0MzQyNzgvZG8tZG9tLXRyZWUtZWxlbWVudHMtd2l0aC1pZHMtYmVjb21lLWdsb2JhbC12YXJpYWJsZXNcbiAgICAgICAgdXRpbHMuaGlkZUZsYXNoRWwodGhpcy5wYXJlbnRFbCk7XG4gICAgICAgIHZhciBwYXJhbXMgPSB7fTtcbiAgICAgICAgcGFyYW1zLm1vdmllID0gc3dmQ29uZmlnLmRhdGE7XG4gICAgICAgIHBhcmFtcy5GbGFzaFZhcnMgPSBgZmxhc2hpZD0ke0ZMQVNIX1RFU1RfRUx9JmhhbmRsZXI9JHtKU0ZsYXNoQnJpZGdlLlZQQUlEX0ZMQVNIX0hBTkRMRVJ9YDtcblxuICAgICAgICB0aGlzLmVsID0gc3dmb2JqZWN0LmNyZWF0ZVNXRihzd2ZDb25maWcsIHBhcmFtcywgRkxBU0hfVEVTVF9FTCk7XG4gICAgICAgIHRoaXMuX2hhbmRsZXJzID0gbmV3IE11bHRpcGxlVmFsdWVzUmVnaXN0cnkoKTtcbiAgICAgICAgdGhpcy5faXNTdXBwb3J0ZWQgPSBmYWxzZTtcbiAgICAgICAgaWYgKHRoaXMuZWwpIHtcbiAgICAgICAgICAgIHV0aWxzLmhpZGVGbGFzaEVsKHRoaXMuZWwpO1xuICAgICAgICAgICAgdGhpcy5fZmxhc2ggPSBuZXcgSlNGbGFzaEJyaWRnZSh0aGlzLmVsLCBzd2ZDb25maWcuZGF0YSwgRkxBU0hfVEVTVF9FTCwgNDAwLCA0MDAsICgpPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN1cHBvcnQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuX2lzU3VwcG9ydGVkID0gc3VwcG9ydDtcbiAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVycy5nZXQoJ2NoYW5nZScpLmZvckVhY2goKGNhbGxiYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCk9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaygnY2hhbmdlJywgc3VwcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaXNTdXBwb3J0ZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1N1cHBvcnRlZDtcbiAgICB9XG4gICAgb24oZXZlbnROYW1lLCBjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9oYW5kbGVycy5hZGQoZXZlbnROYW1lLCBjYWxsYmFjayk7XG4gICAgfVxufVxuXG5leHBvcnQgdmFyIGNyZWF0ZUZsYXNoVGVzdGVyID0gZnVuY3Rpb24gY3JlYXRlRmxhc2hUZXN0ZXIoZWwsIHN3ZkNvbmZpZykge1xuICAgIGlmICghd2luZG93W0ZMQVNIX1RFU1RdKSB7XG4gICAgICAgIHdpbmRvd1tGTEFTSF9URVNUXSA9IG5ldyBGbGFzaFRlc3RlcihlbCwgc3dmQ29uZmlnKTtcbiAgICB9XG4gICAgcmV0dXJuIHdpbmRvd1tGTEFTSF9URVNUXTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbmxldCB1bmlxdWUgPSByZXF1aXJlKCcuL3V0aWxzJykudW5pcXVlO1xubGV0IGlzUG9zaXRpdmVJbnQgPSByZXF1aXJlKCcuL3V0aWxzJykuaXNQb3NpdGl2ZUludDtcbmxldCBzdHJpbmdFbmRzV2l0aCA9IHJlcXVpcmUoJy4vdXRpbHMnKS5zdHJpbmdFbmRzV2l0aDtcbmxldCBTaW5nbGVWYWx1ZVJlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9yZWdpc3RyeScpLlNpbmdsZVZhbHVlUmVnaXN0cnk7XG5sZXQgTXVsdGlwbGVWYWx1ZXNSZWdpc3RyeSA9IHJlcXVpcmUoJy4vcmVnaXN0cnknKS5NdWx0aXBsZVZhbHVlc1JlZ2lzdHJ5O1xuY29uc3QgcmVnaXN0cnkgPSByZXF1aXJlKCcuL2pzRmxhc2hCcmlkZ2VSZWdpc3RyeScpO1xuY29uc3QgVlBBSURfRkxBU0hfSEFORExFUiA9ICd2cGFpZF92aWRlb19mbGFzaF9oYW5kbGVyJztcbmNvbnN0IEVSUk9SID0gJ0FkRXJyb3InO1xuXG5leHBvcnQgY2xhc3MgSlNGbGFzaEJyaWRnZSB7XG4gICAgY29uc3RydWN0b3IgKGVsLCBmbGFzaFVSTCwgZmxhc2hJRCwgd2lkdGgsIGhlaWdodCwgbG9hZEhhbmRTaGFrZSkge1xuICAgICAgICB0aGlzLl9lbCA9IGVsO1xuICAgICAgICB0aGlzLl9mbGFzaElEID0gZmxhc2hJRDtcbiAgICAgICAgdGhpcy5fZmxhc2hVUkwgPSBmbGFzaFVSTDtcbiAgICAgICAgdGhpcy5fd2lkdGggPSB3aWR0aDtcbiAgICAgICAgdGhpcy5faGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgICB0aGlzLl9oYW5kbGVycyA9IG5ldyBNdWx0aXBsZVZhbHVlc1JlZ2lzdHJ5KCk7XG4gICAgICAgIHRoaXMuX2NhbGxiYWNrcyA9IG5ldyBTaW5nbGVWYWx1ZVJlZ2lzdHJ5KCk7XG4gICAgICAgIHRoaXMuX3VuaXF1ZU1ldGhvZElkZW50aWZpZXIgPSB1bmlxdWUodGhpcy5fZmxhc2hJRCk7XG4gICAgICAgIHRoaXMuX3JlYWR5ID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX2hhbmRTaGFrZUhhbmRsZXIgPSBsb2FkSGFuZFNoYWtlO1xuXG4gICAgICAgIHJlZ2lzdHJ5LmFkZEluc3RhbmNlKHRoaXMuX2ZsYXNoSUQsIHRoaXMpO1xuICAgIH1cblxuICAgIG9uKGV2ZW50TmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5faGFuZGxlcnMuYWRkKGV2ZW50TmFtZSwgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIG9mZihldmVudE5hbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVycy5yZW1vdmUoZXZlbnROYW1lLCBjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgb2ZmRXZlbnQoZXZlbnROYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVycy5yZW1vdmVCeUtleShldmVudE5hbWUpO1xuICAgIH1cblxuICAgIG9mZkFsbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZXJzLnJlbW92ZUFsbCgpO1xuICAgIH1cblxuICAgIGNhbGxGbGFzaE1ldGhvZChtZXRob2ROYW1lLCBhcmdzID0gW10sIGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhciBjYWxsYmFja0lEID0gJyc7XG4gICAgICAgIC8vIGlmIG5vIGNhbGxiYWNrLCBzb21lIG1ldGhvZHMgdGhlIHJldHVybiBpcyB2b2lkIHNvIHRoZXkgZG9uJ3QgbmVlZCBjYWxsYmFja1xuICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgIGNhbGxiYWNrSUQgPSBgJHt0aGlzLl91bmlxdWVNZXRob2RJZGVudGlmaWVyKCl9XyR7bWV0aG9kTmFtZX1gO1xuICAgICAgICAgICAgdGhpcy5fY2FsbGJhY2tzLmFkZChjYWxsYmFja0lELCBjYWxsYmFjayk7XG4gICAgICAgIH1cblxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvL21ldGhvZHMgYXJlIGNyZWF0ZWQgYnkgRXh0ZXJuYWxJbnRlcmZhY2UuYWRkQ2FsbGJhY2sgaW4gYXMzIGNvZGUsIGlmIGZvciBzb21lIHJlYXNvbiBpdCBmYWlsZWRcbiAgICAgICAgICAgIC8vdGhpcyBjb2RlIHdpbGwgdGhyb3cgYW4gZXJyb3JcbiAgICAgICAgICAgIHRoaXMuX2VsW21ldGhvZE5hbWVdKFtjYWxsYmFja0lEXS5jb25jYXQoYXJncykpO1xuXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICRhc3luY0NhbGxiYWNrLmNhbGwodGhpcywgY2FsbGJhY2tJRCwgZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgLy9pZiB0aGVyZSBpc24ndCBhbnkgY2FsbGJhY2sgdG8gcmV0dXJuIGVycm9yIHVzZSBlcnJvciBldmVudCBoYW5kbGVyXG4gICAgICAgICAgICAgICAgdGhpcy5fdHJpZ2dlcihFUlJPUiwgZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZW1vdmVDYWxsYmFjayhjYWxsYmFjaykge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2FsbGJhY2tzLnJlbW92ZUJ5VmFsdWUoY2FsbGJhY2spO1xuICAgIH1cblxuICAgIHJlbW92ZUNhbGxiYWNrQnlNZXRob2ROYW1lKHN1ZmZpeCkge1xuICAgICAgICB0aGlzLl9jYWxsYmFja3MuZmlsdGVyS2V5cygoa2V5KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gc3RyaW5nRW5kc1dpdGgoa2V5LCBzdWZmaXgpO1xuICAgICAgICB9KS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrcy5yZW1vdmUoa2V5KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmVtb3ZlQWxsQ2FsbGJhY2tzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2FsbGJhY2tzLnJlbW92ZUFsbCgpO1xuICAgIH1cblxuICAgIF90cmlnZ2VyKGV2ZW50TmFtZSwgZXZlbnQpIHtcbiAgICAgICAgdGhpcy5faGFuZGxlcnMuZ2V0KGV2ZW50TmFtZSkuZm9yRWFjaCgoY2FsbGJhY2spID0+IHtcbiAgICAgICAgICAgIC8vY2xpY2tUaHJ1IGhhcyB0byBiZSBzeW5jLCBpZiBub3Qgd2lsbCBiZSBibG9jayBieSB0aGUgcG9wdXBibG9ja2VyXG4gICAgICAgICAgICBpZiAoZXZlbnROYW1lID09PSAnQWRDbGlja1RocnUnKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2hhbmRsZXJzLmdldChldmVudE5hbWUpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfY2FsbENhbGxiYWNrKG1ldGhvZE5hbWUsIGNhbGxiYWNrSUQsIGVyciwgcmVzdWx0KSB7XG5cbiAgICAgICAgbGV0IGNhbGxiYWNrID0gdGhpcy5fY2FsbGJhY2tzLmdldChjYWxsYmFja0lEKTtcblxuICAgICAgICAvL25vdCBhbGwgbWV0aG9kcyBjYWxsYmFjaydzIGFyZSBtYW5kYXRvcnlcbiAgICAgICAgLy9idXQgaWYgdGhlcmUgZXhpc3QgYW4gZXJyb3IsIGZpcmUgdGhlIGVycm9yIGV2ZW50XG4gICAgICAgIGlmICghY2FsbGJhY2spIHtcbiAgICAgICAgICAgIGlmIChlcnIgJiYgY2FsbGJhY2tJRCA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoRVJST1IsIGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAkYXN5bmNDYWxsYmFjay5jYWxsKHRoaXMsIGNhbGxiYWNrSUQsIGVyciwgcmVzdWx0KTtcblxuICAgIH1cblxuICAgIF9oYW5kU2hha2UoZXJyLCBkYXRhKSB7XG4gICAgICAgIHRoaXMuX3JlYWR5ID0gdHJ1ZTtcbiAgICAgICAgaWYgKHRoaXMuX2hhbmRTaGFrZUhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMuX2hhbmRTaGFrZUhhbmRsZXIoZXJyLCBkYXRhKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9oYW5kU2hha2VIYW5kbGVyO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy9tZXRob2RzIGxpa2UgcHJvcGVydGllcyBzcGVjaWZpYyB0byB0aGlzIGltcGxlbWVudGF0aW9uIG9mIFZQQUlEXG4gICAgZ2V0U2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHt3aWR0aDogdGhpcy5fd2lkdGgsIGhlaWdodDogdGhpcy5faGVpZ2h0fTtcbiAgICB9XG4gICAgc2V0U2l6ZShuZXdXaWR0aCwgbmV3SGVpZ2h0KSB7XG4gICAgICAgIHRoaXMuX3dpZHRoID0gaXNQb3NpdGl2ZUludChuZXdXaWR0aCwgdGhpcy5fd2lkdGgpO1xuICAgICAgICB0aGlzLl9oZWlnaHQgPSBpc1Bvc2l0aXZlSW50KG5ld0hlaWdodCwgdGhpcy5faGVpZ2h0KTtcbiAgICAgICAgdGhpcy5fZWwuc2V0QXR0cmlidXRlKCd3aWR0aCcsIHRoaXMuX3dpZHRoKTtcbiAgICAgICAgdGhpcy5fZWwuc2V0QXR0cmlidXRlKCdoZWlnaHQnLCB0aGlzLl9oZWlnaHQpO1xuICAgIH1cbiAgICBnZXRXaWR0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3dpZHRoO1xuICAgIH1cbiAgICBzZXRXaWR0aChuZXdXaWR0aCkge1xuICAgICAgICB0aGlzLnNldFNpemUobmV3V2lkdGgsIHRoaXMuX2hlaWdodCk7XG4gICAgfVxuICAgIGdldEhlaWdodCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hlaWdodDtcbiAgICB9XG4gICAgc2V0SGVpZ2h0KG5ld0hlaWdodCkge1xuICAgICAgICB0aGlzLnNldFNpemUodGhpcy5fd2lkdGgsIG5ld0hlaWdodCk7XG4gICAgfVxuICAgIGdldEZsYXNoSUQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mbGFzaElEO1xuICAgIH1cbiAgICBnZXRGbGFzaFVSTCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZsYXNoVVJMO1xuICAgIH1cbiAgICBpc1JlYWR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVhZHk7XG4gICAgfVxuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMub2ZmQWxsKCk7XG4gICAgICAgIHRoaXMucmVtb3ZlQWxsQ2FsbGJhY2tzKCk7XG4gICAgICAgIHJlZ2lzdHJ5LnJlbW92ZUluc3RhbmNlQnlJRCh0aGlzLl9mbGFzaElEKTtcbiAgICAgICAgaWYgKHRoaXMuX2VsLnBhcmVudEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX2VsLnBhcmVudEVsZW1lbnQucmVtb3ZlQ2hpbGQodGhpcy5fZWwpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiAkYXN5bmNDYWxsYmFjayhjYWxsYmFja0lELCBlcnIsIHJlc3VsdCkge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBsZXQgY2FsbGJhY2sgPSB0aGlzLl9jYWxsYmFja3MuZ2V0KGNhbGxiYWNrSUQpO1xuICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrcy5yZW1vdmUoY2FsbGJhY2tJRCk7XG4gICAgICAgICAgICBjYWxsYmFjayhlcnIsIHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICB9LCAwKTtcbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEpTRmxhc2hCcmlkZ2UsICdWUEFJRF9GTEFTSF9IQU5ETEVSJywge1xuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgIHZhbHVlOiBWUEFJRF9GTEFTSF9IQU5ETEVSXG59KTtcblxuLyoqXG4gKiBFeHRlcm5hbCBpbnRlcmZhY2UgaGFuZGxlclxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBmbGFzaElEIGlkZW50aWZpZXIgb2YgdGhlIGZsYXNoIHdobyBjYWxsIHRoaXNcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlSUQgd2hhdCB0eXBlIG9mIG1lc3NhZ2UgaXMsIGNhbiBiZSAnZXZlbnQnIG9yICdjYWxsYmFjaydcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlTmFtZSBpZiB0aGUgdHlwZUlEIGlzIGEgZXZlbnQgdGhlIHR5cGVOYW1lIHdpbGwgYmUgdGhlIGV2ZW50TmFtZSwgaWYgaXMgYSBjYWxsYmFjayB0aGUgdHlwZUlEIGlzIHRoZSBtZXRob2ROYW1lIHRoYXQgaXMgcmVsYXRlZCB0aGlzIGNhbGxiYWNrXG4gKiBAcGFyYW0ge3N0cmluZ30gY2FsbGJhY2tJRCBvbmx5IGFwcGxpZXMgd2hlbiB0aGUgdHlwZUlEIGlzICdjYWxsYmFjaycsIGlkZW50aWZpZXIgb2YgdGhlIGNhbGxiYWNrIHRvIGNhbGxcbiAqIEBwYXJhbSB7b2JqZWN0fSBlcnJvciBlcnJvciBvYmplY3RcbiAqIEBwYXJhbSB7b2JqZWN0fSBkYXRhXG4gKi9cbndpbmRvd1tWUEFJRF9GTEFTSF9IQU5ETEVSXSA9IChmbGFzaElELCB0eXBlSUQsIHR5cGVOYW1lLCBjYWxsYmFja0lELCBlcnJvciwgZGF0YSkgPT4ge1xuICAgIGxldCBpbnN0YW5jZSA9IHJlZ2lzdHJ5LmdldEluc3RhbmNlQnlJRChmbGFzaElEKTtcbiAgICBpZiAoIWluc3RhbmNlKSByZXR1cm47XG4gICAgaWYgKHR5cGVOYW1lID09PSAnaGFuZFNoYWtlJykge1xuICAgICAgICBpbnN0YW5jZS5faGFuZFNoYWtlKGVycm9yLCBkYXRhKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodHlwZUlEICE9PSAnZXZlbnQnKSB7XG4gICAgICAgICAgICBpbnN0YW5jZS5fY2FsbENhbGxiYWNrKHR5cGVOYW1lLCBjYWxsYmFja0lELCBlcnJvciwgZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpbnN0YW5jZS5fdHJpZ2dlcih0eXBlTmFtZSwgZGF0YSk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG4iLCIndXNlIHN0cmljdCc7XG5cbmxldCBTaW5nbGVWYWx1ZVJlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9yZWdpc3RyeScpLlNpbmdsZVZhbHVlUmVnaXN0cnk7XG5sZXQgaW5zdGFuY2VzID0gbmV3IFNpbmdsZVZhbHVlUmVnaXN0cnkoKTtcblxuY29uc3QgSlNGbGFzaEJyaWRnZVJlZ2lzdHJ5ID0ge307XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoSlNGbGFzaEJyaWRnZVJlZ2lzdHJ5LCAnYWRkSW5zdGFuY2UnLCB7XG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIChpZCwgaW5zdGFuY2UpIHtcbiAgICAgICAgaW5zdGFuY2VzLmFkZChpZCwgaW5zdGFuY2UpO1xuICAgIH1cbn0pO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoSlNGbGFzaEJyaWRnZVJlZ2lzdHJ5LCAnZ2V0SW5zdGFuY2VCeUlEJywge1xuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoaWQpIHtcbiAgICAgICAgcmV0dXJuIGluc3RhbmNlcy5nZXQoaWQpO1xuICAgIH1cbn0pO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoSlNGbGFzaEJyaWRnZVJlZ2lzdHJ5LCAncmVtb3ZlSW5zdGFuY2VCeUlEJywge1xuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoaWQpIHtcbiAgICAgICAgcmV0dXJuIGluc3RhbmNlcy5yZW1vdmUoaWQpO1xuICAgIH1cbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEpTRmxhc2hCcmlkZ2VSZWdpc3RyeTtcblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnQgY2xhc3MgTXVsdGlwbGVWYWx1ZXNSZWdpc3RyeSB7XG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICB0aGlzLl9yZWdpc3RyaWVzID0ge307XG4gICAgfVxuICAgIGFkZCAoaWQsIHZhbHVlKSB7XG4gICAgICAgIGlmICghdGhpcy5fcmVnaXN0cmllc1tpZF0pIHtcbiAgICAgICAgICAgIHRoaXMuX3JlZ2lzdHJpZXNbaWRdID0gW107XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX3JlZ2lzdHJpZXNbaWRdLmluZGV4T2YodmFsdWUpID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5fcmVnaXN0cmllc1tpZF0ucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IChpZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVnaXN0cmllc1tpZF0gfHwgW107XG4gICAgfVxuICAgIGZpbHRlcktleXMgKGhhbmRsZXIpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuX3JlZ2lzdHJpZXMpLmZpbHRlcihoYW5kbGVyKTtcbiAgICB9XG4gICAgZmluZEJ5VmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXModGhpcy5fcmVnaXN0cmllcykuZmlsdGVyKChrZXkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9yZWdpc3RyaWVzW2tleV0uaW5kZXhPZih2YWx1ZSkgIT09IC0xO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4ga2V5cztcbiAgICB9XG4gICAgcmVtb3ZlKGtleSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9yZWdpc3RyaWVzW2tleV0pIHsgcmV0dXJuOyB9XG5cbiAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5fcmVnaXN0cmllc1trZXldLmluZGV4T2YodmFsdWUpO1xuXG4gICAgICAgIGlmIChpbmRleCA8IDApIHsgcmV0dXJuOyB9XG4gICAgICAgIHJldHVybiB0aGlzLl9yZWdpc3RyaWVzW2tleV0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICB9XG4gICAgcmVtb3ZlQnlLZXkgKGlkKSB7XG4gICAgICAgIGxldCBvbGQgPSB0aGlzLl9yZWdpc3RyaWVzW2lkXTtcbiAgICAgICAgZGVsZXRlIHRoaXMuX3JlZ2lzdHJpZXNbaWRdO1xuICAgICAgICByZXR1cm4gb2xkO1xuICAgIH1cbiAgICByZW1vdmVCeVZhbHVlICh2YWx1ZSkge1xuICAgICAgICBsZXQga2V5cyA9IHRoaXMuZmluZEJ5VmFsdWUodmFsdWUpO1xuICAgICAgICByZXR1cm4ga2V5cy5tYXAoKGtleSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVtb3ZlKGtleSwgdmFsdWUpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmVtb3ZlQWxsKCkge1xuICAgICAgICBsZXQgb2xkID0gdGhpcy5fcmVnaXN0cmllcztcbiAgICAgICAgdGhpcy5fcmVnaXN0cmllcyA9IHt9O1xuICAgICAgICByZXR1cm4gb2xkO1xuICAgIH1cbiAgICBzaXplKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5fcmVnaXN0cmllcykubGVuZ3RoO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNpbmdsZVZhbHVlUmVnaXN0cnkge1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgdGhpcy5fcmVnaXN0cmllcyA9IHt9O1xuICAgIH1cbiAgICBhZGQgKGlkLCB2YWx1ZSkge1xuICAgICAgICB0aGlzLl9yZWdpc3RyaWVzW2lkXSA9IHZhbHVlO1xuICAgIH1cbiAgICBnZXQgKGlkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZWdpc3RyaWVzW2lkXTtcbiAgICB9XG4gICAgZmlsdGVyS2V5cyAoaGFuZGxlcikge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5fcmVnaXN0cmllcykuZmlsdGVyKGhhbmRsZXIpO1xuICAgIH1cbiAgICBmaW5kQnlWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh0aGlzLl9yZWdpc3RyaWVzKS5maWx0ZXIoKGtleSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3JlZ2lzdHJpZXNba2V5XSA9PT0gdmFsdWU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBrZXlzO1xuICAgIH1cbiAgICByZW1vdmUgKGlkKSB7XG4gICAgICAgIGxldCBvbGQgPSB0aGlzLl9yZWdpc3RyaWVzW2lkXTtcbiAgICAgICAgZGVsZXRlIHRoaXMuX3JlZ2lzdHJpZXNbaWRdO1xuICAgICAgICByZXR1cm4gb2xkO1xuICAgIH1cbiAgICByZW1vdmVCeVZhbHVlICh2YWx1ZSkge1xuICAgICAgICBsZXQga2V5cyA9IHRoaXMuZmluZEJ5VmFsdWUodmFsdWUpO1xuICAgICAgICByZXR1cm4ga2V5cy5tYXAoKGtleSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVtb3ZlKGtleSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZW1vdmVBbGwoKSB7XG4gICAgICAgIGxldCBvbGQgPSB0aGlzLl9yZWdpc3RyaWVzO1xuICAgICAgICB0aGlzLl9yZWdpc3RyaWVzID0ge307XG4gICAgICAgIHJldHVybiBvbGQ7XG4gICAgfVxuICAgIHNpemUoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLl9yZWdpc3RyaWVzKS5sZW5ndGg7XG4gICAgfVxufVxuXG4iLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydCBmdW5jdGlvbiB1bmlxdWUocHJlZml4KSB7XG4gICAgbGV0IGNvdW50ID0gLTE7XG4gICAgcmV0dXJuIGYgPT4ge1xuICAgICAgICByZXR1cm4gYCR7cHJlZml4fV8keysrY291bnR9YDtcbiAgICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbm9vcCgpIHtcbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gY2FsbGJhY2tUaW1lb3V0KHRpbWVyLCBvblN1Y2Nlc3MsIG9uVGltZW91dCkge1xuXG4gICAgbGV0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcblxuICAgICAgICBvblN1Y2Nlc3MgPSBub29wO1xuICAgICAgICBvblRpbWVvdXQoKTtcblxuICAgIH0sIHRpbWVyKTtcblxuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgb25TdWNjZXNzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfTtcbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRWxlbWVudFdpdGhJRChwYXJlbnQsIGlkLCBjbGVhbkNvbnRlbnQgPSBmYWxzZSkge1xuICAgIHZhciBuRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBuRWwuaWQgPSBpZDtcbiAgICBpZiAoY2xlYW5Db250ZW50KSB7XG4gICAgICAgIHBhcmVudC5pbm5lckhUTUwgPSAnJztcbiAgICB9XG4gICAgcGFyZW50LmFwcGVuZENoaWxkKG5FbCk7XG4gICAgcmV0dXJuIG5FbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUG9zaXRpdmVJbnQobmV3VmFsLCBvbGRWYWwpIHtcbiAgICByZXR1cm4gIWlzTmFOKHBhcnNlRmxvYXQobmV3VmFsKSkgJiYgaXNGaW5pdGUobmV3VmFsKSAmJiBuZXdWYWwgPiAwID8gbmV3VmFsIDogb2xkVmFsO1xufVxuXG5sZXQgZW5kc1dpdGggPSAoZnVuY3Rpb24gKCkge1xuICAgIGlmIChTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoKSByZXR1cm4gU3RyaW5nLnByb3RvdHlwZS5lbmRzV2l0aDtcbiAgICByZXR1cm4gZnVuY3Rpb24gZW5kc1dpdGggKHNlYXJjaFN0cmluZywgcG9zaXRpb24pIHtcbiAgICAgICAgdmFyIHN1YmplY3RTdHJpbmcgPSB0aGlzLnRvU3RyaW5nKCk7XG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gdW5kZWZpbmVkIHx8IHBvc2l0aW9uID4gc3ViamVjdFN0cmluZy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHBvc2l0aW9uID0gc3ViamVjdFN0cmluZy5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgcG9zaXRpb24gLT0gc2VhcmNoU3RyaW5nLmxlbmd0aDtcbiAgICAgICAgdmFyIGxhc3RJbmRleCA9IHN1YmplY3RTdHJpbmcuaW5kZXhPZihzZWFyY2hTdHJpbmcsIHBvc2l0aW9uKTtcbiAgICAgICAgcmV0dXJuIGxhc3RJbmRleCAhPT0gLTEgJiYgbGFzdEluZGV4ID09PSBwb3NpdGlvbjtcbiAgICB9O1xufSkoKTtcblxuZXhwb3J0IGZ1bmN0aW9uIHN0cmluZ0VuZHNXaXRoKHN0cmluZywgc2VhcmNoKSB7XG4gICAgcmV0dXJuIGVuZHNXaXRoLmNhbGwoc3RyaW5nLCBzZWFyY2gpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGlkZUZsYXNoRWwoZWwpIHtcbiAgICAvLyBjYW4ndCB1c2UgZGlzcGxheSBub25lIG9yIHZpc2liaWxpdHkgbm9uZSBiZWNhdXNlIHdpbGwgYmxvY2sgZmxhc2ggaW4gc29tZSBicm93c2Vyc1xuICAgIGVsLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICBlbC5zdHlsZS5sZWZ0ID0gJy0xcHgnO1xuICAgIGVsLnN0eWxlLnRvcCA9ICctMXB4JztcbiAgICBlbC5zdHlsZS53aWR0aCA9ICcxcHgnO1xuICAgIGVsLnN0eWxlLmhlaWdodCA9ICcxcHgnO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgTUVUSE9EUyA9IFtcbiAgICAnaGFuZHNoYWtlVmVyc2lvbicsXG4gICAgJ2luaXRBZCcsXG4gICAgJ3N0YXJ0QWQnLFxuICAgICdzdG9wQWQnLFxuICAgICdza2lwQWQnLCAvLyBWUEFJRCAyLjAgbmV3IG1ldGhvZFxuICAgICdyZXNpemVBZCcsXG4gICAgJ3BhdXNlQWQnLFxuICAgICdyZXN1bWVBZCcsXG4gICAgJ2V4cGFuZEFkJyxcbiAgICAnY29sbGFwc2VBZCcsXG4gICAgJ3N1YnNjcmliZScsXG4gICAgJ3Vuc3Vic2NyaWJlJ1xuXTtcblxudmFyIEVWRU5UUyA9IFtcbiAgICAnQWRMb2FkZWQnLFxuICAgICdBZFN0YXJ0ZWQnLFxuICAgICdBZFN0b3BwZWQnLFxuICAgICdBZFNraXBwZWQnLFxuICAgICdBZFNraXBwYWJsZVN0YXRlQ2hhbmdlJywgLy8gVlBBSUQgMi4wIG5ldyBldmVudFxuICAgICdBZFNpemVDaGFuZ2UnLCAvLyBWUEFJRCAyLjAgbmV3IGV2ZW50XG4gICAgJ0FkTGluZWFyQ2hhbmdlJyxcbiAgICAnQWREdXJhdGlvbkNoYW5nZScsIC8vIFZQQUlEIDIuMCBuZXcgZXZlbnRcbiAgICAnQWRFeHBhbmRlZENoYW5nZScsXG4gICAgJ0FkUmVtYWluaW5nVGltZUNoYW5nZScsIC8vIFtEZXByZWNhdGVkIGluIDIuMF0gYnV0IHdpbGwgYmUgc3RpbGwgZmlyZWQgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG4gICAgJ0FkVm9sdW1lQ2hhbmdlJyxcbiAgICAnQWRJbXByZXNzaW9uJyxcbiAgICAnQWRWaWRlb1N0YXJ0JyxcbiAgICAnQWRWaWRlb0ZpcnN0UXVhcnRpbGUnLFxuICAgICdBZFZpZGVvTWlkcG9pbnQnLFxuICAgICdBZFZpZGVvVGhpcmRRdWFydGlsZScsXG4gICAgJ0FkVmlkZW9Db21wbGV0ZScsXG4gICAgJ0FkQ2xpY2tUaHJ1JyxcbiAgICAnQWRJbnRlcmFjdGlvbicsIC8vIFZQQUlEIDIuMCBuZXcgZXZlbnRcbiAgICAnQWRVc2VyQWNjZXB0SW52aXRhdGlvbicsXG4gICAgJ0FkVXNlck1pbmltaXplJyxcbiAgICAnQWRVc2VyQ2xvc2UnLFxuICAgICdBZFBhdXNlZCcsXG4gICAgJ0FkUGxheWluZycsXG4gICAgJ0FkTG9nJyxcbiAgICAnQWRFcnJvcidcbl07XG5cbnZhciBHRVRURVJTID0gW1xuICAgICdnZXRBZExpbmVhcicsXG4gICAgJ2dldEFkV2lkdGgnLCAvLyBWUEFJRCAyLjAgbmV3IGdldHRlclxuICAgICdnZXRBZEhlaWdodCcsIC8vIFZQQUlEIDIuMCBuZXcgZ2V0dGVyXG4gICAgJ2dldEFkRXhwYW5kZWQnLFxuICAgICdnZXRBZFNraXBwYWJsZVN0YXRlJywgLy8gVlBBSUQgMi4wIG5ldyBnZXR0ZXJcbiAgICAnZ2V0QWRSZW1haW5pbmdUaW1lJyxcbiAgICAnZ2V0QWREdXJhdGlvbicsIC8vIFZQQUlEIDIuMCBuZXcgZ2V0dGVyXG4gICAgJ2dldEFkVm9sdW1lJyxcbiAgICAnZ2V0QWRDb21wYW5pb25zJywgLy8gVlBBSUQgMi4wIG5ldyBnZXR0ZXJcbiAgICAnZ2V0QWRJY29ucycgLy8gVlBBSUQgMi4wIG5ldyBnZXR0ZXJcbl07XG5cbnZhciBTRVRURVJTID0gW1xuICAgICdzZXRBZFZvbHVtZSdcbl07XG5cblxuLyoqXG4gKiBUaGlzIGNhbGxiYWNrIGlzIGRpc3BsYXllZCBhcyBnbG9iYWwgbWVtYmVyLiBUaGUgY2FsbGJhY2sgdXNlIG5vZGVqcyBlcnJvci1maXJzdCBjYWxsYmFjayBzdHlsZVxuICogQGNhbGxiYWNrIE5vZGVTdHlsZUNhbGxiYWNrXG4gKiBAcGFyYW0ge3N0cmluZ3xudWxsfVxuICogQHBhcmFtIHt1bmRlZmluZWR8b2JqZWN0fVxuICovXG5cblxuLyoqXG4gKiBJVlBBSURBZFVuaXRcbiAqXG4gKiBAY2xhc3NcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gY3JlYXRpdmVcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsXG4gKiBAcGFyYW0ge0hUTUxWaWRlb0VsZW1lbnR9IHZpZGVvXG4gKi9cbmZ1bmN0aW9uIElWUEFJREFkVW5pdChjcmVhdGl2ZSwgZWwsIHZpZGVvKSB7fVxuXG5cbi8qKlxuICogaGFuZHNoYWtlVmVyc2lvblxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBWUEFJRFZlcnNpb25cbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuaGFuZHNoYWtlVmVyc2lvbiA9IGZ1bmN0aW9uIChWUEFJRFZlcnNpb24sIGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBpbml0QWRcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gd2lkdGhcbiAqIEBwYXJhbSB7bnVtYmVyfSBoZWlnaHRcbiAqIEBwYXJhbSB7c3RyaW5nfSB2aWV3TW9kZSBjYW4gYmUgJ25vcm1hbCcsICd0aHVtYm5haWwnIG9yICdmdWxsc2NyZWVuJ1xuICogQHBhcmFtIHtudW1iZXJ9IGRlc2lyZWRCaXRyYXRlIGluZGljYXRlcyB0aGUgZGVzaXJlZCBiaXRyYXRlIGluIGticHNcbiAqIEBwYXJhbSB7b2JqZWN0fSBbY3JlYXRpdmVEYXRhXSB1c2VkIGZvciBhZGRpdGlvbmFsIGluaXRpYWxpemF0aW9uIGRhdGFcbiAqIEBwYXJhbSB7b2JqZWN0fSBbZW52aXJvbm1lbnRWYXJzXSB1c2VkIGZvciBwYXNzaW5nIGltcGxlbWVudGF0aW9uLXNwZWNpZmljIG9mIGpzIHZlcnNpb25cbiAqIEBwYXJhbSB7Tm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuaW5pdEFkID0gZnVuY3Rpb24od2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGRlc2lyZWRCaXRyYXRlLCBjcmVhdGl2ZURhdGEsIGVudmlyb25tZW50VmFycywgY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIHN0YXJ0QWRcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLnN0YXJ0QWQgPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogc3RvcEFkXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5zdG9wQWQgPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogc2tpcEFkXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5za2lwQWQgPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogcmVzaXplQWRcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLnJlc2l6ZUFkID0gZnVuY3Rpb24od2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBwYXVzZUFkXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5wYXVzZUFkID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIHJlc3VtZUFkXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5yZXN1bWVBZCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBleHBhbmRBZFxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuZXhwYW5kQWQgPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogY29sbGFwc2VBZFxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuY29sbGFwc2VBZCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBzdWJzY3JpYmVcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGhhbmRsZXJcbiAqIEBwYXJhbSB7b2JqZWN0fSBjb250ZXh0XG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuc3Vic2NyaWJlID0gZnVuY3Rpb24oZXZlbnQsIGhhbmRsZXIsIGNvbnRleHQpIHt9O1xuXG4vKipcbiAqIHN0YXJ0QWRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGhhbmRsZXJcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS51bnN1YnNjcmliZSA9IGZ1bmN0aW9uKGV2ZW50LCBoYW5kbGVyKSB7fTtcblxuXG5cbi8qKlxuICogZ2V0QWRMaW5lYXJcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLmdldEFkTGluZWFyID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIGdldEFkV2lkdGhcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLmdldEFkV2lkdGggPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogZ2V0QWRIZWlnaHRcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLmdldEFkSGVpZ2h0ID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIGdldEFkRXhwYW5kZWRcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLmdldEFkRXhwYW5kZWQgPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogZ2V0QWRTa2lwcGFibGVTdGF0ZVxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuZ2V0QWRTa2lwcGFibGVTdGF0ZSA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBnZXRBZFJlbWFpbmluZ1RpbWVcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLmdldEFkUmVtYWluaW5nVGltZSA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBnZXRBZER1cmF0aW9uXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5nZXRBZER1cmF0aW9uID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIGdldEFkVm9sdW1lXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5nZXRBZFZvbHVtZSA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBnZXRBZENvbXBhbmlvbnNcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLmdldEFkQ29tcGFuaW9ucyA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBnZXRBZEljb25zXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5nZXRBZEljb25zID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIHNldEFkVm9sdW1lXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHZvbHVtZVxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5zZXRBZFZvbHVtZSA9IGZ1bmN0aW9uKHZvbHVtZSwgY2FsbGJhY2spIHt9O1xuXG5hZGRTdGF0aWNUb0ludGVyZmFjZShJVlBBSURBZFVuaXQsICdNRVRIT0RTJywgTUVUSE9EUyk7XG5hZGRTdGF0aWNUb0ludGVyZmFjZShJVlBBSURBZFVuaXQsICdHRVRURVJTJywgR0VUVEVSUyk7XG5hZGRTdGF0aWNUb0ludGVyZmFjZShJVlBBSURBZFVuaXQsICdTRVRURVJTJywgU0VUVEVSUyk7XG5hZGRTdGF0aWNUb0ludGVyZmFjZShJVlBBSURBZFVuaXQsICdFVkVOVFMnLCAgRVZFTlRTKTtcblxuXG52YXIgVlBBSUQxX01FVEhPRFMgPSBNRVRIT0RTLmZpbHRlcihmdW5jdGlvbihtZXRob2QpIHtcbiAgICByZXR1cm4gWydza2lwQWQnXS5pbmRleE9mKG1ldGhvZCkgPT09IC0xO1xufSk7XG5cbmFkZFN0YXRpY1RvSW50ZXJmYWNlKElWUEFJREFkVW5pdCwgJ2NoZWNrVlBBSURJbnRlcmZhY2UnLCBmdW5jdGlvbiBjaGVja1ZQQUlESW50ZXJmYWNlIChjcmVhdGl2ZSkge1xuICAgIHZhciByZXN1bHQgPSBWUEFJRDFfTUVUSE9EUy5ldmVyeShmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBjcmVhdGl2ZVtrZXldID09PSAnZnVuY3Rpb24nO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBJVlBBSURBZFVuaXQ7XG5cbmZ1bmN0aW9uIGFkZFN0YXRpY1RvSW50ZXJmYWNlKEludGVyZmFjZSwgbmFtZSwgdmFsdWUpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoSW50ZXJmYWNlLCBuYW1lLCB7XG4gICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgdmFsdWU6IHZhbHVlXG4gICAgfSk7XG59XG5cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIElWUEFJREFkVW5pdCA9IHJlcXVpcmUoJy4vSVZQQUlEQWRVbml0Jyk7XG52YXIgU3Vic2NyaWJlciA9IHJlcXVpcmUoJy4vc3Vic2NyaWJlcicpO1xudmFyIGNoZWNrVlBBSURJbnRlcmZhY2UgPSBJVlBBSURBZFVuaXQuY2hlY2tWUEFJREludGVyZmFjZTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciBNRVRIT0RTID0gSVZQQUlEQWRVbml0Lk1FVEhPRFM7XG52YXIgRVJST1IgPSAnQWRFcnJvcic7XG52YXIgQURfQ0xJQ0sgPSAnQWRDbGlja1RocnUnO1xudmFyIEZJTFRFUkVEX0VWRU5UUyA9IElWUEFJREFkVW5pdC5FVkVOVFMuZmlsdGVyKGZ1bmN0aW9uIChldmVudCkge1xuICAgIHJldHVybiBldmVudCAhPSBBRF9DTElDSztcbn0pO1xuXG4vKipcbiAqIFRoaXMgY2FsbGJhY2sgaXMgZGlzcGxheWVkIGFzIGdsb2JhbCBtZW1iZXIuIFRoZSBjYWxsYmFjayB1c2Ugbm9kZWpzIGVycm9yLWZpcnN0IGNhbGxiYWNrIHN0eWxlXG4gKiBAY2FsbGJhY2sgTm9kZVN0eWxlQ2FsbGJhY2tcbiAqIEBwYXJhbSB7c3RyaW5nfG51bGx9XG4gKiBAcGFyYW0ge3VuZGVmaW5lZHxvYmplY3R9XG4gKi9cblxuXG4vKipcbiAqIFZQQUlEQWRVbml0XG4gKiBAY2xhc3NcbiAqXG4gKiBAcGFyYW0gVlBBSURDcmVhdGl2ZVxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gW2VsXSB0aGlzIHdpbGwgYmUgdXNlZCBpbiBpbml0QWQgZW52aXJvbm1lbnRWYXJzLnNsb3QgaWYgZGVmaW5lZFxuICogQHBhcmFtIHtIVE1MVmlkZW9FbGVtZW50fSBbdmlkZW9dIHRoaXMgd2lsbCBiZSB1c2VkIGluIGluaXRBZCBlbnZpcm9ubWVudFZhcnMudmlkZW9TbG90IGlmIGRlZmluZWRcbiAqL1xuZnVuY3Rpb24gVlBBSURBZFVuaXQoVlBBSURDcmVhdGl2ZSwgZWwsIHZpZGVvLCBpZnJhbWUpIHtcbiAgICB0aGlzLl9pc1ZhbGlkID0gY2hlY2tWUEFJREludGVyZmFjZShWUEFJRENyZWF0aXZlKTtcbiAgICBpZiAodGhpcy5faXNWYWxpZCkge1xuICAgICAgICB0aGlzLl9jcmVhdGl2ZSA9IFZQQUlEQ3JlYXRpdmU7XG4gICAgICAgIHRoaXMuX2VsID0gZWw7XG4gICAgICAgIHRoaXMuX3ZpZGVvRWwgPSB2aWRlbztcbiAgICAgICAgdGhpcy5faWZyYW1lID0gaWZyYW1lO1xuICAgICAgICB0aGlzLl9zdWJzY3JpYmVycyA9IG5ldyBTdWJzY3JpYmVyKCk7XG4gICAgICAgICRhZGRFdmVudHNTdWJzY3JpYmVycy5jYWxsKHRoaXMpO1xuICAgIH1cbn1cblxuVlBBSURBZFVuaXQucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShJVlBBSURBZFVuaXQucHJvdG90eXBlKTtcblxuLyoqXG4gKiBpc1ZhbGlkVlBBSURBZCB3aWxsIHJldHVybiBpZiB0aGUgVlBBSURDcmVhdGl2ZSBwYXNzZWQgaW4gY29uc3RydWN0b3IgaXMgdmFsaWQgb3Igbm90XG4gKlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuVlBBSURBZFVuaXQucHJvdG90eXBlLmlzVmFsaWRWUEFJREFkID0gZnVuY3Rpb24gaXNWYWxpZFZQQUlEQWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2lzVmFsaWQ7XG59O1xuXG5JVlBBSURBZFVuaXQuTUVUSE9EUy5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgIC8vTk9URTogdGhpcyBtZXRob2RzIGFyZ3VtZW50cyBvcmRlciBhcmUgaW1wbGVtZW50ZWQgZGlmZmVyZW50bHkgZnJvbSB0aGUgc3BlY1xuICAgIHZhciBpZ25vcmVzID0gW1xuICAgICAgICAnc3Vic2NyaWJlJyxcbiAgICAgICAgJ3Vuc3Vic2NyaWJlJyxcbiAgICAgICAgJ2luaXRBZCdcbiAgICBdO1xuXG4gICAgaWYgKGlnbm9yZXMuaW5kZXhPZihtZXRob2QpICE9PSAtMSkgcmV0dXJuO1xuXG4gICAgVlBBSURBZFVuaXQucHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhcmlhdHkgPSBJVlBBSURBZFVuaXQucHJvdG90eXBlW21ldGhvZF0ubGVuZ3RoO1xuICAgICAgICAvLyBUT0RPIGF2b2lkIGxlYWtpbmcgYXJndW1lbnRzXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9wZXRrYWFudG9ub3YvYmx1ZWJpcmQvd2lraS9PcHRpbWl6YXRpb24ta2lsbGVycyMzMi1sZWFraW5nLWFyZ3VtZW50c1xuICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IChhcmlhdHkgPT09IGFyZ3MubGVuZ3RoKSA/IGFyZ3MucG9wKCkgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgcmVzdWx0LCBlcnJvciA9IG51bGw7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRoaXMuX2NyZWF0aXZlW21ldGhvZF0uYXBwbHkodGhpcy5fY3JlYXRpdmUsIGFyZ3MpO1xuICAgICAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgICAgICAgZXJyb3IgPSBlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYWxsT3JUcmlnZ2VyRXZlbnQoY2FsbGJhY2ssIHRoaXMuX3N1YnNjcmliZXJzLCBlcnJvciwgcmVzdWx0KTtcbiAgICAgICAgfS5iaW5kKHRoaXMpLCAwKTtcbiAgICB9O1xufSk7XG5cblxuLyoqXG4gKiBpbml0QWQgY29uY3JlYXRlIGltcGxlbWVudGF0aW9uXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoXG4gKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0XG4gKiBAcGFyYW0ge3N0cmluZ30gdmlld01vZGUgY2FuIGJlICdub3JtYWwnLCAndGh1bWJuYWlsJyBvciAnZnVsbHNjcmVlbidcbiAqIEBwYXJhbSB7bnVtYmVyfSBkZXNpcmVkQml0cmF0ZSBpbmRpY2F0ZXMgdGhlIGRlc2lyZWQgYml0cmF0ZSBpbiBrYnBzXG4gKiBAcGFyYW0ge29iamVjdH0gW2NyZWF0aXZlRGF0YV0gdXNlZCBmb3IgYWRkaXRpb25hbCBpbml0aWFsaXphdGlvbiBkYXRhXG4gKiBAcGFyYW0ge29iamVjdH0gW2Vudmlyb25tZW50VmFyc10gdXNlZCBmb3IgcGFzc2luZyBpbXBsZW1lbnRhdGlvbi1zcGVjaWZpYyBvZiBqcyB2ZXJzaW9uLCBpZiBlbCAmIHZpZGVvIHdhcyB1c2VkIGluIGNvbnN0cnVjdG9yIHNsb3QgJiB2aWRlb1Nsb3Qgd2lsbCBiZSBhZGRlZCB0byB0aGUgb2JqZWN0XG4gKiBAcGFyYW0ge05vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5WUEFJREFkVW5pdC5wcm90b3R5cGUuaW5pdEFkID0gZnVuY3Rpb24gaW5pdEFkKHdpZHRoLCBoZWlnaHQsIHZpZXdNb2RlLCBkZXNpcmVkQml0cmF0ZSwgY3JlYXRpdmVEYXRhLCBlbnZpcm9ubWVudFZhcnMsIGNhbGxiYWNrKSB7XG4gICAgY3JlYXRpdmVEYXRhID0gY3JlYXRpdmVEYXRhIHx8IHt9O1xuICAgIGVudmlyb25tZW50VmFycyA9IHV0aWxzLmV4dGVuZCh7XG4gICAgICAgIHNsb3Q6IHRoaXMuX2VsLFxuICAgICAgICB2aWRlb1Nsb3Q6IHRoaXMuX3ZpZGVvRWxcbiAgICB9LCBlbnZpcm9ubWVudFZhcnMgfHwge30pO1xuXG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBlcnJvcjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0aXZlLmluaXRBZCh3aWR0aCwgaGVpZ2h0LCB2aWV3TW9kZSwgZGVzaXJlZEJpdHJhdGUsIGNyZWF0aXZlRGF0YSwgZW52aXJvbm1lbnRWYXJzKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgZXJyb3IgPSBlO1xuICAgICAgICB9XG5cbiAgICAgICAgY2FsbE9yVHJpZ2dlckV2ZW50KGNhbGxiYWNrLCB0aGlzLl9zdWJzY3JpYmVycywgZXJyb3IpO1xuICAgIH0uYmluZCh0aGlzKSwgMCk7XG59O1xuXG4vKipcbiAqIHN1YnNjcmliZVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gaGFuZGxlclxuICogQHBhcmFtIHtvYmplY3R9IGNvbnRleHRcbiAqL1xuVlBBSURBZFVuaXQucHJvdG90eXBlLnN1YnNjcmliZSA9IGZ1bmN0aW9uIHN1YnNjcmliZShldmVudCwgaGFuZGxlciwgY29udGV4dCkge1xuICAgIHRoaXMuX3N1YnNjcmliZXJzLnN1YnNjcmliZShoYW5kbGVyLCBldmVudCwgY29udGV4dCk7XG59O1xuXG5cbi8qKlxuICogdW5zdWJzY3JpYmVcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGhhbmRsZXJcbiAqL1xuVlBBSURBZFVuaXQucHJvdG90eXBlLnVuc3Vic2NyaWJlID0gZnVuY3Rpb24gdW5zdWJzY3JpYmUoZXZlbnQsIGhhbmRsZXIpIHtcbiAgICB0aGlzLl9zdWJzY3JpYmVycy51bnN1YnNjcmliZShoYW5kbGVyLCBldmVudCk7XG59O1xuXG4vL2FsaWFzXG5WUEFJREFkVW5pdC5wcm90b3R5cGUub24gPSBWUEFJREFkVW5pdC5wcm90b3R5cGUuc3Vic2NyaWJlO1xuVlBBSURBZFVuaXQucHJvdG90eXBlLm9mZiA9IFZQQUlEQWRVbml0LnByb3RvdHlwZS51bnN1YnNjcmliZTtcblxuSVZQQUlEQWRVbml0LkdFVFRFUlMuZm9yRWFjaChmdW5jdGlvbihnZXR0ZXIpIHtcbiAgICBWUEFJREFkVW5pdC5wcm90b3R5cGVbZ2V0dGVyXSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgdmFyIHJlc3VsdCwgZXJyb3IgPSBudWxsO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSB0aGlzLl9jcmVhdGl2ZVtnZXR0ZXJdKCk7XG4gICAgICAgICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgICAgICAgICBlcnJvciA9IGU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhbGxPclRyaWdnZXJFdmVudChjYWxsYmFjaywgdGhpcy5fc3Vic2NyaWJlcnMsIGVycm9yLCByZXN1bHQpO1xuICAgICAgICB9LmJpbmQodGhpcyksIDApO1xuICAgIH07XG59KTtcblxuLyoqXG4gKiBzZXRBZFZvbHVtZVxuICpcbiAqIEBwYXJhbSB2b2x1bWVcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cblZQQUlEQWRVbml0LnByb3RvdHlwZS5zZXRBZFZvbHVtZSA9IGZ1bmN0aW9uIHNldEFkVm9sdW1lKHZvbHVtZSwgY2FsbGJhY2spIHtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcblxuICAgICAgICB2YXIgcmVzdWx0LCBlcnJvciA9IG51bGw7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLl9jcmVhdGl2ZS5zZXRBZFZvbHVtZSh2b2x1bWUpO1xuICAgICAgICAgICAgcmVzdWx0ID0gdGhpcy5fY3JlYXRpdmUuZ2V0QWRWb2x1bWUoKTtcbiAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgICBlcnJvciA9IGU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWVycm9yKSB7XG4gICAgICAgICAgICBlcnJvciA9IHV0aWxzLnZhbGlkYXRlKHJlc3VsdCA9PT0gdm9sdW1lLCAnZmFpbGVkIHRvIGFwcGx5IHZvbHVtZTogJyArIHZvbHVtZSk7XG4gICAgICAgIH1cbiAgICAgICAgY2FsbE9yVHJpZ2dlckV2ZW50KGNhbGxiYWNrLCB0aGlzLl9zdWJzY3JpYmVycywgZXJyb3IsIHJlc3VsdCk7XG4gICAgfS5iaW5kKHRoaXMpLCAwKTtcbn07XG5cblZQQUlEQWRVbml0LnByb3RvdHlwZS5fZGVzdHJveSA9IGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgdGhpcy5zdG9wQWQoKTtcbiAgICB0aGlzLl9zdWJzY3JpYmVycy51bnN1YnNjcmliZUFsbCgpO1xufTtcblxuZnVuY3Rpb24gJGFkZEV2ZW50c1N1YnNjcmliZXJzKCkge1xuICAgIC8vIHNvbWUgYWRzIGltcGxlbWVudFxuICAgIC8vIHNvIHRoZXkgb25seSBoYW5kbGUgb25lIHN1YnNjcmliZXJcbiAgICAvLyB0byBoYW5kbGUgdGhpcyB3ZSBjcmVhdGUgb3VyIG9uZVxuICAgIEZJTFRFUkVEX0VWRU5UUy5mb3JFYWNoKGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICB0aGlzLl9jcmVhdGl2ZS5zdWJzY3JpYmUoJHRyaWdnZXIuYmluZCh0aGlzLCBldmVudCksIGV2ZW50KTtcbiAgICB9LmJpbmQodGhpcykpO1xuXG4gICAgLy8gbWFwIHRoZSBjbGljayBldmVudCB0byBiZSBhbiBvYmplY3QgaW5zdGVhZCBvZiBkZXBlbmRpbmcgb2YgdGhlIG9yZGVyIG9mIHRoZSBhcmd1bWVudHNcbiAgICAvLyBhbmQgdG8gYmUgY29uc2lzdGVudCB3aXRoIHRoZSBmbGFzaFxuICAgIHRoaXMuX2NyZWF0aXZlLnN1YnNjcmliZSgkY2xpY2tUaHJ1SG9vay5iaW5kKHRoaXMpLCBBRF9DTElDSyk7XG5cbiAgICAvLyBiZWNhdXNlIHdlIGFyZSBhZGRpbmcgdGhlIGVsZW1lbnQgaW5zaWRlIHRoZSBpZnJhbWVcbiAgICAvLyB0aGUgdXNlciBpcyBub3QgYWJsZSB0byBjbGljayBpbiB0aGUgdmlkZW9cbiAgICBpZiAodGhpcy5fdmlkZW9FbCkge1xuICAgICAgICB2YXIgZG9jdW1lbnRFbGVtZW50ID0gdGhpcy5faWZyYW1lLmNvbnRlbnREb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gICAgICAgIHZhciB2aWRlb0VsID0gdGhpcy5fdmlkZW9FbDtcbiAgICAgICAgZG9jdW1lbnRFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgaWYgKGUudGFyZ2V0ID09PSBkb2N1bWVudEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB2aWRlb0VsLmNsaWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gJGNsaWNrVGhydUhvb2sodXJsLCBpZCwgcGxheWVySGFuZGxlcykge1xuICAgIHRoaXMuX3N1YnNjcmliZXJzLnRyaWdnZXJTeW5jKEFEX0NMSUNLLCB7dXJsOiB1cmwsIGlkOiBpZCwgcGxheWVySGFuZGxlczogcGxheWVySGFuZGxlc30pO1xufVxuXG5mdW5jdGlvbiAkdHJpZ2dlcihldmVudCkge1xuICAgIC8vIFRPRE8gYXZvaWQgbGVha2luZyBhcmd1bWVudHNcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vcGV0a2FhbnRvbm92L2JsdWViaXJkL3dpa2kvT3B0aW1pemF0aW9uLWtpbGxlcnMjMzItbGVha2luZy1hcmd1bWVudHNcbiAgICB0aGlzLl9zdWJzY3JpYmVycy50cmlnZ2VyKGV2ZW50LCBBcnJheS5wcm90b3R5cGUuc2xpY2UoYXJndW1lbnRzLCAxKSk7XG59XG5cbmZ1bmN0aW9uIGNhbGxPclRyaWdnZXJFdmVudChjYWxsYmFjaywgc3Vic2NyaWJlcnMsIGVycm9yLCByZXN1bHQpIHtcbiAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgfSBlbHNlIGlmIChlcnJvcikge1xuICAgICAgICBzdWJzY3JpYmVycy50cmlnZ2VyKEVSUk9SLCBlcnJvcik7XG4gICAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFZQQUlEQWRVbml0O1xuXG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciB1bmlxdWUgPSB1dGlscy51bmlxdWUoJ3ZwYWlkSWZyYW1lJyk7XG52YXIgVlBBSURBZFVuaXQgPSByZXF1aXJlKCcuL1ZQQUlEQWRVbml0Jyk7XG5cbnZhciBkZWZhdWx0VGVtcGxhdGUgPSAnPCFET0NUWVBFIGh0bWw+JyArXG4gICAgJzxodG1sIGxhbmc9XCJlblwiPicgK1xuICAgICc8aGVhZD48bWV0YSBjaGFyc2V0PVwiVVRGLThcIj48L2hlYWQ+JyArXG4gICAgJzxib2R5IHN0eWxlPVwibWFyZ2luOjA7cGFkZGluZzowXCI+PGRpdiBjbGFzcz1cImFkLWVsZW1lbnRcIj48L2Rpdj4nICtcbiAgICAnPHNjcmlwdCB0eXBlPVwidGV4dC9qYXZhc2NyaXB0XCIgc3JjPVwie3tpZnJhbWVVUkxfSlN9fVwiPjwvc2NyaXB0PicgK1xuICAgICc8c2NyaXB0IHR5cGU9XCJ0ZXh0L2phdmFzY3JpcHRcIj4nICtcbiAgICAnd2luZG93LnBhcmVudC5wb3N0TWVzc2FnZShcXCd7XCJldmVudFwiOiBcInJlYWR5XCIsIFwiaWRcIjogXCJ7e2lmcmFtZUlEfX1cIn1cXCcsIFxcJ3t7b3JpZ2lufX1cXCcpOycgK1xuICAgICc8L3NjcmlwdD4nICtcbiAgICAnPC9ib2R5PicgK1xuICAgICc8L2h0bWw+JztcblxudmFyIEFEX1NUT1BQRUQgPSAnQWRTdG9wcGVkJztcblxuLyoqXG4gKiBUaGlzIGNhbGxiYWNrIGlzIGRpc3BsYXllZCBhcyBnbG9iYWwgbWVtYmVyLiBUaGUgY2FsbGJhY2sgdXNlIG5vZGVqcyBlcnJvci1maXJzdCBjYWxsYmFjayBzdHlsZVxuICogQGNhbGxiYWNrIE5vZGVTdHlsZUNhbGxiYWNrXG4gKiBAcGFyYW0ge3N0cmluZ3xudWxsfVxuICogQHBhcmFtIHt1bmRlZmluZWR8b2JqZWN0fVxuICovXG5cbi8qKlxuICogVlBBSURIVE1MNUNsaWVudFxuICogQGNsYXNzXG4gKlxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWwgdGhhdCB3aWxsIGNvbnRhaW4gdGhlIGlmcmFtZSB0byBsb2FkIGFkVW5pdCBhbmQgYSBlbCB0byBhZGQgdG8gYWRVbml0IHNsb3RcbiAqIEBwYXJhbSB7SFRNTFZpZGVvRWxlbWVudH0gdmlkZW8gZGVmYXVsdCB2aWRlbyBlbGVtZW50IHRvIGJlIHVzZWQgYnkgYWRVbml0XG4gKiBAcGFyYW0ge29iamVjdH0gW3RlbXBsYXRlQ29uZmlnXSB0ZW1wbGF0ZTogaHRtbCB0ZW1wbGF0ZSB0byBiZSB1c2VkIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQsIGV4dHJhT3B0aW9uczogdG8gYmUgdXNlZCB3aGVuIHJlbmRlcmluZyB0aGUgdGVtcGxhdGVcbiAqIEBwYXJhbSB7b2JqZWN0fSBbdnBhaWRPcHRpb25zXSB0aW1lb3V0OiB3aGVuIGxvYWRpbmcgYWRVbml0XG4gKi9cbmZ1bmN0aW9uIFZQQUlESFRNTDVDbGllbnQoZWwsIHZpZGVvLCB0ZW1wbGF0ZUNvbmZpZywgdnBhaWRPcHRpb25zKSB7XG4gICAgdGVtcGxhdGVDb25maWcgPSB0ZW1wbGF0ZUNvbmZpZyB8fCB7fTtcblxuICAgIHRoaXMuX2lkID0gdW5pcXVlKCk7XG4gICAgdGhpcy5fZGVzdHJveWVkID0gZmFsc2U7XG5cbiAgICB0aGlzLl9mcmFtZUNvbnRhaW5lciA9IHV0aWxzLmNyZWF0ZUVsZW1lbnRJbkVsKGVsLCAnZGl2Jyk7XG4gICAgdGhpcy5fdmlkZW9FbCA9IHZpZGVvO1xuICAgIHRoaXMuX3ZwYWlkT3B0aW9ucyA9IHZwYWlkT3B0aW9ucyB8fCB7dGltZW91dDogMTAwMDB9O1xuXG4gICAgdGhpcy5fdGVtcGxhdGVDb25maWcgPSB7XG4gICAgICAgIHRlbXBsYXRlOiB0ZW1wbGF0ZUNvbmZpZy50ZW1wbGF0ZSB8fCBkZWZhdWx0VGVtcGxhdGUsXG4gICAgICAgIGV4dHJhT3B0aW9uczogdGVtcGxhdGVDb25maWcuZXh0cmFPcHRpb25zIHx8IHt9XG4gICAgfTtcbn1cblxuLyoqXG4gKiBkZXN0cm95XG4gKlxuICovXG5WUEFJREhUTUw1Q2xpZW50LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gZGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy5fZGVzdHJveWVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fZGVzdHJveWVkID0gdHJ1ZTtcbiAgICAkdW5sb2FkUHJldmlvdXNBZFVuaXQuY2FsbCh0aGlzKTtcbn07XG5cbi8qKlxuICogaXNEZXN0cm95ZWRcbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5WUEFJREhUTUw1Q2xpZW50LnByb3RvdHlwZS5pc0Rlc3Ryb3llZCA9IGZ1bmN0aW9uIGlzRGVzdHJveWVkKCkge1xuICAgIHJldHVybiB0aGlzLl9kZXN0cm95ZWQ7XG59O1xuXG4vKipcbiAqIGxvYWRBZFVuaXRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gYWRVUkwgdXJsIG9mIHRoZSBqcyBvZiB0aGUgYWRVbml0XG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5WUEFJREhUTUw1Q2xpZW50LnByb3RvdHlwZS5sb2FkQWRVbml0ID0gZnVuY3Rpb24gbG9hZEFkVW5pdChhZFVSTCwgY2FsbGJhY2spIHtcbiAgICAkdGhyb3dJZkRlc3Ryb3llZC5jYWxsKHRoaXMpO1xuICAgICR1bmxvYWRQcmV2aW91c0FkVW5pdC5jYWxsKHRoaXMpO1xuICAgIHZhciB0aGF0ID0gdGhpcztcblxuICAgIHZhciBmcmFtZSA9IHV0aWxzLmNyZWF0ZUlmcmFtZVdpdGhDb250ZW50KFxuICAgICAgICB0aGlzLl9mcmFtZUNvbnRhaW5lcixcbiAgICAgICAgdGhpcy5fdGVtcGxhdGVDb25maWcudGVtcGxhdGUsXG4gICAgICAgIHV0aWxzLmV4dGVuZCh7XG4gICAgICAgICAgICBpZnJhbWVVUkxfSlM6IGFkVVJMLFxuICAgICAgICAgICAgaWZyYW1lSUQ6IHRoaXMuZ2V0SUQoKSxcbiAgICAgICAgICAgIG9yaWdpbjogZ2V0T3JpZ2luKClcbiAgICAgICAgfSwgdGhpcy5fdGVtcGxhdGVDb25maWcuZXh0cmFPcHRpb25zKVxuICAgICk7XG5cbiAgICB0aGlzLl9mcmFtZSA9IGZyYW1lO1xuXG4gICAgdGhpcy5fb25Mb2FkID0gdXRpbHMuY2FsbGJhY2tUaW1lb3V0KFxuICAgICAgICB0aGlzLl92cGFpZE9wdGlvbnMudGltZW91dCxcbiAgICAgICAgb25Mb2FkLmJpbmQodGhpcyksXG4gICAgICAgIG9uVGltZW91dC5iaW5kKHRoaXMpXG4gICAgKTtcblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdGhpcy5fb25Mb2FkKTtcblxuICAgIGZ1bmN0aW9uIG9uTG9hZCAoZSkge1xuICAgICAgICAvKmpzaGludCB2YWxpZHRoaXM6IGZhbHNlICovXG4gICAgICAgIC8vZG9uJ3QgY2xlYXIgdGltZW91dFxuICAgICAgICBpZiAoZS5vcmlnaW4gIT09IGdldE9yaWdpbigpKSByZXR1cm47XG4gICAgICAgIHZhciByZXN1bHQgPSBKU09OLnBhcnNlKGUuZGF0YSk7XG5cbiAgICAgICAgLy9kb24ndCBjbGVhciB0aW1lb3V0XG4gICAgICAgIGlmIChyZXN1bHQuaWQgIT09IHRoYXQuZ2V0SUQoKSkgcmV0dXJuO1xuXG4gICAgICAgIHZhciBhZFVuaXQsIGVycm9yLCBjcmVhdGVBZDtcbiAgICAgICAgaWYgKCF0aGF0Ll9mcmFtZS5jb250ZW50V2luZG93KSB7XG5cbiAgICAgICAgICAgIGVycm9yID0gJ3RoZSBpZnJhbWUgaXMgbm90IGFueW1vcmUgaW4gdGhlIERPTSB0cmVlJztcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY3JlYXRlQWQgPSB0aGF0Ll9mcmFtZS5jb250ZW50V2luZG93LmdldFZQQUlEQWQ7XG4gICAgICAgICAgICBlcnJvciA9IHV0aWxzLnZhbGlkYXRlKHR5cGVvZiBjcmVhdGVBZCA9PT0gJ2Z1bmN0aW9uJywgJ3RoZSBhZCBkaWRuXFwndCByZXR1cm4gYSBmdW5jdGlvbiB0byBjcmVhdGUgYW4gYWQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghZXJyb3IpIHtcbiAgICAgICAgICAgIHZhciBhZEVsID0gdGhhdC5fZnJhbWUuY29udGVudFdpbmRvdy5kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuYWQtZWxlbWVudCcpO1xuICAgICAgICAgICAgYWRVbml0ID0gbmV3IFZQQUlEQWRVbml0KGNyZWF0ZUFkKCksIGFkRWwsIHRoYXQuX3ZpZGVvRWwsIHRoYXQuX2ZyYW1lKTtcbiAgICAgICAgICAgIGFkVW5pdC5zdWJzY3JpYmUoQURfU1RPUFBFRCwgJGFkRGVzdHJveWVkLmJpbmQodGhhdCkpO1xuICAgICAgICAgICAgZXJyb3IgPSB1dGlscy52YWxpZGF0ZShhZFVuaXQuaXNWYWxpZFZQQUlEQWQoKSwgJ3RoZSBhZGQgaXMgbm90IGZ1bGx5IGNvbXBsYWludCB3aXRoIFZQQUlEIHNwZWNpZmljYXRpb24nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoYXQuX2FkVW5pdCA9IGFkVW5pdDtcbiAgICAgICAgJGRlc3Ryb3lMb2FkTGlzdGVuZXIuY2FsbCh0aGF0KTtcbiAgICAgICAgY2FsbGJhY2soZXJyb3IsIGVycm9yID8gbnVsbCA6IGFkVW5pdCk7XG5cbiAgICAgICAgLy9jbGVhciB0aW1lb3V0XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG9uVGltZW91dCgpIHtcbiAgICAgICAgY2FsbGJhY2soJ3RpbWVvdXQnLCBudWxsKTtcbiAgICB9XG59O1xuXG4vKipcbiAqIHVubG9hZEFkVW5pdFxuICpcbiAqL1xuVlBBSURIVE1MNUNsaWVudC5wcm90b3R5cGUudW5sb2FkQWRVbml0ID0gZnVuY3Rpb24gdW5sb2FkQWRVbml0KCkge1xuICAgICR1bmxvYWRQcmV2aW91c0FkVW5pdC5jYWxsKHRoaXMpO1xufTtcblxuLyoqXG4gKiBnZXRJRCB3aWxsIHJldHVybiB0aGUgdW5pcXVlIGlkXG4gKlxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5WUEFJREhUTUw1Q2xpZW50LnByb3RvdHlwZS5nZXRJRCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5faWQ7XG59O1xuXG5cbi8qKlxuICogJHJlbW92ZUVsXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGtleVxuICovXG5mdW5jdGlvbiAkcmVtb3ZlRWwoa2V5KSB7XG4gICAgdmFyIGVsID0gdGhpc1trZXldO1xuICAgIGlmIChlbCkge1xuICAgICAgICBlbC5yZW1vdmUoKTtcbiAgICAgICAgZGVsZXRlIHRoaXNba2V5XTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uICRhZERlc3Ryb3llZCgpIHtcbiAgICAkcmVtb3ZlQWRFbGVtZW50cy5jYWxsKHRoaXMpO1xuICAgIGRlbGV0ZSB0aGlzLl9hZFVuaXQ7XG59XG5cbmZ1bmN0aW9uICR1bmxvYWRQcmV2aW91c0FkVW5pdCgpIHtcbiAgICAkcmVtb3ZlQWRFbGVtZW50cy5jYWxsKHRoaXMpO1xuICAgICRkZXN0cm95QWRVbml0LmNhbGwodGhpcyk7XG59XG5cbmZ1bmN0aW9uICRyZW1vdmVBZEVsZW1lbnRzKCkge1xuICAgICRyZW1vdmVFbC5jYWxsKHRoaXMsICdfZnJhbWUnKTtcbiAgICAkZGVzdHJveUxvYWRMaXN0ZW5lci5jYWxsKHRoaXMpO1xufVxuXG4vKipcbiAqICRkZXN0cm95TG9hZExpc3RlbmVyXG4gKlxuICovXG5mdW5jdGlvbiAkZGVzdHJveUxvYWRMaXN0ZW5lcigpIHtcbiAgICBpZiAodGhpcy5fb25Mb2FkKSB7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdGhpcy5fb25Mb2FkKTtcbiAgICAgICAgdXRpbHMuY2xlYXJDYWxsYmFja1RpbWVvdXQodGhpcy5fb25Mb2FkKTtcbiAgICAgICAgZGVsZXRlIHRoaXMuX29uTG9hZDtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gJGRlc3Ryb3lBZFVuaXQoKSB7XG4gICAgaWYgKHRoaXMuX2FkVW5pdCkge1xuICAgICAgICB0aGlzLl9hZFVuaXQuc3RvcEFkKCk7XG4gICAgICAgIGRlbGV0ZSB0aGlzLl9hZFVuaXQ7XG4gICAgfVxufVxuXG4vKipcbiAqICR0aHJvd0lmRGVzdHJveWVkXG4gKlxuICovXG5mdW5jdGlvbiAkdGhyb3dJZkRlc3Ryb3llZCgpIHtcbiAgICBpZiAodGhpcy5fZGVzdHJveWVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvciAoJ1ZQQUlESFRNTDVDbGllbnQgYWxyZWFkeSBkZXN0cm95ZWQhJyk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBnZXRPcmlnaW4oKSB7XG4gICAgaWYoIHdpbmRvdy5sb2NhdGlvbi5vcmlnaW4gKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cubG9jYXRpb24ub3JpZ2luO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCArIFwiLy9cIiArXG4gICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaG9zdG5hbWUgK1xuICAgICAgICAgICAgKHdpbmRvdy5sb2NhdGlvbi5wb3J0ID8gJzonICsgd2luZG93LmxvY2F0aW9uLnBvcnQ6ICcnKTtcbiAgICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gVlBBSURIVE1MNUNsaWVudDtcbndpbmRvdy5WUEFJREhUTUw1Q2xpZW50ID0gVlBBSURIVE1MNUNsaWVudDtcblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBTdWJzY3JpYmVyKCkge1xuICAgIHRoaXMuX3N1YnNjcmliZXJzID0ge307XG59XG5cblN1YnNjcmliZXIucHJvdG90eXBlLnN1YnNjcmliZSA9IGZ1bmN0aW9uIHN1YnNjcmliZShoYW5kbGVyLCBldmVudE5hbWUsIGNvbnRleHQpIHtcbiAgICBpZiAoIXRoaXMuaXNIYW5kbGVyQXR0YWNoZWQoaGFuZGxlciwgZXZlbnROYW1lKSkge1xuICAgICAgICB0aGlzLmdldChldmVudE5hbWUpLnB1c2goe2hhbmRsZXI6IGhhbmRsZXIsIGNvbnRleHQ6IGNvbnRleHQsIGV2ZW50TmFtZTogZXZlbnROYW1lfSk7XG4gICAgfVxufTtcblxuU3Vic2NyaWJlci5wcm90b3R5cGUudW5zdWJzY3JpYmUgPSBmdW5jdGlvbiB1bnN1YnNjcmliZShoYW5kbGVyLCBldmVudE5hbWUpIHtcbiAgICB0aGlzLl9zdWJzY3JpYmVyc1tldmVudE5hbWVdID0gdGhpcy5nZXQoZXZlbnROYW1lKS5maWx0ZXIoZnVuY3Rpb24gKHN1YnNjcmliZXIpIHtcbiAgICAgICAgcmV0dXJuIGhhbmRsZXIgIT09IHN1YnNjcmliZXIuaGFuZGxlcjtcbiAgICB9KTtcbn07XG5cblN1YnNjcmliZXIucHJvdG90eXBlLnVuc3Vic2NyaWJlQWxsID0gZnVuY3Rpb24gdW5zdWJzY3JpYmVBbGwoKSB7XG4gICAgdGhpcy5fc3Vic2NyaWJlcnMgPSB7fTtcbn07XG5cblN1YnNjcmliZXIucHJvdG90eXBlLnRyaWdnZXIgPSBmdW5jdGlvbihldmVudE5hbWUsIGRhdGEpIHtcbiAgICB2YXIgdGhhdCA9IHRoaXM7XG4gICAgdmFyIHN1YnNjcmliZXJzID0gdGhpcy5nZXQoZXZlbnROYW1lKVxuICAgICAgICAuY29uY2F0KHRoaXMuZ2V0KCcqJykpO1xuXG4gICAgc3Vic2NyaWJlcnMuZm9yRWFjaChmdW5jdGlvbiAoc3Vic2NyaWJlcikge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICh0aGF0LmlzSGFuZGxlckF0dGFjaGVkKHN1YnNjcmliZXIuaGFuZGxlciwgc3Vic2NyaWJlci5ldmVudE5hbWUpKSB7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5oYW5kbGVyLmNhbGwoc3Vic2NyaWJlci5jb250ZXh0LCBkYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgMCk7XG4gICAgfSk7XG59O1xuXG5TdWJzY3JpYmVyLnByb3RvdHlwZS50cmlnZ2VyU3luYyA9IGZ1bmN0aW9uKGV2ZW50TmFtZSwgZGF0YSkge1xuICAgIHZhciBzdWJzY3JpYmVycyA9IHRoaXMuZ2V0KGV2ZW50TmFtZSlcbiAgICAgICAgLmNvbmNhdCh0aGlzLmdldCgnKicpKTtcblxuICAgIHN1YnNjcmliZXJzLmZvckVhY2goZnVuY3Rpb24gKHN1YnNjcmliZXIpIHtcbiAgICAgICAgc3Vic2NyaWJlci5oYW5kbGVyLmNhbGwoc3Vic2NyaWJlci5jb250ZXh0LCBkYXRhKTtcbiAgICB9KTtcbn07XG5cblN1YnNjcmliZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIGdldChldmVudE5hbWUpIHtcbiAgICBpZiAoIXRoaXMuX3N1YnNjcmliZXJzW2V2ZW50TmFtZV0pIHtcbiAgICAgICAgdGhpcy5fc3Vic2NyaWJlcnNbZXZlbnROYW1lXSA9IFtdO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc3Vic2NyaWJlcnNbZXZlbnROYW1lXTtcbn07XG5cblN1YnNjcmliZXIucHJvdG90eXBlLmlzSGFuZGxlckF0dGFjaGVkID0gZnVuY3Rpb24gaXNIYW5kbGVyQXR0YWNoZWQoaGFuZGxlciwgZXZlbnROYW1lKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGV2ZW50TmFtZSkuc29tZShmdW5jdGlvbihzdWJzY3JpYmVyKSB7XG4gICAgICAgIHJldHVybiBoYW5kbGVyID09PSBzdWJzY3JpYmVyLmhhbmRsZXI7XG4gICAgfSlcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gU3Vic2NyaWJlcjtcblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIG5vb3AgYSBlbXB0eSBmdW5jdGlvblxuICovXG5mdW5jdGlvbiBub29wKCkge31cblxuLyoqXG4gKiB2YWxpZGF0ZSBpZiBpcyBub3QgdmFsaWRhdGUgd2lsbCByZXR1cm4gYW4gRXJyb3Igd2l0aCB0aGUgbWVzc2FnZVxuICpcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNWYWxpZFxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2VcbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGUoaXNWYWxpZCwgbWVzc2FnZSkge1xuICAgIHJldHVybiBpc1ZhbGlkID8gbnVsbCA6IG5ldyBFcnJvcihtZXNzYWdlKTtcbn1cblxudmFyIHRpbWVvdXRzID0ge307XG4vKipcbiAqIGNsZWFyQ2FsbGJhY2tUaW1lb3V0XG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gZnVuYyBoYW5kbGVyIHRvIHJlbW92ZVxuICovXG5mdW5jdGlvbiBjbGVhckNhbGxiYWNrVGltZW91dChmdW5jKSB7XG4gICAgdmFyIHRpbWVvdXQgPSB0aW1lb3V0c1tmdW5jXTtcbiAgICBpZiAodGltZW91dCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgIGRlbGV0ZSB0aW1lb3V0c1tmdW5jXTtcbiAgICB9XG59XG5cbi8qKlxuICogY2FsbGJhY2tUaW1lb3V0IGlmIHRoZSBvblN1Y2Nlc3MgaXMgbm90IGNhbGxlZCBhbmQgcmV0dXJucyB0cnVlIGluIHRoZSB0aW1lbGltaXQgdGhlbiBvblRpbWVvdXQgd2lsbCBiZSBjYWxsZWRcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gdGltZXJcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IG9uU3VjY2Vzc1xuICogQHBhcmFtIHtmdW5jdGlvbn0gb25UaW1lb3V0XG4gKi9cbmZ1bmN0aW9uIGNhbGxiYWNrVGltZW91dCh0aW1lciwgb25TdWNjZXNzLCBvblRpbWVvdXQpIHtcbiAgICB2YXIgY2FsbGJhY2ssIHRpbWVvdXQ7XG5cbiAgICB0aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIG9uU3VjY2VzcyA9IG5vb3A7XG4gICAgICAgIGRlbGV0ZSB0aW1lb3V0W2NhbGxiYWNrXTtcbiAgICAgICAgb25UaW1lb3V0KCk7XG4gICAgfSwgdGltZXIpO1xuXG4gICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIFRPRE8gYXZvaWQgbGVha2luZyBhcmd1bWVudHNcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3BldGthYW50b25vdi9ibHVlYmlyZC93aWtpL09wdGltaXphdGlvbi1raWxsZXJzIzMyLWxlYWtpbmctYXJndW1lbnRzXG4gICAgICAgIGlmIChvblN1Y2Nlc3MuYXBwbHkodGhpcywgYXJndW1lbnRzKSkge1xuICAgICAgICAgICAgY2xlYXJDYWxsYmFja1RpbWVvdXQoY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHRpbWVvdXRzW2NhbGxiYWNrXSA9IHRpbWVvdXQ7XG5cbiAgICByZXR1cm4gY2FsbGJhY2s7XG59XG5cblxuLyoqXG4gKiBjcmVhdGVFbGVtZW50SW5FbFxuICpcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHBhcmVudFxuICogQHBhcmFtIHtzdHJpbmd9IHRhZ05hbWVcbiAqIEBwYXJhbSB7c3RyaW5nfSBpZFxuICovXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50SW5FbChwYXJlbnQsIHRhZ05hbWUsIGlkKSB7XG4gICAgdmFyIG5FbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSk7XG4gICAgaWYgKGlkKSBuRWwuaWQgPSBpZDtcbiAgICBwYXJlbnQuYXBwZW5kQ2hpbGQobkVsKTtcbiAgICByZXR1cm4gbkVsO1xufVxuXG4vKipcbiAqIGNyZWF0ZUlmcmFtZVdpdGhDb250ZW50XG4gKlxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gcGFyZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gdGVtcGxhdGUgc2ltcGxlIHRlbXBsYXRlIHVzaW5nIHt7dmFyfX1cbiAqIEBwYXJhbSB7b2JqZWN0fSBkYXRhXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUlmcmFtZVdpdGhDb250ZW50KHBhcmVudCwgdGVtcGxhdGUsIGRhdGEpIHtcbiAgICB2YXIgaWZyYW1lID0gY3JlYXRlSWZyYW1lKHBhcmVudCwgbnVsbCwgZGF0YS56SW5kZXgpO1xuICAgIGlmICghc2V0SWZyYW1lQ29udGVudChpZnJhbWUsIHNpbXBsZVRlbXBsYXRlKHRlbXBsYXRlLCBkYXRhKSkpIHJldHVybjtcbiAgICByZXR1cm4gaWZyYW1lO1xufVxuXG4vKipcbiAqIGNyZWF0ZUlmcmFtZVxuICpcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHBhcmVudFxuICogQHBhcmFtIHtzdHJpbmd9IHVybFxuICovXG5mdW5jdGlvbiBjcmVhdGVJZnJhbWUocGFyZW50LCB1cmwsIHpJbmRleCkge1xuICAgIHZhciBuRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICBuRWwuc3JjID0gdXJsIHx8ICdhYm91dDpibGFuayc7XG4gICAgbkVsLm1hcmdpbldpZHRoID0gJzAnO1xuICAgIG5FbC5tYXJnaW5IZWlnaHQgPSAnMCc7XG4gICAgbkVsLmZyYW1lQm9yZGVyID0gJzAnO1xuICAgIG5FbC53aWR0aCA9ICcxMDAlJztcbiAgICBuRWwuaGVpZ2h0ID0gJzEwMCUnO1xuICAgIG5FbC5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgbkVsLnN0eWxlLmxlZnQgPSAnMCc7XG4gICAgbkVsLnN0eWxlLnRvcCA9ICcwJztcbiAgICBuRWwuc3R5bGUubWFyZ2luID0gJzBweCc7XG4gICAgbkVsLnN0eWxlLnBhZGRpbmcgPSAnMHB4JztcbiAgICBuRWwuc3R5bGUuYm9yZGVyID0gJ25vbmUnO1xuXG4gICAgaWYoekluZGV4KXtcbiAgICAgICAgbkVsLnN0eWxlLnpJbmRleCA9IHpJbmRleDtcbiAgICB9XG5cbiAgICBuRWwuc2V0QXR0cmlidXRlKCdTQ1JPTExJTkcnLCdOTycpO1xuICAgIHBhcmVudC5pbm5lckhUTUwgPSAnJztcbiAgICBwYXJlbnQuYXBwZW5kQ2hpbGQobkVsKTtcbiAgICByZXR1cm4gbkVsO1xufVxuXG4vKipcbiAqIHNpbXBsZVRlbXBsYXRlXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRlbXBsYXRlXG4gKiBAcGFyYW0ge29iamVjdH0gZGF0YVxuICovXG5mdW5jdGlvbiBzaW1wbGVUZW1wbGF0ZSh0ZW1wbGF0ZSwgZGF0YSkge1xuICAgIE9iamVjdC5rZXlzKGRhdGEpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgICB2YXIgdmFsdWUgPSAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JykgPyBKU09OLnN0cmluZ2lmeShkYXRhW2tleV0pIDogZGF0YVtrZXldO1xuICAgICAgICB0ZW1wbGF0ZSA9IHRlbXBsYXRlLnJlcGxhY2UobmV3IFJlZ0V4cCgne3snICsga2V5ICsgJ319JywgJ2cnKSwgdmFsdWUpO1xuICAgIH0pO1xuICAgIHJldHVybiB0ZW1wbGF0ZTtcbn1cblxuLyoqXG4gKiBzZXRJZnJhbWVDb250ZW50XG4gKlxuICogQHBhcmFtIHtIVE1MSWZyYW1lRWxlbWVudH0gaWZyYW1lRWxcbiAqIEBwYXJhbSBjb250ZW50XG4gKi9cbmZ1bmN0aW9uIHNldElmcmFtZUNvbnRlbnQoaWZyYW1lRWwsIGNvbnRlbnQpIHtcbiAgICB2YXIgaWZyYW1lRG9jID0gaWZyYW1lRWwuY29udGVudFdpbmRvdyAmJiBpZnJhbWVFbC5jb250ZW50V2luZG93LmRvY3VtZW50O1xuICAgIGlmICghaWZyYW1lRG9jKSByZXR1cm4gZmFsc2U7XG5cbiAgICBpZnJhbWVEb2Mud3JpdGUoY29udGVudCk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuXG4vKipcbiAqIGV4dGVuZCBvYmplY3Qgd2l0aCBrZXlzIGZyb20gYW5vdGhlciBvYmplY3RcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gdG9FeHRlbmRcbiAqIEBwYXJhbSB7b2JqZWN0fSBmcm9tU291cmNlXG4gKi9cbmZ1bmN0aW9uIGV4dGVuZCh0b0V4dGVuZCwgZnJvbVNvdXJjZSkge1xuICAgIE9iamVjdC5rZXlzKGZyb21Tb3VyY2UpLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG4gICAgICAgIHRvRXh0ZW5kW2tleV0gPSBmcm9tU291cmNlW2tleV07XG4gICAgfSk7XG4gICAgcmV0dXJuIHRvRXh0ZW5kO1xufVxuXG5cbi8qKlxuICogdW5pcXVlIHdpbGwgY3JlYXRlIGEgdW5pcXVlIHN0cmluZyBldmVyeXRpbWUgaXMgY2FsbGVkLCBzZXF1ZW50aWFsbHkgYW5kIHByZWZpeGVkXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHByZWZpeFxuICovXG5mdW5jdGlvbiB1bmlxdWUocHJlZml4KSB7XG4gICAgdmFyIGNvdW50ID0gLTE7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHByZWZpeCArICdfJyArICgrK2NvdW50KTtcbiAgICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBub29wOiBub29wLFxuICAgIHZhbGlkYXRlOiB2YWxpZGF0ZSxcbiAgICBjbGVhckNhbGxiYWNrVGltZW91dDogY2xlYXJDYWxsYmFja1RpbWVvdXQsXG4gICAgY2FsbGJhY2tUaW1lb3V0OiBjYWxsYmFja1RpbWVvdXQsXG4gICAgY3JlYXRlRWxlbWVudEluRWw6IGNyZWF0ZUVsZW1lbnRJbkVsLFxuICAgIGNyZWF0ZUlmcmFtZVdpdGhDb250ZW50OiBjcmVhdGVJZnJhbWVXaXRoQ29udGVudCxcbiAgICBjcmVhdGVJZnJhbWU6IGNyZWF0ZUlmcmFtZSxcbiAgICBzaW1wbGVUZW1wbGF0ZTogc2ltcGxlVGVtcGxhdGUsXG4gICAgc2V0SWZyYW1lQ29udGVudDogc2V0SWZyYW1lQ29udGVudCxcbiAgICBleHRlbmQ6IGV4dGVuZCxcbiAgICB1bmlxdWU6IHVuaXF1ZVxufTtcblxuIiwiLyohICAgIFNXRk9iamVjdCB2Mi4zLjIwMTMwNTIxIDxodHRwOi8vZ2l0aHViLmNvbS9zd2ZvYmplY3Qvc3dmb2JqZWN0PlxyXG4gICAgaXMgcmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlIDxodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocD5cclxuKi9cclxuXHJcbi8qIGdsb2JhbCBBY3RpdmVYT2JqZWN0OiBmYWxzZSAqL1xyXG5cclxuKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7XHJcbiAgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xyXG4gICAgLy8gQU1EXHJcbiAgICBkZWZpbmUoZmFjdG9yeSk7XHJcbiAgfSBlbHNlIGlmICh0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykge1xyXG4gICAgLy8gTm9kZSwgQ29tbW9uSlMtbGlrZVxyXG4gICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCk7XHJcbiAgfSBlbHNlIHtcclxuICAgIC8vIEJyb3dzZXIgZ2xvYmFscyAocm9vdCBpcyB3aW5kb3cpXHJcbiAgICByb290LnN3Zm9iamVjdCA9IGZhY3RvcnkoKTtcclxuICB9XHJcbn0odGhpcywgZnVuY3Rpb24gKCkge1xyXG5cclxuICAgIHZhciBVTkRFRiA9IFwidW5kZWZpbmVkXCIsXHJcbiAgICAgICAgT0JKRUNUID0gXCJvYmplY3RcIixcclxuICAgICAgICBTSE9DS1dBVkVfRkxBU0ggPSBcIlNob2Nrd2F2ZSBGbGFzaFwiLFxyXG4gICAgICAgIFNIT0NLV0FWRV9GTEFTSF9BWCA9IFwiU2hvY2t3YXZlRmxhc2guU2hvY2t3YXZlRmxhc2hcIixcclxuICAgICAgICBGTEFTSF9NSU1FX1RZUEUgPSBcImFwcGxpY2F0aW9uL3gtc2hvY2t3YXZlLWZsYXNoXCIsXHJcbiAgICAgICAgRVhQUkVTU19JTlNUQUxMX0lEID0gXCJTV0ZPYmplY3RFeHBySW5zdFwiLFxyXG4gICAgICAgIE9OX1JFQURZX1NUQVRFX0NIQU5HRSA9IFwib25yZWFkeXN0YXRlY2hhbmdlXCIsXHJcblxyXG4gICAgICAgIHdpbiA9IHdpbmRvdyxcclxuICAgICAgICBkb2MgPSBkb2N1bWVudCxcclxuICAgICAgICBuYXYgPSBuYXZpZ2F0b3IsXHJcblxyXG4gICAgICAgIHBsdWdpbiA9IGZhbHNlLFxyXG4gICAgICAgIGRvbUxvYWRGbkFyciA9IFtdLFxyXG4gICAgICAgIHJlZ09iakFyciA9IFtdLFxyXG4gICAgICAgIG9iaklkQXJyID0gW10sXHJcbiAgICAgICAgbGlzdGVuZXJzQXJyID0gW10sXHJcbiAgICAgICAgc3RvcmVkRmJDb250ZW50LFxyXG4gICAgICAgIHN0b3JlZEZiQ29udGVudElkLFxyXG4gICAgICAgIHN0b3JlZENhbGxiYWNrRm4sXHJcbiAgICAgICAgc3RvcmVkQ2FsbGJhY2tPYmosXHJcbiAgICAgICAgaXNEb21Mb2FkZWQgPSBmYWxzZSxcclxuICAgICAgICBpc0V4cHJlc3NJbnN0YWxsQWN0aXZlID0gZmFsc2UsXHJcbiAgICAgICAgZHluYW1pY1N0eWxlc2hlZXQsXHJcbiAgICAgICAgZHluYW1pY1N0eWxlc2hlZXRNZWRpYSxcclxuICAgICAgICBhdXRvSGlkZVNob3cgPSB0cnVlLFxyXG4gICAgICAgIGVuY29kZVVSSUVuYWJsZWQgPSBmYWxzZSxcclxuXHJcbiAgICAvKiBDZW50cmFsaXplZCBmdW5jdGlvbiBmb3IgYnJvd3NlciBmZWF0dXJlIGRldGVjdGlvblxyXG4gICAgICAgIC0gVXNlciBhZ2VudCBzdHJpbmcgZGV0ZWN0aW9uIGlzIG9ubHkgdXNlZCB3aGVuIG5vIGdvb2QgYWx0ZXJuYXRpdmUgaXMgcG9zc2libGVcclxuICAgICAgICAtIElzIGV4ZWN1dGVkIGRpcmVjdGx5IGZvciBvcHRpbWFsIHBlcmZvcm1hbmNlXHJcbiAgICAqL1xyXG4gICAgdWEgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIHczY2RvbSA9IHR5cGVvZiBkb2MuZ2V0RWxlbWVudEJ5SWQgIT09IFVOREVGICYmIHR5cGVvZiBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUgIT09IFVOREVGICYmIHR5cGVvZiBkb2MuY3JlYXRlRWxlbWVudCAhPT0gVU5ERUYsXHJcbiAgICAgICAgICAgIHUgPSBuYXYudXNlckFnZW50LnRvTG93ZXJDYXNlKCksXHJcbiAgICAgICAgICAgIHAgPSBuYXYucGxhdGZvcm0udG9Mb3dlckNhc2UoKSxcclxuICAgICAgICAgICAgd2luZG93cyA9IHAgPyAvd2luLy50ZXN0KHApIDogL3dpbi8udGVzdCh1KSxcclxuICAgICAgICAgICAgbWFjID0gcCA/IC9tYWMvLnRlc3QocCkgOiAvbWFjLy50ZXN0KHUpLFxyXG4gICAgICAgICAgICB3ZWJraXQgPSAvd2Via2l0Ly50ZXN0KHUpID8gcGFyc2VGbG9hdCh1LnJlcGxhY2UoL14uKndlYmtpdFxcLyhcXGQrKFxcLlxcZCspPykuKiQvLCBcIiQxXCIpKSA6IGZhbHNlLCAvLyByZXR1cm5zIGVpdGhlciB0aGUgd2Via2l0IHZlcnNpb24gb3IgZmFsc2UgaWYgbm90IHdlYmtpdFxyXG4gICAgICAgICAgICBpZSA9IG5hdi5hcHBOYW1lID09PSBcIk1pY3Jvc29mdCBJbnRlcm5ldCBFeHBsb3JlclwiLFxyXG4gICAgICAgICAgICBwbGF5ZXJWZXJzaW9uID0gWzAsIDAsIDBdLFxyXG4gICAgICAgICAgICBkID0gbnVsbDtcclxuICAgICAgICBpZiAodHlwZW9mIG5hdi5wbHVnaW5zICE9PSBVTkRFRiAmJiB0eXBlb2YgbmF2LnBsdWdpbnNbU0hPQ0tXQVZFX0ZMQVNIXSA9PT0gT0JKRUNUKSB7XHJcbiAgICAgICAgICAgIGQgPSBuYXYucGx1Z2luc1tTSE9DS1dBVkVfRkxBU0hdLmRlc2NyaXB0aW9uO1xyXG4gICAgICAgICAgICAvLyBuYXYubWltZVR5cGVzW1wiYXBwbGljYXRpb24veC1zaG9ja3dhdmUtZmxhc2hcIl0uZW5hYmxlZFBsdWdpbiBpbmRpY2F0ZXMgd2hldGhlciBwbHVnLWlucyBhcmUgZW5hYmxlZCBvciBkaXNhYmxlZCBpbiBTYWZhcmkgMytcclxuICAgICAgICAgICAgaWYgKGQgJiYgKHR5cGVvZiBuYXYubWltZVR5cGVzICE9PSBVTkRFRiAmJiBuYXYubWltZVR5cGVzW0ZMQVNIX01JTUVfVFlQRV0gJiYgbmF2Lm1pbWVUeXBlc1tGTEFTSF9NSU1FX1RZUEVdLmVuYWJsZWRQbHVnaW4pKSB7XHJcbiAgICAgICAgICAgICAgICBwbHVnaW4gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgaWUgPSBmYWxzZTsgLy8gY2FzY2FkZWQgZmVhdHVyZSBkZXRlY3Rpb24gZm9yIEludGVybmV0IEV4cGxvcmVyXHJcbiAgICAgICAgICAgICAgICBkID0gZC5yZXBsYWNlKC9eLipcXHMrKFxcUytcXHMrXFxTKyQpLywgXCIkMVwiKTtcclxuICAgICAgICAgICAgICAgIHBsYXllclZlcnNpb25bMF0gPSB0b0ludChkLnJlcGxhY2UoL14oLiopXFwuLiokLywgXCIkMVwiKSk7XHJcbiAgICAgICAgICAgICAgICBwbGF5ZXJWZXJzaW9uWzFdID0gdG9JbnQoZC5yZXBsYWNlKC9eLipcXC4oLiopXFxzLiokLywgXCIkMVwiKSk7XHJcbiAgICAgICAgICAgICAgICBwbGF5ZXJWZXJzaW9uWzJdID0gL1thLXpBLVpdLy50ZXN0KGQpID8gdG9JbnQoZC5yZXBsYWNlKC9eLipbYS16QS1aXSsoLiopJC8sIFwiJDFcIikpIDogMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygd2luLkFjdGl2ZVhPYmplY3QgIT09IFVOREVGKSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgYSA9IG5ldyBBY3RpdmVYT2JqZWN0KFNIT0NLV0FWRV9GTEFTSF9BWCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoYSkgeyAvLyBhIHdpbGwgcmV0dXJuIG51bGwgd2hlbiBBY3RpdmVYIGlzIGRpc2FibGVkXHJcbiAgICAgICAgICAgICAgICAgICAgZCA9IGEuR2V0VmFyaWFibGUoXCIkdmVyc2lvblwiKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZSA9IHRydWU7IC8vIGNhc2NhZGVkIGZlYXR1cmUgZGV0ZWN0aW9uIGZvciBJbnRlcm5ldCBFeHBsb3JlclxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkID0gZC5zcGxpdChcIiBcIilbMV0uc3BsaXQoXCIsXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwbGF5ZXJWZXJzaW9uID0gW3RvSW50KGRbMF0pLCB0b0ludChkWzFdKSwgdG9JbnQoZFsyXSldO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXRjaCAoZSkge31cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHt3MzogdzNjZG9tLCBwdjogcGxheWVyVmVyc2lvbiwgd2s6IHdlYmtpdCwgaWU6IGllLCB3aW46IHdpbmRvd3MsIG1hYzogbWFjfTtcclxuICAgIH0oKSxcclxuXHJcbiAgICAvKiBDcm9zcy1icm93c2VyIG9uRG9tTG9hZFxyXG4gICAgICAgIC0gV2lsbCBmaXJlIGFuIGV2ZW50IGFzIHNvb24gYXMgdGhlIERPTSBvZiBhIHdlYiBwYWdlIGlzIGxvYWRlZFxyXG4gICAgICAgIC0gSW50ZXJuZXQgRXhwbG9yZXIgd29ya2Fyb3VuZCBiYXNlZCBvbiBEaWVnbyBQZXJpbmkncyBzb2x1dGlvbjogaHR0cDovL2phdmFzY3JpcHQubndib3guY29tL0lFQ29udGVudExvYWRlZC9cclxuICAgICAgICAtIFJlZ3VsYXIgb25sb2FkIHNlcnZlcyBhcyBmYWxsYmFja1xyXG4gICAgKi9cclxuICAgIG9uRG9tTG9hZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAoIXVhLnczKSB7IHJldHVybjsgfVxyXG4gICAgICAgIGlmICgodHlwZW9mIGRvYy5yZWFkeVN0YXRlICE9PSBVTkRFRiAmJiAoZG9jLnJlYWR5U3RhdGUgPT09IFwiY29tcGxldGVcIiB8fCBkb2MucmVhZHlTdGF0ZSA9PT0gXCJpbnRlcmFjdGl2ZVwiKSkgfHwgKHR5cGVvZiBkb2MucmVhZHlTdGF0ZSA9PT0gVU5ERUYgJiYgKGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZShcImJvZHlcIilbMF0gfHwgZG9jLmJvZHkpKSkgeyAvLyBmdW5jdGlvbiBpcyBmaXJlZCBhZnRlciBvbmxvYWQsIGUuZy4gd2hlbiBzY3JpcHQgaXMgaW5zZXJ0ZWQgZHluYW1pY2FsbHlcclxuICAgICAgICAgICAgY2FsbERvbUxvYWRGdW5jdGlvbnMoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFpc0RvbUxvYWRlZCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGRvYy5hZGRFdmVudExpc3RlbmVyICE9PSBVTkRFRikge1xyXG4gICAgICAgICAgICAgICAgZG9jLmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGNhbGxEb21Mb2FkRnVuY3Rpb25zLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHVhLmllKSB7XHJcbiAgICAgICAgICAgICAgICBkb2MuYXR0YWNoRXZlbnQoT05fUkVBRFlfU1RBVEVfQ0hBTkdFLCBmdW5jdGlvbiBkZXRhY2goKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRvYy5yZWFkeVN0YXRlID09PSBcImNvbXBsZXRlXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZG9jLmRldGFjaEV2ZW50KE9OX1JFQURZX1NUQVRFX0NIQU5HRSwgZGV0YWNoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FsbERvbUxvYWRGdW5jdGlvbnMoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIGlmICh3aW4gPT0gdG9wKSB7IC8vIGlmIG5vdCBpbnNpZGUgYW4gaWZyYW1lXHJcbiAgICAgICAgICAgICAgICAgICAgKGZ1bmN0aW9uIGNoZWNrRG9tTG9hZGVkSUUoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0RvbUxvYWRlZCkgeyByZXR1cm47IH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvYy5kb2N1bWVudEVsZW1lbnQuZG9TY3JvbGwoXCJsZWZ0XCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGNoZWNrRG9tTG9hZGVkSUUsIDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxEb21Mb2FkRnVuY3Rpb25zKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSgpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodWEud2spIHtcclxuICAgICAgICAgICAgICAgIChmdW5jdGlvbiBjaGVja0RvbUxvYWRlZFdLKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0RvbUxvYWRlZCkgeyByZXR1cm47IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoIS9sb2FkZWR8Y29tcGxldGUvLnRlc3QoZG9jLnJlYWR5U3RhdGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoY2hlY2tEb21Mb2FkZWRXSywgMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY2FsbERvbUxvYWRGdW5jdGlvbnMoKTtcclxuICAgICAgICAgICAgICAgIH0oKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9KCk7XHJcblxyXG4gICAgZnVuY3Rpb24gY2FsbERvbUxvYWRGdW5jdGlvbnMoKSB7XHJcbiAgICAgICAgaWYgKGlzRG9tTG9hZGVkIHx8ICFkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImJvZHlcIilbMF0pIHsgcmV0dXJuOyB9XHJcbiAgICAgICAgdHJ5IHsgLy8gdGVzdCBpZiB3ZSBjYW4gcmVhbGx5IGFkZC9yZW1vdmUgZWxlbWVudHMgdG8vZnJvbSB0aGUgRE9NOyB3ZSBkb24ndCB3YW50IHRvIGZpcmUgaXQgdG9vIGVhcmx5XHJcbiAgICAgICAgICAgIHZhciB0LCBzcGFuID0gY3JlYXRlRWxlbWVudChcInNwYW5cIik7XHJcbiAgICAgICAgICAgIHNwYW4uc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiOyAvL2hpZGUgdGhlIHNwYW4gaW4gY2FzZSBzb21lb25lIGhhcyBzdHlsZWQgc3BhbnMgdmlhIENTU1xyXG4gICAgICAgICAgICB0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiYm9keVwiKVswXS5hcHBlbmRDaGlsZChzcGFuKTtcclxuICAgICAgICAgICAgdC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHQpO1xyXG4gICAgICAgICAgICB0ID0gbnVsbDsgLy9jbGVhciB0aGUgdmFyaWFibGVzXHJcbiAgICAgICAgICAgIHNwYW4gPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZSkgeyByZXR1cm47IH1cclxuICAgICAgICBpc0RvbUxvYWRlZCA9IHRydWU7XHJcbiAgICAgICAgdmFyIGRsID0gZG9tTG9hZEZuQXJyLmxlbmd0aDtcclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRsOyBpKyspIHtcclxuICAgICAgICAgICAgZG9tTG9hZEZuQXJyW2ldKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIGFkZERvbUxvYWRFdmVudChmbikge1xyXG4gICAgICAgIGlmIChpc0RvbUxvYWRlZCkge1xyXG4gICAgICAgICAgICBmbigpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgZG9tTG9hZEZuQXJyW2RvbUxvYWRGbkFyci5sZW5ndGhdID0gZm47IC8vIEFycmF5LnB1c2goKSBpcyBvbmx5IGF2YWlsYWJsZSBpbiBJRTUuNStcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyogQ3Jvc3MtYnJvd3NlciBvbmxvYWRcclxuICAgICAgICAtIEJhc2VkIG9uIEphbWVzIEVkd2FyZHMnIHNvbHV0aW9uOiBodHRwOi8vYnJvdGhlcmNha2UuY29tL3NpdGUvcmVzb3VyY2VzL3NjcmlwdHMvb25sb2FkL1xyXG4gICAgICAgIC0gV2lsbCBmaXJlIGFuIGV2ZW50IGFzIHNvb24gYXMgYSB3ZWIgcGFnZSBpbmNsdWRpbmcgYWxsIG9mIGl0cyBhc3NldHMgYXJlIGxvYWRlZFxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBhZGRMb2FkRXZlbnQoZm4pIHtcclxuICAgICAgICBpZiAodHlwZW9mIHdpbi5hZGRFdmVudExpc3RlbmVyICE9PSBVTkRFRikge1xyXG4gICAgICAgICAgICB3aW4uYWRkRXZlbnRMaXN0ZW5lcihcImxvYWRcIiwgZm4sIGZhbHNlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIGRvYy5hZGRFdmVudExpc3RlbmVyICE9PSBVTkRFRikge1xyXG4gICAgICAgICAgICBkb2MuYWRkRXZlbnRMaXN0ZW5lcihcImxvYWRcIiwgZm4sIGZhbHNlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIHdpbi5hdHRhY2hFdmVudCAhPT0gVU5ERUYpIHtcclxuICAgICAgICAgICAgYWRkTGlzdGVuZXIod2luLCBcIm9ubG9hZFwiLCBmbik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiB3aW4ub25sb2FkID09PSBcImZ1bmN0aW9uXCIpIHtcclxuICAgICAgICAgICAgdmFyIGZuT2xkID0gd2luLm9ubG9hZDtcclxuICAgICAgICAgICAgd2luLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGZuT2xkKCk7XHJcbiAgICAgICAgICAgICAgICBmbigpO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgd2luLm9ubG9hZCA9IGZuO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKiBEZXRlY3QgdGhlIEZsYXNoIFBsYXllciB2ZXJzaW9uIGZvciBub24tSW50ZXJuZXQgRXhwbG9yZXIgYnJvd3NlcnNcclxuICAgICAgICAtIERldGVjdGluZyB0aGUgcGx1Zy1pbiB2ZXJzaW9uIHZpYSB0aGUgb2JqZWN0IGVsZW1lbnQgaXMgbW9yZSBwcmVjaXNlIHRoYW4gdXNpbmcgdGhlIHBsdWdpbnMgY29sbGVjdGlvbiBpdGVtJ3MgZGVzY3JpcHRpb246XHJcbiAgICAgICAgICBhLiBCb3RoIHJlbGVhc2UgYW5kIGJ1aWxkIG51bWJlcnMgY2FuIGJlIGRldGVjdGVkXHJcbiAgICAgICAgICBiLiBBdm9pZCB3cm9uZyBkZXNjcmlwdGlvbnMgYnkgY29ycnVwdCBpbnN0YWxsZXJzIHByb3ZpZGVkIGJ5IEFkb2JlXHJcbiAgICAgICAgICBjLiBBdm9pZCB3cm9uZyBkZXNjcmlwdGlvbnMgYnkgbXVsdGlwbGUgRmxhc2ggUGxheWVyIGVudHJpZXMgaW4gdGhlIHBsdWdpbiBBcnJheSwgY2F1c2VkIGJ5IGluY29ycmVjdCBicm93c2VyIGltcG9ydHNcclxuICAgICAgICAtIERpc2FkdmFudGFnZSBvZiB0aGlzIG1ldGhvZCBpcyB0aGF0IGl0IGRlcGVuZHMgb24gdGhlIGF2YWlsYWJpbGl0eSBvZiB0aGUgRE9NLCB3aGlsZSB0aGUgcGx1Z2lucyBjb2xsZWN0aW9uIGlzIGltbWVkaWF0ZWx5IGF2YWlsYWJsZVxyXG4gICAgKi9cclxuICAgIGZ1bmN0aW9uIHRlc3RQbGF5ZXJWZXJzaW9uKCkge1xyXG4gICAgICAgIHZhciBiID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiYm9keVwiKVswXTtcclxuICAgICAgICB2YXIgbyA9IGNyZWF0ZUVsZW1lbnQoT0JKRUNUKTtcclxuICAgICAgICBvLnNldEF0dHJpYnV0ZShcInN0eWxlXCIsIFwidmlzaWJpbGl0eTogaGlkZGVuO1wiKTtcclxuICAgICAgICBvLnNldEF0dHJpYnV0ZShcInR5cGVcIiwgRkxBU0hfTUlNRV9UWVBFKTtcclxuICAgICAgICB2YXIgdCA9IGIuYXBwZW5kQ2hpbGQobyk7XHJcbiAgICAgICAgaWYgKHQpIHtcclxuICAgICAgICAgICAgdmFyIGNvdW50ZXIgPSAwO1xyXG4gICAgICAgICAgICAoZnVuY3Rpb24gY2hlY2tHZXRWYXJpYWJsZSgpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdC5HZXRWYXJpYWJsZSAhPT0gVU5ERUYpIHtcclxuICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZCA9IHQuR2V0VmFyaWFibGUoXCIkdmVyc2lvblwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQgPSBkLnNwbGl0KFwiIFwiKVsxXS5zcGxpdChcIixcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1YS5wdiA9IFt0b0ludChkWzBdKSwgdG9JbnQoZFsxXSksIHRvSW50KGRbMl0pXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy90LkdldFZhcmlhYmxlKFwiJHZlcnNpb25cIikgaXMga25vd24gdG8gZmFpbCBpbiBGbGFzaCBQbGF5ZXIgOCBvbiBGaXJlZm94XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vSWYgdGhpcyBlcnJvciBpcyBlbmNvdW50ZXJlZCwgYXNzdW1lIEZQOCBvciBsb3dlci4gVGltZSB0byB1cGdyYWRlLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB1YS5wdiA9IFs4LCAwLCAwXTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChjb3VudGVyIDwgMTApIHtcclxuICAgICAgICAgICAgICAgICAgICBjb3VudGVyKys7XHJcbiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChjaGVja0dldFZhcmlhYmxlLCAxMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYi5yZW1vdmVDaGlsZChvKTtcclxuICAgICAgICAgICAgICAgIHQgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgbWF0Y2hWZXJzaW9ucygpO1xyXG4gICAgICAgICAgICB9KCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgbWF0Y2hWZXJzaW9ucygpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKiBQZXJmb3JtIEZsYXNoIFBsYXllciBhbmQgU1dGIHZlcnNpb24gbWF0Y2hpbmc7IHN0YXRpYyBwdWJsaXNoaW5nIG9ubHlcclxuICAgICovXHJcbiAgICBmdW5jdGlvbiBtYXRjaFZlcnNpb25zKCkge1xyXG4gICAgICAgIHZhciBybCA9IHJlZ09iakFyci5sZW5ndGg7XHJcbiAgICAgICAgaWYgKHJsID4gMCkge1xyXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJsOyBpKyspIHsgLy8gZm9yIGVhY2ggcmVnaXN0ZXJlZCBvYmplY3QgZWxlbWVudFxyXG4gICAgICAgICAgICAgICAgdmFyIGlkID0gcmVnT2JqQXJyW2ldLmlkO1xyXG4gICAgICAgICAgICAgICAgdmFyIGNiID0gcmVnT2JqQXJyW2ldLmNhbGxiYWNrRm47XHJcbiAgICAgICAgICAgICAgICB2YXIgY2JPYmogPSB7c3VjY2VzczogZmFsc2UsIGlkOiBpZH07XHJcbiAgICAgICAgICAgICAgICBpZiAodWEucHZbMF0gPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9iaiA9IGdldEVsZW1lbnRCeUlkKGlkKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAob2JqKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChoYXNQbGF5ZXJWZXJzaW9uKHJlZ09iakFycltpXS5zd2ZWZXJzaW9uKSAmJiAhKHVhLndrICYmIHVhLndrIDwgMzEyKSkgeyAvLyBGbGFzaCBQbGF5ZXIgdmVyc2lvbiA+PSBwdWJsaXNoZWQgU1dGIHZlcnNpb246IEhvdXN0b24sIHdlIGhhdmUgYSBtYXRjaCFcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFZpc2liaWxpdHkoaWQsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2JPYmouc3VjY2VzcyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2JPYmoucmVmID0gZ2V0T2JqZWN0QnlJZChpZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2JPYmouaWQgPSBpZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYihjYk9iaik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAocmVnT2JqQXJyW2ldLmV4cHJlc3NJbnN0YWxsICYmIGNhbkV4cHJlc3NJbnN0YWxsKCkpIHsgLy8gc2hvdyB0aGUgQWRvYmUgRXhwcmVzcyBJbnN0YWxsIGRpYWxvZyBpZiBzZXQgYnkgdGhlIHdlYiBwYWdlIGF1dGhvciBhbmQgaWYgc3VwcG9ydGVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXR0ID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHQuZGF0YSA9IHJlZ09iakFycltpXS5leHByZXNzSW5zdGFsbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dC53aWR0aCA9IG9iai5nZXRBdHRyaWJ1dGUoXCJ3aWR0aFwiKSB8fCBcIjBcIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dC5oZWlnaHQgPSBvYmouZ2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIpIHx8IFwiMFwiO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9iai5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKSkgeyBhdHQuc3R5bGVjbGFzcyA9IG9iai5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKTsgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9iai5nZXRBdHRyaWJ1dGUoXCJhbGlnblwiKSkgeyBhdHQuYWxpZ24gPSBvYmouZ2V0QXR0cmlidXRlKFwiYWxpZ25cIik7IH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHBhcnNlIEhUTUwgb2JqZWN0IHBhcmFtIGVsZW1lbnQncyBuYW1lLXZhbHVlIHBhaXJzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcCA9IG9iai5nZXRFbGVtZW50c0J5VGFnTmFtZShcInBhcmFtXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBsID0gcC5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHBsOyBqKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFtqXS5nZXRBdHRyaWJ1dGUoXCJuYW1lXCIpLnRvTG93ZXJDYXNlKCkgIT09IFwibW92aWVcIikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJbcFtqXS5nZXRBdHRyaWJ1dGUoXCJuYW1lXCIpXSA9IHBbal0uZ2V0QXR0cmlidXRlKFwidmFsdWVcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvd0V4cHJlc3NJbnN0YWxsKGF0dCwgcGFyLCBpZCwgY2IpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgeyAvLyBGbGFzaCBQbGF5ZXIgYW5kIFNXRiB2ZXJzaW9uIG1pc21hdGNoIG9yIGFuIG9sZGVyIFdlYmtpdCBlbmdpbmUgdGhhdCBpZ25vcmVzIHRoZSBIVE1MIG9iamVjdCBlbGVtZW50J3MgbmVzdGVkIHBhcmFtIGVsZW1lbnRzOiBkaXNwbGF5IGZhbGxiYWNrIGNvbnRlbnQgaW5zdGVhZCBvZiBTV0ZcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXlGYkNvbnRlbnQob2JqKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjYikgeyBjYihjYk9iaik7IH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgeyAvLyBpZiBubyBGbGFzaCBQbGF5ZXIgaXMgaW5zdGFsbGVkIG9yIHRoZSBmcCB2ZXJzaW9uIGNhbm5vdCBiZSBkZXRlY3RlZCB3ZSBsZXQgdGhlIEhUTUwgb2JqZWN0IGVsZW1lbnQgZG8gaXRzIGpvYiAoZWl0aGVyIHNob3cgYSBTV0Ygb3IgZmFsbGJhY2sgY29udGVudClcclxuICAgICAgICAgICAgICAgICAgICBzZXRWaXNpYmlsaXR5KGlkLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG8gPSBnZXRPYmplY3RCeUlkKGlkKTsgLy8gdGVzdCB3aGV0aGVyIHRoZXJlIGlzIGFuIEhUTUwgb2JqZWN0IGVsZW1lbnQgb3Igbm90XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvICYmIHR5cGVvZiBvLlNldFZhcmlhYmxlICE9PSBVTkRFRikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2JPYmouc3VjY2VzcyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYk9iai5yZWYgPSBvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2JPYmouaWQgPSBvLmlkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNiKGNiT2JqKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyogTWFpbiBmdW5jdGlvblxyXG4gICAgICAgIC0gV2lsbCBwcmVmZXJhYmx5IGV4ZWN1dGUgb25Eb21Mb2FkLCBvdGhlcndpc2Ugb25sb2FkIChhcyBhIGZhbGxiYWNrKVxyXG4gICAgKi9cclxuICAgIGRvbUxvYWRGbkFyclswXSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAocGx1Z2luKSB7XHJcbiAgICAgICAgICAgIHRlc3RQbGF5ZXJWZXJzaW9uKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBtYXRjaFZlcnNpb25zKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICBmdW5jdGlvbiBnZXRPYmplY3RCeUlkKG9iamVjdElkU3RyKSB7XHJcbiAgICAgICAgdmFyIHIgPSBudWxsLFxyXG4gICAgICAgICAgICBvID0gZ2V0RWxlbWVudEJ5SWQob2JqZWN0SWRTdHIpO1xyXG5cclxuICAgICAgICBpZiAobyAmJiBvLm5vZGVOYW1lLnRvVXBwZXJDYXNlKCkgPT09IFwiT0JKRUNUXCIpIHtcclxuICAgICAgICAgICAgLy9JZiB0YXJnZXRlZCBvYmplY3QgaXMgdmFsaWQgRmxhc2ggZmlsZVxyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG8uU2V0VmFyaWFibGUgIT09IFVOREVGKSB7XHJcbiAgICAgICAgICAgICAgICByID0gbztcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vSWYgU2V0VmFyaWFibGUgaXMgbm90IHdvcmtpbmcgb24gdGFyZ2V0ZWQgb2JqZWN0IGJ1dCBhIG5lc3RlZCBvYmplY3QgaXNcclxuICAgICAgICAgICAgICAgIC8vYXZhaWxhYmxlLCBhc3N1bWUgY2xhc3NpYyBuZXN0ZWQgb2JqZWN0IG1hcmt1cC4gUmV0dXJuIG5lc3RlZCBvYmplY3QuXHJcblxyXG4gICAgICAgICAgICAgICAgLy9JZiBTZXRWYXJpYWJsZSBpcyBub3Qgd29ya2luZyBvbiB0YXJnZXRlZCBvYmplY3QgYW5kIHRoZXJlIGlzIG5vIG5lc3RlZCBvYmplY3QsXHJcbiAgICAgICAgICAgICAgICAvL3JldHVybiB0aGUgb3JpZ2luYWwgb2JqZWN0IGFueXdheS4gVGhpcyBpcyBwcm9iYWJseSBuZXcgc2ltcGxpZmllZCBtYXJrdXAuXHJcblxyXG4gICAgICAgICAgICAgICAgciA9IG8uZ2V0RWxlbWVudHNCeVRhZ05hbWUoT0JKRUNUKVswXSB8fCBvO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gcjtcclxuICAgIH1cclxuXHJcbiAgICAvKiBSZXF1aXJlbWVudHMgZm9yIEFkb2JlIEV4cHJlc3MgSW5zdGFsbFxyXG4gICAgICAgIC0gb25seSBvbmUgaW5zdGFuY2UgY2FuIGJlIGFjdGl2ZSBhdCBhIHRpbWVcclxuICAgICAgICAtIGZwIDYuMC42NSBvciBoaWdoZXJcclxuICAgICAgICAtIFdpbi9NYWMgT1Mgb25seVxyXG4gICAgICAgIC0gbm8gV2Via2l0IGVuZ2luZXMgb2xkZXIgdGhhbiB2ZXJzaW9uIDMxMlxyXG4gICAgKi9cclxuICAgIGZ1bmN0aW9uIGNhbkV4cHJlc3NJbnN0YWxsKCkge1xyXG4gICAgICAgIHJldHVybiAhaXNFeHByZXNzSW5zdGFsbEFjdGl2ZSAmJiBoYXNQbGF5ZXJWZXJzaW9uKFwiNi4wLjY1XCIpICYmICh1YS53aW4gfHwgdWEubWFjKSAmJiAhKHVhLndrICYmIHVhLndrIDwgMzEyKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiBTaG93IHRoZSBBZG9iZSBFeHByZXNzIEluc3RhbGwgZGlhbG9nXHJcbiAgICAgICAgLSBSZWZlcmVuY2U6IGh0dHA6Ly93d3cuYWRvYmUuY29tL2NmdXNpb24va25vd2xlZGdlYmFzZS9pbmRleC5jZm0/aWQ9NmEyNTNiNzVcclxuICAgICovXHJcbiAgICBmdW5jdGlvbiBzaG93RXhwcmVzc0luc3RhbGwoYXR0LCBwYXIsIHJlcGxhY2VFbGVtSWRTdHIsIGNhbGxiYWNrRm4pIHtcclxuXHJcbiAgICAgICAgdmFyIG9iaiA9IGdldEVsZW1lbnRCeUlkKHJlcGxhY2VFbGVtSWRTdHIpO1xyXG5cclxuICAgICAgICAvL0Vuc3VyZSB0aGF0IHJlcGxhY2VFbGVtSWRTdHIgaXMgcmVhbGx5IGEgc3RyaW5nIGFuZCBub3QgYW4gZWxlbWVudFxyXG4gICAgICAgIHJlcGxhY2VFbGVtSWRTdHIgPSBnZXRJZChyZXBsYWNlRWxlbUlkU3RyKTtcclxuXHJcbiAgICAgICAgaXNFeHByZXNzSW5zdGFsbEFjdGl2ZSA9IHRydWU7XHJcbiAgICAgICAgc3RvcmVkQ2FsbGJhY2tGbiA9IGNhbGxiYWNrRm4gfHwgbnVsbDtcclxuICAgICAgICBzdG9yZWRDYWxsYmFja09iaiA9IHtzdWNjZXNzOiBmYWxzZSwgaWQ6IHJlcGxhY2VFbGVtSWRTdHJ9O1xyXG5cclxuICAgICAgICBpZiAob2JqKSB7XHJcbiAgICAgICAgICAgIGlmIChvYmoubm9kZU5hbWUudG9VcHBlckNhc2UoKSA9PT0gXCJPQkpFQ1RcIikgeyAvLyBzdGF0aWMgcHVibGlzaGluZ1xyXG4gICAgICAgICAgICAgICAgc3RvcmVkRmJDb250ZW50ID0gYWJzdHJhY3RGYkNvbnRlbnQob2JqKTtcclxuICAgICAgICAgICAgICAgIHN0b3JlZEZiQ29udGVudElkID0gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHsgLy8gZHluYW1pYyBwdWJsaXNoaW5nXHJcbiAgICAgICAgICAgICAgICBzdG9yZWRGYkNvbnRlbnQgPSBvYmo7XHJcbiAgICAgICAgICAgICAgICBzdG9yZWRGYkNvbnRlbnRJZCA9IHJlcGxhY2VFbGVtSWRTdHI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgYXR0LmlkID0gRVhQUkVTU19JTlNUQUxMX0lEO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGF0dC53aWR0aCA9PT0gVU5ERUYgfHwgKCEvJSQvLnRlc3QoYXR0LndpZHRoKSAmJiB0b0ludChhdHQud2lkdGgpIDwgMzEwKSkgeyBhdHQud2lkdGggPSBcIjMxMFwiOyB9XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYXR0LmhlaWdodCA9PT0gVU5ERUYgfHwgKCEvJSQvLnRlc3QoYXR0LmhlaWdodCkgJiYgdG9JbnQoYXR0LmhlaWdodCkgPCAxMzcpKSB7IGF0dC5oZWlnaHQgPSBcIjEzN1wiOyB9XHJcbiAgICAgICAgICAgIHZhciBwdCA9IHVhLmllID8gXCJBY3RpdmVYXCIgOiBcIlBsdWdJblwiLFxyXG4gICAgICAgICAgICAgICAgZnYgPSBcIk1NcmVkaXJlY3RVUkw9XCIgKyBlbmNvZGVVUklDb21wb25lbnQod2luLmxvY2F0aW9uLnRvU3RyaW5nKCkucmVwbGFjZSgvJi9nLCBcIiUyNlwiKSkgKyBcIiZNTXBsYXllclR5cGU9XCIgKyBwdCArIFwiJk1NZG9jdGl0bGU9XCIgKyBlbmNvZGVVUklDb21wb25lbnQoZG9jLnRpdGxlLnNsaWNlKDAsIDQ3KSArIFwiIC0gRmxhc2ggUGxheWVyIEluc3RhbGxhdGlvblwiKTtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBwYXIuZmxhc2h2YXJzICE9PSBVTkRFRikge1xyXG4gICAgICAgICAgICAgICAgcGFyLmZsYXNodmFycyArPSBcIiZcIiArIGZ2O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcGFyLmZsYXNodmFycyA9IGZ2O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIElFIG9ubHk6IHdoZW4gYSBTV0YgaXMgbG9hZGluZyAoQU5EOiBub3QgYXZhaWxhYmxlIGluIGNhY2hlKSB3YWl0IGZvciB0aGUgcmVhZHlTdGF0ZSBvZiB0aGUgb2JqZWN0IGVsZW1lbnQgdG8gYmVjb21lIDQgYmVmb3JlIHJlbW92aW5nIGl0LFxyXG4gICAgICAgICAgICAvLyBiZWNhdXNlIHlvdSBjYW5ub3QgcHJvcGVybHkgY2FuY2VsIGEgbG9hZGluZyBTV0YgZmlsZSB3aXRob3V0IGJyZWFraW5nIGJyb3dzZXIgbG9hZCByZWZlcmVuY2VzLCBhbHNvIG9iai5vbnJlYWR5c3RhdGVjaGFuZ2UgZG9lc24ndCB3b3JrXHJcbiAgICAgICAgICAgIGlmICh1YS5pZSAmJiBvYmoucmVhZHlTdGF0ZSAhPSA0KSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbmV3T2JqID0gY3JlYXRlRWxlbWVudChcImRpdlwiKTtcclxuICAgICAgICAgICAgICAgIHJlcGxhY2VFbGVtSWRTdHIgKz0gXCJTV0ZPYmplY3ROZXdcIjtcclxuICAgICAgICAgICAgICAgIG5ld09iai5zZXRBdHRyaWJ1dGUoXCJpZFwiLCByZXBsYWNlRWxlbUlkU3RyKTtcclxuICAgICAgICAgICAgICAgIG9iai5wYXJlbnROb2RlLmluc2VydEJlZm9yZShuZXdPYmosIG9iaik7IC8vIGluc2VydCBwbGFjZWhvbGRlciBkaXYgdGhhdCB3aWxsIGJlIHJlcGxhY2VkIGJ5IHRoZSBvYmplY3QgZWxlbWVudCB0aGF0IGxvYWRzIGV4cHJlc3NpbnN0YWxsLnN3ZlxyXG4gICAgICAgICAgICAgICAgb2JqLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcclxuICAgICAgICAgICAgICAgIHJlbW92ZVNXRihvYmopOyAvL3JlbW92ZVNXRiBhY2NlcHRzIGVsZW1lbnRzIG5vd1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNyZWF0ZVNXRihhdHQsIHBhciwgcmVwbGFjZUVsZW1JZFN0cik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qIEZ1bmN0aW9ucyB0byBhYnN0cmFjdCBhbmQgZGlzcGxheSBmYWxsYmFjayBjb250ZW50XHJcbiAgICAqL1xyXG4gICAgZnVuY3Rpb24gZGlzcGxheUZiQ29udGVudChvYmopIHtcclxuICAgICAgICBpZiAodWEuaWUgJiYgb2JqLnJlYWR5U3RhdGUgIT0gNCkge1xyXG4gICAgICAgICAgICAvLyBJRSBvbmx5OiB3aGVuIGEgU1dGIGlzIGxvYWRpbmcgKEFORDogbm90IGF2YWlsYWJsZSBpbiBjYWNoZSkgd2FpdCBmb3IgdGhlIHJlYWR5U3RhdGUgb2YgdGhlIG9iamVjdCBlbGVtZW50IHRvIGJlY29tZSA0IGJlZm9yZSByZW1vdmluZyBpdCxcclxuICAgICAgICAgICAgLy8gYmVjYXVzZSB5b3UgY2Fubm90IHByb3Blcmx5IGNhbmNlbCBhIGxvYWRpbmcgU1dGIGZpbGUgd2l0aG91dCBicmVha2luZyBicm93c2VyIGxvYWQgcmVmZXJlbmNlcywgYWxzbyBvYmoub25yZWFkeXN0YXRlY2hhbmdlIGRvZXNuJ3Qgd29ya1xyXG4gICAgICAgICAgICBvYmouc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xyXG4gICAgICAgICAgICB2YXIgZWwgPSBjcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xyXG4gICAgICAgICAgICBvYmoucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZWwsIG9iaik7IC8vIGluc2VydCBwbGFjZWhvbGRlciBkaXYgdGhhdCB3aWxsIGJlIHJlcGxhY2VkIGJ5IHRoZSBmYWxsYmFjayBjb250ZW50XHJcbiAgICAgICAgICAgIGVsLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGFic3RyYWN0RmJDb250ZW50KG9iaiksIGVsKTtcclxuICAgICAgICAgICAgcmVtb3ZlU1dGKG9iaik7IC8vcmVtb3ZlU1dGIGFjY2VwdHMgZWxlbWVudHMgbm93XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBvYmoucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoYWJzdHJhY3RGYkNvbnRlbnQob2JqKSwgb2JqKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gYWJzdHJhY3RGYkNvbnRlbnQob2JqKSB7XHJcbiAgICAgICAgdmFyIGFjID0gY3JlYXRlRWxlbWVudChcImRpdlwiKTtcclxuICAgICAgICBpZiAodWEud2luICYmIHVhLmllKSB7XHJcbiAgICAgICAgICAgIGFjLmlubmVySFRNTCA9IG9iai5pbm5lckhUTUw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB2YXIgbmVzdGVkT2JqID0gb2JqLmdldEVsZW1lbnRzQnlUYWdOYW1lKE9CSkVDVClbMF07XHJcbiAgICAgICAgICAgIGlmIChuZXN0ZWRPYmopIHtcclxuICAgICAgICAgICAgICAgIHZhciBjID0gbmVzdGVkT2JqLmNoaWxkTm9kZXM7XHJcbiAgICAgICAgICAgICAgICBpZiAoYykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbCA9IGMubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2w7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShjW2ldLm5vZGVUeXBlID09IDEgJiYgY1tpXS5ub2RlTmFtZSA9PT0gXCJQQVJBTVwiKSAmJiAhKGNbaV0ubm9kZVR5cGUgPT0gOCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjLmFwcGVuZENoaWxkKGNbaV0uY2xvbmVOb2RlKHRydWUpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYWM7XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gY3JlYXRlSWVPYmplY3QodXJsLCBwYXJhbVN0cikge1xyXG4gICAgICAgIHZhciBkaXYgPSBjcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xyXG4gICAgICAgIGRpdi5pbm5lckhUTUwgPSBcIjxvYmplY3QgY2xhc3NpZD0nY2xzaWQ6RDI3Q0RCNkUtQUU2RC0xMWNmLTk2QjgtNDQ0NTUzNTQwMDAwJz48cGFyYW0gbmFtZT0nbW92aWUnIHZhbHVlPSdcIiArIHVybCArIFwiJz5cIiArIHBhcmFtU3RyICsgXCI8L29iamVjdD5cIjtcclxuICAgICAgICByZXR1cm4gZGl2LmZpcnN0Q2hpbGQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyogQ3Jvc3MtYnJvd3NlciBkeW5hbWljIFNXRiBjcmVhdGlvblxyXG4gICAgKi9cclxuICAgIGZ1bmN0aW9uIGNyZWF0ZVNXRihhdHRPYmosIHBhck9iaiwgaWQpIHtcclxuICAgICAgICB2YXIgciwgZWwgPSBnZXRFbGVtZW50QnlJZChpZCk7XHJcbiAgICAgICAgaWQgPSBnZXRJZChpZCk7IC8vIGVuc3VyZSBpZCBpcyB0cnVseSBhbiBJRCBhbmQgbm90IGFuIGVsZW1lbnRcclxuXHJcbiAgICAgICAgaWYgKHVhLndrICYmIHVhLndrIDwgMzEyKSB7IHJldHVybiByOyB9XHJcblxyXG4gICAgICAgIGlmIChlbCkge1xyXG4gICAgICAgICAgICB2YXIgbyA9ICh1YS5pZSkgPyBjcmVhdGVFbGVtZW50KFwiZGl2XCIpIDogY3JlYXRlRWxlbWVudChPQkpFQ1QpLFxyXG4gICAgICAgICAgICAgICAgYXR0cixcclxuICAgICAgICAgICAgICAgIGF0dHJMb3dlcixcclxuICAgICAgICAgICAgICAgIHBhcmFtO1xyXG5cclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBhdHRPYmouaWQgPT09IFVOREVGKSB7IC8vIGlmIG5vICdpZCcgaXMgZGVmaW5lZCBmb3IgdGhlIG9iamVjdCBlbGVtZW50LCBpdCB3aWxsIGluaGVyaXQgdGhlICdpZCcgZnJvbSB0aGUgZmFsbGJhY2sgY29udGVudFxyXG4gICAgICAgICAgICAgICAgYXR0T2JqLmlkID0gaWQ7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vQWRkIHBhcmFtc1xyXG4gICAgICAgICAgICBmb3IgKHBhcmFtIGluIHBhck9iaikge1xyXG4gICAgICAgICAgICAgICAgLy9maWx0ZXIgb3V0IHByb3RvdHlwZSBhZGRpdGlvbnMgZnJvbSBvdGhlciBwb3RlbnRpYWwgbGlicmFyaWVzIGFuZCBJRSBzcGVjaWZpYyBwYXJhbSBlbGVtZW50XHJcbiAgICAgICAgICAgICAgICBpZiAocGFyT2JqLmhhc093blByb3BlcnR5KHBhcmFtKSAmJiBwYXJhbS50b0xvd2VyQ2FzZSgpICE9PSBcIm1vdmllXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICBjcmVhdGVPYmpQYXJhbShvLCBwYXJhbSwgcGFyT2JqW3BhcmFtXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vQ3JlYXRlIElFIG9iamVjdCwgY29tcGxldGUgd2l0aCBwYXJhbSBub2Rlc1xyXG4gICAgICAgICAgICBpZiAodWEuaWUpIHsgbyA9IGNyZWF0ZUllT2JqZWN0KGF0dE9iai5kYXRhLCBvLmlubmVySFRNTCk7IH1cclxuXHJcbiAgICAgICAgICAgIC8vQWRkIGF0dHJpYnV0ZXMgdG8gb2JqZWN0XHJcbiAgICAgICAgICAgIGZvciAoYXR0ciBpbiBhdHRPYmopIHtcclxuICAgICAgICAgICAgICAgIGlmIChhdHRPYmouaGFzT3duUHJvcGVydHkoYXR0cikpIHsgLy8gZmlsdGVyIG91dCBwcm90b3R5cGUgYWRkaXRpb25zIGZyb20gb3RoZXIgcG90ZW50aWFsIGxpYnJhcmllc1xyXG4gICAgICAgICAgICAgICAgICAgIGF0dHJMb3dlciA9IGF0dHIudG9Mb3dlckNhc2UoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gJ2NsYXNzJyBpcyBhbiBFQ01BNCByZXNlcnZlZCBrZXl3b3JkXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF0dHJMb3dlciA9PT0gXCJzdHlsZWNsYXNzXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgby5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBhdHRPYmpbYXR0cl0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXR0ckxvd2VyICE9PSBcImNsYXNzaWRcIiAmJiBhdHRyTG93ZXIgIT09IFwiZGF0YVwiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG8uc2V0QXR0cmlidXRlKGF0dHIsIGF0dE9ialthdHRyXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAodWEuaWUpIHtcclxuICAgICAgICAgICAgICAgIG9iaklkQXJyW29iaklkQXJyLmxlbmd0aF0gPSBhdHRPYmouaWQ7IC8vIHN0b3JlZCB0byBmaXggb2JqZWN0ICdsZWFrcycgb24gdW5sb2FkIChkeW5hbWljIHB1Ymxpc2hpbmcgb25seSlcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIG8uc2V0QXR0cmlidXRlKFwidHlwZVwiLCBGTEFTSF9NSU1FX1RZUEUpO1xyXG4gICAgICAgICAgICAgICAgby5zZXRBdHRyaWJ1dGUoXCJkYXRhXCIsIGF0dE9iai5kYXRhKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZWwucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQobywgZWwpO1xyXG4gICAgICAgICAgICByID0gbztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiByO1xyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIGNyZWF0ZU9ialBhcmFtKGVsLCBwTmFtZSwgcFZhbHVlKSB7XHJcbiAgICAgICAgdmFyIHAgPSBjcmVhdGVFbGVtZW50KFwicGFyYW1cIik7XHJcbiAgICAgICAgcC5zZXRBdHRyaWJ1dGUoXCJuYW1lXCIsIHBOYW1lKTtcclxuICAgICAgICBwLnNldEF0dHJpYnV0ZShcInZhbHVlXCIsIHBWYWx1ZSk7XHJcbiAgICAgICAgZWwuYXBwZW5kQ2hpbGQocCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyogQ3Jvc3MtYnJvd3NlciBTV0YgcmVtb3ZhbFxyXG4gICAgICAgIC0gRXNwZWNpYWxseSBuZWVkZWQgdG8gc2FmZWx5IGFuZCBjb21wbGV0ZWx5IHJlbW92ZSBhIFNXRiBpbiBJbnRlcm5ldCBFeHBsb3JlclxyXG4gICAgKi9cclxuICAgIGZ1bmN0aW9uIHJlbW92ZVNXRihpZCkge1xyXG4gICAgICAgIHZhciBvYmogPSBnZXRFbGVtZW50QnlJZChpZCk7XHJcbiAgICAgICAgaWYgKG9iaiAmJiBvYmoubm9kZU5hbWUudG9VcHBlckNhc2UoKSA9PT0gXCJPQkpFQ1RcIikge1xyXG4gICAgICAgICAgICBpZiAodWEuaWUpIHtcclxuICAgICAgICAgICAgICAgIG9iai5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XHJcbiAgICAgICAgICAgICAgICAoZnVuY3Rpb24gcmVtb3ZlU1dGSW5JRSgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAob2JqLnJlYWR5U3RhdGUgPT0gNCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL1RoaXMgc3RlcCBwcmV2ZW50cyBtZW1vcnkgbGVha3MgaW4gSW50ZXJuZXQgRXhwbG9yZXJcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBvYmopIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqW2ldID09PSBcImZ1bmN0aW9uXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmpbaV0gPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iai5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG9iaik7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChyZW1vdmVTV0ZJbklFLCAxMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSgpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIG9iai5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG9iaik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gaXNFbGVtZW50KGlkKSB7XHJcbiAgICAgICAgcmV0dXJuIChpZCAmJiBpZC5ub2RlVHlwZSAmJiBpZC5ub2RlVHlwZSA9PT0gMSk7XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gZ2V0SWQodGhpbmcpIHtcclxuICAgICAgICByZXR1cm4gKGlzRWxlbWVudCh0aGluZykpID8gdGhpbmcuaWQgOiB0aGluZztcclxuICAgIH1cclxuXHJcbiAgICAvKiBGdW5jdGlvbnMgdG8gb3B0aW1pemUgSmF2YVNjcmlwdCBjb21wcmVzc2lvblxyXG4gICAgKi9cclxuICAgIGZ1bmN0aW9uIGdldEVsZW1lbnRCeUlkKGlkKSB7XHJcblxyXG4gICAgICAgIC8vQWxsb3cgdXNlcnMgdG8gcGFzcyBhbiBlbGVtZW50IE9SIGFuIGVsZW1lbnQncyBJRFxyXG4gICAgICAgIGlmIChpc0VsZW1lbnQoaWQpKSB7IHJldHVybiBpZDsgfVxyXG5cclxuICAgICAgICB2YXIgZWwgPSBudWxsO1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGVsID0gZG9jLmdldEVsZW1lbnRCeUlkKGlkKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHt9XHJcbiAgICAgICAgcmV0dXJuIGVsO1xyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnQoZWwpIHtcclxuICAgICAgICByZXR1cm4gZG9jLmNyZWF0ZUVsZW1lbnQoZWwpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vVG8gYWlkIGNvbXByZXNzaW9uOyByZXBsYWNlcyAxNCBpbnN0YW5jZXMgb2YgcGFyZXNlSW50IHdpdGggcmFkaXhcclxuICAgIGZ1bmN0aW9uIHRvSW50KHN0cikge1xyXG4gICAgICAgIHJldHVybiBwYXJzZUludChzdHIsIDEwKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiBVcGRhdGVkIGF0dGFjaEV2ZW50IGZ1bmN0aW9uIGZvciBJbnRlcm5ldCBFeHBsb3JlclxyXG4gICAgICAgIC0gU3RvcmVzIGF0dGFjaEV2ZW50IGluZm9ybWF0aW9uIGluIGFuIEFycmF5LCBzbyBvbiB1bmxvYWQgdGhlIGRldGFjaEV2ZW50IGZ1bmN0aW9ucyBjYW4gYmUgY2FsbGVkIHRvIGF2b2lkIG1lbW9yeSBsZWFrc1xyXG4gICAgKi9cclxuICAgIGZ1bmN0aW9uIGFkZExpc3RlbmVyKHRhcmdldCwgZXZlbnRUeXBlLCBmbikge1xyXG4gICAgICAgIHRhcmdldC5hdHRhY2hFdmVudChldmVudFR5cGUsIGZuKTtcclxuICAgICAgICBsaXN0ZW5lcnNBcnJbbGlzdGVuZXJzQXJyLmxlbmd0aF0gPSBbdGFyZ2V0LCBldmVudFR5cGUsIGZuXTtcclxuICAgIH1cclxuXHJcbiAgICAvKiBGbGFzaCBQbGF5ZXIgYW5kIFNXRiBjb250ZW50IHZlcnNpb24gbWF0Y2hpbmdcclxuICAgICovXHJcbiAgICBmdW5jdGlvbiBoYXNQbGF5ZXJWZXJzaW9uKHJ2KSB7XHJcbiAgICAgICAgcnYgKz0gXCJcIjsgLy9Db2VyY2UgbnVtYmVyIHRvIHN0cmluZywgaWYgbmVlZGVkLlxyXG4gICAgICAgIHZhciBwdiA9IHVhLnB2LCB2ID0gcnYuc3BsaXQoXCIuXCIpO1xyXG4gICAgICAgIHZbMF0gPSB0b0ludCh2WzBdKTtcclxuICAgICAgICB2WzFdID0gdG9JbnQodlsxXSkgfHwgMDsgLy8gc3VwcG9ydHMgc2hvcnQgbm90YXRpb24sIGUuZy4gXCI5XCIgaW5zdGVhZCBvZiBcIjkuMC4wXCJcclxuICAgICAgICB2WzJdID0gdG9JbnQodlsyXSkgfHwgMDtcclxuICAgICAgICByZXR1cm4gKHB2WzBdID4gdlswXSB8fCAocHZbMF0gPT0gdlswXSAmJiBwdlsxXSA+IHZbMV0pIHx8IChwdlswXSA9PSB2WzBdICYmIHB2WzFdID09IHZbMV0gJiYgcHZbMl0gPj0gdlsyXSkpID8gdHJ1ZSA6IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIENyb3NzLWJyb3dzZXIgZHluYW1pYyBDU1MgY3JlYXRpb25cclxuICAgICAgICAtIEJhc2VkIG9uIEJvYmJ5IHZhbiBkZXIgU2x1aXMnIHNvbHV0aW9uOiBodHRwOi8vd3d3LmJvYmJ5dmFuZGVyc2x1aXMuY29tL2FydGljbGVzL2R5bmFtaWNDU1MucGhwXHJcbiAgICAqL1xyXG4gICAgZnVuY3Rpb24gY3JlYXRlQ1NTKHNlbCwgZGVjbCwgbWVkaWEsIG5ld1N0eWxlKSB7XHJcbiAgICAgICAgdmFyIGggPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJoZWFkXCIpWzBdO1xyXG4gICAgICAgIGlmICghaCkgeyByZXR1cm47IH0gLy8gdG8gYWxzbyBzdXBwb3J0IGJhZGx5IGF1dGhvcmVkIEhUTUwgcGFnZXMgdGhhdCBsYWNrIGEgaGVhZCBlbGVtZW50XHJcbiAgICAgICAgdmFyIG0gPSAodHlwZW9mIG1lZGlhID09PSBcInN0cmluZ1wiKSA/IG1lZGlhIDogXCJzY3JlZW5cIjtcclxuICAgICAgICBpZiAobmV3U3R5bGUpIHtcclxuICAgICAgICAgICAgZHluYW1pY1N0eWxlc2hlZXQgPSBudWxsO1xyXG4gICAgICAgICAgICBkeW5hbWljU3R5bGVzaGVldE1lZGlhID0gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFkeW5hbWljU3R5bGVzaGVldCB8fCBkeW5hbWljU3R5bGVzaGVldE1lZGlhICE9IG0pIHtcclxuICAgICAgICAgICAgLy8gY3JlYXRlIGR5bmFtaWMgc3R5bGVzaGVldCArIGdldCBhIGdsb2JhbCByZWZlcmVuY2UgdG8gaXRcclxuICAgICAgICAgICAgdmFyIHMgPSBjcmVhdGVFbGVtZW50KFwic3R5bGVcIik7XHJcbiAgICAgICAgICAgIHMuc2V0QXR0cmlidXRlKFwidHlwZVwiLCBcInRleHQvY3NzXCIpO1xyXG4gICAgICAgICAgICBzLnNldEF0dHJpYnV0ZShcIm1lZGlhXCIsIG0pO1xyXG4gICAgICAgICAgICBkeW5hbWljU3R5bGVzaGVldCA9IGguYXBwZW5kQ2hpbGQocyk7XHJcbiAgICAgICAgICAgIGlmICh1YS5pZSAmJiB0eXBlb2YgZG9jLnN0eWxlU2hlZXRzICE9PSBVTkRFRiAmJiBkb2Muc3R5bGVTaGVldHMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgZHluYW1pY1N0eWxlc2hlZXQgPSBkb2Muc3R5bGVTaGVldHNbZG9jLnN0eWxlU2hlZXRzLmxlbmd0aCAtIDFdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGR5bmFtaWNTdHlsZXNoZWV0TWVkaWEgPSBtO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBhZGQgc3R5bGUgcnVsZVxyXG4gICAgICAgIGlmIChkeW5hbWljU3R5bGVzaGVldCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGR5bmFtaWNTdHlsZXNoZWV0LmFkZFJ1bGUgIT09IFVOREVGKSB7XHJcbiAgICAgICAgICAgICAgICBkeW5hbWljU3R5bGVzaGVldC5hZGRSdWxlKHNlbCwgZGVjbCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGRvYy5jcmVhdGVUZXh0Tm9kZSAhPT0gVU5ERUYpIHtcclxuICAgICAgICAgICAgICAgIGR5bmFtaWNTdHlsZXNoZWV0LmFwcGVuZENoaWxkKGRvYy5jcmVhdGVUZXh0Tm9kZShzZWwgKyBcIiB7XCIgKyBkZWNsICsgXCJ9XCIpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBzZXRWaXNpYmlsaXR5KGlkLCBpc1Zpc2libGUpIHtcclxuICAgICAgICBpZiAoIWF1dG9IaWRlU2hvdykgeyByZXR1cm47IH1cclxuICAgICAgICB2YXIgdiA9IGlzVmlzaWJsZSA/IFwidmlzaWJsZVwiIDogXCJoaWRkZW5cIixcclxuICAgICAgICAgICAgZWwgPSBnZXRFbGVtZW50QnlJZChpZCk7XHJcbiAgICAgICAgaWYgKGlzRG9tTG9hZGVkICYmIGVsKSB7XHJcbiAgICAgICAgICAgIGVsLnN0eWxlLnZpc2liaWxpdHkgPSB2O1xyXG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGlkID09PSBcInN0cmluZ1wiKSB7XHJcbiAgICAgICAgICAgIGNyZWF0ZUNTUyhcIiNcIiArIGlkLCBcInZpc2liaWxpdHk6XCIgKyB2KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyogRmlsdGVyIHRvIGF2b2lkIFhTUyBhdHRhY2tzXHJcbiAgICAqL1xyXG4gICAgZnVuY3Rpb24gdXJsRW5jb2RlSWZOZWNlc3Nhcnkocykge1xyXG4gICAgICAgIHZhciByZWdleCA9IC9bXFxcXFxcXCI8PlxcLjtdLztcclxuICAgICAgICB2YXIgaGFzQmFkQ2hhcnMgPSByZWdleC5leGVjKHMpICE9PSBudWxsO1xyXG4gICAgICAgIHJldHVybiBoYXNCYWRDaGFycyAmJiB0eXBlb2YgZW5jb2RlVVJJQ29tcG9uZW50ICE9PSBVTkRFRiA/IGVuY29kZVVSSUNvbXBvbmVudChzKSA6IHM7XHJcbiAgICB9XHJcblxyXG4gICAgLyogUmVsZWFzZSBtZW1vcnkgdG8gYXZvaWQgbWVtb3J5IGxlYWtzIGNhdXNlZCBieSBjbG9zdXJlcywgZml4IGhhbmdpbmcgYXVkaW8vdmlkZW8gdGhyZWFkcyBhbmQgZm9yY2Ugb3BlbiBzb2NrZXRzL05ldENvbm5lY3Rpb25zIHRvIGRpc2Nvbm5lY3QgKEludGVybmV0IEV4cGxvcmVyIG9ubHkpXHJcbiAgICAqL1xyXG4gICAgdmFyIGNsZWFudXAgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKHVhLmllKSB7XHJcbiAgICAgICAgICAgIHdpbmRvdy5hdHRhY2hFdmVudChcIm9udW5sb2FkXCIsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBsaXN0ZW5lcnMgdG8gYXZvaWQgbWVtb3J5IGxlYWtzXHJcbiAgICAgICAgICAgICAgICB2YXIgbGwgPSBsaXN0ZW5lcnNBcnIubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsbDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzQXJyW2ldWzBdLmRldGFjaEV2ZW50KGxpc3RlbmVyc0FycltpXVsxXSwgbGlzdGVuZXJzQXJyW2ldWzJdKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIGNsZWFudXAgZHluYW1pY2FsbHkgZW1iZWRkZWQgb2JqZWN0cyB0byBmaXggYXVkaW8vdmlkZW8gdGhyZWFkcyBhbmQgZm9yY2Ugb3BlbiBzb2NrZXRzIGFuZCBOZXRDb25uZWN0aW9ucyB0byBkaXNjb25uZWN0XHJcbiAgICAgICAgICAgICAgICB2YXIgaWwgPSBvYmpJZEFyci5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGlsOyBqKyspIHtcclxuICAgICAgICAgICAgICAgICAgICByZW1vdmVTV0Yob2JqSWRBcnJbal0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gY2xlYW51cCBsaWJyYXJ5J3MgbWFpbiBjbG9zdXJlcyB0byBhdm9pZCBtZW1vcnkgbGVha3NcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIGsgaW4gdWEpIHtcclxuICAgICAgICAgICAgICAgICAgICB1YVtrXSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB1YSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBsIGluIHN3Zm9iamVjdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHN3Zm9iamVjdFtsXSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBzd2ZvYmplY3QgPSBudWxsO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9KCk7XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICAvKiBQdWJsaWMgQVBJXHJcbiAgICAgICAgICAgIC0gUmVmZXJlbmNlOiBodHRwOi8vY29kZS5nb29nbGUuY29tL3Avc3dmb2JqZWN0L3dpa2kvZG9jdW1lbnRhdGlvblxyXG4gICAgICAgICovXHJcbiAgICAgICAgcmVnaXN0ZXJPYmplY3Q6IGZ1bmN0aW9uIChvYmplY3RJZFN0ciwgc3dmVmVyc2lvblN0ciwgeGlTd2ZVcmxTdHIsIGNhbGxiYWNrRm4pIHtcclxuICAgICAgICAgICAgaWYgKHVhLnczICYmIG9iamVjdElkU3RyICYmIHN3ZlZlcnNpb25TdHIpIHtcclxuICAgICAgICAgICAgICAgIHZhciByZWdPYmogPSB7fTtcclxuICAgICAgICAgICAgICAgIHJlZ09iai5pZCA9IG9iamVjdElkU3RyO1xyXG4gICAgICAgICAgICAgICAgcmVnT2JqLnN3ZlZlcnNpb24gPSBzd2ZWZXJzaW9uU3RyO1xyXG4gICAgICAgICAgICAgICAgcmVnT2JqLmV4cHJlc3NJbnN0YWxsID0geGlTd2ZVcmxTdHI7XHJcbiAgICAgICAgICAgICAgICByZWdPYmouY2FsbGJhY2tGbiA9IGNhbGxiYWNrRm47XHJcbiAgICAgICAgICAgICAgICByZWdPYmpBcnJbcmVnT2JqQXJyLmxlbmd0aF0gPSByZWdPYmo7XHJcbiAgICAgICAgICAgICAgICBzZXRWaXNpYmlsaXR5KG9iamVjdElkU3RyLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoY2FsbGJhY2tGbikge1xyXG4gICAgICAgICAgICAgICAgY2FsbGJhY2tGbih7c3VjY2VzczogZmFsc2UsIGlkOiBvYmplY3RJZFN0cn0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgZ2V0T2JqZWN0QnlJZDogZnVuY3Rpb24gKG9iamVjdElkU3RyKSB7XHJcbiAgICAgICAgICAgIGlmICh1YS53Mykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGdldE9iamVjdEJ5SWQob2JqZWN0SWRTdHIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgZW1iZWRTV0Y6IGZ1bmN0aW9uIChzd2ZVcmxTdHIsIHJlcGxhY2VFbGVtSWRTdHIsIHdpZHRoU3RyLCBoZWlnaHRTdHIsIHN3ZlZlcnNpb25TdHIsIHhpU3dmVXJsU3RyLCBmbGFzaHZhcnNPYmosIHBhck9iaiwgYXR0T2JqLCBjYWxsYmFja0ZuKSB7XHJcblxyXG4gICAgICAgICAgICB2YXIgaWQgPSBnZXRJZChyZXBsYWNlRWxlbUlkU3RyKSxcclxuICAgICAgICAgICAgICAgIGNhbGxiYWNrT2JqID0ge3N1Y2Nlc3M6IGZhbHNlLCBpZDogaWR9O1xyXG5cclxuICAgICAgICAgICAgaWYgKHVhLnczICYmICEodWEud2sgJiYgdWEud2sgPCAzMTIpICYmIHN3ZlVybFN0ciAmJiByZXBsYWNlRWxlbUlkU3RyICYmIHdpZHRoU3RyICYmIGhlaWdodFN0ciAmJiBzd2ZWZXJzaW9uU3RyKSB7XHJcbiAgICAgICAgICAgICAgICBzZXRWaXNpYmlsaXR5KGlkLCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICBhZGREb21Mb2FkRXZlbnQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHdpZHRoU3RyICs9IFwiXCI7IC8vIGF1dG8tY29udmVydCB0byBzdHJpbmdcclxuICAgICAgICAgICAgICAgICAgICBoZWlnaHRTdHIgKz0gXCJcIjtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYXR0ID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF0dE9iaiAmJiB0eXBlb2YgYXR0T2JqID09PSBPQkpFQ1QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBhdHRPYmopIHsgLy8gY29weSBvYmplY3QgdG8gYXZvaWQgdGhlIHVzZSBvZiByZWZlcmVuY2VzLCBiZWNhdXNlIHdlYiBhdXRob3JzIG9mdGVuIHJldXNlIGF0dE9iaiBmb3IgbXVsdGlwbGUgU1dGc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0W2ldID0gYXR0T2JqW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGF0dC5kYXRhID0gc3dmVXJsU3RyO1xyXG4gICAgICAgICAgICAgICAgICAgIGF0dC53aWR0aCA9IHdpZHRoU3RyO1xyXG4gICAgICAgICAgICAgICAgICAgIGF0dC5oZWlnaHQgPSBoZWlnaHRTdHI7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhciA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJPYmogJiYgdHlwZW9mIHBhck9iaiA9PT0gT0JKRUNUKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4gcGFyT2JqKSB7IC8vIGNvcHkgb2JqZWN0IHRvIGF2b2lkIHRoZSB1c2Ugb2YgcmVmZXJlbmNlcywgYmVjYXVzZSB3ZWIgYXV0aG9ycyBvZnRlbiByZXVzZSBwYXJPYmogZm9yIG11bHRpcGxlIFNXRnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcltqXSA9IHBhck9ialtqXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoZmxhc2h2YXJzT2JqICYmIHR5cGVvZiBmbGFzaHZhcnNPYmogPT09IE9CSkVDVCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBrIGluIGZsYXNodmFyc09iaikgeyAvLyBjb3B5IG9iamVjdCB0byBhdm9pZCB0aGUgdXNlIG9mIHJlZmVyZW5jZXMsIGJlY2F1c2Ugd2ViIGF1dGhvcnMgb2Z0ZW4gcmV1c2UgZmxhc2h2YXJzT2JqIGZvciBtdWx0aXBsZSBTV0ZzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmxhc2h2YXJzT2JqLmhhc093blByb3BlcnR5KGspKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBrZXkgPSAoZW5jb2RlVVJJRW5hYmxlZCkgPyBlbmNvZGVVUklDb21wb25lbnQoaykgOiBrLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IChlbmNvZGVVUklFbmFibGVkKSA/IGVuY29kZVVSSUNvbXBvbmVudChmbGFzaHZhcnNPYmpba10pIDogZmxhc2h2YXJzT2JqW2tdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHBhci5mbGFzaHZhcnMgIT09IFVOREVGKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhci5mbGFzaHZhcnMgKz0gXCImXCIgKyBrZXkgKyBcIj1cIiArIHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyLmZsYXNodmFycyA9IGtleSArIFwiPVwiICsgdmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoaGFzUGxheWVyVmVyc2lvbihzd2ZWZXJzaW9uU3RyKSkgeyAvLyBjcmVhdGUgU1dGXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvYmogPSBjcmVhdGVTV0YoYXR0LCBwYXIsIHJlcGxhY2VFbGVtSWRTdHIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0LmlkID09IGlkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRWaXNpYmlsaXR5KGlkLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFja09iai5zdWNjZXNzID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tPYmoucmVmID0gb2JqO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFja09iai5pZCA9IG9iai5pZDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoeGlTd2ZVcmxTdHIgJiYgY2FuRXhwcmVzc0luc3RhbGwoKSkgeyAvLyBzaG93IEFkb2JlIEV4cHJlc3MgSW5zdGFsbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhdHQuZGF0YSA9IHhpU3dmVXJsU3RyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzaG93RXhwcmVzc0luc3RhbGwoYXR0LCBwYXIsIHJlcGxhY2VFbGVtSWRTdHIsIGNhbGxiYWNrRm4pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgeyAvLyBzaG93IGZhbGxiYWNrIGNvbnRlbnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VmlzaWJpbGl0eShpZCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjYWxsYmFja0ZuKSB7IGNhbGxiYWNrRm4oY2FsbGJhY2tPYmopOyB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChjYWxsYmFja0ZuKSB7IGNhbGxiYWNrRm4oY2FsbGJhY2tPYmopOyB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgc3dpdGNoT2ZmQXV0b0hpZGVTaG93OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGF1dG9IaWRlU2hvdyA9IGZhbHNlO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIGVuYWJsZVVyaUVuY29kaW5nOiBmdW5jdGlvbiAoYm9vbCkge1xyXG4gICAgICAgICAgICBlbmNvZGVVUklFbmFibGVkID0gKHR5cGVvZiBib29sID09PSBVTkRFRikgPyB0cnVlIDogYm9vbDtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICB1YTogdWEsXHJcblxyXG4gICAgICAgIGdldEZsYXNoUGxheWVyVmVyc2lvbjogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4ge21ham9yOiB1YS5wdlswXSwgbWlub3I6IHVhLnB2WzFdLCByZWxlYXNlOiB1YS5wdlsyXX07XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgaGFzRmxhc2hQbGF5ZXJWZXJzaW9uOiBoYXNQbGF5ZXJWZXJzaW9uLFxyXG5cclxuICAgICAgICBjcmVhdGVTV0Y6IGZ1bmN0aW9uIChhdHRPYmosIHBhck9iaiwgcmVwbGFjZUVsZW1JZFN0cikge1xyXG4gICAgICAgICAgICBpZiAodWEudzMpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVTV0YoYXR0T2JqLCBwYXJPYmosIHJlcGxhY2VFbGVtSWRTdHIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIHNob3dFeHByZXNzSW5zdGFsbDogZnVuY3Rpb24gKGF0dCwgcGFyLCByZXBsYWNlRWxlbUlkU3RyLCBjYWxsYmFja0ZuKSB7XHJcbiAgICAgICAgICAgIGlmICh1YS53MyAmJiBjYW5FeHByZXNzSW5zdGFsbCgpKSB7XHJcbiAgICAgICAgICAgICAgICBzaG93RXhwcmVzc0luc3RhbGwoYXR0LCBwYXIsIHJlcGxhY2VFbGVtSWRTdHIsIGNhbGxiYWNrRm4pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgcmVtb3ZlU1dGOiBmdW5jdGlvbiAob2JqRWxlbUlkU3RyKSB7XHJcbiAgICAgICAgICAgIGlmICh1YS53Mykge1xyXG4gICAgICAgICAgICAgICAgcmVtb3ZlU1dGKG9iakVsZW1JZFN0cik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBjcmVhdGVDU1M6IGZ1bmN0aW9uIChzZWxTdHIsIGRlY2xTdHIsIG1lZGlhU3RyLCBuZXdTdHlsZUJvb2xlYW4pIHtcclxuICAgICAgICAgICAgaWYgKHVhLnczKSB7XHJcbiAgICAgICAgICAgICAgICBjcmVhdGVDU1Moc2VsU3RyLCBkZWNsU3RyLCBtZWRpYVN0ciwgbmV3U3R5bGVCb29sZWFuKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIGFkZERvbUxvYWRFdmVudDogYWRkRG9tTG9hZEV2ZW50LFxyXG5cclxuICAgICAgICBhZGRMb2FkRXZlbnQ6IGFkZExvYWRFdmVudCxcclxuXHJcbiAgICAgICAgZ2V0UXVlcnlQYXJhbVZhbHVlOiBmdW5jdGlvbiAocGFyYW0pIHtcclxuICAgICAgICAgICAgdmFyIHEgPSBkb2MubG9jYXRpb24uc2VhcmNoIHx8IGRvYy5sb2NhdGlvbi5oYXNoO1xyXG4gICAgICAgICAgICBpZiAocSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKC9cXD8vLnRlc3QocSkpIHsgcSA9IHEuc3BsaXQoXCI/XCIpWzFdOyB9IC8vIHN0cmlwIHF1ZXN0aW9uIG1hcmtcclxuICAgICAgICAgICAgICAgIGlmICghcGFyYW0pIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdXJsRW5jb2RlSWZOZWNlc3NhcnkocSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB2YXIgcGFpcnMgPSBxLnNwbGl0KFwiJlwiKTtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGFpcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocGFpcnNbaV0uc3Vic3RyaW5nKDAsIHBhaXJzW2ldLmluZGV4T2YoXCI9XCIpKSA9PSBwYXJhbSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdXJsRW5jb2RlSWZOZWNlc3NhcnkocGFpcnNbaV0uc3Vic3RyaW5nKChwYWlyc1tpXS5pbmRleE9mKFwiPVwiKSArIDEpKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBcIlwiO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8vIEZvciBpbnRlcm5hbCB1c2FnZSBvbmx5XHJcbiAgICAgICAgZXhwcmVzc0luc3RhbGxDYWxsYmFjazogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAoaXNFeHByZXNzSW5zdGFsbEFjdGl2ZSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIG9iaiA9IGdldEVsZW1lbnRCeUlkKEVYUFJFU1NfSU5TVEFMTF9JRCk7XHJcbiAgICAgICAgICAgICAgICBpZiAob2JqICYmIHN0b3JlZEZiQ29udGVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG9iai5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChzdG9yZWRGYkNvbnRlbnQsIG9iaik7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0b3JlZEZiQ29udGVudElkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFZpc2liaWxpdHkoc3RvcmVkRmJDb250ZW50SWQsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodWEuaWUpIHsgc3RvcmVkRmJDb250ZW50LnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7IH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0b3JlZENhbGxiYWNrRm4pIHsgc3RvcmVkQ2FsbGJhY2tGbihzdG9yZWRDYWxsYmFja09iaik7IH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlzRXhwcmVzc0luc3RhbGxBY3RpdmUgPSBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIHZlcnNpb246IFwiMi4zXCJcclxuXHJcbiAgICB9O1xyXG59KSk7XHJcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEluTGluZSA9IHJlcXVpcmUoJy4vSW5MaW5lJyk7XG52YXIgV3JhcHBlciA9IHJlcXVpcmUoJy4vV3JhcHBlcicpO1xuXG5mdW5jdGlvbiBBZChhZEpUcmVlKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBBZCkpIHtcbiAgICByZXR1cm4gbmV3IEFkKGFkSlRyZWUpO1xuICB9XG4gIHRoaXMuaW5pdGlhbGl6ZShhZEpUcmVlKTtcbn1cblxuQWQucHJvdG90eXBlLmluaXRpYWxpemUgPSBmdW5jdGlvbihhZEpUcmVlKSB7XG4gIHRoaXMuaWQgPSBhZEpUcmVlLmF0dHIoJ2lkJyk7XG4gIHRoaXMuc2VxdWVuY2UgPSBhZEpUcmVlLmF0dHIoJ3NlcXVlbmNlJyk7XG5cbiAgaWYoYWRKVHJlZS5pbkxpbmUpIHtcbiAgICB0aGlzLmluTGluZSA9IG5ldyBJbkxpbmUoYWRKVHJlZS5pbkxpbmUpO1xuICB9XG5cbiAgaWYoYWRKVHJlZS53cmFwcGVyKXtcbiAgICB0aGlzLndyYXBwZXIgPSBuZXcgV3JhcHBlcihhZEpUcmVlLndyYXBwZXIpO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFkOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIFRyYWNraW5nRXZlbnQgPSByZXF1aXJlKCcuL1RyYWNraW5nRXZlbnQnKTtcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxudmFyIHhtbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3htbCcpO1xuXG5cbmZ1bmN0aW9uIENvbXBhbmlvbihjb21wYW5pb25KVHJlZSkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQ29tcGFuaW9uKSkge1xuICAgIHJldHVybiBuZXcgQ29tcGFuaW9uKGNvbXBhbmlvbkpUcmVlKTtcbiAgfVxuXG4gIC8vUmVxdWlyZWQgRWxlbWVudHNcbiAgdGhpcy5jcmVhdGl2ZVR5cGUgPSB4bWwuYXR0cihjb21wYW5pb25KVHJlZS5zdGF0aWNSZXNvdXJjZSwgJ2NyZWF0aXZlVHlwZScpO1xuICB0aGlzLnN0YXRpY1Jlc291cmNlID0geG1sLmtleVZhbHVlKGNvbXBhbmlvbkpUcmVlLnN0YXRpY1Jlc291cmNlKTtcblxuICAvLyBXZWlyZCBidWcgd2hlbiB0aGUgSlhPTiB0cmVlIGlzIGJ1aWx0IGl0IGRvZXNuJ3QgaGFuZGxlIGNhc2luZyBwcm9wZXJseSBpbiB0aGlzIHNpdHVhdGlvbi4uLlxuICB2YXIgaHRtbFJlc291cmNlID0gbnVsbDtcbiAgaWYgKHhtbC5rZXlWYWx1ZShjb21wYW5pb25KVHJlZS5IVE1MUmVzb3VyY2UpKSB7XG4gICAgaHRtbFJlc291cmNlID0geG1sLmtleVZhbHVlKGNvbXBhbmlvbkpUcmVlLkhUTUxSZXNvdXJjZSk7XG4gIH0gZWxzZSBpZiAoeG1sLmtleVZhbHVlKGNvbXBhbmlvbkpUcmVlLmhUTUxSZXNvdXJjZSkpIHtcbiAgICBodG1sUmVzb3VyY2UgPSB4bWwua2V5VmFsdWUoY29tcGFuaW9uSlRyZWUuaFRNTFJlc291cmNlKTtcbiAgfVxuICB0aGlzLmh0bWxSZXNvdXJjZSA9IGh0bWxSZXNvdXJjZTtcblxuICB2YXIgaWZyYW1lUmVzb3VyY2UgPSBudWxsO1xuICBpZiAoeG1sLmtleVZhbHVlKGNvbXBhbmlvbkpUcmVlLklGcmFtZVJlc291cmNlKSkge1xuICAgIGlmcmFtZVJlc291cmNlID0geG1sLmtleVZhbHVlKGNvbXBhbmlvbkpUcmVlLklGcmFtZVJlc291cmNlKTtcbiAgfSBlbHNlIGlmICh4bWwua2V5VmFsdWUoY29tcGFuaW9uSlRyZWUuaUZyYW1lcmVzb3VyY2UpKSB7XG4gICAgaWZyYW1lUmVzb3VyY2UgPSB4bWwua2V5VmFsdWUoY29tcGFuaW9uSlRyZWUuaUZyYW1lcmVzb3VyY2UpO1xuICB9XG4gIHRoaXMuaWZyYW1lUmVzb3VyY2UgPSBpZnJhbWVSZXNvdXJjZTtcblxuICAvL09wdGlvbmFsIGZpZWxkc1xuICB0aGlzLmlkID0geG1sLmF0dHIoY29tcGFuaW9uSlRyZWUsICdpZCcpO1xuICB0aGlzLndpZHRoID0geG1sLmF0dHIoY29tcGFuaW9uSlRyZWUsICd3aWR0aCcpO1xuICB0aGlzLmhlaWdodCA9IHhtbC5hdHRyKGNvbXBhbmlvbkpUcmVlLCAnaGVpZ2h0Jyk7XG4gIHRoaXMuZXhwYW5kZWRXaWR0aCA9IHhtbC5hdHRyKGNvbXBhbmlvbkpUcmVlLCAnZXhwYW5kZWRXaWR0aCcpO1xuICB0aGlzLmV4cGFuZGVkSGVpZ2h0ID0geG1sLmF0dHIoY29tcGFuaW9uSlRyZWUsICdleHBhbmRlZEhlaWdodCcpO1xuICB0aGlzLnNjYWxhYmxlID0geG1sLmF0dHIoY29tcGFuaW9uSlRyZWUsICdzY2FsYWJsZScpO1xuICB0aGlzLm1haW50YWluQXNwZWN0UmF0aW8gPSB4bWwuYXR0cihjb21wYW5pb25KVHJlZSwgJ21haW50YWluQXNwZWN0UmF0aW8nKTtcbiAgdGhpcy5taW5TdWdnZXN0ZWREdXJhdGlvbiA9IHhtbC5hdHRyKGNvbXBhbmlvbkpUcmVlLCAnbWluU3VnZ2VzdGVkRHVyYXRpb24nKTtcbiAgdGhpcy5hcGlGcmFtZXdvcmsgPSB4bWwuYXR0cihjb21wYW5pb25KVHJlZSwgJ2FwaUZyYW1ld29yaycpO1xuICB0aGlzLmNvbXBhbmlvbkNsaWNrVGhyb3VnaCA9IHhtbC5rZXlWYWx1ZShjb21wYW5pb25KVHJlZS5jb21wYW5pb25DbGlja1Rocm91Z2gpO1xuICB0aGlzLnRyYWNraW5nRXZlbnRzID0gcGFyc2VUcmFja2luZ0V2ZW50cyhjb21wYW5pb25KVHJlZS50cmFja2luZ0V2ZW50cyAmJiBjb21wYW5pb25KVHJlZS50cmFja2luZ0V2ZW50cy50cmFja2luZyk7XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBwYXJzZVRyYWNraW5nRXZlbnRzKHRyYWNraW5nRXZlbnRzKSB7XG4gICAgdmFyIHRyYWNraW5ncyA9IFtdO1xuICAgIGlmICh1dGlsaXRpZXMuaXNEZWZpbmVkKHRyYWNraW5nRXZlbnRzKSkge1xuICAgICAgdHJhY2tpbmdFdmVudHMgPSB1dGlsaXRpZXMuaXNBcnJheSh0cmFja2luZ0V2ZW50cykgPyB0cmFja2luZ0V2ZW50cyA6IFt0cmFja2luZ0V2ZW50c107XG4gICAgICB0cmFja2luZ0V2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uICh0cmFja2luZ0RhdGEpIHtcbiAgICAgICAgdHJhY2tpbmdzLnB1c2gobmV3IFRyYWNraW5nRXZlbnQodHJhY2tpbmdEYXRhKSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRyYWNraW5ncztcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IENvbXBhbmlvbjsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBMaW5lYXIgPSByZXF1aXJlKCcuL0xpbmVhcicpO1xudmFyIENvbXBhbmlvbiA9IHJlcXVpcmUoJy4vQ29tcGFuaW9uJyk7XG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucycpO1xuXG5mdW5jdGlvbiBDcmVhdGl2ZShjcmVhdGl2ZUpUcmVlKSB7XG4gIGlmKCEodGhpcyBpbnN0YW5jZW9mIENyZWF0aXZlKSkge1xuICAgIHJldHVybiBuZXcgQ3JlYXRpdmUoY3JlYXRpdmVKVHJlZSk7XG4gIH1cblxuICB0aGlzLmlkID0gY3JlYXRpdmVKVHJlZS5hdHRyKCdpZCcpO1xuICB0aGlzLnNlcXVlbmNlID0gY3JlYXRpdmVKVHJlZS5hdHRyKCdzZXF1ZW5jZScpO1xuICB0aGlzLmFkSWQgPSBjcmVhdGl2ZUpUcmVlLmF0dHIoJ2FkSWQnKTtcbiAgdGhpcy5hcGlGcmFtZXdvcmsgPSBjcmVhdGl2ZUpUcmVlLmF0dHIoJ2FwaUZyYW1ld29yaycpO1xuXG4gIGlmKGNyZWF0aXZlSlRyZWUubGluZWFyKSB7XG4gICAgdGhpcy5saW5lYXIgPSBuZXcgTGluZWFyKGNyZWF0aXZlSlRyZWUubGluZWFyKTtcbiAgfVxuXG4gIGlmIChjcmVhdGl2ZUpUcmVlLmNvbXBhbmlvbkFkcykge1xuICAgIHZhciBjb21wYW5pb25zID0gW107XG4gICAgdmFyIGNvbXBhbmlvbkFkcyA9IGNyZWF0aXZlSlRyZWUuY29tcGFuaW9uQWRzICYmIGNyZWF0aXZlSlRyZWUuY29tcGFuaW9uQWRzLmNvbXBhbmlvbjtcbiAgICBpZiAodXRpbGl0aWVzLmlzRGVmaW5lZChjb21wYW5pb25BZHMpKSB7XG4gICAgICBjb21wYW5pb25BZHMgPSB1dGlsaXRpZXMuaXNBcnJheShjb21wYW5pb25BZHMpID8gY29tcGFuaW9uQWRzIDogW2NvbXBhbmlvbkFkc107XG4gICAgICBjb21wYW5pb25BZHMuZm9yRWFjaChmdW5jdGlvbiAoY29tcGFuaW9uRGF0YSkge1xuICAgICAgICBjb21wYW5pb25zLnB1c2gobmV3IENvbXBhbmlvbihjb21wYW5pb25EYXRhKSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhpcy5jb21wYW5pb25BZHMgPSBjb21wYW5pb25zO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIGF0IHRoZSBjcmVhdGl2ZS5cbiAqL1xuQ3JlYXRpdmUucHJvdG90eXBlLmlzU3VwcG9ydGVkID0gZnVuY3Rpb24oKXtcbiAgaWYodGhpcy5saW5lYXIpIHtcbiAgICByZXR1cm4gdGhpcy5saW5lYXIuaXNTdXBwb3J0ZWQoKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuQ3JlYXRpdmUucGFyc2VDcmVhdGl2ZXMgPSBmdW5jdGlvbiBwYXJzZUNyZWF0aXZlcyhjcmVhdGl2ZXNKVHJlZSkge1xuICB2YXIgY3JlYXRpdmVzID0gW107XG4gIHZhciBjcmVhdGl2ZXNEYXRhO1xuICBpZiAodXRpbGl0aWVzLmlzRGVmaW5lZChjcmVhdGl2ZXNKVHJlZSkgJiYgdXRpbGl0aWVzLmlzRGVmaW5lZChjcmVhdGl2ZXNKVHJlZS5jcmVhdGl2ZSkpIHtcbiAgICBjcmVhdGl2ZXNEYXRhID0gdXRpbGl0aWVzLmlzQXJyYXkoY3JlYXRpdmVzSlRyZWUuY3JlYXRpdmUpID8gY3JlYXRpdmVzSlRyZWUuY3JlYXRpdmUgOiBbY3JlYXRpdmVzSlRyZWUuY3JlYXRpdmVdO1xuICAgIGNyZWF0aXZlc0RhdGEuZm9yRWFjaChmdW5jdGlvbiAoY3JlYXRpdmUpIHtcbiAgICAgIGNyZWF0aXZlcy5wdXNoKG5ldyBDcmVhdGl2ZShjcmVhdGl2ZSkpO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBjcmVhdGl2ZXM7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IENyZWF0aXZlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdmFzdFV0aWwgPSByZXF1aXJlKCcuL3Zhc3RVdGlsJyk7XG52YXIgQ3JlYXRpdmUgPSByZXF1aXJlKCcuL0NyZWF0aXZlJyk7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG52YXIgeG1sID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMveG1sJyk7XG5cbmZ1bmN0aW9uIEluTGluZShpbmxpbmVKVHJlZSkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgSW5MaW5lKSkge1xuICAgIHJldHVybiBuZXcgSW5MaW5lKGlubGluZUpUcmVlKTtcbiAgfVxuXG4gIC8vUmVxdWlyZWQgRmllbGRzXG4gIHRoaXMuYWRUaXRsZSA9IHhtbC5rZXlWYWx1ZShpbmxpbmVKVHJlZS5hZFRpdGxlKTtcbiAgdGhpcy5hZFN5c3RlbSA9IHhtbC5rZXlWYWx1ZShpbmxpbmVKVHJlZS5hZFN5c3RlbSk7XG4gIHRoaXMuaW1wcmVzc2lvbnMgPSB2YXN0VXRpbC5wYXJzZUltcHJlc3Npb25zKGlubGluZUpUcmVlLmltcHJlc3Npb24pO1xuICB0aGlzLmNyZWF0aXZlcyA9IENyZWF0aXZlLnBhcnNlQ3JlYXRpdmVzKGlubGluZUpUcmVlLmNyZWF0aXZlcyk7XG5cbiAgLy9PcHRpb25hbCBGaWVsZHNcbiAgdGhpcy5kZXNjcmlwdGlvbiA9IHhtbC5rZXlWYWx1ZShpbmxpbmVKVHJlZS5kZXNjcmlwdGlvbik7XG4gIHRoaXMuYWR2ZXJ0aXNlciA9IHhtbC5rZXlWYWx1ZShpbmxpbmVKVHJlZS5hZHZlcnRpc2VyKTtcbiAgdGhpcy5zdXJ2ZXlzID0gcGFyc2VTdXJ2ZXlzKGlubGluZUpUcmVlLnN1cnZleSk7XG4gIHRoaXMuZXJyb3IgPSB4bWwua2V5VmFsdWUoaW5saW5lSlRyZWUuZXJyb3IpO1xuICB0aGlzLnByaWNpbmcgPSB4bWwua2V5VmFsdWUoaW5saW5lSlRyZWUucHJpY2luZyk7XG4gIHRoaXMuZXh0ZW5zaW9ucyA9IGlubGluZUpUcmVlLmV4dGVuc2lvbnM7XG5cbiAgLyoqKiBMb2NhbCBGdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBwYXJzZVN1cnZleXMoaW5saW5lU3VydmV5cykge1xuICAgIGlmIChpbmxpbmVTdXJ2ZXlzKSB7XG4gICAgICByZXR1cm4gdXRpbGl0aWVzLnRyYW5zZm9ybUFycmF5KHV0aWxpdGllcy5pc0FycmF5KGlubGluZVN1cnZleXMpID8gaW5saW5lU3VydmV5cyA6IFtpbmxpbmVTdXJ2ZXlzXSwgZnVuY3Rpb24gKHN1cnZleSkge1xuICAgICAgICBpZih1dGlsaXRpZXMuaXNOb3RFbXB0eVN0cmluZyhzdXJ2ZXkua2V5VmFsdWUpKXtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdXJpOiBzdXJ2ZXkua2V5VmFsdWUsXG4gICAgICAgICAgICB0eXBlOiBzdXJ2ZXkuYXR0cigndHlwZScpXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xuICB9XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgYWxsIHRoZSBjcmVhdGl2ZXMuXG4gKi9cbkluTGluZS5wcm90b3R5cGUuaXNTdXBwb3J0ZWQgPSBmdW5jdGlvbigpe1xuICB2YXIgaSxsZW47XG5cbiAgaWYodGhpcy5jcmVhdGl2ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZm9yKGkgPSAwLCBsZW4gPSB0aGlzLmNyZWF0aXZlcy5sZW5ndGg7IGk8IGxlbjsgaSs9MSl7XG4gICAgaWYoIXRoaXMuY3JlYXRpdmVzW2ldLmlzU3VwcG9ydGVkKCkpe1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gSW5MaW5lO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHJhY2tpbmdFdmVudCA9IHJlcXVpcmUoJy4vVHJhY2tpbmdFdmVudCcpO1xudmFyIE1lZGlhRmlsZSA9IHJlcXVpcmUoJy4vTWVkaWFGaWxlJyk7XG52YXIgVmlkZW9DbGlja3MgPSByZXF1aXJlKCcuL1ZpZGVvQ2xpY2tzJyk7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG52YXIgcGFyc2VycyA9IHJlcXVpcmUoJy4vcGFyc2VycycpO1xuXG52YXIgeG1sID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMveG1sJyk7XG5cblxuZnVuY3Rpb24gTGluZWFyKGxpbmVhckpUcmVlKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBMaW5lYXIpKSB7XG4gICAgcmV0dXJuIG5ldyBMaW5lYXIobGluZWFySlRyZWUpO1xuICB9XG5cbiAgLy9SZXF1aXJlZCBFbGVtZW50c1xuICB0aGlzLmR1cmF0aW9uID0gcGFyc2Vycy5kdXJhdGlvbih4bWwua2V5VmFsdWUobGluZWFySlRyZWUuZHVyYXRpb24pKTtcbiAgdGhpcy5tZWRpYUZpbGVzID0gcGFyc2VNZWRpYUZpbGVzKGxpbmVhckpUcmVlLm1lZGlhRmlsZXMgJiYgbGluZWFySlRyZWUubWVkaWFGaWxlcy5tZWRpYUZpbGUpO1xuXG4gIC8vT3B0aW9uYWwgZmllbGRzXG4gIHRoaXMudHJhY2tpbmdFdmVudHMgPSBwYXJzZVRyYWNraW5nRXZlbnRzKGxpbmVhckpUcmVlLnRyYWNraW5nRXZlbnRzICYmIGxpbmVhckpUcmVlLnRyYWNraW5nRXZlbnRzLnRyYWNraW5nLCB0aGlzLmR1cmF0aW9uKTtcbiAgdGhpcy5za2lwb2Zmc2V0ID0gcGFyc2Vycy5vZmZzZXQoeG1sLmF0dHIobGluZWFySlRyZWUsICdza2lwb2Zmc2V0JyksIHRoaXMuZHVyYXRpb24pO1xuXG4gIGlmIChsaW5lYXJKVHJlZS52aWRlb0NsaWNrcykge1xuICAgIHRoaXMudmlkZW9DbGlja3MgPSBuZXcgVmlkZW9DbGlja3MobGluZWFySlRyZWUudmlkZW9DbGlja3MpO1xuICB9XG5cbiAgaWYobGluZWFySlRyZWUuYWRQYXJhbWV0ZXJzKSB7XG4gICAgdGhpcy5hZFBhcmFtZXRlcnMgPSB4bWwua2V5VmFsdWUobGluZWFySlRyZWUuYWRQYXJhbWV0ZXJzKTtcblxuICAgIGlmKHhtbC5hdHRyKGxpbmVhckpUcmVlLmFkUGFyYW1ldGVycywgJ3htbEVuY29kZWQnKSl7XG4gICAgICB0aGlzLmFkUGFyYW1ldGVycyA9IHhtbC5kZWNvZGUodGhpcy5hZFBhcmFtZXRlcnMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gcGFyc2VUcmFja2luZ0V2ZW50cyh0cmFja2luZ0V2ZW50cywgZHVyYXRpb24pIHtcbiAgICB2YXIgdHJhY2tpbmdzID0gW107XG4gICAgaWYgKHV0aWxpdGllcy5pc0RlZmluZWQodHJhY2tpbmdFdmVudHMpKSB7XG4gICAgICB0cmFja2luZ0V2ZW50cyA9IHV0aWxpdGllcy5pc0FycmF5KHRyYWNraW5nRXZlbnRzKSA/IHRyYWNraW5nRXZlbnRzIDogW3RyYWNraW5nRXZlbnRzXTtcbiAgICAgIHRyYWNraW5nRXZlbnRzLmZvckVhY2goZnVuY3Rpb24gKHRyYWNraW5nRGF0YSkge1xuICAgICAgICB0cmFja2luZ3MucHVzaChuZXcgVHJhY2tpbmdFdmVudCh0cmFja2luZ0RhdGEsIGR1cmF0aW9uKSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRyYWNraW5ncztcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlTWVkaWFGaWxlcyhtZWRpYUZpbGVzSnhvblRyZWUpIHtcbiAgICB2YXIgbWVkaWFGaWxlcyA9IFtdO1xuICAgIGlmICh1dGlsaXRpZXMuaXNEZWZpbmVkKG1lZGlhRmlsZXNKeG9uVHJlZSkpIHtcbiAgICAgIG1lZGlhRmlsZXNKeG9uVHJlZSA9IHV0aWxpdGllcy5pc0FycmF5KG1lZGlhRmlsZXNKeG9uVHJlZSkgPyBtZWRpYUZpbGVzSnhvblRyZWUgOiBbbWVkaWFGaWxlc0p4b25UcmVlXTtcblxuICAgICAgbWVkaWFGaWxlc0p4b25UcmVlLmZvckVhY2goZnVuY3Rpb24gKG1mRGF0YSkge1xuICAgICAgICBtZWRpYUZpbGVzLnB1c2gobmV3IE1lZGlhRmlsZShtZkRhdGEpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gbWVkaWFGaWxlcztcbiAgfVxufVxuXG4vKipcbiAqIE11c3QgcmV0dXJuIHRydWUgaWYgYXQgbGVhc3Qgb25lIG9mIHRoZSBNZWRpYUZpbGVzJyB0eXBlIGlzIHN1cHBvcnRlZFxuICovXG5MaW5lYXIucHJvdG90eXBlLmlzU3VwcG9ydGVkID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaSwgbGVuO1xuICBmb3IoaT0wLCBsZW49dGhpcy5tZWRpYUZpbGVzLmxlbmd0aDsgaTxsZW47IGkrPTEpIHtcbiAgICBpZih0aGlzLm1lZGlhRmlsZXNbaV0uaXNTdXBwb3J0ZWQoKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBMaW5lYXI7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgeG1sID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMveG1sJyk7XG52YXIgdmFzdFV0aWwgPSByZXF1aXJlKCcuL3Zhc3RVdGlsJyk7XG5cbnZhciBhdHRyaWJ1dGVzTGlzdCA9IFtcbiAgLy9SZXF1aXJlZCBhdHRyaWJ1dGVzXG4gICdkZWxpdmVyeScsXG4gICd0eXBlJyxcbiAgJ3dpZHRoJyxcbiAgJ2hlaWdodCcsXG4gIC8vT3B0aW9uYWwgYXR0cmlidXRlc1xuICAnY29kZWMnLFxuICAnaWQnLFxuICAnYml0cmF0ZScsXG4gICdtaW5CaXRyYXRlJyxcbiAgJ21heEJpdHJhdGUnLFxuICAnc2NhbGFibGUnLFxuICAnbWFpbnRhaW5Bc3BlY3RSYXRpbycsXG4gICdhcGlGcmFtZXdvcmsnXG5dO1xuXG5mdW5jdGlvbiBNZWRpYUZpbGUobWVkaWFGaWxlSlRyZWUpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIE1lZGlhRmlsZSkpIHtcbiAgICByZXR1cm4gbmV3IE1lZGlhRmlsZShtZWRpYUZpbGVKVHJlZSk7XG4gIH1cblxuICAvL1JlcXVpcmVkIGF0dHJpYnV0ZXNcbiAgdGhpcy5zcmMgPSB4bWwua2V5VmFsdWUobWVkaWFGaWxlSlRyZWUpO1xuXG4gIGZvcih2YXIgeD0wOyB4PGF0dHJpYnV0ZXNMaXN0Lmxlbmd0aDsgeCsrKSB7XG4gICAgdmFyIGF0dHJpYnV0ZSA9IGF0dHJpYnV0ZXNMaXN0W3hdO1xuICAgIHRoaXNbYXR0cmlidXRlXSA9IG1lZGlhRmlsZUpUcmVlLmF0dHIoYXR0cmlidXRlKTtcbiAgfVxufVxuXG5NZWRpYUZpbGUucHJvdG90eXBlLmlzU3VwcG9ydGVkID0gZnVuY3Rpb24oKXtcbiAgaWYodmFzdFV0aWwuaXNWUEFJRCh0aGlzKSkge1xuICAgIHJldHVybiAhIXZhc3RVdGlsLmZpbmRTdXBwb3J0ZWRWUEFJRFRlY2godGhpcy50eXBlKTtcbiAgfVxuXG4gIGlmICh0aGlzLnR5cGUgPT09ICd2aWRlby94LWZsdicpIHtcbiAgICByZXR1cm4gdmFzdFV0aWwuaXNGbGFzaFN1cHBvcnRlZCgpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1lZGlhRmlsZTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHBhcnNlcnMgPSByZXF1aXJlKCcuL3BhcnNlcnMnKTtcblxudmFyIHhtbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3htbCcpO1xuXG5mdW5jdGlvbiBUcmFja2luZ0V2ZW50KHRyYWNraW5nSlRyZWUsIGR1cmF0aW9uKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBUcmFja2luZ0V2ZW50KSkge1xuICAgIHJldHVybiBuZXcgVHJhY2tpbmdFdmVudCh0cmFja2luZ0pUcmVlLCBkdXJhdGlvbik7XG4gIH1cblxuICB0aGlzLm5hbWUgPSB0cmFja2luZ0pUcmVlLmF0dHIoJ2V2ZW50Jyk7XG4gIHRoaXMudXJpID0geG1sLmtleVZhbHVlKHRyYWNraW5nSlRyZWUpO1xuXG4gIGlmKCdwcm9ncmVzcycgPT09IHRoaXMubmFtZSkge1xuICAgIHRoaXMub2Zmc2V0ID0gcGFyc2Vycy5vZmZzZXQodHJhY2tpbmdKVHJlZS5hdHRyKCdvZmZzZXQnKSwgZHVyYXRpb24pO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gVHJhY2tpbmdFdmVudDsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBBZCA9IHJlcXVpcmUoJy4vQWQnKTtcbnZhciBWQVNURXJyb3IgPSByZXF1aXJlKCcuL1ZBU1RFcnJvcicpO1xudmFyIFZBU1RSZXNwb25zZSA9IHJlcXVpcmUoJy4vVkFTVFJlc3BvbnNlJyk7XG52YXIgdmFzdFV0aWwgPSByZXF1aXJlKCcuL3Zhc3RVdGlsJyk7XG5cbnZhciBhc3luYyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL2FzeW5jJyk7XG52YXIgaHR0cCA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL2h0dHAnKS5odHRwO1xudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcbnZhciB4bWwgPSByZXF1aXJlKCcuLi8uLi91dGlscy94bWwnKTtcblxuZnVuY3Rpb24gVkFTVENsaWVudChvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBWQVNUQ2xpZW50KSkge1xuICAgIHJldHVybiBuZXcgVkFTVENsaWVudChvcHRpb25zKTtcbiAgfVxuICB2YXIgZGVmYXVsdE9wdGlvbnMgPSB7XG4gICAgV1JBUFBFUl9MSU1JVDogNVxuICB9O1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICB0aGlzLnNldHRpbmdzID0gdXRpbGl0aWVzLmV4dGVuZCh7fSwgb3B0aW9ucywgZGVmYXVsdE9wdGlvbnMpO1xuICB0aGlzLmVycm9yVVJMTWFjcm9zID0gW107XG59XG5cblZBU1RDbGllbnQucHJvdG90eXBlLmdldFZBU1RSZXNwb25zZSA9IGZ1bmN0aW9uIGdldFZBU1RSZXNwb25zZShhZFRhZ1VybCwgY2FsbGJhY2spIHtcbiAgdmFyIHRoYXQgPSB0aGlzO1xuXG4gIHZhciBlcnJvciA9IHNhbml0eUNoZWNrKGFkVGFnVXJsLCBjYWxsYmFjayk7XG4gIGlmIChlcnJvcikge1xuICAgIGlmICh1dGlsaXRpZXMuaXNGdW5jdGlvbihjYWxsYmFjaykpIHtcbiAgICAgIHJldHVybiBjYWxsYmFjayhlcnJvcik7XG4gICAgfVxuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgYXN5bmMud2F0ZXJmYWxsKFtcbiAgICAgIHRoaXMuX2dldFZBU1RBZC5iaW5kKHRoaXMsIGFkVGFnVXJsKSxcbiAgICAgIGJ1aWxkVkFTVFJlc3BvbnNlXG4gICAgXSxcbiAgICBjYWxsYmFjayk7XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBidWlsZFZBU1RSZXNwb25zZShhZHNDaGFpbiwgY2IpIHtcbiAgICB0cnkge1xuICAgICAgdmFyIHJlc3BvbnNlID0gdGhhdC5fYnVpbGRWQVNUUmVzcG9uc2UoYWRzQ2hhaW4pO1xuICAgICAgY2IobnVsbCwgcmVzcG9uc2UpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNiKGUpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNhbml0eUNoZWNrKGFkVGFnVXJsLCBjYikge1xuICAgIGlmICghYWRUYWdVcmwpIHtcbiAgICAgIHJldHVybiBuZXcgVkFTVEVycm9yKCdvbiBWQVNUQ2xpZW50LmdldFZBU1RSZXNwb25zZSwgbWlzc2luZyBhZCB0YWcgVVJMJyk7XG4gICAgfVxuXG4gICAgaWYgKCF1dGlsaXRpZXMuaXNGdW5jdGlvbihjYikpIHtcbiAgICAgIHJldHVybiBuZXcgVkFTVEVycm9yKCdvbiBWQVNUQ2xpZW50LmdldFZBU1RSZXNwb25zZSwgbWlzc2luZyBjYWxsYmFjayBmdW5jdGlvbicpO1xuICAgIH1cbiAgfVxufTtcblxuVkFTVENsaWVudC5wcm90b3R5cGUuX2dldFZBU1RBZCA9IGZ1bmN0aW9uIChhZFRhZ1VybCwgY2FsbGJhY2spIHtcbiAgdmFyIHRoYXQgPSB0aGlzO1xuXG4gIGdldEFkV2F0ZXJmYWxsKGFkVGFnVXJsLCBmdW5jdGlvbiAoZXJyb3IsIHZhc3RUcmVlKSB7XG4gICAgdmFyIHdhdGVyZmFsbEFkcyA9IHZhc3RUcmVlICYmIHV0aWxpdGllcy5pc0FycmF5KHZhc3RUcmVlLmFkcykgPyB2YXN0VHJlZS5hZHMgOiBudWxsO1xuICAgIGlmIChlcnJvcikge1xuICAgICAgdGhhdC5fdHJhY2tFcnJvcihlcnJvciwgd2F0ZXJmYWxsQWRzKTtcbiAgICAgIHJldHVybiBjYWxsYmFjayhlcnJvciwgd2F0ZXJmYWxsQWRzKTtcbiAgICB9XG5cbiAgICBnZXRBZCh3YXRlcmZhbGxBZHMuc2hpZnQoKSwgW10sIHdhdGVyZmFsbEhhbmRsZXIpO1xuXG4gICAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqL1xuICAgIGZ1bmN0aW9uIHdhdGVyZmFsbEhhbmRsZXIoZXJyb3IsIGFkQ2hhaW4pIHtcbiAgICAgIGlmIChlcnJvcikge1xuICAgICAgICB0aGF0Ll90cmFja0Vycm9yKGVycm9yLCBhZENoYWluKTtcbiAgICAgICAgaWYgKHdhdGVyZmFsbEFkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgZ2V0QWQod2F0ZXJmYWxsQWRzLnNoaWZ0KCksW10sIHdhdGVyZmFsbEhhbmRsZXIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNhbGxiYWNrKGVycm9yLCBhZENoYWluKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FsbGJhY2sobnVsbCwgYWRDaGFpbik7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICAvKioqIExvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIGdldEFkV2F0ZXJmYWxsKGFkVGFnVXJsLCBjYWxsYmFjaykge1xuICAgIHZhciByZXF1ZXN0VmFzdFhNTCA9IHRoYXQuX3JlcXVlc3RWQVNUWG1sLmJpbmQodGhhdCwgYWRUYWdVcmwpO1xuICAgIGFzeW5jLndhdGVyZmFsbChbXG4gICAgICByZXF1ZXN0VmFzdFhNTCxcbiAgICAgIGJ1aWxkVmFzdFdhdGVyZmFsbFxuICAgIF0sIGNhbGxiYWNrKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGJ1aWxkVmFzdFdhdGVyZmFsbCh4bWxTdHIsIGNhbGxiYWNrKSB7XG4gICAgdmFyIHZhc3RUcmVlO1xuICAgIHRyeSB7XG4gICAgICB2YXN0VHJlZSA9IHhtbC50b0pYT05UcmVlKHhtbFN0cik7XG5cbiAgICAgIGlmKHV0aWxpdGllcy5pc0FycmF5KHZhc3RUcmVlLmFkKSkge1xuICAgICAgICB2YXN0VHJlZS5hZHMgPSB2YXN0VHJlZS5hZDtcbiAgICAgIH0gZWxzZSBpZih2YXN0VHJlZS5hZCl7XG4gICAgICAgIHZhc3RUcmVlLmFkcyA9IFt2YXN0VHJlZS5hZF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXN0VHJlZS5hZHMgPSBbXTtcbiAgICAgIH1cbiAgICAgIGNhbGxiYWNrKHZhbGlkYXRlVkFTVFRyZWUodmFzdFRyZWUpLCB2YXN0VHJlZSk7XG5cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjYWxsYmFjayhuZXcgVkFTVEVycm9yKFwib24gVkFTVENsaWVudC5nZXRWQVNUQWQuYnVpbGRWYXN0V2F0ZXJmYWxsLCBlcnJvciBwYXJzaW5nIHhtbFwiLCAxMDApLCBudWxsKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB2YWxpZGF0ZVZBU1RUcmVlKHZhc3RUcmVlKSB7XG4gICAgdmFyIHZhc3RWZXJzaW9uID0geG1sLmF0dHIodmFzdFRyZWUsICd2ZXJzaW9uJyk7XG5cbiAgICBpZiAoIXZhc3RUcmVlLmFkKSB7XG4gICAgICByZXR1cm4gbmV3IFZBU1RFcnJvcignb24gVkFTVENsaWVudC5nZXRWQVNUQWQudmFsaWRhdGVWQVNUVHJlZSwgbm8gQWQgaW4gVkFTVCB0cmVlJywgMzAzKTtcbiAgICB9XG5cbiAgICBpZiAodmFzdFZlcnNpb24gJiYgKHZhc3RWZXJzaW9uICE9IDMgJiYgdmFzdFZlcnNpb24gIT0gMikpIHtcbiAgICAgIHJldHVybiBuZXcgVkFTVEVycm9yKCdvbiBWQVNUQ2xpZW50LmdldFZBU1RBZC52YWxpZGF0ZVZBU1RUcmVlLCBub3Qgc3VwcG9ydGVkIFZBU1QgdmVyc2lvbiBcIicgKyB2YXN0VmVyc2lvbiArICdcIicsIDEwMik7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRBZChhZFRhZ1VybCwgYWRDaGFpbiwgY2FsbGJhY2spIHtcbiAgICBpZiAoYWRDaGFpbi5sZW5ndGggPj0gdGhhdC5XUkFQUEVSX0xJTUlUKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2sobmV3IFZBU1RFcnJvcihcIm9uIFZBU1RDbGllbnQuZ2V0VkFTVEFkLmdldEFkLCBwbGF5ZXJzIHdyYXBwZXIgbGltaXQgcmVhY2hlZCAodGhlIGxpbWl0IGlzIFwiICsgdGhhdC5XUkFQUEVSX0xJTUlUICsgXCIpXCIsIDMwMiksIGFkQ2hhaW4pO1xuICAgIH1cblxuICAgIGFzeW5jLndhdGVyZmFsbChbXG4gICAgICBmdW5jdGlvbiAobmV4dCkge1xuICAgICAgICBpZiAodXRpbGl0aWVzLmlzU3RyaW5nKGFkVGFnVXJsKSkge1xuICAgICAgICAgIHJlcXVlc3RWQVNUQWQoYWRUYWdVcmwsIG5leHQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5leHQobnVsbCwgYWRUYWdVcmwpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgYnVpbGRBZFxuICAgIF0sIGZ1bmN0aW9uIChlcnJvciwgYWQpIHtcbiAgICAgIGlmIChhZCkge1xuICAgICAgICBhZENoYWluLnB1c2goYWQpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycm9yLCBhZENoYWluKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFkLndyYXBwZXIpIHtcbiAgICAgICAgcmV0dXJuIGdldEFkKGFkLndyYXBwZXIuVkFTVEFkVGFnVVJJLCBhZENoYWluLCBjYWxsYmFjayk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBhZENoYWluKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGJ1aWxkQWQoYWRKeG9uVHJlZSwgY2FsbGJhY2spIHtcbiAgICB0cnkge1xuICAgICAgdmFyIGFkID0gbmV3IEFkKGFkSnhvblRyZWUpO1xuICAgICAgY2FsbGJhY2sodmFsaWRhdGVBZChhZCksIGFkKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjYWxsYmFjayhuZXcgVkFTVEVycm9yKCdvbiBWQVNUQ2xpZW50LmdldFZBU1RBZC5idWlsZEFkLCBlcnJvciBwYXJzaW5nIHhtbCcsIDEwMCksIG51bGwpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHZhbGlkYXRlQWQoYWQpIHtcbiAgICB2YXIgd3JhcHBlciA9IGFkLndyYXBwZXI7XG4gICAgdmFyIGluTGluZSA9IGFkLmluTGluZTtcbiAgICB2YXIgZXJyTXNnUHJlZml4ID0gJ29uIFZBU1RDbGllbnQuZ2V0VkFTVEFkLnZhbGlkYXRlQWQsICc7XG5cbiAgICBpZiAoaW5MaW5lICYmIHdyYXBwZXIpIHtcbiAgICAgIHJldHVybiBuZXcgVkFTVEVycm9yKGVyck1zZ1ByZWZpeCArXCJJbkxpbmUgYW5kIFdyYXBwZXIgYm90aCBmb3VuZCBvbiB0aGUgc2FtZSBBZFwiLCAxMDEpO1xuICAgIH1cblxuICAgIGlmICghaW5MaW5lICYmICF3cmFwcGVyKSB7XG4gICAgICByZXR1cm4gbmV3IFZBU1RFcnJvcihlcnJNc2dQcmVmaXggKyBcIm5vciB3cmFwcGVyIG5vciBpbmxpbmUgZWxlbWVudHMgZm91bmQgb24gdGhlIEFkXCIsIDEwMSk7XG4gICAgfVxuXG4gICAgaWYgKGluTGluZSAmJiAhaW5MaW5lLmlzU3VwcG9ydGVkKCkpIHtcbiAgICAgIHJldHVybiBuZXcgVkFTVEVycm9yKGVyck1zZ1ByZWZpeCArIFwiY291bGQgbm90IGZpbmQgTWVkaWFGaWxlIHRoYXQgaXMgc3VwcG9ydGVkIGJ5IHRoaXMgdmlkZW8gcGxheWVyXCIsIDQwMyk7XG4gICAgfVxuXG4gICAgaWYgKHdyYXBwZXIgJiYgIXdyYXBwZXIuVkFTVEFkVGFnVVJJKSB7XG4gICAgICByZXR1cm4gbmV3IFZBU1RFcnJvcihlcnJNc2dQcmVmaXggKyBcIm1pc3NpbmcgJ1ZBU1RBZFRhZ1VSSScgaW4gd3JhcHBlclwiLCAxMDEpO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVxdWVzdFZBU1RBZChhZFRhZ1VybCwgY2FsbGJhY2spIHtcbiAgICB0aGF0Ll9yZXF1ZXN0VkFTVFhtbChhZFRhZ1VybCwgZnVuY3Rpb24gKGVycm9yLCB4bWxTdHIpIHtcbiAgICAgIGlmIChlcnJvcikge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyb3IpO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgdmFyIHZhc3RUcmVlID0geG1sLnRvSlhPTlRyZWUoeG1sU3RyKTtcbiAgICAgICAgY2FsbGJhY2sodmFsaWRhdGVWQVNUVHJlZSh2YXN0VHJlZSksIHZhc3RUcmVlLmFkKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FsbGJhY2sobmV3IFZBU1RFcnJvcihcIm9uIFZBU1RDbGllbnQuZ2V0VkFTVEFkLnJlcXVlc3RWQVNUQWQsIGVycm9yIHBhcnNpbmcgeG1sXCIsIDEwMCkpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59O1xuXG5WQVNUQ2xpZW50LnByb3RvdHlwZS5fcmVxdWVzdFZBU1RYbWwgPSBmdW5jdGlvbiByZXF1ZXN0VkFTVFhtbChhZFRhZ1VybCwgY2FsbGJhY2spIHtcbiAgdHJ5IHtcbiAgICBpZiAodXRpbGl0aWVzLmlzRnVuY3Rpb24oYWRUYWdVcmwpKSB7XG4gICAgICBhZFRhZ1VybChyZXF1ZXN0SGFuZGxlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGh0dHAuZ2V0KGFkVGFnVXJsLCByZXF1ZXN0SGFuZGxlciwge1xuICAgICAgICB3aXRoQ3JlZGVudGlhbHM6IHRydWVcbiAgICAgIH0pO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGNhbGxiYWNrKGUpO1xuICB9XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiByZXF1ZXN0SGFuZGxlcihlcnJvciwgcmVzcG9uc2UsIHN0YXR1cykge1xuICAgIGlmIChlcnJvcikge1xuICAgICAgdmFyIGVyck1zZyA9IHV0aWxpdGllcy5pc0RlZmluZWQoc3RhdHVzKSA/XG4gICAgICBcIm9uIFZBU1RDbGllbnQucmVxdWVzdFZhc3RYTUwsIEhUVFAgcmVxdWVzdCBlcnJvciB3aXRoIHN0YXR1cyAnXCIgKyBzdGF0dXMgKyBcIidcIiA6XG4gICAgICAgIFwib24gVkFTVENsaWVudC5yZXF1ZXN0VmFzdFhNTCwgRXJyb3IgZ2V0dGluZyB0aGUgdGhlIFZBU1QgWE1MIHdpdGggaGUgcGFzc2VkIGFkVGFnWE1MIGZuXCI7XG4gICAgICByZXR1cm4gY2FsbGJhY2sobmV3IFZBU1RFcnJvcihlcnJNc2csIDMwMSksIG51bGwpO1xuICAgIH1cblxuICAgIGNhbGxiYWNrKG51bGwsIHJlc3BvbnNlKTtcbiAgfVxufTtcblxuVkFTVENsaWVudC5wcm90b3R5cGUuX2J1aWxkVkFTVFJlc3BvbnNlID0gZnVuY3Rpb24gYnVpbGRWQVNUUmVzcG9uc2UoYWRzQ2hhaW4pIHtcbiAgdmFyIHJlc3BvbnNlID0gbmV3IFZBU1RSZXNwb25zZSgpO1xuICBhZGRBZHNUb1Jlc3BvbnNlKHJlc3BvbnNlLCBhZHNDaGFpbik7XG4gIHZhbGlkYXRlUmVzcG9uc2UocmVzcG9uc2UpO1xuXG4gIHJldHVybiByZXNwb25zZTtcblxuICAvLyoqKiBMb2NhbCBmdW5jdGlvbiAqKioqXG4gIGZ1bmN0aW9uIGFkZEFkc1RvUmVzcG9uc2UocmVzcG9uc2UsIGFkcykge1xuICAgIGFkcy5mb3JFYWNoKGZ1bmN0aW9uIChhZCkge1xuICAgICAgcmVzcG9uc2UuYWRkQWQoYWQpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gdmFsaWRhdGVSZXNwb25zZShyZXNwb25zZSkge1xuICAgIHZhciBwcm9ncmVzc0V2ZW50cyA9IHJlc3BvbnNlLnRyYWNraW5nRXZlbnRzLnByb2dyZXNzO1xuXG4gICAgaWYgKCFyZXNwb25zZS5oYXNMaW5lYXIoKSkge1xuICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcihcIm9uIFZBU1RDbGllbnQuX2J1aWxkVkFTVFJlc3BvbnNlLCBSZWNlaXZlZCBhbiBBZCB0eXBlIHRoYXQgaXMgbm90IHN1cHBvcnRlZFwiLCAyMDApO1xuICAgIH1cblxuICAgIGlmIChyZXNwb25zZS5kdXJhdGlvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFwib24gVkFTVENsaWVudC5fYnVpbGRWQVNUUmVzcG9uc2UsIE1pc3NpbmcgZHVyYXRpb24gZmllbGQgaW4gVkFTVCByZXNwb25zZVwiLCAxMDEpO1xuICAgIH1cblxuICAgIGlmIChwcm9ncmVzc0V2ZW50cykge1xuICAgICAgcHJvZ3Jlc3NFdmVudHMuZm9yRWFjaChmdW5jdGlvbiAocHJvZ3Jlc3NFdmVudCkge1xuICAgICAgICBpZiAoIXV0aWxpdGllcy5pc051bWJlcihwcm9ncmVzc0V2ZW50Lm9mZnNldCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFwib24gVkFTVENsaWVudC5fYnVpbGRWQVNUUmVzcG9uc2UsIG1pc3Npbmcgb3Igd3Jvbmcgb2Zmc2V0IGF0dHJpYnV0ZSBvbiBwcm9ncmVzcyB0cmFja2luZyBldmVudFwiLCAxMDEpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn07XG5cblZBU1RDbGllbnQucHJvdG90eXBlLl90cmFja0Vycm9yID0gZnVuY3Rpb24gKGVycm9yLCBhZENoYWluKSB7XG4gIGlmICghdXRpbGl0aWVzLmlzQXJyYXkoYWRDaGFpbikgfHwgYWRDaGFpbi5sZW5ndGggPT09IDApIHsgLy9UaGVyZSBpcyBub3RoaW5nIHRvIHRyYWNrXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGVycm9yVVJMTWFjcm9zID0gW107XG4gIGFkQ2hhaW4uZm9yRWFjaChhZGRFcnJvclVybE1hY3Jvcyk7XG4gIHZhc3RVdGlsLnRyYWNrKGVycm9yVVJMTWFjcm9zLCB7RVJST1JDT0RFOiBlcnJvci5jb2RlIHx8IDkwMH0pOyAgLy85MDAgPD09IFVuZGVmaW5lZCBlcnJvclxuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb25zICAqKiovXG4gIGZ1bmN0aW9uIGFkZEVycm9yVXJsTWFjcm9zKGFkKSB7XG4gICAgaWYgKGFkLndyYXBwZXIgJiYgYWQud3JhcHBlci5lcnJvcikge1xuICAgICAgZXJyb3JVUkxNYWNyb3MucHVzaChhZC53cmFwcGVyLmVycm9yKTtcbiAgICB9XG5cbiAgICBpZiAoYWQuaW5MaW5lICYmIGFkLmluTGluZS5lcnJvcikge1xuICAgICAgZXJyb3JVUkxNYWNyb3MucHVzaChhZC5pbkxpbmUuZXJyb3IpO1xuICAgIH1cbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBWQVNUQ2xpZW50O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBWQVNURXJyb3IobWVzc2FnZSwgY29kZSkge1xuICB0aGlzLm1lc3NhZ2UgPSAnVkFTVCBFcnJvcjogJyArIChtZXNzYWdlIHx8ICcnKTtcbiAgaWYgKGNvZGUpIHtcbiAgICB0aGlzLmNvZGUgPSBjb2RlO1xuICB9XG59XG5cblZBU1RFcnJvci5wcm90b3R5cGUgPSBuZXcgRXJyb3IoKTtcblZBU1RFcnJvci5wcm90b3R5cGUubmFtZSA9IFwiVkFTVCBFcnJvclwiO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZBU1RFcnJvcjsiLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogSW5uZXIgaGVscGVyIGNsYXNzIHRoYXQgZGVhbHMgd2l0aCB0aGUgbG9naWMgb2YgdGhlIGluZGl2aWR1YWwgc3RlcHMgbmVlZGVkIHRvIHNldHVwIGFuIGFkIGluIHRoZSBwbGF5ZXIuXG4gKlxuICogQHBhcmFtIHBsYXllciB7b2JqZWN0fSBpbnN0YW5jZSBvZiB0aGUgcGxheWVyIHRoYXQgd2lsbCBwbGF5IHRoZSBhZC4gSXQgYXNzdW1lcyB0aGF0IHRoZSB2aWRlb2pzLWNvbnRyaWItYWRzIHBsdWdpblxuICogICAgICAgICAgICAgICAgICAgICAgICBoYXMgYmVlbiBpbml0aWFsaXplZCB3aGVuIHlvdSB1c2UgaXRzIHV0aWxpdHkgZnVuY3Rpb25zLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5cbnZhciBWQVNUUmVzcG9uc2UgPSByZXF1aXJlKCcuL1ZBU1RSZXNwb25zZScpO1xudmFyIFZBU1RFcnJvciA9IHJlcXVpcmUoJy4vVkFTVEVycm9yJyk7XG52YXIgVkFTVFRyYWNrZXIgPSByZXF1aXJlKCcuL1ZBU1RUcmFja2VyJyk7XG52YXIgdmFzdFV0aWwgPSByZXF1aXJlKCcuL3Zhc3RVdGlsJyk7XG5cbnZhciBhc3luYyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL2FzeW5jJyk7XG52YXIgZG9tID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvZG9tJyk7XG52YXIgcGxheWVyVXRpbHMgPSByZXF1aXJlKCcuLi8uLi91dGlscy9wbGF5ZXJVdGlscycpO1xudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxuZnVuY3Rpb24gVkFTVEludGVncmF0b3IocGxheWVyKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBWQVNUSW50ZWdyYXRvcikpIHtcbiAgICByZXR1cm4gbmV3IFZBU1RJbnRlZ3JhdG9yKHBsYXllcik7XG4gIH1cblxuICB0aGlzLnBsYXllciA9IHBsYXllcjtcbn1cblxuVkFTVEludGVncmF0b3IucHJvdG90eXBlLnBsYXlBZCA9IGZ1bmN0aW9uIHBsYXlBZCh2YXN0UmVzcG9uc2UsIGNhbGxiYWNrKSB7XG4gIHZhciB0aGF0ID0gdGhpcztcbiAgY2FsbGJhY2sgPSBjYWxsYmFjayB8fCB1dGlsaXRpZXMubm9vcDtcblxuICBpZiAoISh2YXN0UmVzcG9uc2UgaW5zdGFuY2VvZiBWQVNUUmVzcG9uc2UpKSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBWQVNURXJyb3IoJ09uIFZBU1RJbnRlZ3JhdG9yLCBtaXNzaW5nIHJlcXVpcmVkIFZBU1RSZXNwb25zZScpKTtcbiAgfVxuXG4gIGFzeW5jLndhdGVyZmFsbChbXG4gICAgZnVuY3Rpb24gKG5leHQpIHtcbiAgICAgIG5leHQobnVsbCwgdmFzdFJlc3BvbnNlKTtcbiAgICB9LFxuICAgIHRoaXMuX3NlbGVjdEFkU291cmNlLmJpbmQodGhpcyksXG4gICAgdGhpcy5fY3JlYXRlVkFTVFRyYWNrZXIuYmluZCh0aGlzKSxcbiAgICB0aGlzLl9hZGRDbGlja1Rocm91Z2guYmluZCh0aGlzKSxcbiAgICB0aGlzLl9hZGRTa2lwQnV0dG9uLmJpbmQodGhpcyksXG4gICAgdGhpcy5fc2V0dXBFdmVudHMuYmluZCh0aGlzKSxcbiAgICB0aGlzLl9wbGF5U2VsZWN0ZWRBZC5iaW5kKHRoaXMpXG4gIF0sIGZ1bmN0aW9uIChlcnJvciwgcmVzcG9uc2UpIHtcbiAgICBpZiAoZXJyb3IgJiYgcmVzcG9uc2UpIHtcbiAgICAgIHRoYXQuX3RyYWNrRXJyb3IoZXJyb3IsIHJlc3BvbnNlKTtcbiAgICB9XG4gICAgY2FsbGJhY2soZXJyb3IsIHJlc3BvbnNlKTtcbiAgfSk7XG5cbiAgdGhpcy5fYWRVbml0ID0ge1xuICAgIF9zcmM6IG51bGwsXG4gICAgdHlwZTogJ1ZBU1QnLFxuICAgIHBhdXNlQWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoYXQucGxheWVyLnBhdXNlKHRydWUpO1xuICAgIH0sXG5cbiAgICByZXN1bWVBZDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhhdC5wbGF5ZXIucGxheSh0cnVlKTtcbiAgICB9LFxuXG4gICAgaXNQYXVzZWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiB0aGF0LnBsYXllci5wYXVzZWQodHJ1ZSk7XG4gICAgfSxcblxuICAgIGdldFNyYzogZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3NyYztcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHRoaXMuX2FkVW5pdDtcbn07XG5cblZBU1RJbnRlZ3JhdG9yLnByb3RvdHlwZS5fc2VsZWN0QWRTb3VyY2UgPSBmdW5jdGlvbiBzZWxlY3RBZFNvdXJjZShyZXNwb25zZSwgY2FsbGJhY2spIHtcbiAgdmFyIHNvdXJjZTtcblxuICB2YXIgcGxheWVyV2lkdGggPSBkb20uZ2V0RGltZW5zaW9uKHRoaXMucGxheWVyLmVsKCkpLndpZHRoO1xuICByZXNwb25zZS5tZWRpYUZpbGVzLnNvcnQoZnVuY3Rpb24gY29tcGFyZVRvKGEsIGIpIHtcbiAgICB2YXIgZGVsdGFBID0gTWF0aC5hYnMocGxheWVyV2lkdGggLSBhLndpZHRoKTtcbiAgICB2YXIgZGVsdGFCID0gTWF0aC5hYnMocGxheWVyV2lkdGggLSBiLndpZHRoKTtcbiAgICByZXR1cm4gZGVsdGFBIC0gZGVsdGFCO1xuICB9KTtcblxuICBzb3VyY2UgPSB0aGlzLnBsYXllci5zZWxlY3RTb3VyY2UocmVzcG9uc2UubWVkaWFGaWxlcykuc291cmNlO1xuXG4gIGlmIChzb3VyY2UpIHtcbiAgICBpZiAodGhpcy5fYWRVbml0KSB7XG4gICAgICB0aGlzLl9hZFVuaXQuX3NyYyA9IHNvdXJjZTtcbiAgICB9XG4gICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHNvdXJjZSwgcmVzcG9uc2UpO1xuICB9XG5cbiAgLy8gY29kZSA0MDMgPD09IENvdWxkbid0IGZpbmQgTWVkaWFGaWxlIHRoYXQgaXMgc3VwcG9ydGVkIGJ5IHRoaXMgdmlkZW8gcGxheWVyXG4gIGNhbGxiYWNrKG5ldyBWQVNURXJyb3IoXCJDb3VsZCBub3QgZmluZCBBZCBtZWRpYWZpbGUgc3VwcG9ydGVkIGJ5IHRoaXMgcGxheWVyXCIsIDQwMyksIHJlc3BvbnNlKTtcbn07XG5cblZBU1RJbnRlZ3JhdG9yLnByb3RvdHlwZS5fY3JlYXRlVkFTVFRyYWNrZXIgPSBmdW5jdGlvbiBjcmVhdGVWQVNUVHJhY2tlcihhZE1lZGlhRmlsZSwgcmVzcG9uc2UsIGNhbGxiYWNrKSB7XG4gIHRyeSB7XG4gICAgY2FsbGJhY2sobnVsbCwgYWRNZWRpYUZpbGUsIG5ldyBWQVNUVHJhY2tlcihhZE1lZGlhRmlsZS5zcmMsIHJlc3BvbnNlKSwgcmVzcG9uc2UpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgY2FsbGJhY2soZSwgcmVzcG9uc2UpO1xuICB9XG59O1xuXG5WQVNUSW50ZWdyYXRvci5wcm90b3R5cGUuX3NldHVwRXZlbnRzID0gZnVuY3Rpb24gc2V0dXBFdmVudHMoYWRNZWRpYUZpbGUsIHRyYWNrZXIsIHJlc3BvbnNlLCBjYWxsYmFjaykge1xuICB2YXIgcHJldmlvdXNseU11dGVkO1xuICB2YXIgcGxheWVyID0gdGhpcy5wbGF5ZXI7XG4gIHBsYXllci5vbignZnVsbHNjcmVlbmNoYW5nZScsIHRyYWNrRnVsbHNjcmVlbkNoYW5nZSk7XG4gIHBsYXllci5vbigndmFzdC5hZFN0YXJ0JywgdHJhY2tJbXByZXNzaW9ucyk7XG4gIHBsYXllci5vbigncGF1c2UnLCB0cmFja1BhdXNlKTtcbiAgcGxheWVyLm9uKCd0aW1ldXBkYXRlJywgdHJhY2tQcm9ncmVzcyk7XG4gIHBsYXllci5vbigndm9sdW1lY2hhbmdlJywgdHJhY2tWb2x1bWVDaGFuZ2UpO1xuXG4gIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3Zhc3QuYWRFbmQnLCAndmFzdC5hZHNDYW5jZWwnXSwgdW5iaW5kRXZlbnRzKTtcbiAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsndmFzdC5hZEVuZCcsICd2YXN0LmFkc0NhbmNlbCcsICd2YXN0LmFkU2tpcCddLCBmdW5jdGlvbihldnQpe1xuICAgIGlmKGV2dC50eXBlID09PSAndmFzdC5hZEVuZCcpe1xuICAgICAgdHJhY2tlci50cmFja0NvbXBsZXRlKCk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gY2FsbGJhY2sobnVsbCwgYWRNZWRpYUZpbGUsIHJlc3BvbnNlKTtcblxuICAvKioqIExvY2FsIEZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIHVuYmluZEV2ZW50cygpIHtcbiAgICBwbGF5ZXIub2ZmKCdmdWxsc2NyZWVuY2hhbmdlJywgdHJhY2tGdWxsc2NyZWVuQ2hhbmdlKTtcbiAgICBwbGF5ZXIub2ZmKCd2YXN0LmFkU3RhcnQnLCB0cmFja0ltcHJlc3Npb25zKTtcbiAgICBwbGF5ZXIub2ZmKCdwYXVzZScsIHRyYWNrUGF1c2UpO1xuICAgIHBsYXllci5vZmYoJ3RpbWV1cGRhdGUnLCB0cmFja1Byb2dyZXNzKTtcbiAgICBwbGF5ZXIub2ZmKCd2b2x1bWVjaGFuZ2UnLCB0cmFja1ZvbHVtZUNoYW5nZSk7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFja0Z1bGxzY3JlZW5DaGFuZ2UoKSB7XG4gICAgaWYgKHBsYXllci5pc0Z1bGxzY3JlZW4oKSkge1xuICAgICAgdHJhY2tlci50cmFja0Z1bGxzY3JlZW4oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdHJhY2tlci50cmFja0V4aXRGdWxsc2NyZWVuKCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdHJhY2tQYXVzZSgpIHtcbiAgICAvL05PVEU6IHdoZW5ldmVyIGEgdmlkZW8gZW5kcyB0aGUgdmlkZW8gRWxlbWVudCB0cmlnZ2VycyBhICdwYXVzZScgZXZlbnQgYmVmb3JlIHRoZSAnZW5kZWQnIGV2ZW50LlxuICAgIC8vICAgICAgV2Ugc2hvdWxkIG5vdCB0cmFjayB0aGlzIHBhdXNlIGV2ZW50IGJlY2F1c2UgaXQgbWFrZXMgdGhlIFZBU1QgdHJhY2tpbmcgY29uZnVzaW5nIGFnYWluIHdlIHVzZSBhXG4gICAgLy8gICAgICBUaHJlc2hvbGQgb2YgMiBzZWNvbmRzIHRvIHByZXZlbnQgZmFsc2UgcG9zaXRpdmVzIG9uIElPUy5cbiAgICBpZiAoTWF0aC5hYnMocGxheWVyLmR1cmF0aW9uKCkgLSBwbGF5ZXIuY3VycmVudFRpbWUoKSkgPCAyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJhY2tlci50cmFja1BhdXNlKCk7XG4gICAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsncGxheScsICd2YXN0LmFkRW5kJywgJ3Zhc3QuYWRzQ2FuY2VsJ10sIGZ1bmN0aW9uIChldnQpIHtcbiAgICAgIGlmKGV2dC50eXBlID09PSAncGxheScpe1xuICAgICAgICB0cmFja2VyLnRyYWNrUmVzdW1lKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFja1Byb2dyZXNzKCkge1xuICAgIHZhciBjdXJyZW50VGltZUluTXMgPSBwbGF5ZXIuY3VycmVudFRpbWUoKSAqIDEwMDA7XG4gICAgdHJhY2tlci50cmFja1Byb2dyZXNzKGN1cnJlbnRUaW1lSW5Ncyk7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFja0ltcHJlc3Npb25zKCkge1xuICAgIHRyYWNrZXIudHJhY2tJbXByZXNzaW9ucygpO1xuICAgIHRyYWNrZXIudHJhY2tDcmVhdGl2ZVZpZXcoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYWNrVm9sdW1lQ2hhbmdlKCkge1xuICAgIHZhciBtdXRlZCA9IHBsYXllci5tdXRlZCgpO1xuICAgIGlmIChtdXRlZCkge1xuICAgICAgdHJhY2tlci50cmFja011dGUoKTtcbiAgICB9IGVsc2UgaWYgKHByZXZpb3VzbHlNdXRlZCkge1xuICAgICAgdHJhY2tlci50cmFja1VubXV0ZSgpO1xuICAgIH1cbiAgICBwcmV2aW91c2x5TXV0ZWQgPSBtdXRlZDtcbiAgfVxufTtcblxuVkFTVEludGVncmF0b3IucHJvdG90eXBlLl9hZGRTa2lwQnV0dG9uID0gZnVuY3Rpb24gYWRkU2tpcEJ1dHRvbihzb3VyY2UsIHRyYWNrZXIsIHJlc3BvbnNlLCBjYWxsYmFjaykge1xuICB2YXIgc2tpcE9mZnNldEluU2VjO1xuICB2YXIgdGhhdCA9IHRoaXM7XG5cbiAgaWYgKHV0aWxpdGllcy5pc051bWJlcihyZXNwb25zZS5za2lwb2Zmc2V0KSkge1xuICAgIHNraXBPZmZzZXRJblNlYyA9IHJlc3BvbnNlLnNraXBvZmZzZXQgLyAxMDAwO1xuICAgIGFkZFNraXBCdXR0b25Ub1BsYXllcih0aGlzLnBsYXllciwgc2tpcE9mZnNldEluU2VjKTtcbiAgfVxuICBjYWxsYmFjayhudWxsLCBzb3VyY2UsIHRyYWNrZXIsIHJlc3BvbnNlKTtcblxuICAvKioqIExvY2FsIGZ1bmN0aW9uICoqKi9cbiAgZnVuY3Rpb24gYWRkU2tpcEJ1dHRvblRvUGxheWVyKHBsYXllciwgc2tpcE9mZnNldCkge1xuICAgIHZhciBza2lwQnV0dG9uID0gY3JlYXRlU2tpcEJ1dHRvbihwbGF5ZXIpO1xuICAgIHZhciB1cGRhdGVTa2lwQnV0dG9uID0gdXBkYXRlU2tpcEJ1dHRvblN0YXRlLmJpbmQodGhhdCwgc2tpcEJ1dHRvbiwgc2tpcE9mZnNldCwgcGxheWVyKTtcblxuICAgIHBsYXllci5lbCgpLmFwcGVuZENoaWxkKHNraXBCdXR0b24pO1xuICAgIHBsYXllci5vbigndGltZXVwZGF0ZScsIHVwZGF0ZVNraXBCdXR0b24pO1xuXG4gICAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsndmFzdC5hZEVuZCcsICd2YXN0LmFkc0NhbmNlbCddLCByZW1vdmVTa2lwQnV0dG9uKTtcblxuICAgIGZ1bmN0aW9uIHJlbW92ZVNraXBCdXR0b24oKSB7XG4gICAgICBwbGF5ZXIub2ZmKCd0aW1ldXBkYXRlJywgdXBkYXRlU2tpcEJ1dHRvbik7XG4gICAgICBkb20ucmVtb3ZlKHNraXBCdXR0b24pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZVNraXBCdXR0b24ocGxheWVyKSB7XG4gICAgdmFyIHNraXBCdXR0b24gPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICBkb20uYWRkQ2xhc3Moc2tpcEJ1dHRvbiwgXCJ2YXN0LXNraXAtYnV0dG9uXCIpO1xuXG4gICAgc2tpcEJ1dHRvbi5vbmNsaWNrID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgIGlmIChkb20uaGFzQ2xhc3Moc2tpcEJ1dHRvbiwgJ2VuYWJsZWQnKSkge1xuICAgICAgICB0cmFja2VyLnRyYWNrU2tpcCgpO1xuICAgICAgICBwbGF5ZXIudHJpZ2dlcigndmFzdC5hZFNraXAnKTtcbiAgICAgIH1cblxuICAgICAgLy9XZSBwcmV2ZW50IGV2ZW50IHByb3BhZ2F0aW9uIHRvIGF2b2lkIHByb2JsZW1zIHdpdGggdGhlIGNsaWNrVGhyb3VnaCBhbmQgc28gb25cbiAgICAgIGlmICh3aW5kb3cuRXZlbnQucHJvdG90eXBlLnN0b3BQcm9wYWdhdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBza2lwQnV0dG9uO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlU2tpcEJ1dHRvblN0YXRlKHNraXBCdXR0b24sIHNraXBPZmZzZXQsIHBsYXllcikge1xuICAgIHZhciB0aW1lTGVmdCA9IE1hdGguY2VpbChza2lwT2Zmc2V0IC0gcGxheWVyLmN1cnJlbnRUaW1lKCkpO1xuICAgIGlmICh0aW1lTGVmdCA+IDApIHtcbiAgICAgIHNraXBCdXR0b24uaW5uZXJIVE1MID0gXCJTa2lwIGluIFwiICsgdXRpbGl0aWVzLnRvRml4ZWREaWdpdHModGltZUxlZnQsIDIpICsgXCIuLi5cIjtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFkb20uaGFzQ2xhc3Moc2tpcEJ1dHRvbiwgJ2VuYWJsZWQnKSkge1xuICAgICAgICBkb20uYWRkQ2xhc3Moc2tpcEJ1dHRvbiwgJ2VuYWJsZWQnKTtcbiAgICAgICAgc2tpcEJ1dHRvbi5pbm5lckhUTUwgPSBcIlNraXAgYWRcIjtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG5cblZBU1RJbnRlZ3JhdG9yLnByb3RvdHlwZS5fYWRkQ2xpY2tUaHJvdWdoID0gZnVuY3Rpb24gYWRkQ2xpY2tUaHJvdWdoKG1lZGlhRmlsZSwgdHJhY2tlciwgcmVzcG9uc2UsIGNhbGxiYWNrKSB7XG4gIHZhciBwbGF5ZXIgPSB0aGlzLnBsYXllcjtcbiAgdmFyIGJsb2NrZXIgPSBjcmVhdGVDbGlja1Rocm91Z2hCbG9ja2VyKHBsYXllciwgdHJhY2tlciwgcmVzcG9uc2UpO1xuICB2YXIgdXBkYXRlQmxvY2tlciA9IHVwZGF0ZUJsb2NrZXJVUkwuYmluZCh0aGlzLCBibG9ja2VyLCByZXNwb25zZSwgcGxheWVyKTtcblxuICBwbGF5ZXIuZWwoKS5pbnNlcnRCZWZvcmUoYmxvY2tlciwgcGxheWVyLmNvbnRyb2xCYXIuZWwoKSk7XG4gIHBsYXllci5vbigndGltZXVwZGF0ZScsIHVwZGF0ZUJsb2NrZXIpO1xuICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWyd2YXN0LmFkRW5kJywgJ3Zhc3QuYWRzQ2FuY2VsJ10sIHJlbW92ZUJsb2NrZXIpO1xuXG4gIHJldHVybiBjYWxsYmFjayhudWxsLCBtZWRpYUZpbGUsIHRyYWNrZXIsIHJlc3BvbnNlKTtcblxuICAvKioqIExvY2FsIEZ1bmN0aW9ucyAqKiovXG5cbiAgZnVuY3Rpb24gY3JlYXRlQ2xpY2tUaHJvdWdoQmxvY2tlcihwbGF5ZXIsIHRyYWNrZXIsIHJlc3BvbnNlKSB7XG4gICAgdmFyIGJsb2NrZXIgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImFcIik7XG4gICAgdmFyIGNsaWNrVGhyb3VnaE1hY3JvID0gcmVzcG9uc2UuY2xpY2tUaHJvdWdoO1xuXG4gICAgZG9tLmFkZENsYXNzKGJsb2NrZXIsICd2YXN0LWJsb2NrZXInKTtcbiAgICBibG9ja2VyLmhyZWYgPSBnZW5lcmF0ZUNsaWNrVGhyb3VnaFVSTChjbGlja1Rocm91Z2hNYWNybywgcGxheWVyKTtcblxuICAgIGlmICh1dGlsaXRpZXMuaXNTdHJpbmcoY2xpY2tUaHJvdWdoTWFjcm8pKSB7XG4gICAgICBibG9ja2VyLnRhcmdldCA9IFwiX2JsYW5rXCI7XG4gICAgfVxuXG4gICAgYmxvY2tlci5vbmNsaWNrID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgIGlmIChwbGF5ZXIucGF1c2VkKCkpIHtcbiAgICAgICAgcGxheWVyLnBsYXkoKTtcblxuICAgICAgICAvL1dlIHByZXZlbnQgZXZlbnQgcHJvcGFnYXRpb24gdG8gYXZvaWQgcHJvYmxlbXMgd2l0aCB0aGUgcGxheWVyJ3Mgbm9ybWFsIHBhdXNlIG1lY2hhbmlzbVxuICAgICAgICBpZiAod2luZG93LkV2ZW50LnByb3RvdHlwZS5zdG9wUHJvcGFnYXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBwbGF5ZXIucGF1c2UoKTtcbiAgICAgIHRyYWNrZXIudHJhY2tDbGljaygpO1xuICAgIH07XG5cbiAgICByZXR1cm4gYmxvY2tlcjtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZUJsb2NrZXJVUkwoYmxvY2tlciwgcmVzcG9uc2UsIHBsYXllcikge1xuICAgIGJsb2NrZXIuaHJlZiA9IGdlbmVyYXRlQ2xpY2tUaHJvdWdoVVJMKHJlc3BvbnNlLmNsaWNrVGhyb3VnaCwgcGxheWVyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdlbmVyYXRlQ2xpY2tUaHJvdWdoVVJMKGNsaWNrVGhyb3VnaE1hY3JvLCBwbGF5ZXIpIHtcbiAgICB2YXIgdmFyaWFibGVzID0ge1xuICAgICAgQVNTRVRVUkk6IG1lZGlhRmlsZS5zcmMsXG4gICAgICBDT05URU5UUExBWUhFQUQ6IHZhc3RVdGlsLmZvcm1hdFByb2dyZXNzKHBsYXllci5jdXJyZW50VGltZSgpICogMTAwMClcbiAgICB9O1xuXG4gICAgcmV0dXJuIGNsaWNrVGhyb3VnaE1hY3JvID8gdmFzdFV0aWwucGFyc2VVUkxNYWNybyhjbGlja1Rocm91Z2hNYWNybywgdmFyaWFibGVzKSA6ICcjJztcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbW92ZUJsb2NrZXIoKSB7XG4gICAgcGxheWVyLm9mZigndGltZXVwZGF0ZScsIHVwZGF0ZUJsb2NrZXIpO1xuICAgIGRvbS5yZW1vdmUoYmxvY2tlcik7XG4gIH1cbn07XG5cblZBU1RJbnRlZ3JhdG9yLnByb3RvdHlwZS5fcGxheVNlbGVjdGVkQWQgPSBmdW5jdGlvbiBwbGF5U2VsZWN0ZWRBZChzb3VyY2UsIHJlc3BvbnNlLCBjYWxsYmFjaykge1xuICB2YXIgcGxheWVyID0gdGhpcy5wbGF5ZXI7XG5cbiAgcGxheWVyLnByZWxvYWQoXCJhdXRvXCIpOyAvL3dpdGhvdXQgcHJlbG9hZD1hdXRvIHRoZSBkdXJhdGlvbmNoYW5nZSBldmVudCBpcyBuZXZlciBmaXJlZFxuICBwbGF5ZXIuc3JjKHNvdXJjZSk7XG5cbiAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsnZHVyYXRpb25jaGFuZ2UnLCAnZXJyb3InLCAndmFzdC5hZHNDYW5jZWwnXSwgZnVuY3Rpb24gKGV2dCkge1xuICAgIGlmIChldnQudHlwZSA9PT0gJ2R1cmF0aW9uY2hhbmdlJykge1xuICAgICAgcGxheUFkKCk7XG4gICAgfSBlbHNlIGlmKGV2dC50eXBlID09PSAnZXJyb3InKSB7XG4gICAgICBjYWxsYmFjayhuZXcgVkFTVEVycm9yKFwib24gVkFTVEludGVncmF0b3IsIFBsYXllciBpcyB1bmFibGUgdG8gcGxheSB0aGUgQWRcIiwgNDAwKSwgcmVzcG9uc2UpO1xuICAgIH1cbiAgICAvL05PVEU6IElmIHRoZSBhZHMgZ2V0IGNhbmNlbGVkIHdlIGRvIG5vdGhpbmcvXG4gIH0pO1xuXG4gIC8qKioqIGxvY2FsIGZ1bmN0aW9ucyAqKioqKiovXG4gIGZ1bmN0aW9uIHBsYXlBZCgpIHtcblxuICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3BsYXlpbmcnLCAndmFzdC5hZHNDYW5jZWwnXSwgZnVuY3Rpb24gKGV2dCkge1xuICAgICAgaWYoZXZ0LnR5cGUgPT09ICd2YXN0LmFkc0NhbmNlbCcpe1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHBsYXllci50cmlnZ2VyKCd2YXN0LmFkU3RhcnQnKTtcblxuICAgICAgcGxheWVyLm9uKCdlbmRlZCcsIHByb2NlZWQpO1xuICAgICAgcGxheWVyLm9uKCd2YXN0LmFkc0NhbmNlbCcsIHByb2NlZWQpO1xuICAgICAgcGxheWVyLm9uKCd2YXN0LmFkU2tpcCcsIHByb2NlZWQpO1xuXG4gICAgICBmdW5jdGlvbiBwcm9jZWVkKGV2dCkge1xuXG4gICAgICAgIGlmKGV2dC50eXBlID09PSAnZW5kZWQnICYmIChwbGF5ZXIuZHVyYXRpb24oKSAtIHBsYXllci5jdXJyZW50VGltZSgpKSA+IDMgKSB7XG4gICAgICAgICAgLy8gSWdub3JlIGVuZGVkIGV2ZW50IGlmIHRoZSBBZCB0aW1lIHdhcyBub3QgJ25lYXInIHRoZSBlbmRcbiAgICAgICAgICAvLyBhdm9pZHMgaXNzdWVzIHdoZXJlIElPUyBjb250cm9scyBjb3VsZCBza2lwIHRoZSBBZFxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHBsYXllci5vZmYoJ2VuZGVkJywgcHJvY2VlZCk7XG4gICAgICAgIHBsYXllci5vZmYoJ3Zhc3QuYWRzQ2FuY2VsJywgcHJvY2VlZCk7XG4gICAgICAgIHBsYXllci5vZmYoJ3Zhc3QuYWRTa2lwJywgcHJvY2VlZCk7XG5cbiAgICAgICAgLy9OT1RFOiBpZiB0aGUgYWRzIGdldCBjYW5jZWwgd2UgZG8gbm90aGluZyBhcGFydCByZW1vdmluZyB0aGUgbGlzdG5lcnNcbiAgICAgICAgaWYoZXZ0LnR5cGUgPT09ICdlbmRlZCcgfHwgZXZ0LnR5cGUgPT09ICd2YXN0LmFkU2tpcCcpe1xuICAgICAgICAgIGNhbGxiYWNrKG51bGwsIHJlc3BvbnNlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcGxheWVyLnBsYXkoKTtcbiAgfVxufTtcblxuVkFTVEludGVncmF0b3IucHJvdG90eXBlLl90cmFja0Vycm9yID0gZnVuY3Rpb24gdHJhY2tFcnJvcihlcnJvciwgcmVzcG9uc2UpIHtcbiAgdmFzdFV0aWwudHJhY2socmVzcG9uc2UuZXJyb3JVUkxNYWNyb3MsIHtFUlJPUkNPREU6IGVycm9yLmNvZGUgfHwgOTAwfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZBU1RJbnRlZ3JhdG9yOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIEFkID0gcmVxdWlyZSgnLi9BZCcpO1xudmFyIFZpZGVvQ2xpY2tzID0gcmVxdWlyZSgnLi9WaWRlb0NsaWNrcycpO1xudmFyIExpbmVhciA9IHJlcXVpcmUoJy4vTGluZWFyJyk7XG52YXIgSW5MaW5lID0gcmVxdWlyZSgnLi9JbkxpbmUnKTtcbnZhciBXcmFwcGVyID0gcmVxdWlyZSgnLi9XcmFwcGVyJyk7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG52YXIgeG1sID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMveG1sJyk7XG5cbndpbmRvdy5JbkxpbmVfX0EgPSBJbkxpbmU7XG5mdW5jdGlvbiBWQVNUUmVzcG9uc2UoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBWQVNUUmVzcG9uc2UpKSB7XG4gICAgcmV0dXJuIG5ldyBWQVNUUmVzcG9uc2UoKTtcbiAgfVxuXG4gIHRoaXMuX2xpbmVhckFkZGVkID0gZmFsc2U7XG4gIHRoaXMuYWRzID0gW107XG4gIHRoaXMuZXJyb3JVUkxNYWNyb3MgPSBbXTtcbiAgdGhpcy5pbXByZXNzaW9ucyA9IFtdO1xuICB0aGlzLmNsaWNrVHJhY2tpbmdzID0gW107XG4gIHRoaXMuY3VzdG9tQ2xpY2tzID0gW107XG4gIHRoaXMudHJhY2tpbmdFdmVudHMgPSB7fTtcbiAgdGhpcy5tZWRpYUZpbGVzID0gW107XG4gIHRoaXMuY2xpY2tUaHJvdWdoID0gdW5kZWZpbmVkO1xuICB0aGlzLmFkVGl0bGUgPSAnJztcbiAgdGhpcy5kdXJhdGlvbiA9IHVuZGVmaW5lZDtcbiAgdGhpcy5za2lwb2Zmc2V0ID0gdW5kZWZpbmVkO1xufVxuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLmFkZEFkID0gZnVuY3Rpb24gKGFkKSB7XG4gIHZhciBpbkxpbmUsIHdyYXBwZXI7XG4gIGlmIChhZCBpbnN0YW5jZW9mIEFkKSB7XG4gICAgaW5MaW5lID0gYWQuaW5MaW5lO1xuICAgIHdyYXBwZXIgPSBhZC53cmFwcGVyO1xuXG4gICAgdGhpcy5hZHMucHVzaChhZCk7XG5cbiAgICBpZiAoaW5MaW5lKSB7XG4gICAgICB0aGlzLl9hZGRJbkxpbmUoaW5MaW5lKTtcbiAgICB9XG5cbiAgICBpZiAod3JhcHBlcikge1xuICAgICAgdGhpcy5fYWRkV3JhcHBlcih3cmFwcGVyKTtcbiAgICB9XG4gIH1cbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZEVycm9yVHJhY2tVcmwgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgdmFyIGVycm9yVVJMID0gZXJyb3IgaW5zdGFuY2VvZiB4bWwuSlhPTlRyZWUgPyB4bWwua2V5VmFsdWUoZXJyb3IpIDogZXJyb3I7XG4gIGlmIChlcnJvclVSTCkge1xuICAgIHRoaXMuZXJyb3JVUkxNYWNyb3MucHVzaChlcnJvclVSTCk7XG4gIH1cbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZEltcHJlc3Npb25zID0gZnVuY3Rpb24gKGltcHJlc3Npb25zKSB7XG4gIHV0aWxpdGllcy5pc0FycmF5KGltcHJlc3Npb25zKSAmJiBhcHBlbmRUb0FycmF5KHRoaXMuaW1wcmVzc2lvbnMsIGltcHJlc3Npb25zKTtcbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZENsaWNrVGhyb3VnaCA9IGZ1bmN0aW9uIChjbGlja1Rocm91Z2gpIHtcbiAgaWYgKHV0aWxpdGllcy5pc05vdEVtcHR5U3RyaW5nKGNsaWNrVGhyb3VnaCkpIHtcbiAgICB0aGlzLmNsaWNrVGhyb3VnaCA9IGNsaWNrVGhyb3VnaDtcbiAgfVxufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkQ2xpY2tUcmFja2luZ3MgPSBmdW5jdGlvbiAoY2xpY2tUcmFja2luZ3MpIHtcbiAgdXRpbGl0aWVzLmlzQXJyYXkoY2xpY2tUcmFja2luZ3MpICYmIGFwcGVuZFRvQXJyYXkodGhpcy5jbGlja1RyYWNraW5ncywgY2xpY2tUcmFja2luZ3MpO1xufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkQ3VzdG9tQ2xpY2tzID0gZnVuY3Rpb24gKGN1c3RvbUNsaWNrcykge1xuICB1dGlsaXRpZXMuaXNBcnJheShjdXN0b21DbGlja3MpICYmIGFwcGVuZFRvQXJyYXkodGhpcy5jdXN0b21DbGlja3MsIGN1c3RvbUNsaWNrcyk7XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRUcmFja2luZ0V2ZW50cyA9IGZ1bmN0aW9uICh0cmFja2luZ0V2ZW50cykge1xuICB2YXIgZXZlbnRzTWFwID0gdGhpcy50cmFja2luZ0V2ZW50cztcblxuICBpZiAodHJhY2tpbmdFdmVudHMpIHtcbiAgICB0cmFja2luZ0V2ZW50cyA9IHV0aWxpdGllcy5pc0FycmF5KHRyYWNraW5nRXZlbnRzKSA/IHRyYWNraW5nRXZlbnRzIDogW3RyYWNraW5nRXZlbnRzXTtcbiAgICB0cmFja2luZ0V2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uICh0cmFja2luZ0V2ZW50KSB7XG4gICAgICBpZiAoIWV2ZW50c01hcFt0cmFja2luZ0V2ZW50Lm5hbWVdKSB7XG4gICAgICAgIGV2ZW50c01hcFt0cmFja2luZ0V2ZW50Lm5hbWVdID0gW107XG4gICAgICB9XG4gICAgICBldmVudHNNYXBbdHJhY2tpbmdFdmVudC5uYW1lXS5wdXNoKHRyYWNraW5nRXZlbnQpO1xuICAgIH0pO1xuICB9XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRUaXRsZSA9IGZ1bmN0aW9uICh0aXRsZSkge1xuICBpZiAodXRpbGl0aWVzLmlzTm90RW1wdHlTdHJpbmcodGl0bGUpKSB7XG4gICAgdGhpcy5hZFRpdGxlID0gdGl0bGU7XG4gIH1cbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZER1cmF0aW9uID0gZnVuY3Rpb24gKGR1cmF0aW9uKSB7XG4gIGlmICh1dGlsaXRpZXMuaXNOdW1iZXIoZHVyYXRpb24pKSB7XG4gICAgdGhpcy5kdXJhdGlvbiA9IGR1cmF0aW9uO1xuICB9XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRWaWRlb0NsaWNrcyA9IGZ1bmN0aW9uICh2aWRlb0NsaWNrcykge1xuICBpZiAodmlkZW9DbGlja3MgaW5zdGFuY2VvZiBWaWRlb0NsaWNrcykge1xuICAgIHRoaXMuX2FkZENsaWNrVGhyb3VnaCh2aWRlb0NsaWNrcy5jbGlja1Rocm91Z2gpO1xuICAgIHRoaXMuX2FkZENsaWNrVHJhY2tpbmdzKHZpZGVvQ2xpY2tzLmNsaWNrVHJhY2tpbmdzKTtcbiAgICB0aGlzLl9hZGRDdXN0b21DbGlja3ModmlkZW9DbGlja3MuY3VzdG9tQ2xpY2tzKTtcbiAgfVxufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkTWVkaWFGaWxlcyA9IGZ1bmN0aW9uIChtZWRpYUZpbGVzKSB7XG4gIHV0aWxpdGllcy5pc0FycmF5KG1lZGlhRmlsZXMpICYmIGFwcGVuZFRvQXJyYXkodGhpcy5tZWRpYUZpbGVzLCBtZWRpYUZpbGVzKTtcbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZFNraXBvZmZzZXQgPSBmdW5jdGlvbiAob2Zmc2V0KSB7XG4gIGlmIChvZmZzZXQpIHtcbiAgICB0aGlzLnNraXBvZmZzZXQgPSBvZmZzZXQ7XG4gIH1cbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZEFkUGFyYW1ldGVycyA9IGZ1bmN0aW9uIChhZFBhcmFtZXRlcnMpIHtcbiAgaWYgKGFkUGFyYW1ldGVycykge1xuICAgIHRoaXMuYWRQYXJhbWV0ZXJzID0gYWRQYXJhbWV0ZXJzO1xuICB9XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRMaW5lYXIgPSBmdW5jdGlvbiAobGluZWFyKSB7XG4gIGlmIChsaW5lYXIgaW5zdGFuY2VvZiBMaW5lYXIpIHtcbiAgICB0aGlzLl9hZGREdXJhdGlvbihsaW5lYXIuZHVyYXRpb24pO1xuICAgIHRoaXMuX2FkZFRyYWNraW5nRXZlbnRzKGxpbmVhci50cmFja2luZ0V2ZW50cyk7XG4gICAgdGhpcy5fYWRkVmlkZW9DbGlja3MobGluZWFyLnZpZGVvQ2xpY2tzKTtcbiAgICB0aGlzLl9hZGRNZWRpYUZpbGVzKGxpbmVhci5tZWRpYUZpbGVzKTtcbiAgICB0aGlzLl9hZGRTa2lwb2Zmc2V0KGxpbmVhci5za2lwb2Zmc2V0KTtcbiAgICB0aGlzLl9hZGRBZFBhcmFtZXRlcnMobGluZWFyLmFkUGFyYW1ldGVycyk7XG4gICAgdGhpcy5fbGluZWFyQWRkZWQgPSB0cnVlO1xuICB9XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRJbkxpbmUgPSBmdW5jdGlvbiAoaW5MaW5lKSB7XG4gIHZhciB0aGF0ID0gdGhpcztcblxuICBpZiAoaW5MaW5lIGluc3RhbmNlb2YgSW5MaW5lKSB7XG4gICAgdGhpcy5fYWRkVGl0bGUoaW5MaW5lLmFkVGl0bGUpO1xuICAgIHRoaXMuX2FkZEVycm9yVHJhY2tVcmwoaW5MaW5lLmVycm9yKTtcbiAgICB0aGlzLl9hZGRJbXByZXNzaW9ucyhpbkxpbmUuaW1wcmVzc2lvbnMpO1xuXG4gICAgaW5MaW5lLmNyZWF0aXZlcy5mb3JFYWNoKGZ1bmN0aW9uIChjcmVhdGl2ZSkge1xuICAgICAgaWYgKGNyZWF0aXZlLmxpbmVhcikge1xuICAgICAgICB0aGF0Ll9hZGRMaW5lYXIoY3JlYXRpdmUubGluZWFyKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkV3JhcHBlciA9IGZ1bmN0aW9uICh3cmFwcGVyKSB7XG4gIHZhciB0aGF0ID0gdGhpcztcblxuICBpZiAod3JhcHBlciBpbnN0YW5jZW9mIFdyYXBwZXIpIHtcbiAgICB0aGlzLl9hZGRFcnJvclRyYWNrVXJsKHdyYXBwZXIuZXJyb3IpO1xuICAgIHRoaXMuX2FkZEltcHJlc3Npb25zKHdyYXBwZXIuaW1wcmVzc2lvbnMpO1xuXG4gICAgd3JhcHBlci5jcmVhdGl2ZXMuZm9yRWFjaChmdW5jdGlvbiAoY3JlYXRpdmUpIHtcbiAgICAgIHZhciBsaW5lYXIgPSBjcmVhdGl2ZS5saW5lYXI7XG4gICAgICBpZiAobGluZWFyKSB7XG4gICAgICAgIHRoYXQuX2FkZFZpZGVvQ2xpY2tzKGxpbmVhci52aWRlb0NsaWNrcyk7XG4gICAgICAgIHRoYXQuY2xpY2tUaHJvdWdoID0gdW5kZWZpbmVkOy8vV2UgZW5zdXJlIHRoYXQgbm8gY2xpY2tUaHJvdWdoIGhhcyBiZWVuIGFkZGVkXG4gICAgICAgIHRoYXQuX2FkZFRyYWNraW5nRXZlbnRzKGxpbmVhci50cmFja2luZ0V2ZW50cyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuaGFzTGluZWFyID0gZnVuY3Rpb24oKXtcbiAgcmV0dXJuIHRoaXMuX2xpbmVhckFkZGVkO1xufTtcblxuZnVuY3Rpb24gYXBwZW5kVG9BcnJheShhcnJheSwgaXRlbXMpIHtcbiAgaXRlbXMuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xuICAgIGFycmF5LnB1c2goaXRlbSk7XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFZBU1RSZXNwb25zZTtcblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVkFTVEVycm9yID0gcmVxdWlyZSgnLi9WQVNURXJyb3InKTtcbnZhciBWQVNUUmVzcG9uc2UgPSByZXF1aXJlKCcuL1ZBU1RSZXNwb25zZScpO1xudmFyIHZhc3RVdGlsID0gcmVxdWlyZSgnLi92YXN0VXRpbCcpO1xudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxuZnVuY3Rpb24gVkFTVFRyYWNrZXIoYXNzZXRVUkksIHZhc3RSZXNwb25zZSkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVkFTVFRyYWNrZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBWQVNUVHJhY2tlcihhc3NldFVSSSwgdmFzdFJlc3BvbnNlKTtcbiAgfVxuXG4gIHRoaXMuc2FuaXR5Q2hlY2soYXNzZXRVUkksIHZhc3RSZXNwb25zZSk7XG4gIHRoaXMuaW5pdGlhbGl6ZShhc3NldFVSSSwgdmFzdFJlc3BvbnNlKTtcblxufVxuXG5WQVNUVHJhY2tlci5wcm90b3R5cGUuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKGFzc2V0VVJJLCB2YXN0UmVzcG9uc2UpIHtcbiAgdGhpcy5yZXNwb25zZSA9IHZhc3RSZXNwb25zZTtcbiAgdGhpcy5hc3NldFVSSSA9IGFzc2V0VVJJO1xuICB0aGlzLnByb2dyZXNzID0gMDtcbiAgdGhpcy5xdWFydGlsZXMgPSB7XG4gICAgZmlyc3RRdWFydGlsZToge3RyYWNrZWQ6IGZhbHNlLCB0aW1lOiBNYXRoLnJvdW5kKDI1ICogdmFzdFJlc3BvbnNlLmR1cmF0aW9uKSAvIDEwMH0sXG4gICAgbWlkcG9pbnQ6IHt0cmFja2VkOiBmYWxzZSwgdGltZTogTWF0aC5yb3VuZCg1MCAqIHZhc3RSZXNwb25zZS5kdXJhdGlvbikgLyAxMDB9LFxuICAgIHRoaXJkUXVhcnRpbGU6IHt0cmFja2VkOiBmYWxzZSwgdGltZTogTWF0aC5yb3VuZCg3NSAqIHZhc3RSZXNwb25zZS5kdXJhdGlvbikgLyAxMDB9XG4gIH07XG59O1xuXG5WQVNUVHJhY2tlci5wcm90b3R5cGUuc2FuaXR5Q2hlY2sgPSBmdW5jdGlvbihhc3NldFVSSSwgdmFzdFJlc3BvbnNlKSB7XG4gIGlmICghdXRpbGl0aWVzLmlzU3RyaW5nKGFzc2V0VVJJKSB8fCB1dGlsaXRpZXMuaXNFbXB0eVN0cmluZyhhc3NldFVSSSkpIHtcbiAgICB0aHJvdyBuZXcgVkFTVEVycm9yKCdvbiBWQVNUVHJhY2tlciBjb25zdHJ1Y3RvciwgbWlzc2luZyByZXF1aXJlZCB0aGUgVVJJIG9mIHRoZSBhZCBhc3NldCBiZWluZyBwbGF5ZWQnKTtcbiAgfVxuXG4gIGlmICghKHZhc3RSZXNwb25zZSBpbnN0YW5jZW9mIFZBU1RSZXNwb25zZSkpIHtcbiAgICB0aHJvdyBuZXcgVkFTVEVycm9yKCdvbiBWQVNUVHJhY2tlciBjb25zdHJ1Y3RvciwgbWlzc2luZyByZXF1aXJlZCBWQVNUIHJlc3BvbnNlJyk7XG4gIH1cbn07XG5cblZBU1RUcmFja2VyLnByb3RvdHlwZS50cmFja1VSTHMgPSBmdW5jdGlvbiB0cmFja1VSTHModXJscywgdmFyaWFibGVzKSB7XG4gIGlmICh1dGlsaXRpZXMuaXNBcnJheSh1cmxzKSAmJiB1cmxzLmxlbmd0aCA+IDApIHtcbiAgICB2YXJpYWJsZXMgPSB1dGlsaXRpZXMuZXh0ZW5kKHtcbiAgICAgIEFTU0VUVVJJOiB0aGlzLmFzc2V0VVJJLFxuICAgICAgQ09OVEVOVFBMQVlIRUFEOiB2YXN0VXRpbC5mb3JtYXRQcm9ncmVzcyh0aGlzLnByb2dyZXNzKVxuICAgIH0sIHZhcmlhYmxlcyB8fCB7fSk7XG5cbiAgICB2YXN0VXRpbC50cmFjayh1cmxzLCB2YXJpYWJsZXMpO1xuICB9XG59O1xuXG5WQVNUVHJhY2tlci5wcm90b3R5cGUudHJhY2tFdmVudCA9IGZ1bmN0aW9uIHRyYWNrRXZlbnQoZXZlbnROYW1lLCB0cmFja09uY2UpIHtcbiAgdGhpcy50cmFja1VSTHMoZ2V0RXZlbnRVcmlzKHRoaXMucmVzcG9uc2UudHJhY2tpbmdFdmVudHNbZXZlbnROYW1lXSkpO1xuICBpZiAodHJhY2tPbmNlKSB7XG4gICAgdGhpcy5yZXNwb25zZS50cmFja2luZ0V2ZW50c1tldmVudE5hbWVdID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbiAqKiovXG4gIGZ1bmN0aW9uIGdldEV2ZW50VXJpcyh0cmFja2luZ0V2ZW50cykge1xuICAgIHZhciB1cmlzO1xuXG4gICAgaWYgKHRyYWNraW5nRXZlbnRzKSB7XG4gICAgICB1cmlzID0gW107XG4gICAgICB0cmFja2luZ0V2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICB1cmlzLnB1c2goZXZlbnQudXJpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdXJpcztcbiAgfVxufTtcblxuVkFTVFRyYWNrZXIucHJvdG90eXBlLnRyYWNrUHJvZ3Jlc3MgPSBmdW5jdGlvbiB0cmFja1Byb2dyZXNzKG5ld1Byb2dyZXNzSW5Ncykge1xuICB2YXIgdGhhdCA9IHRoaXM7XG4gIHZhciBldmVudHMgPSBbXTtcbiAgdmFyIE9OQ0UgPSB0cnVlO1xuICB2YXIgQUxXQVlTID0gZmFsc2U7XG4gIHZhciB0cmFja2luZ0V2ZW50cyA9IHRoaXMucmVzcG9uc2UudHJhY2tpbmdFdmVudHM7XG5cbiAgaWYgKHV0aWxpdGllcy5pc051bWJlcihuZXdQcm9ncmVzc0luTXMpKSB7XG4gICAgYWRkVHJhY2tFdmVudCgnc3RhcnQnLCBPTkNFLCBuZXdQcm9ncmVzc0luTXMgPiAwKTtcbiAgICBhZGRUcmFja0V2ZW50KCdyZXdpbmQnLCBBTFdBWVMsIGhhc1Jld291bmQodGhpcy5wcm9ncmVzcywgbmV3UHJvZ3Jlc3NJbk1zKSk7XG4gICAgYWRkUXVhcnRpbGVFdmVudHMobmV3UHJvZ3Jlc3NJbk1zKTtcbiAgICB0cmFja1Byb2dyZXNzRXZlbnRzKG5ld1Byb2dyZXNzSW5Ncyk7XG4gICAgdHJhY2tFdmVudHMoKTtcbiAgICB0aGlzLnByb2dyZXNzID0gbmV3UHJvZ3Jlc3NJbk1zO1xuICB9XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbiAqKiovXG4gIGZ1bmN0aW9uIGhhc1Jld291bmQoY3VycmVudFByb2dyZXNzLCBuZXdQcm9ncmVzcykge1xuICAgIHZhciBSRVdJTkRfVEhSRVNIT0xEID0gMzAwMDsgLy9JT1MgdmlkZW8gY2xvY2sgaXMgdmVyeSB1bnJlbGlhYmxlIGFuZCB3ZSBuZWVkIGEgMyBzZWNvbmRzIHRocmVzaG9sZCB0byBlbnN1cmUgdGhhdCB0aGVyZSB3YXMgYSByZXdpbmQgYW4gdGhhdCBpdCB3YXMgb24gcHVycG9zZS5cbiAgICByZXR1cm4gY3VycmVudFByb2dyZXNzID4gbmV3UHJvZ3Jlc3NJbk1zICYmIE1hdGguYWJzKG5ld1Byb2dyZXNzIC0gY3VycmVudFByb2dyZXNzKSA+IFJFV0lORF9USFJFU0hPTEQ7XG4gIH1cblxuICBmdW5jdGlvbiBhZGRUcmFja0V2ZW50KGV2ZW50TmFtZSwgdHJhY2tPbmNlLCBjYW5CZUFkZGVkKSB7XG4gICAgaWYgKHRyYWNraW5nRXZlbnRzW2V2ZW50TmFtZV0gJiYgY2FuQmVBZGRlZCkge1xuICAgICAgZXZlbnRzLnB1c2goe1xuICAgICAgICBuYW1lOiBldmVudE5hbWUsXG4gICAgICAgIHRyYWNrT25jZTogISF0cmFja09uY2VcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZFF1YXJ0aWxlRXZlbnRzKHByb2dyZXNzKSB7XG4gICAgdmFyIHF1YXJ0aWxlcyA9IHRoYXQucXVhcnRpbGVzO1xuICAgIHZhciBmaXJzdFF1YXJ0aWxlID0gdGhhdC5xdWFydGlsZXMuZmlyc3RRdWFydGlsZTtcbiAgICB2YXIgbWlkcG9pbnQgPSB0aGF0LnF1YXJ0aWxlcy5taWRwb2ludDtcbiAgICB2YXIgdGhpcmRRdWFydGlsZSA9IHRoYXQucXVhcnRpbGVzLnRoaXJkUXVhcnRpbGU7XG5cbiAgICBpZiAoIWZpcnN0UXVhcnRpbGUudHJhY2tlZCkge1xuICAgICAgdHJhY2tRdWFydGlsZSgnZmlyc3RRdWFydGlsZScsIHByb2dyZXNzKTtcbiAgICB9IGVsc2UgaWYgKCFtaWRwb2ludC50cmFja2VkKSB7XG4gICAgICB0cmFja1F1YXJ0aWxlKCdtaWRwb2ludCcsIHByb2dyZXNzKTtcbiAgICB9IGVsc2UgaWYgKCF0aGlyZFF1YXJ0aWxlLnRyYWNrZWQpe1xuICAgICAgdHJhY2tRdWFydGlsZSgndGhpcmRRdWFydGlsZScsIHByb2dyZXNzKTtcbiAgICB9XG5cbiAgICAvKioqIExvY2FsIGZ1bmN0aW9uICoqKi9cbiAgICBmdW5jdGlvbiB0cmFja1F1YXJ0aWxlKHF1YXJ0aWxlTmFtZSwgcHJvZ3Jlc3Mpe1xuICAgICAgdmFyIHF1YXJ0aWxlID0gcXVhcnRpbGVzW3F1YXJ0aWxlTmFtZV07XG4gICAgICBpZihjYW5CZVRyYWNrZWQocXVhcnRpbGUsIHByb2dyZXNzKSl7XG4gICAgICAgIHF1YXJ0aWxlLnRyYWNrZWQgPSB0cnVlO1xuICAgICAgICBhZGRUcmFja0V2ZW50KHF1YXJ0aWxlTmFtZSwgT05DRSwgdHJ1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gY2FuQmVUcmFja2VkKHF1YXJ0aWxlLCBwcm9ncmVzcykge1xuICAgIHZhciBxdWFydGlsZVRpbWUgPSBxdWFydGlsZS50aW1lO1xuICAgIC8vV2Ugb25seSBmaXJlIHRoZSBxdWFydGlsZSBldmVudCBpZiB0aGUgcHJvZ3Jlc3MgaXMgYmlnZ2VyIHRoYW4gdGhlIHF1YXJ0aWxlIHRpbWUgYnkgNSBzZWNvbmRzIGF0IG1vc3QuXG4gICAgcmV0dXJuIHByb2dyZXNzID49IHF1YXJ0aWxlVGltZSAmJiBwcm9ncmVzcyA8PSAocXVhcnRpbGVUaW1lICsgNTAwMCk7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFja1Byb2dyZXNzRXZlbnRzKHByb2dyZXNzKSB7XG4gICAgaWYgKCF1dGlsaXRpZXMuaXNBcnJheSh0cmFja2luZ0V2ZW50cy5wcm9ncmVzcykpIHtcbiAgICAgIHJldHVybjsgLy9Ob3RoaW5nIHRvIHRyYWNrXG4gICAgfVxuXG4gICAgdmFyIHBlbmRpbmdQcm9ncmVzc0V2dHMgPSBbXTtcblxuICAgIHRyYWNraW5nRXZlbnRzLnByb2dyZXNzLmZvckVhY2goZnVuY3Rpb24gKGV2dCkge1xuICAgICAgaWYgKGV2dC5vZmZzZXQgPD0gcHJvZ3Jlc3MpIHtcbiAgICAgICAgdGhhdC50cmFja1VSTHMoW2V2dC51cmldKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBlbmRpbmdQcm9ncmVzc0V2dHMucHVzaChldnQpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRyYWNraW5nRXZlbnRzLnByb2dyZXNzID0gcGVuZGluZ1Byb2dyZXNzRXZ0cztcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYWNrRXZlbnRzKCkge1xuICAgIGV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgdGhhdC50cmFja0V2ZW50KGV2ZW50Lm5hbWUsIGV2ZW50LnRyYWNrT25jZSk7XG4gICAgfSk7XG4gIH1cbn07XG5cbltcbiAgJ3Jld2luZCcsXG4gICdmdWxsc2NyZWVuJyxcbiAgJ2V4aXRGdWxsc2NyZWVuJyxcbiAgJ3BhdXNlJyxcbiAgJ3Jlc3VtZScsXG4gICdtdXRlJyxcbiAgJ3VubXV0ZScsXG4gICdhY2NlcHRJbnZpdGF0aW9uJyxcbiAgJ2FjY2VwdEludml0YXRpb25MaW5lYXInLFxuICAnY29sbGFwc2UnLFxuICAnZXhwYW5kJ1xuXS5mb3JFYWNoKGZ1bmN0aW9uIChldmVudE5hbWUpIHtcbiAgICBWQVNUVHJhY2tlci5wcm90b3R5cGVbJ3RyYWNrJyArIHV0aWxpdGllcy5jYXBpdGFsaXplKGV2ZW50TmFtZSldID0gZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy50cmFja0V2ZW50KGV2ZW50TmFtZSk7XG4gICAgfTtcbiAgfSk7XG5cbltcbiAgJ3N0YXJ0JyxcbiAgJ3NraXAnLFxuICAnY2xvc2UnLFxuICAnY2xvc2VMaW5lYXInXG5dLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xuICAgIFZBU1RUcmFja2VyLnByb3RvdHlwZVsndHJhY2snICsgdXRpbGl0aWVzLmNhcGl0YWxpemUoZXZlbnROYW1lKV0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLnRyYWNrRXZlbnQoZXZlbnROYW1lLCB0cnVlKTtcbiAgICB9O1xuICB9KTtcblxuW1xuICAnZmlyc3RRdWFydGlsZScsXG4gICdtaWRwb2ludCcsXG4gICd0aGlyZFF1YXJ0aWxlJ1xuXS5mb3JFYWNoKGZ1bmN0aW9uIChxdWFydGlsZSkge1xuICAgIFZBU1RUcmFja2VyLnByb3RvdHlwZVsndHJhY2snICsgdXRpbGl0aWVzLmNhcGl0YWxpemUocXVhcnRpbGUpXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMucXVhcnRpbGVzW3F1YXJ0aWxlXS50cmFja2VkID0gdHJ1ZTtcbiAgICAgIHRoaXMudHJhY2tFdmVudChxdWFydGlsZSwgdHJ1ZSk7XG4gICAgfTtcbiAgfSk7XG5cblZBU1RUcmFja2VyLnByb3RvdHlwZS50cmFja0NvbXBsZXRlID0gZnVuY3Rpb24gKCkge1xuICBpZih0aGlzLnF1YXJ0aWxlcy50aGlyZFF1YXJ0aWxlLnRyYWNrZWQpe1xuICAgIHRoaXMudHJhY2tFdmVudCgnY29tcGxldGUnLCB0cnVlKTtcbiAgfVxufTtcblxuVkFTVFRyYWNrZXIucHJvdG90eXBlLnRyYWNrRXJyb3JXaXRoQ29kZSA9IGZ1bmN0aW9uIHRyYWNrRXJyb3JXaXRoQ29kZShlcnJvcmNvZGUpIHtcbiAgaWYgKHV0aWxpdGllcy5pc051bWJlcihlcnJvcmNvZGUpKSB7XG4gICAgdGhpcy50cmFja1VSTHModGhpcy5yZXNwb25zZS5lcnJvclVSTE1hY3Jvcywge0VSUk9SQ09ERTogZXJyb3Jjb2RlfSk7XG4gIH1cbn07XG5cblZBU1RUcmFja2VyLnByb3RvdHlwZS50cmFja0ltcHJlc3Npb25zID0gZnVuY3Rpb24gdHJhY2tJbXByZXNzaW9ucygpIHtcbiAgdGhpcy50cmFja1VSTHModGhpcy5yZXNwb25zZS5pbXByZXNzaW9ucyk7XG59O1xuXG5WQVNUVHJhY2tlci5wcm90b3R5cGUudHJhY2tDcmVhdGl2ZVZpZXcgPSBmdW5jdGlvbiB0cmFja0NyZWF0aXZlVmlldygpIHtcbiAgdGhpcy50cmFja0V2ZW50KCdjcmVhdGl2ZVZpZXcnKTtcbn07XG5cblZBU1RUcmFja2VyLnByb3RvdHlwZS50cmFja0NsaWNrID0gZnVuY3Rpb24gdHJhY2tDbGljaygpIHtcbiAgdGhpcy50cmFja1VSTHModGhpcy5yZXNwb25zZS5jbGlja1RyYWNraW5ncyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZBU1RUcmFja2VyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucycpO1xudmFyIHhtbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3htbCcpO1xuXG5mdW5jdGlvbiBWaWRlb0NsaWNrcyh2aWRlb0NsaWNrSlRyZWUpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFZpZGVvQ2xpY2tzKSkge1xuICAgIHJldHVybiBuZXcgVmlkZW9DbGlja3ModmlkZW9DbGlja0pUcmVlKTtcbiAgfVxuXG4gIHRoaXMuY2xpY2tUaHJvdWdoID0geG1sLmtleVZhbHVlKHZpZGVvQ2xpY2tKVHJlZS5jbGlja1Rocm91Z2gpO1xuICB0aGlzLmNsaWNrVHJhY2tpbmdzID0gcGFyc2VDbGlja1RyYWNraW5ncyh2aWRlb0NsaWNrSlRyZWUuY2xpY2tUcmFja2luZyk7XG4gIHRoaXMuY3VzdG9tQ2xpY2tzID0gcGFyc2VDbGlja1RyYWNraW5ncyh2aWRlb0NsaWNrSlRyZWUuY3VzdG9tQ2xpY2spO1xuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gcGFyc2VDbGlja1RyYWNraW5ncyh0cmFja2luZ0RhdGEpIHtcbiAgICB2YXIgY2xpY2tUcmFja2luZ3MgPSBbXTtcbiAgICBpZiAodHJhY2tpbmdEYXRhKSB7XG4gICAgICB0cmFja2luZ0RhdGEgPSB1dGlsaXRpZXMuaXNBcnJheSh0cmFja2luZ0RhdGEpID8gdHJhY2tpbmdEYXRhIDogW3RyYWNraW5nRGF0YV07XG4gICAgICB0cmFja2luZ0RhdGEuZm9yRWFjaChmdW5jdGlvbiAoY2xpY2tUcmFja2luZ0RhdGEpIHtcbiAgICAgICAgY2xpY2tUcmFja2luZ3MucHVzaCh4bWwua2V5VmFsdWUoY2xpY2tUcmFja2luZ0RhdGEpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gY2xpY2tUcmFja2luZ3M7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBWaWRlb0NsaWNrczsiLCIndXNlIHN0cmljdCc7XG5cbnZhciB2YXN0VXRpbCA9IHJlcXVpcmUoJy4vdmFzdFV0aWwnKTtcbnZhciBDcmVhdGl2ZSA9IHJlcXVpcmUoJy4vQ3JlYXRpdmUnKTtcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcbnZhciB4bWwgPSByZXF1aXJlKCcuLi8uLi91dGlscy94bWwnKTtcblxuZnVuY3Rpb24gV3JhcHBlcih3cmFwcGVySlRyZWUpIHtcbiAgaWYoISh0aGlzIGluc3RhbmNlb2YgV3JhcHBlcikpIHtcbiAgICByZXR1cm4gbmV3IFdyYXBwZXIod3JhcHBlckpUcmVlKTtcbiAgfVxuXG4gIC8vUmVxdWlyZWQgZWxlbWVudHNcbiAgdGhpcy5hZFN5c3RlbSA9IHhtbC5rZXlWYWx1ZSh3cmFwcGVySlRyZWUuYWRTeXN0ZW0pO1xuICB0aGlzLmltcHJlc3Npb25zID0gdmFzdFV0aWwucGFyc2VJbXByZXNzaW9ucyh3cmFwcGVySlRyZWUuaW1wcmVzc2lvbik7XG4gIHRoaXMuVkFTVEFkVGFnVVJJID0geG1sLmtleVZhbHVlKHdyYXBwZXJKVHJlZS52QVNUQWRUYWdVUkkpO1xuXG4gIC8vT3B0aW9uYWwgZWxlbWVudHNcbiAgdGhpcy5jcmVhdGl2ZXMgPSBDcmVhdGl2ZS5wYXJzZUNyZWF0aXZlcyh3cmFwcGVySlRyZWUuY3JlYXRpdmVzKTtcbiAgdGhpcy5lcnJvciA9IHhtbC5rZXlWYWx1ZSh3cmFwcGVySlRyZWUuZXJyb3IpO1xuICB0aGlzLmV4dGVuc2lvbnMgPSB3cmFwcGVySlRyZWUuZXh0ZW5zaW9ucztcblxuICAvL09wdGlvbmFsIGF0dHJzXG4gIHRoaXMuZm9sbG93QWRkaXRpb25hbFdyYXBwZXJzID0gdXRpbGl0aWVzLmlzRGVmaW5lZCh4bWwuYXR0cih3cmFwcGVySlRyZWUsICdmb2xsb3dBZGRpdGlvbmFsV3JhcHBlcnMnKSk/IHhtbC5hdHRyKHdyYXBwZXJKVHJlZSwgJ2ZvbGxvd0FkZGl0aW9uYWxXcmFwcGVycycpOiB0cnVlO1xuICB0aGlzLmFsbG93TXVsdGlwbGVBZHMgPSB4bWwuYXR0cih3cmFwcGVySlRyZWUsICdhbGxvd011bHRpcGxlQWRzJyk7XG4gIHRoaXMuZmFsbGJhY2tPbk5vQWQgPSB4bWwuYXR0cih3cmFwcGVySlRyZWUsICdmYWxsYmFja09uTm9BZCcpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFdyYXBwZXI7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbnZhciBkdXJhdGlvblJlZ2V4ID0gLyhcXGRcXGQpOihcXGRcXGQpOihcXGRcXGQpKFxcLihcXGRcXGRcXGQpKT8vO1xuXG52YXIgcGFyc2VycyA9IHtcblxuICBkdXJhdGlvbjogZnVuY3Rpb24gcGFyc2VEdXJhdGlvbihkdXJhdGlvblN0cikge1xuXG4gICAgdmFyIG1hdGNoLCBkdXJhdGlvbkluTXM7XG5cbiAgICBpZiAodXRpbGl0aWVzLmlzU3RyaW5nKGR1cmF0aW9uU3RyKSkge1xuICAgICAgbWF0Y2ggPSBkdXJhdGlvblN0ci5tYXRjaChkdXJhdGlvblJlZ2V4KTtcbiAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICBkdXJhdGlvbkluTXMgPSBwYXJzZUhvdXJzVG9NcyhtYXRjaFsxXSkgKyBwYXJzZU1pblRvTXMobWF0Y2hbMl0pICsgcGFyc2VTZWNUb01zKG1hdGNoWzNdKSArIHBhcnNlSW50KG1hdGNoWzVdIHx8IDApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBpc05hTihkdXJhdGlvbkluTXMpID8gbnVsbCA6IGR1cmF0aW9uSW5NcztcblxuICAgIC8qKiogbG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgICBmdW5jdGlvbiBwYXJzZUhvdXJzVG9Ncyhob3VyU3RyKSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQoaG91clN0ciwgMTApICogNjAgKiA2MCAqIDEwMDA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VNaW5Ub01zKG1pblN0cikge1xuICAgICAgcmV0dXJuIHBhcnNlSW50KG1pblN0ciwgMTApICogNjAgKiAxMDAwO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlU2VjVG9NcyhzZWNTdHIpIHtcbiAgICAgIHJldHVybiBwYXJzZUludChzZWNTdHIsIDEwKSAqIDEwMDA7XG4gICAgfVxuICB9LFxuXG4gIG9mZnNldDogZnVuY3Rpb24gcGFyc2VPZmZzZXQob2Zmc2V0LCBkdXJhdGlvbikge1xuICAgIGlmKGlzUGVyY2VudGFnZShvZmZzZXQpKXtcbiAgICAgIHJldHVybiBjYWxjdWxhdGVQZXJjZW50YWdlKG9mZnNldCwgZHVyYXRpb24pO1xuICAgIH1cbiAgICByZXR1cm4gcGFyc2Vycy5kdXJhdGlvbihvZmZzZXQpO1xuXG4gICAgLyoqKiBMb2NhbCBmdW5jdGlvbiAqKiovXG4gICAgZnVuY3Rpb24gaXNQZXJjZW50YWdlKG9mZnNldCkge1xuICAgICAgdmFyIHBlcmNlbnRhZ2VSZWdleCA9IC9eXFxkKyhcXC5cXGQrKT8lJC9nO1xuICAgICAgcmV0dXJuIHBlcmNlbnRhZ2VSZWdleC50ZXN0KG9mZnNldCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FsY3VsYXRlUGVyY2VudGFnZShwZXJjZW50U3RyLCBkdXJhdGlvbikge1xuICAgICAgaWYoZHVyYXRpb24pIHtcbiAgICAgICAgcmV0dXJuIGNhbGNQZXJjZW50KGR1cmF0aW9uLCBwYXJzZUZsb2F0KHBlcmNlbnRTdHIucmVwbGFjZSgnJScsICcnKSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FsY1BlcmNlbnQocXVhbnRpdHksIHBlcmNlbnQpe1xuICAgICAgcmV0dXJuIHF1YW50aXR5ICogcGVyY2VudCAvIDEwMDtcbiAgICB9XG4gIH1cblxufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IHBhcnNlcnM7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucycpO1xudmFyIFZQQUlESFRNTDVUZWNoID0gcmVxdWlyZSgnLi4vdnBhaWQvVlBBSURIVE1MNVRlY2gnKTtcbnZhciBWUEFJREZsYXNoVGVjaCA9IHJlcXVpcmUoJy4uL3ZwYWlkL1ZQQUlERmxhc2hUZWNoJyk7XG52YXIgVlBBSURGTEFTSENsaWVudCA9IHJlcXVpcmUoJ1ZQQUlERkxBU0hDbGllbnQvanMvVlBBSURGTEFTSENsaWVudCcpO1xuXG52YXIgdmFzdFV0aWwgPSB7XG5cbiAgdHJhY2s6IGZ1bmN0aW9uIHRyYWNrKFVSTE1hY3JvcywgdmFyaWFibGVzKSB7XG4gICAgdmFyIHNvdXJjZXMgPSB2YXN0VXRpbC5wYXJzZVVSTE1hY3JvcyhVUkxNYWNyb3MsIHZhcmlhYmxlcyk7XG4gICAgdmFyIHRyYWNrSW1ncyA9IFtdO1xuICAgIHNvdXJjZXMuZm9yRWFjaChmdW5jdGlvbiAoc3JjKSB7XG4gICAgICB2YXIgaW1nID0gbmV3IEltYWdlKCk7XG4gICAgICBpbWcuc3JjID0gc3JjO1xuICAgICAgdHJhY2tJbWdzLnB1c2goaW1nKTtcbiAgICB9KTtcbiAgICByZXR1cm4gdHJhY2tJbWdzO1xuICB9LFxuXG4gIHBhcnNlVVJMTWFjcm9zOiBmdW5jdGlvbiBwYXJzZU1hY3JvcyhVUkxNYWNyb3MsIHZhcmlhYmxlcykge1xuICAgIHZhciBwYXJzZWRVUkxzID0gW107XG5cbiAgICB2YXJpYWJsZXMgPSB2YXJpYWJsZXMgfHwge307XG5cbiAgICBpZiAoISh2YXJpYWJsZXNbXCJDQUNIRUJVU1RJTkdcIl0pKSB7XG4gICAgICB2YXJpYWJsZXNbXCJDQUNIRUJVU1RJTkdcIl0gPSBNYXRoLnJvdW5kKE1hdGgucmFuZG9tKCkgKiAxLjBlKzEwKTtcbiAgICB9XG5cbiAgICBVUkxNYWNyb3MuZm9yRWFjaChmdW5jdGlvbiAoVVJMTWFjcm8pIHtcbiAgICAgIHBhcnNlZFVSTHMucHVzaCh2YXN0VXRpbC5fcGFyc2VVUkxNYWNybyhVUkxNYWNybywgdmFyaWFibGVzKSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcGFyc2VkVVJMcztcbiAgfSxcblxuICBwYXJzZVVSTE1hY3JvOiBmdW5jdGlvbiBwYXJzZU1hY3JvKFVSTE1hY3JvLCB2YXJpYWJsZXMpIHtcbiAgICB2YXJpYWJsZXMgPSB2YXJpYWJsZXMgfHwge307XG5cbiAgICBpZiAoISh2YXJpYWJsZXNbXCJDQUNIRUJVU1RJTkdcIl0pKSB7XG4gICAgICB2YXJpYWJsZXNbXCJDQUNIRUJVU1RJTkdcIl0gPSBNYXRoLnJvdW5kKE1hdGgucmFuZG9tKCkgKiAxLjBlKzEwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFzdFV0aWwuX3BhcnNlVVJMTWFjcm8oVVJMTWFjcm8sIHZhcmlhYmxlcyk7XG4gIH0sXG5cbiAgX3BhcnNlVVJMTWFjcm86IGZ1bmN0aW9uIHBhcnNlTWFjcm8oVVJMTWFjcm8sIHZhcmlhYmxlcykge1xuICAgIHZhcmlhYmxlcyA9IHZhcmlhYmxlcyB8fCB7fTtcblxuICAgIHV0aWxpdGllcy5mb3JFYWNoKHZhcmlhYmxlcywgZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcbiAgICAgIFVSTE1hY3JvID0gVVJMTWFjcm8ucmVwbGFjZShuZXcgUmVnRXhwKFwiXFxcXFtcIiArIGtleSArIFwiXFxcXFxcXVwiLCAnZ20nKSwgdmFsdWUpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIFVSTE1hY3JvO1xuICB9LFxuXG4gIHBhcnNlRHVyYXRpb246IGZ1bmN0aW9uIHBhcnNlRHVyYXRpb24oZHVyYXRpb25TdHIpIHtcbiAgICB2YXIgZHVyYXRpb25SZWdleCA9IC8oXFxkXFxkKTooXFxkXFxkKTooXFxkXFxkKShcXC4oXFxkXFxkXFxkKSk/LztcbiAgICB2YXIgbWF0Y2gsIGR1cmF0aW9uSW5NcztcblxuICAgIGlmICh1dGlsaXRpZXMuaXNTdHJpbmcoZHVyYXRpb25TdHIpKSB7XG4gICAgICBtYXRjaCA9IGR1cmF0aW9uU3RyLm1hdGNoKGR1cmF0aW9uUmVnZXgpO1xuICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgIGR1cmF0aW9uSW5NcyA9IHBhcnNlSG91cnNUb01zKG1hdGNoWzFdKSArIHBhcnNlTWluVG9NcyhtYXRjaFsyXSkgKyBwYXJzZVNlY1RvTXMobWF0Y2hbM10pICsgcGFyc2VJbnQobWF0Y2hbNV0gfHwgMCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGlzTmFOKGR1cmF0aW9uSW5NcykgPyBudWxsIDogZHVyYXRpb25Jbk1zO1xuXG4gICAgLyoqKiBsb2NhbCBmdW5jdGlvbnMgKioqL1xuICAgIGZ1bmN0aW9uIHBhcnNlSG91cnNUb01zKGhvdXJTdHIpIHtcbiAgICAgIHJldHVybiBwYXJzZUludChob3VyU3RyLCAxMCkgKiA2MCAqIDYwICogMTAwMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZU1pblRvTXMobWluU3RyKSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQobWluU3RyLCAxMCkgKiA2MCAqIDEwMDA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VTZWNUb01zKHNlY1N0cikge1xuICAgICAgcmV0dXJuIHBhcnNlSW50KHNlY1N0ciwgMTApICogMTAwMDtcbiAgICB9XG4gIH0sXG5cbiAgcGFyc2VJbXByZXNzaW9uczogZnVuY3Rpb24gcGFyc2VJbXByZXNzaW9ucyhpbXByZXNzaW9ucykge1xuICAgIGlmIChpbXByZXNzaW9ucykge1xuICAgICAgaW1wcmVzc2lvbnMgPSB1dGlsaXRpZXMuaXNBcnJheShpbXByZXNzaW9ucykgPyBpbXByZXNzaW9ucyA6IFtpbXByZXNzaW9uc107XG4gICAgICByZXR1cm4gdXRpbGl0aWVzLnRyYW5zZm9ybUFycmF5KGltcHJlc3Npb25zLCBmdW5jdGlvbiAoaW1wcmVzc2lvbikge1xuICAgICAgICBpZiAodXRpbGl0aWVzLmlzTm90RW1wdHlTdHJpbmcoaW1wcmVzc2lvbi5rZXlWYWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4gaW1wcmVzc2lvbi5rZXlWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBbXTtcbiAgfSxcblxuXG4gIC8vV2UgYXNzdW1lIHRoYXQgdGhlIHByb2dyZXNzIGlzIGdvaW5nIHRvIGFycml2ZSBpbiBtaWxsaXNlY29uZHNcbiAgZm9ybWF0UHJvZ3Jlc3M6IGZ1bmN0aW9uIGZvcm1hdFByb2dyZXNzKHByb2dyZXNzKSB7XG4gICAgdmFyIGhvdXJzLCBtaW51dGVzLCBzZWNvbmRzLCBtaWxsaXNlY29uZHM7XG4gICAgaG91cnMgPSBwcm9ncmVzcyAvICg2MCAqIDYwICogMTAwMCk7XG4gICAgaG91cnMgPSBNYXRoLmZsb29yKGhvdXJzKTtcbiAgICBtaW51dGVzID0gKHByb2dyZXNzIC8gKDYwICogMTAwMCkpICUgNjA7XG4gICAgbWludXRlcyA9IE1hdGguZmxvb3IobWludXRlcyk7XG4gICAgc2Vjb25kcyA9IChwcm9ncmVzcyAvIDEwMDApICUgNjA7XG4gICAgc2Vjb25kcyA9IE1hdGguZmxvb3Ioc2Vjb25kcyk7XG4gICAgbWlsbGlzZWNvbmRzID0gcHJvZ3Jlc3MgJSAxMDAwO1xuICAgIHJldHVybiB1dGlsaXRpZXMudG9GaXhlZERpZ2l0cyhob3VycywgMikgKyAnOicgKyB1dGlsaXRpZXMudG9GaXhlZERpZ2l0cyhtaW51dGVzLCAyKSArICc6JyArIHV0aWxpdGllcy50b0ZpeGVkRGlnaXRzKHNlY29uZHMsIDIpICsgJy4nICsgdXRpbGl0aWVzLnRvRml4ZWREaWdpdHMobWlsbGlzZWNvbmRzLCAzKTtcbiAgfSxcblxuICBwYXJzZU9mZnNldDogZnVuY3Rpb24gcGFyc2VPZmZzZXQob2Zmc2V0LCBkdXJhdGlvbikge1xuICAgIGlmIChpc1BlcmNlbnRhZ2Uob2Zmc2V0KSkge1xuICAgICAgcmV0dXJuIGNhbGN1bGF0ZVBlcmNlbnRhZ2Uob2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgfVxuICAgIHJldHVybiB2YXN0VXRpbC5wYXJzZUR1cmF0aW9uKG9mZnNldCk7XG5cbiAgICAvKioqIExvY2FsIGZ1bmN0aW9uICoqKi9cbiAgICBmdW5jdGlvbiBpc1BlcmNlbnRhZ2Uob2Zmc2V0KSB7XG4gICAgICB2YXIgcGVyY2VudGFnZVJlZ2V4ID0gL15cXGQrKFxcLlxcZCspPyUkL2c7XG4gICAgICByZXR1cm4gcGVyY2VudGFnZVJlZ2V4LnRlc3Qob2Zmc2V0KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjYWxjdWxhdGVQZXJjZW50YWdlKHBlcmNlbnRTdHIsIGR1cmF0aW9uKSB7XG4gICAgICBpZiAoZHVyYXRpb24pIHtcbiAgICAgICAgcmV0dXJuIGNhbGNQZXJjZW50KGR1cmF0aW9uLCBwYXJzZUZsb2F0KHBlcmNlbnRTdHIucmVwbGFjZSgnJScsICcnKSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FsY1BlcmNlbnQocXVhbnRpdHksIHBlcmNlbnQpIHtcbiAgICAgIHJldHVybiBxdWFudGl0eSAqIHBlcmNlbnQgLyAxMDA7XG4gICAgfVxuICB9LFxuXG5cbiAgLy9MaXN0IG9mIHN1cHBvcnRlZCBWUEFJRCB0ZWNobm9sb2dpZXNcbiAgVlBBSURfdGVjaHM6IFtcbiAgICBWUEFJREZsYXNoVGVjaCxcbiAgICBWUEFJREhUTUw1VGVjaFxuICBdLFxuXG4gIGlzVlBBSUQ6IGZ1bmN0aW9uIGlzVlBBSURNZWRpYUZpbGUobWVkaWFGaWxlKSB7XG4gICAgcmV0dXJuICEhbWVkaWFGaWxlICYmIG1lZGlhRmlsZS5hcGlGcmFtZXdvcmsgPT09ICdWUEFJRCc7XG4gIH0sXG5cbiAgZmluZFN1cHBvcnRlZFZQQUlEVGVjaDogZnVuY3Rpb24gZmluZFN1cHBvcnRlZFZQQUlEVGVjaChtaW1lVHlwZSkge1xuICAgIHZhciBpLCBsZW4sIFZQQUlEVGVjaDtcblxuICAgIGZvciAoaSA9IDAsIGxlbiA9IHRoaXMuVlBBSURfdGVjaHMubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgIFZQQUlEVGVjaCA9IHRoaXMuVlBBSURfdGVjaHNbaV07XG4gICAgICBpZiAoVlBBSURUZWNoLnN1cHBvcnRzKG1pbWVUeXBlKSkge1xuICAgICAgICByZXR1cm4gVlBBSURUZWNoO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfSxcblxuICBpc0ZsYXNoU3VwcG9ydGVkOiBmdW5jdGlvbiBpc0ZsYXNoU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiBWUEFJREZMQVNIQ2xpZW50LmlzU3VwcG9ydGVkKCk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIE5lY2Vzc2FyeSBzdGVwIGZvciBWUEFJREZMQVNoQ2xpZW50IHRvIGtub3cgaWYgZmxhc2ggaXMgc3VwcG9ydGVkIGFuZCBub3QgYmxvY2tlZC5cbiAgICogSU1QT1JUQU5UIE5PVEU6IFRoaXMgaXMgYW4gYXN5bmMgdGVzdCBhbmQgbmVlZHMgdG8gYmUgcnVuIGFzIHNvb24gYXMgcG9zc2libGUuXG4gICAqXG4gICAqIEBwYXJhbSB2cGFpZEZsYXNoTG9hZGVyUGF0aCB0aGUgcGF0aCB0byB0aGUgdnBhaWRGbGFzaExvYWRlciBzd2Ygb2JqLlxuICAgKi9cbiAgcnVuRmxhc2hTdXBwb3J0Q2hlY2s6IGZ1bmN0aW9uIHJ1bkZsYXNoU3VwcG9ydENoZWNrKHZwYWlkRmxhc2hMb2FkZXJQYXRoKSB7XG4gICAgVlBBSURGTEFTSENsaWVudC5ydW5GbGFzaFRlc3Qoe2RhdGE6IHZwYWlkRmxhc2hMb2FkZXJQYXRofSk7XG4gIH1cblxufTtcblxubW9kdWxlLmV4cG9ydHMgPSB2YXN0VXRpbDtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFZBU1RFcnJvciA9IHJlcXVpcmUoJy4uL3Zhc3QvVkFTVEVycm9yJyk7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbmZ1bmN0aW9uIFZQQUlEQWRVbml0V3JhcHBlcih2cGFpZEFkVW5pdCwgb3B0cykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVlBBSURBZFVuaXRXcmFwcGVyKSkge1xuICAgIHJldHVybiBuZXcgVlBBSURBZFVuaXRXcmFwcGVyKHZwYWlkQWRVbml0LCBvcHRzKTtcbiAgfVxuICBzYW5pdHlDaGVjayh2cGFpZEFkVW5pdCwgb3B0cyk7XG5cbiAgdGhpcy5vcHRpb25zID0gdXRpbGl0aWVzLmV4dGVuZCh7fSwgb3B0cyk7XG5cbiAgdGhpcy5fYWRVbml0ID0gdnBhaWRBZFVuaXQ7XG5cbiAgLyoqKiBMb2NhbCBGdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBzYW5pdHlDaGVjayhhZFVuaXQsIG9wdHMpIHtcbiAgICBpZiAoIWFkVW5pdCB8fCAhVlBBSURBZFVuaXRXcmFwcGVyLmNoZWNrVlBBSURJbnRlcmZhY2UoYWRVbml0KSkge1xuICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcignb24gVlBBSURBZFVuaXRXcmFwcGVyLCB0aGUgcGFzc2VkIFZQQUlEIGFkVW5pdCBkb2VzIG5vdCBmdWxseSBpbXBsZW1lbnQgdGhlIFZQQUlEIGludGVyZmFjZScpO1xuICAgIH1cblxuICAgIGlmICghdXRpbGl0aWVzLmlzT2JqZWN0KG9wdHMpKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFwib24gVlBBSURBZFVuaXRXcmFwcGVyLCBleHBlY3RlZCBvcHRpb25zIGhhc2ggIGJ1dCBnb3QgJ1wiICsgb3B0cyArIFwiJ1wiKTtcbiAgICB9XG5cbiAgICBpZiAoIShcInJlc3BvbnNlVGltZW91dFwiIGluIG9wdHMpIHx8ICF1dGlsaXRpZXMuaXNOdW1iZXIob3B0cy5yZXNwb25zZVRpbWVvdXQpICl7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFwib24gVlBBSURBZFVuaXRXcmFwcGVyLCBleHBlY3RlZCByZXNwb25zZVRpbWVvdXQgaW4gb3B0aW9uc1wiKTtcbiAgICB9XG4gIH1cbn1cblxuVlBBSURBZFVuaXRXcmFwcGVyLmNoZWNrVlBBSURJbnRlcmZhY2UgPSBmdW5jdGlvbiBjaGVja1ZQQUlESW50ZXJmYWNlKFZQQUlEQWRVbml0KSB7XG4gIC8vTk9URTogc2tpcEFkIGlzIG5vdCBwYXJ0IG9mIHRoZSBtZXRob2QgbGlzdCBiZWNhdXNlIGl0IG9ubHkgYXBwZWFycyBpbiBWUEFJRCAyLjAgYW5kIHdlIHN1cHBvcnQgVlBBSUQgMS4wXG4gIHZhciBWUEFJREludGVyZmFjZU1ldGhvZHMgPSBbXG4gICAgJ2hhbmRzaGFrZVZlcnNpb24nLCAnaW5pdEFkJywgJ3N0YXJ0QWQnLCAnc3RvcEFkJywgJ3Jlc2l6ZUFkJywgJ3BhdXNlQWQnLCAnZXhwYW5kQWQnLCAnY29sbGFwc2VBZCdcbiAgXTtcblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gVlBBSURJbnRlcmZhY2VNZXRob2RzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgaWYgKCFWUEFJREFkVW5pdCB8fCAhdXRpbGl0aWVzLmlzRnVuY3Rpb24oVlBBSURBZFVuaXRbVlBBSURJbnRlcmZhY2VNZXRob2RzW2ldXSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuXG4gIHJldHVybiBjYW5TdWJzY3JpYmVUb0V2ZW50cyhWUEFJREFkVW5pdCkgJiYgY2FuVW5zdWJzY3JpYmVGcm9tRXZlbnRzKFZQQUlEQWRVbml0KTtcblxuICAvKioqIExvY2FsIEZ1bmN0aW9ucyAqKiovXG5cbiAgZnVuY3Rpb24gY2FuU3Vic2NyaWJlVG9FdmVudHMoYWRVbml0KSB7XG4gICAgcmV0dXJuIHV0aWxpdGllcy5pc0Z1bmN0aW9uKGFkVW5pdC5zdWJzY3JpYmUpIHx8IHV0aWxpdGllcy5pc0Z1bmN0aW9uKGFkVW5pdC5hZGRFdmVudExpc3RlbmVyKSB8fCB1dGlsaXRpZXMuaXNGdW5jdGlvbihhZFVuaXQub24pO1xuICB9XG5cbiAgZnVuY3Rpb24gY2FuVW5zdWJzY3JpYmVGcm9tRXZlbnRzKGFkVW5pdCkge1xuICAgIHJldHVybiB1dGlsaXRpZXMuaXNGdW5jdGlvbihhZFVuaXQudW5zdWJzY3JpYmUpIHx8IHV0aWxpdGllcy5pc0Z1bmN0aW9uKGFkVW5pdC5yZW1vdmVFdmVudExpc3RlbmVyKSB8fCB1dGlsaXRpZXMuaXNGdW5jdGlvbihhZFVuaXQub2ZmKTtcblxuICB9XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLmFkVW5pdEFzeW5jQ2FsbCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGFyZ3MgPSB1dGlsaXRpZXMuYXJyYXlMaWtlT2JqVG9BcnJheShhcmd1bWVudHMpO1xuICB2YXIgbWV0aG9kID0gYXJncy5zaGlmdCgpO1xuICB2YXIgY2IgPSBhcmdzLnBvcCgpO1xuICB2YXIgdGltZW91dElkO1xuXG4gIHNhbml0eUNoZWNrKG1ldGhvZCwgY2IsIHRoaXMuX2FkVW5pdCk7XG4gIGFyZ3MucHVzaCh3cmFwQ2FsbGJhY2soKSk7XG5cbiAgdGhpcy5fYWRVbml0W21ldGhvZF0uYXBwbHkodGhpcy5fYWRVbml0LCBhcmdzKTtcbiAgdGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgdGltZW91dElkID0gbnVsbDtcbiAgICBjYihuZXcgVkFTVEVycm9yKFwib24gVlBBSURBZFVuaXRXcmFwcGVyLCB0aW1lb3V0IHdoaWxlIHdhaXRpbmcgZm9yIGEgcmVzcG9uc2Ugb24gY2FsbCAnXCIgKyBtZXRob2QgKyBcIidcIikpO1xuICAgIGNiID0gdXRpbGl0aWVzLm5vb3A7XG4gIH0sIHRoaXMub3B0aW9ucy5yZXNwb25zZVRpbWVvdXQpO1xuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gc2FuaXR5Q2hlY2sobWV0aG9kLCBjYiwgYWRVbml0KSB7XG4gICAgaWYgKCF1dGlsaXRpZXMuaXNTdHJpbmcobWV0aG9kKSB8fCAhdXRpbGl0aWVzLmlzRnVuY3Rpb24oYWRVbml0W21ldGhvZF0pKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFwib24gVlBBSURBZFVuaXRXcmFwcGVyLmFkVW5pdEFzeW5jQ2FsbCwgaW52YWxpZCBtZXRob2QgbmFtZVwiKTtcbiAgICB9XG5cbiAgICBpZiAoIXV0aWxpdGllcy5pc0Z1bmN0aW9uKGNiKSkge1xuICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcihcIm9uIFZQQUlEQWRVbml0V3JhcHBlci5hZFVuaXRBc3luY0NhbGwsIG1pc3NpbmcgY2FsbGJhY2tcIik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gd3JhcENhbGxiYWNrKCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAodGltZW91dElkKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgfVxuICAgICAgY2IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuICB9XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLm9uID0gZnVuY3Rpb24gKGV2dE5hbWUsIGhhbmRsZXIpIHtcbiAgdmFyIGFkZEV2ZW50TGlzdGVuZXIgPSB0aGlzLl9hZFVuaXQuYWRkRXZlbnRMaXN0ZW5lciB8fCB0aGlzLl9hZFVuaXQuc3Vic2NyaWJlIHx8IHRoaXMuX2FkVW5pdC5vbjtcbiAgYWRkRXZlbnRMaXN0ZW5lci5jYWxsKHRoaXMuX2FkVW5pdCwgZXZ0TmFtZSwgaGFuZGxlcik7XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIChldnROYW1lLCBoYW5kbGVyKSB7XG4gIHZhciByZW1vdmVFdmVudExpc3RlbmVyID0gdGhpcy5fYWRVbml0LnJlbW92ZUV2ZW50TGlzdGVuZXIgfHwgdGhpcy5fYWRVbml0LnVuc3Vic2NyaWJlIHx8IHRoaXMuX2FkVW5pdC5vZmY7XG4gIHJlbW92ZUV2ZW50TGlzdGVuZXIuY2FsbCh0aGlzLl9hZFVuaXQsIGV2dE5hbWUsIGhhbmRsZXIpO1xufTtcblxuVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZS53YWl0Rm9yRXZlbnQgPSBmdW5jdGlvbiAoZXZ0TmFtZSwgY2IsIGNvbnRleHQpIHtcbiAgdmFyIHRpbWVvdXRJZDtcbiAgc2FuaXR5Q2hlY2soZXZ0TmFtZSwgY2IpO1xuICBjb250ZXh0ID0gY29udGV4dCB8fCBudWxsO1xuXG4gIHRoaXMub24oZXZ0TmFtZSwgcmVzcG9uc2VMaXN0ZW5lcik7XG5cbiAgdGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgY2IobmV3IFZBU1RFcnJvcihcIm9uIFZQQUlEQWRVbml0V3JhcHBlci53YWl0Rm9yRXZlbnQsIHRpbWVvdXQgd2hpbGUgd2FpdGluZyBmb3IgZXZlbnQgJ1wiICsgZXZ0TmFtZSArIFwiJ1wiKSk7XG4gICAgdGltZW91dElkID0gbnVsbDtcbiAgICBjYiA9IHV0aWxpdGllcy5ub29wO1xuICB9LCB0aGlzLm9wdGlvbnMucmVzcG9uc2VUaW1lb3V0KTtcblxuICAvKioqIExvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIHNhbml0eUNoZWNrKGV2dE5hbWUsIGNiKSB7XG4gICAgaWYgKCF1dGlsaXRpZXMuaXNTdHJpbmcoZXZ0TmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoXCJvbiBWUEFJREFkVW5pdFdyYXBwZXIud2FpdEZvckV2ZW50LCBtaXNzaW5nIGV2dCBuYW1lXCIpO1xuICAgIH1cblxuICAgIGlmICghdXRpbGl0aWVzLmlzRnVuY3Rpb24oY2IpKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFwib24gVlBBSURBZFVuaXRXcmFwcGVyLndhaXRGb3JFdmVudCwgbWlzc2luZyBjYWxsYmFja1wiKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZXNwb25zZUxpc3RlbmVyKCkge1xuICAgIHZhciBhcmdzID0gdXRpbGl0aWVzLmFycmF5TGlrZU9ialRvQXJyYXkoYXJndW1lbnRzKTtcblxuICAgIGlmICh0aW1lb3V0SWQpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgdGltZW91dElkID0gbnVsbDtcbiAgICB9XG5cbiAgICBhcmdzLnVuc2hpZnQobnVsbCk7XG4gICAgY2IuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gIH1cbn07XG5cbi8vIFZQQUlEIE1FVEhPRFNcblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUuaGFuZHNoYWtlVmVyc2lvbiA9IGZ1bmN0aW9uICh2ZXJzaW9uLCBjYikge1xuICB0aGlzLmFkVW5pdEFzeW5jQ2FsbCgnaGFuZHNoYWtlVmVyc2lvbicsIHZlcnNpb24sIGNiKTtcbn07XG5cbi8qIGpzaGludCBtYXhwYXJhbXM6NiAqL1xuVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZS5pbml0QWQgPSBmdW5jdGlvbiAod2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGRlc2lyZWRCaXRyYXRlLCBhZFVuaXREYXRhLCBjYikge1xuICB0aGlzLndhaXRGb3JFdmVudCgnQWRMb2FkZWQnLCBjYik7XG4gIHRoaXMuX2FkVW5pdC5pbml0QWQod2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGRlc2lyZWRCaXRyYXRlLCBhZFVuaXREYXRhKTtcbn07XG5cblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUucmVzaXplQWQgPSBmdW5jdGlvbiAod2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGNiKSB7XG4gIC8vIE5PVEU6IEFkU2l6ZUNoYW5nZSBldmVudCBpcyBvbmx5IHN1cHBvcnRlZCBvbiBWUEFJRCAyLjAgc28gZm9yIHRoZSBtb21lbnQgd2UgYXJlIG5vdCBnb2luZyB0byB1c2UgaXRcbiAgLy8gYW5kIHdpbGwgYXNzdW1lIHRoYXQgZXZlcnl0aGluZyBpcyBmaW5lIGFmdGVyIHRoZSBhc3luYyBjYWxsXG4gIHRoaXMuYWRVbml0QXN5bmNDYWxsKCdyZXNpemVBZCcsIHdpZHRoLCBoZWlnaHQsIHZpZXdNb2RlLCBjYik7XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLnN0YXJ0QWQgPSBmdW5jdGlvbiAoY2IpIHtcbiAgdGhpcy53YWl0Rm9yRXZlbnQoJ0FkU3RhcnRlZCcsIGNiKTtcbiAgdGhpcy5fYWRVbml0LnN0YXJ0QWQoKTtcbn07XG5cblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUuc3RvcEFkID0gZnVuY3Rpb24gKGNiKSB7XG4gIHRoaXMud2FpdEZvckV2ZW50KCdBZFN0b3BwZWQnLCBjYik7XG4gIHRoaXMuX2FkVW5pdC5zdG9wQWQoKTtcbn07XG5cblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUucGF1c2VBZCA9IGZ1bmN0aW9uIChjYikge1xuICB0aGlzLndhaXRGb3JFdmVudCgnQWRQYXVzZWQnLCBjYik7XG4gIHRoaXMuX2FkVW5pdC5wYXVzZUFkKCk7XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLnJlc3VtZUFkID0gZnVuY3Rpb24gKGNiKSB7XG4gIHRoaXMud2FpdEZvckV2ZW50KCdBZFBsYXlpbmcnLCBjYik7XG4gIHRoaXMuX2FkVW5pdC5yZXN1bWVBZCgpO1xufTtcblxuVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZS5leHBhbmRBZCA9IGZ1bmN0aW9uIChjYikge1xuICB0aGlzLndhaXRGb3JFdmVudCgnQWRFeHBhbmRlZENoYW5nZScsIGNiKTtcbiAgdGhpcy5fYWRVbml0LmV4cGFuZEFkKCk7XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLmNvbGxhcHNlQWQgPSBmdW5jdGlvbiAoY2IpIHtcbiAgdGhpcy53YWl0Rm9yRXZlbnQoJ0FkRXhwYW5kZWRDaGFuZ2UnLCBjYik7XG4gIHRoaXMuX2FkVW5pdC5jb2xsYXBzZUFkKCk7XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLnNraXBBZCA9IGZ1bmN0aW9uIChjYikge1xuICB0aGlzLndhaXRGb3JFdmVudCgnQWRTa2lwcGVkJywgY2IpO1xuICB0aGlzLl9hZFVuaXQuc2tpcEFkKCk7XG59O1xuXG4vL1ZQQUlEIHByb3BlcnR5IGdldHRlcnNcbltcbiAgJ2FkTGluZWFyJyxcbiAgJ2FkV2lkdGgnLFxuICAnYWRIZWlnaHQnLFxuICAnYWRFeHBhbmRlZCcsXG4gICdhZFNraXBwYWJsZVN0YXRlJyxcbiAgJ2FkUmVtYWluaW5nVGltZScsXG4gICdhZER1cmF0aW9uJyxcbiAgJ2FkVm9sdW1lJyxcbiAgJ2FkQ29tcGFuaW9ucycsXG4gICdhZEljb25zJ1xuXS5mb3JFYWNoKGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuICB2YXIgZ2V0dGVyTmFtZSA9ICdnZXQnICsgdXRpbGl0aWVzLmNhcGl0YWxpemUocHJvcGVydHkpO1xuXG4gIFZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGVbZ2V0dGVyTmFtZV0gPSBmdW5jdGlvbiAoY2IpIHtcbiAgICB0aGlzLmFkVW5pdEFzeW5jQ2FsbChnZXR0ZXJOYW1lLCBjYik7XG4gIH07XG59KTtcblxuLy9WUEFJRCBwcm9wZXJ0eSBzZXR0ZXJzXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLnNldEFkVm9sdW1lID0gZnVuY3Rpb24odm9sdW1lLCBjYil7XG4gIHRoaXMuYWRVbml0QXN5bmNDYWxsKCdzZXRBZFZvbHVtZScsdm9sdW1lLCBjYik7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZQQUlEQWRVbml0V3JhcHBlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFZBU1RFcnJvciA9IHJlcXVpcmUoJy4uL3Zhc3QvVkFTVEVycm9yJyk7XG5cbnZhciBWUEFJREZMQVNIQ2xpZW50ID0gcmVxdWlyZSgnVlBBSURGTEFTSENsaWVudC9qcy9WUEFJREZMQVNIQ2xpZW50Jyk7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG52YXIgZG9tID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvZG9tJyk7XG5cbmZ1bmN0aW9uIFZQQUlERmxhc2hUZWNoKG1lZGlhRmlsZSwgc2V0dGluZ3MpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFZQQUlERmxhc2hUZWNoKSkge1xuICAgIHJldHVybiBuZXcgVlBBSURGbGFzaFRlY2gobWVkaWFGaWxlKTtcbiAgfVxuICBzYW5pdHlDaGVjayhtZWRpYUZpbGUpO1xuICB0aGlzLm5hbWUgPSAndnBhaWQtZmxhc2gnO1xuICB0aGlzLm1lZGlhRmlsZSA9IG1lZGlhRmlsZTtcbiAgdGhpcy5jb250YWluZXJFbCA9IG51bGw7XG4gIHRoaXMudnBhaWRGbGFzaENsaWVudCA9IG51bGw7XG4gIHRoaXMuc2V0dGluZ3MgPSBzZXR0aW5ncztcblxuICAvKioqIGxvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIHNhbml0eUNoZWNrKG1lZGlhRmlsZSkge1xuICAgIGlmICghbWVkaWFGaWxlIHx8ICF1dGlsaXRpZXMuaXNTdHJpbmcobWVkaWFGaWxlLnNyYykpIHtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoJ29uIFZQQUlERmxhc2hUZWNoLCBpbnZhbGlkIE1lZGlhRmlsZScpO1xuICAgIH1cbiAgfVxufVxuXG5WUEFJREZsYXNoVGVjaC5WUEFJREZMQVNIQ2xpZW50ID0gVlBBSURGTEFTSENsaWVudDtcblxuVlBBSURGbGFzaFRlY2guc3VwcG9ydHMgPSBmdW5jdGlvbiAodHlwZSkge1xuICByZXR1cm4gdHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3gtc2hvY2t3YXZlLWZsYXNoJyAmJiBWUEFJREZsYXNoVGVjaC5WUEFJREZMQVNIQ2xpZW50LmlzU3VwcG9ydGVkKCk7XG59O1xuXG5WUEFJREZsYXNoVGVjaC5wcm90b3R5cGUubG9hZEFkVW5pdCA9IGZ1bmN0aW9uIGxvYWRGbGFzaENyZWF0aXZlKGNvbnRhaW5lckVsLCBvYmplY3RFbCwgY2FsbGJhY2spIHtcbiAgdmFyIHRoYXQgPSB0aGlzO1xuICB2YXIgZmxhc2hDbGllbnRPcHRzID0gdGhpcy5zZXR0aW5ncyAmJiB0aGlzLnNldHRpbmdzLnZwYWlkRmxhc2hMb2FkZXJQYXRoID8ge2RhdGE6IHRoaXMuc2V0dGluZ3MudnBhaWRGbGFzaExvYWRlclBhdGh9IDogdW5kZWZpbmVkO1xuICBzYW5pdHlDaGVjayhjb250YWluZXJFbCwgY2FsbGJhY2spO1xuXG4gIHRoaXMuY29udGFpbmVyRWwgPSBjb250YWluZXJFbDtcbiAgdGhpcy52cGFpZEZsYXNoQ2xpZW50ID0gbmV3IFZQQUlERmxhc2hUZWNoLlZQQUlERkxBU0hDbGllbnQoY29udGFpbmVyRWwsIGZ1bmN0aW9uIChlcnJvcikge1xuICAgIGlmIChlcnJvcikge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycm9yKTtcbiAgICB9XG5cbiAgICB0aGF0LnZwYWlkRmxhc2hDbGllbnQubG9hZEFkVW5pdCh0aGF0Lm1lZGlhRmlsZS5zcmMsIGNhbGxiYWNrKTtcbiAgfSwgZmxhc2hDbGllbnRPcHRzKTtcblxuICAvKioqIExvY2FsIEZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIHNhbml0eUNoZWNrKGNvbnRhaW5lciwgY2IpIHtcblxuICAgIGlmICghZG9tLmlzRG9tRWxlbWVudChjb250YWluZXIpKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKCdvbiBWUEFJREZsYXNoVGVjaC5sb2FkQWRVbml0LCBpbnZhbGlkIGRvbSBjb250YWluZXIgZWxlbWVudCcpO1xuICAgIH1cblxuICAgIGlmICghdXRpbGl0aWVzLmlzRnVuY3Rpb24oY2IpKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKCdvbiBWUEFJREZsYXNoVGVjaC5sb2FkQWRVbml0LCBtaXNzaW5nIHZhbGlkIGNhbGxiYWNrJyk7XG4gICAgfVxuICB9XG59O1xuXG5WUEFJREZsYXNoVGVjaC5wcm90b3R5cGUudW5sb2FkQWRVbml0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy52cGFpZEZsYXNoQ2xpZW50KSB7XG4gICAgdHJ5e1xuICAgICAgdGhpcy52cGFpZEZsYXNoQ2xpZW50LmRlc3Ryb3koKTtcbiAgICB9IGNhdGNoKGUpe1xuICAgICAgaWYoY29uc29sZSAmJiB1dGlsaXRpZXMuaXNGdW5jdGlvbihjb25zb2xlLmxvZykpe1xuICAgICAgICBjb25zb2xlLmxvZygnVkFTVCBFUlJPUjogdHJ5aW5nIHRvIHVubG9hZCB0aGUgVlBBSUQgYWR1bml0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMudnBhaWRGbGFzaENsaWVudCA9IG51bGw7XG4gIH1cblxuICBpZiAodGhpcy5jb250YWluZXJFbCkge1xuICAgIGRvbS5yZW1vdmUodGhpcy5jb250YWluZXJFbCk7XG4gICAgdGhpcy5jb250YWluZXJFbCA9IG51bGw7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gVlBBSURGbGFzaFRlY2g7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBWQVNURXJyb3IgPSByZXF1aXJlKCcuLi92YXN0L1ZBU1RFcnJvcicpO1xuXG52YXIgVlBBSURIVE1MNUNsaWVudCA9IHJlcXVpcmUoJ1ZQQUlESFRNTDVDbGllbnQvanMvVlBBSURIVE1MNUNsaWVudCcpO1xuXG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucycpO1xudmFyIGRvbSA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL2RvbScpO1xuXG5mdW5jdGlvbiBWUEFJREhUTUw1VGVjaChtZWRpYUZpbGUpIHtcblxuICBpZighKHRoaXMgaW5zdGFuY2VvZiBWUEFJREhUTUw1VGVjaCkpIHtcbiAgICByZXR1cm4gbmV3IFZQQUlESFRNTDVUZWNoKG1lZGlhRmlsZSk7XG4gIH1cblxuICBzYW5pdHlDaGVjayhtZWRpYUZpbGUpO1xuXG4gIHRoaXMubmFtZSA9ICd2cGFpZC1odG1sNSc7XG4gIHRoaXMuY29udGFpbmVyRWwgPSBudWxsO1xuICB0aGlzLnZpZGVvRWwgPSBudWxsO1xuICB0aGlzLnZwYWlkSFRNTENsaWVudCA9IG51bGw7XG5cbiAgdGhpcy5tZWRpYUZpbGUgPSBtZWRpYUZpbGU7XG5cbiAgZnVuY3Rpb24gc2FuaXR5Q2hlY2sobWVkaWFGaWxlKSB7XG4gICAgICBpZiAoIW1lZGlhRmlsZSB8fCAhdXRpbGl0aWVzLmlzU3RyaW5nKG1lZGlhRmlsZS5zcmMpKSB7XG4gICAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoVlBBSURIVE1MNVRlY2guSU5WQUxJRF9NRURJQV9GSUxFKTtcbiAgICAgIH1cbiAgfVxufVxuXG5WUEFJREhUTUw1VGVjaC5WUEFJREhUTUw1Q2xpZW50ID0gVlBBSURIVE1MNUNsaWVudDtcblxuVlBBSURIVE1MNVRlY2guc3VwcG9ydHMgPSBmdW5jdGlvbiAodHlwZSkge1xuICByZXR1cm4gIXV0aWxpdGllcy5pc09sZElFKCkgJiYgdHlwZSA9PT0gJ2FwcGxpY2F0aW9uL2phdmFzY3JpcHQnO1xufTtcblxuVlBBSURIVE1MNVRlY2gucHJvdG90eXBlLmxvYWRBZFVuaXQgPSBmdW5jdGlvbiBsb2FkQWRVbml0KGNvbnRhaW5lckVsLCB2aWRlb0VsLCBjYWxsYmFjaykge1xuICBzYW5pdHlDaGVjayhjb250YWluZXJFbCwgdmlkZW9FbCwgY2FsbGJhY2spO1xuXG4gIHRoaXMuY29udGFpbmVyRWwgPSBjb250YWluZXJFbDtcbiAgdGhpcy52aWRlb0VsID0gdmlkZW9FbDtcbiAgdGhpcy52cGFpZEhUTUxDbGllbnQgPSBuZXcgVlBBSURIVE1MNVRlY2guVlBBSURIVE1MNUNsaWVudChjb250YWluZXJFbCwgdmlkZW9FbCwge30pO1xuICB0aGlzLnZwYWlkSFRNTENsaWVudC5sb2FkQWRVbml0KHRoaXMubWVkaWFGaWxlLnNyYywgY2FsbGJhY2spO1xuXG4gIGZ1bmN0aW9uIHNhbml0eUNoZWNrKGNvbnRhaW5lciwgdmlkZW8sIGNiKSB7XG4gICAgaWYgKCFkb20uaXNEb21FbGVtZW50KGNvbnRhaW5lcikpIHtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoVlBBSURIVE1MNVRlY2guSU5WQUxJRF9ET01fQ09OVEFJTkVSX0VMKTtcbiAgICB9XG5cbiAgICBpZiAoIWRvbS5pc0RvbUVsZW1lbnQodmlkZW8pIHx8IHZpZGVvLnRhZ05hbWUudG9Mb3dlckNhc2UoKSAhPT0gJ3ZpZGVvJykge1xuICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcihWUEFJREhUTUw1VGVjaC5JTlZBTElEX0RPTV9DT05UQUlORVJfRUwpO1xuICAgIH1cblxuICAgIGlmICghdXRpbGl0aWVzLmlzRnVuY3Rpb24oY2IpKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFZQQUlESFRNTDVUZWNoLk1JU1NJTkdfQ0FMTEJBQ0spO1xuICAgIH1cbiAgfVxufTtcblxuVlBBSURIVE1MNVRlY2gucHJvdG90eXBlLnVubG9hZEFkVW5pdCA9IGZ1bmN0aW9uIHVubG9hZEFkVW5pdCgpIHtcbiAgaWYgKHRoaXMudnBhaWRIVE1MQ2xpZW50KSB7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMudnBhaWRIVE1MQ2xpZW50LmRlc3Ryb3koKTtcbiAgICB9IGNhdGNoKGUpIHtcbiAgICAgIGlmIChjb25zb2xlICYmIHV0aWxpdGllcy5pc0Z1bmN0aW9uKGNvbnNvbGUubG9nKSkge1xuICAgICAgICBjb25zb2xlLmxvZygnVkFTVCBFUlJPUjogdHJ5aW5nIHRvIHVubG9hZCB0aGUgVlBBSUQgYWR1bml0Jyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy52cGFpZEhUTUxDbGllbnQgPSBudWxsO1xuICB9XG5cbiAgaWYgKHRoaXMuY29udGFpbmVyRWwpIHtcbiAgICBkb20ucmVtb3ZlKHRoaXMuY29udGFpbmVyRWwpO1xuICAgIHRoaXMuY29udGFpbmVyRWwgPSBudWxsO1xuICB9XG59O1xuXG52YXIgUFJFRklYID0gJ29uIFZQQUlESFRNTDVUZWNoJztcblZQQUlESFRNTDVUZWNoLklOVkFMSURfTUVESUFfRklMRSA9IFBSRUZJWCArICcsIGludmFsaWQgTWVkaWFGaWxlJztcblZQQUlESFRNTDVUZWNoLklOVkFMSURfRE9NX0NPTlRBSU5FUl9FTCA9IFBSRUZJWCArICcsIGludmFsaWQgY29udGFpbmVyIEh0bWxFbGVtZW50JztcblZQQUlESFRNTDVUZWNoLklOVkFMSURfRE9NX1ZJREVPX0VMID0gUFJFRklYICsgJywgaW52YWxpZCBIVE1MVmlkZW9FbGVtZW50JztcblZQQUlESFRNTDVUZWNoLk1JU1NJTkdfQ0FMTEJBQ0sgPSBQUkVGSVggKyAnLCBtaXNzaW5nIHZhbGlkIGNhbGxiYWNrJztcblxubW9kdWxlLmV4cG9ydHMgPSBWUEFJREhUTUw1VGVjaDsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBWQVNURXJyb3IgPSByZXF1aXJlKCcuLi92YXN0L1ZBU1RFcnJvcicpO1xudmFyIFZBU1RSZXNwb25zZSA9IHJlcXVpcmUoJy4uL3Zhc3QvVkFTVFJlc3BvbnNlJyk7XG52YXIgVkFTVFRyYWNrZXIgPSByZXF1aXJlKCcuLi92YXN0L1ZBU1RUcmFja2VyJyk7XG52YXIgdmFzdFV0aWwgPSByZXF1aXJlKCcuLi92YXN0L3Zhc3RVdGlsJyk7XG5cbnZhciBWUEFJREFkVW5pdFdyYXBwZXIgPSByZXF1aXJlKCcuL1ZQQUlEQWRVbml0V3JhcHBlcicpO1xuXG52YXIgYXN5bmMgPSByZXF1aXJlKCcuLi8uLi91dGlscy9hc3luYycpO1xudmFyIGRvbSA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL2RvbScpO1xudmFyIHBsYXllclV0aWxzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvcGxheWVyVXRpbHMnKTtcbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbmZ1bmN0aW9uIFZQQUlESW50ZWdyYXRvcihwbGF5ZXIsIHNldHRpbmdzKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBWUEFJREludGVncmF0b3IpKSB7XG4gICAgcmV0dXJuIG5ldyBWUEFJREludGVncmF0b3IocGxheWVyKTtcbiAgfVxuXG4gIHRoaXMuVklFV19NT0RFID0ge1xuICAgIE5PUk1BTDogJ25vcm1hbCcsXG4gICAgRlVMTFNDUkVFTjogXCJmdWxsc2NyZWVuXCIsXG4gICAgVEhVTUJOQUlMOiBcInRodW1ibmFpbFwiXG4gIH07XG4gIHRoaXMucGxheWVyID0gcGxheWVyO1xuICB0aGlzLmNvbnRhaW5lckVsID0gY3JlYXRlVlBBSURDb250YWluZXJFbChwbGF5ZXIpO1xuICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgcmVzcG9uc2VUaW1lb3V0OiA1MDAwLFxuICAgIFZQQUlEX1ZFUlNJT046ICcyLjAnXG4gIH07XG4gIHRoaXMuc2V0dGluZ3MgPSBzZXR0aW5ncztcblxuICAvKioqIExvY2FsIGZ1bmN0aW9ucyAqKiovXG5cbiAgZnVuY3Rpb24gY3JlYXRlVlBBSURDb250YWluZXJFbCgpIHtcbiAgICB2YXIgY29udGFpbmVyRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBkb20uYWRkQ2xhc3MoY29udGFpbmVyRWwsICdWUEFJRC1jb250YWluZXInKTtcbiAgICBwbGF5ZXIuZWwoKS5pbnNlcnRCZWZvcmUoY29udGFpbmVyRWwsIHBsYXllci5jb250cm9sQmFyLmVsKCkpO1xuICAgIHJldHVybiBjb250YWluZXJFbDtcblxuICB9XG59XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUucGxheUFkID0gZnVuY3Rpb24gcGxheVZQYWlkQWQodmFzdFJlc3BvbnNlLCBjYWxsYmFjaykge1xuICBpZiAoISh2YXN0UmVzcG9uc2UgaW5zdGFuY2VvZiBWQVNUUmVzcG9uc2UpKSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBWQVNURXJyb3IoJ29uIFZBU1RJbnRlZ3JhdG9yLnBsYXlBZCwgbWlzc2luZyByZXF1aXJlZCBWQVNUUmVzcG9uc2UnKSk7XG4gIH1cblxuICB2YXIgdGhhdCA9IHRoaXM7XG4gIHZhciBwbGF5ZXIgPSB0aGlzLnBsYXllcjtcbiAgdmFyIHRlY2ggPSB0aGlzLl9maW5kU3VwcG9ydGVkVGVjaCh2YXN0UmVzcG9uc2UsIHRoaXMuc2V0dGluZ3MpO1xuXG4gIGNhbGxiYWNrID0gY2FsbGJhY2sgfHwgdXRpbGl0aWVzLm5vb3A7XG5cbiAgdGhpcy5fYWRVbml0ID0gbnVsbDtcblxuICBkb20uYWRkQ2xhc3MocGxheWVyLmVsKCksICd2anMtdnBhaWQtYWQnKTtcblxuICBwbGF5ZXIub24oJ3Zhc3QuYWRzQ2FuY2VsJywgdHJpZ2dlclZwYWlkQWRFbmQpO1xuICBwbGF5ZXIub25lKCd2cGFpZC5hZEVuZCcsIGZ1bmN0aW9uKCl7XG4gICAgcGxheWVyLm9mZigndmFzdC5hZHNDYW5jZWwnLCB0cmlnZ2VyVnBhaWRBZEVuZCk7XG4gICAgcmVtb3ZlQWRVbml0KCk7XG4gIH0pO1xuXG4gIGlmICh0ZWNoKSB7XG4gICAgYXN5bmMud2F0ZXJmYWxsKFtcbiAgICAgIGZ1bmN0aW9uIChuZXh0KSB7XG4gICAgICAgIG5leHQobnVsbCwgdGVjaCwgdmFzdFJlc3BvbnNlKTtcbiAgICAgIH0sXG4gICAgICB0aGlzLl9sb2FkQWRVbml0LmJpbmQodGhpcyksXG4gICAgICB0aGlzLl9wbGF5QWRVbml0LmJpbmQodGhpcyksXG4gICAgICB0aGlzLl9maW5pc2hQbGF5aW5nLmJpbmQodGhpcylcblxuICAgIF0sIGFkQ29tcGxldGUpO1xuXG4gICAgdGhpcy5fYWRVbml0ID0ge1xuICAgICAgX3BhdXNlZDogdHJ1ZSxcbiAgICAgIHR5cGU6ICdWUEFJRCcsXG4gICAgICBwYXVzZUFkOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLnBhdXNlQWQnKTtcbiAgICAgICAgcGxheWVyLnBhdXNlKHRydWUpOy8vd2UgbWFrZSBzdXJlIHRoYXQgdGhlIHZpZGVvIGNvbnRlbnQgZ2V0cyBzdG9wcGVkLlxuICAgICAgfSxcbiAgICAgIHJlc3VtZUFkOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQucmVzdW1lQWQnKTtcbiAgICAgIH0sXG4gICAgICBpc1BhdXNlZDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXVzZWQ7XG4gICAgICB9LFxuICAgICAgZ2V0U3JjOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRlY2gubWVkaWFGaWxlO1xuICAgICAgfVxuICAgIH07XG5cbiAgfSBlbHNlIHtcbiAgICB2YXIgZXJyb3IgPSBuZXcgVkFTVEVycm9yKCdvbiBWUEFJREludGVncmF0b3IucGxheUFkLCBjb3VsZCBub3QgZmluZCBhIHN1cHBvcnRlZCBtZWRpYUZpbGUnLCA0MDMpO1xuICAgIGFkQ29tcGxldGUoZXJyb3IsIHRoaXMuX2FkVW5pdCwgdmFzdFJlc3BvbnNlKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLl9hZFVuaXQ7XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBhZENvbXBsZXRlKGVycm9yLCBhZFVuaXQsIHZhc3RSZXNwb25zZSkge1xuICAgIGlmIChlcnJvciAmJiB2YXN0UmVzcG9uc2UpIHtcbiAgICAgIHRoYXQuX3RyYWNrRXJyb3IodmFzdFJlc3BvbnNlLCBlcnJvci5jb2RlKTtcbiAgICB9XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLmFkRW5kJyk7XG4gICAgY2FsbGJhY2soZXJyb3IsIHZhc3RSZXNwb25zZSk7XG4gIH1cblxuICBmdW5jdGlvbiB0cmlnZ2VyVnBhaWRBZEVuZCgpe1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5hZEVuZCcpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVtb3ZlQWRVbml0KCkge1xuICAgIGlmICh0ZWNoKSB7XG4gICAgICB0ZWNoLnVubG9hZEFkVW5pdCgpO1xuICAgIH1cbiAgICBkb20ucmVtb3ZlQ2xhc3MocGxheWVyLmVsKCksICd2anMtdnBhaWQtYWQnKTtcbiAgfVxufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5fZmluZFN1cHBvcnRlZFRlY2ggPSBmdW5jdGlvbiAodmFzdFJlc3BvbnNlLCBzZXR0aW5ncykge1xuICBpZiAoISh2YXN0UmVzcG9uc2UgaW5zdGFuY2VvZiBWQVNUUmVzcG9uc2UpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgdnBhaWRNZWRpYUZpbGVzID0gdmFzdFJlc3BvbnNlLm1lZGlhRmlsZXMuZmlsdGVyKHZhc3RVdGlsLmlzVlBBSUQpO1xuICB2YXIgaSwgbGVuLCBtZWRpYUZpbGUsIFZQQUlEVGVjaDtcblxuICBmb3IgKGkgPSAwLCBsZW4gPSB2cGFpZE1lZGlhRmlsZXMubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICBtZWRpYUZpbGUgPSB2cGFpZE1lZGlhRmlsZXNbaV07XG4gICAgVlBBSURUZWNoID0gdmFzdFV0aWwuZmluZFN1cHBvcnRlZFZQQUlEVGVjaChtZWRpYUZpbGUudHlwZSk7XG4gICAgaWYgKFZQQUlEVGVjaCkge1xuICAgICAgcmV0dXJuIG5ldyBWUEFJRFRlY2gobWVkaWFGaWxlLCBzZXR0aW5ncyk7XG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsO1xufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5fY3JlYXRlVlBBSURBZFVuaXRXcmFwcGVyID0gZnVuY3Rpb24oYWRVbml0LCBzcmMsIHJlc3BvbnNlVGltZW91dCkge1xuICByZXR1cm4gbmV3IFZQQUlEQWRVbml0V3JhcHBlcihhZFVuaXQsIHtzcmM6IHNyYywgcmVzcG9uc2VUaW1lb3V0OiByZXNwb25zZVRpbWVvdXR9KTtcbn07XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUuX2xvYWRBZFVuaXQgPSBmdW5jdGlvbiAodGVjaCwgdmFzdFJlc3BvbnNlLCBuZXh0KSB7XG4gIHZhciB0aGF0ID0gdGhpcztcbiAgdmFyIHBsYXllciA9IHRoaXMucGxheWVyO1xuICB2YXIgdmpzVGVjaEVsID0gcGxheWVyLmVsKCkucXVlcnlTZWxlY3RvcignLnZqcy10ZWNoJyk7XG4gIHZhciByZXNwb25zZVRpbWVvdXQgPSB0aGlzLnNldHRpbmdzLnJlc3BvbnNlVGltZW91dCB8fCB0aGlzLm9wdGlvbnMucmVzcG9uc2VUaW1lb3V0O1xuICB0ZWNoLmxvYWRBZFVuaXQodGhpcy5jb250YWluZXJFbCwgdmpzVGVjaEVsLCBmdW5jdGlvbiAoZXJyb3IsIGFkVW5pdCkge1xuICAgIGlmIChlcnJvcikge1xuICAgICAgcmV0dXJuIG5leHQoZXJyb3IsIGFkVW5pdCwgdmFzdFJlc3BvbnNlKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgdmFyIFdyYXBwZWRBZFVuaXQgPSB0aGF0Ll9jcmVhdGVWUEFJREFkVW5pdFdyYXBwZXIoYWRVbml0LCB0ZWNoLm1lZGlhRmlsZS5zcmMsIHJlc3BvbnNlVGltZW91dCk7XG4gICAgICB2YXIgdGVjaENsYXNzID0gJ3Zqcy0nICsgdGVjaC5uYW1lICsgJy1hZCc7XG4gICAgICBkb20uYWRkQ2xhc3MocGxheWVyLmVsKCksIHRlY2hDbGFzcyk7XG4gICAgICBwbGF5ZXIub25lKCd2cGFpZC5hZEVuZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgICBkb20ucmVtb3ZlQ2xhc3MocGxheWVyLmVsKCksdGVjaENsYXNzKTtcbiAgICAgIH0pO1xuICAgICAgbmV4dChudWxsLCBXcmFwcGVkQWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIG5leHQoZSwgYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuICAgIH1cbiAgfSk7XG59O1xuXG5WUEFJREludGVncmF0b3IucHJvdG90eXBlLl9wbGF5QWRVbml0ID0gZnVuY3Rpb24gKGFkVW5pdCwgdmFzdFJlc3BvbnNlLCBjYWxsYmFjaykge1xuICBhc3luYy53YXRlcmZhbGwoW1xuICAgIGZ1bmN0aW9uIChuZXh0KSB7XG4gICAgICBuZXh0KG51bGwsIGFkVW5pdCwgdmFzdFJlc3BvbnNlKTtcbiAgICB9LFxuICAgIHRoaXMuX2hhbmRzaGFrZS5iaW5kKHRoaXMpLFxuICAgIHRoaXMuX2luaXRBZC5iaW5kKHRoaXMpLFxuICAgIHRoaXMuX3NldHVwRXZlbnRzLmJpbmQodGhpcyksXG4gICAgdGhpcy5fYWRkU2tpcEJ1dHRvbi5iaW5kKHRoaXMpLFxuICAgIHRoaXMuX2xpbmtQbGF5ZXJDb250cm9scy5iaW5kKHRoaXMpLFxuICAgIHRoaXMuX3N0YXJ0QWQuYmluZCh0aGlzKVxuICBdLCBjYWxsYmFjayk7XG59O1xuXG5WUEFJREludGVncmF0b3IucHJvdG90eXBlLl9oYW5kc2hha2UgPSBmdW5jdGlvbiBoYW5kc2hha2UoYWRVbml0LCB2YXN0UmVzcG9uc2UsIG5leHQpIHtcbiAgYWRVbml0LmhhbmRzaGFrZVZlcnNpb24odGhpcy5vcHRpb25zLlZQQUlEX1ZFUlNJT04sIGZ1bmN0aW9uIChlcnJvciwgdmVyc2lvbikge1xuICAgIGlmIChlcnJvcikge1xuICAgICAgcmV0dXJuIG5leHQoZXJyb3IsIGFkVW5pdCwgdmFzdFJlc3BvbnNlKTtcbiAgICB9XG5cbiAgICBpZiAodmVyc2lvbiAmJiBpc1N1cHBvcnRlZFZlcnNpb24odmVyc2lvbikpIHtcbiAgICAgIHJldHVybiBuZXh0KG51bGwsIGFkVW5pdCwgdmFzdFJlc3BvbnNlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV4dChuZXcgVkFTVEVycm9yKCdvbiBWUEFJREludGVncmF0b3IuX2hhbmRzaGFrZSwgdW5zdXBwb3J0ZWQgdmVyc2lvbiBcIicgKyB2ZXJzaW9uICsgJ1wiJyksIGFkVW5pdCwgdmFzdFJlc3BvbnNlKTtcbiAgfSk7XG5cbiAgZnVuY3Rpb24gaXNTdXBwb3J0ZWRWZXJzaW9uKHZlcnNpb24pIHtcbiAgICB2YXIgbWFqb3JOdW0gPSBtYWpvcih2ZXJzaW9uKTtcbiAgICByZXR1cm4gbWFqb3JOdW0gPj0gMSAmJiBtYWpvck51bSA8PSAyO1xuICB9XG5cbiAgZnVuY3Rpb24gbWFqb3IodmVyc2lvbikge1xuICAgIHZhciBwYXJ0cyA9IHZlcnNpb24uc3BsaXQoJy4nKTtcbiAgICByZXR1cm4gcGFyc2VJbnQocGFydHNbMF0sIDEwKTtcbiAgfVxufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5faW5pdEFkID0gZnVuY3Rpb24gKGFkVW5pdCwgdmFzdFJlc3BvbnNlLCBuZXh0KSB7XG4gIHZhciB0ZWNoID0gdGhpcy5wbGF5ZXIuZWwoKS5xdWVyeVNlbGVjdG9yKCcudmpzLXRlY2gnKTtcbiAgdmFyIGRpbWVuc2lvbiA9IGRvbS5nZXREaW1lbnNpb24odGVjaCk7XG4gIGFkVW5pdC5pbml0QWQoZGltZW5zaW9uLndpZHRoLCBkaW1lbnNpb24uaGVpZ2h0LCB0aGlzLlZJRVdfTU9ERS5OT1JNQUwsIC0xLCB7QWRQYXJhbWV0ZXJzOiB2YXN0UmVzcG9uc2UuYWRQYXJhbWV0ZXJzIHx8ICcnfSwgZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgbmV4dChlcnJvciwgYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuICB9KTtcbn07XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUuX2NyZWF0ZVZBU1RUcmFja2VyID0gZnVuY3Rpb24oYWRVbml0U3JjLCB2YXN0UmVzcG9uc2UpIHtcbiAgcmV0dXJuIG5ldyBWQVNUVHJhY2tlcihhZFVuaXRTcmMsIHZhc3RSZXNwb25zZSk7XG59O1xuXG5WUEFJREludGVncmF0b3IucHJvdG90eXBlLl9zZXR1cEV2ZW50cyA9IGZ1bmN0aW9uIChhZFVuaXQsIHZhc3RSZXNwb25zZSwgbmV4dCkge1xuICB2YXIgYWRVbml0U3JjID0gYWRVbml0Lm9wdGlvbnMuc3JjO1xuICB2YXIgdHJhY2tlciA9IHRoaXMuX2NyZWF0ZVZBU1RUcmFja2VyKGFkVW5pdFNyYywgdmFzdFJlc3BvbnNlKTtcbiAgdmFyIHBsYXllciA9IHRoaXMucGxheWVyO1xuICB2YXIgdGhhdCA9IHRoaXM7XG5cbiAgYWRVbml0Lm9uKCdBZFNraXBwZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkU2tpcHBlZCcpO1xuICAgIHRyYWNrZXIudHJhY2tTa2lwKCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRJbXByZXNzaW9uJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZEltcHJlc3Npb24nKTtcbiAgICB0cmFja2VyLnRyYWNrSW1wcmVzc2lvbnMoKTtcbiAgfSk7XG5cbiAgYWRVbml0Lm9uKCdBZFN0YXJ0ZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkU3RhcnRlZCcpO1xuICAgIHRyYWNrZXIudHJhY2tDcmVhdGl2ZVZpZXcoKTtcbiAgICBub3RpZnlQbGF5VG9QbGF5ZXIoKTtcbiAgfSk7XG5cbiAgYWRVbml0Lm9uKCdBZFZpZGVvU3RhcnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkVmlkZW9TdGFydCcpO1xuICAgIHRyYWNrZXIudHJhY2tTdGFydCgpO1xuICAgIG5vdGlmeVBsYXlUb1BsYXllcigpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkUGxheWluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuQWRQbGF5aW5nJyk7XG4gICAgdHJhY2tlci50cmFja1Jlc3VtZSgpO1xuICAgIG5vdGlmeVBsYXlUb1BsYXllcigpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkUGF1c2VkJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFBhdXNlZCcpO1xuICAgIHRyYWNrZXIudHJhY2tQYXVzZSgpO1xuICAgIG5vdGlmeVBhdXNlVG9QbGF5ZXIoKTtcbiAgfSk7XG5cbiAgZnVuY3Rpb24gbm90aWZ5UGxheVRvUGxheWVyKCl7XG4gICAgaWYodGhhdC5fYWRVbml0ICYmIHRoYXQuX2FkVW5pdC5pc1BhdXNlZCgpKXtcbiAgICAgIHRoYXQuX2FkVW5pdC5fcGF1c2VkID0gZmFsc2U7XG4gICAgfVxuICAgIHBsYXllci50cmlnZ2VyKCdwbGF5Jyk7XG5cbiAgfVxuXG4gIGZ1bmN0aW9uIG5vdGlmeVBhdXNlVG9QbGF5ZXIoKSB7XG4gICAgaWYodGhhdC5fYWRVbml0KXtcbiAgICAgIHRoYXQuX2FkVW5pdC5fcGF1c2VkID0gdHJ1ZTtcbiAgICB9XG4gICAgcGxheWVyLnRyaWdnZXIoJ3BhdXNlJyk7XG4gIH1cblxuICBhZFVuaXQub24oJ0FkVmlkZW9GaXJzdFF1YXJ0aWxlJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFZpZGVvRmlyc3RRdWFydGlsZScpO1xuICAgIHRyYWNrZXIudHJhY2tGaXJzdFF1YXJ0aWxlKCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRWaWRlb01pZHBvaW50JywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFZpZGVvTWlkcG9pbnQnKTtcbiAgICB0cmFja2VyLnRyYWNrTWlkcG9pbnQoKTtcbiAgfSk7XG5cbiAgYWRVbml0Lm9uKCdBZFZpZGVvVGhpcmRRdWFydGlsZScsIGZ1bmN0aW9uICgpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuQWRWaWRlb1RoaXJkUXVhcnRpbGUnKTtcbiAgICB0cmFja2VyLnRyYWNrVGhpcmRRdWFydGlsZSgpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkVmlkZW9Db21wbGV0ZScsIGZ1bmN0aW9uICgpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuQWRWaWRlb0NvbXBsZXRlJyk7XG4gICAgdHJhY2tlci50cmFja0NvbXBsZXRlKCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRDbGlja1RocnUnLCBmdW5jdGlvbiAoZGF0YSkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZENsaWNrVGhydScpO1xuICAgIHZhciB1cmwgPSBkYXRhLnVybDtcbiAgICB2YXIgcGxheWVySGFuZGxlcyA9IGRhdGEucGxheWVySGFuZGxlcztcbiAgICB2YXIgY2xpY2tUaHJ1VXJsID0gdXRpbGl0aWVzLmlzTm90RW1wdHlTdHJpbmcodXJsKSA/IHVybCA6IGdlbmVyYXRlQ2xpY2tUaHJvdWdoVVJMKHZhc3RSZXNwb25zZS5jbGlja1Rocm91Z2gpO1xuXG4gICAgdHJhY2tlci50cmFja0NsaWNrKCk7XG4gICAgaWYgKHBsYXllckhhbmRsZXMgJiYgY2xpY2tUaHJ1VXJsKSB7XG4gICAgICB3aW5kb3cub3BlbihjbGlja1RocnVVcmwsICdfYmxhbmsnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZW5lcmF0ZUNsaWNrVGhyb3VnaFVSTChjbGlja1Rocm91Z2hNYWNybykge1xuICAgICAgdmFyIHZhcmlhYmxlcyA9IHtcbiAgICAgICAgQVNTRVRVUkk6IGFkVW5pdC5vcHRpb25zLnNyYyxcbiAgICAgICAgQ09OVEVOVFBMQVlIRUFEOiAwIC8vSW4gVlBBSUQgdGhlcmUgaXMgbm8gbWV0aG9kIHRvIGtub3cgdGhlIGN1cnJlbnQgdGltZSBmcm9tIHRoZSBhZFVuaXRcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiBjbGlja1Rocm91Z2hNYWNybyA/IHZhc3RVdGlsLnBhcnNlVVJMTWFjcm8oY2xpY2tUaHJvdWdoTWFjcm8sIHZhcmlhYmxlcykgOiBudWxsO1xuICAgIH1cbiAgfSk7XG5cbiAgYWRVbml0Lm9uKCdBZFVzZXJBY2NlcHRJbnZpdGF0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFVzZXJBY2NlcHRJbnZpdGF0aW9uJyk7XG4gICAgdHJhY2tlci50cmFja0FjY2VwdEludml0YXRpb24oKTtcbiAgICB0cmFja2VyLnRyYWNrQWNjZXB0SW52aXRhdGlvbkxpbmVhcigpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkVXNlckNsb3NlJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFVzZXJDbG9zZScpO1xuICAgIHRyYWNrZXIudHJhY2tDbG9zZSgpO1xuICAgIHRyYWNrZXIudHJhY2tDbG9zZUxpbmVhcigpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkVXNlck1pbmltaXplJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFVzZXJNaW5pbWl6ZScpO1xuICAgIHRyYWNrZXIudHJhY2tDb2xsYXBzZSgpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkRXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkRXJyb3InKTtcbiAgICAvL05PVEU6IHdlIHRyYWNrIGVycm9ycyBjb2RlIDkwMSwgYXMgbm90ZWQgaW4gVkFTVCAzLjBcbiAgICB0cmFja2VyLnRyYWNrRXJyb3JXaXRoQ29kZSg5MDEpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkVm9sdW1lQ2hhbmdlJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFZvbHVtZUNoYW5nZScpO1xuICAgIHZhciBsYXN0Vm9sdW1lID0gcGxheWVyLnZvbHVtZSgpO1xuICAgIGFkVW5pdC5nZXRBZFZvbHVtZShmdW5jdGlvbiAoZXJyb3IsIGN1cnJlbnRWb2x1bWUpIHtcbiAgICAgIGlmIChjdXJyZW50Vm9sdW1lID09PSAwICYmIGxhc3RWb2x1bWUgPiAwKSB7XG4gICAgICAgIHRyYWNrZXIudHJhY2tNdXRlKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjdXJyZW50Vm9sdW1lID4gMCAmJiBsYXN0Vm9sdW1lID09PSAwKSB7XG4gICAgICAgIHRyYWNrZXIudHJhY2tVbm11dGUoKTtcbiAgICAgIH1cblxuICAgICAgcGxheWVyLnZvbHVtZShjdXJyZW50Vm9sdW1lKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgdmFyIHVwZGF0ZVZpZXdTaXplID0gcmVzaXplQWQuYmluZCh0aGlzLCBwbGF5ZXIsIGFkVW5pdCwgdGhpcy5WSUVXX01PREUpO1xuICB2YXIgdXBkYXRlVmlld1NpemVUaHJvdHRsZWQgPSB1dGlsaXRpZXMudGhyb3R0bGUodXBkYXRlVmlld1NpemUsIDEwMCk7XG4gIHZhciBhdXRvUmVzaXplID0gdGhpcy5zZXR0aW5ncy5hdXRvUmVzaXplO1xuXG4gIGlmIChhdXRvUmVzaXplKSB7XG4gICAgZG9tLmFkZEV2ZW50TGlzdGVuZXIod2luZG93LCAncmVzaXplJywgdXBkYXRlVmlld1NpemVUaHJvdHRsZWQpO1xuICAgIGRvbS5hZGRFdmVudExpc3RlbmVyKHdpbmRvdywgJ29yaWVudGF0aW9uY2hhbmdlJywgdXBkYXRlVmlld1NpemVUaHJvdHRsZWQpO1xuICB9XG5cbiAgcGxheWVyLm9uKCd2YXN0LnJlc2l6ZScsIHVwZGF0ZVZpZXdTaXplKTtcbiAgcGxheWVyLm9uKCd2cGFpZC5wYXVzZUFkJywgcGF1c2VBZFVuaXQpO1xuICBwbGF5ZXIub24oJ3ZwYWlkLnJlc3VtZUFkJywgcmVzdW1lQWRVbml0KTtcblxuICBwbGF5ZXIub25lKCd2cGFpZC5hZEVuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBwbGF5ZXIub2ZmKCd2YXN0LnJlc2l6ZScsIHVwZGF0ZVZpZXdTaXplKTtcbiAgICBwbGF5ZXIub2ZmKCd2cGFpZC5wYXVzZUFkJywgcGF1c2VBZFVuaXQpO1xuICAgIHBsYXllci5vZmYoJ3ZwYWlkLnJlc3VtZUFkJywgcmVzdW1lQWRVbml0KTtcblxuICAgIGlmIChhdXRvUmVzaXplKSB7XG4gICAgICBkb20ucmVtb3ZlRXZlbnRMaXN0ZW5lcih3aW5kb3csICdyZXNpemUnLCB1cGRhdGVWaWV3U2l6ZVRocm90dGxlZCk7XG4gICAgICBkb20ucmVtb3ZlRXZlbnRMaXN0ZW5lcih3aW5kb3csICdvcmllbnRhdGlvbmNoYW5nZScsIHVwZGF0ZVZpZXdTaXplVGhyb3R0bGVkKTtcbiAgICB9XG4gIH0pO1xuXG4gIG5leHQobnVsbCwgYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuXG4gIC8qKiogTG9jYWwgRnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gcGF1c2VBZFVuaXQoKSB7XG4gICAgYWRVbml0LnBhdXNlQWQodXRpbGl0aWVzLm5vb3ApO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzdW1lQWRVbml0KCkge1xuICAgIGFkVW5pdC5yZXN1bWVBZCh1dGlsaXRpZXMubm9vcCk7XG4gIH1cbn07XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUuX2FkZFNraXBCdXR0b24gPSBmdW5jdGlvbiAoYWRVbml0LCB2YXN0UmVzcG9uc2UsIG5leHQpIHtcbiAgdmFyIHNraXBCdXR0b247XG4gIHZhciBwbGF5ZXIgPSB0aGlzLnBsYXllcjtcblxuICBhZFVuaXQub24oJ0FkU2tpcHBhYmxlU3RhdGVDaGFuZ2UnLCB1cGRhdGVTa2lwQnV0dG9uU3RhdGUpO1xuXG4gIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3Zhc3QuYWRFbmQnLCAndmFzdC5hZHNDYW5jZWwnXSwgcmVtb3ZlU2tpcEJ1dHRvbik7XG5cbiAgbmV4dChudWxsLCBhZFVuaXQsIHZhc3RSZXNwb25zZSk7XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbiAqKiovXG4gIGZ1bmN0aW9uIHVwZGF0ZVNraXBCdXR0b25TdGF0ZSgpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuQWRTa2lwcGFibGVTdGF0ZUNoYW5nZScpO1xuICAgIGFkVW5pdC5nZXRBZFNraXBwYWJsZVN0YXRlKGZ1bmN0aW9uIChlcnJvciwgaXNTa2lwcGFibGUpIHtcbiAgICAgIGlmIChpc1NraXBwYWJsZSkge1xuICAgICAgICBpZiAoIXNraXBCdXR0b24pIHtcbiAgICAgICAgICBhZGRTa2lwQnV0dG9uKHBsYXllcik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlbW92ZVNraXBCdXR0b24ocGxheWVyKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZFNraXBCdXR0b24ocGxheWVyKSB7XG4gICAgc2tpcEJ1dHRvbiA9IGNyZWF0ZVNraXBCdXR0b24ocGxheWVyKTtcbiAgICBwbGF5ZXIuZWwoKS5hcHBlbmRDaGlsZChza2lwQnV0dG9uKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbW92ZVNraXBCdXR0b24oKSB7XG4gICAgZG9tLnJlbW92ZShza2lwQnV0dG9uKTtcbiAgICBza2lwQnV0dG9uID0gbnVsbDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZVNraXBCdXR0b24oKSB7XG4gICAgdmFyIHNraXBCdXR0b24gPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICBkb20uYWRkQ2xhc3Moc2tpcEJ1dHRvbiwgXCJ2YXN0LXNraXAtYnV0dG9uXCIpO1xuICAgIGRvbS5hZGRDbGFzcyhza2lwQnV0dG9uLCBcImVuYWJsZWRcIik7XG4gICAgc2tpcEJ1dHRvbi5pbm5lckhUTUwgPSBcIlNraXAgYWRcIjtcblxuICAgIHNraXBCdXR0b24ub25jbGljayA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICBhZFVuaXQuc2tpcEFkKHV0aWxpdGllcy5ub29wKTsvL1dlIHNraXAgdGhlIGFkVW5pdFxuXG4gICAgICAvL1dlIHByZXZlbnQgZXZlbnQgcHJvcGFnYXRpb24gdG8gYXZvaWQgcHJvYmxlbXMgd2l0aCB0aGUgY2xpY2tUaHJvdWdoIGFuZCBzbyBvblxuICAgICAgaWYgKHdpbmRvdy5FdmVudC5wcm90b3R5cGUuc3RvcFByb3BhZ2F0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIHNraXBCdXR0b247XG4gIH1cbn07XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUuX2xpbmtQbGF5ZXJDb250cm9scyA9IGZ1bmN0aW9uIChhZFVuaXQsIHZhc3RSZXNwb25zZSwgbmV4dCkge1xuICB2YXIgdGhhdCA9IHRoaXM7XG4gIGxpbmtWb2x1bWVDb250cm9sKHRoaXMucGxheWVyLCBhZFVuaXQpO1xuICBsaW5rRnVsbFNjcmVlbkNvbnRyb2wodGhpcy5wbGF5ZXIsIGFkVW5pdCwgdGhpcy5WSUVXX01PREUpO1xuXG4gIG5leHQobnVsbCwgYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gbGlua1ZvbHVtZUNvbnRyb2wocGxheWVyLCBhZFVuaXQpIHtcbiAgICBwbGF5ZXIub24oJ3ZvbHVtZWNoYW5nZScsIHVwZGF0ZUFkVW5pdFZvbHVtZSk7XG4gICAgYWRVbml0Lm9uKCdBZFZvbHVtZUNoYW5nZScsIHVwZGF0ZVBsYXllclZvbHVtZSk7XG5cbiAgICBwbGF5ZXIub25lKCd2cGFpZC5hZEVuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHBsYXllci5vZmYoJ3ZvbHVtZWNoYW5nZScsIHVwZGF0ZUFkVW5pdFZvbHVtZSk7XG4gICAgfSk7XG5cblxuICAgIC8qKiogbG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgICBmdW5jdGlvbiB1cGRhdGVBZFVuaXRWb2x1bWUoKSB7XG4gICAgICB2YXIgdm9sID0gcGxheWVyLm11dGVkKCkgPyAwIDogcGxheWVyLnZvbHVtZSgpO1xuICAgICAgYWRVbml0LnNldEFkVm9sdW1lKHZvbCwgbG9nRXJyb3IpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHVwZGF0ZVBsYXllclZvbHVtZSgpIHtcbiAgICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFZvbHVtZUNoYW5nZScpO1xuICAgICAgYWRVbml0LmdldEFkVm9sdW1lKGZ1bmN0aW9uIChlcnJvciwgdm9sKSB7XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgIGxvZ0Vycm9yKGVycm9yKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwbGF5ZXIudm9sdW1lKHZvbCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGxpbmtGdWxsU2NyZWVuQ29udHJvbChwbGF5ZXIsIGFkVW5pdCwgVklFV19NT0RFKSB7XG4gICAgdmFyIHVwZGF0ZVZpZXdTaXplID0gcmVzaXplQWQuYmluZCh0aGF0LCBwbGF5ZXIsIGFkVW5pdCwgVklFV19NT0RFKTtcblxuICAgIHBsYXllci5vbignZnVsbHNjcmVlbmNoYW5nZScsIHVwZGF0ZVZpZXdTaXplKTtcblxuICAgIHBsYXllci5vbmUoJ3ZwYWlkLmFkRW5kJywgZnVuY3Rpb24gKCkge1xuICAgICAgcGxheWVyLm9mZignZnVsbHNjcmVlbmNoYW5nZScsIHVwZGF0ZVZpZXdTaXplKTtcbiAgICB9KTtcbiAgfVxufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5fc3RhcnRBZCA9IGZ1bmN0aW9uIChhZFVuaXQsIHZhc3RSZXNwb25zZSwgbmV4dCkge1xuICB2YXIgcGxheWVyID0gdGhpcy5wbGF5ZXI7XG5cbiAgYWRVbml0LnN0YXJ0QWQoZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgaWYgKCFlcnJvcikge1xuICAgICAgcGxheWVyLnRyaWdnZXIoJ3Zhc3QuYWRTdGFydCcpO1xuICAgIH1cbiAgICBuZXh0KGVycm9yLCBhZFVuaXQsIHZhc3RSZXNwb25zZSk7XG4gIH0pO1xufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5fZmluaXNoUGxheWluZyA9IGZ1bmN0aW9uIChhZFVuaXQsIHZhc3RSZXNwb25zZSwgbmV4dCkge1xuICB2YXIgcGxheWVyID0gdGhpcy5wbGF5ZXI7XG4gIGFkVW5pdC5vbignQWRTdG9wcGVkJywgZnVuY3Rpb24gKCkge1xuICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkU3RvcHBlZCcpO1xuICAgZmluaXNoUGxheWluZ0FkKG51bGwpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkRXJyb3InLCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICB2YXIgZXJyTXNnID0gZXJyb3I/IGVycm9yLm1lc3NhZ2UgOiAnb24gVlBBSURJbnRlZ3JhdG9yLCBlcnJvciB3aGlsZSB3YWl0aW5nIGZvciB0aGUgYWRVbml0IHRvIGZpbmlzaCBwbGF5aW5nJztcbiAgICBmaW5pc2hQbGF5aW5nQWQobmV3IFZBU1RFcnJvcihlcnJNc2cpKTtcbiAgfSk7XG5cbiAgLyoqKiBsb2NhbCBmdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBmaW5pc2hQbGF5aW5nQWQoZXJyb3IpIHtcbiAgICBuZXh0KGVycm9yLCBhZFVuaXQsIHZhc3RSZXNwb25zZSk7XG4gIH1cbn07XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUuX3RyYWNrRXJyb3IgPSBmdW5jdGlvbiB0cmFja0Vycm9yKHJlc3BvbnNlLCBlcnJvckNvZGUpIHtcbiAgdmFzdFV0aWwudHJhY2socmVzcG9uc2UuZXJyb3JVUkxNYWNyb3MsIHtFUlJPUkNPREU6IGVycm9yQ29kZSB8fCA5MDF9KTtcbn07XG5cbmZ1bmN0aW9uIHJlc2l6ZUFkKHBsYXllciwgYWRVbml0LCBWSUVXX01PREUpIHtcbiAgdmFyIHRlY2ggPSBwbGF5ZXIuZWwoKS5xdWVyeVNlbGVjdG9yKCcudmpzLXRlY2gnKTtcbiAgdmFyIGRpbWVuc2lvbiA9IGRvbS5nZXREaW1lbnNpb24odGVjaCk7XG4gIHZhciBNT0RFID0gcGxheWVyLmlzRnVsbHNjcmVlbigpID8gVklFV19NT0RFLkZVTExTQ1JFRU4gOiBWSUVXX01PREUuTk9STUFMO1xuICBhZFVuaXQucmVzaXplQWQoZGltZW5zaW9uLndpZHRoLCBkaW1lbnNpb24uaGVpZ2h0LCBNT0RFLCBsb2dFcnJvcik7XG59XG5cbmZ1bmN0aW9uIGxvZ0Vycm9yKGVycm9yKSB7XG4gIGlmIChlcnJvciAmJiBjb25zb2xlICYmIGNvbnNvbGUubG9nKSB7XG4gICAgY29uc29sZS5sb2coJ0VSUk9SOiAnICsgZXJyb3IubWVzc2FnZSwgZXJyb3IpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gVlBBSURJbnRlZ3JhdG9yOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIGRvbSA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL2RvbScpO1xuXG52YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuZWxlbWVudC5jbGFzc05hbWUgPSAndmpzLWFkcy1sYWJlbCB2anMtY29udHJvbCB2anMtbGFiZWwtaGlkZGVuJztcbmVsZW1lbnQuaW5uZXJIVE1MID0gJ0FkdmVydGlzZW1lbnQnO1xuXG52YXIgQWRzTGFiZWxGYWN0b3J5ID0gZnVuY3Rpb24oYmFzZUNvbXBvbmVudCkge1xuICByZXR1cm4ge1xuICAgIC8qKiBAY29uc3RydWN0b3IgKi9cbiAgICBpbml0OiBmdW5jdGlvbiBpbml0KHBsYXllciwgb3B0aW9ucykge1xuICAgICAgb3B0aW9ucy5lbCA9IGVsZW1lbnQ7XG4gICAgICBiYXNlQ29tcG9uZW50LmNhbGwodGhpcywgcGxheWVyLCBvcHRpb25zKTtcblxuICAgICAgLy8gV2UgYXN5bmNocm9ub3VzbHkgcmVwb3NpdGlvbiB0aGUgYWRzIGxhYmVsIGVsZW1lbnRcbiAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY3VycmVudFRpbWVDb21wID0gcGxheWVyLmNvbnRyb2xCYXIgJiYoIHBsYXllci5jb250cm9sQmFyLmdldENoaWxkKFwidGltZXJDb250cm9sc1wiKSB8fCBwbGF5ZXIuY29udHJvbEJhci5nZXRDaGlsZChcImN1cnJlbnRUaW1lRGlzcGxheVwiKSApO1xuICAgICAgICBpZihjdXJyZW50VGltZUNvbXApIHtcbiAgICAgICAgICBwbGF5ZXIuY29udHJvbEJhci5lbCgpLmluc2VydEJlZm9yZShlbGVtZW50LCBjdXJyZW50VGltZUNvbXAuZWwoKSk7XG4gICAgICAgIH1cbiAgICAgICAgZG9tLnJlbW92ZUNsYXNzKGVsZW1lbnQsICd2anMtbGFiZWwtaGlkZGVuJyk7XG4gICAgICB9LCAwKTtcbiAgICB9LFxuXG4gICAgZWw6IGZ1bmN0aW9uIGdldEVsZW1lbnQoKSB7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFkc0xhYmVsRmFjdG9yeTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBiYXNlVmlkZW9Kc0NvbXBvbmVudCA9IHZpZGVvanMuZ2V0Q29tcG9uZW50KCdDb21wb25lbnQnKTtcblxudmFyIEFkc0xhYmVsID0gcmVxdWlyZSgnLi9hZHMtbGFiZWwnKShiYXNlVmlkZW9Kc0NvbXBvbmVudCk7XG5cbnZpZGVvanMucmVnaXN0ZXJDb21wb25lbnQoJ0Fkc0xhYmVsJywgdmlkZW9qcy5leHRlbmQoYmFzZVZpZGVvSnNDb21wb25lbnQsIEFkc0xhYmVsKSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogVGhlIGNvbXBvbmVudCB0aGF0IHNob3dzIGEgYmxhY2sgc2NyZWVuIHVudGlsIHRoZSBhZHMgcGx1Z2luIGhhcyBkZWNpZGVkIGlmIGl0IGNhbiBvciBpdCBjYW4gbm90IHBsYXkgdGhlIGFkLlxuICpcbiAqIE5vdGU6IEluIGNhc2UgeW91IHdvbmRlciB3aHkgaW5zdGVhZCBvZiB0aGlzIGJsYWNrIHBvc3RlciB3ZSBkb24ndCBqdXN0IHNob3cgdGhlIHNwaW5uZXIgbG9hZGVyLlxuICogICAgICAgSU9TIGRldmljZXMgZG8gbm90IHdvcmsgd2VsbCB3aXRoIGFuaW1hdGlvbnMgYW5kIHRoZSBicm93c2VyIGNocmFzaGVzIGZyb20gdGltZSB0byB0aW1lIFRoYXQgaXMgd2h5IHdlIGNob3NlIHRvXG4gKiAgICAgICBoYXZlIGEgc2Vjb25kYXJ5IGJsYWNrIHBvc3Rlci5cbiAqXG4gKiAgICAgICBJdCBhbHNvIG1ha2VzIGl0IG11Y2ggbW9yZSBlYXNpZXIgZm9yIHRoZSB1c2VycyBvZiB0aGUgcGx1Z2luIHNpbmNlIGl0IGRvZXMgbm90IGNoYW5nZSB0aGUgZGVmYXVsdCBiZWhhdmlvdXIgb2YgdGhlXG4gKiAgICAgICBzcGlubmVyIGFuZCB0aGUgcGxheWVyIHdvcmtzIHRoZSBzYW1lIHdheSB3aXRoIGFuZCB3aXRob3V0IHRoZSBwbHVnaW4uXG4gKlxuICogQHBhcmFtIHt2anMuUGxheWVyfE9iamVjdH0gcGxheWVyXG4gKiBAcGFyYW0ge09iamVjdD19IG9wdGlvbnNcbiAqIEBjb25zdHJ1Y3RvclxuICovXG52YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXG52YXIgQmxhY2tQb3N0ZXJGYWN0b3J5ID0gZnVuY3Rpb24oYmFzZUNvbXBvbmVudCkge1xuICByZXR1cm4ge1xuICAgIC8qKiBAY29uc3RydWN0b3IgKi9cbiAgICBpbml0OiBmdW5jdGlvbiBpbml0KHBsYXllciwgb3B0aW9ucykge1xuICAgICAgb3B0aW9ucy5lbCA9IGVsZW1lbnQ7XG4gICAgICBlbGVtZW50LmNsYXNzTmFtZSA9ICd2anMtYmxhY2stcG9zdGVyJztcbiAgICAgIGJhc2VDb21wb25lbnQuY2FsbCh0aGlzLCBwbGF5ZXIsIG9wdGlvbnMpO1xuXG4gICAgICB2YXIgcG9zdGVySW1nID0gcGxheWVyLmdldENoaWxkKCdwb3N0ZXJJbWFnZScpO1xuXG4gICAgICAvL1dlIG5lZWQgdG8gZG8gaXQgYXN5bmNocm9ub3VzbHkgdG8gYmUgc3VyZSB0aGF0IHRoZSBibGFjayBwb3N0ZXIgZWwgaXMgb24gdGhlIGRvbS5cbiAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmKHBvc3RlckltZyAmJiBwbGF5ZXIgJiYgcGxheWVyLmVsKCkpIHtcbiAgICAgICAgICBwbGF5ZXIuZWwoKS5pbnNlcnRCZWZvcmUoZWxlbWVudCwgcG9zdGVySW1nLmVsKCkpO1xuICAgICAgICB9XG4gICAgICB9LCAwKTtcbiAgICB9LFxuICAgIGVsOiBmdW5jdGlvbiBnZXRFbGVtZW50KCkge1xuICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBCbGFja1Bvc3RlckZhY3Rvcnk7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYmFzZVZpZGVvSnNDb21wb25lbnQgPSB2aWRlb2pzLmdldENvbXBvbmVudCgnQ29tcG9uZW50Jyk7XG5cbnZhciBCbGFja1Bvc3RlciA9IHJlcXVpcmUoJy4vYmxhY2stcG9zdGVyJykoYmFzZVZpZGVvSnNDb21wb25lbnQpO1xuXG52aWRlb2pzLnJlZ2lzdGVyQ29tcG9uZW50KCdCbGFja1Bvc3RlcicsIHZpZGVvanMuZXh0ZW5kKGJhc2VWaWRlb0pzQ29tcG9uZW50LCBCbGFja1Bvc3RlcikpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVkFTVENsaWVudCA9IHJlcXVpcmUoJy4uL2Fkcy92YXN0L1ZBU1RDbGllbnQnKTtcbnZhciBWQVNURXJyb3IgPSByZXF1aXJlKCcuLi9hZHMvdmFzdC9WQVNURXJyb3InKTtcbnZhciB2YXN0VXRpbCA9IHJlcXVpcmUoJy4uL2Fkcy92YXN0L3Zhc3RVdGlsJyk7XG5cbnZhciBWQVNUSW50ZWdyYXRvciA9IHJlcXVpcmUoJy4uL2Fkcy92YXN0L1ZBU1RJbnRlZ3JhdG9yJyk7XG52YXIgVlBBSURJbnRlZ3JhdG9yID0gcmVxdWlyZSgnLi4vYWRzL3ZwYWlkL1ZQQUlESW50ZWdyYXRvcicpO1xuXG52YXIgYXN5bmMgPSByZXF1aXJlKCcuLi91dGlscy9hc3luYycpO1xudmFyIGRvbSA9IHJlcXVpcmUoJy4uL3V0aWxzL2RvbScpO1xudmFyIHBsYXllclV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMvcGxheWVyVXRpbHMnKTtcbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVkFTVFBsdWdpbihvcHRpb25zKSB7XG4gIHZhciBzbmFwc2hvdDtcbiAgdmFyIHBsYXllciA9IHRoaXM7XG4gIHZhciB2YXN0ID0gbmV3IFZBU1RDbGllbnQoKTtcbiAgdmFyIGFkc0NhbmNlbGVkID0gZmFsc2U7XG4gIHZhciBkZWZhdWx0T3B0cyA9IHtcbiAgICAvLyBtYXhpbXVtIGFtb3VudCBvZiB0aW1lIGluIG1zIHRvIHdhaXQgdG8gcmVjZWl2ZSBgYWRzcmVhZHlgIGZyb20gdGhlIGFkXG4gICAgLy8gaW1wbGVtZW50YXRpb24gYWZ0ZXIgcGxheSBoYXMgYmVlbiByZXF1ZXN0ZWQuIEFkIGltcGxlbWVudGF0aW9ucyBhcmVcbiAgICAvLyBleHBlY3RlZCB0byBsb2FkIGFueSBkeW5hbWljIGxpYnJhcmllcyBhbmQgbWFrZSBhbnkgcmVxdWVzdHMgdG8gZGV0ZXJtaW5lXG4gICAgLy8gYWQgcG9saWNpZXMgZm9yIGEgdmlkZW8gZHVyaW5nIHRoaXMgdGltZS5cbiAgICB0aW1lb3V0OiA1MDAsXG5cbiAgICAvL1RPRE86ZmluaXNoIHRoaXMgSU9TIEZJWFxuICAgIC8vV2hlbmV2ZXIgeW91IHBsYXkgYW4gYWRkIG9uIElPUywgdGhlIG5hdGl2ZSBwbGF5ZXIga2lja3MgaW4gYW5kIHdlIGxvb3NlIGNvbnRyb2wgb2YgaXQuIE9uIHZlcnkgaGVhdnkgcGFnZXMgdGhlICdwbGF5JyBldmVudFxuICAgIC8vIE1heSBvY2N1ciBhZnRlciB0aGUgdmlkZW8gY29udGVudCBoYXMgYWxyZWFkeSBzdGFydGVkLiBUaGlzIGlzIHdyb25nIGlmIHlvdSB3YW50IHRvIHBsYXkgYSBwcmVyb2xsIGFkIHRoYXQgbmVlZHMgdG8gaGFwcGVuIGJlZm9yZSB0aGUgdXNlclxuICAgIC8vIHN0YXJ0cyB3YXRjaGluZyB0aGUgY29udGVudC4gVG8gcHJldmVudCB0aGlzIHVzZWNcbiAgICBpb3NQcmVyb2xsQ2FuY2VsVGltZW91dDogMjAwMCxcblxuICAgIC8vIG1heGltdW4gYW1vdW50IG9mIHRpbWUgZm9yIHRoZSBhZCB0byBhY3R1YWxseSBzdGFydCBwbGF5aW5nLiBJZiB0aGlzIHRpbWVvdXQgZ2V0c1xuICAgIC8vIHRyaWdnZXJlZCB0aGUgYWRzIHdpbGwgYmUgY2FuY2VsbGVkXG4gICAgYWRDYW5jZWxUaW1lb3V0OiAzMDAwLFxuXG4gICAgLy8gQm9vbGVhbiBmbGFnIHRoYXQgY29uZmlndXJlcyB0aGUgcGxheWVyIHRvIHBsYXkgYSBuZXcgYWQgYmVmb3JlIHRoZSB1c2VyIHNlZXMgdGhlIHZpZGVvIGFnYWluXG4gICAgLy8gdGhlIGN1cnJlbnQgdmlkZW9cbiAgICBwbGF5QWRBbHdheXM6IGZhbHNlLFxuXG4gICAgLy8gRmxhZyB0byBlbmFibGUgb3IgZGlzYWJsZSB0aGUgYWRzIGJ5IGRlZmF1bHQuXG4gICAgYWRzRW5hYmxlZDogdHJ1ZSxcblxuICAgIC8vIEJvb2xlYW4gZmxhZyB0byBlbmFibGUgb3IgZGlzYWJsZSB0aGUgcmVzaXplIHdpdGggd2luZG93LnJlc2l6ZSBvciBvcmllbnRhdGlvbmNoYW5nZVxuICAgIGF1dG9SZXNpemU6IHRydWUsXG5cbiAgICAvLyBQYXRoIHRvIHRoZSBWUEFJRCBmbGFzaCBhZCdzIGxvYWRlclxuICAgIHZwYWlkRmxhc2hMb2FkZXJQYXRoOiAnL1ZQQUlERmxhc2guc3dmJ1xuICB9O1xuXG4gIHZhciBzZXR0aW5ncyA9IHV0aWxpdGllcy5leHRlbmQoe30sIGRlZmF1bHRPcHRzLCBvcHRpb25zIHx8IHt9KTtcblxuICBpZih1dGlsaXRpZXMuaXNVbmRlZmluZWQoc2V0dGluZ3MuYWRUYWdVcmwpICYmIHV0aWxpdGllcy5pc0RlZmluZWQoc2V0dGluZ3MudXJsKSl7XG4gICAgc2V0dGluZ3MuYWRUYWdVcmwgPSBzZXR0aW5ncy51cmw7XG4gIH1cblxuICBpZiAodXRpbGl0aWVzLmlzU3RyaW5nKHNldHRpbmdzLmFkVGFnVXJsKSkge1xuICAgIHNldHRpbmdzLmFkVGFnVXJsID0gdXRpbGl0aWVzLmVjaG9GbihzZXR0aW5ncy5hZFRhZ1VybCk7XG4gIH1cblxuICBpZiAodXRpbGl0aWVzLmlzRGVmaW5lZChzZXR0aW5ncy5hZFRhZ1hNTCkgJiYgIXV0aWxpdGllcy5pc0Z1bmN0aW9uKHNldHRpbmdzLmFkVGFnWE1MKSkge1xuICAgIHJldHVybiB0cmFja0FkRXJyb3IobmV3IFZBU1RFcnJvcignb24gVmlkZW9KUyBWQVNUIHBsdWdpbiwgdGhlIHBhc3NlZCBhZFRhZ1hNTCBvcHRpb24gZG9lcyBub3QgY29udGFpbiBhIGZ1bmN0aW9uJykpO1xuICB9XG5cbiAgaWYgKCF1dGlsaXRpZXMuaXNEZWZpbmVkKHNldHRpbmdzLmFkVGFnVXJsKSAmJiAhdXRpbGl0aWVzLmlzRnVuY3Rpb24oc2V0dGluZ3MuYWRUYWdYTUwpKSB7XG4gICAgcmV0dXJuIHRyYWNrQWRFcnJvcihuZXcgVkFTVEVycm9yKCdvbiBWaWRlb0pTIFZBU1QgcGx1Z2luLCBtaXNzaW5nIGFkVGFnVXJsIG9uIG9wdGlvbnMgb2JqZWN0JykpO1xuICB9XG5cbiAgdmFzdFV0aWwucnVuRmxhc2hTdXBwb3J0Q2hlY2soc2V0dGluZ3MudnBhaWRGbGFzaExvYWRlclBhdGgpOy8vIE5lY2Vzc2FyeSBzdGVwIGZvciBWUEFJREZMQVNIQ2xpZW50IHRvIHdvcmsuXG5cbiAgcGxheWVyVXRpbHMucHJlcGFyZUZvckFkcyhwbGF5ZXIpO1xuXG4gIGlmIChzZXR0aW5ncy5wbGF5QWRBbHdheXMpIHtcbiAgICAvLyBObyBtYXR0ZXIgd2hhdCBoYXBwZW5zIHdlIHBsYXkgYSBuZXcgYWQgYmVmb3JlIHRoZSB1c2VyIHNlZXMgdGhlIHZpZGVvIGFnYWluLlxuICAgIHBsYXllci5vbigndmFzdC5jb250ZW50RW5kJywgZnVuY3Rpb24gKCkge1xuICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHBsYXllci50cmlnZ2VyKCd2YXN0LnJlc2V0Jyk7XG4gICAgICB9LCAwKTtcbiAgICB9KTtcbiAgfVxuXG4gIHBsYXllci5vbigndmFzdC5maXJzdFBsYXknLCB0cnlUb1BsYXlQcmVyb2xsQWQpO1xuXG4gIHBsYXllci5vbigndmFzdC5yZXNldCcsIGZ1bmN0aW9uICgpIHtcbiAgICAvL0lmIHdlIGFyZSByZXNldGluZyB0aGUgcGx1Z2luLCB3ZSBkb24ndCB3YW50IHRvIHJlc3RvcmUgdGhlIGNvbnRlbnRcbiAgICBzbmFwc2hvdCA9IG51bGw7XG4gICAgY2FuY2VsQWRzKCk7XG4gIH0pO1xuXG4gIHBsYXllci52YXN0ID0ge1xuICAgIGlzRW5hYmxlZDogZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIHNldHRpbmdzLmFkc0VuYWJsZWQ7XG4gICAgfSxcblxuICAgIGVuYWJsZTogZnVuY3Rpb24gKCkge1xuICAgICAgc2V0dGluZ3MuYWRzRW5hYmxlZCA9IHRydWU7XG4gICAgfSxcblxuICAgIGRpc2FibGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHNldHRpbmdzLmFkc0VuYWJsZWQgPSBmYWxzZTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHBsYXllci52YXN0O1xuXG4gIC8qKioqIExvY2FsIGZ1bmN0aW9ucyAqKioqL1xuICBmdW5jdGlvbiB0cnlUb1BsYXlQcmVyb2xsQWQoKSB7XG4gICAgLy9XZSByZW1vdmUgdGhlIHBvc3RlciB0byBwcmV2ZW50IGZsaWNrZXJpbmcgd2hlbmV2ZXIgdGhlIGNvbnRlbnQgc3RhcnRzIHBsYXlpbmdcbiAgICBwbGF5ZXJVdGlscy5yZW1vdmVOYXRpdmVQb3N0ZXIocGxheWVyKTtcblxuICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3Zhc3QuYWRzQ2FuY2VsJywgJ3Zhc3QuYWRFbmQnXSwgZnVuY3Rpb24gKCkge1xuICAgICAgcmVtb3ZlQWRVbml0KCk7XG4gICAgICByZXN0b3JlVmlkZW9Db250ZW50KCk7XG4gICAgfSk7XG5cbiAgICBhc3luYy53YXRlcmZhbGwoW1xuICAgICAgY2hlY2tBZHNFbmFibGVkLFxuICAgICAgcHJlcGFyZVBsYXllckZvckFkLFxuICAgICAgc3RhcnRBZENhbmNlbFRpbWVvdXQsXG4gICAgICBwbGF5UHJlcm9sbEFkXG4gICAgXSwgZnVuY3Rpb24gKGVycm9yLCByZXNwb25zZSkge1xuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIHRyYWNrQWRFcnJvcihlcnJvciwgcmVzcG9uc2UpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGxheWVyLnRyaWdnZXIoJ3Zhc3QuYWRFbmQnKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cblxuICAgIGZ1bmN0aW9uIHJlbW92ZUFkVW5pdCgpIHtcbiAgICAgIGlmIChwbGF5ZXIudmFzdCAmJiBwbGF5ZXIudmFzdC5hZFVuaXQpIHtcbiAgICAgICAgcGxheWVyLnZhc3QuYWRVbml0ID0gbnVsbDsgLy9XZSByZW1vdmUgdGhlIGFkVW5pdFxuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlc3RvcmVWaWRlb0NvbnRlbnQoKSB7XG4gICAgICBzZXR1cENvbnRlbnRFdmVudHMoKTtcbiAgICAgIGlmIChzbmFwc2hvdCkge1xuICAgICAgICBwbGF5ZXJVdGlscy5yZXN0b3JlUGxheWVyU25hcHNob3QocGxheWVyLCBzbmFwc2hvdCk7XG4gICAgICAgIHNuYXBzaG90ID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXR1cENvbnRlbnRFdmVudHMoKSB7XG4gICAgICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWydwbGF5aW5nJywgJ3Zhc3QucmVzZXQnLCAndmFzdC5maXJzdFBsYXknXSwgZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBpZiAoZXZ0LnR5cGUgIT09ICdwbGF5aW5nJykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHBsYXllci50cmlnZ2VyKCd2YXN0LmNvbnRlbnRTdGFydCcpO1xuXG4gICAgICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ2VuZGVkJywgJ3Zhc3QucmVzZXQnLCAndmFzdC5maXJzdFBsYXknXSwgZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICAgIGlmIChldnQudHlwZSA9PT0gJ2VuZGVkJykge1xuICAgICAgICAgICAgcGxheWVyLnRyaWdnZXIoJ3Zhc3QuY29udGVudEVuZCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjaGVja0Fkc0VuYWJsZWQobmV4dCkge1xuICAgICAgaWYgKHNldHRpbmdzLmFkc0VuYWJsZWQpIHtcbiAgICAgICAgcmV0dXJuIG5leHQobnVsbCk7XG4gICAgICB9XG4gICAgICBuZXh0KG5ldyBWQVNURXJyb3IoJ0FkcyBhcmUgbm90IGVuYWJsZWQnKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcHJlcGFyZVBsYXllckZvckFkKG5leHQpIHtcbiAgICAgIGlmIChjYW5QbGF5UHJlcm9sbEFkKCkpIHtcbiAgICAgICAgc25hcHNob3QgPSBwbGF5ZXJVdGlscy5nZXRQbGF5ZXJTbmFwc2hvdChwbGF5ZXIpO1xuICAgICAgICBwbGF5ZXIucGF1c2UoKTtcbiAgICAgICAgYWRkU3Bpbm5lckljb24oKTtcblxuICAgICAgICBpZihwbGF5ZXIucGF1c2VkKCkpIHtcbiAgICAgICAgICBuZXh0KG51bGwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3BsYXlpbmcnXSwgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBwbGF5ZXIucGF1c2UoKTtcbiAgICAgICAgICAgIG5leHQobnVsbCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5leHQobmV3IFZBU1RFcnJvcigndmlkZW8gY29udGVudCBoYXMgYmVlbiBwbGF5aW5nIGJlZm9yZSBwcmVyb2xsIGFkJykpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNhblBsYXlQcmVyb2xsQWQoKSB7XG4gICAgICByZXR1cm4gIXV0aWxpdGllcy5pc0lQaG9uZSgpIHx8IHBsYXllci5jdXJyZW50VGltZSgpIDw9IHNldHRpbmdzLmlvc1ByZXJvbGxDYW5jZWxUaW1lb3V0O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN0YXJ0QWRDYW5jZWxUaW1lb3V0KG5leHQpIHtcbiAgICAgIHZhciBhZENhbmNlbFRpbWVvdXRJZDtcbiAgICAgIGFkc0NhbmNlbGVkID0gZmFsc2U7XG5cbiAgICAgIGFkQ2FuY2VsVGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRyYWNrQWRFcnJvcihuZXcgVkFTVEVycm9yKCd0aW1lb3V0IHdoaWxlIHdhaXRpbmcgZm9yIHRoZSB2aWRlbyB0byBzdGFydCBwbGF5aW5nJywgNDAyKSk7XG4gICAgICB9LCBzZXR0aW5ncy5hZENhbmNlbFRpbWVvdXQpO1xuXG4gICAgICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWyd2YXN0LmFkU3RhcnQnLCAndmFzdC5hZHNDYW5jZWwnXSwgY2xlYXJBZENhbmNlbFRpbWVvdXQpO1xuXG4gICAgICAvKioqIGxvY2FsIGZ1bmN0aW9ucyAqKiovXG4gICAgICBmdW5jdGlvbiBjbGVhckFkQ2FuY2VsVGltZW91dCgpIHtcbiAgICAgICAgaWYgKGFkQ2FuY2VsVGltZW91dElkKSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KGFkQ2FuY2VsVGltZW91dElkKTtcbiAgICAgICAgICBhZENhbmNlbFRpbWVvdXRJZCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbmV4dChudWxsKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhZGRTcGlubmVySWNvbigpIHtcbiAgICAgIGRvbS5hZGRDbGFzcyhwbGF5ZXIuZWwoKSwgJ3Zqcy12YXN0LWFkLWxvYWRpbmcnKTtcbiAgICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3Zhc3QuYWRTdGFydCcsICd2YXN0LmFkc0NhbmNlbCddLCByZW1vdmVTcGlubmVySWNvbik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVtb3ZlU3Bpbm5lckljb24oKSB7XG4gICAgICAvL0lNUE9SVEFOVCBOT1RFOiBXZSByZW1vdmUgdGhlIHNwaW5uZXJJY29uIGFzeW5jaHJvbm91c2x5IHRvIGdpdmUgdGltZSB0byB0aGUgYnJvd3NlciB0byBzdGFydCB0aGUgdmlkZW8uXG4gICAgICAvLyBJZiB3ZSByZW1vdmUgaXQgc3luY2hyb25vdXNseSB3ZSBzZWUgYSBmbGFzaCBvZiB0aGUgY29udGVudCB2aWRlbyBiZWZvcmUgdGhlIGFkIHN0YXJ0cyBwbGF5aW5nLlxuICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRvbS5yZW1vdmVDbGFzcyhwbGF5ZXIuZWwoKSwgJ3Zqcy12YXN0LWFkLWxvYWRpbmcnKTtcbiAgICAgIH0sIDEwMCk7XG4gICAgfVxuXG4gIH1cblxuICBmdW5jdGlvbiBjYW5jZWxBZHMoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3Zhc3QuYWRzQ2FuY2VsJyk7XG4gICAgYWRzQ2FuY2VsZWQgPSB0cnVlO1xuICB9XG5cbiAgZnVuY3Rpb24gcGxheVByZXJvbGxBZChjYWxsYmFjaykge1xuICAgIGFzeW5jLndhdGVyZmFsbChbXG4gICAgICBnZXRWYXN0UmVzcG9uc2UsXG4gICAgICBwbGF5QWRcbiAgICBdLCBjYWxsYmFjayk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRWYXN0UmVzcG9uc2UoY2FsbGJhY2spIHtcbiAgICB2YXN0LmdldFZBU1RSZXNwb25zZShzZXR0aW5ncy5hZFRhZ1VybCA/IHNldHRpbmdzLmFkVGFnVXJsKCkgOiBzZXR0aW5ncy5hZFRhZ1hNTCwgY2FsbGJhY2spO1xuICB9XG5cbiAgZnVuY3Rpb24gcGxheUFkKHZhc3RSZXNwb25zZSwgY2FsbGJhY2spIHtcbiAgICAvL1RPRE86IEZpbmQgYSBiZXR0ZXIgd2F5IHRvIHN0b3AgdGhlIHBsYXkuIFRoZSAncGxheVByZXJvbGxXYXRlcmZhbGwnIGVuZHMgaW4gYW4gaW5jb25zaXN0ZW50IHNpdHVhdGlvblxuICAgIC8vSWYgdGhlIHN0YXRlIGlzIG5vdCAncHJlcm9sbD8nIGl0IG1lYW5zIHRoZSBhZHMgd2VyZSBjYW5jZWxlZCB0aGVyZWZvcmUsIHdlIGJyZWFrIHRoZSB3YXRlcmZhbGxcbiAgICBpZiAoYWRzQ2FuY2VsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgYWRJbnRlZ3JhdG9yID0gaXNWUEFJRCh2YXN0UmVzcG9uc2UpID8gbmV3IFZQQUlESW50ZWdyYXRvcihwbGF5ZXIsIHNldHRpbmdzKSA6IG5ldyBWQVNUSW50ZWdyYXRvcihwbGF5ZXIpO1xuICAgIHZhciBhZEZpbmlzaGVkID0gZmFsc2U7XG5cbiAgICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWyd2YXN0LmFkU3RhcnQnLCAndmFzdC5hZHNDYW5jZWwnXSwgZnVuY3Rpb24gKGV2dCkge1xuICAgICAgaWYgKGV2dC50eXBlID09PSAndmFzdC5hZFN0YXJ0Jykge1xuICAgICAgICBhZGRBZHNMYWJlbCgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsndmFzdC5hZEVuZCcsICd2YXN0LmFkc0NhbmNlbCddLCByZW1vdmVBZHNMYWJlbCk7XG5cbiAgICBpZiAodXRpbGl0aWVzLmlzSURldmljZSgpKSB7XG4gICAgICBwcmV2ZW50TWFudWFsUHJvZ3Jlc3MoKTtcbiAgICB9XG5cbiAgICBwbGF5ZXIudmFzdC52YXN0UmVzcG9uc2UgPSB2YXN0UmVzcG9uc2U7XG4gICAgcGxheWVyLnZhc3QuYWRVbml0ID0gYWRJbnRlZ3JhdG9yLnBsYXlBZCh2YXN0UmVzcG9uc2UsIGNhbGxiYWNrKTtcblxuICAgIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKiovXG4gICAgZnVuY3Rpb24gYWRkQWRzTGFiZWwoKSB7XG4gICAgICBpZiAoYWRGaW5pc2hlZCB8fCBwbGF5ZXIuY29udHJvbEJhci5nZXRDaGlsZCgnQWRzTGFiZWwnKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHBsYXllci5jb250cm9sQmFyLmFkZENoaWxkKCdBZHNMYWJlbCcpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlbW92ZUFkc0xhYmVsKCkge1xuICAgICAgcGxheWVyLmNvbnRyb2xCYXIucmVtb3ZlQ2hpbGQoJ0Fkc0xhYmVsJyk7XG4gICAgICBhZEZpbmlzaGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmV2ZW50TWFudWFsUHJvZ3Jlc3MoKSB7XG4gICAgICAvL0lPUyB2aWRlbyBjbG9jayBpcyB2ZXJ5IHVucmVsaWFibGUgYW5kIHdlIG5lZWQgYSAzIHNlY29uZHMgdGhyZXNob2xkIHRvIGVuc3VyZSB0aGF0IHRoZSB1c2VyIGZvcndhcmRlZC9yZXdvdW5kIHRoZSBhZFxuICAgICAgdmFyIFBST0dSRVNTX1RIUkVTSE9MRCA9IDM7XG4gICAgICB2YXIgcHJldmlvdXNUaW1lID0gMDtcbiAgICAgIHZhciBza2lwYWRfYXR0ZW1wdHMgPSAwO1xuXG4gICAgICBwbGF5ZXIub24oJ3RpbWV1cGRhdGUnLCBwcmV2ZW50QWRTZWVrKTtcbiAgICAgIHBsYXllci5vbignZW5kZWQnLCBwcmV2ZW50QWRTa2lwKTtcblxuICAgICAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsndmFzdC5hZEVuZCcsICd2YXN0LmFkc0NhbmNlbCcsICd2YXN0LmFkRXJyb3InXSwgc3RvcFByZXZlbnRNYW51YWxQcm9ncmVzcyk7XG5cbiAgICAgIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgICAgIGZ1bmN0aW9uIHByZXZlbnRBZFNraXAoKSB7XG4gICAgICAgIC8vIElnbm9yZSBlbmRlZCBldmVudCBpZiB0aGUgQWQgdGltZSB3YXMgbm90ICduZWFyJyB0aGUgZW5kXG4gICAgICAgIC8vIGFuZCByZXZlcnQgdGltZSB0byB0aGUgcHJldmlvdXMgJ3ZhbGlkJyB0aW1lXG4gICAgICAgIGlmICgocGxheWVyLmR1cmF0aW9uKCkgLSBwcmV2aW91c1RpbWUpID4gUFJPR1JFU1NfVEhSRVNIT0xEKSB7XG4gICAgICAgICAgcGxheWVyLnBhdXNlKHRydWUpOyAvLyB0aGlzIHJlZHVjZSB0aGUgdmlkZW8gaml0dGVyIGlmIHRoZSBJT1Mgc2tpcCBidXR0b24gaXMgcHJlc3NlZFxuICAgICAgICAgIHBsYXllci5wbGF5KHRydWUpOyAvLyB3ZSBuZWVkIHRvIHRyaWdnZXIgdGhlIHBsYXkgdG8gcHV0IHRoZSB2aWRlbyBlbGVtZW50IGJhY2sgaW4gYSB2YWxpZCBzdGF0ZVxuICAgICAgICAgIHBsYXllci5jdXJyZW50VGltZShwcmV2aW91c1RpbWUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIHByZXZlbnRBZFNlZWsoKSB7XG4gICAgICAgIHZhciBjdXJyZW50VGltZSA9IHBsYXllci5jdXJyZW50VGltZSgpO1xuICAgICAgICB2YXIgcHJvZ3Jlc3NEZWx0YSA9IE1hdGguYWJzKGN1cnJlbnRUaW1lIC0gcHJldmlvdXNUaW1lKTtcbiAgICAgICAgaWYgKHByb2dyZXNzRGVsdGEgPiBQUk9HUkVTU19USFJFU0hPTEQpIHtcbiAgICAgICAgICBza2lwYWRfYXR0ZW1wdHMgKz0gMTtcbiAgICAgICAgICBpZiAoc2tpcGFkX2F0dGVtcHRzID49IDIpIHtcbiAgICAgICAgICAgIHBsYXllci5wYXVzZSh0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcGxheWVyLmN1cnJlbnRUaW1lKHByZXZpb3VzVGltZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcHJldmlvdXNUaW1lID0gY3VycmVudFRpbWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gc3RvcFByZXZlbnRNYW51YWxQcm9ncmVzcygpIHtcbiAgICAgICAgcGxheWVyLm9mZigndGltZXVwZGF0ZScsIHByZXZlbnRBZFNlZWspO1xuICAgICAgICBwbGF5ZXIub2ZmKCdlbmRlZCcsIHByZXZlbnRBZFNraXApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYWNrQWRFcnJvcihlcnJvciwgdmFzdFJlc3BvbnNlKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoe3R5cGU6ICd2YXN0LmFkRXJyb3InLCBlcnJvcjogZXJyb3J9KTtcbiAgICBjYW5jZWxBZHMoKTtcbiAgICBpZiAoY29uc29sZSAmJiBjb25zb2xlLmxvZykge1xuICAgICAgY29uc29sZS5sb2coJ0FEIEVSUk9SOicsIGVycm9yLm1lc3NhZ2UsIGVycm9yLCB2YXN0UmVzcG9uc2UpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGlzVlBBSUQodmFzdFJlc3BvbnNlKSB7XG4gICAgdmFyIGksIGxlbjtcbiAgICB2YXIgbWVkaWFGaWxlcyA9IHZhc3RSZXNwb25zZS5tZWRpYUZpbGVzO1xuICAgIGZvciAoaSA9IDAsIGxlbiA9IG1lZGlhRmlsZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGlmICh2YXN0VXRpbC5pc1ZQQUlEKG1lZGlhRmlsZXNbaV0pKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG4iLCIvL1NtYWxsIHN1YnNldCBvZiBhc3luY1xuXG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbnZhciBhc3luYyA9IHt9O1xuXG5hc3luYy5zZXRJbW1lZGlhdGUgPSBmdW5jdGlvbiAoZm4pIHtcbiAgc2V0VGltZW91dChmbiwgMCk7XG59O1xuXG5hc3luYy5pdGVyYXRvciA9IGZ1bmN0aW9uICh0YXNrcykge1xuICB2YXIgbWFrZUNhbGxiYWNrID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgdmFyIGZuID0gZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHRhc2tzLmxlbmd0aCkge1xuICAgICAgICB0YXNrc1tpbmRleF0uYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmbi5uZXh0KCk7XG4gICAgfTtcbiAgICBmbi5uZXh0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIChpbmRleCA8IHRhc2tzLmxlbmd0aCAtIDEpID8gbWFrZUNhbGxiYWNrKGluZGV4ICsgMSkgOiBudWxsO1xuICAgIH07XG4gICAgcmV0dXJuIGZuO1xuICB9O1xuICByZXR1cm4gbWFrZUNhbGxiYWNrKDApO1xufTtcblxuXG5hc3luYy53YXRlcmZhbGwgPSBmdW5jdGlvbiAodGFza3MsIGNhbGxiYWNrKSB7XG4gIGNhbGxiYWNrID0gY2FsbGJhY2sgfHwgZnVuY3Rpb24gKCkgeyB9O1xuICBpZiAoIXV0aWxpdGllcy5pc0FycmF5KHRhc2tzKSkge1xuICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IHRvIHdhdGVyZmFsbCBtdXN0IGJlIGFuIGFycmF5IG9mIGZ1bmN0aW9ucycpO1xuICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICB9XG4gIGlmICghdGFza3MubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gIH1cbiAgdmFyIHdyYXBJdGVyYXRvciA9IGZ1bmN0aW9uIChpdGVyYXRvcikge1xuICAgIHJldHVybiBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIGNhbGxiYWNrLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gICAgICAgIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgdmFyIG5leHQgPSBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgIGlmIChuZXh0KSB7XG4gICAgICAgICAgYXJncy5wdXNoKHdyYXBJdGVyYXRvcihuZXh0KSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgYXJncy5wdXNoKGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgICAgICBhc3luYy5zZXRJbW1lZGlhdGUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGl0ZXJhdG9yLmFwcGx5KG51bGwsIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9O1xuICB9O1xuICB3cmFwSXRlcmF0b3IoYXN5bmMuaXRlcmF0b3IodGFza3MpKSgpO1xufTtcblxuYXN5bmMud2hlbiA9IGZ1bmN0aW9uIChjb25kaXRpb24sIGNhbGxiYWNrKSB7XG4gIGlmICghdXRpbGl0aWVzLmlzRnVuY3Rpb24oY2FsbGJhY2spKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiYXN5bmMud2hlbiBlcnJvcjogbWlzc2luZyBjYWxsYmFjayBhcmd1bWVudFwiKTtcbiAgfVxuXG4gIHZhciBpc0FsbG93ZWQgPSB1dGlsaXRpZXMuaXNGdW5jdGlvbihjb25kaXRpb24pID8gY29uZGl0aW9uIDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAhIWNvbmRpdGlvbjtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhcmdzID0gdXRpbGl0aWVzLmFycmF5TGlrZU9ialRvQXJyYXkoYXJndW1lbnRzKTtcbiAgICB2YXIgbmV4dCA9IGFyZ3MucG9wKCk7XG5cbiAgICBpZiAoaXNBbGxvd2VkLmFwcGx5KG51bGwsIGFyZ3MpKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2suYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBhcmdzLnVuc2hpZnQobnVsbCk7XG4gICAgcmV0dXJuIG5leHQuYXBwbHkobnVsbCwgYXJncyk7XG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGFzeW5jO1xuXG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxudmFyIGRvbSA9IHt9O1xuXG5kb20uaXNWaXNpYmxlID0gZnVuY3Rpb24gaXNWaXNpYmxlKGVsKSB7XG4gIHZhciBzdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsKTtcbiAgcmV0dXJuIHN0eWxlLnZpc2liaWxpdHkgIT09ICdoaWRkZW4nO1xufTtcblxuZG9tLmlzSGlkZGVuID0gZnVuY3Rpb24gaXNIaWRkZW4oZWwpIHtcbiAgdmFyIHN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWwpO1xuICByZXR1cm4gc3R5bGUuZGlzcGxheSA9PT0gJ25vbmUnO1xufTtcblxuZG9tLmlzU2hvd24gPSBmdW5jdGlvbiBpc1Nob3duKGVsKSB7XG4gIHJldHVybiAhZG9tLmlzSGlkZGVuKGVsKTtcbn07XG5cbmRvbS5oaWRlID0gZnVuY3Rpb24gaGlkZShlbCkge1xuICBlbC5fX3ByZXZfc3R5bGVfZGlzcGxheV8gPSBlbC5zdHlsZS5kaXNwbGF5O1xuICBlbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xufTtcblxuZG9tLnNob3cgPSBmdW5jdGlvbiBzaG93KGVsKSB7XG4gIGlmIChkb20uaXNIaWRkZW4oZWwpKSB7XG4gICAgZWwuc3R5bGUuZGlzcGxheSA9IGVsLl9fcHJldl9zdHlsZV9kaXNwbGF5XztcbiAgfVxuICBlbC5fX3ByZXZfc3R5bGVfZGlzcGxheV8gPSB1bmRlZmluZWQ7XG59O1xuXG5kb20uaGFzQ2xhc3MgPSBmdW5jdGlvbiBoYXNDbGFzcyhlbCwgY3NzQ2xhc3MpIHtcbiAgdmFyIGNsYXNzZXMsIGksIGxlbjtcblxuICBpZiAodXRpbGl0aWVzLmlzTm90RW1wdHlTdHJpbmcoY3NzQ2xhc3MpKSB7XG4gICAgaWYgKGVsLmNsYXNzTGlzdCkge1xuICAgICAgcmV0dXJuIGVsLmNsYXNzTGlzdC5jb250YWlucyhjc3NDbGFzcyk7XG4gICAgfVxuXG4gICAgY2xhc3NlcyA9IHV0aWxpdGllcy5pc1N0cmluZyhlbC5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykpID8gZWwuZ2V0QXR0cmlidXRlKCdjbGFzcycpLnNwbGl0KC9cXHMrLykgOiBbXTtcbiAgICBjc3NDbGFzcyA9IChjc3NDbGFzcyB8fCAnJyk7XG5cbiAgICBmb3IgKGkgPSAwLCBsZW4gPSBjbGFzc2VzLmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKSB7XG4gICAgICBpZiAoY2xhc3Nlc1tpXSA9PT0gY3NzQ2xhc3MpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn07XG5cbmRvbS5hZGRDbGFzcyA9IGZ1bmN0aW9uIChlbCwgY3NzQ2xhc3MpIHtcbiAgdmFyIGNsYXNzZXM7XG5cbiAgaWYgKHV0aWxpdGllcy5pc05vdEVtcHR5U3RyaW5nKGNzc0NsYXNzKSkge1xuICAgIGlmIChlbC5jbGFzc0xpc3QpIHtcbiAgICAgIHJldHVybiBlbC5jbGFzc0xpc3QuYWRkKGNzc0NsYXNzKTtcbiAgICB9XG5cbiAgICBjbGFzc2VzID0gdXRpbGl0aWVzLmlzU3RyaW5nKGVsLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSkgPyBlbC5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykuc3BsaXQoL1xccysvKSA6IFtdO1xuICAgIGlmICh1dGlsaXRpZXMuaXNTdHJpbmcoY3NzQ2xhc3MpICYmIHV0aWxpdGllcy5pc05vdEVtcHR5U3RyaW5nKGNzc0NsYXNzLnJlcGxhY2UoL1xccysvLCAnJykpKSB7XG4gICAgICBjbGFzc2VzLnB1c2goY3NzQ2xhc3MpO1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCdjbGFzcycsIGNsYXNzZXMuam9pbignICcpKTtcbiAgICB9XG4gIH1cbn07XG5cbmRvbS5yZW1vdmVDbGFzcyA9IGZ1bmN0aW9uIChlbCwgY3NzQ2xhc3MpIHtcbiAgdmFyIGNsYXNzZXM7XG5cbiAgaWYgKHV0aWxpdGllcy5pc05vdEVtcHR5U3RyaW5nKGNzc0NsYXNzKSkge1xuICAgIGlmIChlbC5jbGFzc0xpc3QpIHtcbiAgICAgIHJldHVybiBlbC5jbGFzc0xpc3QucmVtb3ZlKGNzc0NsYXNzKTtcbiAgICB9XG5cbiAgICBjbGFzc2VzID0gdXRpbGl0aWVzLmlzU3RyaW5nKGVsLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSkgPyBlbC5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykuc3BsaXQoL1xccysvKSA6IFtdO1xuICAgIHZhciBuZXdDbGFzc2VzID0gW107XG4gICAgdmFyIGksIGxlbjtcbiAgICBpZiAodXRpbGl0aWVzLmlzU3RyaW5nKGNzc0NsYXNzKSAmJiB1dGlsaXRpZXMuaXNOb3RFbXB0eVN0cmluZyhjc3NDbGFzcy5yZXBsYWNlKC9cXHMrLywgJycpKSkge1xuXG4gICAgICBmb3IgKGkgPSAwLCBsZW4gPSBjbGFzc2VzLmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKSB7XG4gICAgICAgIGlmIChjc3NDbGFzcyAhPT0gY2xhc3Nlc1tpXSkge1xuICAgICAgICAgIG5ld0NsYXNzZXMucHVzaChjbGFzc2VzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZWwuc2V0QXR0cmlidXRlKCdjbGFzcycsIG5ld0NsYXNzZXMuam9pbignICcpKTtcbiAgICB9XG4gIH1cbn07XG5cbmRvbS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gYWRkRXZlbnRMaXN0ZW5lcihlbCwgdHlwZSwgaGFuZGxlcikge1xuICBpZih1dGlsaXRpZXMuaXNBcnJheShlbCkpe1xuICAgIHV0aWxpdGllcy5mb3JFYWNoKGVsLCBmdW5jdGlvbihlKSB7XG4gICAgICBkb20uYWRkRXZlbnRMaXN0ZW5lcihlLCB0eXBlLCBoYW5kbGVyKTtcbiAgICB9KTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZih1dGlsaXRpZXMuaXNBcnJheSh0eXBlKSl7XG4gICAgdXRpbGl0aWVzLmZvckVhY2godHlwZSwgZnVuY3Rpb24odCkge1xuICAgICAgZG9tLmFkZEV2ZW50TGlzdGVuZXIoZWwsIHQsIGhhbmRsZXIpO1xuICAgIH0pO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChlbC5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgZWwuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBoYW5kbGVyLCBmYWxzZSk7XG4gIH0gZWxzZSBpZiAoZWwuYXR0YWNoRXZlbnQpIHtcbiAgICAvLyBXQVJOSU5HISEhIHRoaXMgaXMgYSB2ZXJ5IG5haXZlIGltcGxlbWVudGF0aW9uICFcbiAgICAvLyB0aGUgZXZlbnQgb2JqZWN0IHRoYXQgc2hvdWxkIGJlIHBhc3NlZCB0byB0aGUgaGFuZGxlclxuICAgIC8vIHdvdWxkIG5vdCBiZSB0aGVyZSBmb3IgSUU4XG4gICAgLy8gd2Ugc2hvdWxkIHVzZSBcIndpbmRvdy5ldmVudFwiIGFuZCB0aGVuIFwiZXZlbnQuc3JjRWxlbWVudFwiXG4gICAgLy8gaW5zdGVhZCBvZiBcImV2ZW50LnRhcmdldFwiXG4gICAgZWwuYXR0YWNoRXZlbnQoXCJvblwiICsgdHlwZSwgaGFuZGxlcik7XG4gIH1cbn07XG5cbmRvbS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gcmVtb3ZlRXZlbnRMaXN0ZW5lcihlbCwgdHlwZSwgaGFuZGxlcikge1xuICBpZih1dGlsaXRpZXMuaXNBcnJheShlbCkpe1xuICAgIHV0aWxpdGllcy5mb3JFYWNoKGVsLCBmdW5jdGlvbihlKSB7XG4gICAgICBkb20ucmVtb3ZlRXZlbnRMaXN0ZW5lcihlLCB0eXBlLCBoYW5kbGVyKTtcbiAgICB9KTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZih1dGlsaXRpZXMuaXNBcnJheSh0eXBlKSl7XG4gICAgdXRpbGl0aWVzLmZvckVhY2godHlwZSwgZnVuY3Rpb24odCkge1xuICAgICAgZG9tLnJlbW92ZUV2ZW50TGlzdGVuZXIoZWwsIHQsIGhhbmRsZXIpO1xuICAgIH0pO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChlbC5yZW1vdmVFdmVudExpc3RlbmVyKSB7XG4gICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBoYW5kbGVyLCBmYWxzZSk7XG4gIH0gZWxzZSBpZiAoZWwuZGV0YWNoRXZlbnQpIHtcbiAgICBlbC5kZXRhY2hFdmVudChcIm9uXCIgKyB0eXBlLCBoYW5kbGVyKTtcbiAgfSBlbHNlIHtcbiAgICBlbFtcIm9uXCIgKyB0eXBlXSA9IG51bGw7XG4gIH1cbn07XG5cbmRvbS5kaXNwYXRjaEV2ZW50ID0gZnVuY3Rpb24gZGlzcGF0Y2hFdmVudChlbCwgZXZlbnQpIHtcbiAgaWYgKGVsLmRpc3BhdGNoRXZlbnQpIHtcbiAgICBlbC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgfSBlbHNlIHtcbiAgICBlbC5maXJlRXZlbnQoXCJvblwiICsgZXZlbnQuZXZlbnRUeXBlLCBldmVudCk7XG4gIH1cbn07XG5cbmRvbS5pc0Rlc2NlbmRhbnQgPSBmdW5jdGlvbiBpc0Rlc2NlbmRhbnQocGFyZW50LCBjaGlsZCkge1xuICB2YXIgbm9kZSA9IGNoaWxkLnBhcmVudE5vZGU7XG4gIHdoaWxlIChub2RlICE9PSBudWxsKSB7XG4gICAgaWYgKG5vZGUgPT09IHBhcmVudCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuZG9tLmdldFRleHRDb250ZW50ID0gZnVuY3Rpb24gZ2V0VGV4dENvbnRlbnQoZWwpe1xuICByZXR1cm4gZWwudGV4dENvbnRlbnQgfHwgZWwudGV4dDtcbn07XG5cbmRvbS5wcmVwZW5kQ2hpbGQgPSBmdW5jdGlvbiBwcmVwZW5kQ2hpbGQocGFyZW50LCBjaGlsZCkge1xuICBpZihjaGlsZC5wYXJlbnROb2RlKXtcbiAgICBjaGlsZC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGNoaWxkKTtcbiAgfVxuICByZXR1cm4gcGFyZW50Lmluc2VydEJlZm9yZShjaGlsZCwgcGFyZW50LmZpcnN0Q2hpbGQpO1xufTtcblxuZG9tLnJlbW92ZSA9IGZ1bmN0aW9uIHJlbW92ZU5vZGUobm9kZSl7XG4gIGlmKG5vZGUgJiYgbm9kZS5wYXJlbnROb2RlKXtcbiAgICBub2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobm9kZSk7XG4gIH1cbn07XG5cbmRvbS5pc0RvbUVsZW1lbnQgPSBmdW5jdGlvbiBpc0RvbUVsZW1lbnQobykge1xuICByZXR1cm4gbyBpbnN0YW5jZW9mIEVsZW1lbnQ7XG59O1xuXG5kb20uY2xpY2sgPSBmdW5jdGlvbihlbCwgaGFuZGxlcikge1xuICBkb20uYWRkRXZlbnRMaXN0ZW5lcihlbCwgJ2NsaWNrJywgaGFuZGxlcik7XG59O1xuXG5kb20ub25jZSA9IGZ1bmN0aW9uKGVsLCB0eXBlLCBoYW5kbGVyKSB7XG4gIGZ1bmN0aW9uIGhhbmRsZXJXcmFwKCkge1xuICAgIGhhbmRsZXIuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICBkb20ucmVtb3ZlRXZlbnRMaXN0ZW5lcihlbCwgdHlwZSwgaGFuZGxlcldyYXApO1xuICB9XG5cbiAgZG9tLmFkZEV2ZW50TGlzdGVuZXIoZWwsIHR5cGUsIGhhbmRsZXJXcmFwKTtcbn07XG5cbi8vTm90ZTogdGhlcmUgaXMgbm8gZ2V0Qm91bmRpbmdDbGllbnRSZWN0IG9uIGlQYWQgc28gd2UgbmVlZCBhIGZhbGxiYWNrXG5kb20uZ2V0RGltZW5zaW9uID0gZnVuY3Rpb24gZ2V0RGltZW5zaW9uKGVsZW1lbnQpIHtcbiAgdmFyIHJlY3Q7XG5cbiAgLy9PbiBJRTkgYW5kIGJlbG93IGdldEJvdW5kaW5nQ2xpZW50UmVjdCBkb2VzIG5vdCB3b3JrIGNvbnNpc3RlbnRseVxuICBpZighdXRpbGl0aWVzLmlzT2xkSUUoKSAmJiBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCkge1xuICAgIHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHJldHVybiB7XG4gICAgICB3aWR0aDogcmVjdC53aWR0aCxcbiAgICAgIGhlaWdodDogcmVjdC5oZWlnaHRcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB3aWR0aDogZWxlbWVudC5vZmZzZXRXaWR0aCxcbiAgICBoZWlnaHQ6IGVsZW1lbnQub2Zmc2V0SGVpZ2h0XG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRvbTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciB1cmxVdGlscyA9IHJlcXVpcmUoJy4vdXJsVXRpbHMnKTtcbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxuZnVuY3Rpb24gSHR0cFJlcXVlc3RFcnJvcihtZXNzYWdlKSB7XG4gIHRoaXMubWVzc2FnZSA9ICdIdHRwUmVxdWVzdCBFcnJvcjogJyArIChtZXNzYWdlIHx8ICcnKTtcbn1cbkh0dHBSZXF1ZXN0RXJyb3IucHJvdG90eXBlID0gbmV3IEVycm9yKCk7XG5IdHRwUmVxdWVzdEVycm9yLnByb3RvdHlwZS5uYW1lID0gXCJIdHRwUmVxdWVzdCBFcnJvclwiO1xuXG5mdW5jdGlvbiBIdHRwUmVxdWVzdChjcmVhdGVYaHIpIHtcbiAgaWYgKCF1dGlsaXRpZXMuaXNGdW5jdGlvbihjcmVhdGVYaHIpKSB7XG4gICAgdGhyb3cgbmV3IEh0dHBSZXF1ZXN0RXJyb3IoJ01pc3NpbmcgWE1MSHR0cFJlcXVlc3QgZmFjdG9yeSBtZXRob2QnKTtcbiAgfVxuXG4gIHRoaXMuY3JlYXRlWGhyID0gY3JlYXRlWGhyO1xufVxuXG5IdHRwUmVxdWVzdC5wcm90b3R5cGUucnVuID0gZnVuY3Rpb24gKG1ldGhvZCwgdXJsLCBjYWxsYmFjaywgb3B0aW9ucykge1xuICBzYW5pdHlDaGVjayh1cmwsIGNhbGxiYWNrLCBvcHRpb25zKTtcbiAgdmFyIHRpbWVvdXQsIHRpbWVvdXRJZDtcbiAgdmFyIHhociA9IHRoaXMuY3JlYXRlWGhyKCk7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICB0aW1lb3V0ID0gdXRpbGl0aWVzLmlzTnVtYmVyKG9wdGlvbnMudGltZW91dCkgPyBvcHRpb25zLnRpbWVvdXQgOiAwO1xuXG4gIHhoci5vcGVuKG1ldGhvZCwgdXJsVXRpbHMudXJsUGFydHModXJsKS5ocmVmLCB0cnVlKTtcblxuICBpZiAob3B0aW9ucy5oZWFkZXJzKSB7XG4gICAgc2V0SGVhZGVycyh4aHIsIG9wdGlvbnMuaGVhZGVycyk7XG4gIH1cblxuICBpZiAob3B0aW9ucy53aXRoQ3JlZGVudGlhbHMpIHtcbiAgICB4aHIud2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcbiAgfVxuXG4gIHhoci5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHN0YXR1c1RleHQsIHJlc3BvbnNlLCBzdGF0dXM7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb25seSB3YXkgdG8gZG8gYSBzZWN1cmUgcmVxdWVzdCBvbiBJRTggYW5kIElFOSBpcyB3aXRoIHRoZSBYRG9tYWluUmVxdWVzdCBvYmplY3QuIFVuZm9ydHVuYXRlbHksIG1pY3Jvc29mdCBpc1xuICAgICAqIHNvIG5pY2UgdGhhdCBkZWNpZGVkIHRoYXQgdGhlIHN0YXR1cyBwcm9wZXJ0eSBhbmQgdGhlICdnZXRBbGxSZXNwb25zZUhlYWRlcnMnIG1ldGhvZCB3aGVyZSBub3QgbmVlZGVkIHNvIHdlIGhhdmUgdG9cbiAgICAgKiBmYWtlIHRoZW0uIElmIHRoZSByZXF1ZXN0IGdldHMgZG9uZSB3aXRoIGFuIFhEb21haW5SZXF1ZXN0IGluc3RhbmNlLCB3ZSB3aWxsIGFzc3VtZSB0aGF0IHRoZXJlIGFyZSBubyBoZWFkZXJzIGFuZFxuICAgICAqIHRoZSBzdGF0dXMgd2lsbCBhbHdheXMgYmUgMjAwLiBJZiB5b3UgZG9uJ3QgbGlrZSBpdCwgRE8gTk9UIFVTRSBBTkNJRU5UIEJST1dTRVJTISEhXG4gICAgICpcbiAgICAgKiBGb3IgbW9yIGluZm8gZ28gdG86IGh0dHBzOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvY2MyODgwNjAodj12cy44NSkuYXNweFxuICAgICAqL1xuICAgIGlmICgheGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycykge1xuICAgICAgeGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICgheGhyLnN0YXR1cykge1xuICAgICAgeGhyLnN0YXR1cyA9IDIwMDtcbiAgICB9XG5cbiAgICBpZiAodXRpbGl0aWVzLmlzRGVmaW5lZCh0aW1lb3V0SWQpKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgIHRpbWVvdXRJZCA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBzdGF0dXNUZXh0ID0geGhyLnN0YXR1c1RleHQgfHwgJyc7XG5cbiAgICAvLyByZXNwb25zZVRleHQgaXMgdGhlIG9sZC1zY2hvb2wgd2F5IG9mIHJldHJpZXZpbmcgcmVzcG9uc2UgKHN1cHBvcnRlZCBieSBJRTggJiA5KVxuICAgIC8vIHJlc3BvbnNlL3Jlc3BvbnNlVHlwZSBwcm9wZXJ0aWVzIHdlcmUgaW50cm9kdWNlZCBpbiBYSFIgTGV2ZWwyIHNwZWMgKHN1cHBvcnRlZCBieSBJRTEwKVxuICAgIHJlc3BvbnNlID0gKCdyZXNwb25zZScgaW4geGhyKSA/IHhoci5yZXNwb25zZSA6IHhoci5yZXNwb25zZVRleHQ7XG5cbiAgICAvLyBub3JtYWxpemUgSUU5IGJ1ZyAoaHR0cDovL2J1Z3MuanF1ZXJ5LmNvbS90aWNrZXQvMTQ1MClcbiAgICBzdGF0dXMgPSB4aHIuc3RhdHVzID09PSAxMjIzID8gMjA0IDogeGhyLnN0YXR1cztcblxuICAgIGNhbGxiYWNrKFxuICAgICAgc3RhdHVzLFxuICAgICAgcmVzcG9uc2UsXG4gICAgICB4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCksXG4gICAgICBzdGF0dXNUZXh0KTtcbiAgfTtcblxuICB4aHIub25lcnJvciA9IHJlcXVlc3RFcnJvcjtcbiAgeGhyLm9uYWJvcnQgPSByZXF1ZXN0RXJyb3I7XG5cbiAgeGhyLnNlbmQoKTtcblxuICBpZiAodGltZW91dCA+IDApIHtcbiAgICB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHhociAmJiB4aHIuYWJvcnQoKTtcbiAgICB9LCB0aW1lb3V0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNhbml0eUNoZWNrKHVybCwgY2FsbGJhY2ssIG9wdGlvbnMpIHtcbiAgICBpZiAoIXV0aWxpdGllcy5pc1N0cmluZyh1cmwpIHx8IHV0aWxpdGllcy5pc0VtcHR5U3RyaW5nKHVybCkpIHtcbiAgICAgIHRocm93IG5ldyBIdHRwUmVxdWVzdEVycm9yKFwiSW52YWxpZCB1cmwgJ1wiICsgdXJsICsgXCInXCIpO1xuICAgIH1cblxuICAgIGlmICghdXRpbGl0aWVzLmlzRnVuY3Rpb24oY2FsbGJhY2spKSB7XG4gICAgICB0aHJvdyBuZXcgSHR0cFJlcXVlc3RFcnJvcihcIkludmFsaWQgaGFuZGxlciAnXCIgKyBjYWxsYmFjayArIFwiJyBmb3IgdGhlIGh0dHAgcmVxdWVzdFwiKTtcbiAgICB9XG5cbiAgICBpZiAodXRpbGl0aWVzLmlzRGVmaW5lZChvcHRpb25zKSAmJiAhdXRpbGl0aWVzLmlzT2JqZWN0KG9wdGlvbnMpKSB7XG4gICAgICB0aHJvdyBuZXcgSHR0cFJlcXVlc3RFcnJvcihcIkludmFsaWQgb3B0aW9ucyBtYXAgJ1wiICsgb3B0aW9ucyArIFwiJ1wiKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBzZXRIZWFkZXJzKHhociwgaGVhZGVycykge1xuICAgIHV0aWxpdGllcy5mb3JFYWNoKGhlYWRlcnMsIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICBpZiAodXRpbGl0aWVzLmlzRGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoa2V5LCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiByZXF1ZXN0RXJyb3IoKSB7XG4gICAgY2FsbGJhY2soLTEsIG51bGwsIG51bGwsICcnKTtcbiAgfVxufTtcblxuSHR0cFJlcXVlc3QucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uICh1cmwsIGNhbGxiYWNrLCBvcHRpb25zKSB7XG4gIHRoaXMucnVuKCdHRVQnLCB1cmwsIHByb2Nlc3NSZXNwb25zZSwgb3B0aW9ucyk7XG5cbiAgZnVuY3Rpb24gcHJvY2Vzc1Jlc3BvbnNlKHN0YXR1cywgcmVzcG9uc2UsIGhlYWRlcnNTdHJpbmcsIHN0YXR1c1RleHQpIHtcbiAgICBpZiAoaXNTdWNjZXNzKHN0YXR1cykpIHtcbiAgICAgIGNhbGxiYWNrKG51bGwsIHJlc3BvbnNlLCBzdGF0dXMsIGhlYWRlcnNTdHJpbmcsIHN0YXR1c1RleHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjYWxsYmFjayhuZXcgSHR0cFJlcXVlc3RFcnJvcihzdGF0dXNUZXh0KSwgcmVzcG9uc2UsIHN0YXR1cywgaGVhZGVyc1N0cmluZywgc3RhdHVzVGV4dCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaXNTdWNjZXNzKHN0YXR1cykge1xuICAgIHJldHVybiAyMDAgPD0gc3RhdHVzICYmIHN0YXR1cyA8IDMwMDtcbiAgfVxufTtcblxuZnVuY3Rpb24gY3JlYXRlWGhyKCkge1xuICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gIGlmICghKFwid2l0aENyZWRlbnRpYWxzXCIgaW4geGhyKSkge1xuICAgIC8vIFhEb21haW5SZXF1ZXN0IGZvciBJRS5cbiAgICB4aHIgPSBuZXcgWERvbWFpblJlcXVlc3QoKTtcbiAgfVxuICByZXR1cm4geGhyO1xufVxuXG52YXIgaHR0cCA9IG5ldyBIdHRwUmVxdWVzdChjcmVhdGVYaHIpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgaHR0cDogaHR0cCxcbiAgSHR0cFJlcXVlc3Q6IEh0dHBSZXF1ZXN0LFxuICBIdHRwUmVxdWVzdEVycm9yOiBIdHRwUmVxdWVzdEVycm9yLFxuICBjcmVhdGVYaHI6IGNyZWF0ZVhoclxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGRvbSA9IHJlcXVpcmUoJy4vZG9tJyk7XG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbnZhciBwbGF5ZXJVdGlscyA9IHt9O1xuXG4vKipcbiAqIFJldHVybnMgYW4gb2JqZWN0IHRoYXQgY2FwdHVyZXMgdGhlIHBvcnRpb25zIG9mIHBsYXllciBzdGF0ZSByZWxldmFudCB0b1xuICogdmlkZW8gcGxheWJhY2suIFRoZSByZXN1bHQgb2YgdGhpcyBmdW5jdGlvbiBjYW4gYmUgcGFzc2VkIHRvXG4gKiByZXN0b3JlUGxheWVyU25hcHNob3Qgd2l0aCBhIHBsYXllciB0byByZXR1cm4gdGhlIHBsYXllciB0byB0aGUgc3RhdGUgaXRcbiAqIHdhcyBpbiB3aGVuIHRoaXMgZnVuY3Rpb24gd2FzIGludm9rZWQuXG4gKiBAcGFyYW0ge29iamVjdH0gcGxheWVyIFRoZSB2aWRlb2pzIHBsYXllciBvYmplY3RcbiAqL1xucGxheWVyVXRpbHMuZ2V0UGxheWVyU25hcHNob3QgPSBmdW5jdGlvbiBnZXRQbGF5ZXJTbmFwc2hvdChwbGF5ZXIpIHtcbiAgdmFyIHRlY2ggPSBwbGF5ZXIuZWwoKS5xdWVyeVNlbGVjdG9yKCcudmpzLXRlY2gnKTtcblxuICB2YXIgc25hcHNob3QgPSB7XG4gICAgZW5kZWQ6IHBsYXllci5lbmRlZCgpLFxuICAgIHNyYzogcGxheWVyLmN1cnJlbnRTcmMoKSxcbiAgICBjdXJyZW50VGltZTogcGxheWVyLmN1cnJlbnRUaW1lKCksXG4gICAgdHlwZTogcGxheWVyLmN1cnJlbnRUeXBlKCksXG4gICAgcGxheWluZzogIXBsYXllci5wYXVzZWQoKSxcbiAgICBzdXBwcmVzc2VkVHJhY2tzOiBnZXRTdXBwcmVzc2VkVHJhY2tzKHBsYXllcilcbiAgfTtcblxuICBpZiAodGVjaCkge1xuICAgIHNuYXBzaG90Lm5hdGl2ZVBvc3RlciA9IHRlY2gucG9zdGVyO1xuICAgIHNuYXBzaG90LnN0eWxlID0gdGVjaC5nZXRBdHRyaWJ1dGUoJ3N0eWxlJyk7XG4gIH1cbiAgcmV0dXJuIHNuYXBzaG90O1xuXG4gIC8qKioqIExvY2FsIEZ1bmN0aW9ucyAqKioqL1xuICBmdW5jdGlvbiBnZXRTdXBwcmVzc2VkVHJhY2tzKHBsYXllcikge1xuICAgIHZhciB0cmFja3MgPSBwbGF5ZXIucmVtb3RlVGV4dFRyYWNrcyA/IHBsYXllci5yZW1vdGVUZXh0VHJhY2tzKCkgOiBbXTtcblxuICAgIGlmICh0cmFja3MgJiYgdXRpbGl0aWVzLmlzQXJyYXkodHJhY2tzLnRyYWNrc18pKSB7XG4gICAgICB0cmFja3MgPSB0cmFja3MudHJhY2tzXztcbiAgICB9XG5cbiAgICBpZiAoIXV0aWxpdGllcy5pc0FycmF5KHRyYWNrcykpIHtcbiAgICAgIHRyYWNrcyA9IFtdO1xuICAgIH1cblxuICAgIHZhciBzdXBwcmVzc2VkVHJhY2tzID0gW107XG4gICAgdHJhY2tzLmZvckVhY2goZnVuY3Rpb24gKHRyYWNrKSB7XG4gICAgICBzdXBwcmVzc2VkVHJhY2tzLnB1c2goe1xuICAgICAgICB0cmFjazogdHJhY2ssXG4gICAgICAgIG1vZGU6IHRyYWNrLm1vZGVcbiAgICAgIH0pO1xuICAgICAgdHJhY2subW9kZSA9ICdkaXNhYmxlZCc7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc3VwcHJlc3NlZFRyYWNrcztcbiAgfVxufTtcblxuLyoqXG4gKiBBdHRlbXB0cyB0byBtb2RpZnkgdGhlIHNwZWNpZmllZCBwbGF5ZXIgc28gdGhhdCBpdHMgc3RhdGUgaXMgZXF1aXZhbGVudCB0b1xuICogdGhlIHN0YXRlIG9mIHRoZSBzbmFwc2hvdC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBzbmFwc2hvdCAtIHRoZSBwbGF5ZXIgc3RhdGUgdG8gYXBwbHlcbiAqL1xucGxheWVyVXRpbHMucmVzdG9yZVBsYXllclNuYXBzaG90ID0gZnVuY3Rpb24gcmVzdG9yZVBsYXllclNuYXBzaG90KHBsYXllciwgc25hcHNob3QpIHtcbiAgdmFyIHRlY2ggPSBwbGF5ZXIuZWwoKS5xdWVyeVNlbGVjdG9yKCcudmpzLXRlY2gnKTtcbiAgdmFyIGF0dGVtcHRzID0gMjA7IC8vIHRoZSBudW1iZXIgb2YgcmVtYWluaW5nIGF0dGVtcHRzIHRvIHJlc3RvcmUgdGhlIHNuYXBzaG90XG5cbiAgaWYgKHNuYXBzaG90Lm5hdGl2ZVBvc3Rlcikge1xuICAgIHRlY2gucG9zdGVyID0gc25hcHNob3QubmF0aXZlUG9zdGVyO1xuICB9XG5cbiAgaWYgKCdzdHlsZScgaW4gc25hcHNob3QpIHtcbiAgICAvLyBvdmVyd3JpdGUgYWxsIGNzcyBzdHlsZSBwcm9wZXJ0aWVzIHRvIHJlc3RvcmUgc3RhdGUgcHJlY2lzZWx5XG4gICAgdGVjaC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgc25hcHNob3Quc3R5bGUgfHwgJycpO1xuICB9XG5cbiAgaWYgKGhhc1NyY0NoYW5nZWQocGxheWVyLCBzbmFwc2hvdCkpIHtcblxuICAgIC8vIG9uIGlvczcsIGZpZGRsaW5nIHdpdGggdGV4dFRyYWNrcyB0b28gZWFybHkgd2lsbCBjYXVzZSBzYWZhcmkgdG8gY3Jhc2hcbiAgICBwbGF5ZXIub25lKCdjb250ZW50bG9hZGVkbWV0YWRhdGEnLCByZXN0b3JlVHJhY2tzKTtcblxuICAgIHBsYXllci5vbmUoJ2NhbnBsYXknLCB0cnlUb1Jlc3VtZSk7XG4gICAgZW5zdXJlQ2FucGxheUV2dEdldHNGaXJlZCgpO1xuXG4gICAgLy8gaWYgdGhlIHNyYyBjaGFuZ2VkIGZvciBhZCBwbGF5YmFjaywgcmVzZXQgaXRcbiAgICBwbGF5ZXIuc3JjKHtzcmM6IHNuYXBzaG90LnNyYywgdHlwZTogc25hcHNob3QudHlwZX0pO1xuXG4gICAgLy8gc2FmYXJpIHJlcXVpcmVzIGEgY2FsbCB0byBgbG9hZGAgdG8gcGljayB1cCBhIGNoYW5nZWQgc291cmNlXG4gICAgcGxheWVyLmxvYWQoKTtcblxuICB9IGVsc2Uge1xuICAgIHJlc3RvcmVUcmFja3MoKTtcblxuICAgIGlmIChzbmFwc2hvdC5wbGF5aW5nKSB7XG4gICAgICBwbGF5ZXIucGxheSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiogTG9jYWwgRnVuY3Rpb25zICoqKi9cblxuICAvKipcbiAgICogU29tZXRpbWVzIGZpcmVmb3ggZG9lcyBub3QgdHJpZ2dlciB0aGUgJ2NhbnBsYXknIGV2dC5cbiAgICogVGhpcyBjb2RlIGVuc3VyZSB0aGF0IGl0IGFsd2F5cyBnZXRzIHRyaWdnZXJlZCB0cmlnZ2VyZWQuXG4gICAqL1xuICBmdW5jdGlvbiBlbnN1cmVDYW5wbGF5RXZ0R2V0c0ZpcmVkKCkge1xuICAgIHZhciB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgcGxheWVyLnRyaWdnZXIoJ2NhbnBsYXknKTtcbiAgICB9LCAxMDAwKTtcblxuICAgIHBsYXllci5vbmUoJ2NhbnBsYXknLCBmdW5jdGlvbigpe1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIHBsYXllciBuZWVkcyB0byBiZSByZXN0b3JlZCB0byBpdHMgc3RhdGVcbiAgICogYmVmb3JlIGFkIHBsYXliYWNrIGJlZ2FuLiBXaXRoIGEgY3VzdG9tIGFkIGRpc3BsYXkgb3IgYnVybmVkLWluXG4gICAqIGFkcywgdGhlIGNvbnRlbnQgcGxheWVyIHN0YXRlIGhhc24ndCBiZWVuIG1vZGlmaWVkIGFuZCBzbyBub1xuICAgKiByZXN0b3JhdGlvbiBpcyByZXF1aXJlZFxuICAgKi9cbiAgZnVuY3Rpb24gaGFzU3JjQ2hhbmdlZChwbGF5ZXIsIHNuYXBzaG90KSB7XG4gICAgaWYgKHBsYXllci5zcmMoKSkge1xuICAgICAgcmV0dXJuIHBsYXllci5zcmMoKSAhPT0gc25hcHNob3Quc3JjO1xuICAgIH1cbiAgICAvLyB0aGUgcGxheWVyIHdhcyBjb25maWd1cmVkIHRocm91Z2ggc291cmNlIGVsZW1lbnQgY2hpbGRyZW5cbiAgICByZXR1cm4gcGxheWVyLmN1cnJlbnRTcmMoKSAhPT0gc25hcHNob3Quc3JjO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzdG9yZVRyYWNrcygpIHtcbiAgICB2YXIgc3VwcHJlc3NlZFRyYWNrcyA9IHNuYXBzaG90LnN1cHByZXNzZWRUcmFja3M7XG4gICAgc3VwcHJlc3NlZFRyYWNrcy5mb3JFYWNoKGZ1bmN0aW9uICh0cmFja1NuYXBzaG90KSB7XG4gICAgICB0cmFja1NuYXBzaG90LnRyYWNrLm1vZGUgPSB0cmFja1NuYXBzaG90Lm1vZGU7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lIGlmIHRoZSB2aWRlbyBlbGVtZW50IGhhcyBsb2FkZWQgZW5vdWdoIG9mIHRoZSBzbmFwc2hvdCBzb3VyY2VcbiAgICogdG8gYmUgcmVhZHkgdG8gYXBwbHkgdGhlIHJlc3Qgb2YgdGhlIHN0YXRlXG4gICAqL1xuICBmdW5jdGlvbiB0cnlUb1Jlc3VtZSgpIHtcblxuICAgIC8vIGlmIHNvbWUgcGVyaW9kIG9mIHRoZSB2aWRlbyBpcyBzZWVrYWJsZSwgcmVzdW1lIHBsYXliYWNrXG4gICAgLy8gb3RoZXJ3aXNlIGRlbGF5IGEgYml0IGFuZCB0aGVuIGNoZWNrIGFnYWluIHVubGVzcyB3ZSdyZSBvdXQgb2YgYXR0ZW1wdHNcblxuICAgIGlmICghcGxheWVyVXRpbHMuaXNSZWFkeVRvUmVzdW1lKHBsYXllcikgJiYgYXR0ZW1wdHMtLSkge1xuICAgICAgc2V0VGltZW91dCh0cnlUb1Jlc3VtZSwgNTApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0cnkge1xuICAgICAgICBpZihwbGF5ZXIuY3VycmVudFRpbWUoKSAhPT0gc25hcHNob3QuY3VycmVudFRpbWUpIHtcbiAgICAgICAgICBpZiAoc25hcHNob3QucGxheWluZykgeyAvLyBpZiBuZWVkZWQgcmVzdG9yZSBwbGF5aW5nIHN0YXR1cyBhZnRlciBzZWVrIGNvbXBsZXRlc1xuICAgICAgICAgICAgcGxheWVyLm9uZSgnc2Vla2VkJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgIHBsYXllci5wbGF5KCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcGxheWVyLmN1cnJlbnRUaW1lKHNuYXBzaG90LmN1cnJlbnRUaW1lKTtcblxuICAgICAgICB9IGVsc2UgaWYgKHNuYXBzaG90LnBsYXlpbmcpIHtcbiAgICAgICAgICAvLyBpZiBuZWVkZWQgYW5kIG5vIHNlZWsgaGFzIGJlZW4gcGVyZm9ybWVkLCByZXN0b3JlIHBsYXlpbmcgc3RhdHVzIGltbWVkaWF0ZWx5XG4gICAgICAgICAgcGxheWVyLnBsYXkoKTtcbiAgICAgICAgfVxuXG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHZpZGVvanMubG9nLndhcm4oJ0ZhaWxlZCB0byByZXN1bWUgdGhlIGNvbnRlbnQgYWZ0ZXIgYW4gYWR2ZXJ0aXNlbWVudCcsIGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxucGxheWVyVXRpbHMuaXNSZWFkeVRvUmVzdW1lID0gZnVuY3Rpb24gKHBsYXllcikge1xuXG4gIGlmIChwbGF5ZXIucmVhZHlTdGF0ZSgpID4gMSkge1xuICAgIC8vIHNvbWUgYnJvd3NlcnMgYW5kIG1lZGlhIGFyZW4ndCBcInNlZWthYmxlXCIuXG4gICAgLy8gcmVhZHlTdGF0ZSBncmVhdGVyIHRoYW4gMSBhbGxvd3MgZm9yIHNlZWtpbmcgd2l0aG91dCBleGNlcHRpb25zXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBpZiAocGxheWVyLnNlZWthYmxlKCkgPT09IHVuZGVmaW5lZCkge1xuICAgIC8vIGlmIHRoZSBwbGF5ZXIgZG9lc24ndCBleHBvc2UgdGhlIHNlZWthYmxlIHRpbWUgcmFuZ2VzLCB0cnkgdG9cbiAgICAvLyByZXN1bWUgcGxheWJhY2sgaW1tZWRpYXRlbHlcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChwbGF5ZXIuc2Vla2FibGUoKS5sZW5ndGggPiAwKSB7XG4gICAgLy8gaWYgc29tZSBwZXJpb2Qgb2YgdGhlIHZpZGVvIGlzIHNlZWthYmxlLCByZXN1bWUgcGxheWJhY2tcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBwcmVwYXJlcyB0aGUgcGxheWVyIHRvIGRpc3BsYXkgYWRzLlxuICogQWRkaW5nIGNvbnZlbmllbmNlIGV2ZW50cyBsaWtlIHRoZSAndmFzdC5maXJzUGxheScgdGhhdCBnZXRzIGZpcmVkIHdoZW4gdGhlIHZpZGVvIGlzIGZpcnN0IHBsYXllZFxuICogYW5kIGFkcyB0aGUgYmxhY2tQb3N0ZXIgdG8gdGhlIHBsYXllciB0byBwcmV2ZW50IGNvbnRlbnQgZnJvbSBiZWluZyBkaXNwbGF5ZWQgYmVmb3JlIHRoZSBwcmVyb2xsIGFkLlxuICpcbiAqIEBwYXJhbSBwbGF5ZXJcbiAqL1xucGxheWVyVXRpbHMucHJlcGFyZUZvckFkcyA9IGZ1bmN0aW9uIChwbGF5ZXIpIHtcbiAgdmFyIGJsYWNrUG9zdGVyID0gcGxheWVyLmFkZENoaWxkKCdibGFja1Bvc3RlcicpO1xuICB2YXIgX2ZpcnN0UGxheSA9IHRydWU7XG4gIHZhciB2b2x1bWVTbmFwc2hvdDtcblxuXG4gIG1vbmtleVBhdGNoUGxheWVyQXBpKCk7XG5cbiAgcGxheWVyLm9uKCdwbGF5JywgdHJ5VG9UcmlnZ2VyRmlyc3RQbGF5KTtcbiAgcGxheWVyLm9uKCd2YXN0LnJlc2V0JywgcmVzZXRGaXJzdFBsYXkpOy8vRXZlcnkgdGltZSB3ZSBjaGFuZ2UgdGhlIHNvdXJjZXMgd2UgcmVzZXQgdGhlIGZpcnN0IHBsYXkuXG4gIHBsYXllci5vbigndmFzdC5maXJzdFBsYXknLCByZXN0b3JlQ29udGVudFZvbHVtZSk7XG4gIHBsYXllci5vbignZXJyb3InLCBoaWRlQmxhY2tQb3N0ZXIpOy8vSWYgdGhlcmUgaXMgYW4gZXJyb3IgaW4gdGhlIHBsYXllciB3ZSByZW1vdmUgdGhlIGJsYWNrcG9zdGVyIHRvIHNob3cgdGhlIGVyciBtc2dcbiAgcGxheWVyLm9uKCd2YXN0LmFkU3RhcnQnLCBoaWRlQmxhY2tQb3N0ZXIpO1xuICBwbGF5ZXIub24oJ3Zhc3QuYWRzQ2FuY2VsJywgaGlkZUJsYWNrUG9zdGVyKTtcbiAgcGxheWVyLm9uKCd2YXN0LmFkRXJyb3InLCBoaWRlQmxhY2tQb3N0ZXIpO1xuICBwbGF5ZXIub24oJ3Zhc3QuYWRTdGFydCcsIGFkZFN0eWxlcyk7XG4gIHBsYXllci5vbigndmFzdC5hZEVuZCcsIHJlbW92ZVN0eWxlcyk7XG4gIHBsYXllci5vbigndmFzdC5hZHNDYW5jZWwnLCByZW1vdmVTdHlsZXMpO1xuXG4gIC8qKiogTG9jYWwgRnVuY3Rpb25zICoqKi9cblxuICAvKipcbiAgIFdoYXQgdGhpcyBmdW5jdGlvbiBkb2VzIGlzIHVnbHkgYW5kIGhvcnJpYmxlIGFuZCBJIHNob3VsZCB0aGluayB0d2ljZSBiZWZvcmUgY2FsbGluZyBteXNlbGYgYSBnb29kIGRldmVsb3Blci4gV2l0aCB0aGF0IHNhaWQsXG4gICBpdCBpcyB0aGUgYmVzdCBzb2x1dGlvbiBJIGNvdWxkIGZpbmQgdG8gbXV0ZSB0aGUgdmlkZW8gdW50aWwgdGhlICdwbGF5JyBldmVudCBoYXBwZW5zIChvbiBtb2JpbGUgZGV2aWNlcykgYW5kIHRoZSBwbHVnaW4gY2FuIGRlY2lkZSB3aGV0aGVyXG4gICB0byBwbGF5IHRoZSBhZCBvciBub3QuXG5cbiAgIFdlIGFsc28gbmVlZCB0aGlzIG1vbmtleXBhdGNoIHRvIGJlIGFibGUgdG8gcGF1c2UgYW5kIHJlc3VtZSBhbiBhZCB1c2luZyB0aGUgcGxheWVyJ3MgQVBJXG5cbiAgIElmIHlvdSBoYXZlIGEgYmV0dGVyIHNvbHV0aW9uIHBsZWFzZSBkbyB0ZWxsIG1lLlxuICAgKi9cbiAgZnVuY3Rpb24gbW9ua2V5UGF0Y2hQbGF5ZXJBcGkoKSB7XG5cbiAgICAvKipcbiAgICAgKiBNb25rZXkgcGF0Y2ggbmVlZGVkIHRvIGhhbmRsZSBmaXJzdFBsYXkgYW5kIHJlc3VtZSBvZiBwbGF5aW5nIGFkLlxuICAgICAqXG4gICAgICogQHBhcmFtIGNhbGxPcmlnUGxheSBuZWNlc3NhcnkgZmxhZyB0byBwcmV2ZW50IGluZmluaXRlIGxvb3Agd2hlbiB5b3UgYXJlIHJlc3RvcmluZyBhIFZBU1QgYWQuXG4gICAgICogQHJldHVybnMge3BsYXllcn1cbiAgICAgKi9cbiAgICB2YXIgb3JpZ1BsYXkgPSBwbGF5ZXIucGxheTtcbiAgICBwbGF5ZXIucGxheSA9IGZ1bmN0aW9uIChjYWxsT3JpZ1BsYXkpIHtcbiAgICAgIHZhciB0aGF0ID0gdGhpcztcblxuICAgICAgaWYgKGlzRmlyc3RQbGF5KCkpIHtcbiAgICAgICAgZmlyc3RQbGF5KCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bWUoY2FsbE9yaWdQbGF5KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIC8qKiogbG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgICAgIGZ1bmN0aW9uIGZpcnN0UGxheSgpIHtcbiAgICAgICAgaWYgKCF1dGlsaXRpZXMuaXNJUGhvbmUoKSkge1xuICAgICAgICAgIHZvbHVtZVNuYXBzaG90ID0gc2F2ZVZvbHVtZVNuYXBzaG90KCk7XG4gICAgICAgICAgcGxheWVyLm11dGVkKHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgb3JpZ1BsYXkuYXBwbHkodGhhdCwgYXJndW1lbnRzKTtcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gcmVzdW1lKGNhbGxPcmlnUGxheSkge1xuICAgICAgICBpZiAoaXNBZFBsYXlpbmcoKSAmJiAhY2FsbE9yaWdQbGF5KSB7XG4gICAgICAgICAgcGxheWVyLnZhc3QuYWRVbml0LnJlc3VtZUFkKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb3JpZ1BsYXkuYXBwbHkodGhhdCwgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cblxuICAgIC8qKlxuICAgICAqIE5lZWRlZCBtb25rZXkgcGF0Y2ggdG8gaGFuZGxlIHBhdXNlIG9mIHBsYXlpbmcgYWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY2FsbE9yaWdQbGF5IG5lY2Vzc2FyeSBmbGFnIHRvIHByZXZlbnQgaW5maW5pdGUgbG9vcCB3aGVuIHlvdSBhcmUgcGF1c2luZyBhIFZBU1QgYWQuXG4gICAgICogQHJldHVybnMge3BsYXllcn1cbiAgICAgKi9cbiAgICB2YXIgb3JpZ1BhdXNlID0gcGxheWVyLnBhdXNlO1xuICAgIHBsYXllci5wYXVzZSA9IGZ1bmN0aW9uIChjYWxsT3JpZ1BhdXNlKSB7XG4gICAgICBpZiAoaXNBZFBsYXlpbmcoKSAmJiAhY2FsbE9yaWdQYXVzZSkge1xuICAgICAgICBwbGF5ZXIudmFzdC5hZFVuaXQucGF1c2VBZCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3JpZ1BhdXNlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5cbiAgICAvKipcbiAgICAgKiBOZWVkZWQgbW9ua2V5IHBhdGNoIHRvIGhhbmRsZSBwYXVzZWQgc3RhdGUgb2YgdGhlIHBsYXllciB3aGVuIGFkcyBhcmUgcGxheWluZy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBjYWxsT3JpZ1BsYXkgbmVjZXNzYXJ5IGZsYWcgdG8gcHJldmVudCBpbmZpbml0ZSBsb29wIHdoZW4geW91IGFyZSBwYXVzaW5nIGEgVkFTVCBhZC5cbiAgICAgKiBAcmV0dXJucyB7cGxheWVyfVxuICAgICAqL1xuICAgIHZhciBvcmlnUGF1c2VkID0gcGxheWVyLnBhdXNlZDtcbiAgICBwbGF5ZXIucGF1c2VkID0gZnVuY3Rpb24gKGNhbGxPcmlnUGF1c2VkKSB7XG4gICAgICBpZiAoaXNBZFBsYXlpbmcoKSAmJiAhY2FsbE9yaWdQYXVzZWQpIHtcbiAgICAgICAgcmV0dXJuIHBsYXllci52YXN0LmFkVW5pdC5pc1BhdXNlZCgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9yaWdQYXVzZWQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gaXNBZFBsYXlpbmcoKSB7XG4gICAgcmV0dXJuIHBsYXllci52YXN0ICYmIHBsYXllci52YXN0LmFkVW5pdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyeVRvVHJpZ2dlckZpcnN0UGxheSgpIHtcbiAgICBpZiAoaXNGaXJzdFBsYXkoKSkge1xuICAgICAgX2ZpcnN0UGxheSA9IGZhbHNlO1xuICAgICAgcGxheWVyLnRyaWdnZXIoJ3Zhc3QuZmlyc3RQbGF5Jyk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVzZXRGaXJzdFBsYXkoKSB7XG4gICAgX2ZpcnN0UGxheSA9IHRydWU7XG4gICAgYmxhY2tQb3N0ZXIuc2hvdygpO1xuICAgIHJlc3RvcmVDb250ZW50Vm9sdW1lKCk7XG4gIH1cblxuICBmdW5jdGlvbiBpc0ZpcnN0UGxheSgpIHtcbiAgICByZXR1cm4gX2ZpcnN0UGxheTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNhdmVWb2x1bWVTbmFwc2hvdCgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbXV0ZWQ6IHBsYXllci5tdXRlZCgpLFxuICAgICAgdm9sdW1lOiBwbGF5ZXIudm9sdW1lKClcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzdG9yZUNvbnRlbnRWb2x1bWUoKSB7XG4gICAgaWYgKHZvbHVtZVNuYXBzaG90KSB7XG4gICAgICBwbGF5ZXIuY3VycmVudFRpbWUoMCk7XG4gICAgICByZXN0b3JlVm9sdW1lU25hcHNob3Qodm9sdW1lU25hcHNob3QpO1xuICAgICAgdm9sdW1lU25hcHNob3QgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc3RvcmVWb2x1bWVTbmFwc2hvdChzbmFwc2hvdCkge1xuICAgIGlmICh1dGlsaXRpZXMuaXNPYmplY3Qoc25hcHNob3QpKSB7XG4gICAgICBwbGF5ZXIudm9sdW1lKHNuYXBzaG90LnZvbHVtZSk7XG4gICAgICBwbGF5ZXIubXV0ZWQoc25hcHNob3QubXV0ZWQpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGhpZGVCbGFja1Bvc3RlcigpIHtcbiAgICBpZiAoIWRvbS5oYXNDbGFzcyhibGFja1Bvc3Rlci5lbCgpLCAndmpzLWhpZGRlbicpKSB7XG4gICAgICBibGFja1Bvc3Rlci5oaWRlKCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gYWRkU3R5bGVzKCkge1xuICAgIGRvbS5hZGRDbGFzcyhwbGF5ZXIuZWwoKSwgJ3Zqcy1hZC1wbGF5aW5nJyk7XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVTdHlsZXMoKSB7XG4gICAgZG9tLnJlbW92ZUNsYXNzKHBsYXllci5lbCgpLCAndmpzLWFkLXBsYXlpbmcnKTtcbiAgfVxufTtcblxuLyoqXG4gKiBSZW1vdmUgdGhlIHBvc3RlciBhdHRyaWJ1dGUgZnJvbSB0aGUgdmlkZW8gZWxlbWVudCB0ZWNoLCBpZiBwcmVzZW50LiBXaGVuXG4gKiByZXVzaW5nIGEgdmlkZW8gZWxlbWVudCBmb3IgbXVsdGlwbGUgdmlkZW9zLCB0aGUgcG9zdGVyIGltYWdlIHdpbGwgYnJpZWZseVxuICogcmVhcHBlYXIgd2hpbGUgdGhlIG5ldyBzb3VyY2UgbG9hZHMuIFJlbW92aW5nIHRoZSBhdHRyaWJ1dGUgYWhlYWQgb2YgdGltZVxuICogcHJldmVudHMgdGhlIHBvc3RlciBmcm9tIHNob3dpbmcgdXAgYmV0d2VlbiB2aWRlb3MuXG4gKiBAcGFyYW0ge29iamVjdH0gcGxheWVyIFRoZSB2aWRlb2pzIHBsYXllciBvYmplY3RcbiAqL1xucGxheWVyVXRpbHMucmVtb3ZlTmF0aXZlUG9zdGVyID0gZnVuY3Rpb24gKHBsYXllcikge1xuICB2YXIgdGVjaCA9IHBsYXllci5lbCgpLnF1ZXJ5U2VsZWN0b3IoJy52anMtdGVjaCcpO1xuICBpZiAodGVjaCkge1xuICAgIHRlY2gucmVtb3ZlQXR0cmlidXRlKCdwb3N0ZXInKTtcbiAgfVxufTtcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gbGlzdGVuIHRvIG1hbnkgZXZlbnRzIHVudGlsIG9uZSBvZiB0aGVtIGdldHMgZmlyZWQsIHRoZW4gd2VcbiAqIGV4ZWN1dGUgdGhlIGhhbmRsZXIgYW5kIHVuc3Vic2NyaWJlIGFsbCB0aGUgZXZlbnQgbGlzdGVuZXJzO1xuICpcbiAqIEBwYXJhbSBwbGF5ZXIgc3BlY2lmaWMgcGxheWVyIGZyb20gd2hlcmUgdG8gbGlzdGVuIGZvciB0aGUgZXZlbnRzXG4gKiBAcGFyYW0gZXZlbnRzIGFycmF5IG9mIGV2ZW50c1xuICogQHBhcmFtIGhhbmRsZXIgZnVuY3Rpb24gdG8gZXhlY3V0ZSBvbmNlIG9uZSBvZiB0aGUgZXZlbnRzIGZpcmVzXG4gKi9cbnBsYXllclV0aWxzLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHBsYXllciwgZXZlbnRzLCBoYW5kbGVyKSB7XG4gIGZ1bmN0aW9uIGxpc3RlbmVyKCkge1xuICAgIGhhbmRsZXIuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcblxuICAgIGV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgcGxheWVyLm9mZihldmVudCwgbGlzdGVuZXIpO1xuICAgIH0pO1xuICB9XG5cbiAgZXZlbnRzLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgcGxheWVyLm9uKGV2ZW50LCBsaXN0ZW5lcik7XG4gIH0pO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IHBsYXllclV0aWxzOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4vdXRpbGl0eUZ1bmN0aW9ucycpO1xuXG4vKipcbiAqXG4gKiBJTVBPUlRBTlQgTk9URTogVGhpcyBmdW5jdGlvbiBjb21lcyBmcm9tIGFuZ3VsYXJKcyBhbmQgd2FzIG9yaWdpbmFsbHkgY2FsbGVkIHVybFJlc29sdmVcbiAqICAgICAgICAgICAgICAgICB5b3UgY2FuIHRha2UgYSBsb29rIGF0IHRoZSBvcmlnaW5hbCBjb2RlIGhlcmUgaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci5qcy9ibG9iL21hc3Rlci9zcmMvbmcvdXJsVXRpbHMuanNcbiAqXG4gKiBJbXBsZW1lbnRhdGlvbiBOb3RlcyBmb3Igbm9uLUlFIGJyb3dzZXJzXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBBc3NpZ25pbmcgYSBVUkwgdG8gdGhlIGhyZWYgcHJvcGVydHkgb2YgYW4gYW5jaG9yIERPTSBub2RlLCBldmVuIG9uZSBhdHRhY2hlZCB0byB0aGUgRE9NLFxuICogcmVzdWx0cyBib3RoIGluIHRoZSBub3JtYWxpemluZyBhbmQgcGFyc2luZyBvZiB0aGUgVVJMLiAgTm9ybWFsaXppbmcgbWVhbnMgdGhhdCBhIHJlbGF0aXZlXG4gKiBVUkwgd2lsbCBiZSByZXNvbHZlZCBpbnRvIGFuIGFic29sdXRlIFVSTCBpbiB0aGUgY29udGV4dCBvZiB0aGUgYXBwbGljYXRpb24gZG9jdW1lbnQuXG4gKiBQYXJzaW5nIG1lYW5zIHRoYXQgdGhlIGFuY2hvciBub2RlJ3MgaG9zdCwgaG9zdG5hbWUsIHByb3RvY29sLCBwb3J0LCBwYXRobmFtZSBhbmQgcmVsYXRlZFxuICogcHJvcGVydGllcyBhcmUgYWxsIHBvcHVsYXRlZCB0byByZWZsZWN0IHRoZSBub3JtYWxpemVkIFVSTC4gIFRoaXMgYXBwcm9hY2ggaGFzIHdpZGVcbiAqIGNvbXBhdGliaWxpdHkgLSBTYWZhcmkgMSssIE1vemlsbGEgMSssIE9wZXJhIDcrLGUgZXRjLiAgU2VlXG4gKiBodHRwOi8vd3d3LmFwdGFuYS5jb20vcmVmZXJlbmNlL2h0bWwvYXBpL0hUTUxBbmNob3JFbGVtZW50Lmh0bWxcbiAqXG4gKiBJbXBsZW1lbnRhdGlvbiBOb3RlcyBmb3IgSUVcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogSUUgPj0gOCBhbmQgPD0gMTAgbm9ybWFsaXplcyB0aGUgVVJMIHdoZW4gYXNzaWduZWQgdG8gdGhlIGFuY2hvciBub2RlIHNpbWlsYXIgdG8gdGhlIG90aGVyXG4gKiBicm93c2Vycy4gIEhvd2V2ZXIsIHRoZSBwYXJzZWQgY29tcG9uZW50cyB3aWxsIG5vdCBiZSBzZXQgaWYgdGhlIFVSTCBhc3NpZ25lZCBkaWQgbm90IHNwZWNpZnlcbiAqIHRoZW0uICAoZS5nLiBpZiB5b3UgYXNzaWduIGEuaHJlZiA9IFwiZm9vXCIsIHRoZW4gYS5wcm90b2NvbCwgYS5ob3N0LCBldGMuIHdpbGwgYmUgZW1wdHkuKSAgV2VcbiAqIHdvcmsgYXJvdW5kIHRoYXQgYnkgcGVyZm9ybWluZyB0aGUgcGFyc2luZyBpbiBhIDJuZCBzdGVwIGJ5IHRha2luZyBhIHByZXZpb3VzbHkgbm9ybWFsaXplZFxuICogVVJMIChlLmcuIGJ5IGFzc2lnbmluZyB0byBhLmhyZWYpIGFuZCBhc3NpZ25pbmcgaXQgYS5ocmVmIGFnYWluLiAgVGhpcyBjb3JyZWN0bHkgcG9wdWxhdGVzIHRoZVxuICogcHJvcGVydGllcyBzdWNoIGFzIHByb3RvY29sLCBob3N0bmFtZSwgcG9ydCwgZXRjLlxuICpcbiAqIElFNyBkb2VzIG5vdCBub3JtYWxpemUgdGhlIFVSTCB3aGVuIGFzc2lnbmVkIHRvIGFuIGFuY2hvciBub2RlLiAgKEFwcGFyZW50bHksIGl0IGRvZXMsIGlmIG9uZVxuICogdXNlcyB0aGUgaW5uZXIgSFRNTCBhcHByb2FjaCB0byBhc3NpZ24gdGhlIFVSTCBhcyBwYXJ0IG9mIGFuIEhUTUwgc25pcHBldCAtXG4gKiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS80NzI3MjkpICBIb3dldmVyLCBzZXR0aW5nIGltZ1tzcmNdIGRvZXMgbm9ybWFsaXplIHRoZSBVUkwuXG4gKiBVbmZvcnR1bmF0ZWx5LCBzZXR0aW5nIGltZ1tzcmNdIHRvIHNvbWV0aGluZyBsaWtlIFwiamF2YXNjcmlwdDpmb29cIiBvbiBJRSB0aHJvd3MgYW4gZXhjZXB0aW9uLlxuICogU2luY2UgdGhlIHByaW1hcnkgdXNhZ2UgZm9yIG5vcm1hbGl6aW5nIFVSTHMgaXMgdG8gc2FuaXRpemUgc3VjaCBVUkxzLCB3ZSBjYW4ndCB1c2UgdGhhdFxuICogbWV0aG9kIGFuZCBJRSA8IDggaXMgdW5zdXBwb3J0ZWQuXG4gKlxuICogUmVmZXJlbmNlczpcbiAqICAgaHR0cDovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvSFRNTEFuY2hvckVsZW1lbnRcbiAqICAgaHR0cDovL3d3dy5hcHRhbmEuY29tL3JlZmVyZW5jZS9odG1sL2FwaS9IVE1MQW5jaG9yRWxlbWVudC5odG1sXG4gKiAgIGh0dHA6Ly91cmwuc3BlYy53aGF0d2cub3JnLyN1cmx1dGlsc1xuICogICBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyLmpzL3B1bGwvMjkwMlxuICogICBodHRwOi8vamFtZXMucGFkb2xzZXkuY29tL2phdmFzY3JpcHQvcGFyc2luZy11cmxzLXdpdGgtdGhlLWRvbS9cbiAqXG4gKiBAa2luZCBmdW5jdGlvblxuICogQHBhcmFtIHtzdHJpbmd9IHVybCBUaGUgVVJMIHRvIGJlIHBhcnNlZC5cbiAqIEBkZXNjcmlwdGlvbiBOb3JtYWxpemVzIGFuZCBwYXJzZXMgYSBVUkwuXG4gKiBAcmV0dXJucyB7b2JqZWN0fSBSZXR1cm5zIHRoZSBub3JtYWxpemVkIFVSTCBhcyBhIGRpY3Rpb25hcnkuXG4gKlxuICogICB8IG1lbWJlciBuYW1lICAgfCBEZXNjcmlwdGlvbiAgICB8XG4gKiAgIHwtLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLXxcbiAqICAgfCBocmVmICAgICAgICAgIHwgQSBub3JtYWxpemVkIHZlcnNpb24gb2YgdGhlIHByb3ZpZGVkIFVSTCBpZiBpdCB3YXMgbm90IGFuIGFic29sdXRlIFVSTCB8XG4gKiAgIHwgcHJvdG9jb2wgICAgICB8IFRoZSBwcm90b2NvbCBpbmNsdWRpbmcgdGhlIHRyYWlsaW5nIGNvbG9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogICB8IGhvc3QgICAgICAgICAgfCBUaGUgaG9zdCBhbmQgcG9ydCAoaWYgdGhlIHBvcnQgaXMgbm9uLWRlZmF1bHQpIG9mIHRoZSBub3JtYWxpemVkVXJsICAgIHxcbiAqICAgfCBzZWFyY2ggICAgICAgIHwgVGhlIHNlYXJjaCBwYXJhbXMsIG1pbnVzIHRoZSBxdWVzdGlvbiBtYXJrICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgIHwgaGFzaCAgICAgICAgICB8IFRoZSBoYXNoIHN0cmluZywgbWludXMgdGhlIGhhc2ggc3ltYm9sXG4gKiAgIHwgaG9zdG5hbWUgICAgICB8IFRoZSBob3N0bmFtZVxuICogICB8IHBvcnQgICAgICAgICAgfCBUaGUgcG9ydCwgd2l0aG91dCBcIjpcIlxuICogICB8IHBhdGhuYW1lICAgICAgfCBUaGUgcGF0aG5hbWUsIGJlZ2lubmluZyB3aXRoIFwiL1wiXG4gKlxuICovXG5cbnZhciB1cmxQYXJzaW5nTm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJhXCIpO1xuLyoqXG4gKiBkb2N1bWVudE1vZGUgaXMgYW4gSUUtb25seSBwcm9wZXJ0eVxuICogaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2llL2NjMTk2OTg4KHY9dnMuODUpLmFzcHhcbiAqL1xudmFyIG1zaWUgPSBkb2N1bWVudC5kb2N1bWVudE1vZGU7XG5cbmZ1bmN0aW9uIHVybFBhcnRzKHVybCkge1xuICB2YXIgaHJlZiA9IHVybDtcblxuICBpZiAobXNpZSkge1xuICAgIC8vIE5vcm1hbGl6ZSBiZWZvcmUgcGFyc2UuICBSZWZlciBJbXBsZW1lbnRhdGlvbiBOb3RlcyBvbiB3aHkgdGhpcyBpc1xuICAgIC8vIGRvbmUgaW4gdHdvIHN0ZXBzIG9uIElFLlxuICAgIHVybFBhcnNpbmdOb2RlLnNldEF0dHJpYnV0ZShcImhyZWZcIiwgaHJlZik7XG4gICAgaHJlZiA9IHVybFBhcnNpbmdOb2RlLmhyZWY7XG4gIH1cblxuICB1cmxQYXJzaW5nTm9kZS5zZXRBdHRyaWJ1dGUoJ2hyZWYnLCBocmVmKTtcblxuICAvLyB1cmxQYXJzaW5nTm9kZSBwcm92aWRlcyB0aGUgVXJsVXRpbHMgaW50ZXJmYWNlIC0gaHR0cDovL3VybC5zcGVjLndoYXR3Zy5vcmcvI3VybHV0aWxzXG4gIHJldHVybiB7XG4gICAgaHJlZjogdXJsUGFyc2luZ05vZGUuaHJlZixcbiAgICBwcm90b2NvbDogdXJsUGFyc2luZ05vZGUucHJvdG9jb2wgPyB1cmxQYXJzaW5nTm9kZS5wcm90b2NvbC5yZXBsYWNlKC86JC8sICcnKSA6ICcnLFxuICAgIGhvc3Q6IHVybFBhcnNpbmdOb2RlLmhvc3QsXG4gICAgc2VhcmNoOiB1cmxQYXJzaW5nTm9kZS5zZWFyY2ggPyB1cmxQYXJzaW5nTm9kZS5zZWFyY2gucmVwbGFjZSgvXlxcPy8sICcnKSA6ICcnLFxuICAgIGhhc2g6IHVybFBhcnNpbmdOb2RlLmhhc2ggPyB1cmxQYXJzaW5nTm9kZS5oYXNoLnJlcGxhY2UoL14jLywgJycpIDogJycsXG4gICAgaG9zdG5hbWU6IHVybFBhcnNpbmdOb2RlLmhvc3RuYW1lLFxuICAgIHBvcnQ6IHV0aWxpdGllcy5pc05vdEVtcHR5U3RyaW5nKHVybFBhcnNpbmdOb2RlLnBvcnQpPyB1cmxQYXJzaW5nTm9kZS5wb3J0OiA4MCxcbiAgICBwYXRobmFtZTogKHVybFBhcnNpbmdOb2RlLnBhdGhuYW1lLmNoYXJBdCgwKSA9PT0gJy8nKVxuICAgICAgPyB1cmxQYXJzaW5nTm9kZS5wYXRobmFtZVxuICAgICAgOiAnLycgKyB1cmxQYXJzaW5nTm9kZS5wYXRobmFtZVxuICB9O1xufVxuXG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBhY2NlcHRzIGEgcXVlcnkgc3RyaW5nIChzZWFyY2ggcGFydCBvZiBhIHVybCkgYW5kIHJldHVybnMgYSBkaWN0aW9uYXJ5IHdpdGhcbiAqIHRoZSBkaWZmZXJlbnQga2V5IHZhbHVlIHBhaXJzXG4gKiBAcGFyYW0ge3N0cmluZ30gcXMgcXVlcnlTdHJpbmdcbiAqL1xuZnVuY3Rpb24gcXVlcnlTdHJpbmdUb09iaihxcywgY29uZCkge1xuICB2YXIgcGFpcnMsIHFzT2JqO1xuXG4gIGNvbmQgPSB1dGlsaXRpZXMuaXNGdW5jdGlvbihjb25kKT8gY29uZCA6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIHFzID0gcXMudHJpbSgpLnJlcGxhY2UoL15cXD8vLCAnJyk7XG4gIHBhaXJzID0gcXMuc3BsaXQoJyYnKTtcbiAgcXNPYmogPSB7fTtcblxuICB1dGlsaXRpZXMuZm9yRWFjaChwYWlycywgZnVuY3Rpb24gKHBhaXIpIHtcbiAgICB2YXIga2V5VmFsdWUsIGtleSwgdmFsdWU7XG4gICAgaWYgKHBhaXIgIT09ICcnKSB7XG4gICAgICBrZXlWYWx1ZSA9IHBhaXIuc3BsaXQoJz0nKTtcbiAgICAgIGtleSA9IGtleVZhbHVlWzBdO1xuICAgICAgdmFsdWUgPSBrZXlWYWx1ZVsxXTtcbiAgICAgIGlmKGNvbmQoa2V5LCB2YWx1ZSkpe1xuICAgICAgICBxc09ialtrZXldID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gcXNPYmo7XG59XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBhY2NlcHRzIGFuIG9iamVjdCBhbmQgc2VyaWFsaXplcyBpdCBpbnRvIGEgcXVlcnkgc3RyaW5nIHdpdGhvdXQgdGhlIGxlYWRpbmcgJz8nXG4gKiBAcGFyYW0gb2JqXG4gKiBAcmV0dXJucyB7c3RyaW5nfVxuICovXG5mdW5jdGlvbiBvYmpUb1F1ZXJ5U3RyaW5nKG9iaikge1xuICB2YXIgcGFpcnMgPSBbXTtcbiAgdXRpbGl0aWVzLmZvckVhY2gob2JqLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgIHBhaXJzLnB1c2goa2V5ICsgJz0nICsgdmFsdWUpO1xuICB9KTtcbiAgcmV0dXJuIHBhaXJzLmpvaW4oJyYnKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHVybFBhcnRzOiB1cmxQYXJ0cyxcbiAgcXVlcnlTdHJpbmdUb09iajogcXVlcnlTdHJpbmdUb09iaixcbiAgb2JqVG9RdWVyeVN0cmluZzogb2JqVG9RdWVyeVN0cmluZ1xufTtcbiIsIi8qanNoaW50IHVudXNlZDpmYWxzZSAqL1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBOT0RFX1RZUEVfRUxFTUVOVCA9IDE7XG52YXIgU05BS0VfQ0FTRV9SRUdFWFAgPSAvW0EtWl0vZztcbnZhciBFTUFJTF9SRUdFWFAgPSAvXlthLXowLTkhIyQlJicqK1xcLz0/Xl9ge3x9fi4tXStAW2EtejAtOV0oW2EtejAtOS1dKlthLXowLTldKT8oXFwuW2EtejAtOV0oW2EtejAtOS1dKlthLXowLTldKT8pKyQvaTtcbi8qanNsaW50IG1heGxlbjogNTAwICovXG52YXIgSVNPODA4Nl9SRUdFWFAgPSAvXihbXFwrLV0/XFxkezR9KD8hXFxkezJ9XFxiKSkoKC0/KSgoMFsxLTldfDFbMC0yXSkoXFwzKFsxMl1cXGR8MFsxLTldfDNbMDFdKSk/fFcoWzAtNF1cXGR8NVswLTJdKSgtP1sxLTddKT98KDAwWzEtOV18MFsxLTldXFxkfFsxMl1cXGR7Mn18MyhbMC01XVxcZHw2WzEtNl0pKSkoW1RcXHNdKCgoWzAxXVxcZHwyWzAtM10pKCg6PylbMC01XVxcZCk/fDI0XFw6PzAwKShbXFwuLF1cXGQrKD8hOikpPyk/KFxcMTdbMC01XVxcZChbXFwuLF1cXGQrKT8pPyhbelpdfChbXFwrLV0pKFswMV1cXGR8MlswLTNdKTo/KFswLTVdXFxkKT8pPyk/KT8kLztcblxuXG5mdW5jdGlvbiBub29wKCl7IH1cblxuZnVuY3Rpb24gaXNOdWxsKG8pIHtcbiAgcmV0dXJuIG8gPT09IG51bGw7XG59XG5cbmZ1bmN0aW9uIGlzRGVmaW5lZChvKXtcbiAgcmV0dXJuIG8gIT09IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gaXNVbmRlZmluZWQobyl7XG4gIHJldHVybiBvID09PSB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KG9iaikge1xuICByZXR1cm4gdHlwZW9mIG9iaiA9PT0gJ29iamVjdCc7XG59XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oc3RyKXtcbiAgcmV0dXJuIHR5cGVvZiBzdHIgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGlzTnVtYmVyKG51bSl7XG4gIHJldHVybiB0eXBlb2YgbnVtID09PSAnbnVtYmVyJztcbn1cblxuZnVuY3Rpb24gaXNXaW5kb3cob2JqKSB7XG4gIHJldHVybiB1dGlsaXRpZXMuaXNPYmplY3Qob2JqKSAmJiBvYmoud2luZG93ID09PSBvYmo7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXkoYXJyYXkpe1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKCBhcnJheSApID09PSAnW29iamVjdCBBcnJheV0nO1xufVxuXG5mdW5jdGlvbiBpc0FycmF5TGlrZShvYmopIHtcbiAgaWYgKG9iaiA9PT0gbnVsbCB8fCB1dGlsaXRpZXMuaXNXaW5kb3cob2JqKSB8fCB1dGlsaXRpZXMuaXNGdW5jdGlvbihvYmopIHx8IHV0aWxpdGllcy5pc1VuZGVmaW5lZChvYmopKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyIGxlbmd0aCA9IG9iai5sZW5ndGg7XG5cbiAgaWYgKG9iai5ub2RlVHlwZSA9PT0gTk9ERV9UWVBFX0VMRU1FTlQgJiYgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gdXRpbGl0aWVzLmlzU3RyaW5nKG9iaikgfHwgdXRpbGl0aWVzLmlzQXJyYXkob2JqKSB8fCBsZW5ndGggPT09IDAgfHxcbiAgICB0eXBlb2YgbGVuZ3RoID09PSAnbnVtYmVyJyAmJiBsZW5ndGggPiAwICYmIChsZW5ndGggLSAxKSBpbiBvYmo7XG59XG5cbmZ1bmN0aW9uIGlzU3RyaW5nKHN0cil7XG4gIHJldHVybiB0eXBlb2Ygc3RyID09PSAnc3RyaW5nJztcbn1cblxuZnVuY3Rpb24gaXNFbXB0eVN0cmluZyhzdHIpIHtcbiAgcmV0dXJuIHV0aWxpdGllcy5pc1N0cmluZyhzdHIpICYmIHN0ci5sZW5ndGggPT09IDA7XG59XG5cbmZ1bmN0aW9uIGlzTm90RW1wdHlTdHJpbmcoc3RyKSB7XG4gIHJldHVybiB1dGlsaXRpZXMuaXNTdHJpbmcoc3RyKSAmJiBzdHIubGVuZ3RoICE9PSAwO1xufVxuXG5mdW5jdGlvbiBhcnJheUxpa2VPYmpUb0FycmF5KGFyZ3MpIHtcbiAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3MpO1xufVxuXG5mdW5jdGlvbiBmb3JFYWNoKG9iaiwgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgdmFyIGtleSwgbGVuZ3RoO1xuICBpZiAob2JqKSB7XG4gICAgaWYgKGlzRnVuY3Rpb24ob2JqKSkge1xuICAgICAgZm9yIChrZXkgaW4gb2JqKSB7XG4gICAgICAgIC8vIE5lZWQgdG8gY2hlY2sgaWYgaGFzT3duUHJvcGVydHkgZXhpc3RzLFxuICAgICAgICAvLyBhcyBvbiBJRTggdGhlIHJlc3VsdCBvZiBxdWVyeVNlbGVjdG9yQWxsIGlzIGFuIG9iamVjdCB3aXRob3V0IGEgaGFzT3duUHJvcGVydHkgZnVuY3Rpb25cbiAgICAgICAgaWYgKGtleSAhPT0gJ3Byb3RvdHlwZScgJiYga2V5ICE9PSAnbGVuZ3RoJyAmJiBrZXkgIT09ICduYW1lJyAmJiAoIW9iai5oYXNPd25Qcm9wZXJ0eSB8fCBvYmouaGFzT3duUHJvcGVydHkoa2V5KSkpIHtcbiAgICAgICAgICBpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9ialtrZXldLCBrZXksIG9iaik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkob2JqKSkge1xuICAgICAgdmFyIGlzUHJpbWl0aXZlID0gdHlwZW9mIG9iaiAhPT0gJ29iamVjdCc7XG4gICAgICBmb3IgKGtleSA9IDAsIGxlbmd0aCA9IG9iai5sZW5ndGg7IGtleSA8IGxlbmd0aDsga2V5KyspIHtcbiAgICAgICAgaWYgKGlzUHJpbWl0aXZlIHx8IGtleSBpbiBvYmopIHtcbiAgICAgICAgICBpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9ialtrZXldLCBrZXksIG9iaik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG9iai5mb3JFYWNoICYmIG9iai5mb3JFYWNoICE9PSBmb3JFYWNoKSB7XG4gICAgICBvYmouZm9yRWFjaChpdGVyYXRvciwgY29udGV4dCwgb2JqKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChrZXkgaW4gb2JqKSB7XG4gICAgICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgb2JqW2tleV0sIGtleSwgb2JqKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gb2JqO1xufVxuXG5mdW5jdGlvbiBzbmFrZV9jYXNlKG5hbWUsIHNlcGFyYXRvcikge1xuICBzZXBhcmF0b3IgPSBzZXBhcmF0b3IgfHwgJ18nO1xuICByZXR1cm4gbmFtZS5yZXBsYWNlKFNOQUtFX0NBU0VfUkVHRVhQLCBmdW5jdGlvbihsZXR0ZXIsIHBvcykge1xuICAgIHJldHVybiAocG9zID8gc2VwYXJhdG9yIDogJycpICsgbGV0dGVyLnRvTG93ZXJDYXNlKCk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBpc1ZhbGlkRW1haWwoZW1haWwpe1xuICBpZighdXRpbGl0aWVzLmlzU3RyaW5nKGVtYWlsKSl7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIEVNQUlMX1JFR0VYUC50ZXN0KGVtYWlsLnRyaW0oKSk7XG59XG5cbmZ1bmN0aW9uIGV4dGVuZCAob2JqKSB7XG4gIHZhciBhcmcsIGksIGs7XG4gIGZvciAoaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICBhcmcgPSBhcmd1bWVudHNbaV07XG4gICAgZm9yIChrIGluIGFyZykge1xuICAgICAgaWYgKGFyZy5oYXNPd25Qcm9wZXJ0eShrKSkge1xuICAgICAgICBpZihpc09iamVjdChvYmpba10pICYmICFpc051bGwob2JqW2tdKSAmJiBpc09iamVjdChhcmdba10pKXtcbiAgICAgICAgICBvYmpba10gPSBleHRlbmQoe30sIG9ialtrXSwgYXJnW2tdKTtcbiAgICAgICAgfWVsc2Uge1xuICAgICAgICAgIG9ialtrXSA9IGFyZ1trXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gb2JqO1xufVxuXG5mdW5jdGlvbiBjYXBpdGFsaXplKHMpe1xuICByZXR1cm4gcy5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHMuc2xpY2UoMSk7XG59XG5cbmZ1bmN0aW9uIGRlY2FwaXRhbGl6ZShzKSB7XG4gIHJldHVybiBzLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpICsgcy5zbGljZSgxKTtcbn1cblxuLyoqXG4gKiBUaGlzIG1ldGhvZCB3b3JrcyB0aGUgc2FtZSB3YXkgYXJyYXkucHJvdG90eXBlLm1hcCB3b3JrcyBidXQgaWYgdGhlIHRyYW5zZm9ybWVyIHJldHVybnMgdW5kZWZpbmUsIHRoZW5cbiAqIGl0IHdvbid0IGJlIGFkZGVkIHRvIHRoZSB0cmFuc2Zvcm1lZCBBcnJheS5cbiAqL1xuZnVuY3Rpb24gdHJhbnNmb3JtQXJyYXkoYXJyYXksIHRyYW5zZm9ybWVyKSB7XG4gIHZhciB0cmFuc2Zvcm1lZEFycmF5ID0gW107XG5cbiAgYXJyYXkuZm9yRWFjaChmdW5jdGlvbihpdGVtLCBpbmRleCl7XG4gICAgdmFyIHRyYW5zZm9ybWVkSXRlbSA9IHRyYW5zZm9ybWVyKGl0ZW0sIGluZGV4KTtcbiAgICBpZih1dGlsaXRpZXMuaXNEZWZpbmVkKHRyYW5zZm9ybWVkSXRlbSkpIHtcbiAgICAgIHRyYW5zZm9ybWVkQXJyYXkucHVzaCh0cmFuc2Zvcm1lZEl0ZW0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHRyYW5zZm9ybWVkQXJyYXk7XG59XG5cbmZ1bmN0aW9uIHRvRml4ZWREaWdpdHMobnVtLCBkaWdpdHMpIHtcbiAgdmFyIGZvcm1hdHRlZE51bSA9IG51bSArICcnO1xuICBkaWdpdHMgPSB1dGlsaXRpZXMuaXNOdW1iZXIoZGlnaXRzKSA/IGRpZ2l0cyA6IDA7XG4gIG51bSA9IHV0aWxpdGllcy5pc051bWJlcihudW0pID8gbnVtIDogcGFyc2VJbnQobnVtLCAxMCk7XG4gIGlmKHV0aWxpdGllcy5pc051bWJlcihudW0pICYmICFpc05hTihudW0pKXtcbiAgICBmb3JtYXR0ZWROdW0gPSBudW0gKyAnJztcbiAgICB3aGlsZShmb3JtYXR0ZWROdW0ubGVuZ3RoIDwgZGlnaXRzKSB7XG4gICAgICBmb3JtYXR0ZWROdW0gPSAnMCcgKyBmb3JtYXR0ZWROdW07XG4gICAgfVxuICAgIHJldHVybiBmb3JtYXR0ZWROdW07XG4gIH1cbiAgcmV0dXJuIE5hTiArICcnO1xufVxuXG5mdW5jdGlvbiB0aHJvdHRsZShjYWxsYmFjaywgZGVsYXkpIHtcbiAgdmFyIHByZXZpb3VzQ2FsbCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpIC0gKGRlbGF5ICsgMSk7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgIGlmICgodGltZSAtIHByZXZpb3VzQ2FsbCkgPj0gZGVsYXkpIHtcbiAgICAgIHByZXZpb3VzQ2FsbCA9IHRpbWU7XG4gICAgICBjYWxsYmFjay5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gZGVib3VuY2UgKGNhbGxiYWNrLCB3YWl0KSB7XG4gIHZhciB0aW1lb3V0SWQ7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICgpe1xuICAgIGlmKHRpbWVvdXRJZCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgfVxuICAgIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgIGNhbGxiYWNrLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB0aW1lb3V0SWQgPSB1bmRlZmluZWQ7XG4gICAgfSwgd2FpdCk7XG4gIH07XG59XG5cbi8vIGEgZnVuY3Rpb24gZGVzaWduZWQgdG8gYmxvdyB1cCB0aGUgc3RhY2sgaW4gYSBuYWl2ZSB3YXlcbi8vIGJ1dCBpdCBpcyBvayBmb3IgdmlkZW9KcyBjaGlsZHJlbiBjb21wb25lbnRzXG5mdW5jdGlvbiB0cmVlU2VhcmNoKHJvb3QsIGdldENoaWxkcmVuLCBmb3VuZCl7XG4gIHZhciBjaGlsZHJlbiA9IGdldENoaWxkcmVuKHJvb3QpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKXtcbiAgICBpZiAoZm91bmQoY2hpbGRyZW5baV0pKSB7XG4gICAgICByZXR1cm4gY2hpbGRyZW5baV07XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdmFyIGVsID0gdHJlZVNlYXJjaChjaGlsZHJlbltpXSwgZ2V0Q2hpbGRyZW4sIGZvdW5kKTtcbiAgICAgIGlmIChlbCl7XG4gICAgICAgIHJldHVybiBlbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZWNob0ZuKHZhbCkge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB2YWw7XG4gIH07XG59XG5cbi8vTm90ZTogU3VwcG9ydGVkIGZvcm1hdHMgY29tZSBmcm9tIGh0dHA6Ly93d3cudzMub3JnL1RSL05PVEUtZGF0ZXRpbWVcbi8vIGFuZCB0aGUgaXNvODYwMSByZWdleCBjb21lcyBmcm9tIGh0dHA6Ly93d3cucGVsYWdvZGVzaWduLmNvbS9ibG9nLzIwMDkvMDUvMjAvaXNvLTg2MDEtZGF0ZS12YWxpZGF0aW9uLXRoYXQtZG9lc250LXN1Y2svXG5mdW5jdGlvbiBpc0lTTzg2MDEodmFsdWUpIHtcbiAgaWYodXRpbGl0aWVzLmlzTnVtYmVyKHZhbHVlKSl7XG4gICAgdmFsdWUgPSB2YWx1ZSArICcnOyAgLy93ZSBtYWtlIHN1cmUgdGhhdCB3ZSBhcmUgd29ya2luZyB3aXRoIHN0cmluZ3NcbiAgfVxuXG4gIGlmKCF1dGlsaXRpZXMuaXNTdHJpbmcodmFsdWUpKXtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gSVNPODA4Nl9SRUdFWFAudGVzdCh2YWx1ZS50cmltKCkpO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgQnJvd3NlciBpcyBJRTkgYW5kIGJlbG93XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaXNPbGRJRSgpIHtcbiAgdmFyIHZlcnNpb24gPSB1dGlsaXRpZXMuZ2V0SW50ZXJuZXRFeHBsb3JlclZlcnNpb24obmF2aWdhdG9yKTtcbiAgaWYgKHZlcnNpb24gPT09IC0xKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHZlcnNpb24gPCAxMDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSB2ZXJzaW9uIG9mIEludGVybmV0IEV4cGxvcmVyIG9yIGEgLTEgKGluZGljYXRpbmcgdGhlIHVzZSBvZiBhbm90aGVyIGJyb3dzZXIpLlxuICogU291cmNlOiBodHRwczovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L21zNTM3NTA5KHY9dnMuODUpLmFzcHhcbiAqIEByZXR1cm5zIHtudW1iZXJ9IHRoZSB2ZXJzaW9uIG9mIEludGVybmV0IEV4cGxvcmVyIG9yIGEgLTEgKGluZGljYXRpbmcgdGhlIHVzZSBvZiBhbm90aGVyIGJyb3dzZXIpLlxuICovXG5mdW5jdGlvbiBnZXRJbnRlcm5ldEV4cGxvcmVyVmVyc2lvbihuYXZpZ2F0b3IpIHtcbiAgdmFyIHJ2ID0gLTE7XG5cbiAgaWYgKG5hdmlnYXRvci5hcHBOYW1lID09ICdNaWNyb3NvZnQgSW50ZXJuZXQgRXhwbG9yZXInKSB7XG4gICAgdmFyIHVhID0gbmF2aWdhdG9yLnVzZXJBZ2VudDtcbiAgICB2YXIgcmUgPSBuZXcgUmVnRXhwKFwiTVNJRSAoWzAtOV17MSx9W1xcLjAtOV17MCx9KVwiKTtcbiAgICB2YXIgcmVzID0gcmUuZXhlYyh1YSk7XG4gICAgaWYgKHJlcyAhPT0gbnVsbCkge1xuICAgICAgcnYgPSBwYXJzZUZsb2F0KHJlc1sxXSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJ2O1xufVxuXG4vKioqIE1vYmlsZSBVdGlsaXR5IGZ1bmN0aW9ucyAqKiovXG5mdW5jdGlvbiBpc0lEZXZpY2UoKSB7XG4gIHJldHVybiAvaVAoaG9uZXxhZCkvLnRlc3QodXRpbGl0aWVzLl9VQSk7XG59XG5cbmZ1bmN0aW9uIGlzTW9iaWxlKCkge1xuICByZXR1cm4gL2lQKGhvbmV8YWR8b2QpfEFuZHJvaWR8V2luZG93cyBQaG9uZS8udGVzdCh1dGlsaXRpZXMuX1VBKTtcbn1cblxuZnVuY3Rpb24gaXNJUGhvbmUoKSB7XG4gIHJldHVybiAvaVAoaG9uZXxvZCkvLnRlc3QodXRpbGl0aWVzLl9VQSk7XG59XG5cbmZ1bmN0aW9uIGlzQW5kcm9pZCgpIHtcbiAgcmV0dXJuIC9BbmRyb2lkLy50ZXN0KHV0aWxpdGllcy5fVUEpO1xufVxuXG52YXIgdXRpbGl0aWVzID0ge1xuICBfVUE6IG5hdmlnYXRvci51c2VyQWdlbnQsXG4gIG5vb3A6IG5vb3AsXG4gIGlzTnVsbDogaXNOdWxsLFxuICBpc0RlZmluZWQ6IGlzRGVmaW5lZCxcbiAgaXNVbmRlZmluZWQ6IGlzVW5kZWZpbmVkLFxuICBpc09iamVjdDogaXNPYmplY3QsXG4gIGlzRnVuY3Rpb246IGlzRnVuY3Rpb24sXG4gIGlzTnVtYmVyOiBpc051bWJlcixcbiAgaXNXaW5kb3c6IGlzV2luZG93LFxuICBpc0FycmF5OiBpc0FycmF5LFxuICBpc0FycmF5TGlrZTogaXNBcnJheUxpa2UsXG4gIGlzU3RyaW5nOiBpc1N0cmluZyxcbiAgaXNFbXB0eVN0cmluZzogaXNFbXB0eVN0cmluZyxcbiAgaXNOb3RFbXB0eVN0cmluZzogaXNOb3RFbXB0eVN0cmluZyxcbiAgYXJyYXlMaWtlT2JqVG9BcnJheTogYXJyYXlMaWtlT2JqVG9BcnJheSxcbiAgZm9yRWFjaDogZm9yRWFjaCxcbiAgc25ha2VfY2FzZTogc25ha2VfY2FzZSxcbiAgaXNWYWxpZEVtYWlsOiBpc1ZhbGlkRW1haWwsXG4gIGV4dGVuZDogZXh0ZW5kLFxuICBjYXBpdGFsaXplOiBjYXBpdGFsaXplLFxuICBkZWNhcGl0YWxpemU6IGRlY2FwaXRhbGl6ZSxcbiAgdHJhbnNmb3JtQXJyYXk6IHRyYW5zZm9ybUFycmF5LFxuICB0b0ZpeGVkRGlnaXRzOiB0b0ZpeGVkRGlnaXRzLFxuICB0aHJvdHRsZTogdGhyb3R0bGUsXG4gIGRlYm91bmNlOiBkZWJvdW5jZSxcbiAgdHJlZVNlYXJjaDogdHJlZVNlYXJjaCxcbiAgZWNob0ZuOiBlY2hvRm4sXG4gIGlzSVNPODYwMTogaXNJU084NjAxLFxuICBpc09sZElFOiBpc09sZElFLFxuICBnZXRJbnRlcm5ldEV4cGxvcmVyVmVyc2lvbjogZ2V0SW50ZXJuZXRFeHBsb3JlclZlcnNpb24sXG4gIGlzSURldmljZTogaXNJRGV2aWNlLFxuICBpc01vYmlsZTogaXNNb2JpbGUsXG4gIGlzSVBob25lOiBpc0lQaG9uZSxcbiAgaXNBbmRyb2lkOiBpc0FuZHJvaWRcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gdXRpbGl0aWVzOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4vdXRpbGl0eUZ1bmN0aW9ucycpO1xuXG52YXIgeG1sID0ge307XG5cbnhtbC5zdHJUb1hNTERvYyA9IGZ1bmN0aW9uIHN0clRvWE1MRG9jKHN0cmluZ0NvbnRhaW5pbmdYTUxTb3VyY2Upe1xuICAvL0lFIDhcbiAgaWYodHlwZW9mIHdpbmRvdy5ET01QYXJzZXIgPT09ICd1bmRlZmluZWQnKXtcbiAgICB2YXIgeG1sRG9jdW1lbnQgPSBuZXcgQWN0aXZlWE9iamVjdCgnTWljcm9zb2Z0LlhNTERPTScpO1xuICAgIHhtbERvY3VtZW50LmFzeW5jID0gZmFsc2U7XG4gICAgeG1sRG9jdW1lbnQubG9hZFhNTChzdHJpbmdDb250YWluaW5nWE1MU291cmNlKTtcbiAgICByZXR1cm4geG1sRG9jdW1lbnQ7XG4gIH1cblxuICByZXR1cm4gcGFyc2VTdHJpbmcoc3RyaW5nQ29udGFpbmluZ1hNTFNvdXJjZSk7XG5cbiAgZnVuY3Rpb24gcGFyc2VTdHJpbmcoc3RyaW5nQ29udGFpbmluZ1hNTFNvdXJjZSl7XG4gICAgdmFyIHBhcnNlciA9IG5ldyBET01QYXJzZXIoKTtcbiAgICB2YXIgcGFyc2VkRG9jdW1lbnQ7XG5cbiAgICAvL05vdGU6IFRoaXMgdHJ5IGNhdGNoIGlzIHRvIGRlYWwgd2l0aCB0aGUgZmFjdCB0aGF0IG9uIElFIHBhcnNlci5wYXJzZUZyb21TdHJpbmcgZG9lcyB0aHJvdyBhbiBlcnJvciBidXQgdGhlIHJlc3Qgb2YgdGhlIGJyb3dzZXJzIGRvbid0LlxuICAgIHRyeSB7XG4gICAgICBwYXJzZWREb2N1bWVudCA9IHBhcnNlci5wYXJzZUZyb21TdHJpbmcoc3RyaW5nQ29udGFpbmluZ1hNTFNvdXJjZSwgXCJhcHBsaWNhdGlvbi94bWxcIik7XG5cbiAgICAgIGlmKGlzUGFyc2VFcnJvcihwYXJzZWREb2N1bWVudCkgfHwgdXRpbGl0aWVzLmlzRW1wdHlTdHJpbmcoc3RyaW5nQ29udGFpbmluZ1hNTFNvdXJjZSkpe1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICAgIH1cbiAgICB9Y2F0Y2goZSl7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ4bWwuc3RyVG9YTUxET0M6IEVycm9yIHBhcnNpbmcgdGhlIHN0cmluZzogJ1wiICsgc3RyaW5nQ29udGFpbmluZ1hNTFNvdXJjZSArIFwiJ1wiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFyc2VkRG9jdW1lbnQ7XG4gIH1cblxuICBmdW5jdGlvbiBpc1BhcnNlRXJyb3IocGFyc2VkRG9jdW1lbnQpIHtcbiAgICB0cnkgeyAvLyBwYXJzZXIgYW5kIHBhcnNlcmVycm9yTlMgY291bGQgYmUgY2FjaGVkIG9uIHN0YXJ0dXAgZm9yIGVmZmljaWVuY3lcbiAgICAgIHZhciBwYXJzZXIgPSBuZXcgRE9NUGFyc2VyKCksXG4gICAgICAgIGVycm9uZW91c1BhcnNlID0gcGFyc2VyLnBhcnNlRnJvbVN0cmluZygnSU5WQUxJRCcsICd0ZXh0L3htbCcpLFxuICAgICAgICBwYXJzZXJlcnJvck5TID0gZXJyb25lb3VzUGFyc2UuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJwYXJzZXJlcnJvclwiKVswXS5uYW1lc3BhY2VVUkk7XG5cbiAgICAgIGlmIChwYXJzZXJlcnJvck5TID09PSAnaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCcpIHtcbiAgICAgICAgLy8gSW4gUGhhbnRvbUpTIHRoZSBwYXJzZWVycm9yIGVsZW1lbnQgZG9lc24ndCBzZWVtIHRvIGhhdmUgYSBzcGVjaWFsIG5hbWVzcGFjZSwgc28gd2UgYXJlIGp1c3QgZ3Vlc3NpbmcgaGVyZSA6KFxuICAgICAgICByZXR1cm4gcGFyc2VkRG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJwYXJzZXJlcnJvclwiKS5sZW5ndGggPiAwO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcGFyc2VkRG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyhwYXJzZXJlcnJvck5TLCAncGFyc2VyZXJyb3InKS5sZW5ndGggPiAwO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vTm90ZSBvbiBJRSBwYXJzZVN0cmluZyB0aHJvd3MgYW4gZXJyb3IgYnkgaXRzZWxmIGFuZCBpdCB3aWxsIG5ldmVyIHJlYWNoIHRoaXMgY29kZS4gQmVjYXVzZSBpdCB3aWxsIGhhdmUgZmFpbGVkIGJlZm9yZVxuICAgIH1cbiAgfVxufTtcblxueG1sLnBhcnNlVGV4dCA9IGZ1bmN0aW9uIHBhcnNlVGV4dCAoc1ZhbHVlKSB7XG4gIGlmICgvXlxccyokLy50ZXN0KHNWYWx1ZSkpIHsgcmV0dXJuIG51bGw7IH1cbiAgaWYgKC9eKD86dHJ1ZXxmYWxzZSkkL2kudGVzdChzVmFsdWUpKSB7IHJldHVybiBzVmFsdWUudG9Mb3dlckNhc2UoKSA9PT0gXCJ0cnVlXCI7IH1cbiAgaWYgKGlzRmluaXRlKHNWYWx1ZSkpIHsgcmV0dXJuIHBhcnNlRmxvYXQoc1ZhbHVlKTsgfVxuICBpZiAodXRpbGl0aWVzLmlzSVNPODYwMShzVmFsdWUpKSB7IHJldHVybiBuZXcgRGF0ZShzVmFsdWUpOyB9XG4gIHJldHVybiBzVmFsdWUudHJpbSgpO1xufTtcblxueG1sLkpYT05UcmVlID0gZnVuY3Rpb24gSlhPTlRyZWUgKG9YTUxQYXJlbnQpIHtcbiAgdmFyIHBhcnNlVGV4dCA9IHhtbC5wYXJzZVRleHQ7XG5cbiAgLy9UaGUgZG9jdW1lbnQgb2JqZWN0IGlzIGFuIGVzcGVjaWFsIG9iamVjdCB0aGF0IGl0IG1heSBtaXNzIHNvbWUgZnVuY3Rpb25zIG9yIGF0dHJzIGRlcGVuZGluZyBvbiB0aGUgYnJvd3Nlci5cbiAgLy9UbyBwcmV2ZW50IHRoaXMgcHJvYmxlbSB3aXRoIGNyZWF0ZSB0aGUgSlhPTlRyZWUgdXNpbmcgdGhlIHJvb3QgY2hpbGROb2RlIHdoaWNoIGlzIGEgZnVsbHkgZmxlc2hlZCBub2RlIG9uIGFsbCBzdXBwb3J0ZWRcbiAgLy9icm93c2Vycy5cbiAgaWYob1hNTFBhcmVudC5kb2N1bWVudEVsZW1lbnQpe1xuICAgIHJldHVybiBuZXcgeG1sLkpYT05UcmVlKG9YTUxQYXJlbnQuZG9jdW1lbnRFbGVtZW50KTtcbiAgfVxuXG4gIGlmIChvWE1MUGFyZW50Lmhhc0NoaWxkTm9kZXMoKSkge1xuICAgIHZhciBzQ29sbGVjdGVkVHh0ID0gXCJcIjtcbiAgICBmb3IgKHZhciBvTm9kZSwgc1Byb3AsIHZDb250ZW50LCBuSXRlbSA9IDA7IG5JdGVtIDwgb1hNTFBhcmVudC5jaGlsZE5vZGVzLmxlbmd0aDsgbkl0ZW0rKykge1xuICAgICAgb05vZGUgPSBvWE1MUGFyZW50LmNoaWxkTm9kZXMuaXRlbShuSXRlbSk7XG4gICAgICAvKmpzaGludCBiaXR3aXNlOiBmYWxzZSovXG4gICAgICBpZiAoKG9Ob2RlLm5vZGVUeXBlIC0gMSB8IDEpID09PSAzKSB7IHNDb2xsZWN0ZWRUeHQgKz0gb05vZGUubm9kZVR5cGUgPT09IDMgPyBvTm9kZS5ub2RlVmFsdWUudHJpbSgpIDogb05vZGUubm9kZVZhbHVlOyB9XG4gICAgICBlbHNlIGlmIChvTm9kZS5ub2RlVHlwZSA9PT0gMSAmJiAhb05vZGUucHJlZml4KSB7XG4gICAgICAgIHNQcm9wID0gdXRpbGl0aWVzLmRlY2FwaXRhbGl6ZShvTm9kZS5ub2RlTmFtZSk7XG4gICAgICAgIHZDb250ZW50ID0gbmV3IHhtbC5KWE9OVHJlZShvTm9kZSk7XG4gICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KHNQcm9wKSkge1xuICAgICAgICAgIGlmICh0aGlzW3NQcm9wXS5jb25zdHJ1Y3RvciAhPT0gQXJyYXkpIHsgdGhpc1tzUHJvcF0gPSBbdGhpc1tzUHJvcF1dOyB9XG4gICAgICAgICAgdGhpc1tzUHJvcF0ucHVzaCh2Q29udGVudCk7XG4gICAgICAgIH0gZWxzZSB7IHRoaXNbc1Byb3BdID0gdkNvbnRlbnQ7IH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHNDb2xsZWN0ZWRUeHQpIHsgdGhpcy5rZXlWYWx1ZSA9IHBhcnNlVGV4dChzQ29sbGVjdGVkVHh0KTsgfVxuICB9XG5cbiAgLy9JRTggU3R1cGlkIGZpeFxuICB2YXIgaGFzQXR0ciA9IHR5cGVvZiBvWE1MUGFyZW50Lmhhc0F0dHJpYnV0ZXMgPT09ICd1bmRlZmluZWQnPyBvWE1MUGFyZW50LmF0dHJpYnV0ZXMubGVuZ3RoID4gMDogb1hNTFBhcmVudC5oYXNBdHRyaWJ1dGVzKCk7XG4gIGlmIChoYXNBdHRyKSB7XG4gICAgdmFyIG9BdHRyaWI7XG4gICAgZm9yICh2YXIgbkF0dHJpYiA9IDA7IG5BdHRyaWIgPCBvWE1MUGFyZW50LmF0dHJpYnV0ZXMubGVuZ3RoOyBuQXR0cmliKyspIHtcbiAgICAgIG9BdHRyaWIgPSBvWE1MUGFyZW50LmF0dHJpYnV0ZXMuaXRlbShuQXR0cmliKTtcbiAgICAgIHRoaXNbXCJAXCIgKyB1dGlsaXRpZXMuZGVjYXBpdGFsaXplKG9BdHRyaWIubmFtZSldID0gcGFyc2VUZXh0KG9BdHRyaWIudmFsdWUudHJpbSgpKTtcbiAgICB9XG4gIH1cbn07XG5cbnhtbC5KWE9OVHJlZS5wcm90b3R5cGUuYXR0ciA9IGZ1bmN0aW9uKGF0dHIpIHtcbiAgcmV0dXJuIHRoaXNbJ0AnICsgdXRpbGl0aWVzLmRlY2FwaXRhbGl6ZShhdHRyKV07XG59O1xuXG54bWwudG9KWE9OVHJlZSA9IGZ1bmN0aW9uIHRvSlhPTlRyZWUoeG1sU3RyaW5nKXtcbiAgdmFyIHhtbERvYyA9IHhtbC5zdHJUb1hNTERvYyh4bWxTdHJpbmcpO1xuICByZXR1cm4gbmV3IHhtbC5KWE9OVHJlZSh4bWxEb2MpO1xufTtcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gZXh0cmFjdCB0aGUga2V5dmFsdWUgb2YgYSBKWE9OVHJlZSBvYmpcbiAqXG4gKiBAcGFyYW0geG1sT2JqIHtKWE9OVHJlZX1cbiAqIHJldHVybiB0aGUga2V5IHZhbHVlIG9yIHVuZGVmaW5lZDtcbiAqL1xueG1sLmtleVZhbHVlID0gZnVuY3Rpb24gZ2V0S2V5VmFsdWUoeG1sT2JqKSB7XG4gIGlmKHhtbE9iail7XG4gICAgcmV0dXJuIHhtbE9iai5rZXlWYWx1ZTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufTtcblxueG1sLmF0dHIgPSBmdW5jdGlvbiBnZXRBdHRyVmFsdWUoeG1sT2JqLCBhdHRyKSB7XG4gIGlmKHhtbE9iaikge1xuICAgIHJldHVybiB4bWxPYmpbJ0AnICsgdXRpbGl0aWVzLmRlY2FwaXRhbGl6ZShhdHRyKV07XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn07XG5cbnhtbC5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGVYTUwoc3RyKSB7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvJi9nLCAnJmFtcDsnKVxuICAgIC5yZXBsYWNlKC88L2csICcmbHQ7JylcbiAgICAucmVwbGFjZSgvPi9nLCAnJmd0OycpXG4gICAgLnJlcGxhY2UoL1wiL2csICcmcXVvdDsnKVxuICAgIC5yZXBsYWNlKC8nL2csICcmYXBvczsnKTtcbn07XG5cbnhtbC5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGVYTUwoc3RyKSB7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvJmFwb3M7L2csIFwiJ1wiKVxuICAgIC5yZXBsYWNlKC8mcXVvdDsvZywgJ1wiJylcbiAgICAucmVwbGFjZSgvJmd0Oy9nLCAnPicpXG4gICAgLnJlcGxhY2UoLyZsdDsvZywgJzwnKVxuICAgIC5yZXBsYWNlKC8mYW1wOy9nLCAnJicpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB4bWw7IiwiJ3VzZSBzdHJpY3QnO1xuXG5yZXF1aXJlKCcuL3BsdWdpbi9jb21wb25lbnRzL2Fkcy1sYWJlbF81Jyk7XG5yZXF1aXJlKCcuL3BsdWdpbi9jb21wb25lbnRzL2JsYWNrLXBvc3Rlcl81Jyk7XG5cbnZhciB2aWRlb0pzVkFTVCA9IHJlcXVpcmUoJy4vcGx1Z2luL3ZpZGVvanMudmFzdC52cGFpZCcpO1xuXG52aWRlb2pzLnBsdWdpbigndmFzdENsaWVudCcsIHZpZGVvSnNWQVNUKTtcbiJdfQ== +},{"./plugin/components/ads-label_5":34,"./plugin/components/black-poster_5":36,"./plugin/videojs.vast.vpaid":37}]},{},[45]) +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlERkxBU0hDbGllbnQvanMvSVZQQUlEQWRVbml0LmpzIiwiYm93ZXJfY29tcG9uZW50cy9WUEFJREZMQVNIQ2xpZW50L2pzL1ZQQUlEQWRVbml0LmpzIiwiYm93ZXJfY29tcG9uZW50cy9WUEFJREZMQVNIQ2xpZW50L2pzL1ZQQUlERkxBU0hDbGllbnQuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlERkxBU0hDbGllbnQvanMvanNGbGFzaEJyaWRnZS5qcyIsImJvd2VyX2NvbXBvbmVudHMvVlBBSURGTEFTSENsaWVudC9qcy9qc0ZsYXNoQnJpZGdlUmVnaXN0cnkuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlERkxBU0hDbGllbnQvanMvcmVnaXN0cnkuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlERkxBU0hDbGllbnQvanMvdXRpbHMuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlESFRNTDVDbGllbnQvanMvSVZQQUlEQWRVbml0LmpzIiwiYm93ZXJfY29tcG9uZW50cy9WUEFJREhUTUw1Q2xpZW50L2pzL1ZQQUlEQWRVbml0LmpzIiwiYm93ZXJfY29tcG9uZW50cy9WUEFJREhUTUw1Q2xpZW50L2pzL1ZQQUlESFRNTDVDbGllbnQuanMiLCJib3dlcl9jb21wb25lbnRzL1ZQQUlESFRNTDVDbGllbnQvanMvc3Vic2NyaWJlci5qcyIsImJvd2VyX2NvbXBvbmVudHMvVlBBSURIVE1MNUNsaWVudC9qcy91dGlscy5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L0FkLmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvQ29tcGFuaW9uLmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvQ3JlYXRpdmUuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9JbkxpbmUuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9MaW5lYXIuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9NZWRpYUZpbGUuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9UcmFja2luZ0V2ZW50LmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvVkFTVENsaWVudC5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L1ZBU1RFcnJvci5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L1ZBU1RJbnRlZ3JhdG9yLmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvVkFTVFJlc3BvbnNlLmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvVkFTVFRyYWNrZXIuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9WaWRlb0NsaWNrcy5qcyIsInNyYy9zY3JpcHRzL2Fkcy92YXN0L1dyYXBwZXIuanMiLCJzcmMvc2NyaXB0cy9hZHMvdmFzdC9wYXJzZXJzLmpzIiwic3JjL3NjcmlwdHMvYWRzL3Zhc3QvdmFzdFV0aWwuanMiLCJzcmMvc2NyaXB0cy9hZHMvdnBhaWQvVlBBSURBZFVuaXRXcmFwcGVyLmpzIiwic3JjL3NjcmlwdHMvYWRzL3ZwYWlkL1ZQQUlERmxhc2hUZWNoLmpzIiwic3JjL3NjcmlwdHMvYWRzL3ZwYWlkL1ZQQUlESFRNTDVUZWNoLmpzIiwic3JjL3NjcmlwdHMvYWRzL3ZwYWlkL1ZQQUlESW50ZWdyYXRvci5qcyIsInNyYy9zY3JpcHRzL3BsdWdpbi9jb21wb25lbnRzL2Fkcy1sYWJlbC5qcyIsInNyYy9zY3JpcHRzL3BsdWdpbi9jb21wb25lbnRzL2Fkcy1sYWJlbF81LmpzIiwic3JjL3NjcmlwdHMvcGx1Z2luL2NvbXBvbmVudHMvYmxhY2stcG9zdGVyLmpzIiwic3JjL3NjcmlwdHMvcGx1Z2luL2NvbXBvbmVudHMvYmxhY2stcG9zdGVyXzUuanMiLCJzcmMvc2NyaXB0cy9wbHVnaW4vdmlkZW9qcy52YXN0LnZwYWlkLmpzIiwic3JjL3NjcmlwdHMvdXRpbHMvYXN5bmMuanMiLCJzcmMvc2NyaXB0cy91dGlscy9kb20uanMiLCJzcmMvc2NyaXB0cy91dGlscy9odHRwLmpzIiwic3JjL3NjcmlwdHMvdXRpbHMvcGxheWVyVXRpbHMuanMiLCJzcmMvc2NyaXB0cy91dGlscy91cmxVdGlscy5qcyIsInNyYy9zY3JpcHRzL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMuanMiLCJzcmMvc2NyaXB0cy91dGlscy94bWwuanMiLCJzcmMvc2NyaXB0cy92aWRlb2pzXzUudmFzdC52cGFpZC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBOzs7Ozs7Ozs7Ozs7SUFHYTs7Ozs7Ozs7OzsyQ0FJMEQ7Z0JBQWxELDJFQUFxQixxQkFBNkI7Z0JBQXRCLGlFQUFXLHlCQUFXOzs7Ozs7OytCQUczRCxPQUFPLFFBQVEsVUFBVSxnQkFBMkc7Z0JBQTNGLHFFQUFlLEVBQUMsY0FBYSxFQUFiLGtCQUEyRTtnQkFBekQsd0VBQWtCLEVBQUMsV0FBVyxFQUFYLGtCQUFzQztnQkFBdEIsaUVBQVcseUJBQVc7Ozs7aUNBQ25JLE9BQU8sUUFBUSxVQUFnQztnQkFBdEIsaUVBQVcseUJBQVc7Ozs7a0NBRTFCO2dCQUF0QixpRUFBVyx5QkFBVzs7OztpQ0FDRDtnQkFBdEIsaUVBQVcseUJBQVc7Ozs7a0NBQ0M7Z0JBQXRCLGlFQUFXLHlCQUFXOzs7O21DQUNDO2dCQUF0QixpRUFBVyx5QkFBVzs7OzttQ0FDQTtnQkFBdEIsaUVBQVcseUJBQVc7Ozs7cUNBQ0U7Z0JBQXRCLGlFQUFXLHlCQUFXOzs7O2lDQUNKO2dCQUF0QixpRUFBVyx5QkFBVzs7Ozs7OztvQ0FHakIsVUFBVTs7O21DQUNYLFVBQVU7OztvQ0FDVCxVQUFVOzs7c0NBQ1IsVUFBVTs7OzRDQUNKLFVBQVU7OzsyQ0FDWCxVQUFVOzs7c0NBQ2YsVUFBVTs7O29DQUNaLGFBQW1DO2dCQUF0QixpRUFBVyx5QkFBVzs7OztvQ0FDbkMsVUFBVTs7O3dDQUNOLFVBQVU7OzttQ0FDZixVQUFVOzs7V0E3Qlo7OztBQWdDYixPQUFPLGNBQVAsQ0FBc0IsWUFBdEIsRUFBb0MsUUFBcEMsRUFBOEM7QUFDMUMsY0FBVSxLQUFWO0FBQ0Esa0JBQWMsS0FBZDtBQUNBLFdBQU8sQ0FD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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3UkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDck5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeExBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2aUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeFVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdE5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNySkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDellBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdFVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIndXNlIHN0cmljdCc7XG5cbi8vc2ltcGxlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBBUElcbmV4cG9ydCBjbGFzcyBJVlBBSURBZFVuaXQge1xuXG4gICAgLy9hbGwgbWV0aG9kcyBiZWxvd1xuICAgIC8vYXJlIGFzeW5jIG1ldGhvZHNcbiAgICBoYW5kc2hha2VWZXJzaW9uKHBsYXllclZQQUlEVmVyc2lvbiA9ICcyLjAnLCBjYWxsYmFjayA9IHVuZGVmaW5lZCkge31cblxuICAgIC8vY3JlYXRpdmVEYXRhIGlzIGFuIG9iamVjdCB0byBiZSBjb25zaXN0ZW50IHdpdGggVlBBSURIVE1MXG4gICAgaW5pdEFkICh3aWR0aCwgaGVpZ2h0LCB2aWV3TW9kZSwgZGVzaXJlZEJpdHJhdGUsIGNyZWF0aXZlRGF0YSA9IHtBZFBhcmFtZXRlcnM6Jyd9LCBlbnZpcm9ubWVudFZhcnMgPSB7Zmxhc2hWYXJzOiAnJ30sIGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7fVxuICAgIHJlc2l6ZUFkKHdpZHRoLCBoZWlnaHQsIHZpZXdNb2RlLCBjYWxsYmFjayA9IHVuZGVmaW5lZCkge31cblxuICAgIHN0YXJ0QWQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHt9XG4gICAgc3RvcEFkKGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7fVxuICAgIHBhdXNlQWQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHt9XG4gICAgcmVzdW1lQWQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHt9XG4gICAgZXhwYW5kQWQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHt9XG4gICAgY29sbGFwc2VBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge31cbiAgICBza2lwQWQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHt9XG5cbiAgICAvL3Byb3BlcnRpZXMgdGhhdCB3aWxsIGJlIHRyZWF0IGFzIGFzeW5jIG1ldGhvZHNcbiAgICBnZXRBZExpbmVhcihjYWxsYmFjaykge31cbiAgICBnZXRBZFdpZHRoKGNhbGxiYWNrKSB7fVxuICAgIGdldEFkSGVpZ2h0KGNhbGxiYWNrKSB7fVxuICAgIGdldEFkRXhwYW5kZWQoY2FsbGJhY2spIHt9XG4gICAgZ2V0QWRTa2lwcGFibGVTdGF0ZShjYWxsYmFjaykge31cbiAgICBnZXRBZFJlbWFpbmluZ1RpbWUoY2FsbGJhY2spIHt9XG4gICAgZ2V0QWREdXJhdGlvbihjYWxsYmFjaykge31cbiAgICBzZXRBZFZvbHVtZShzb3VuZFZvbHVtZSwgY2FsbGJhY2sgPSB1bmRlZmluZWQpIHt9XG4gICAgZ2V0QWRWb2x1bWUoY2FsbGJhY2spIHt9XG4gICAgZ2V0QWRDb21wYW5pb25zKGNhbGxiYWNrKSB7fVxuICAgIGdldEFkSWNvbnMoY2FsbGJhY2spIHt9XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShJVlBBSURBZFVuaXQsICdFVkVOVFMnLCB7XG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgdmFsdWU6IFtcbiAgICAgICAgJ0FkTG9hZGVkJyxcbiAgICAgICAgJ0FkU3RhcnRlZCcsXG4gICAgICAgICdBZFN0b3BwZWQnLFxuICAgICAgICAnQWRTa2lwcGVkJyxcbiAgICAgICAgJ0FkU2tpcHBhYmxlU3RhdGVDaGFuZ2UnLCAvLyBWUEFJRCAyLjAgbmV3IGV2ZW50XG4gICAgICAgICdBZFNpemVDaGFuZ2UnLCAvLyBWUEFJRCAyLjAgbmV3IGV2ZW50XG4gICAgICAgICdBZExpbmVhckNoYW5nZScsXG4gICAgICAgICdBZER1cmF0aW9uQ2hhbmdlJywgLy8gVlBBSUQgMi4wIG5ldyBldmVudFxuICAgICAgICAnQWRFeHBhbmRlZENoYW5nZScsXG4gICAgICAgICdBZFJlbWFpbmluZ1RpbWVDaGFuZ2UnLCAvLyBbRGVwcmVjYXRlZCBpbiAyLjBdIGJ1dCB3aWxsIGJlIHN0aWxsIGZpcmVkIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxuICAgICAgICAnQWRWb2x1bWVDaGFuZ2UnLFxuICAgICAgICAnQWRJbXByZXNzaW9uJyxcbiAgICAgICAgJ0FkVmlkZW9TdGFydCcsXG4gICAgICAgICdBZFZpZGVvRmlyc3RRdWFydGlsZScsXG4gICAgICAgICdBZFZpZGVvTWlkcG9pbnQnLFxuICAgICAgICAnQWRWaWRlb1RoaXJkUXVhcnRpbGUnLFxuICAgICAgICAnQWRWaWRlb0NvbXBsZXRlJyxcbiAgICAgICAgJ0FkQ2xpY2tUaHJ1JyxcbiAgICAgICAgJ0FkSW50ZXJhY3Rpb24nLCAvLyBWUEFJRCAyLjAgbmV3IGV2ZW50XG4gICAgICAgICdBZFVzZXJBY2NlcHRJbnZpdGF0aW9uJyxcbiAgICAgICAgJ0FkVXNlck1pbmltaXplJyxcbiAgICAgICAgJ0FkVXNlckNsb3NlJyxcbiAgICAgICAgJ0FkUGF1c2VkJyxcbiAgICAgICAgJ0FkUGxheWluZycsXG4gICAgICAgICdBZExvZycsXG4gICAgICAgICdBZEVycm9yJ1xuICAgIF1cbn0pO1xuXG4iLCIndXNlIHN0cmljdCc7XG5cbmxldCBJVlBBSURBZFVuaXQgPSByZXF1aXJlKCcuL0lWUEFJREFkVW5pdCcpLklWUEFJREFkVW5pdDtcbmxldCBBTExfVlBBSURfTUVUSE9EUyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKElWUEFJREFkVW5pdC5wcm90b3R5cGUpLmZpbHRlcihmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICByZXR1cm4gWydjb25zdHJ1Y3RvciddLmluZGV4T2YocHJvcGVydHkpID09PSAtMTtcbn0pO1xuXG5leHBvcnQgY2xhc3MgVlBBSURBZFVuaXQgZXh0ZW5kcyBJVlBBSURBZFVuaXQge1xuICAgIGNvbnN0cnVjdG9yIChmbGFzaCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLl9kZXN0cm95ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fZmxhc2ggPSBmbGFzaDtcbiAgICB9XG5cbiAgICBfZGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5fZGVzdHJveWVkID0gdHJ1ZTtcbiAgICAgICAgQUxMX1ZQQUlEX01FVEhPRFMuZm9yRWFjaCgobWV0aG9kTmFtZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fZmxhc2gucmVtb3ZlQ2FsbGJhY2tCeU1ldGhvZE5hbWUobWV0aG9kTmFtZSk7XG4gICAgICAgIH0pO1xuICAgICAgICBJVlBBSURBZFVuaXQuRVZFTlRTLmZvckVhY2goKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9mbGFzaC5vZmZFdmVudChldmVudCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuX2ZsYXNoID0gbnVsbDtcbiAgICB9XG5cbiAgICBpc0Rlc3Ryb3llZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZXN0cm95ZWQ7XG4gICAgfVxuXG4gICAgb24oZXZlbnROYW1lLCBjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9mbGFzaC5vbihldmVudE5hbWUsIGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICBvZmYoZXZlbnROYW1lLCBjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9mbGFzaC5vZmYoZXZlbnROYW1lLCBjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgLy9WUEFJRCBpbnRlcmZhY2VcbiAgICBoYW5kc2hha2VWZXJzaW9uKHBsYXllclZQQUlEVmVyc2lvbiA9ICcyLjAnLCBjYWxsYmFjayA9IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2hhbmRzaGFrZVZlcnNpb24nLCBbcGxheWVyVlBBSURWZXJzaW9uXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBpbml0QWQgKHdpZHRoLCBoZWlnaHQsIHZpZXdNb2RlLCBkZXNpcmVkQml0cmF0ZSwgY3JlYXRpdmVEYXRhID0ge0FkUGFyYW1ldGVyczogJyd9LCBlbnZpcm9ubWVudFZhcnMgPSB7Zmxhc2hWYXJzOiAnJ30sIGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vcmVzaXplIGVsZW1lbnQgdGhhdCBoYXMgdGhlIGZsYXNoIG9iamVjdFxuICAgICAgICB0aGlzLl9mbGFzaC5zZXRTaXplKHdpZHRoLCBoZWlnaHQpO1xuICAgICAgICBjcmVhdGl2ZURhdGEgPSBjcmVhdGl2ZURhdGEgfHwge0FkUGFyYW1ldGVyczogJyd9O1xuICAgICAgICBlbnZpcm9ubWVudFZhcnMgPSBlbnZpcm9ubWVudFZhcnMgfHwge2ZsYXNoVmFyczogJyd9O1xuXG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnaW5pdEFkJywgW3RoaXMuX2ZsYXNoLmdldFdpZHRoKCksIHRoaXMuX2ZsYXNoLmdldEhlaWdodCgpLCB2aWV3TW9kZSwgZGVzaXJlZEJpdHJhdGUsIGNyZWF0aXZlRGF0YS5BZFBhcmFtZXRlcnMgfHwgJycsIGVudmlyb25tZW50VmFycy5mbGFzaFZhcnMgfHwgJyddLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIHJlc2l6ZUFkKHdpZHRoLCBoZWlnaHQsIHZpZXdNb2RlLCBjYWxsYmFjayA9IHVuZGVmaW5lZCkge1xuICAgICAgICAvL3Jlc2l6ZSBlbGVtZW50IHRoYXQgaGFzIHRoZSBmbGFzaCBvYmplY3RcbiAgICAgICAgdGhpcy5fZmxhc2guc2V0U2l6ZSh3aWR0aCwgaGVpZ2h0KTtcblxuICAgICAgICAvL3Jlc2l6ZSBhZCBpbnNpZGUgdGhlIGZsYXNoXG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgncmVzaXplQWQnLCBbdGhpcy5fZmxhc2guZ2V0V2lkdGgoKSwgdGhpcy5fZmxhc2guZ2V0SGVpZ2h0KCksIHZpZXdNb2RlXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBzdGFydEFkKGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnc3RhcnRBZCcsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIHN0b3BBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ3N0b3BBZCcsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIHBhdXNlQWQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdwYXVzZUFkJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgcmVzdW1lQWQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdyZXN1bWVBZCcsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGV4cGFuZEFkKGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnZXhwYW5kQWQnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBjb2xsYXBzZUFkKGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnY29sbGFwc2VBZCcsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIHNraXBBZChjYWxsYmFjayA9IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ3NraXBBZCcsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgLy9wcm9wZXJ0aWVzIHRoYXQgd2lsbCBiZSB0cmVhdCBhcyBhc3luYyBtZXRob2RzXG4gICAgZ2V0QWRMaW5lYXIoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdnZXRBZExpbmVhcicsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGdldEFkV2lkdGgoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdnZXRBZFdpZHRoJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgZ2V0QWRIZWlnaHQoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdnZXRBZEhlaWdodCcsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGdldEFkRXhwYW5kZWQoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdnZXRBZEV4cGFuZGVkJywgW10sIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgZ2V0QWRTa2lwcGFibGVTdGF0ZShjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ2dldEFkU2tpcHBhYmxlU3RhdGUnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBnZXRBZFJlbWFpbmluZ1RpbWUoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdnZXRBZFJlbWFpbmluZ1RpbWUnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBnZXRBZER1cmF0aW9uKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnZ2V0QWREdXJhdGlvbicsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIHNldEFkVm9sdW1lKHZvbHVtZSwgY2FsbGJhY2sgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdzZXRBZFZvbHVtZScsIFt2b2x1bWVdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGdldEFkVm9sdW1lKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnZ2V0QWRWb2x1bWUnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBnZXRBZENvbXBhbmlvbnMoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fZmxhc2guY2FsbEZsYXNoTWV0aG9kKCdnZXRBZENvbXBhbmlvbnMnLCBbXSwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBnZXRBZEljb25zKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnZ2V0QWRJY29ucycsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxufVxuXG4iLCIndXNlIHN0cmljdCc7XG5cbmxldCBKU0ZsYXNoQnJpZGdlID0gcmVxdWlyZSgnLi9qc0ZsYXNoQnJpZGdlJykuSlNGbGFzaEJyaWRnZTtcbmxldCBWUEFJREFkVW5pdCA9IHJlcXVpcmUoJy4vVlBBSURBZFVuaXQnKS5WUEFJREFkVW5pdDtcblxubGV0IG5vb3AgPSByZXF1aXJlKCcuL3V0aWxzJykubm9vcDtcbmxldCBjYWxsYmFja1RpbWVvdXQgPSByZXF1aXJlKCcuL3V0aWxzJykuY2FsbGJhY2tUaW1lb3V0O1xubGV0IGlzUG9zaXRpdmVJbnQgPSByZXF1aXJlKCcuL3V0aWxzJykuaXNQb3NpdGl2ZUludDtcbmxldCBjcmVhdGVFbGVtZW50V2l0aElEID0gcmVxdWlyZSgnLi91dGlscycpLmNyZWF0ZUVsZW1lbnRXaXRoSUQ7XG5sZXQgdW5pcXVlVlBBSUQgPSByZXF1aXJlKCcuL3V0aWxzJykudW5pcXVlKCd2cGFpZCcpO1xuXG5jb25zdCBFUlJPUiA9ICdlcnJvcic7XG5jb25zdCBGTEFTSF9WRVJTSU9OID0gJzEwLjEuMCc7XG5cbmNsYXNzIFZQQUlERkxBU0hDbGllbnQge1xuICAgIGNvbnN0cnVjdG9yICh2cGFpZFBhcmVudEVsLCBjYWxsYmFjaywgc3dmQ29uZmlnID0ge2RhdGE6ICdWUEFJREZsYXNoLnN3ZicsIHdpZHRoOiA4MDAsIGhlaWdodDogNDAwfSwgcGFyYW1zID0geyB3bW9kZTogJ3RyYW5zcGFyZW50Jywgc2FsaWduOiAndGwnLCBhbGlnbjogJ2xlZnQnLCBhbGxvd1NjcmlwdEFjY2VzczogJ2Fsd2F5cycsIHNjYWxlOiAnbm9TY2FsZScsIGFsbG93RnVsbFNjcmVlbjogJ3RydWUnLCBxdWFsaXR5OiAnaGlnaCd9LCB2cGFpZE9wdGlvbnMgPSB7IGRlYnVnOiBmYWxzZSwgdGltZW91dDogMTAwMDAgfSkge1xuXG4gICAgICAgIGlmICghVlBBSURGTEFTSENsaWVudC5oYXNFeHRlcm5hbERlcGVuZGVuY2llcygpKSB7XG4gICAgICAgICAgICByZXR1cm4gb25FcnJvcignbm8gc3dmb2JqZWN0IGluIGdsb2JhbCBzY29wZS4gY2hlY2s6IGh0dHBzOi8vZ2l0aHViLmNvbS9zd2ZvYmplY3Qvc3dmb2JqZWN0IG9yIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3Avc3dmb2JqZWN0LycpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fdnBhaWRQYXJlbnRFbCA9IHZwYWlkUGFyZW50RWw7XG4gICAgICAgIHRoaXMuX2ZsYXNoSUQgPSB1bmlxdWVWUEFJRCgpO1xuICAgICAgICB0aGlzLl9kZXN0cm95ZWQgPSBmYWxzZTtcbiAgICAgICAgY2FsbGJhY2sgPSBjYWxsYmFjayB8fCBub29wO1xuXG4gICAgICAgIHN3ZkNvbmZpZy53aWR0aCA9IGlzUG9zaXRpdmVJbnQoc3dmQ29uZmlnLndpZHRoLCA4MDApO1xuICAgICAgICBzd2ZDb25maWcuaGVpZ2h0ID0gaXNQb3NpdGl2ZUludChzd2ZDb25maWcuaGVpZ2h0LCA0MDApO1xuXG4gICAgICAgIGNyZWF0ZUVsZW1lbnRXaXRoSUQodnBhaWRQYXJlbnRFbCwgdGhpcy5fZmxhc2hJRCk7XG5cbiAgICAgICAgcGFyYW1zLm1vdmllID0gc3dmQ29uZmlnLmRhdGE7XG4gICAgICAgIHBhcmFtcy5GbGFzaFZhcnMgPSBgZmxhc2hpZD0ke3RoaXMuX2ZsYXNoSUR9JmhhbmRsZXI9JHtKU0ZsYXNoQnJpZGdlLlZQQUlEX0ZMQVNIX0hBTkRMRVJ9JmRlYnVnPSR7dnBhaWRPcHRpb25zLmRlYnVnfSZzYWxpZ249JHtwYXJhbXMuc2FsaWdufWA7XG5cbiAgICAgICAgaWYgKCFWUEFJREZMQVNIQ2xpZW50LmlzU3VwcG9ydGVkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBvbkVycm9yKCd1c2VyIGRvblxcJ3Qgc3VwcG9ydCBmbGFzaCBvciBkb2VzblxcJ3QgaGF2ZSB0aGUgbWluaW11bSByZXF1aXJlZCB2ZXJzaW9uIG9mIGZsYXNoICcgKyBGTEFTSF9WRVJTSU9OKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWwgPSBzd2ZvYmplY3QuY3JlYXRlU1dGKHN3ZkNvbmZpZywgcGFyYW1zLCB0aGlzLl9mbGFzaElEKTtcblxuICAgICAgICBpZiAoIXRoaXMuZWwpIHtcbiAgICAgICAgICAgIHJldHVybiBvbkVycm9yKCAnc3dmb2JqZWN0IGZhaWxlZCB0byBjcmVhdGUgb2JqZWN0IGluIGVsZW1lbnQnICk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaGFuZGxlciA9IGNhbGxiYWNrVGltZW91dCh2cGFpZE9wdGlvbnMudGltZW91dCxcbiAgICAgICAgICAgIChlcnIsIGRhdGEpID0+IHtcbiAgICAgICAgICAgICAgICAkbG9hZFBlbmRlZEFkVW5pdC5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVyciwgZGF0YSk7XG4gICAgICAgICAgICB9LCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soICd2cGFpZCBmbGFzaCBsb2FkIHRpbWVvdXQgJyArIHZwYWlkT3B0aW9ucy50aW1lb3V0ICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5fZmxhc2ggPSBuZXcgSlNGbGFzaEJyaWRnZSh0aGlzLmVsLCBzd2ZDb25maWcuZGF0YSwgdGhpcy5fZmxhc2hJRCwgc3dmQ29uZmlnLndpZHRoLCBzd2ZDb25maWcuaGVpZ2h0LCBoYW5kbGVyKTtcblxuICAgICAgICBmdW5jdGlvbiBvbkVycm9yKGVycm9yKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhuZXcgRXJyb3IoZXJyb3IpKTtcbiAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgIH1cblxuICAgIGRlc3Ryb3kgKCkge1xuICAgICAgICB0aGlzLl9kZXN0cm95QWRVbml0KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuX2ZsYXNoKSB7XG4gICAgICAgICAgICB0aGlzLl9mbGFzaC5kZXN0cm95KCk7XG4gICAgICAgICAgICB0aGlzLl9mbGFzaCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lbCA9IG51bGw7XG4gICAgICAgIHRoaXMuX2Rlc3Ryb3llZCA9IHRydWU7XG4gICAgfVxuXG4gICAgaXNEZXN0cm95ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVzdHJveWVkO1xuICAgIH1cblxuICAgIF9kZXN0cm95QWRVbml0KCkge1xuICAgICAgICBkZWxldGUgdGhpcy5fbG9hZExhdGVyO1xuXG4gICAgICAgIGlmICh0aGlzLl9hZFVuaXRMb2FkKSB7XG4gICAgICAgICAgICB0aGlzLl9hZFVuaXRMb2FkID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX2ZsYXNoLnJlbW92ZUNhbGxiYWNrKHRoaXMuX2FkVW5pdExvYWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuX2FkVW5pdCkge1xuICAgICAgICAgICAgdGhpcy5fYWRVbml0Ll9kZXN0cm95KCk7XG4gICAgICAgICAgICB0aGlzLl9hZFVuaXQgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbG9hZEFkVW5pdChhZFVSTCwgY2FsbGJhY2spIHtcbiAgICAgICAgJHRocm93SWZEZXN0cm95ZWQuY2FsbCh0aGlzKTtcblxuICAgICAgICBpZiAodGhpcy5fYWRVbml0KSB7XG4gICAgICAgICAgICB0aGlzLl9kZXN0cm95QWRVbml0KCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fZmxhc2guaXNSZWFkeSgpKSB7XG4gICAgICAgICAgICB0aGlzLl9hZFVuaXRMb2FkID0gKGVyciwgbWVzc2FnZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2FkVW5pdCA9IG5ldyBWUEFJREFkVW5pdCh0aGlzLl9mbGFzaCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX2FkVW5pdExvYWQgPSBudWxsO1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVyciwgdGhpcy5fYWRVbml0KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMuX2ZsYXNoLmNhbGxGbGFzaE1ldGhvZCgnbG9hZEFkVW5pdCcsIFthZFVSTF0sIHRoaXMuX2FkVW5pdExvYWQpO1xuICAgICAgICB9ZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9sb2FkTGF0ZXIgPSB7dXJsOiBhZFVSTCwgY2FsbGJhY2t9O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdW5sb2FkQWRVbml0KGNhbGxiYWNrID0gdW5kZWZpbmVkKSB7XG4gICAgICAgICR0aHJvd0lmRGVzdHJveWVkLmNhbGwodGhpcyk7XG5cbiAgICAgICAgdGhpcy5fZGVzdHJveUFkVW5pdCgpO1xuICAgICAgICB0aGlzLl9mbGFzaC5jYWxsRmxhc2hNZXRob2QoJ3VubG9hZEFkVW5pdCcsIFtdLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGdldEZsYXNoSUQoKSB7XG4gICAgICAgICR0aHJvd0lmRGVzdHJveWVkLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzLl9mbGFzaC5nZXRGbGFzaElEKCk7XG4gICAgfVxuICAgIGdldEZsYXNoVVJMKCkge1xuICAgICAgICAkdGhyb3dJZkRlc3Ryb3llZC5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdGhpcy5fZmxhc2guZ2V0Rmxhc2hVUkwoKTtcbiAgICB9XG59XG5cbnNldFN0YXRpY1Byb3BlcnR5KCdpc1N1cHBvcnRlZCcsICgpID0+IHtcbiAgICByZXR1cm4gVlBBSURGTEFTSENsaWVudC5oYXNFeHRlcm5hbERlcGVuZGVuY2llcygpICYmIHN3Zm9iamVjdC5oYXNGbGFzaFBsYXllclZlcnNpb24oRkxBU0hfVkVSU0lPTik7XG59KTtcblxuc2V0U3RhdGljUHJvcGVydHkoJ2hhc0V4dGVybmFsRGVwZW5kZW5jaWVzJywgKCkgPT4ge1xuICAgIHJldHVybiAhIXdpbmRvdy5zd2ZvYmplY3Q7XG59KTtcblxuZnVuY3Rpb24gJHRocm93SWZEZXN0cm95ZWQoKSB7XG4gICAgaWYodGhpcy5fZGVzdHJveWVkKSB7XG4gICAgICAgIHRocm93IG5ldyBlcnJvcignVlBBSURGbGFzaFRvSlMgaXMgZGVzdHJveWVkIScpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gJGxvYWRQZW5kZWRBZFVuaXQoKSB7XG4gICAgaWYgKHRoaXMuX2xvYWRMYXRlcikge1xuICAgICAgICB0aGlzLmxvYWRBZFVuaXQodGhpcy5fbG9hZExhdGVyLnVybCwgdGhpcy5fbG9hZExhdGVyLmNhbGxiYWNrKTtcbiAgICAgICAgZGVsZXRlIHRoaXMuX2xvYWRMYXRlcjtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHNldFN0YXRpY1Byb3BlcnR5KHByb3BlcnR5TmFtZSwgdmFsdWUpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVlBBSURGTEFTSENsaWVudCwgcHJvcGVydHlOYW1lLCB7XG4gICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgdmFsdWU6IHZhbHVlXG4gICAgfSk7XG59XG5cbndpbmRvdy5WUEFJREZMQVNIQ2xpZW50ID0gVlBBSURGTEFTSENsaWVudDtcbm1vZHVsZS5leHBvcnRzID0gVlBBSURGTEFTSENsaWVudDtcblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgdW5pcXVlID0gcmVxdWlyZSgnLi91dGlscycpLnVuaXF1ZTtcbmxldCBpc1Bvc2l0aXZlSW50ID0gcmVxdWlyZSgnLi91dGlscycpLmlzUG9zaXRpdmVJbnQ7XG5sZXQgc3RyaW5nRW5kc1dpdGggPSByZXF1aXJlKCcuL3V0aWxzJykuc3RyaW5nRW5kc1dpdGg7XG5sZXQgU2luZ2xlVmFsdWVSZWdpc3RyeSA9IHJlcXVpcmUoJy4vcmVnaXN0cnknKS5TaW5nbGVWYWx1ZVJlZ2lzdHJ5O1xubGV0IE11bHRpcGxlVmFsdWVzUmVnaXN0cnkgPSByZXF1aXJlKCcuL3JlZ2lzdHJ5JykuTXVsdGlwbGVWYWx1ZXNSZWdpc3RyeTtcbmNvbnN0IHJlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9qc0ZsYXNoQnJpZGdlUmVnaXN0cnknKTtcbmNvbnN0IFZQQUlEX0ZMQVNIX0hBTkRMRVIgPSAndnBhaWRfdmlkZW9fZmxhc2hfaGFuZGxlcic7XG5jb25zdCBFUlJPUiA9ICdBZEVycm9yJztcblxuZXhwb3J0IGNsYXNzIEpTRmxhc2hCcmlkZ2Uge1xuICAgIGNvbnN0cnVjdG9yIChlbCwgZmxhc2hVUkwsIGZsYXNoSUQsIHdpZHRoLCBoZWlnaHQsIGxvYWRIYW5kU2hha2UpIHtcbiAgICAgICAgdGhpcy5fZWwgPSBlbDtcbiAgICAgICAgdGhpcy5fZmxhc2hJRCA9IGZsYXNoSUQ7XG4gICAgICAgIHRoaXMuX2ZsYXNoVVJMID0gZmxhc2hVUkw7XG4gICAgICAgIHRoaXMuX3dpZHRoID0gd2lkdGg7XG4gICAgICAgIHRoaXMuX2hlaWdodCA9IGhlaWdodDtcbiAgICAgICAgdGhpcy5faGFuZGxlcnMgPSBuZXcgTXVsdGlwbGVWYWx1ZXNSZWdpc3RyeSgpO1xuICAgICAgICB0aGlzLl9jYWxsYmFja3MgPSBuZXcgU2luZ2xlVmFsdWVSZWdpc3RyeSgpO1xuICAgICAgICB0aGlzLl91bmlxdWVNZXRob2RJZGVudGlmaWVyID0gdW5pcXVlKHRoaXMuX2ZsYXNoSUQpO1xuICAgICAgICB0aGlzLl9yZWFkeSA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9oYW5kU2hha2VIYW5kbGVyID0gbG9hZEhhbmRTaGFrZTtcblxuICAgICAgICByZWdpc3RyeS5hZGRJbnN0YW5jZSh0aGlzLl9mbGFzaElELCB0aGlzKTtcbiAgICB9XG5cbiAgICBvbihldmVudE5hbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2hhbmRsZXJzLmFkZChldmVudE5hbWUsIGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICBvZmYoZXZlbnROYW1lLCBjYWxsYmFjaykge1xuICAgICAgICByZXR1cm4gdGhpcy5faGFuZGxlcnMucmVtb3ZlKGV2ZW50TmFtZSwgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIG9mZkV2ZW50KGV2ZW50TmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5faGFuZGxlcnMucmVtb3ZlQnlLZXkoZXZlbnROYW1lKTtcbiAgICB9XG5cbiAgICBvZmZBbGwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVycy5yZW1vdmVBbGwoKTtcbiAgICB9XG5cbiAgICBjYWxsRmxhc2hNZXRob2QobWV0aG9kTmFtZSwgYXJncyA9IFtdLCBjYWxsYmFjayA9IHVuZGVmaW5lZCkge1xuICAgICAgICB2YXIgY2FsbGJhY2tJRCA9ICcnO1xuICAgICAgICAvLyBpZiBubyBjYWxsYmFjaywgc29tZSBtZXRob2RzIHRoZSByZXR1cm4gaXMgdm9pZCBzbyB0aGV5IGRvbid0IG5lZWQgY2FsbGJhY2tcbiAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICBjYWxsYmFja0lEID0gYCR7dGhpcy5fdW5pcXVlTWV0aG9kSWRlbnRpZmllcigpfV8ke21ldGhvZE5hbWV9YDtcbiAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrcy5hZGQoY2FsbGJhY2tJRCwgY2FsbGJhY2spO1xuICAgICAgICB9XG5cblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy9tZXRob2RzIGFyZSBjcmVhdGVkIGJ5IEV4dGVybmFsSW50ZXJmYWNlLmFkZENhbGxiYWNrIGluIGFzMyBjb2RlLCBpZiBmb3Igc29tZSByZWFzb24gaXQgZmFpbGVkXG4gICAgICAgICAgICAvL3RoaXMgY29kZSB3aWxsIHRocm93IGFuIGVycm9yXG4gICAgICAgICAgICB0aGlzLl9lbFttZXRob2ROYW1lXShbY2FsbGJhY2tJRF0uY29uY2F0KGFyZ3MpKTtcblxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAkYXN5bmNDYWxsYmFjay5jYWxsKHRoaXMsIGNhbGxiYWNrSUQsIGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIC8vaWYgdGhlcmUgaXNuJ3QgYW55IGNhbGxiYWNrIHRvIHJldHVybiBlcnJvciB1c2UgZXJyb3IgZXZlbnQgaGFuZGxlclxuICAgICAgICAgICAgICAgIHRoaXMuX3RyaWdnZXIoRVJST1IsIGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmVtb3ZlQ2FsbGJhY2soY2FsbGJhY2spIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhbGxiYWNrcy5yZW1vdmVCeVZhbHVlKGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICByZW1vdmVDYWxsYmFja0J5TWV0aG9kTmFtZShzdWZmaXgpIHtcbiAgICAgICAgdGhpcy5fY2FsbGJhY2tzLmZpbHRlcktleXMoKGtleSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHN0cmluZ0VuZHNXaXRoKGtleSwgc3VmZml4KTtcbiAgICAgICAgfSkuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9jYWxsYmFja3MucmVtb3ZlKGtleSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJlbW92ZUFsbENhbGxiYWNrcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhbGxiYWNrcy5yZW1vdmVBbGwoKTtcbiAgICB9XG5cbiAgICBfdHJpZ2dlcihldmVudE5hbWUsIGV2ZW50KSB7XG4gICAgICAgIHRoaXMuX2hhbmRsZXJzLmdldChldmVudE5hbWUpLmZvckVhY2goKGNhbGxiYWNrKSA9PiB7XG4gICAgICAgICAgICAvL2NsaWNrVGhydSBoYXMgdG8gYmUgc3luYywgaWYgbm90IHdpbGwgYmUgYmxvY2sgYnkgdGhlIHBvcHVwYmxvY2tlclxuICAgICAgICAgICAgaWYgKGV2ZW50TmFtZSA9PT0gJ0FkQ2xpY2tUaHJ1Jykge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9oYW5kbGVycy5nZXQoZXZlbnROYW1lKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhldmVudCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgX2NhbGxDYWxsYmFjayhtZXRob2ROYW1lLCBjYWxsYmFja0lELCBlcnIsIHJlc3VsdCkge1xuXG4gICAgICAgIGxldCBjYWxsYmFjayA9IHRoaXMuX2NhbGxiYWNrcy5nZXQoY2FsbGJhY2tJRCk7XG5cbiAgICAgICAgLy9ub3QgYWxsIG1ldGhvZHMgY2FsbGJhY2sncyBhcmUgbWFuZGF0b3J5XG4gICAgICAgIC8vYnV0IGlmIHRoZXJlIGV4aXN0IGFuIGVycm9yLCBmaXJlIHRoZSBlcnJvciBldmVudFxuICAgICAgICBpZiAoIWNhbGxiYWNrKSB7XG4gICAgICAgICAgICBpZiAoZXJyICYmIGNhbGxiYWNrSUQgPT09ICcnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKEVSUk9SLCBlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgJGFzeW5jQ2FsbGJhY2suY2FsbCh0aGlzLCBjYWxsYmFja0lELCBlcnIsIHJlc3VsdCk7XG5cbiAgICB9XG5cbiAgICBfaGFuZFNoYWtlKGVyciwgZGF0YSkge1xuICAgICAgICB0aGlzLl9yZWFkeSA9IHRydWU7XG4gICAgICAgIGlmICh0aGlzLl9oYW5kU2hha2VIYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLl9oYW5kU2hha2VIYW5kbGVyKGVyciwgZGF0YSk7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5faGFuZFNoYWtlSGFuZGxlcjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vbWV0aG9kcyBsaWtlIHByb3BlcnRpZXMgc3BlY2lmaWMgdG8gdGhpcyBpbXBsZW1lbnRhdGlvbiBvZiBWUEFJRFxuICAgIGdldFNpemUoKSB7XG4gICAgICAgIHJldHVybiB7d2lkdGg6IHRoaXMuX3dpZHRoLCBoZWlnaHQ6IHRoaXMuX2hlaWdodH07XG4gICAgfVxuICAgIHNldFNpemUobmV3V2lkdGgsIG5ld0hlaWdodCkge1xuICAgICAgICB0aGlzLl93aWR0aCA9IGlzUG9zaXRpdmVJbnQobmV3V2lkdGgsIHRoaXMuX3dpZHRoKTtcbiAgICAgICAgdGhpcy5faGVpZ2h0ID0gaXNQb3NpdGl2ZUludChuZXdIZWlnaHQsIHRoaXMuX2hlaWdodCk7XG4gICAgICAgIHRoaXMuX2VsLnNldEF0dHJpYnV0ZSgnd2lkdGgnLCB0aGlzLl93aWR0aCk7XG4gICAgICAgIHRoaXMuX2VsLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgdGhpcy5faGVpZ2h0KTtcbiAgICB9XG4gICAgZ2V0V2lkdGgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl93aWR0aDtcbiAgICB9XG4gICAgc2V0V2lkdGgobmV3V2lkdGgpIHtcbiAgICAgICAgdGhpcy5zZXRTaXplKG5ld1dpZHRoLCB0aGlzLl9oZWlnaHQpO1xuICAgIH1cbiAgICBnZXRIZWlnaHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9oZWlnaHQ7XG4gICAgfVxuICAgIHNldEhlaWdodChuZXdIZWlnaHQpIHtcbiAgICAgICAgdGhpcy5zZXRTaXplKHRoaXMuX3dpZHRoLCBuZXdIZWlnaHQpO1xuICAgIH1cbiAgICBnZXRGbGFzaElEKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmxhc2hJRDtcbiAgICB9XG4gICAgZ2V0Rmxhc2hVUkwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mbGFzaFVSTDtcbiAgICB9XG4gICAgaXNSZWFkeSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlYWR5O1xuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICB0aGlzLm9mZkFsbCgpO1xuICAgICAgICB0aGlzLnJlbW92ZUFsbENhbGxiYWNrcygpO1xuICAgICAgICByZWdpc3RyeS5yZW1vdmVJbnN0YW5jZUJ5SUQodGhpcy5fZmxhc2hJRCk7XG4gICAgICAgIGlmICh0aGlzLl9lbC5wYXJlbnRFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9lbC5wYXJlbnRFbGVtZW50LnJlbW92ZUNoaWxkKHRoaXMuX2VsKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gJGFzeW5jQ2FsbGJhY2soY2FsbGJhY2tJRCwgZXJyLCByZXN1bHQpIHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgbGV0IGNhbGxiYWNrID0gdGhpcy5fY2FsbGJhY2tzLmdldChjYWxsYmFja0lEKTtcbiAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICB0aGlzLl9jYWxsYmFja3MucmVtb3ZlKGNhbGxiYWNrSUQpO1xuICAgICAgICAgICAgY2FsbGJhY2soZXJyLCByZXN1bHQpO1xuICAgICAgICB9XG4gICAgfSwgMCk7XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShKU0ZsYXNoQnJpZGdlLCAnVlBBSURfRkxBU0hfSEFORExFUicsIHtcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICB2YWx1ZTogVlBBSURfRkxBU0hfSEFORExFUlxufSk7XG5cbi8qKlxuICogRXh0ZXJuYWwgaW50ZXJmYWNlIGhhbmRsZXJcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmxhc2hJRCBpZGVudGlmaWVyIG9mIHRoZSBmbGFzaCB3aG8gY2FsbCB0aGlzXG4gKiBAcGFyYW0ge3N0cmluZ30gdHlwZUlEIHdoYXQgdHlwZSBvZiBtZXNzYWdlIGlzLCBjYW4gYmUgJ2V2ZW50JyBvciAnY2FsbGJhY2snXG4gKiBAcGFyYW0ge3N0cmluZ30gdHlwZU5hbWUgaWYgdGhlIHR5cGVJRCBpcyBhIGV2ZW50IHRoZSB0eXBlTmFtZSB3aWxsIGJlIHRoZSBldmVudE5hbWUsIGlmIGlzIGEgY2FsbGJhY2sgdGhlIHR5cGVJRCBpcyB0aGUgbWV0aG9kTmFtZSB0aGF0IGlzIHJlbGF0ZWQgdGhpcyBjYWxsYmFja1xuICogQHBhcmFtIHtzdHJpbmd9IGNhbGxiYWNrSUQgb25seSBhcHBsaWVzIHdoZW4gdGhlIHR5cGVJRCBpcyAnY2FsbGJhY2snLCBpZGVudGlmaWVyIG9mIHRoZSBjYWxsYmFjayB0byBjYWxsXG4gKiBAcGFyYW0ge29iamVjdH0gZXJyb3IgZXJyb3Igb2JqZWN0XG4gKiBAcGFyYW0ge29iamVjdH0gZGF0YVxuICovXG53aW5kb3dbVlBBSURfRkxBU0hfSEFORExFUl0gPSAoZmxhc2hJRCwgdHlwZUlELCB0eXBlTmFtZSwgY2FsbGJhY2tJRCwgZXJyb3IsIGRhdGEpID0+IHtcbiAgICBsZXQgaW5zdGFuY2UgPSByZWdpc3RyeS5nZXRJbnN0YW5jZUJ5SUQoZmxhc2hJRCk7XG4gICAgaWYgKCFpbnN0YW5jZSkgcmV0dXJuO1xuICAgIGlmICh0eXBlTmFtZSA9PT0gJ2hhbmRTaGFrZScpIHtcbiAgICAgICAgaW5zdGFuY2UuX2hhbmRTaGFrZShlcnJvciwgZGF0YSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHR5cGVJRCAhPT0gJ2V2ZW50Jykge1xuICAgICAgICAgICAgaW5zdGFuY2UuX2NhbGxDYWxsYmFjayh0eXBlTmFtZSwgY2FsbGJhY2tJRCwgZXJyb3IsIGRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaW5zdGFuY2UuX3RyaWdnZXIodHlwZU5hbWUsIGRhdGEpO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgU2luZ2xlVmFsdWVSZWdpc3RyeSA9IHJlcXVpcmUoJy4vcmVnaXN0cnknKS5TaW5nbGVWYWx1ZVJlZ2lzdHJ5O1xubGV0IGluc3RhbmNlcyA9IG5ldyBTaW5nbGVWYWx1ZVJlZ2lzdHJ5KCk7XG5cbmNvbnN0IEpTRmxhc2hCcmlkZ2VSZWdpc3RyeSA9IHt9O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KEpTRmxhc2hCcmlkZ2VSZWdpc3RyeSwgJ2FkZEluc3RhbmNlJywge1xuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoaWQsIGluc3RhbmNlKSB7XG4gICAgICAgIGluc3RhbmNlcy5hZGQoaWQsIGluc3RhbmNlKTtcbiAgICB9XG59KTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEpTRmxhc2hCcmlkZ2VSZWdpc3RyeSwgJ2dldEluc3RhbmNlQnlJRCcsIHtcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICB2YWx1ZTogZnVuY3Rpb24gKGlkKSB7XG4gICAgICAgIHJldHVybiBpbnN0YW5jZXMuZ2V0KGlkKTtcbiAgICB9XG59KTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEpTRmxhc2hCcmlkZ2VSZWdpc3RyeSwgJ3JlbW92ZUluc3RhbmNlQnlJRCcsIHtcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICB2YWx1ZTogZnVuY3Rpb24gKGlkKSB7XG4gICAgICAgIHJldHVybiBpbnN0YW5jZXMucmVtb3ZlKGlkKTtcbiAgICB9XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBKU0ZsYXNoQnJpZGdlUmVnaXN0cnk7XG5cbiIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0IGNsYXNzIE11bHRpcGxlVmFsdWVzUmVnaXN0cnkge1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgdGhpcy5fcmVnaXN0cmllcyA9IHt9O1xuICAgIH1cbiAgICBhZGQgKGlkLCB2YWx1ZSkge1xuICAgICAgICBpZiAoIXRoaXMuX3JlZ2lzdHJpZXNbaWRdKSB7XG4gICAgICAgICAgICB0aGlzLl9yZWdpc3RyaWVzW2lkXSA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9yZWdpc3RyaWVzW2lkXS5pbmRleE9mKHZhbHVlKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuX3JlZ2lzdHJpZXNbaWRdLnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCAoaWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlZ2lzdHJpZXNbaWRdIHx8IFtdO1xuICAgIH1cbiAgICBmaWx0ZXJLZXlzIChoYW5kbGVyKSB7XG4gICAgICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLl9yZWdpc3RyaWVzKS5maWx0ZXIoaGFuZGxlcik7XG4gICAgfVxuICAgIGZpbmRCeVZhbHVlICh2YWx1ZSkge1xuICAgICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHRoaXMuX3JlZ2lzdHJpZXMpLmZpbHRlcigoa2V5KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVnaXN0cmllc1trZXldLmluZGV4T2YodmFsdWUpICE9PSAtMTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIGtleXM7XG4gICAgfVxuICAgIHJlbW92ZShrZXksIHZhbHVlKSB7XG4gICAgICAgIGlmICghdGhpcy5fcmVnaXN0cmllc1trZXldKSB7IHJldHVybjsgfVxuXG4gICAgICAgIHZhciBpbmRleCA9IHRoaXMuX3JlZ2lzdHJpZXNba2V5XS5pbmRleE9mKHZhbHVlKTtcblxuICAgICAgICBpZiAoaW5kZXggPCAwKSB7IHJldHVybjsgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcmVnaXN0cmllc1trZXldLnNwbGljZShpbmRleCwgMSk7XG4gICAgfVxuICAgIHJlbW92ZUJ5S2V5IChpZCkge1xuICAgICAgICBsZXQgb2xkID0gdGhpcy5fcmVnaXN0cmllc1tpZF07XG4gICAgICAgIGRlbGV0ZSB0aGlzLl9yZWdpc3RyaWVzW2lkXTtcbiAgICAgICAgcmV0dXJuIG9sZDtcbiAgICB9XG4gICAgcmVtb3ZlQnlWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgbGV0IGtleXMgPSB0aGlzLmZpbmRCeVZhbHVlKHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIGtleXMubWFwKChrZXkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnJlbW92ZShrZXksIHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJlbW92ZUFsbCgpIHtcbiAgICAgICAgbGV0IG9sZCA9IHRoaXMuX3JlZ2lzdHJpZXM7XG4gICAgICAgIHRoaXMuX3JlZ2lzdHJpZXMgPSB7fTtcbiAgICAgICAgcmV0dXJuIG9sZDtcbiAgICB9XG4gICAgc2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuX3JlZ2lzdHJpZXMpLmxlbmd0aDtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTaW5nbGVWYWx1ZVJlZ2lzdHJ5IHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHRoaXMuX3JlZ2lzdHJpZXMgPSB7fTtcbiAgICB9XG4gICAgYWRkIChpZCwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5fcmVnaXN0cmllc1tpZF0gPSB2YWx1ZTtcbiAgICB9XG4gICAgZ2V0IChpZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVnaXN0cmllc1tpZF07XG4gICAgfVxuICAgIGZpbHRlcktleXMgKGhhbmRsZXIpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuX3JlZ2lzdHJpZXMpLmZpbHRlcihoYW5kbGVyKTtcbiAgICB9XG4gICAgZmluZEJ5VmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXModGhpcy5fcmVnaXN0cmllcykuZmlsdGVyKChrZXkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9yZWdpc3RyaWVzW2tleV0gPT09IHZhbHVlO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4ga2V5cztcbiAgICB9XG4gICAgcmVtb3ZlIChpZCkge1xuICAgICAgICBsZXQgb2xkID0gdGhpcy5fcmVnaXN0cmllc1tpZF07XG4gICAgICAgIGRlbGV0ZSB0aGlzLl9yZWdpc3RyaWVzW2lkXTtcbiAgICAgICAgcmV0dXJuIG9sZDtcbiAgICB9XG4gICAgcmVtb3ZlQnlWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgbGV0IGtleXMgPSB0aGlzLmZpbmRCeVZhbHVlKHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIGtleXMubWFwKChrZXkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnJlbW92ZShrZXkpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmVtb3ZlQWxsKCkge1xuICAgICAgICBsZXQgb2xkID0gdGhpcy5fcmVnaXN0cmllcztcbiAgICAgICAgdGhpcy5fcmVnaXN0cmllcyA9IHt9O1xuICAgICAgICByZXR1cm4gb2xkO1xuICAgIH1cbiAgICBzaXplKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5fcmVnaXN0cmllcykubGVuZ3RoO1xuICAgIH1cbn1cblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnQgZnVuY3Rpb24gdW5pcXVlKHByZWZpeCkge1xuICAgIGxldCBjb3VudCA9IC0xO1xuICAgIHJldHVybiBmID0+IHtcbiAgICAgICAgcmV0dXJuIGAke3ByZWZpeH1fJHsrK2NvdW50fWA7XG4gICAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG5vb3AoKSB7XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGNhbGxiYWNrVGltZW91dCh0aW1lciwgb25TdWNjZXNzLCBvblRpbWVvdXQpIHtcblxuICAgIGxldCB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG5cbiAgICAgICAgb25TdWNjZXNzID0gbm9vcDtcbiAgICAgICAgb25UaW1lb3V0KCk7XG5cbiAgICB9LCB0aW1lcik7XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgIG9uU3VjY2Vzcy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnRXaXRoSUQocGFyZW50LCBpZCkge1xuICAgIHZhciBuRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBuRWwuaWQgPSBpZDtcbiAgICBwYXJlbnQuaW5uZXJIVE1MID0gJyc7XG4gICAgcGFyZW50LmFwcGVuZENoaWxkKG5FbCk7XG4gICAgcmV0dXJuIG5FbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUG9zaXRpdmVJbnQobmV3VmFsLCBvbGRWYWwpIHtcbiAgICByZXR1cm4gIWlzTmFOKHBhcnNlRmxvYXQobmV3VmFsKSkgJiYgaXNGaW5pdGUobmV3VmFsKSAmJiBuZXdWYWwgPiAwID8gbmV3VmFsIDogb2xkVmFsO1xufVxuXG5sZXQgZW5kc1dpdGggPSAoZnVuY3Rpb24gKCkge1xuICAgIGlmIChTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoKSByZXR1cm4gU3RyaW5nLnByb3RvdHlwZS5lbmRzV2l0aDtcbiAgICByZXR1cm4gZnVuY3Rpb24gZW5kc1dpdGggKHNlYXJjaFN0cmluZywgcG9zaXRpb24pIHtcbiAgICAgICAgdmFyIHN1YmplY3RTdHJpbmcgPSB0aGlzLnRvU3RyaW5nKCk7XG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gdW5kZWZpbmVkIHx8IHBvc2l0aW9uID4gc3ViamVjdFN0cmluZy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHBvc2l0aW9uID0gc3ViamVjdFN0cmluZy5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgcG9zaXRpb24gLT0gc2VhcmNoU3RyaW5nLmxlbmd0aDtcbiAgICAgICAgdmFyIGxhc3RJbmRleCA9IHN1YmplY3RTdHJpbmcuaW5kZXhPZihzZWFyY2hTdHJpbmcsIHBvc2l0aW9uKTtcbiAgICAgICAgcmV0dXJuIGxhc3RJbmRleCAhPT0gLTEgJiYgbGFzdEluZGV4ID09PSBwb3NpdGlvbjtcbiAgICB9XG59KSgpO1xuXG5leHBvcnQgZnVuY3Rpb24gc3RyaW5nRW5kc1dpdGgoc3RyaW5nLCBzZWFyY2gpIHtcbiAgICByZXR1cm4gZW5kc1dpdGguY2FsbChzdHJpbmcsIHNlYXJjaCk7XG59XG5cblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgTUVUSE9EUyA9IFtcbiAgICAnaGFuZHNoYWtlVmVyc2lvbicsXG4gICAgJ2luaXRBZCcsXG4gICAgJ3N0YXJ0QWQnLFxuICAgICdzdG9wQWQnLFxuICAgICdza2lwQWQnLCAvLyBWUEFJRCAyLjAgbmV3IG1ldGhvZFxuICAgICdyZXNpemVBZCcsXG4gICAgJ3BhdXNlQWQnLFxuICAgICdyZXN1bWVBZCcsXG4gICAgJ2V4cGFuZEFkJyxcbiAgICAnY29sbGFwc2VBZCcsXG4gICAgJ3N1YnNjcmliZScsXG4gICAgJ3Vuc3Vic2NyaWJlJ1xuXTtcblxudmFyIEVWRU5UUyA9IFtcbiAgICAnQWRMb2FkZWQnLFxuICAgICdBZFN0YXJ0ZWQnLFxuICAgICdBZFN0b3BwZWQnLFxuICAgICdBZFNraXBwZWQnLFxuICAgICdBZFNraXBwYWJsZVN0YXRlQ2hhbmdlJywgLy8gVlBBSUQgMi4wIG5ldyBldmVudFxuICAgICdBZFNpemVDaGFuZ2UnLCAvLyBWUEFJRCAyLjAgbmV3IGV2ZW50XG4gICAgJ0FkTGluZWFyQ2hhbmdlJyxcbiAgICAnQWREdXJhdGlvbkNoYW5nZScsIC8vIFZQQUlEIDIuMCBuZXcgZXZlbnRcbiAgICAnQWRFeHBhbmRlZENoYW5nZScsXG4gICAgJ0FkUmVtYWluaW5nVGltZUNoYW5nZScsIC8vIFtEZXByZWNhdGVkIGluIDIuMF0gYnV0IHdpbGwgYmUgc3RpbGwgZmlyZWQgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG4gICAgJ0FkVm9sdW1lQ2hhbmdlJyxcbiAgICAnQWRJbXByZXNzaW9uJyxcbiAgICAnQWRWaWRlb1N0YXJ0JyxcbiAgICAnQWRWaWRlb0ZpcnN0UXVhcnRpbGUnLFxuICAgICdBZFZpZGVvTWlkcG9pbnQnLFxuICAgICdBZFZpZGVvVGhpcmRRdWFydGlsZScsXG4gICAgJ0FkVmlkZW9Db21wbGV0ZScsXG4gICAgJ0FkQ2xpY2tUaHJ1JyxcbiAgICAnQWRJbnRlcmFjdGlvbicsIC8vIFZQQUlEIDIuMCBuZXcgZXZlbnRcbiAgICAnQWRVc2VyQWNjZXB0SW52aXRhdGlvbicsXG4gICAgJ0FkVXNlck1pbmltaXplJyxcbiAgICAnQWRVc2VyQ2xvc2UnLFxuICAgICdBZFBhdXNlZCcsXG4gICAgJ0FkUGxheWluZycsXG4gICAgJ0FkTG9nJyxcbiAgICAnQWRFcnJvcidcbl07XG5cbnZhciBHRVRURVJTID0gW1xuICAgICdnZXRBZExpbmVhcicsXG4gICAgJ2dldEFkV2lkdGgnLCAvLyBWUEFJRCAyLjAgbmV3IGdldHRlclxuICAgICdnZXRBZEhlaWdodCcsIC8vIFZQQUlEIDIuMCBuZXcgZ2V0dGVyXG4gICAgJ2dldEFkRXhwYW5kZWQnLFxuICAgICdnZXRBZFNraXBwYWJsZVN0YXRlJywgLy8gVlBBSUQgMi4wIG5ldyBnZXR0ZXJcbiAgICAnZ2V0QWRSZW1haW5pbmdUaW1lJyxcbiAgICAnZ2V0QWREdXJhdGlvbicsIC8vIFZQQUlEIDIuMCBuZXcgZ2V0dGVyXG4gICAgJ2dldEFkVm9sdW1lJyxcbiAgICAnZ2V0QWRDb21wYW5pb25zJywgLy8gVlBBSUQgMi4wIG5ldyBnZXR0ZXJcbiAgICAnZ2V0QWRJY29ucycgLy8gVlBBSUQgMi4wIG5ldyBnZXR0ZXJcbl07XG5cbnZhciBTRVRURVJTID0gW1xuICAgICdzZXRBZFZvbHVtZSdcbl07XG5cblxuLyoqXG4gKiBUaGlzIGNhbGxiYWNrIGlzIGRpc3BsYXllZCBhcyBnbG9iYWwgbWVtYmVyLiBUaGUgY2FsbGJhY2sgdXNlIG5vZGVqcyBlcnJvci1maXJzdCBjYWxsYmFjayBzdHlsZVxuICogQGNhbGxiYWNrIE5vZGVTdHlsZUNhbGxiYWNrXG4gKiBAcGFyYW0ge3N0cmluZ3xudWxsfVxuICogQHBhcmFtIHt1bmRlZmluZWR8b2JqZWN0fVxuICovXG5cblxuLyoqXG4gKiBJVlBBSURBZFVuaXRcbiAqXG4gKiBAY2xhc3NcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gY3JlYXRpdmVcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsXG4gKiBAcGFyYW0ge0hUTUxWaWRlb0VsZW1lbnR9IHZpZGVvXG4gKi9cbmZ1bmN0aW9uIElWUEFJREFkVW5pdChjcmVhdGl2ZSwgZWwsIHZpZGVvKSB7fVxuXG5cbi8qKlxuICogaGFuZHNoYWtlVmVyc2lvblxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBWUEFJRFZlcnNpb25cbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuaGFuZHNoYWtlVmVyc2lvbiA9IGZ1bmN0aW9uIChWUEFJRFZlcnNpb24sIGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBpbml0QWRcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gd2lkdGhcbiAqIEBwYXJhbSB7bnVtYmVyfSBoZWlnaHRcbiAqIEBwYXJhbSB7c3RyaW5nfSB2aWV3TW9kZSBjYW4gYmUgJ25vcm1hbCcsICd0aHVtYm5haWwnIG9yICdmdWxsc2NyZWVuJ1xuICogQHBhcmFtIHtudW1iZXJ9IGRlc2lyZWRCaXRyYXRlIGluZGljYXRlcyB0aGUgZGVzaXJlZCBiaXRyYXRlIGluIGticHNcbiAqIEBwYXJhbSB7b2JqZWN0fSBbY3JlYXRpdmVEYXRhXSB1c2VkIGZvciBhZGRpdGlvbmFsIGluaXRpYWxpemF0aW9uIGRhdGFcbiAqIEBwYXJhbSB7b2JqZWN0fSBbZW52aXJvbm1lbnRWYXJzXSB1c2VkIGZvciBwYXNzaW5nIGltcGxlbWVudGF0aW9uLXNwZWNpZmljIG9mIGpzIHZlcnNpb25cbiAqIEBwYXJhbSB7Tm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuaW5pdEFkID0gZnVuY3Rpb24od2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGRlc2lyZWRCaXRyYXRlLCBjcmVhdGl2ZURhdGEsIGVudmlyb25tZW50VmFycywgY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIHN0YXJ0QWRcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLnN0YXJ0QWQgPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogc3RvcEFkXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5zdG9wQWQgPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogc2tpcEFkXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5za2lwQWQgPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogcmVzaXplQWRcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLnJlc2l6ZUFkID0gZnVuY3Rpb24od2lkdGgsIGhlaWdodCwgdmlld01vZGUsIGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBwYXVzZUFkXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5wYXVzZUFkID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIHJlc3VtZUFkXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5yZXN1bWVBZCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBleHBhbmRBZFxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuZXhwYW5kQWQgPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogY29sbGFwc2VBZFxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuY29sbGFwc2VBZCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBzdWJzY3JpYmVcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGhhbmRsZXJcbiAqIEBwYXJhbSB7b2JqZWN0fSBjb250ZXh0XG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuc3Vic2NyaWJlID0gZnVuY3Rpb24oZXZlbnQsIGhhbmRsZXIsIGNvbnRleHQpIHt9O1xuXG4vKipcbiAqIHN0YXJ0QWRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGhhbmRsZXJcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS51bnN1YnNjcmliZSA9IGZ1bmN0aW9uKGV2ZW50LCBoYW5kbGVyKSB7fTtcblxuXG5cbi8qKlxuICogZ2V0QWRMaW5lYXJcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLmdldEFkTGluZWFyID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIGdldEFkV2lkdGhcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLmdldEFkV2lkdGggPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogZ2V0QWRIZWlnaHRcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLmdldEFkSGVpZ2h0ID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIGdldEFkRXhwYW5kZWRcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLmdldEFkRXhwYW5kZWQgPSBmdW5jdGlvbihjYWxsYmFjaykge307XG5cbi8qKlxuICogZ2V0QWRTa2lwcGFibGVTdGF0ZVxuICpcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cbklWUEFJREFkVW5pdC5wcm90b3R5cGUuZ2V0QWRTa2lwcGFibGVTdGF0ZSA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBnZXRBZFJlbWFpbmluZ1RpbWVcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLmdldEFkUmVtYWluaW5nVGltZSA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBnZXRBZER1cmF0aW9uXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5nZXRBZER1cmF0aW9uID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIGdldEFkVm9sdW1lXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5nZXRBZFZvbHVtZSA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBnZXRBZENvbXBhbmlvbnNcbiAqXG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5JVlBBSURBZFVuaXQucHJvdG90eXBlLmdldEFkQ29tcGFuaW9ucyA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7fTtcblxuLyoqXG4gKiBnZXRBZEljb25zXG4gKlxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5nZXRBZEljb25zID0gZnVuY3Rpb24oY2FsbGJhY2spIHt9O1xuXG4vKipcbiAqIHNldEFkVm9sdW1lXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHZvbHVtZVxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gY2FsbGJhY2tcbiAqL1xuSVZQQUlEQWRVbml0LnByb3RvdHlwZS5zZXRBZFZvbHVtZSA9IGZ1bmN0aW9uKHZvbHVtZSwgY2FsbGJhY2spIHt9O1xuXG5hZGRTdGF0aWNUb0ludGVyZmFjZShJVlBBSURBZFVuaXQsICdNRVRIT0RTJywgTUVUSE9EUyk7XG5hZGRTdGF0aWNUb0ludGVyZmFjZShJVlBBSURBZFVuaXQsICdHRVRURVJTJywgR0VUVEVSUyk7XG5hZGRTdGF0aWNUb0ludGVyZmFjZShJVlBBSURBZFVuaXQsICdTRVRURVJTJywgU0VUVEVSUyk7XG5hZGRTdGF0aWNUb0ludGVyZmFjZShJVlBBSURBZFVuaXQsICdFVkVOVFMnLCAgRVZFTlRTKTtcblxuXG52YXIgVlBBSUQxX01FVEhPRFMgPSBNRVRIT0RTLmZpbHRlcihmdW5jdGlvbihtZXRob2QpIHtcbiAgICByZXR1cm4gWydza2lwQWQnXS5pbmRleE9mKG1ldGhvZCkgPT09IC0xO1xufSk7XG5cbmFkZFN0YXRpY1RvSW50ZXJmYWNlKElWUEFJREFkVW5pdCwgJ2NoZWNrVlBBSURJbnRlcmZhY2UnLCBmdW5jdGlvbiBjaGVja1ZQQUlESW50ZXJmYWNlIChjcmVhdGl2ZSkge1xuICAgIHZhciByZXN1bHQgPSBWUEFJRDFfTUVUSE9EUy5ldmVyeShmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBjcmVhdGl2ZVtrZXldID09PSAnZnVuY3Rpb24nO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBJVlBBSURBZFVuaXQ7XG5cbmZ1bmN0aW9uIGFkZFN0YXRpY1RvSW50ZXJmYWNlKEludGVyZmFjZSwgbmFtZSwgdmFsdWUpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoSW50ZXJmYWNlLCBuYW1lLCB7XG4gICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgdmFsdWU6IHZhbHVlXG4gICAgfSk7XG59XG5cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIElWUEFJREFkVW5pdCA9IHJlcXVpcmUoJy4vSVZQQUlEQWRVbml0Jyk7XG52YXIgU3Vic2NyaWJlciA9IHJlcXVpcmUoJy4vc3Vic2NyaWJlcicpO1xudmFyIGNoZWNrVlBBSURJbnRlcmZhY2UgPSBJVlBBSURBZFVuaXQuY2hlY2tWUEFJREludGVyZmFjZTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciBNRVRIT0RTID0gSVZQQUlEQWRVbml0Lk1FVEhPRFM7XG52YXIgRVJST1IgPSAnQWRFcnJvcic7XG52YXIgQURfQ0xJQ0sgPSAnQWRDbGlja1RocnUnO1xudmFyIEZJTFRFUkVEX0VWRU5UUyA9IElWUEFJREFkVW5pdC5FVkVOVFMuZmlsdGVyKGZ1bmN0aW9uIChldmVudCkge1xuICAgIHJldHVybiBldmVudCAhPSBBRF9DTElDSztcbn0pO1xuXG4vKipcbiAqIFRoaXMgY2FsbGJhY2sgaXMgZGlzcGxheWVkIGFzIGdsb2JhbCBtZW1iZXIuIFRoZSBjYWxsYmFjayB1c2Ugbm9kZWpzIGVycm9yLWZpcnN0IGNhbGxiYWNrIHN0eWxlXG4gKiBAY2FsbGJhY2sgTm9kZVN0eWxlQ2FsbGJhY2tcbiAqIEBwYXJhbSB7c3RyaW5nfG51bGx9XG4gKiBAcGFyYW0ge3VuZGVmaW5lZHxvYmplY3R9XG4gKi9cblxuXG4vKipcbiAqIFZQQUlEQWRVbml0XG4gKiBAY2xhc3NcbiAqXG4gKiBAcGFyYW0gVlBBSURDcmVhdGl2ZVxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gW2VsXSB0aGlzIHdpbGwgYmUgdXNlZCBpbiBpbml0QWQgZW52aXJvbm1lbnRWYXJzLnNsb3QgaWYgZGVmaW5lZFxuICogQHBhcmFtIHtIVE1MVmlkZW9FbGVtZW50fSBbdmlkZW9dIHRoaXMgd2lsbCBiZSB1c2VkIGluIGluaXRBZCBlbnZpcm9ubWVudFZhcnMudmlkZW9TbG90IGlmIGRlZmluZWRcbiAqL1xuZnVuY3Rpb24gVlBBSURBZFVuaXQoVlBBSURDcmVhdGl2ZSwgZWwsIHZpZGVvLCBpZnJhbWUpIHtcbiAgICB0aGlzLl9pc1ZhbGlkID0gY2hlY2tWUEFJREludGVyZmFjZShWUEFJRENyZWF0aXZlKTtcbiAgICBpZiAodGhpcy5faXNWYWxpZCkge1xuICAgICAgICB0aGlzLl9jcmVhdGl2ZSA9IFZQQUlEQ3JlYXRpdmU7XG4gICAgICAgIHRoaXMuX2VsID0gZWw7XG4gICAgICAgIHRoaXMuX3ZpZGVvRWwgPSB2aWRlbztcbiAgICAgICAgdGhpcy5faWZyYW1lID0gaWZyYW1lO1xuICAgICAgICB0aGlzLl9zdWJzY3JpYmVycyA9IG5ldyBTdWJzY3JpYmVyKCk7XG4gICAgICAgICRhZGRFdmVudHNTdWJzY3JpYmVycy5jYWxsKHRoaXMpO1xuICAgIH1cbn1cblxuVlBBSURBZFVuaXQucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShJVlBBSURBZFVuaXQucHJvdG90eXBlKTtcblxuLyoqXG4gKiBpc1ZhbGlkVlBBSURBZCB3aWxsIHJldHVybiBpZiB0aGUgVlBBSURDcmVhdGl2ZSBwYXNzZWQgaW4gY29uc3RydWN0b3IgaXMgdmFsaWQgb3Igbm90XG4gKlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuVlBBSURBZFVuaXQucHJvdG90eXBlLmlzVmFsaWRWUEFJREFkID0gZnVuY3Rpb24gaXNWYWxpZFZQQUlEQWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2lzVmFsaWQ7XG59O1xuXG5JVlBBSURBZFVuaXQuTUVUSE9EUy5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgIC8vTk9URTogdGhpcyBtZXRob2RzIGFyZ3VtZW50cyBvcmRlciBhcmUgaW1wbGVtZW50ZWQgZGlmZmVyZW50bHkgZnJvbSB0aGUgc3BlY1xuICAgIHZhciBpZ25vcmVzID0gW1xuICAgICAgICAnc3Vic2NyaWJlJyxcbiAgICAgICAgJ3Vuc3Vic2NyaWJlJyxcbiAgICAgICAgJ2luaXRBZCdcbiAgICBdO1xuXG4gICAgaWYgKGlnbm9yZXMuaW5kZXhPZihtZXRob2QpICE9PSAtMSkgcmV0dXJuO1xuXG4gICAgVlBBSURBZFVuaXQucHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhcmlhdHkgPSBJVlBBSURBZFVuaXQucHJvdG90eXBlW21ldGhvZF0ubGVuZ3RoO1xuICAgICAgICAvLyBUT0RPIGF2b2lkIGxlYWtpbmcgYXJndW1lbnRzXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9wZXRrYWFudG9ub3YvYmx1ZWJpcmQvd2lraS9PcHRpbWl6YXRpb24ta2lsbGVycyMzMi1sZWFraW5nLWFyZ3VtZW50c1xuICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IChhcmlhdHkgPT09IGFyZ3MubGVuZ3RoKSA/IGFyZ3MucG9wKCkgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgcmVzdWx0LCBlcnJvciA9IG51bGw7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRoaXMuX2NyZWF0aXZlW21ldGhvZF0uYXBwbHkodGhpcy5fY3JlYXRpdmUsIGFyZ3MpO1xuICAgICAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgICAgICAgZXJyb3IgPSBlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYWxsT3JUcmlnZ2VyRXZlbnQoY2FsbGJhY2ssIHRoaXMuX3N1YnNjcmliZXJzLCBlcnJvciwgcmVzdWx0KTtcbiAgICAgICAgfS5iaW5kKHRoaXMpLCAwKTtcbiAgICB9O1xufSk7XG5cblxuLyoqXG4gKiBpbml0QWQgY29uY3JlYXRlIGltcGxlbWVudGF0aW9uXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoXG4gKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0XG4gKiBAcGFyYW0ge3N0cmluZ30gdmlld01vZGUgY2FuIGJlICdub3JtYWwnLCAndGh1bWJuYWlsJyBvciAnZnVsbHNjcmVlbidcbiAqIEBwYXJhbSB7bnVtYmVyfSBkZXNpcmVkQml0cmF0ZSBpbmRpY2F0ZXMgdGhlIGRlc2lyZWQgYml0cmF0ZSBpbiBrYnBzXG4gKiBAcGFyYW0ge29iamVjdH0gW2NyZWF0aXZlRGF0YV0gdXNlZCBmb3IgYWRkaXRpb25hbCBpbml0aWFsaXphdGlvbiBkYXRhXG4gKiBAcGFyYW0ge29iamVjdH0gW2Vudmlyb25tZW50VmFyc10gdXNlZCBmb3IgcGFzc2luZyBpbXBsZW1lbnRhdGlvbi1zcGVjaWZpYyBvZiBqcyB2ZXJzaW9uLCBpZiBlbCAmIHZpZGVvIHdhcyB1c2VkIGluIGNvbnN0cnVjdG9yIHNsb3QgJiB2aWRlb1Nsb3Qgd2lsbCBiZSBhZGRlZCB0byB0aGUgb2JqZWN0XG4gKiBAcGFyYW0ge05vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5WUEFJREFkVW5pdC5wcm90b3R5cGUuaW5pdEFkID0gZnVuY3Rpb24gaW5pdEFkKHdpZHRoLCBoZWlnaHQsIHZpZXdNb2RlLCBkZXNpcmVkQml0cmF0ZSwgY3JlYXRpdmVEYXRhLCBlbnZpcm9ubWVudFZhcnMsIGNhbGxiYWNrKSB7XG4gICAgY3JlYXRpdmVEYXRhID0gY3JlYXRpdmVEYXRhIHx8IHt9O1xuICAgIGVudmlyb25tZW50VmFycyA9IHV0aWxzLmV4dGVuZCh7XG4gICAgICAgIHNsb3Q6IHRoaXMuX2VsLFxuICAgICAgICB2aWRlb1Nsb3Q6IHRoaXMuX3ZpZGVvRWxcbiAgICB9LCBlbnZpcm9ubWVudFZhcnMgfHwge30pO1xuXG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBlcnJvcjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0aXZlLmluaXRBZCh3aWR0aCwgaGVpZ2h0LCB2aWV3TW9kZSwgZGVzaXJlZEJpdHJhdGUsIGNyZWF0aXZlRGF0YSwgZW52aXJvbm1lbnRWYXJzKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgZXJyb3IgPSBlO1xuICAgICAgICB9XG5cbiAgICAgICAgY2FsbE9yVHJpZ2dlckV2ZW50KGNhbGxiYWNrLCB0aGlzLl9zdWJzY3JpYmVycywgZXJyb3IpO1xuICAgIH0uYmluZCh0aGlzKSwgMCk7XG59O1xuXG4vKipcbiAqIHN1YnNjcmliZVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtub2RlU3R5bGVDYWxsYmFja30gaGFuZGxlclxuICogQHBhcmFtIHtvYmplY3R9IGNvbnRleHRcbiAqL1xuVlBBSURBZFVuaXQucHJvdG90eXBlLnN1YnNjcmliZSA9IGZ1bmN0aW9uIHN1YnNjcmliZShldmVudCwgaGFuZGxlciwgY29udGV4dCkge1xuICAgIHRoaXMuX3N1YnNjcmliZXJzLnN1YnNjcmliZShoYW5kbGVyLCBldmVudCwgY29udGV4dCk7XG59O1xuXG5cbi8qKlxuICogdW5zdWJzY3JpYmVcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGhhbmRsZXJcbiAqL1xuVlBBSURBZFVuaXQucHJvdG90eXBlLnVuc3Vic2NyaWJlID0gZnVuY3Rpb24gdW5zdWJzY3JpYmUoZXZlbnQsIGhhbmRsZXIpIHtcbiAgICB0aGlzLl9zdWJzY3JpYmVycy51bnN1YnNjcmliZShoYW5kbGVyLCBldmVudCk7XG59O1xuXG4vL2FsaWFzXG5WUEFJREFkVW5pdC5wcm90b3R5cGUub24gPSBWUEFJREFkVW5pdC5wcm90b3R5cGUuc3Vic2NyaWJlO1xuVlBBSURBZFVuaXQucHJvdG90eXBlLm9mZiA9IFZQQUlEQWRVbml0LnByb3RvdHlwZS51bnN1YnNjcmliZTtcblxuSVZQQUlEQWRVbml0LkdFVFRFUlMuZm9yRWFjaChmdW5jdGlvbihnZXR0ZXIpIHtcbiAgICBWUEFJREFkVW5pdC5wcm90b3R5cGVbZ2V0dGVyXSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgdmFyIHJlc3VsdCwgZXJyb3IgPSBudWxsO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSB0aGlzLl9jcmVhdGl2ZVtnZXR0ZXJdKCk7XG4gICAgICAgICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgICAgICAgICBlcnJvciA9IGU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhbGxPclRyaWdnZXJFdmVudChjYWxsYmFjaywgdGhpcy5fc3Vic2NyaWJlcnMsIGVycm9yLCByZXN1bHQpO1xuICAgICAgICB9LmJpbmQodGhpcyksIDApO1xuICAgIH07XG59KTtcblxuLyoqXG4gKiBzZXRBZFZvbHVtZVxuICpcbiAqIEBwYXJhbSB2b2x1bWVcbiAqIEBwYXJhbSB7bm9kZVN0eWxlQ2FsbGJhY2t9IGNhbGxiYWNrXG4gKi9cblZQQUlEQWRVbml0LnByb3RvdHlwZS5zZXRBZFZvbHVtZSA9IGZ1bmN0aW9uIHNldEFkVm9sdW1lKHZvbHVtZSwgY2FsbGJhY2spIHtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcblxuICAgICAgICB2YXIgcmVzdWx0LCBlcnJvciA9IG51bGw7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLl9jcmVhdGl2ZS5zZXRBZFZvbHVtZSh2b2x1bWUpO1xuICAgICAgICAgICAgcmVzdWx0ID0gdGhpcy5fY3JlYXRpdmUuZ2V0QWRWb2x1bWUoKTtcbiAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgICBlcnJvciA9IGU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWVycm9yKSB7XG4gICAgICAgICAgICBlcnJvciA9IHV0aWxzLnZhbGlkYXRlKHJlc3VsdCA9PT0gdm9sdW1lLCAnZmFpbGVkIHRvIGFwcGx5IHZvbHVtZTogJyArIHZvbHVtZSk7XG4gICAgICAgIH1cbiAgICAgICAgY2FsbE9yVHJpZ2dlckV2ZW50KGNhbGxiYWNrLCB0aGlzLl9zdWJzY3JpYmVycywgZXJyb3IsIHJlc3VsdCk7XG4gICAgfS5iaW5kKHRoaXMpLCAwKTtcbn07XG5cblZQQUlEQWRVbml0LnByb3RvdHlwZS5fZGVzdHJveSA9IGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgdGhpcy5zdG9wQWQoKTtcbiAgICB0aGlzLl9zdWJzY3JpYmVycy51bnN1YnNjcmliZUFsbCgpO1xufTtcblxuZnVuY3Rpb24gJGFkZEV2ZW50c1N1YnNjcmliZXJzKCkge1xuICAgIC8vIHNvbWUgYWRzIGltcGxlbWVudFxuICAgIC8vIHNvIHRoZXkgb25seSBoYW5kbGUgb25lIHN1YnNjcmliZXJcbiAgICAvLyB0byBoYW5kbGUgdGhpcyB3ZSBjcmVhdGUgb3VyIG9uZVxuICAgIEZJTFRFUkVEX0VWRU5UUy5mb3JFYWNoKGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICB0aGlzLl9jcmVhdGl2ZS5zdWJzY3JpYmUoJHRyaWdnZXIuYmluZCh0aGlzLCBldmVudCksIGV2ZW50KTtcbiAgICB9LmJpbmQodGhpcykpO1xuXG4gICAgLy8gbWFwIHRoZSBjbGljayBldmVudCB0byBiZSBhbiBvYmplY3QgaW5zdGVhZCBvZiBkZXBlbmRpbmcgb2YgdGhlIG9yZGVyIG9mIHRoZSBhcmd1bWVudHNcbiAgICAvLyBhbmQgdG8gYmUgY29uc2lzdGVudCB3aXRoIHRoZSBmbGFzaFxuICAgIHRoaXMuX2NyZWF0aXZlLnN1YnNjcmliZSgkY2xpY2tUaHJ1SG9vay5iaW5kKHRoaXMpLCBBRF9DTElDSyk7XG5cbiAgICAvLyBiZWNhdXNlIHdlIGFyZSBhZGRpbmcgdGhlIGVsZW1lbnQgaW5zaWRlIHRoZSBpZnJhbWVcbiAgICAvLyB0aGUgdXNlciBpcyBub3QgYWJsZSB0byBjbGljayBpbiB0aGUgdmlkZW9cbiAgICBpZiAodGhpcy5fdmlkZW9FbCkge1xuICAgICAgICB2YXIgZG9jdW1lbnRFbGVtZW50ID0gdGhpcy5faWZyYW1lLmNvbnRlbnREb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gICAgICAgIHZhciB2aWRlb0VsID0gdGhpcy5fdmlkZW9FbDtcbiAgICAgICAgZG9jdW1lbnRFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgaWYgKGUudGFyZ2V0ID09PSBkb2N1bWVudEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB2aWRlb0VsLmNsaWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gJGNsaWNrVGhydUhvb2sodXJsLCBpZCwgcGxheWVySGFuZGxlcykge1xuICAgIHRoaXMuX3N1YnNjcmliZXJzLnRyaWdnZXJTeW5jKEFEX0NMSUNLLCB7dXJsOiB1cmwsIGlkOiBpZCwgcGxheWVySGFuZGxlczogcGxheWVySGFuZGxlc30pO1xufVxuXG5mdW5jdGlvbiAkdHJpZ2dlcihldmVudCkge1xuICAgIC8vIFRPRE8gYXZvaWQgbGVha2luZyBhcmd1bWVudHNcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vcGV0a2FhbnRvbm92L2JsdWViaXJkL3dpa2kvT3B0aW1pemF0aW9uLWtpbGxlcnMjMzItbGVha2luZy1hcmd1bWVudHNcbiAgICB0aGlzLl9zdWJzY3JpYmVycy50cmlnZ2VyKGV2ZW50LCBBcnJheS5wcm90b3R5cGUuc2xpY2UoYXJndW1lbnRzLCAxKSk7XG59XG5cbmZ1bmN0aW9uIGNhbGxPclRyaWdnZXJFdmVudChjYWxsYmFjaywgc3Vic2NyaWJlcnMsIGVycm9yLCByZXN1bHQpIHtcbiAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgfSBlbHNlIGlmIChlcnJvcikge1xuICAgICAgICBzdWJzY3JpYmVycy50cmlnZ2VyKEVSUk9SLCBlcnJvcik7XG4gICAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFZQQUlEQWRVbml0O1xuXG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciB1bmlxdWUgPSB1dGlscy51bmlxdWUoJ3ZwYWlkSWZyYW1lJyk7XG52YXIgVlBBSURBZFVuaXQgPSByZXF1aXJlKCcuL1ZQQUlEQWRVbml0Jyk7XG5cbnZhciBkZWZhdWx0VGVtcGxhdGUgPSAnPCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz1cImVuXCI+PGhlYWQ+PG1ldGEgY2hhcnNldD1cIlVURi04XCI+PC9oZWFkPjxib2R5IHN0eWxlPVwibWFyZ2luOjA7cGFkZGluZzowXCI+JztcbmRlZmF1bHRUZW1wbGF0ZSArPSAnPHNjcmlwdCB0eXBlPVwidGV4dC9qYXZhc2NyaXB0XCIgc3JjPVwie3tpZnJhbWVVUkxfSlN9fVwiPjwvc2NyaXB0PjxzY3JpcHQ+JztcbmRlZmF1bHRUZW1wbGF0ZSArPSAncGFyZW50LnBvc3RNZXNzYWdlKFxcJ3tcImV2ZW50XCI6IFwicmVhZHlcIiwgXCJpZFwiOiBcInt7aWZyYW1lSUR9fVwifVxcJywgd2luZG93LmxvY2F0aW9uLm9yaWdpbik7JztcbmRlZmF1bHRUZW1wbGF0ZSArPSAnPC9zY3JpcHQ+PGRpdiBjbGFzcz1cImFkLWVsZW1lbnRcIj48L2Rpdj48L2JvZHk+PC9odG1sPic7XG5cbnZhciBBRF9TVE9QUEVEID0gJ0FkU3RvcHBlZCc7XG5cbi8qKlxuICogVGhpcyBjYWxsYmFjayBpcyBkaXNwbGF5ZWQgYXMgZ2xvYmFsIG1lbWJlci4gVGhlIGNhbGxiYWNrIHVzZSBub2RlanMgZXJyb3ItZmlyc3QgY2FsbGJhY2sgc3R5bGVcbiAqIEBjYWxsYmFjayBOb2RlU3R5bGVDYWxsYmFja1xuICogQHBhcmFtIHtzdHJpbmd8bnVsbH1cbiAqIEBwYXJhbSB7dW5kZWZpbmVkfG9iamVjdH1cbiAqL1xuXG4vKipcbiAqIFZQQUlESFRNTDVDbGllbnRcbiAqIEBjbGFzc1xuICpcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsIHRoYXQgd2lsbCBjb250YWluIHRoZSBpZnJhbWUgdG8gbG9hZCBhZFVuaXQgYW5kIGEgZWwgdG8gYWRkIHRvIGFkVW5pdCBzbG90XG4gKiBAcGFyYW0ge0hUTUxWaWRlb0VsZW1lbnR9IHZpZGVvIGRlZmF1bHQgdmlkZW8gZWxlbWVudCB0byBiZSB1c2VkIGJ5IGFkVW5pdFxuICogQHBhcmFtIHtvYmplY3R9IFt0ZW1wbGF0ZUNvbmZpZ10gdGVtcGxhdGU6IGh0bWwgdGVtcGxhdGUgdG8gYmUgdXNlZCBpbnN0ZWFkIG9mIHRoZSBkZWZhdWx0LCBleHRyYU9wdGlvbnM6IHRvIGJlIHVzZWQgd2hlbiByZW5kZXJpbmcgdGhlIHRlbXBsYXRlXG4gKiBAcGFyYW0ge29iamVjdH0gW3ZwYWlkT3B0aW9uc10gdGltZW91dDogd2hlbiBsb2FkaW5nIGFkVW5pdFxuICovXG5mdW5jdGlvbiBWUEFJREhUTUw1Q2xpZW50KGVsLCB2aWRlbywgdGVtcGxhdGVDb25maWcsIHZwYWlkT3B0aW9ucykge1xuICAgIHRlbXBsYXRlQ29uZmlnID0gdGVtcGxhdGVDb25maWcgfHwge307XG5cbiAgICB0aGlzLl9pZCA9IHVuaXF1ZSgpO1xuICAgIHRoaXMuX2Rlc3Ryb3llZCA9IGZhbHNlO1xuXG4gICAgdGhpcy5fZnJhbWVDb250YWluZXIgPSB1dGlscy5jcmVhdGVFbGVtZW50SW5FbChlbCwgJ2RpdicpO1xuICAgIHRoaXMuX3ZpZGVvRWwgPSB2aWRlbztcbiAgICB0aGlzLl92cGFpZE9wdGlvbnMgPSB2cGFpZE9wdGlvbnMgfHwge3RpbWVvdXQ6IDEwMDAwfTtcblxuICAgIHRoaXMuX3RlbXBsYXRlQ29uZmlnID0ge1xuICAgICAgICB0ZW1wbGF0ZTogdGVtcGxhdGVDb25maWcudGVtcGxhdGUgfHwgZGVmYXVsdFRlbXBsYXRlLFxuICAgICAgICBleHRyYU9wdGlvbnM6IHRlbXBsYXRlQ29uZmlnLmV4dHJhT3B0aW9ucyB8fCB7fVxuICAgIH07XG5cbn1cblxuLyoqXG4gKiBkZXN0cm95XG4gKlxuICovXG5WUEFJREhUTUw1Q2xpZW50LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gZGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy5fZGVzdHJveWVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fZGVzdHJveWVkID0gdHJ1ZTtcbiAgICAkdW5sb2FkUHJldmlvdXNBZFVuaXQuY2FsbCh0aGlzKTtcbn07XG5cbi8qKlxuICogaXNEZXN0cm95ZWRcbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5WUEFJREhUTUw1Q2xpZW50LnByb3RvdHlwZS5pc0Rlc3Ryb3llZCA9IGZ1bmN0aW9uIGlzRGVzdHJveWVkKCkge1xuICAgIHJldHVybiB0aGlzLl9kZXN0cm95ZWQ7XG59O1xuXG4vKipcbiAqIGxvYWRBZFVuaXRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gYWRVUkwgdXJsIG9mIHRoZSBqcyBvZiB0aGUgYWRVbml0XG4gKiBAcGFyYW0ge25vZGVTdHlsZUNhbGxiYWNrfSBjYWxsYmFja1xuICovXG5WUEFJREhUTUw1Q2xpZW50LnByb3RvdHlwZS5sb2FkQWRVbml0ID0gZnVuY3Rpb24gbG9hZEFkVW5pdChhZFVSTCwgY2FsbGJhY2spIHtcbiAgICAkdGhyb3dJZkRlc3Ryb3llZC5jYWxsKHRoaXMpO1xuICAgICR1bmxvYWRQcmV2aW91c0FkVW5pdC5jYWxsKHRoaXMpO1xuXG4gICAgdmFyIGZyYW1lID0gdXRpbHMuY3JlYXRlSWZyYW1lV2l0aENvbnRlbnQoXG4gICAgICAgIHRoaXMuX2ZyYW1lQ29udGFpbmVyLFxuICAgICAgICB0aGlzLl90ZW1wbGF0ZUNvbmZpZy50ZW1wbGF0ZSxcbiAgICAgICAgdXRpbHMuZXh0ZW5kKHtcbiAgICAgICAgICAgIGlmcmFtZVVSTF9KUzogYWRVUkwsXG4gICAgICAgICAgICBpZnJhbWVJRDogdGhpcy5nZXRJRCgpXG4gICAgICAgIH0sIHRoaXMuX3RlbXBsYXRlQ29uZmlnLmV4dHJhT3B0aW9ucylcbiAgICApO1xuICAgIHRoaXMuX2ZyYW1lID0gZnJhbWU7XG5cbiAgICB0aGlzLl9vbkxvYWQgPSB1dGlscy5jYWxsYmFja1RpbWVvdXQoXG4gICAgICAgIHRoaXMuX3ZwYWlkT3B0aW9ucy50aW1lb3V0LFxuICAgICAgICBvbkxvYWQuYmluZCh0aGlzKSxcbiAgICAgICAgb25UaW1lb3V0LmJpbmQodGhpcylcbiAgICApO1xuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0aGlzLl9vbkxvYWQpO1xuXG4gICAgZnVuY3Rpb24gb25Mb2FkIChlKSB7XG4gICAgICAgIC8qanNoaW50IHZhbGlkdGhpczogZmFsc2UgKi9cbiAgICAgICAgLy9kb24ndCBjbGVhciB0aW1lb3V0XG4gICAgICAgIGlmIChlLm9yaWdpbiAhPT0gd2luZG93LmxvY2F0aW9uLm9yaWdpbikgcmV0dXJuO1xuICAgICAgICB2YXIgcmVzdWx0ID0gSlNPTi5wYXJzZShlLmRhdGEpO1xuXG4gICAgICAgIC8vZG9uJ3QgY2xlYXIgdGltZW91dFxuICAgICAgICBpZiAocmVzdWx0LmlkICE9PSB0aGlzLmdldElEKCkpIHJldHVybjtcblxuICAgICAgICB2YXIgYWRVbml0LCBlcnJvciwgY3JlYXRlQWQ7XG4gICAgICAgIGlmICghdGhpcy5fZnJhbWUuY29udGVudFdpbmRvdykge1xuXG4gICAgICAgICAgICBlcnJvciA9ICd0aGUgaWZyYW1lIGlzIG5vdCBhbnltb3JlIGluIHRoZSBET00gdHJlZSc7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNyZWF0ZUFkID0gdGhpcy5fZnJhbWUuY29udGVudFdpbmRvdy5nZXRWUEFJREFkO1xuICAgICAgICAgICAgZXJyb3IgPSB1dGlscy52YWxpZGF0ZSh0eXBlb2YgY3JlYXRlQWQgPT09ICdmdW5jdGlvbicsICd0aGUgYWQgZGlkblxcJ3QgcmV0dXJuIGEgZnVuY3Rpb24gdG8gY3JlYXRlIGFuIGFkJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWVycm9yKSB7XG4gICAgICAgICAgICB2YXIgYWRFbCA9IHRoaXMuX2ZyYW1lLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmFkLWVsZW1lbnQnKTtcbiAgICAgICAgICAgIGFkVW5pdCA9IG5ldyBWUEFJREFkVW5pdChjcmVhdGVBZCgpLCBhZEVsLCB0aGlzLl92aWRlb0VsLCB0aGlzLl9mcmFtZSk7XG4gICAgICAgICAgICBhZFVuaXQuc3Vic2NyaWJlKEFEX1NUT1BQRUQsICRhZERlc3Ryb3llZC5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIGVycm9yID0gdXRpbHMudmFsaWRhdGUoYWRVbml0LmlzVmFsaWRWUEFJREFkKCksICd0aGUgYWRkIGlzIG5vdCBmdWxseSBjb21wbGFpbnQgd2l0aCBWUEFJRCBzcGVjaWZpY2F0aW9uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9hZFVuaXQgPSBhZFVuaXQ7XG4gICAgICAgICRkZXN0cm95TG9hZExpc3RlbmVyLmNhbGwodGhpcyk7XG4gICAgICAgIGNhbGxiYWNrKGVycm9yLCBlcnJvciA/IG51bGwgOiBhZFVuaXQpO1xuXG4gICAgICAgIC8vY2xlYXIgdGltZW91dFxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBvblRpbWVvdXQoKSB7XG4gICAgICAgIGNhbGxiYWNrKCd0aW1lb3V0JywgbnVsbCk7XG4gICAgfVxufTtcblxuLyoqXG4gKiB1bmxvYWRBZFVuaXRcbiAqXG4gKi9cblZQQUlESFRNTDVDbGllbnQucHJvdG90eXBlLnVubG9hZEFkVW5pdCA9IGZ1bmN0aW9uIHVubG9hZEFkVW5pdCgpIHtcbiAgICAkdW5sb2FkUHJldmlvdXNBZFVuaXQuY2FsbCh0aGlzKTtcbn07XG5cbi8qKlxuICogZ2V0SUQgd2lsbCByZXR1cm4gdGhlIHVuaXF1ZSBpZFxuICpcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuVlBBSURIVE1MNUNsaWVudC5wcm90b3R5cGUuZ2V0SUQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2lkO1xufTtcblxuXG4vKipcbiAqICRyZW1vdmVFbFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAqL1xuZnVuY3Rpb24gJHJlbW92ZUVsKGtleSkge1xuICAgIHZhciBlbCA9IHRoaXNba2V5XTtcbiAgICBpZiAoZWwpIHtcbiAgICAgICAgZWwucmVtb3ZlKCk7XG4gICAgICAgIGRlbGV0ZSB0aGlzW2tleV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiAkYWREZXN0cm95ZWQoKSB7XG4gICAgJHJlbW92ZUFkRWxlbWVudHMuY2FsbCh0aGlzKTtcbiAgICBkZWxldGUgdGhpcy5fYWRVbml0O1xufVxuXG5mdW5jdGlvbiAkdW5sb2FkUHJldmlvdXNBZFVuaXQoKSB7XG4gICAgJHJlbW92ZUFkRWxlbWVudHMuY2FsbCh0aGlzKTtcbiAgICAkZGVzdHJveUFkVW5pdC5jYWxsKHRoaXMpO1xufVxuXG5mdW5jdGlvbiAkcmVtb3ZlQWRFbGVtZW50cygpIHtcbiAgICAkcmVtb3ZlRWwuY2FsbCh0aGlzLCAnX2ZyYW1lJyk7XG4gICAgJGRlc3Ryb3lMb2FkTGlzdGVuZXIuY2FsbCh0aGlzKTtcbn1cblxuLyoqXG4gKiAkZGVzdHJveUxvYWRMaXN0ZW5lclxuICpcbiAqL1xuZnVuY3Rpb24gJGRlc3Ryb3lMb2FkTGlzdGVuZXIoKSB7XG4gICAgaWYgKHRoaXMuX29uTG9hZCkge1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRoaXMuX29uTG9hZCk7XG4gICAgICAgIHV0aWxzLmNsZWFyQ2FsbGJhY2tUaW1lb3V0KHRoaXMuX29uTG9hZCk7XG4gICAgICAgIGRlbGV0ZSB0aGlzLl9vbkxvYWQ7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uICRkZXN0cm95QWRVbml0KCkge1xuICAgIGlmICh0aGlzLl9hZFVuaXQpIHtcbiAgICAgICAgdGhpcy5fYWRVbml0LnN0b3BBZCgpO1xuICAgICAgICBkZWxldGUgdGhpcy5fYWRVbml0O1xuICAgIH1cbn1cblxuLyoqXG4gKiAkdGhyb3dJZkRlc3Ryb3llZFxuICpcbiAqL1xuZnVuY3Rpb24gJHRocm93SWZEZXN0cm95ZWQoKSB7XG4gICAgaWYgKHRoaXMuX2Rlc3Ryb3llZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IgKCdWUEFJREhUTUw1Q2xpZW50IGFscmVhZHkgZGVzdHJveWVkIScpO1xuICAgIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBWUEFJREhUTUw1Q2xpZW50O1xud2luZG93LlZQQUlESFRNTDVDbGllbnQgPSBWUEFJREhUTUw1Q2xpZW50O1xuXG4iLCIndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIFN1YnNjcmliZXIoKSB7XG4gICAgdGhpcy5fc3Vic2NyaWJlcnMgPSB7fTtcbn1cblxuU3Vic2NyaWJlci5wcm90b3R5cGUuc3Vic2NyaWJlID0gZnVuY3Rpb24gc3Vic2NyaWJlKGhhbmRsZXIsIGV2ZW50TmFtZSwgY29udGV4dCkge1xuICAgIHRoaXMuZ2V0KGV2ZW50TmFtZSkucHVzaCh7aGFuZGxlcjogaGFuZGxlciwgY29udGV4dDogY29udGV4dH0pO1xufTtcblxuU3Vic2NyaWJlci5wcm90b3R5cGUudW5zdWJzY3JpYmUgPSBmdW5jdGlvbiB1bnN1YnNjcmliZShoYW5kbGVyLCBldmVudE5hbWUpIHtcbiAgICB0aGlzLl9zdWJzY3JpYmVyc1tldmVudE5hbWVdID0gdGhpcy5nZXQoZXZlbnROYW1lKS5maWx0ZXIoZnVuY3Rpb24gKHN1YnNjcmliZXIpIHtcbiAgICAgICAgcmV0dXJuIGhhbmRsZXIgPT09IHN1YnNjcmliZXIuaGFuZGxlcjtcbiAgICB9KTtcbn07XG5cblN1YnNjcmliZXIucHJvdG90eXBlLnVuc3Vic2NyaWJlQWxsID0gZnVuY3Rpb24gdW5zdWJzY3JpYmVBbGwoKSB7XG4gICAgdGhpcy5fc3Vic2NyaWJlcnMgPSB7fTtcbn07XG5cblN1YnNjcmliZXIucHJvdG90eXBlLnRyaWdnZXIgPSBmdW5jdGlvbihldmVudE5hbWUsIGRhdGEpIHtcbiAgICB2YXIgdGhhdCA9IHRoaXM7XG4gICAgdGhhdC5nZXQoZXZlbnROYW1lKS5mb3JFYWNoKGZ1bmN0aW9uIChzdWJzY3JpYmVyKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKHRoYXQuZ2V0KGV2ZW50TmFtZSkpIHtcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVyLmhhbmRsZXIuY2FsbChzdWJzY3JpYmVyLmNvbnRleHQsIGRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCAwKTtcbiAgICB9KTtcbn07XG5cblN1YnNjcmliZXIucHJvdG90eXBlLnRyaWdnZXJTeW5jID0gZnVuY3Rpb24oZXZlbnROYW1lLCBkYXRhKSB7XG4gICAgdGhpcy5nZXQoZXZlbnROYW1lKS5mb3JFYWNoKGZ1bmN0aW9uIChzdWJzY3JpYmVyKSB7XG4gICAgICAgIHN1YnNjcmliZXIuaGFuZGxlci5jYWxsKHN1YnNjcmliZXIuY29udGV4dCwgZGF0YSk7XG4gICAgfSk7XG59O1xuXG5TdWJzY3JpYmVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiBnZXQoZXZlbnROYW1lKSB7XG4gICAgaWYgKCF0aGlzLl9zdWJzY3JpYmVyc1tldmVudE5hbWVdKSB7XG4gICAgICAgIHRoaXMuX3N1YnNjcmliZXJzW2V2ZW50TmFtZV0gPSBbXTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3N1YnNjcmliZXJzW2V2ZW50TmFtZV07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFN1YnNjcmliZXI7XG5cbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBub29wIGEgZW1wdHkgZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbi8qKlxuICogdmFsaWRhdGUgaWYgaXMgbm90IHZhbGlkYXRlIHdpbGwgcmV0dXJuIGFuIEVycm9yIHdpdGggdGhlIG1lc3NhZ2VcbiAqXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGlzVmFsaWRcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlKGlzVmFsaWQsIG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gaXNWYWxpZCA/IG51bGwgOiBuZXcgRXJyb3IobWVzc2FnZSk7XG59XG5cbnZhciB0aW1lb3V0cyA9IHt9O1xuLyoqXG4gKiBjbGVhckNhbGxiYWNrVGltZW91dFxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGZ1bmMgaGFuZGxlciB0byByZW1vdmVcbiAqL1xuZnVuY3Rpb24gY2xlYXJDYWxsYmFja1RpbWVvdXQoZnVuYykge1xuICAgIHZhciB0aW1lb3V0ID0gdGltZW91dHNbZnVuY107XG4gICAgaWYgKHRpbWVvdXQpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICBkZWxldGUgdGltZW91dHNbZnVuY107XG4gICAgfVxufVxuXG4vKipcbiAqIGNhbGxiYWNrVGltZW91dCBpZiB0aGUgb25TdWNjZXNzIGlzIG5vdCBjYWxsZWQgYW5kIHJldHVybnMgdHJ1ZSBpbiB0aGUgdGltZWxpbWl0IHRoZW4gb25UaW1lb3V0IHdpbGwgYmUgY2FsbGVkXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHRpbWVyXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBvblN1Y2Nlc3NcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IG9uVGltZW91dFxuICovXG5mdW5jdGlvbiBjYWxsYmFja1RpbWVvdXQodGltZXIsIG9uU3VjY2Vzcywgb25UaW1lb3V0KSB7XG4gICAgdmFyIGNhbGxiYWNrLCB0aW1lb3V0O1xuXG4gICAgdGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBvblN1Y2Nlc3MgPSBub29wO1xuICAgICAgICBkZWxldGUgdGltZW91dFtjYWxsYmFja107XG4gICAgICAgIG9uVGltZW91dCgpO1xuICAgIH0sIHRpbWVyKTtcblxuICAgIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBUT0RPIGF2b2lkIGxlYWtpbmcgYXJndW1lbnRzXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9wZXRrYWFudG9ub3YvYmx1ZWJpcmQvd2lraS9PcHRpbWl6YXRpb24ta2lsbGVycyMzMi1sZWFraW5nLWFyZ3VtZW50c1xuICAgICAgICBpZiAob25TdWNjZXNzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpIHtcbiAgICAgICAgICAgIGNsZWFyQ2FsbGJhY2tUaW1lb3V0KGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB0aW1lb3V0c1tjYWxsYmFja10gPSB0aW1lb3V0O1xuXG4gICAgcmV0dXJuIGNhbGxiYWNrO1xufVxuXG5cbi8qKlxuICogY3JlYXRlRWxlbWVudEluRWxcbiAqXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBwYXJlbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWdOYW1lXG4gKiBAcGFyYW0ge3N0cmluZ30gaWRcbiAqL1xuZnVuY3Rpb24gY3JlYXRlRWxlbWVudEluRWwocGFyZW50LCB0YWdOYW1lLCBpZCkge1xuICAgIHZhciBuRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZ05hbWUpO1xuICAgIGlmIChpZCkgbkVsLmlkID0gaWQ7XG4gICAgcGFyZW50LmFwcGVuZENoaWxkKG5FbCk7XG4gICAgcmV0dXJuIG5FbDtcbn1cblxuLyoqXG4gKiBjcmVhdGVJZnJhbWVXaXRoQ29udGVudFxuICpcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHBhcmVudFxuICogQHBhcmFtIHtzdHJpbmd9IHRlbXBsYXRlIHNpbXBsZSB0ZW1wbGF0ZSB1c2luZyB7e3Zhcn19XG4gKiBAcGFyYW0ge29iamVjdH0gZGF0YVxuICovXG5mdW5jdGlvbiBjcmVhdGVJZnJhbWVXaXRoQ29udGVudChwYXJlbnQsIHRlbXBsYXRlLCBkYXRhKSB7XG4gICAgdmFyIGlmcmFtZSA9IGNyZWF0ZUlmcmFtZShwYXJlbnQpO1xuICAgIGlmICghc2V0SWZyYW1lQ29udGVudChpZnJhbWUsIHNpbXBsZVRlbXBsYXRlKHRlbXBsYXRlLCBkYXRhKSkpIHJldHVybjtcbiAgICByZXR1cm4gaWZyYW1lO1xufVxuXG4vKipcbiAqIGNyZWF0ZUlmcmFtZVxuICpcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHBhcmVudFxuICogQHBhcmFtIHtzdHJpbmd9IHVybFxuICovXG5mdW5jdGlvbiBjcmVhdGVJZnJhbWUocGFyZW50LCB1cmwpIHtcbiAgICB2YXIgbkVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgbkVsLnNyYyA9IHVybCB8fCAnYWJvdXQ6YmxhbmsnO1xuICAgIG5FbC5tYXJnaW5XaWR0aCA9ICcwJztcbiAgICBuRWwubWFyZ2luSGVpZ2h0ID0gJzAnO1xuICAgIG5FbC5mcmFtZUJvcmRlciA9ICcwJztcbiAgICBuRWwud2lkdGggPSAnMTAwJSc7XG4gICAgbkVsLmhlaWdodCA9ICcxMDAlJztcbiAgICBuRWwuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgIG5FbC5zdHlsZS5sZWZ0ID0gJzAnO1xuICAgIG5FbC5zdHlsZS50b3AgPSAnMCc7XG4gICAgbkVsLnN0eWxlLm1hcmdpbiA9ICcwcHgnO1xuICAgIG5FbC5zdHlsZS5wYWRkaW5nID0gJzBweCc7XG4gICAgbkVsLnN0eWxlLmJvcmRlciA9ICdub25lJztcbiAgICBuRWwuc2V0QXR0cmlidXRlKCdTQ1JPTExJTkcnLCdOTycpO1xuICAgIHBhcmVudC5pbm5lckhUTUwgPSAnJztcbiAgICBwYXJlbnQuYXBwZW5kQ2hpbGQobkVsKTtcbiAgICByZXR1cm4gbkVsO1xufVxuXG4vKipcbiAqIHNpbXBsZVRlbXBsYXRlXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRlbXBsYXRlXG4gKiBAcGFyYW0ge29iamVjdH0gZGF0YVxuICovXG5mdW5jdGlvbiBzaW1wbGVUZW1wbGF0ZSh0ZW1wbGF0ZSwgZGF0YSkge1xuICAgIE9iamVjdC5rZXlzKGRhdGEpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgICB2YXIgdmFsdWUgPSAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JykgPyBKU09OLnN0cmluZ2lmeShkYXRhW2tleV0pIDogZGF0YVtrZXldO1xuICAgICAgICB0ZW1wbGF0ZSA9IHRlbXBsYXRlLnJlcGxhY2UobmV3IFJlZ0V4cCgne3snICsga2V5ICsgJ319JywgJ2cnKSwgdmFsdWUpO1xuICAgIH0pO1xuICAgIHJldHVybiB0ZW1wbGF0ZTtcbn1cblxuLyoqXG4gKiBzZXRJZnJhbWVDb250ZW50XG4gKlxuICogQHBhcmFtIHtIVE1MSWZyYW1lRWxlbWVudH0gaWZyYW1lRWxcbiAqIEBwYXJhbSBjb250ZW50XG4gKi9cbmZ1bmN0aW9uIHNldElmcmFtZUNvbnRlbnQoaWZyYW1lRWwsIGNvbnRlbnQpIHtcbiAgICB2YXIgaWZyYW1lRG9jID0gaWZyYW1lRWwuY29udGVudFdpbmRvdyAmJiBpZnJhbWVFbC5jb250ZW50V2luZG93LmRvY3VtZW50O1xuICAgIGlmICghaWZyYW1lRG9jKSByZXR1cm4gZmFsc2U7XG5cbiAgICBpZnJhbWVEb2Mud3JpdGUoY29udGVudCk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuXG4vKipcbiAqIGV4dGVuZCBvYmplY3Qgd2l0aCBrZXlzIGZyb20gYW5vdGhlciBvYmplY3RcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gdG9FeHRlbmRcbiAqIEBwYXJhbSB7b2JqZWN0fSBmcm9tU291cmNlXG4gKi9cbmZ1bmN0aW9uIGV4dGVuZCh0b0V4dGVuZCwgZnJvbVNvdXJjZSkge1xuICAgIE9iamVjdC5rZXlzKGZyb21Tb3VyY2UpLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG4gICAgICAgIHRvRXh0ZW5kW2tleV0gPSBmcm9tU291cmNlW2tleV07XG4gICAgfSk7XG4gICAgcmV0dXJuIHRvRXh0ZW5kO1xufVxuXG5cbi8qKlxuICogdW5pcXVlIHdpbGwgY3JlYXRlIGEgdW5pcXVlIHN0cmluZyBldmVyeXRpbWUgaXMgY2FsbGVkLCBzZXF1ZW50aWFsbHkgYW5kIHByZWZpeGVkXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHByZWZpeFxuICovXG5mdW5jdGlvbiB1bmlxdWUocHJlZml4KSB7XG4gICAgdmFyIGNvdW50ID0gLTE7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHByZWZpeCArICdfJyArICgrK2NvdW50KTtcbiAgICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBub29wOiBub29wLFxuICAgIHZhbGlkYXRlOiB2YWxpZGF0ZSxcbiAgICBjbGVhckNhbGxiYWNrVGltZW91dDogY2xlYXJDYWxsYmFja1RpbWVvdXQsXG4gICAgY2FsbGJhY2tUaW1lb3V0OiBjYWxsYmFja1RpbWVvdXQsXG4gICAgY3JlYXRlRWxlbWVudEluRWw6IGNyZWF0ZUVsZW1lbnRJbkVsLFxuICAgIGNyZWF0ZUlmcmFtZVdpdGhDb250ZW50OiBjcmVhdGVJZnJhbWVXaXRoQ29udGVudCxcbiAgICBjcmVhdGVJZnJhbWU6IGNyZWF0ZUlmcmFtZSxcbiAgICBzaW1wbGVUZW1wbGF0ZTogc2ltcGxlVGVtcGxhdGUsXG4gICAgc2V0SWZyYW1lQ29udGVudDogc2V0SWZyYW1lQ29udGVudCxcbiAgICBleHRlbmQ6IGV4dGVuZCxcbiAgICB1bmlxdWU6IHVuaXF1ZVxufTtcblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgSW5MaW5lID0gcmVxdWlyZSgnLi9JbkxpbmUnKTtcbnZhciBXcmFwcGVyID0gcmVxdWlyZSgnLi9XcmFwcGVyJyk7XG5cbmZ1bmN0aW9uIEFkKGFkSlRyZWUpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEFkKSkge1xuICAgIHJldHVybiBuZXcgQWQoYWRKVHJlZSk7XG4gIH1cbiAgdGhpcy5pbml0aWFsaXplKGFkSlRyZWUpO1xufVxuXG5BZC5wcm90b3R5cGUuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKGFkSlRyZWUpIHtcbiAgdGhpcy5pZCA9IGFkSlRyZWUuYXR0cignaWQnKTtcbiAgdGhpcy5zZXF1ZW5jZSA9IGFkSlRyZWUuYXR0cignc2VxdWVuY2UnKTtcblxuICBpZihhZEpUcmVlLmluTGluZSkge1xuICAgIHRoaXMuaW5MaW5lID0gbmV3IEluTGluZShhZEpUcmVlLmluTGluZSk7XG4gIH1cblxuICBpZihhZEpUcmVlLndyYXBwZXIpe1xuICAgIHRoaXMud3JhcHBlciA9IG5ldyBXcmFwcGVyKGFkSlRyZWUud3JhcHBlcik7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gQWQ7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHJhY2tpbmdFdmVudCA9IHJlcXVpcmUoJy4vVHJhY2tpbmdFdmVudCcpO1xuXG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucycpO1xuXG52YXIgeG1sID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMveG1sJyk7XG5cblxuZnVuY3Rpb24gQ29tcGFuaW9uKGNvbXBhbmlvbkpUcmVlKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBDb21wYW5pb24pKSB7XG4gICAgcmV0dXJuIG5ldyBDb21wYW5pb24oY29tcGFuaW9uSlRyZWUpO1xuICB9XG5cbiAgLy9SZXF1aXJlZCBFbGVtZW50c1xuICB0aGlzLmNyZWF0aXZlVHlwZSA9IHhtbC5hdHRyKGNvbXBhbmlvbkpUcmVlLnN0YXRpY1Jlc291cmNlLCAnY3JlYXRpdmVUeXBlJyk7XG4gIHRoaXMuc3RhdGljUmVzb3VyY2UgPSB4bWwua2V5VmFsdWUoY29tcGFuaW9uSlRyZWUuc3RhdGljUmVzb3VyY2UpO1xuXG4gIC8vIFdlaXJkIGJ1ZyB3aGVuIHRoZSBKWE9OIHRyZWUgaXMgYnVpbHQgaXQgZG9lc24ndCBoYW5kbGUgY2FzaW5nIHByb3Blcmx5IGluIHRoaXMgc2l0dWF0aW9uLi4uXG4gIHZhciBodG1sUmVzb3VyY2UgPSBudWxsO1xuICBpZiAoeG1sLmtleVZhbHVlKGNvbXBhbmlvbkpUcmVlLkhUTUxSZXNvdXJjZSkpIHtcbiAgICBodG1sUmVzb3VyY2UgPSB4bWwua2V5VmFsdWUoY29tcGFuaW9uSlRyZWUuSFRNTFJlc291cmNlKTtcbiAgfSBlbHNlIGlmICh4bWwua2V5VmFsdWUoY29tcGFuaW9uSlRyZWUuaFRNTFJlc291cmNlKSkge1xuICAgIGh0bWxSZXNvdXJjZSA9IHhtbC5rZXlWYWx1ZShjb21wYW5pb25KVHJlZS5oVE1MUmVzb3VyY2UpO1xuICB9XG4gIHRoaXMuaHRtbFJlc291cmNlID0gaHRtbFJlc291cmNlO1xuXG4gIHZhciBpZnJhbWVSZXNvdXJjZSA9IG51bGw7XG4gIGlmICh4bWwua2V5VmFsdWUoY29tcGFuaW9uSlRyZWUuSUZyYW1lUmVzb3VyY2UpKSB7XG4gICAgaWZyYW1lUmVzb3VyY2UgPSB4bWwua2V5VmFsdWUoY29tcGFuaW9uSlRyZWUuSUZyYW1lUmVzb3VyY2UpO1xuICB9IGVsc2UgaWYgKHhtbC5rZXlWYWx1ZShjb21wYW5pb25KVHJlZS5pRnJhbWVyZXNvdXJjZSkpIHtcbiAgICBpZnJhbWVSZXNvdXJjZSA9IHhtbC5rZXlWYWx1ZShjb21wYW5pb25KVHJlZS5pRnJhbWVyZXNvdXJjZSk7XG4gIH1cbiAgdGhpcy5pZnJhbWVSZXNvdXJjZSA9IGlmcmFtZVJlc291cmNlO1xuXG4gIC8vT3B0aW9uYWwgZmllbGRzXG4gIHRoaXMuaWQgPSB4bWwuYXR0cihjb21wYW5pb25KVHJlZSwgJ2lkJyk7XG4gIHRoaXMud2lkdGggPSB4bWwuYXR0cihjb21wYW5pb25KVHJlZSwgJ3dpZHRoJyk7XG4gIHRoaXMuaGVpZ2h0ID0geG1sLmF0dHIoY29tcGFuaW9uSlRyZWUsICdoZWlnaHQnKTtcbiAgdGhpcy5leHBhbmRlZFdpZHRoID0geG1sLmF0dHIoY29tcGFuaW9uSlRyZWUsICdleHBhbmRlZFdpZHRoJyk7XG4gIHRoaXMuZXhwYW5kZWRIZWlnaHQgPSB4bWwuYXR0cihjb21wYW5pb25KVHJlZSwgJ2V4cGFuZGVkSGVpZ2h0Jyk7XG4gIHRoaXMuc2NhbGFibGUgPSB4bWwuYXR0cihjb21wYW5pb25KVHJlZSwgJ3NjYWxhYmxlJyk7XG4gIHRoaXMubWFpbnRhaW5Bc3BlY3RSYXRpbyA9IHhtbC5hdHRyKGNvbXBhbmlvbkpUcmVlLCAnbWFpbnRhaW5Bc3BlY3RSYXRpbycpO1xuICB0aGlzLm1pblN1Z2dlc3RlZER1cmF0aW9uID0geG1sLmF0dHIoY29tcGFuaW9uSlRyZWUsICdtaW5TdWdnZXN0ZWREdXJhdGlvbicpO1xuICB0aGlzLmFwaUZyYW1ld29yayA9IHhtbC5hdHRyKGNvbXBhbmlvbkpUcmVlLCAnYXBpRnJhbWV3b3JrJyk7XG4gIHRoaXMuY29tcGFuaW9uQ2xpY2tUaHJvdWdoID0geG1sLmtleVZhbHVlKGNvbXBhbmlvbkpUcmVlLmNvbXBhbmlvbkNsaWNrVGhyb3VnaCk7XG4gIHRoaXMudHJhY2tpbmdFdmVudHMgPSBwYXJzZVRyYWNraW5nRXZlbnRzKGNvbXBhbmlvbkpUcmVlLnRyYWNraW5nRXZlbnRzICYmIGNvbXBhbmlvbkpUcmVlLnRyYWNraW5nRXZlbnRzLnRyYWNraW5nKTtcblxuICAvKioqIExvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIHBhcnNlVHJhY2tpbmdFdmVudHModHJhY2tpbmdFdmVudHMpIHtcbiAgICB2YXIgdHJhY2tpbmdzID0gW107XG4gICAgaWYgKHV0aWxpdGllcy5pc0RlZmluZWQodHJhY2tpbmdFdmVudHMpKSB7XG4gICAgICB0cmFja2luZ0V2ZW50cyA9IHV0aWxpdGllcy5pc0FycmF5KHRyYWNraW5nRXZlbnRzKSA/IHRyYWNraW5nRXZlbnRzIDogW3RyYWNraW5nRXZlbnRzXTtcbiAgICAgIHRyYWNraW5nRXZlbnRzLmZvckVhY2goZnVuY3Rpb24gKHRyYWNraW5nRGF0YSkge1xuICAgICAgICB0cmFja2luZ3MucHVzaChuZXcgVHJhY2tpbmdFdmVudCh0cmFja2luZ0RhdGEpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdHJhY2tpbmdzO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQ29tcGFuaW9uOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIExpbmVhciA9IHJlcXVpcmUoJy4vTGluZWFyJyk7XG52YXIgQ29tcGFuaW9uID0gcmVxdWlyZSgnLi9Db21wYW5pb24nKTtcbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbmZ1bmN0aW9uIENyZWF0aXZlKGNyZWF0aXZlSlRyZWUpIHtcbiAgaWYoISh0aGlzIGluc3RhbmNlb2YgQ3JlYXRpdmUpKSB7XG4gICAgcmV0dXJuIG5ldyBDcmVhdGl2ZShjcmVhdGl2ZUpUcmVlKTtcbiAgfVxuXG4gIHRoaXMuaWQgPSBjcmVhdGl2ZUpUcmVlLmF0dHIoJ2lkJyk7XG4gIHRoaXMuc2VxdWVuY2UgPSBjcmVhdGl2ZUpUcmVlLmF0dHIoJ3NlcXVlbmNlJyk7XG4gIHRoaXMuYWRJZCA9IGNyZWF0aXZlSlRyZWUuYXR0cignYWRJZCcpO1xuICB0aGlzLmFwaUZyYW1ld29yayA9IGNyZWF0aXZlSlRyZWUuYXR0cignYXBpRnJhbWV3b3JrJyk7XG5cbiAgaWYoY3JlYXRpdmVKVHJlZS5saW5lYXIpIHtcbiAgICB0aGlzLmxpbmVhciA9IG5ldyBMaW5lYXIoY3JlYXRpdmVKVHJlZS5saW5lYXIpO1xuICB9XG5cbiAgaWYgKGNyZWF0aXZlSlRyZWUuY29tcGFuaW9uQWRzKSB7XG4gICAgdmFyIGNvbXBhbmlvbnMgPSBbXTtcbiAgICB2YXIgY29tcGFuaW9uQWRzID0gY3JlYXRpdmVKVHJlZS5jb21wYW5pb25BZHMgJiYgY3JlYXRpdmVKVHJlZS5jb21wYW5pb25BZHMuY29tcGFuaW9uO1xuICAgIGNvbXBhbmlvbkFkcyA9IHV0aWxpdGllcy5pc0FycmF5KGNvbXBhbmlvbkFkcykgPyBjb21wYW5pb25BZHMgOiBbY29tcGFuaW9uQWRzXTtcbiAgICBjb21wYW5pb25BZHMuZm9yRWFjaChmdW5jdGlvbiAoY29tcGFuaW9uRGF0YSkge1xuICAgICAgY29tcGFuaW9ucy5wdXNoKG5ldyBDb21wYW5pb24oY29tcGFuaW9uRGF0YSkpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5jb21wYW5pb25BZHMgPSBjb21wYW5pb25zO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQ3JlYXRpdmU7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdmFzdFV0aWwgPSByZXF1aXJlKCcuL3Zhc3RVdGlsJyk7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG52YXIgeG1sID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMveG1sJyk7XG5cbmZ1bmN0aW9uIEluTGluZShpbmxpbmVKVHJlZSkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgSW5MaW5lKSkge1xuICAgIHJldHVybiBuZXcgSW5MaW5lKGlubGluZUpUcmVlKTtcbiAgfVxuXG4gIC8vUmVxdWlyZWQgRmllbGRzXG4gIHRoaXMuYWRUaXRsZSA9IHhtbC5rZXlWYWx1ZShpbmxpbmVKVHJlZS5hZFRpdGxlKTtcbiAgdGhpcy5hZFN5c3RlbSA9IHhtbC5rZXlWYWx1ZShpbmxpbmVKVHJlZS5hZFN5c3RlbSk7XG4gIHRoaXMuaW1wcmVzc2lvbnMgPSB2YXN0VXRpbC5wYXJzZUltcHJlc3Npb25zKGlubGluZUpUcmVlLmltcHJlc3Npb24pO1xuICB0aGlzLmNyZWF0aXZlcyA9IHZhc3RVdGlsLnBhcnNlQ3JlYXRpdmVzKGlubGluZUpUcmVlLmNyZWF0aXZlcyk7XG5cbiAgLy9PcHRpb25hbCBGaWVsZHNcbiAgdGhpcy5kZXNjcmlwdGlvbiA9IHhtbC5rZXlWYWx1ZShpbmxpbmVKVHJlZS5kZXNjcmlwdGlvbik7XG4gIHRoaXMuYWR2ZXJ0aXNlciA9IHhtbC5rZXlWYWx1ZShpbmxpbmVKVHJlZS5hZHZlcnRpc2VyKTtcbiAgdGhpcy5zdXJ2ZXlzID0gcGFyc2VTdXJ2ZXlzKGlubGluZUpUcmVlLnN1cnZleSk7XG4gIHRoaXMuZXJyb3IgPSB4bWwua2V5VmFsdWUoaW5saW5lSlRyZWUuZXJyb3IpO1xuICB0aGlzLnByaWNpbmcgPSB4bWwua2V5VmFsdWUoaW5saW5lSlRyZWUucHJpY2luZyk7XG4gIHRoaXMuZXh0ZW5zaW9ucyA9IGlubGluZUpUcmVlLmV4dGVuc2lvbnM7XG5cbiAgLyoqKiBMb2NhbCBGdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBwYXJzZVN1cnZleXMoaW5saW5lU3VydmV5cykge1xuICAgIGlmIChpbmxpbmVTdXJ2ZXlzKSB7XG4gICAgICByZXR1cm4gdXRpbGl0aWVzLnRyYW5zZm9ybUFycmF5KHV0aWxpdGllcy5pc0FycmF5KGlubGluZVN1cnZleXMpID8gaW5saW5lU3VydmV5cyA6IFtpbmxpbmVTdXJ2ZXlzXSwgZnVuY3Rpb24gKHN1cnZleSkge1xuICAgICAgICBpZih1dGlsaXRpZXMuaXNOb3RFbXB0eVN0cmluZyhzdXJ2ZXkua2V5VmFsdWUpKXtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdXJpOiBzdXJ2ZXkua2V5VmFsdWUsXG4gICAgICAgICAgICB0eXBlOiBzdXJ2ZXkuYXR0cigndHlwZScpXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gSW5MaW5lOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIFRyYWNraW5nRXZlbnQgPSByZXF1aXJlKCcuL1RyYWNraW5nRXZlbnQnKTtcbnZhciBNZWRpYUZpbGUgPSByZXF1aXJlKCcuL01lZGlhRmlsZScpO1xudmFyIFZpZGVvQ2xpY2tzID0gcmVxdWlyZSgnLi9WaWRlb0NsaWNrcycpO1xuXG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucycpO1xudmFyIHBhcnNlcnMgPSByZXF1aXJlKCcuL3BhcnNlcnMnKTtcblxudmFyIHhtbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3htbCcpO1xuXG5cbmZ1bmN0aW9uIExpbmVhcihsaW5lYXJKVHJlZSkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgTGluZWFyKSkge1xuICAgIHJldHVybiBuZXcgTGluZWFyKGxpbmVhckpUcmVlKTtcbiAgfVxuXG4gIC8vUmVxdWlyZWQgRWxlbWVudHNcbiAgdGhpcy5kdXJhdGlvbiA9IHBhcnNlcnMuZHVyYXRpb24oeG1sLmtleVZhbHVlKGxpbmVhckpUcmVlLmR1cmF0aW9uKSk7XG4gIHRoaXMubWVkaWFGaWxlcyA9IHBhcnNlTWVkaWFGaWxlcyhsaW5lYXJKVHJlZS5tZWRpYUZpbGVzICYmIGxpbmVhckpUcmVlLm1lZGlhRmlsZXMubWVkaWFGaWxlKTtcblxuICAvL09wdGlvbmFsIGZpZWxkc1xuICB0aGlzLnRyYWNraW5nRXZlbnRzID0gcGFyc2VUcmFja2luZ0V2ZW50cyhsaW5lYXJKVHJlZS50cmFja2luZ0V2ZW50cyAmJiBsaW5lYXJKVHJlZS50cmFja2luZ0V2ZW50cy50cmFja2luZywgdGhpcy5kdXJhdGlvbik7XG4gIHRoaXMuc2tpcG9mZnNldCA9IHBhcnNlcnMub2Zmc2V0KHhtbC5hdHRyKGxpbmVhckpUcmVlLCAnc2tpcG9mZnNldCcpLCB0aGlzLmR1cmF0aW9uKTtcblxuICBpZiAobGluZWFySlRyZWUudmlkZW9DbGlja3MpIHtcbiAgICB0aGlzLnZpZGVvQ2xpY2tzID0gbmV3IFZpZGVvQ2xpY2tzKGxpbmVhckpUcmVlLnZpZGVvQ2xpY2tzKTtcbiAgfVxuXG4gIGlmKGxpbmVhckpUcmVlLmFkUGFyYW1ldGVycykge1xuICAgIHRoaXMuYWRQYXJhbWV0ZXJzID0geG1sLmtleVZhbHVlKGxpbmVhckpUcmVlLmFkUGFyYW1ldGVycyk7XG5cbiAgICBpZih4bWwuYXR0cihsaW5lYXJKVHJlZS5hZFBhcmFtZXRlcnMsICd4bWxFbmNvZGVkJykpe1xuICAgICAgdGhpcy5hZFBhcmFtZXRlcnMgPSB4bWwuZGVjb2RlKHRoaXMuYWRQYXJhbWV0ZXJzKTtcbiAgICB9XG4gIH1cblxuICAvKioqIExvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIHBhcnNlVHJhY2tpbmdFdmVudHModHJhY2tpbmdFdmVudHMsIGR1cmF0aW9uKSB7XG4gICAgdmFyIHRyYWNraW5ncyA9IFtdO1xuICAgIGlmICh1dGlsaXRpZXMuaXNEZWZpbmVkKHRyYWNraW5nRXZlbnRzKSkge1xuICAgICAgdHJhY2tpbmdFdmVudHMgPSB1dGlsaXRpZXMuaXNBcnJheSh0cmFja2luZ0V2ZW50cykgPyB0cmFja2luZ0V2ZW50cyA6IFt0cmFja2luZ0V2ZW50c107XG4gICAgICB0cmFja2luZ0V2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uICh0cmFja2luZ0RhdGEpIHtcbiAgICAgICAgdHJhY2tpbmdzLnB1c2gobmV3IFRyYWNraW5nRXZlbnQodHJhY2tpbmdEYXRhLCBkdXJhdGlvbikpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0cmFja2luZ3M7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZU1lZGlhRmlsZXMobWVkaWFGaWxlc0p4b25UcmVlKSB7XG4gICAgdmFyIG1lZGlhRmlsZXMgPSBbXTtcbiAgICBpZiAodXRpbGl0aWVzLmlzRGVmaW5lZChtZWRpYUZpbGVzSnhvblRyZWUpKSB7XG4gICAgICBtZWRpYUZpbGVzSnhvblRyZWUgPSB1dGlsaXRpZXMuaXNBcnJheShtZWRpYUZpbGVzSnhvblRyZWUpID8gbWVkaWFGaWxlc0p4b25UcmVlIDogW21lZGlhRmlsZXNKeG9uVHJlZV07XG5cbiAgICAgIG1lZGlhRmlsZXNKeG9uVHJlZS5mb3JFYWNoKGZ1bmN0aW9uIChtZkRhdGEpIHtcbiAgICAgICAgbWVkaWFGaWxlcy5wdXNoKG5ldyBNZWRpYUZpbGUobWZEYXRhKSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIG1lZGlhRmlsZXM7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBMaW5lYXI7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgeG1sID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMveG1sJyk7XG5cbnZhciBhdHRyaWJ1dGVzTGlzdCA9IFtcbiAgLy9SZXF1aXJlZCBhdHRyaWJ1dGVzXG4gICdkZWxpdmVyeScsXG4gICd0eXBlJyxcbiAgJ3dpZHRoJyxcbiAgJ2hlaWdodCcsXG4gIC8vT3B0aW9uYWwgYXR0cmlidXRlc1xuICAnY29kZWMnLFxuICAnaWQnLFxuICAnYml0cmF0ZScsXG4gICdtaW5CaXRyYXRlJyxcbiAgJ21heEJpdHJhdGUnLFxuICAnc2NhbGFibGUnLFxuICAnbWFpbnRhaW5Bc3BlY3RSYXRpbycsXG4gICdhcGlGcmFtZXdvcmsnXG5dO1xuXG5mdW5jdGlvbiBNZWRpYUZpbGUobWVkaWFGaWxlSlRyZWUpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIE1lZGlhRmlsZSkpIHtcbiAgICByZXR1cm4gbmV3IE1lZGlhRmlsZShtZWRpYUZpbGVKVHJlZSk7XG4gIH1cblxuICAvL1JlcXVpcmVkIGF0dHJpYnV0ZXNcbiAgdGhpcy5zcmMgPSB4bWwua2V5VmFsdWUobWVkaWFGaWxlSlRyZWUpO1xuXG4gIGZvcih2YXIgeD0wOyB4PGF0dHJpYnV0ZXNMaXN0Lmxlbmd0aDsgeCsrKSB7XG4gICAgdmFyIGF0dHJpYnV0ZSA9IGF0dHJpYnV0ZXNMaXN0W3hdO1xuICAgIHRoaXNbYXR0cmlidXRlXSA9IG1lZGlhRmlsZUpUcmVlLmF0dHIoYXR0cmlidXRlKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IE1lZGlhRmlsZTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBwYXJzZXJzID0gcmVxdWlyZSgnLi9wYXJzZXJzJyk7XG5cbnZhciB4bWwgPSByZXF1aXJlKCcuLi8uLi91dGlscy94bWwnKTtcblxuZnVuY3Rpb24gVHJhY2tpbmdFdmVudCh0cmFja2luZ0pUcmVlLCBkdXJhdGlvbikge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVHJhY2tpbmdFdmVudCkpIHtcbiAgICByZXR1cm4gbmV3IFRyYWNraW5nRXZlbnQodHJhY2tpbmdKVHJlZSwgZHVyYXRpb24pO1xuICB9XG5cbiAgdGhpcy5uYW1lID0gdHJhY2tpbmdKVHJlZS5hdHRyKCdldmVudCcpO1xuICB0aGlzLnVyaSA9IHhtbC5rZXlWYWx1ZSh0cmFja2luZ0pUcmVlKTtcblxuICBpZigncHJvZ3Jlc3MnID09PSB0aGlzLm5hbWUpIHtcbiAgICB0aGlzLm9mZnNldCA9IHBhcnNlcnMub2Zmc2V0KHRyYWNraW5nSlRyZWUuYXR0cignb2Zmc2V0JyksIGR1cmF0aW9uKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFRyYWNraW5nRXZlbnQ7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQWQgPSByZXF1aXJlKCcuL0FkJyk7XG52YXIgVkFTVEVycm9yID0gcmVxdWlyZSgnLi9WQVNURXJyb3InKTtcbnZhciBWQVNUUmVzcG9uc2UgPSByZXF1aXJlKCcuL1ZBU1RSZXNwb25zZScpO1xudmFyIHZhc3RVdGlsID0gcmVxdWlyZSgnLi92YXN0VXRpbCcpO1xuXG52YXIgYXN5bmMgPSByZXF1aXJlKCcuLi8uLi91dGlscy9hc3luYycpO1xudmFyIGh0dHAgPSByZXF1aXJlKCcuLi8uLi91dGlscy9odHRwJykuaHR0cDtcbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG52YXIgeG1sID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMveG1sJyk7XG5cbmZ1bmN0aW9uIFZBU1RDbGllbnQob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVkFTVENsaWVudCkpIHtcbiAgICByZXR1cm4gbmV3IFZBU1RDbGllbnQob3B0aW9ucyk7XG4gIH1cbiAgdmFyIGRlZmF1bHRPcHRpb25zID0ge1xuICAgIFdSQVBQRVJfTElNSVQ6IDVcbiAgfTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgdGhpcy5zZXR0aW5ncyA9IHV0aWxpdGllcy5leHRlbmQoe30sIG9wdGlvbnMsIGRlZmF1bHRPcHRpb25zKTtcbiAgdGhpcy5lcnJvclVSTE1hY3JvcyA9IFtdO1xufVxuXG5WQVNUQ2xpZW50LnByb3RvdHlwZS5nZXRWQVNUUmVzcG9uc2UgPSBmdW5jdGlvbiBnZXRWQVNUUmVzcG9uc2UoYWRUYWdVcmwsIGNhbGxiYWNrKSB7XG4gIHZhciB0aGF0ID0gdGhpcztcblxuICB2YXIgZXJyb3IgPSBzYW5pdHlDaGVjayhhZFRhZ1VybCwgY2FsbGJhY2spO1xuICBpZiAoZXJyb3IpIHtcbiAgICBpZiAodXRpbGl0aWVzLmlzRnVuY3Rpb24oY2FsbGJhY2spKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2soZXJyb3IpO1xuICAgIH1cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuXG4gIGFzeW5jLndhdGVyZmFsbChbXG4gICAgICB0aGlzLl9nZXRWQVNUQWQuYmluZCh0aGlzLCBhZFRhZ1VybCksXG4gICAgICBidWlsZFZBU1RSZXNwb25zZVxuICAgIF0sXG4gICAgY2FsbGJhY2spO1xuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gYnVpbGRWQVNUUmVzcG9uc2UoYWRzQ2hhaW4sIGNiKSB7XG4gICAgdHJ5IHtcbiAgICAgIHZhciByZXNwb25zZSA9IHRoYXQuX2J1aWxkVkFTVFJlc3BvbnNlKGFkc0NoYWluKTtcbiAgICAgIGNiKG51bGwsIHJlc3BvbnNlKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjYihlKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBzYW5pdHlDaGVjayhhZFRhZ1VybCwgY2IpIHtcbiAgICBpZiAoIWFkVGFnVXJsKSB7XG4gICAgICByZXR1cm4gbmV3IFZBU1RFcnJvcignb24gVkFTVENsaWVudC5nZXRWQVNUUmVzcG9uc2UsIG1pc3NpbmcgYWQgdGFnIFVSTCcpO1xuICAgIH1cblxuICAgIGlmICghdXRpbGl0aWVzLmlzRnVuY3Rpb24oY2IpKSB7XG4gICAgICByZXR1cm4gbmV3IFZBU1RFcnJvcignb24gVkFTVENsaWVudC5nZXRWQVNUUmVzcG9uc2UsIG1pc3NpbmcgY2FsbGJhY2sgZnVuY3Rpb24nKTtcbiAgICB9XG4gIH1cbn07XG5cblZBU1RDbGllbnQucHJvdG90eXBlLl9nZXRWQVNUQWQgPSBmdW5jdGlvbiAoYWRUYWdVcmwsIGNhbGxiYWNrKSB7XG4gIHZhciB0aGF0ID0gdGhpcztcblxuICBnZXRBZFdhdGVyZmFsbChhZFRhZ1VybCwgZnVuY3Rpb24gKGVycm9yLCB2YXN0VHJlZSkge1xuICAgIHZhciB3YXRlcmZhbGxBZHMgPSB2YXN0VHJlZSAmJiB1dGlsaXRpZXMuaXNBcnJheSh2YXN0VHJlZS5hZHMpID8gdmFzdFRyZWUuYWRzIDogbnVsbDtcbiAgICBpZiAoZXJyb3IpIHtcbiAgICAgIHRoYXQuX3RyYWNrRXJyb3IoZXJyb3IsIHdhdGVyZmFsbEFkcyk7XG4gICAgICByZXR1cm4gY2FsbGJhY2soZXJyb3IsIHdhdGVyZmFsbEFkcyk7XG4gICAgfVxuXG4gICAgZ2V0QWQod2F0ZXJmYWxsQWRzLnNoaWZ0KCksIFtdLCB3YXRlcmZhbGxIYW5kbGVyKTtcblxuICAgIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgICBmdW5jdGlvbiB3YXRlcmZhbGxIYW5kbGVyKGVycm9yLCBhZENoYWluKSB7XG4gICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgdGhhdC5fdHJhY2tFcnJvcihlcnJvciwgYWRDaGFpbik7XG4gICAgICAgIGlmICh3YXRlcmZhbGxBZHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGdldEFkKHdhdGVyZmFsbEFkcy5zaGlmdCgpLFtdLCB3YXRlcmZhbGxIYW5kbGVyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjYWxsYmFjayhlcnJvciwgYWRDaGFpbik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNhbGxiYWNrKG51bGwsIGFkQ2hhaW4pO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBnZXRBZFdhdGVyZmFsbChhZFRhZ1VybCwgY2FsbGJhY2spIHtcbiAgICB2YXIgcmVxdWVzdFZhc3RYTUwgPSB0aGF0Ll9yZXF1ZXN0VkFTVFhtbC5iaW5kKHRoYXQsIGFkVGFnVXJsKTtcbiAgICBhc3luYy53YXRlcmZhbGwoW1xuICAgICAgcmVxdWVzdFZhc3RYTUwsXG4gICAgICBidWlsZFZhc3RXYXRlcmZhbGxcbiAgICBdLCBjYWxsYmFjayk7XG4gIH1cblxuICBmdW5jdGlvbiBidWlsZFZhc3RXYXRlcmZhbGwoeG1sU3RyLCBjYWxsYmFjaykge1xuICAgIHZhciB2YXN0VHJlZTtcbiAgICB0cnkge1xuICAgICAgdmFzdFRyZWUgPSB4bWwudG9KWE9OVHJlZSh4bWxTdHIpO1xuXG4gICAgICBpZih1dGlsaXRpZXMuaXNBcnJheSh2YXN0VHJlZS5hZCkpIHtcbiAgICAgICAgdmFzdFRyZWUuYWRzID0gdmFzdFRyZWUuYWQ7XG4gICAgICB9IGVsc2UgaWYodmFzdFRyZWUuYWQpe1xuICAgICAgICB2YXN0VHJlZS5hZHMgPSBbdmFzdFRyZWUuYWRdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFzdFRyZWUuYWRzID0gW107XG4gICAgICB9XG4gICAgICBjYWxsYmFjayh2YWxpZGF0ZVZBU1RUcmVlKHZhc3RUcmVlKSwgdmFzdFRyZWUpO1xuXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY2FsbGJhY2sobmV3IFZBU1RFcnJvcihcIm9uIFZBU1RDbGllbnQuZ2V0VkFTVEFkLmJ1aWxkVmFzdFdhdGVyZmFsbCwgZXJyb3IgcGFyc2luZyB4bWxcIiwgMTAwKSwgbnVsbCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdmFsaWRhdGVWQVNUVHJlZSh2YXN0VHJlZSkge1xuICAgIHZhciB2YXN0VmVyc2lvbiA9IHhtbC5hdHRyKHZhc3RUcmVlLCAndmVyc2lvbicpO1xuXG4gICAgaWYgKCF2YXN0VHJlZS5hZCkge1xuICAgICAgcmV0dXJuIG5ldyBWQVNURXJyb3IoJ29uIFZBU1RDbGllbnQuZ2V0VkFTVEFkLnZhbGlkYXRlVkFTVFRyZWUsIG5vIEFkIGluIFZBU1QgdHJlZScsIDMwMyk7XG4gICAgfVxuXG4gICAgaWYgKHZhc3RWZXJzaW9uICYmICh2YXN0VmVyc2lvbiAhPSAzICYmIHZhc3RWZXJzaW9uICE9IDIpKSB7XG4gICAgICByZXR1cm4gbmV3IFZBU1RFcnJvcignb24gVkFTVENsaWVudC5nZXRWQVNUQWQudmFsaWRhdGVWQVNUVHJlZSwgbm90IHN1cHBvcnRlZCBWQVNUIHZlcnNpb24gXCInICsgdmFzdFZlcnNpb24gKyAnXCInLCAxMDIpO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0QWQoYWRUYWdVcmwsIGFkQ2hhaW4sIGNhbGxiYWNrKSB7XG4gICAgaWYgKGFkQ2hhaW4ubGVuZ3RoID49IHRoYXQuV1JBUFBFUl9MSU1JVCkge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBWQVNURXJyb3IoXCJvbiBWQVNUQ2xpZW50LmdldFZBU1RBZC5nZXRBZCwgcGxheWVycyB3cmFwcGVyIGxpbWl0IHJlYWNoZWQgKHRoZSBsaW1pdCBpcyBcIiArIHRoYXQuV1JBUFBFUl9MSU1JVCArIFwiKVwiLCAzMDIpLCBhZENoYWluKTtcbiAgICB9XG5cbiAgICBhc3luYy53YXRlcmZhbGwoW1xuICAgICAgZnVuY3Rpb24gKG5leHQpIHtcbiAgICAgICAgaWYgKHV0aWxpdGllcy5pc1N0cmluZyhhZFRhZ1VybCkpIHtcbiAgICAgICAgICByZXF1ZXN0VkFTVEFkKGFkVGFnVXJsLCBuZXh0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXh0KG51bGwsIGFkVGFnVXJsKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGJ1aWxkQWRcbiAgICBdLCBmdW5jdGlvbiAoZXJyb3IsIGFkKSB7XG4gICAgICBpZiAoYWQpIHtcbiAgICAgICAgYWRDaGFpbi5wdXNoKGFkKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnJvciwgYWRDaGFpbik7XG4gICAgICB9XG5cbiAgICAgIGlmIChhZC53cmFwcGVyKSB7XG4gICAgICAgIHJldHVybiBnZXRBZChhZC53cmFwcGVyLlZBU1RBZFRhZ1VSSSwgYWRDaGFpbiwgY2FsbGJhY2spO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgYWRDaGFpbik7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBidWlsZEFkKGFkSnhvblRyZWUsIGNhbGxiYWNrKSB7XG4gICAgdHJ5IHtcbiAgICAgIHZhciBhZCA9IG5ldyBBZChhZEp4b25UcmVlKTtcbiAgICAgIGNhbGxiYWNrKHZhbGlkYXRlQWQoYWQpLCBhZCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY2FsbGJhY2sobmV3IFZBU1RFcnJvcignb24gVkFTVENsaWVudC5nZXRWQVNUQWQuYnVpbGRBZCwgZXJyb3IgcGFyc2luZyB4bWwnLCAxMDApLCBudWxsKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB2YWxpZGF0ZUFkKGFkKSB7XG4gICAgdmFyIHdyYXBwZXIgPSBhZC53cmFwcGVyO1xuICAgIHZhciBpbkxpbmUgPSBhZC5pbkxpbmU7XG4gICAgdmFyIGVyck1zZ1ByZWZpeCA9ICdvbiBWQVNUQ2xpZW50LmdldFZBU1RBZC52YWxpZGF0ZUFkLCAnO1xuXG4gICAgaWYgKGluTGluZSAmJiB3cmFwcGVyKSB7XG4gICAgICByZXR1cm4gbmV3IFZBU1RFcnJvcihlcnJNc2dQcmVmaXggK1wiSW5MaW5lIGFuZCBXcmFwcGVyIGJvdGggZm91bmQgb24gdGhlIHNhbWUgQWRcIiwgMTAxKTtcbiAgICB9XG5cbiAgICBpZiAoIWluTGluZSAmJiAhd3JhcHBlcikge1xuICAgICAgcmV0dXJuIG5ldyBWQVNURXJyb3IoZXJyTXNnUHJlZml4ICsgXCJub3Igd3JhcHBlciBub3IgaW5saW5lIGVsZW1lbnRzIGZvdW5kIG9uIHRoZSBBZFwiLCAxMDEpO1xuICAgIH1cblxuICAgIGlmIChpbkxpbmUgJiYgaW5MaW5lLmNyZWF0aXZlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBuZXcgVkFTVEVycm9yKGVyck1zZ1ByZWZpeCArIFwibWlzc2luZyBjcmVhdGl2ZSBpbiBJbkxpbmUgZWxlbWVudFwiLCAxMDEpO1xuICAgIH1cblxuICAgIGlmICh3cmFwcGVyICYmICF3cmFwcGVyLlZBU1RBZFRhZ1VSSSkge1xuICAgICAgcmV0dXJuIG5ldyBWQVNURXJyb3IoZXJyTXNnUHJlZml4ICsgXCJtaXNzaW5nICdWQVNUQWRUYWdVUkknIGluIHdyYXBwZXJcIiwgMTAxKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZXF1ZXN0VkFTVEFkKGFkVGFnVXJsLCBjYWxsYmFjaykge1xuICAgIHRoYXQuX3JlcXVlc3RWQVNUWG1sKGFkVGFnVXJsLCBmdW5jdGlvbiAoZXJyb3IsIHhtbFN0cikge1xuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnJvcik7XG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICB2YXIgdmFzdFRyZWUgPSB4bWwudG9KWE9OVHJlZSh4bWxTdHIpO1xuICAgICAgICBjYWxsYmFjayh2YWxpZGF0ZVZBU1RUcmVlKHZhc3RUcmVlKSwgdmFzdFRyZWUuYWQpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWxsYmFjayhuZXcgVkFTVEVycm9yKFwib24gVkFTVENsaWVudC5nZXRWQVNUQWQucmVxdWVzdFZBU1RBZCwgZXJyb3IgcGFyc2luZyB4bWxcIiwgMTAwKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn07XG5cblZBU1RDbGllbnQucHJvdG90eXBlLl9yZXF1ZXN0VkFTVFhtbCA9IGZ1bmN0aW9uIHJlcXVlc3RWQVNUWG1sKGFkVGFnVXJsLCBjYWxsYmFjaykge1xuICB0cnkge1xuICAgIGlmICh1dGlsaXRpZXMuaXNGdW5jdGlvbihhZFRhZ1VybCkpIHtcbiAgICAgIGFkVGFnVXJsKHJlcXVlc3RIYW5kbGVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaHR0cC5nZXQoYWRUYWdVcmwsIHJlcXVlc3RIYW5kbGVyLCB7XG4gICAgICAgIHdpdGhDcmVkZW50aWFsczogdHJ1ZVxuICAgICAgfSk7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgY2FsbGJhY2soZSk7XG4gIH1cblxuICAvKioqIExvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIHJlcXVlc3RIYW5kbGVyKGVycm9yLCByZXNwb25zZSwgc3RhdHVzKSB7XG4gICAgaWYgKGVycm9yKSB7XG4gICAgICB2YXIgZXJyTXNnID0gdXRpbGl0aWVzLmlzRGVmaW5lZChzdGF0dXMpID9cbiAgICAgIFwib24gVkFTVENsaWVudC5yZXF1ZXN0VmFzdFhNTCwgSFRUUCByZXF1ZXN0IGVycm9yIHdpdGggc3RhdHVzICdcIiArIHN0YXR1cyArIFwiJ1wiIDpcbiAgICAgICAgXCJvbiBWQVNUQ2xpZW50LnJlcXVlc3RWYXN0WE1MLCBFcnJvciBnZXR0aW5nIHRoZSB0aGUgVkFTVCBYTUwgd2l0aCBoZSBwYXNzZWQgYWRUYWdYTUwgZm5cIjtcbiAgICAgIHJldHVybiBjYWxsYmFjayhuZXcgVkFTVEVycm9yKGVyck1zZywgMzAxKSwgbnVsbCk7XG4gICAgfVxuXG4gICAgY2FsbGJhY2sobnVsbCwgcmVzcG9uc2UpO1xuICB9XG59O1xuXG5WQVNUQ2xpZW50LnByb3RvdHlwZS5fYnVpbGRWQVNUUmVzcG9uc2UgPSBmdW5jdGlvbiBidWlsZFZBU1RSZXNwb25zZShhZHNDaGFpbikge1xuICB2YXIgcmVzcG9uc2UgPSBuZXcgVkFTVFJlc3BvbnNlKCk7XG4gIGFkZEFkc1RvUmVzcG9uc2UocmVzcG9uc2UsIGFkc0NoYWluKTtcbiAgdmFsaWRhdGVSZXNwb25zZShyZXNwb25zZSk7XG5cbiAgcmV0dXJuIHJlc3BvbnNlO1xuXG4gIC8vKioqIExvY2FsIGZ1bmN0aW9uICoqKipcbiAgZnVuY3Rpb24gYWRkQWRzVG9SZXNwb25zZShyZXNwb25zZSwgYWRzKSB7XG4gICAgYWRzLmZvckVhY2goZnVuY3Rpb24gKGFkKSB7XG4gICAgICByZXNwb25zZS5hZGRBZChhZCk7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiB2YWxpZGF0ZVJlc3BvbnNlKHJlc3BvbnNlKSB7XG4gICAgdmFyIHByb2dyZXNzRXZlbnRzID0gcmVzcG9uc2UudHJhY2tpbmdFdmVudHMucHJvZ3Jlc3M7XG5cbiAgICBpZiAoIXJlc3BvbnNlLmhhc0xpbmVhcigpKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFwib24gVkFTVENsaWVudC5fYnVpbGRWQVNUUmVzcG9uc2UsIFJlY2VpdmVkIGFuIEFkIHR5cGUgdGhhdCBpcyBub3Qgc3VwcG9ydGVkXCIsIDIwMCk7XG4gICAgfVxuXG4gICAgaWYgKHJlc3BvbnNlLmR1cmF0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoXCJvbiBWQVNUQ2xpZW50Ll9idWlsZFZBU1RSZXNwb25zZSwgTWlzc2luZyBkdXJhdGlvbiBmaWVsZCBpbiBWQVNUIHJlc3BvbnNlXCIsIDEwMSk7XG4gICAgfVxuXG4gICAgaWYgKHByb2dyZXNzRXZlbnRzKSB7XG4gICAgICBwcm9ncmVzc0V2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChwcm9ncmVzc0V2ZW50KSB7XG4gICAgICAgIGlmICghdXRpbGl0aWVzLmlzTnVtYmVyKHByb2dyZXNzRXZlbnQub2Zmc2V0KSkge1xuICAgICAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoXCJvbiBWQVNUQ2xpZW50Ll9idWlsZFZBU1RSZXNwb25zZSwgbWlzc2luZyBvciB3cm9uZyBvZmZzZXQgYXR0cmlidXRlIG9uIHByb2dyZXNzIHRyYWNraW5nIGV2ZW50XCIsIDEwMSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufTtcblxuVkFTVENsaWVudC5wcm90b3R5cGUuX3RyYWNrRXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IsIGFkQ2hhaW4pIHtcbiAgaWYgKCF1dGlsaXRpZXMuaXNBcnJheShhZENoYWluKSB8fCBhZENoYWluLmxlbmd0aCA9PT0gMCkgeyAvL1RoZXJlIGlzIG5vdGhpbmcgdG8gdHJhY2tcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgZXJyb3JVUkxNYWNyb3MgPSBbXTtcbiAgYWRDaGFpbi5mb3JFYWNoKGFkZEVycm9yVXJsTWFjcm9zKTtcbiAgdmFzdFV0aWwudHJhY2soZXJyb3JVUkxNYWNyb3MsIHtFUlJPUkNPREU6IGVycm9yLmNvZGUgfHwgOTAwfSk7ICAvLzkwMCA8PT0gVW5kZWZpbmVkIGVycm9yXG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgICoqKi9cbiAgZnVuY3Rpb24gYWRkRXJyb3JVcmxNYWNyb3MoYWQpIHtcbiAgICBpZiAoYWQud3JhcHBlciAmJiBhZC53cmFwcGVyLmVycm9yKSB7XG4gICAgICBlcnJvclVSTE1hY3Jvcy5wdXNoKGFkLndyYXBwZXIuZXJyb3IpO1xuICAgIH1cblxuICAgIGlmIChhZC5pbkxpbmUgJiYgYWQuaW5MaW5lLmVycm9yKSB7XG4gICAgICBlcnJvclVSTE1hY3Jvcy5wdXNoKGFkLmluTGluZS5lcnJvcik7XG4gICAgfVxuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZBU1RDbGllbnQ7XG4iLCIndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIFZBU1RFcnJvcihtZXNzYWdlLCBjb2RlKSB7XG4gIHRoaXMubWVzc2FnZSA9ICdWQVNUIEVycm9yOiAnICsgKG1lc3NhZ2UgfHwgJycpO1xuICBpZiAoY29kZSkge1xuICAgIHRoaXMuY29kZSA9IGNvZGU7XG4gIH1cbn1cblxuVkFTVEVycm9yLnByb3RvdHlwZSA9IG5ldyBFcnJvcigpO1xuVkFTVEVycm9yLnByb3RvdHlwZS5uYW1lID0gXCJWQVNUIEVycm9yXCI7XG5cbm1vZHVsZS5leHBvcnRzID0gVkFTVEVycm9yOyIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBJbm5lciBoZWxwZXIgY2xhc3MgdGhhdCBkZWFscyB3aXRoIHRoZSBsb2dpYyBvZiB0aGUgaW5kaXZpZHVhbCBzdGVwcyBuZWVkZWQgdG8gc2V0dXAgYW4gYWQgaW4gdGhlIHBsYXllci5cbiAqXG4gKiBAcGFyYW0gcGxheWVyIHtvYmplY3R9IGluc3RhbmNlIG9mIHRoZSBwbGF5ZXIgdGhhdCB3aWxsIHBsYXkgdGhlIGFkLiBJdCBhc3N1bWVzIHRoYXQgdGhlIHZpZGVvanMtY29udHJpYi1hZHMgcGx1Z2luXG4gKiAgICAgICAgICAgICAgICAgICAgICAgIGhhcyBiZWVuIGluaXRpYWxpemVkIHdoZW4geW91IHVzZSBpdHMgdXRpbGl0eSBmdW5jdGlvbnMuXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cblxudmFyIFZBU1RSZXNwb25zZSA9IHJlcXVpcmUoJy4vVkFTVFJlc3BvbnNlJyk7XG52YXIgVkFTVEVycm9yID0gcmVxdWlyZSgnLi9WQVNURXJyb3InKTtcbnZhciBWQVNUVHJhY2tlciA9IHJlcXVpcmUoJy4vVkFTVFRyYWNrZXInKTtcbnZhciB2YXN0VXRpbCA9IHJlcXVpcmUoJy4vdmFzdFV0aWwnKTtcblxudmFyIGFzeW5jID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvYXN5bmMnKTtcbnZhciBkb20gPSByZXF1aXJlKCcuLi8uLi91dGlscy9kb20nKTtcbnZhciBwbGF5ZXJVdGlscyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3BsYXllclV0aWxzJyk7XG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucycpO1xuXG5mdW5jdGlvbiBWQVNUSW50ZWdyYXRvcihwbGF5ZXIpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFZBU1RJbnRlZ3JhdG9yKSkge1xuICAgIHJldHVybiBuZXcgVkFTVEludGVncmF0b3IocGxheWVyKTtcbiAgfVxuXG4gIHRoaXMucGxheWVyID0gcGxheWVyO1xufVxuXG5WQVNUSW50ZWdyYXRvci5wcm90b3R5cGUucGxheUFkID0gZnVuY3Rpb24gcGxheUFkKHZhc3RSZXNwb25zZSwgY2FsbGJhY2spIHtcbiAgdmFyIHRoYXQgPSB0aGlzO1xuICBjYWxsYmFjayA9IGNhbGxiYWNrIHx8IHV0aWxpdGllcy5ub29wO1xuXG4gIGlmICghKHZhc3RSZXNwb25zZSBpbnN0YW5jZW9mIFZBU1RSZXNwb25zZSkpIHtcbiAgICByZXR1cm4gY2FsbGJhY2sobmV3IFZBU1RFcnJvcignT24gVkFTVEludGVncmF0b3IsIG1pc3NpbmcgcmVxdWlyZWQgVkFTVFJlc3BvbnNlJykpO1xuICB9XG5cbiAgYXN5bmMud2F0ZXJmYWxsKFtcbiAgICBmdW5jdGlvbiAobmV4dCkge1xuICAgICAgbmV4dChudWxsLCB2YXN0UmVzcG9uc2UpO1xuICAgIH0sXG4gICAgdGhpcy5fc2VsZWN0QWRTb3VyY2UuYmluZCh0aGlzKSxcbiAgICB0aGlzLl9jcmVhdGVWQVNUVHJhY2tlci5iaW5kKHRoaXMpLFxuICAgIHRoaXMuX2FkZENsaWNrVGhyb3VnaC5iaW5kKHRoaXMpLFxuICAgIHRoaXMuX2FkZFNraXBCdXR0b24uYmluZCh0aGlzKSxcbiAgICB0aGlzLl9zZXR1cEV2ZW50cy5iaW5kKHRoaXMpLFxuICAgIHRoaXMuX3BsYXlTZWxlY3RlZEFkLmJpbmQodGhpcylcbiAgXSwgZnVuY3Rpb24gKGVycm9yLCByZXNwb25zZSkge1xuICAgIGlmIChlcnJvciAmJiByZXNwb25zZSkge1xuICAgICAgdGhhdC5fdHJhY2tFcnJvcihlcnJvciwgcmVzcG9uc2UpO1xuICAgIH1cbiAgICBjYWxsYmFjayhlcnJvciwgcmVzcG9uc2UpO1xuICB9KTtcblxuICB0aGlzLl9hZFVuaXQgPSB7XG4gICAgX3NyYzogbnVsbCxcbiAgICB0eXBlOiAnVkFTVCcsXG4gICAgcGF1c2VBZDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhhdC5wbGF5ZXIucGF1c2UodHJ1ZSk7XG4gICAgfSxcblxuICAgIHJlc3VtZUFkOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGF0LnBsYXllci5wbGF5KHRydWUpO1xuICAgIH0sXG5cbiAgICBpc1BhdXNlZDogZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIHRoYXQucGxheWVyLnBhdXNlZCh0cnVlKTtcbiAgICB9LFxuXG4gICAgZ2V0U3JjOiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fc3JjO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gdGhpcy5fYWRVbml0O1xufTtcblxuVkFTVEludGVncmF0b3IucHJvdG90eXBlLl9zZWxlY3RBZFNvdXJjZSA9IGZ1bmN0aW9uIHNlbGVjdEFkU291cmNlKHJlc3BvbnNlLCBjYWxsYmFjaykge1xuICB2YXIgc291cmNlO1xuXG4gIHZhciBwbGF5ZXJXaWR0aCA9IGRvbS5nZXREaW1lbnNpb24odGhpcy5wbGF5ZXIuZWwoKSkud2lkdGg7XG4gIHJlc3BvbnNlLm1lZGlhRmlsZXMuc29ydChmdW5jdGlvbiBjb21wYXJlVG8oYSwgYikge1xuICAgIHZhciBkZWx0YUEgPSBNYXRoLmFicyhwbGF5ZXJXaWR0aCAtIGEud2lkdGgpO1xuICAgIHZhciBkZWx0YUIgPSBNYXRoLmFicyhwbGF5ZXJXaWR0aCAtIGIud2lkdGgpO1xuICAgIHJldHVybiBkZWx0YUEgLSBkZWx0YUI7XG4gIH0pO1xuXG4gIHNvdXJjZSA9IHRoaXMucGxheWVyLnNlbGVjdFNvdXJjZShyZXNwb25zZS5tZWRpYUZpbGVzKS5zb3VyY2U7XG5cbiAgaWYgKHNvdXJjZSkge1xuICAgIGlmICh0aGlzLl9hZFVuaXQpIHtcbiAgICAgIHRoaXMuX2FkVW5pdC5fc3JjID0gc291cmNlO1xuICAgIH1cbiAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgc291cmNlLCByZXNwb25zZSk7XG4gIH1cblxuICAvLyBjb2RlIDQwMyA8PT0gQ291bGRuJ3QgZmluZCBNZWRpYUZpbGUgdGhhdCBpcyBzdXBwb3J0ZWQgYnkgdGhpcyB2aWRlbyBwbGF5ZXJcbiAgY2FsbGJhY2sobmV3IFZBU1RFcnJvcihcIkNvdWxkIG5vdCBmaW5kIEFkIG1lZGlhZmlsZSBzdXBwb3J0ZWQgYnkgdGhpcyBwbGF5ZXJcIiwgNDAzKSwgcmVzcG9uc2UpO1xufTtcblxuVkFTVEludGVncmF0b3IucHJvdG90eXBlLl9jcmVhdGVWQVNUVHJhY2tlciA9IGZ1bmN0aW9uIGNyZWF0ZVZBU1RUcmFja2VyKGFkTWVkaWFGaWxlLCByZXNwb25zZSwgY2FsbGJhY2spIHtcbiAgdHJ5IHtcbiAgICBjYWxsYmFjayhudWxsLCBhZE1lZGlhRmlsZSwgbmV3IFZBU1RUcmFja2VyKGFkTWVkaWFGaWxlLnNyYywgcmVzcG9uc2UpLCByZXNwb25zZSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjYWxsYmFjayhlLCByZXNwb25zZSk7XG4gIH1cbn07XG5cblZBU1RJbnRlZ3JhdG9yLnByb3RvdHlwZS5fc2V0dXBFdmVudHMgPSBmdW5jdGlvbiBzZXR1cEV2ZW50cyhhZE1lZGlhRmlsZSwgdHJhY2tlciwgcmVzcG9uc2UsIGNhbGxiYWNrKSB7XG4gIHZhciBwcmV2aW91c2x5TXV0ZWQ7XG4gIHZhciBwbGF5ZXIgPSB0aGlzLnBsYXllcjtcbiAgcGxheWVyLm9uKCdmdWxsc2NyZWVuY2hhbmdlJywgdHJhY2tGdWxsc2NyZWVuQ2hhbmdlKTtcbiAgcGxheWVyLm9uKCd2YXN0LmFkU3RhcnQnLCB0cmFja0ltcHJlc3Npb25zKTtcbiAgcGxheWVyLm9uKCdwYXVzZScsIHRyYWNrUGF1c2UpO1xuICBwbGF5ZXIub24oJ3RpbWV1cGRhdGUnLCB0cmFja1Byb2dyZXNzKTtcbiAgcGxheWVyLm9uKCd2b2x1bWVjaGFuZ2UnLCB0cmFja1ZvbHVtZUNoYW5nZSk7XG5cbiAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsndmFzdC5hZEVuZCcsICd2YXN0LmFkc0NhbmNlbCddLCB1bmJpbmRFdmVudHMpO1xuICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWyd2YXN0LmFkRW5kJywgJ3Zhc3QuYWRzQ2FuY2VsJywgJ3Zhc3QuYWRTa2lwJ10sIGZ1bmN0aW9uKGV2dCl7XG4gICAgaWYoZXZ0LnR5cGUgPT09ICd2YXN0LmFkRW5kJyl7XG4gICAgICB0cmFja2VyLnRyYWNrQ29tcGxldGUoKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBjYWxsYmFjayhudWxsLCBhZE1lZGlhRmlsZSwgcmVzcG9uc2UpO1xuXG4gIC8qKiogTG9jYWwgRnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gdW5iaW5kRXZlbnRzKCkge1xuICAgIHBsYXllci5vZmYoJ2Z1bGxzY3JlZW5jaGFuZ2UnLCB0cmFja0Z1bGxzY3JlZW5DaGFuZ2UpO1xuICAgIHBsYXllci5vZmYoJ3Zhc3QuYWRTdGFydCcsIHRyYWNrSW1wcmVzc2lvbnMpO1xuICAgIHBsYXllci5vZmYoJ3BhdXNlJywgdHJhY2tQYXVzZSk7XG4gICAgcGxheWVyLm9mZigndGltZXVwZGF0ZScsIHRyYWNrUHJvZ3Jlc3MpO1xuICAgIHBsYXllci5vZmYoJ3ZvbHVtZWNoYW5nZScsIHRyYWNrVm9sdW1lQ2hhbmdlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYWNrRnVsbHNjcmVlbkNoYW5nZSgpIHtcbiAgICBpZiAocGxheWVyLmlzRnVsbHNjcmVlbigpKSB7XG4gICAgICB0cmFja2VyLnRyYWNrRnVsbHNjcmVlbigpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0cmFja2VyLnRyYWNrRXhpdEZ1bGxzY3JlZW4oKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB0cmFja1BhdXNlKCkge1xuICAgIC8vTk9URTogd2hlbmV2ZXIgYSB2aWRlbyBlbmRzIHRoZSB2aWRlbyBFbGVtZW50IHRyaWdnZXJzIGEgJ3BhdXNlJyBldmVudCBiZWZvcmUgdGhlICdlbmRlZCcgZXZlbnQuXG4gICAgLy8gICAgICBXZSBzaG91bGQgbm90IHRyYWNrIHRoaXMgcGF1c2UgZXZlbnQgYmVjYXVzZSBpdCBtYWtlcyB0aGUgVkFTVCB0cmFja2luZyBjb25mdXNpbmcgYWdhaW4gd2UgdXNlIGFcbiAgICAvLyAgICAgIFRocmVzaG9sZCBvZiAyIHNlY29uZHMgdG8gcHJldmVudCBmYWxzZSBwb3NpdGl2ZXMgb24gSU9TLlxuICAgIGlmIChNYXRoLmFicyhwbGF5ZXIuZHVyYXRpb24oKSAtIHBsYXllci5jdXJyZW50VGltZSgpKSA8IDIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cmFja2VyLnRyYWNrUGF1c2UoKTtcbiAgICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWydwbGF5JywgJ3Zhc3QuYWRFbmQnLCAndmFzdC5hZHNDYW5jZWwnXSwgZnVuY3Rpb24gKGV2dCkge1xuICAgICAgaWYoZXZ0LnR5cGUgPT09ICdwbGF5Jyl7XG4gICAgICAgIHRyYWNrZXIudHJhY2tSZXN1bWUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYWNrUHJvZ3Jlc3MoKSB7XG4gICAgdmFyIGN1cnJlbnRUaW1lSW5NcyA9IHBsYXllci5jdXJyZW50VGltZSgpICogMTAwMDtcbiAgICB0cmFja2VyLnRyYWNrUHJvZ3Jlc3MoY3VycmVudFRpbWVJbk1zKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYWNrSW1wcmVzc2lvbnMoKSB7XG4gICAgdHJhY2tlci50cmFja0ltcHJlc3Npb25zKCk7XG4gICAgdHJhY2tlci50cmFja0NyZWF0aXZlVmlldygpO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJhY2tWb2x1bWVDaGFuZ2UoKSB7XG4gICAgdmFyIG11dGVkID0gcGxheWVyLm11dGVkKCk7XG4gICAgaWYgKG11dGVkKSB7XG4gICAgICB0cmFja2VyLnRyYWNrTXV0ZSgpO1xuICAgIH0gZWxzZSBpZiAocHJldmlvdXNseU11dGVkKSB7XG4gICAgICB0cmFja2VyLnRyYWNrVW5tdXRlKCk7XG4gICAgfVxuICAgIHByZXZpb3VzbHlNdXRlZCA9IG11dGVkO1xuICB9XG59O1xuXG5WQVNUSW50ZWdyYXRvci5wcm90b3R5cGUuX2FkZFNraXBCdXR0b24gPSBmdW5jdGlvbiBhZGRTa2lwQnV0dG9uKHNvdXJjZSwgdHJhY2tlciwgcmVzcG9uc2UsIGNhbGxiYWNrKSB7XG4gIHZhciBza2lwT2Zmc2V0SW5TZWM7XG4gIHZhciB0aGF0ID0gdGhpcztcblxuICBpZiAodXRpbGl0aWVzLmlzTnVtYmVyKHJlc3BvbnNlLnNraXBvZmZzZXQpKSB7XG4gICAgc2tpcE9mZnNldEluU2VjID0gcmVzcG9uc2Uuc2tpcG9mZnNldCAvIDEwMDA7XG4gICAgYWRkU2tpcEJ1dHRvblRvUGxheWVyKHRoaXMucGxheWVyLCBza2lwT2Zmc2V0SW5TZWMpO1xuICB9XG4gIGNhbGxiYWNrKG51bGwsIHNvdXJjZSwgdHJhY2tlciwgcmVzcG9uc2UpO1xuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb24gKioqL1xuICBmdW5jdGlvbiBhZGRTa2lwQnV0dG9uVG9QbGF5ZXIocGxheWVyLCBza2lwT2Zmc2V0KSB7XG4gICAgdmFyIHNraXBCdXR0b24gPSBjcmVhdGVTa2lwQnV0dG9uKHBsYXllcik7XG4gICAgdmFyIHVwZGF0ZVNraXBCdXR0b24gPSB1cGRhdGVTa2lwQnV0dG9uU3RhdGUuYmluZCh0aGF0LCBza2lwQnV0dG9uLCBza2lwT2Zmc2V0LCBwbGF5ZXIpO1xuXG4gICAgcGxheWVyLmVsKCkuYXBwZW5kQ2hpbGQoc2tpcEJ1dHRvbik7XG4gICAgcGxheWVyLm9uKCd0aW1ldXBkYXRlJywgdXBkYXRlU2tpcEJ1dHRvbik7XG5cbiAgICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWyd2YXN0LmFkRW5kJywgJ3Zhc3QuYWRzQ2FuY2VsJ10sIHJlbW92ZVNraXBCdXR0b24pO1xuXG4gICAgZnVuY3Rpb24gcmVtb3ZlU2tpcEJ1dHRvbigpIHtcbiAgICAgIHBsYXllci5vZmYoJ3RpbWV1cGRhdGUnLCB1cGRhdGVTa2lwQnV0dG9uKTtcbiAgICAgIGRvbS5yZW1vdmUoc2tpcEJ1dHRvbik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlU2tpcEJ1dHRvbihwbGF5ZXIpIHtcbiAgICB2YXIgc2tpcEJ1dHRvbiA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgIGRvbS5hZGRDbGFzcyhza2lwQnV0dG9uLCBcInZhc3Qtc2tpcC1idXR0b25cIik7XG5cbiAgICBza2lwQnV0dG9uLm9uY2xpY2sgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgaWYgKGRvbS5oYXNDbGFzcyhza2lwQnV0dG9uLCAnZW5hYmxlZCcpKSB7XG4gICAgICAgIHRyYWNrZXIudHJhY2tTa2lwKCk7XG4gICAgICAgIHBsYXllci50cmlnZ2VyKCd2YXN0LmFkU2tpcCcpO1xuICAgICAgfVxuXG4gICAgICAvL1dlIHByZXZlbnQgZXZlbnQgcHJvcGFnYXRpb24gdG8gYXZvaWQgcHJvYmxlbXMgd2l0aCB0aGUgY2xpY2tUaHJvdWdoIGFuZCBzbyBvblxuICAgICAgaWYgKHdpbmRvdy5FdmVudC5wcm90b3R5cGUuc3RvcFByb3BhZ2F0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIHNraXBCdXR0b247XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVTa2lwQnV0dG9uU3RhdGUoc2tpcEJ1dHRvbiwgc2tpcE9mZnNldCwgcGxheWVyKSB7XG4gICAgdmFyIHRpbWVMZWZ0ID0gTWF0aC5jZWlsKHNraXBPZmZzZXQgLSBwbGF5ZXIuY3VycmVudFRpbWUoKSk7XG4gICAgaWYgKHRpbWVMZWZ0ID4gMCkge1xuICAgICAgc2tpcEJ1dHRvbi5pbm5lckhUTUwgPSBcIlNraXAgaW4gXCIgKyB1dGlsaXRpZXMudG9GaXhlZERpZ2l0cyh0aW1lTGVmdCwgMikgKyBcIi4uLlwiO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIWRvbS5oYXNDbGFzcyhza2lwQnV0dG9uLCAnZW5hYmxlZCcpKSB7XG4gICAgICAgIGRvbS5hZGRDbGFzcyhza2lwQnV0dG9uLCAnZW5hYmxlZCcpO1xuICAgICAgICBza2lwQnV0dG9uLmlubmVySFRNTCA9IFwiU2tpcCBhZFwiO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuVkFTVEludGVncmF0b3IucHJvdG90eXBlLl9hZGRDbGlja1Rocm91Z2ggPSBmdW5jdGlvbiBhZGRDbGlja1Rocm91Z2gobWVkaWFGaWxlLCB0cmFja2VyLCByZXNwb25zZSwgY2FsbGJhY2spIHtcbiAgdmFyIHBsYXllciA9IHRoaXMucGxheWVyO1xuICB2YXIgYmxvY2tlciA9IGNyZWF0ZUNsaWNrVGhyb3VnaEJsb2NrZXIocGxheWVyLCB0cmFja2VyLCByZXNwb25zZSk7XG4gIHZhciB1cGRhdGVCbG9ja2VyID0gdXBkYXRlQmxvY2tlclVSTC5iaW5kKHRoaXMsIGJsb2NrZXIsIHJlc3BvbnNlLCBwbGF5ZXIpO1xuXG4gIHBsYXllci5lbCgpLmluc2VydEJlZm9yZShibG9ja2VyLCBwbGF5ZXIuY29udHJvbEJhci5lbCgpKTtcbiAgcGxheWVyLm9uKCd0aW1ldXBkYXRlJywgdXBkYXRlQmxvY2tlcik7XG4gIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3Zhc3QuYWRFbmQnLCAndmFzdC5hZHNDYW5jZWwnXSwgcmVtb3ZlQmxvY2tlcik7XG5cbiAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIG1lZGlhRmlsZSwgdHJhY2tlciwgcmVzcG9uc2UpO1xuXG4gIC8qKiogTG9jYWwgRnVuY3Rpb25zICoqKi9cblxuICBmdW5jdGlvbiBjcmVhdGVDbGlja1Rocm91Z2hCbG9ja2VyKHBsYXllciwgdHJhY2tlciwgcmVzcG9uc2UpIHtcbiAgICB2YXIgYmxvY2tlciA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYVwiKTtcbiAgICB2YXIgY2xpY2tUaHJvdWdoTWFjcm8gPSByZXNwb25zZS5jbGlja1Rocm91Z2g7XG5cbiAgICBkb20uYWRkQ2xhc3MoYmxvY2tlciwgJ3Zhc3QtYmxvY2tlcicpO1xuICAgIGJsb2NrZXIuaHJlZiA9IGdlbmVyYXRlQ2xpY2tUaHJvdWdoVVJMKGNsaWNrVGhyb3VnaE1hY3JvLCBwbGF5ZXIpO1xuXG4gICAgaWYgKHV0aWxpdGllcy5pc1N0cmluZyhjbGlja1Rocm91Z2hNYWNybykpIHtcbiAgICAgIGJsb2NrZXIudGFyZ2V0ID0gXCJfYmxhbmtcIjtcbiAgICB9XG5cbiAgICBibG9ja2VyLm9uY2xpY2sgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgaWYgKHBsYXllci5wYXVzZWQoKSkge1xuICAgICAgICBwbGF5ZXIucGxheSgpO1xuXG4gICAgICAgIC8vV2UgcHJldmVudCBldmVudCBwcm9wYWdhdGlvbiB0byBhdm9pZCBwcm9ibGVtcyB3aXRoIHRoZSBwbGF5ZXIncyBub3JtYWwgcGF1c2UgbWVjaGFuaXNtXG4gICAgICAgIGlmICh3aW5kb3cuRXZlbnQucHJvdG90eXBlLnN0b3BQcm9wYWdhdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHBsYXllci5wYXVzZSgpO1xuICAgICAgdHJhY2tlci50cmFja0NsaWNrKCk7XG4gICAgfTtcblxuICAgIHJldHVybiBibG9ja2VyO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlQmxvY2tlclVSTChibG9ja2VyLCByZXNwb25zZSwgcGxheWVyKSB7XG4gICAgYmxvY2tlci5ocmVmID0gZ2VuZXJhdGVDbGlja1Rocm91Z2hVUkwocmVzcG9uc2UuY2xpY2tUaHJvdWdoLCBwbGF5ZXIpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2VuZXJhdGVDbGlja1Rocm91Z2hVUkwoY2xpY2tUaHJvdWdoTWFjcm8sIHBsYXllcikge1xuICAgIHZhciB2YXJpYWJsZXMgPSB7XG4gICAgICBBU1NFVFVSSTogbWVkaWFGaWxlLnNyYyxcbiAgICAgIENPTlRFTlRQTEFZSEVBRDogdmFzdFV0aWwuZm9ybWF0UHJvZ3Jlc3MocGxheWVyLmN1cnJlbnRUaW1lKCkgKiAxMDAwKVxuICAgIH07XG5cbiAgICByZXR1cm4gY2xpY2tUaHJvdWdoTWFjcm8gPyB2YXN0VXRpbC5wYXJzZVVSTE1hY3JvKGNsaWNrVGhyb3VnaE1hY3JvLCB2YXJpYWJsZXMpIDogJyMnO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVtb3ZlQmxvY2tlcigpIHtcbiAgICBwbGF5ZXIub2ZmKCd0aW1ldXBkYXRlJywgdXBkYXRlQmxvY2tlcik7XG4gICAgZG9tLnJlbW92ZShibG9ja2VyKTtcbiAgfVxufTtcblxuVkFTVEludGVncmF0b3IucHJvdG90eXBlLl9wbGF5U2VsZWN0ZWRBZCA9IGZ1bmN0aW9uIHBsYXlTZWxlY3RlZEFkKHNvdXJjZSwgcmVzcG9uc2UsIGNhbGxiYWNrKSB7XG4gIHZhciBwbGF5ZXIgPSB0aGlzLnBsYXllcjtcblxuICBwbGF5ZXIucHJlbG9hZChcImF1dG9cIik7IC8vd2l0aG91dCBwcmVsb2FkPWF1dG8gdGhlIGR1cmF0aW9uY2hhbmdlIGV2ZW50IGlzIG5ldmVyIGZpcmVkXG4gIHBsYXllci5zcmMoc291cmNlKTtcblxuICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWydkdXJhdGlvbmNoYW5nZScsICdlcnJvcicsICd2YXN0LmFkc0NhbmNlbCddLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgaWYgKGV2dC50eXBlID09PSAnZHVyYXRpb25jaGFuZ2UnKSB7XG4gICAgICBwbGF5QWQoKTtcbiAgICB9IGVsc2UgaWYoZXZ0LnR5cGUgPT09ICdlcnJvcicpIHtcbiAgICAgIGNhbGxiYWNrKG5ldyBWQVNURXJyb3IoXCJvbiBWQVNUSW50ZWdyYXRvciwgUGxheWVyIGlzIHVuYWJsZSB0byBwbGF5IHRoZSBBZFwiLCA0MDApLCByZXNwb25zZSk7XG4gICAgfVxuICAgIC8vTk9URTogSWYgdGhlIGFkcyBnZXQgY2FuY2VsZWQgd2UgZG8gbm90aGluZy9cbiAgfSk7XG5cbiAgLyoqKiogbG9jYWwgZnVuY3Rpb25zICoqKioqKi9cbiAgZnVuY3Rpb24gcGxheUFkKCkge1xuICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3BsYXlpbmcnLCAndmFzdC5hZHNDYW5jZWwnXSwgZnVuY3Rpb24gKGV2dCkge1xuICAgICAgaWYoZXZ0LnR5cGUgPT09ICd2YXN0LmFkc0NhbmNlbCcpe1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHBsYXllci50cmlnZ2VyKCd2YXN0LmFkU3RhcnQnKTtcblxuICAgICAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsnZW5kZWQnLCAndmFzdC5hZHNDYW5jZWwnLCAndmFzdC5hZFNraXAnXSwgZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBpZihldnQudHlwZSA9PT0gJ2VuZGVkJyB8fCBldnQudHlwZSA9PT0gJ3Zhc3QuYWRTa2lwJyl7XG4gICAgICAgICAgY2FsbGJhY2sobnVsbCwgcmVzcG9uc2UpO1xuICAgICAgICB9XG4gICAgICAgIC8vTk9URTogaWYgdGhlIGFkcyBnZXQgY2FuY2VsIHdlIGRvIG5vdGhpbmdcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHBsYXllci5wbGF5KCk7XG4gIH1cbn07XG5cblZBU1RJbnRlZ3JhdG9yLnByb3RvdHlwZS5fdHJhY2tFcnJvciA9IGZ1bmN0aW9uIHRyYWNrRXJyb3IoZXJyb3IsIHJlc3BvbnNlKSB7XG4gIHZhc3RVdGlsLnRyYWNrKHJlc3BvbnNlLmVycm9yVVJMTWFjcm9zLCB7RVJST1JDT0RFOiBlcnJvci5jb2RlIHx8IDkwMH0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBWQVNUSW50ZWdyYXRvcjsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBBZCA9IHJlcXVpcmUoJy4vQWQnKTtcbnZhciBWaWRlb0NsaWNrcyA9IHJlcXVpcmUoJy4vVmlkZW9DbGlja3MnKTtcbnZhciBMaW5lYXIgPSByZXF1aXJlKCcuL0xpbmVhcicpO1xudmFyIEluTGluZSA9IHJlcXVpcmUoJy4vSW5MaW5lJyk7XG52YXIgV3JhcHBlciA9IHJlcXVpcmUoJy4vV3JhcHBlcicpO1xuXG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucycpO1xudmFyIHhtbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3htbCcpO1xuXG53aW5kb3cuSW5MaW5lX19BID0gSW5MaW5lO1xuZnVuY3Rpb24gVkFTVFJlc3BvbnNlKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVkFTVFJlc3BvbnNlKSkge1xuICAgIHJldHVybiBuZXcgVkFTVFJlc3BvbnNlKCk7XG4gIH1cblxuICB0aGlzLl9saW5lYXJBZGRlZCA9IGZhbHNlO1xuICB0aGlzLmFkcyA9IFtdO1xuICB0aGlzLmVycm9yVVJMTWFjcm9zID0gW107XG4gIHRoaXMuaW1wcmVzc2lvbnMgPSBbXTtcbiAgdGhpcy5jbGlja1RyYWNraW5ncyA9IFtdO1xuICB0aGlzLmN1c3RvbUNsaWNrcyA9IFtdO1xuICB0aGlzLnRyYWNraW5nRXZlbnRzID0ge307XG4gIHRoaXMubWVkaWFGaWxlcyA9IFtdO1xuICB0aGlzLmNsaWNrVGhyb3VnaCA9IHVuZGVmaW5lZDtcbiAgdGhpcy5hZFRpdGxlID0gJyc7XG4gIHRoaXMuZHVyYXRpb24gPSB1bmRlZmluZWQ7XG4gIHRoaXMuc2tpcG9mZnNldCA9IHVuZGVmaW5lZDtcbn1cblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5hZGRBZCA9IGZ1bmN0aW9uIChhZCkge1xuICB2YXIgaW5MaW5lLCB3cmFwcGVyO1xuICBpZiAoYWQgaW5zdGFuY2VvZiBBZCkge1xuICAgIGluTGluZSA9IGFkLmluTGluZTtcbiAgICB3cmFwcGVyID0gYWQud3JhcHBlcjtcblxuICAgIHRoaXMuYWRzLnB1c2goYWQpO1xuXG4gICAgaWYgKGluTGluZSkge1xuICAgICAgdGhpcy5fYWRkSW5MaW5lKGluTGluZSk7XG4gICAgfVxuXG4gICAgaWYgKHdyYXBwZXIpIHtcbiAgICAgIHRoaXMuX2FkZFdyYXBwZXIod3JhcHBlcik7XG4gICAgfVxuICB9XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRFcnJvclRyYWNrVXJsID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gIHZhciBlcnJvclVSTCA9IGVycm9yIGluc3RhbmNlb2YgeG1sLkpYT05UcmVlID8geG1sLmtleVZhbHVlKGVycm9yKSA6IGVycm9yO1xuICBpZiAoZXJyb3JVUkwpIHtcbiAgICB0aGlzLmVycm9yVVJMTWFjcm9zLnB1c2goZXJyb3JVUkwpO1xuICB9XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRJbXByZXNzaW9ucyA9IGZ1bmN0aW9uIChpbXByZXNzaW9ucykge1xuICB1dGlsaXRpZXMuaXNBcnJheShpbXByZXNzaW9ucykgJiYgYXBwZW5kVG9BcnJheSh0aGlzLmltcHJlc3Npb25zLCBpbXByZXNzaW9ucyk7XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRDbGlja1Rocm91Z2ggPSBmdW5jdGlvbiAoY2xpY2tUaHJvdWdoKSB7XG4gIGlmICh1dGlsaXRpZXMuaXNOb3RFbXB0eVN0cmluZyhjbGlja1Rocm91Z2gpKSB7XG4gICAgdGhpcy5jbGlja1Rocm91Z2ggPSBjbGlja1Rocm91Z2g7XG4gIH1cbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZENsaWNrVHJhY2tpbmdzID0gZnVuY3Rpb24gKGNsaWNrVHJhY2tpbmdzKSB7XG4gIHV0aWxpdGllcy5pc0FycmF5KGNsaWNrVHJhY2tpbmdzKSAmJiBhcHBlbmRUb0FycmF5KHRoaXMuY2xpY2tUcmFja2luZ3MsIGNsaWNrVHJhY2tpbmdzKTtcbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZEN1c3RvbUNsaWNrcyA9IGZ1bmN0aW9uIChjdXN0b21DbGlja3MpIHtcbiAgdXRpbGl0aWVzLmlzQXJyYXkoY3VzdG9tQ2xpY2tzKSAmJiBhcHBlbmRUb0FycmF5KHRoaXMuY3VzdG9tQ2xpY2tzLCBjdXN0b21DbGlja3MpO1xufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkVHJhY2tpbmdFdmVudHMgPSBmdW5jdGlvbiAodHJhY2tpbmdFdmVudHMpIHtcbiAgdmFyIGV2ZW50c01hcCA9IHRoaXMudHJhY2tpbmdFdmVudHM7XG5cbiAgaWYgKHRyYWNraW5nRXZlbnRzKSB7XG4gICAgdHJhY2tpbmdFdmVudHMgPSB1dGlsaXRpZXMuaXNBcnJheSh0cmFja2luZ0V2ZW50cykgPyB0cmFja2luZ0V2ZW50cyA6IFt0cmFja2luZ0V2ZW50c107XG4gICAgdHJhY2tpbmdFdmVudHMuZm9yRWFjaChmdW5jdGlvbiAodHJhY2tpbmdFdmVudCkge1xuICAgICAgaWYgKCFldmVudHNNYXBbdHJhY2tpbmdFdmVudC5uYW1lXSkge1xuICAgICAgICBldmVudHNNYXBbdHJhY2tpbmdFdmVudC5uYW1lXSA9IFtdO1xuICAgICAgfVxuICAgICAgZXZlbnRzTWFwW3RyYWNraW5nRXZlbnQubmFtZV0ucHVzaCh0cmFja2luZ0V2ZW50KTtcbiAgICB9KTtcbiAgfVxufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkVGl0bGUgPSBmdW5jdGlvbiAodGl0bGUpIHtcbiAgaWYgKHV0aWxpdGllcy5pc05vdEVtcHR5U3RyaW5nKHRpdGxlKSkge1xuICAgIHRoaXMuYWRUaXRsZSA9IHRpdGxlO1xuICB9XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGREdXJhdGlvbiA9IGZ1bmN0aW9uIChkdXJhdGlvbikge1xuICBpZiAodXRpbGl0aWVzLmlzTnVtYmVyKGR1cmF0aW9uKSkge1xuICAgIHRoaXMuZHVyYXRpb24gPSBkdXJhdGlvbjtcbiAgfVxufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkVmlkZW9DbGlja3MgPSBmdW5jdGlvbiAodmlkZW9DbGlja3MpIHtcbiAgaWYgKHZpZGVvQ2xpY2tzIGluc3RhbmNlb2YgVmlkZW9DbGlja3MpIHtcbiAgICB0aGlzLl9hZGRDbGlja1Rocm91Z2godmlkZW9DbGlja3MuY2xpY2tUaHJvdWdoKTtcbiAgICB0aGlzLl9hZGRDbGlja1RyYWNraW5ncyh2aWRlb0NsaWNrcy5jbGlja1RyYWNraW5ncyk7XG4gICAgdGhpcy5fYWRkQ3VzdG9tQ2xpY2tzKHZpZGVvQ2xpY2tzLmN1c3RvbUNsaWNrcyk7XG4gIH1cbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZE1lZGlhRmlsZXMgPSBmdW5jdGlvbiAobWVkaWFGaWxlcykge1xuICB1dGlsaXRpZXMuaXNBcnJheShtZWRpYUZpbGVzKSAmJiBhcHBlbmRUb0FycmF5KHRoaXMubWVkaWFGaWxlcywgbWVkaWFGaWxlcyk7XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRTa2lwb2Zmc2V0ID0gZnVuY3Rpb24gKG9mZnNldCkge1xuICBpZiAob2Zmc2V0KSB7XG4gICAgdGhpcy5za2lwb2Zmc2V0ID0gb2Zmc2V0O1xuICB9XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLl9hZGRBZFBhcmFtZXRlcnMgPSBmdW5jdGlvbiAoYWRQYXJhbWV0ZXJzKSB7XG4gIGlmIChhZFBhcmFtZXRlcnMpIHtcbiAgICB0aGlzLmFkUGFyYW1ldGVycyA9IGFkUGFyYW1ldGVycztcbiAgfVxufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkTGluZWFyID0gZnVuY3Rpb24gKGxpbmVhcikge1xuICBpZiAobGluZWFyIGluc3RhbmNlb2YgTGluZWFyKSB7XG4gICAgdGhpcy5fYWRkRHVyYXRpb24obGluZWFyLmR1cmF0aW9uKTtcbiAgICB0aGlzLl9hZGRUcmFja2luZ0V2ZW50cyhsaW5lYXIudHJhY2tpbmdFdmVudHMpO1xuICAgIHRoaXMuX2FkZFZpZGVvQ2xpY2tzKGxpbmVhci52aWRlb0NsaWNrcyk7XG4gICAgdGhpcy5fYWRkTWVkaWFGaWxlcyhsaW5lYXIubWVkaWFGaWxlcyk7XG4gICAgdGhpcy5fYWRkU2tpcG9mZnNldChsaW5lYXIuc2tpcG9mZnNldCk7XG4gICAgdGhpcy5fYWRkQWRQYXJhbWV0ZXJzKGxpbmVhci5hZFBhcmFtZXRlcnMpO1xuICAgIHRoaXMuX2xpbmVhckFkZGVkID0gdHJ1ZTtcbiAgfVxufTtcblxuVkFTVFJlc3BvbnNlLnByb3RvdHlwZS5fYWRkSW5MaW5lID0gZnVuY3Rpb24gKGluTGluZSkge1xuICB2YXIgdGhhdCA9IHRoaXM7XG5cbiAgaWYgKGluTGluZSBpbnN0YW5jZW9mIEluTGluZSkge1xuICAgIHRoaXMuX2FkZFRpdGxlKGluTGluZS5hZFRpdGxlKTtcbiAgICB0aGlzLl9hZGRFcnJvclRyYWNrVXJsKGluTGluZS5lcnJvcik7XG4gICAgdGhpcy5fYWRkSW1wcmVzc2lvbnMoaW5MaW5lLmltcHJlc3Npb25zKTtcblxuICAgIGluTGluZS5jcmVhdGl2ZXMuZm9yRWFjaChmdW5jdGlvbiAoY3JlYXRpdmUpIHtcbiAgICAgIGlmIChjcmVhdGl2ZS5saW5lYXIpIHtcbiAgICAgICAgdGhhdC5fYWRkTGluZWFyKGNyZWF0aXZlLmxpbmVhcik7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn07XG5cblZBU1RSZXNwb25zZS5wcm90b3R5cGUuX2FkZFdyYXBwZXIgPSBmdW5jdGlvbiAod3JhcHBlcikge1xuICB2YXIgdGhhdCA9IHRoaXM7XG5cbiAgaWYgKHdyYXBwZXIgaW5zdGFuY2VvZiBXcmFwcGVyKSB7XG4gICAgdGhpcy5fYWRkRXJyb3JUcmFja1VybCh3cmFwcGVyLmVycm9yKTtcbiAgICB0aGlzLl9hZGRJbXByZXNzaW9ucyh3cmFwcGVyLmltcHJlc3Npb25zKTtcblxuICAgIHdyYXBwZXIuY3JlYXRpdmVzLmZvckVhY2goZnVuY3Rpb24gKGNyZWF0aXZlKSB7XG4gICAgICB2YXIgbGluZWFyID0gY3JlYXRpdmUubGluZWFyO1xuICAgICAgaWYgKGxpbmVhcikge1xuICAgICAgICB0aGF0Ll9hZGRWaWRlb0NsaWNrcyhsaW5lYXIudmlkZW9DbGlja3MpO1xuICAgICAgICB0aGF0LmNsaWNrVGhyb3VnaCA9IHVuZGVmaW5lZDsvL1dlIGVuc3VyZSB0aGF0IG5vIGNsaWNrVGhyb3VnaCBoYXMgYmVlbiBhZGRlZFxuICAgICAgICB0aGF0Ll9hZGRUcmFja2luZ0V2ZW50cyhsaW5lYXIudHJhY2tpbmdFdmVudHMpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59O1xuXG5WQVNUUmVzcG9uc2UucHJvdG90eXBlLmhhc0xpbmVhciA9IGZ1bmN0aW9uKCl7XG4gIHJldHVybiB0aGlzLl9saW5lYXJBZGRlZDtcbn07XG5cbmZ1bmN0aW9uIGFwcGVuZFRvQXJyYXkoYXJyYXksIGl0ZW1zKSB7XG4gIGl0ZW1zLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICBhcnJheS5wdXNoKGl0ZW0pO1xuICB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBWQVNUUmVzcG9uc2U7XG5cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFZBU1RFcnJvciA9IHJlcXVpcmUoJy4vVkFTVEVycm9yJyk7XG52YXIgVkFTVFJlc3BvbnNlID0gcmVxdWlyZSgnLi9WQVNUUmVzcG9uc2UnKTtcbnZhciB2YXN0VXRpbCA9IHJlcXVpcmUoJy4vdmFzdFV0aWwnKTtcbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbmZ1bmN0aW9uIFZBU1RUcmFja2VyKGFzc2V0VVJJLCB2YXN0UmVzcG9uc2UpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFZBU1RUcmFja2VyKSkge1xuICAgIHJldHVybiBuZXcgVkFTVFRyYWNrZXIoYXNzZXRVUkksIHZhc3RSZXNwb25zZSk7XG4gIH1cblxuICB0aGlzLnNhbml0eUNoZWNrKGFzc2V0VVJJLCB2YXN0UmVzcG9uc2UpO1xuICB0aGlzLmluaXRpYWxpemUoYXNzZXRVUkksIHZhc3RSZXNwb25zZSk7XG5cbn1cblxuVkFTVFRyYWNrZXIucHJvdG90eXBlLmluaXRpYWxpemUgPSBmdW5jdGlvbihhc3NldFVSSSwgdmFzdFJlc3BvbnNlKSB7XG4gIHRoaXMucmVzcG9uc2UgPSB2YXN0UmVzcG9uc2U7XG4gIHRoaXMuYXNzZXRVUkkgPSBhc3NldFVSSTtcbiAgdGhpcy5wcm9ncmVzcyA9IDA7XG4gIHRoaXMucXVhcnRpbGVzID0ge1xuICAgIGZpcnN0UXVhcnRpbGU6IHt0cmFja2VkOiBmYWxzZSwgdGltZTogTWF0aC5yb3VuZCgyNSAqIHZhc3RSZXNwb25zZS5kdXJhdGlvbikgLyAxMDB9LFxuICAgIG1pZHBvaW50OiB7dHJhY2tlZDogZmFsc2UsIHRpbWU6IE1hdGgucm91bmQoNTAgKiB2YXN0UmVzcG9uc2UuZHVyYXRpb24pIC8gMTAwfSxcbiAgICB0aGlyZFF1YXJ0aWxlOiB7dHJhY2tlZDogZmFsc2UsIHRpbWU6IE1hdGgucm91bmQoNzUgKiB2YXN0UmVzcG9uc2UuZHVyYXRpb24pIC8gMTAwfVxuICB9O1xufTtcblxuVkFTVFRyYWNrZXIucHJvdG90eXBlLnNhbml0eUNoZWNrID0gZnVuY3Rpb24oYXNzZXRVUkksIHZhc3RSZXNwb25zZSkge1xuICBpZiAoIXV0aWxpdGllcy5pc1N0cmluZyhhc3NldFVSSSkgfHwgdXRpbGl0aWVzLmlzRW1wdHlTdHJpbmcoYXNzZXRVUkkpKSB7XG4gICAgdGhyb3cgbmV3IFZBU1RFcnJvcignb24gVkFTVFRyYWNrZXIgY29uc3RydWN0b3IsIG1pc3NpbmcgcmVxdWlyZWQgdGhlIFVSSSBvZiB0aGUgYWQgYXNzZXQgYmVpbmcgcGxheWVkJyk7XG4gIH1cblxuICBpZiAoISh2YXN0UmVzcG9uc2UgaW5zdGFuY2VvZiBWQVNUUmVzcG9uc2UpKSB7XG4gICAgdGhyb3cgbmV3IFZBU1RFcnJvcignb24gVkFTVFRyYWNrZXIgY29uc3RydWN0b3IsIG1pc3NpbmcgcmVxdWlyZWQgVkFTVCByZXNwb25zZScpO1xuICB9XG59O1xuXG5WQVNUVHJhY2tlci5wcm90b3R5cGUudHJhY2tVUkxzID0gZnVuY3Rpb24gdHJhY2tVUkxzKHVybHMsIHZhcmlhYmxlcykge1xuICBpZiAodXRpbGl0aWVzLmlzQXJyYXkodXJscykgJiYgdXJscy5sZW5ndGggPiAwKSB7XG4gICAgdmFyaWFibGVzID0gdXRpbGl0aWVzLmV4dGVuZCh7XG4gICAgICBBU1NFVFVSSTogdGhpcy5hc3NldFVSSSxcbiAgICAgIENPTlRFTlRQTEFZSEVBRDogdmFzdFV0aWwuZm9ybWF0UHJvZ3Jlc3ModGhpcy5wcm9ncmVzcylcbiAgICB9LCB2YXJpYWJsZXMgfHwge30pO1xuXG4gICAgdmFzdFV0aWwudHJhY2sodXJscywgdmFyaWFibGVzKTtcbiAgfVxufTtcblxuVkFTVFRyYWNrZXIucHJvdG90eXBlLnRyYWNrRXZlbnQgPSBmdW5jdGlvbiB0cmFja0V2ZW50KGV2ZW50TmFtZSwgdHJhY2tPbmNlKSB7XG4gIHRoaXMudHJhY2tVUkxzKGdldEV2ZW50VXJpcyh0aGlzLnJlc3BvbnNlLnRyYWNraW5nRXZlbnRzW2V2ZW50TmFtZV0pKTtcbiAgaWYgKHRyYWNrT25jZSkge1xuICAgIHRoaXMucmVzcG9uc2UudHJhY2tpbmdFdmVudHNbZXZlbnROYW1lXSA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb24gKioqL1xuICBmdW5jdGlvbiBnZXRFdmVudFVyaXModHJhY2tpbmdFdmVudHMpIHtcbiAgICB2YXIgdXJpcztcblxuICAgIGlmICh0cmFja2luZ0V2ZW50cykge1xuICAgICAgdXJpcyA9IFtdO1xuICAgICAgdHJhY2tpbmdFdmVudHMuZm9yRWFjaChmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgdXJpcy5wdXNoKGV2ZW50LnVyaSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHVyaXM7XG4gIH1cbn07XG5cblZBU1RUcmFja2VyLnByb3RvdHlwZS50cmFja1Byb2dyZXNzID0gZnVuY3Rpb24gdHJhY2tQcm9ncmVzcyhuZXdQcm9ncmVzc0luTXMpIHtcbiAgdmFyIHRoYXQgPSB0aGlzO1xuICB2YXIgZXZlbnRzID0gW107XG4gIHZhciBPTkNFID0gdHJ1ZTtcbiAgdmFyIEFMV0FZUyA9IGZhbHNlO1xuICB2YXIgdHJhY2tpbmdFdmVudHMgPSB0aGlzLnJlc3BvbnNlLnRyYWNraW5nRXZlbnRzO1xuXG4gIGlmICh1dGlsaXRpZXMuaXNOdW1iZXIobmV3UHJvZ3Jlc3NJbk1zKSkge1xuICAgIGFkZFRyYWNrRXZlbnQoJ3N0YXJ0JywgT05DRSwgbmV3UHJvZ3Jlc3NJbk1zID4gMCk7XG4gICAgYWRkVHJhY2tFdmVudCgncmV3aW5kJywgQUxXQVlTLCBoYXNSZXdvdW5kKHRoaXMucHJvZ3Jlc3MsIG5ld1Byb2dyZXNzSW5NcykpO1xuICAgIGFkZFF1YXJ0aWxlRXZlbnRzKG5ld1Byb2dyZXNzSW5Ncyk7XG4gICAgdHJhY2tQcm9ncmVzc0V2ZW50cyhuZXdQcm9ncmVzc0luTXMpO1xuICAgIHRyYWNrRXZlbnRzKCk7XG4gICAgdGhpcy5wcm9ncmVzcyA9IG5ld1Byb2dyZXNzSW5NcztcbiAgfVxuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb24gKioqL1xuICBmdW5jdGlvbiBoYXNSZXdvdW5kKGN1cnJlbnRQcm9ncmVzcywgbmV3UHJvZ3Jlc3MpIHtcbiAgICB2YXIgUkVXSU5EX1RIUkVTSE9MRCA9IDMwMDA7IC8vSU9TIHZpZGVvIGNsb2NrIGlzIHZlcnkgdW5yZWxpYWJsZSBhbmQgd2UgbmVlZCBhIDMgc2Vjb25kcyB0aHJlc2hvbGQgdG8gZW5zdXJlIHRoYXQgdGhlcmUgd2FzIGEgcmV3aW5kIGFuIHRoYXQgaXQgd2FzIG9uIHB1cnBvc2UuXG4gICAgcmV0dXJuIGN1cnJlbnRQcm9ncmVzcyA+IG5ld1Byb2dyZXNzSW5NcyAmJiBNYXRoLmFicyhuZXdQcm9ncmVzcyAtIGN1cnJlbnRQcm9ncmVzcykgPiBSRVdJTkRfVEhSRVNIT0xEO1xuICB9XG5cbiAgZnVuY3Rpb24gYWRkVHJhY2tFdmVudChldmVudE5hbWUsIHRyYWNrT25jZSwgY2FuQmVBZGRlZCkge1xuICAgIGlmICh0cmFja2luZ0V2ZW50c1tldmVudE5hbWVdICYmIGNhbkJlQWRkZWQpIHtcbiAgICAgIGV2ZW50cy5wdXNoKHtcbiAgICAgICAgbmFtZTogZXZlbnROYW1lLFxuICAgICAgICB0cmFja09uY2U6ICEhdHJhY2tPbmNlXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBhZGRRdWFydGlsZUV2ZW50cyhwcm9ncmVzcykge1xuICAgIHZhciBxdWFydGlsZXMgPSB0aGF0LnF1YXJ0aWxlcztcbiAgICB2YXIgZmlyc3RRdWFydGlsZSA9IHRoYXQucXVhcnRpbGVzLmZpcnN0UXVhcnRpbGU7XG4gICAgdmFyIG1pZHBvaW50ID0gdGhhdC5xdWFydGlsZXMubWlkcG9pbnQ7XG4gICAgdmFyIHRoaXJkUXVhcnRpbGUgPSB0aGF0LnF1YXJ0aWxlcy50aGlyZFF1YXJ0aWxlO1xuXG4gICAgaWYgKCFmaXJzdFF1YXJ0aWxlLnRyYWNrZWQpIHtcbiAgICAgIHRyYWNrUXVhcnRpbGUoJ2ZpcnN0UXVhcnRpbGUnLCBwcm9ncmVzcyk7XG4gICAgfSBlbHNlIGlmICghbWlkcG9pbnQudHJhY2tlZCkge1xuICAgICAgdHJhY2tRdWFydGlsZSgnbWlkcG9pbnQnLCBwcm9ncmVzcyk7XG4gICAgfSBlbHNlIGlmICghdGhpcmRRdWFydGlsZS50cmFja2VkKXtcbiAgICAgIHRyYWNrUXVhcnRpbGUoJ3RoaXJkUXVhcnRpbGUnLCBwcm9ncmVzcyk7XG4gICAgfVxuXG4gICAgLyoqKiBMb2NhbCBmdW5jdGlvbiAqKiovXG4gICAgZnVuY3Rpb24gdHJhY2tRdWFydGlsZShxdWFydGlsZU5hbWUsIHByb2dyZXNzKXtcbiAgICAgIHZhciBxdWFydGlsZSA9IHF1YXJ0aWxlc1txdWFydGlsZU5hbWVdO1xuICAgICAgaWYoY2FuQmVUcmFja2VkKHF1YXJ0aWxlLCBwcm9ncmVzcykpe1xuICAgICAgICBxdWFydGlsZS50cmFja2VkID0gdHJ1ZTtcbiAgICAgICAgYWRkVHJhY2tFdmVudChxdWFydGlsZU5hbWUsIE9OQ0UsIHRydWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGNhbkJlVHJhY2tlZChxdWFydGlsZSwgcHJvZ3Jlc3MpIHtcbiAgICB2YXIgcXVhcnRpbGVUaW1lID0gcXVhcnRpbGUudGltZTtcbiAgICAvL1dlIG9ubHkgZmlyZSB0aGUgcXVhcnRpbGUgZXZlbnQgaWYgdGhlIHByb2dyZXNzIGlzIGJpZ2dlciB0aGFuIHRoZSBxdWFydGlsZSB0aW1lIGJ5IDUgc2Vjb25kcyBhdCBtb3N0LlxuICAgIHJldHVybiBwcm9ncmVzcyA+PSBxdWFydGlsZVRpbWUgJiYgcHJvZ3Jlc3MgPD0gKHF1YXJ0aWxlVGltZSArIDUwMDApO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJhY2tQcm9ncmVzc0V2ZW50cyhwcm9ncmVzcykge1xuICAgIGlmICghdXRpbGl0aWVzLmlzQXJyYXkodHJhY2tpbmdFdmVudHMucHJvZ3Jlc3MpKSB7XG4gICAgICByZXR1cm47IC8vTm90aGluZyB0byB0cmFja1xuICAgIH1cblxuICAgIHZhciBwZW5kaW5nUHJvZ3Jlc3NFdnRzID0gW107XG5cbiAgICB0cmFja2luZ0V2ZW50cy5wcm9ncmVzcy5mb3JFYWNoKGZ1bmN0aW9uIChldnQpIHtcbiAgICAgIGlmIChldnQub2Zmc2V0IDw9IHByb2dyZXNzKSB7XG4gICAgICAgIHRoYXQudHJhY2tVUkxzKFtldnQudXJpXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwZW5kaW5nUHJvZ3Jlc3NFdnRzLnB1c2goZXZ0KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0cmFja2luZ0V2ZW50cy5wcm9ncmVzcyA9IHBlbmRpbmdQcm9ncmVzc0V2dHM7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFja0V2ZW50cygpIHtcbiAgICBldmVudHMuZm9yRWFjaChmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgIHRoYXQudHJhY2tFdmVudChldmVudC5uYW1lLCBldmVudC50cmFja09uY2UpO1xuICAgIH0pO1xuICB9XG59O1xuXG5bXG4gICdyZXdpbmQnLFxuICAnZnVsbHNjcmVlbicsXG4gICdleGl0RnVsbHNjcmVlbicsXG4gICdwYXVzZScsXG4gICdyZXN1bWUnLFxuICAnbXV0ZScsXG4gICd1bm11dGUnLFxuICAnYWNjZXB0SW52aXRhdGlvbicsXG4gICdhY2NlcHRJbnZpdGF0aW9uTGluZWFyJyxcbiAgJ2NvbGxhcHNlJyxcbiAgJ2V4cGFuZCdcbl0uZm9yRWFjaChmdW5jdGlvbiAoZXZlbnROYW1lKSB7XG4gICAgVkFTVFRyYWNrZXIucHJvdG90eXBlWyd0cmFjaycgKyB1dGlsaXRpZXMuY2FwaXRhbGl6ZShldmVudE5hbWUpXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMudHJhY2tFdmVudChldmVudE5hbWUpO1xuICAgIH07XG4gIH0pO1xuXG5bXG4gICdzdGFydCcsXG4gICdza2lwJyxcbiAgJ2Nsb3NlJyxcbiAgJ2Nsb3NlTGluZWFyJ1xuXS5mb3JFYWNoKGZ1bmN0aW9uIChldmVudE5hbWUpIHtcbiAgICBWQVNUVHJhY2tlci5wcm90b3R5cGVbJ3RyYWNrJyArIHV0aWxpdGllcy5jYXBpdGFsaXplKGV2ZW50TmFtZSldID0gZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy50cmFja0V2ZW50KGV2ZW50TmFtZSwgdHJ1ZSk7XG4gICAgfTtcbiAgfSk7XG5cbltcbiAgJ2ZpcnN0UXVhcnRpbGUnLFxuICAnbWlkcG9pbnQnLFxuICAndGhpcmRRdWFydGlsZSdcbl0uZm9yRWFjaChmdW5jdGlvbiAocXVhcnRpbGUpIHtcbiAgICBWQVNUVHJhY2tlci5wcm90b3R5cGVbJ3RyYWNrJyArIHV0aWxpdGllcy5jYXBpdGFsaXplKHF1YXJ0aWxlKV0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLnF1YXJ0aWxlc1txdWFydGlsZV0udHJhY2tlZCA9IHRydWU7XG4gICAgICB0aGlzLnRyYWNrRXZlbnQocXVhcnRpbGUsIHRydWUpO1xuICAgIH07XG4gIH0pO1xuXG5WQVNUVHJhY2tlci5wcm90b3R5cGUudHJhY2tDb21wbGV0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYodGhpcy5xdWFydGlsZXMudGhpcmRRdWFydGlsZS50cmFja2VkKXtcbiAgICB0aGlzLnRyYWNrRXZlbnQoJ2NvbXBsZXRlJywgdHJ1ZSk7XG4gIH1cbn07XG5cblZBU1RUcmFja2VyLnByb3RvdHlwZS50cmFja0Vycm9yV2l0aENvZGUgPSBmdW5jdGlvbiB0cmFja0Vycm9yV2l0aENvZGUoZXJyb3Jjb2RlKSB7XG4gIGlmICh1dGlsaXRpZXMuaXNOdW1iZXIoZXJyb3Jjb2RlKSkge1xuICAgIHRoaXMudHJhY2tVUkxzKHRoaXMucmVzcG9uc2UuZXJyb3JVUkxNYWNyb3MsIHtFUlJPUkNPREU6IGVycm9yY29kZX0pO1xuICB9XG59O1xuXG5WQVNUVHJhY2tlci5wcm90b3R5cGUudHJhY2tJbXByZXNzaW9ucyA9IGZ1bmN0aW9uIHRyYWNrSW1wcmVzc2lvbnMoKSB7XG4gIHRoaXMudHJhY2tVUkxzKHRoaXMucmVzcG9uc2UuaW1wcmVzc2lvbnMpO1xufTtcblxuVkFTVFRyYWNrZXIucHJvdG90eXBlLnRyYWNrQ3JlYXRpdmVWaWV3ID0gZnVuY3Rpb24gdHJhY2tDcmVhdGl2ZVZpZXcoKSB7XG4gIHRoaXMudHJhY2tFdmVudCgnY3JlYXRpdmVWaWV3Jyk7XG59O1xuXG5WQVNUVHJhY2tlci5wcm90b3R5cGUudHJhY2tDbGljayA9IGZ1bmN0aW9uIHRyYWNrQ2xpY2soKSB7XG4gIHRoaXMudHJhY2tVUkxzKHRoaXMucmVzcG9uc2UuY2xpY2tUcmFja2luZ3MpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBWQVNUVHJhY2tlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcbnZhciB4bWwgPSByZXF1aXJlKCcuLi8uLi91dGlscy94bWwnKTtcblxuZnVuY3Rpb24gVmlkZW9DbGlja3ModmlkZW9DbGlja0pUcmVlKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBWaWRlb0NsaWNrcykpIHtcbiAgICByZXR1cm4gbmV3IFZpZGVvQ2xpY2tzKHZpZGVvQ2xpY2tKVHJlZSk7XG4gIH1cblxuICB0aGlzLmNsaWNrVGhyb3VnaCA9IHhtbC5rZXlWYWx1ZSh2aWRlb0NsaWNrSlRyZWUuY2xpY2tUaHJvdWdoKTtcbiAgdGhpcy5jbGlja1RyYWNraW5ncyA9IHBhcnNlQ2xpY2tUcmFja2luZ3ModmlkZW9DbGlja0pUcmVlLmNsaWNrVHJhY2tpbmcpO1xuICB0aGlzLmN1c3RvbUNsaWNrcyA9IHBhcnNlQ2xpY2tUcmFja2luZ3ModmlkZW9DbGlja0pUcmVlLmN1c3RvbUNsaWNrKTtcblxuICAvKioqIExvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIHBhcnNlQ2xpY2tUcmFja2luZ3ModHJhY2tpbmdEYXRhKSB7XG4gICAgdmFyIGNsaWNrVHJhY2tpbmdzID0gW107XG4gICAgaWYgKHRyYWNraW5nRGF0YSkge1xuICAgICAgdHJhY2tpbmdEYXRhID0gdXRpbGl0aWVzLmlzQXJyYXkodHJhY2tpbmdEYXRhKSA/IHRyYWNraW5nRGF0YSA6IFt0cmFja2luZ0RhdGFdO1xuICAgICAgdHJhY2tpbmdEYXRhLmZvckVhY2goZnVuY3Rpb24gKGNsaWNrVHJhY2tpbmdEYXRhKSB7XG4gICAgICAgIGNsaWNrVHJhY2tpbmdzLnB1c2goeG1sLmtleVZhbHVlKGNsaWNrVHJhY2tpbmdEYXRhKSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGNsaWNrVHJhY2tpbmdzO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gVmlkZW9DbGlja3M7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdmFzdFV0aWwgPSByZXF1aXJlKCcuL3Zhc3RVdGlsJyk7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG52YXIgeG1sID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMveG1sJyk7XG5cbmZ1bmN0aW9uIFdyYXBwZXIod3JhcHBlckpUcmVlKSB7XG4gIGlmKCEodGhpcyBpbnN0YW5jZW9mIFdyYXBwZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBXcmFwcGVyKHdyYXBwZXJKVHJlZSk7XG4gIH1cblxuICAvL1JlcXVpcmVkIGVsZW1lbnRzXG4gIHRoaXMuYWRTeXN0ZW0gPSB4bWwua2V5VmFsdWUod3JhcHBlckpUcmVlLmFkU3lzdGVtKTtcbiAgdGhpcy5pbXByZXNzaW9ucyA9IHZhc3RVdGlsLnBhcnNlSW1wcmVzc2lvbnMod3JhcHBlckpUcmVlLmltcHJlc3Npb24pO1xuICB0aGlzLlZBU1RBZFRhZ1VSSSA9IHhtbC5rZXlWYWx1ZSh3cmFwcGVySlRyZWUudkFTVEFkVGFnVVJJKTtcblxuICAvL09wdGlvbmFsIGVsZW1lbnRzXG4gIHRoaXMuY3JlYXRpdmVzID0gdmFzdFV0aWwucGFyc2VDcmVhdGl2ZXMod3JhcHBlckpUcmVlLmNyZWF0aXZlcyk7XG4gIHRoaXMuZXJyb3IgPSB4bWwua2V5VmFsdWUod3JhcHBlckpUcmVlLmVycm9yKTtcbiAgdGhpcy5leHRlbnNpb25zID0gd3JhcHBlckpUcmVlLmV4dGVuc2lvbnM7XG5cbiAgLy9PcHRpb25hbCBhdHRyc1xuICB0aGlzLmZvbGxvd0FkZGl0aW9uYWxXcmFwcGVycyA9IHV0aWxpdGllcy5pc0RlZmluZWQoeG1sLmF0dHIod3JhcHBlckpUcmVlLCAnZm9sbG93QWRkaXRpb25hbFdyYXBwZXJzJykpPyB4bWwuYXR0cih3cmFwcGVySlRyZWUsICdmb2xsb3dBZGRpdGlvbmFsV3JhcHBlcnMnKTogdHJ1ZTtcbiAgdGhpcy5hbGxvd011bHRpcGxlQWRzID0geG1sLmF0dHIod3JhcHBlckpUcmVlLCAnYWxsb3dNdWx0aXBsZUFkcycpO1xuICB0aGlzLmZhbGxiYWNrT25Ob0FkID0geG1sLmF0dHIod3JhcHBlckpUcmVlLCAnZmFsbGJhY2tPbk5vQWQnKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBXcmFwcGVyOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxudmFyIGR1cmF0aW9uUmVnZXggPSAvKFxcZFxcZCk6KFxcZFxcZCk6KFxcZFxcZCkoXFwuKFxcZFxcZFxcZCkpPy87XG5cbnZhciBwYXJzZXJzID0ge1xuXG4gIGR1cmF0aW9uOiBmdW5jdGlvbiBwYXJzZUR1cmF0aW9uKGR1cmF0aW9uU3RyKSB7XG5cbiAgICB2YXIgbWF0Y2gsIGR1cmF0aW9uSW5NcztcblxuICAgIGlmICh1dGlsaXRpZXMuaXNTdHJpbmcoZHVyYXRpb25TdHIpKSB7XG4gICAgICBtYXRjaCA9IGR1cmF0aW9uU3RyLm1hdGNoKGR1cmF0aW9uUmVnZXgpO1xuICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgIGR1cmF0aW9uSW5NcyA9IHBhcnNlSG91cnNUb01zKG1hdGNoWzFdKSArIHBhcnNlTWluVG9NcyhtYXRjaFsyXSkgKyBwYXJzZVNlY1RvTXMobWF0Y2hbM10pICsgcGFyc2VJbnQobWF0Y2hbNV0gfHwgMCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGlzTmFOKGR1cmF0aW9uSW5NcykgPyBudWxsIDogZHVyYXRpb25Jbk1zO1xuXG4gICAgLyoqKiBsb2NhbCBmdW5jdGlvbnMgKioqL1xuICAgIGZ1bmN0aW9uIHBhcnNlSG91cnNUb01zKGhvdXJTdHIpIHtcbiAgICAgIHJldHVybiBwYXJzZUludChob3VyU3RyLCAxMCkgKiA2MCAqIDYwICogMTAwMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZU1pblRvTXMobWluU3RyKSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQobWluU3RyLCAxMCkgKiA2MCAqIDEwMDA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VTZWNUb01zKHNlY1N0cikge1xuICAgICAgcmV0dXJuIHBhcnNlSW50KHNlY1N0ciwgMTApICogMTAwMDtcbiAgICB9XG4gIH0sXG5cbiAgb2Zmc2V0OiBmdW5jdGlvbiBwYXJzZU9mZnNldChvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgaWYoaXNQZXJjZW50YWdlKG9mZnNldCkpe1xuICAgICAgcmV0dXJuIGNhbGN1bGF0ZVBlcmNlbnRhZ2Uob2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgfVxuICAgIHJldHVybiBwYXJzZXJzLmR1cmF0aW9uKG9mZnNldCk7XG5cbiAgICAvKioqIExvY2FsIGZ1bmN0aW9uICoqKi9cbiAgICBmdW5jdGlvbiBpc1BlcmNlbnRhZ2Uob2Zmc2V0KSB7XG4gICAgICB2YXIgcGVyY2VudGFnZVJlZ2V4ID0gL15cXGQrKFxcLlxcZCspPyUkL2c7XG4gICAgICByZXR1cm4gcGVyY2VudGFnZVJlZ2V4LnRlc3Qob2Zmc2V0KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjYWxjdWxhdGVQZXJjZW50YWdlKHBlcmNlbnRTdHIsIGR1cmF0aW9uKSB7XG4gICAgICBpZihkdXJhdGlvbikge1xuICAgICAgICByZXR1cm4gY2FsY1BlcmNlbnQoZHVyYXRpb24sIHBhcnNlRmxvYXQocGVyY2VudFN0ci5yZXBsYWNlKCclJywgJycpKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjYWxjUGVyY2VudChxdWFudGl0eSwgcGVyY2VudCl7XG4gICAgICByZXR1cm4gcXVhbnRpdHkgKiBwZXJjZW50IC8gMTAwO1xuICAgIH1cbiAgfVxuXG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gcGFyc2VyczsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBDcmVhdGl2ZSA9IHJlcXVpcmUoJy4vQ3JlYXRpdmUnKTtcbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbnZhciB2YXN0VXRpbCA9IHtcblxuICB0cmFjazogZnVuY3Rpb24gdHJhY2soVVJMTWFjcm9zLCB2YXJpYWJsZXMpIHtcbiAgICB2YXIgc291cmNlcyA9IHZhc3RVdGlsLnBhcnNlVVJMTWFjcm9zKFVSTE1hY3JvcywgdmFyaWFibGVzKTtcbiAgICB2YXIgdHJhY2tJbWdzID0gW107XG4gICAgc291cmNlcy5mb3JFYWNoKGZ1bmN0aW9uIChzcmMpIHtcbiAgICAgIHZhciBpbWcgPSBuZXcgSW1hZ2UoKTtcbiAgICAgIGltZy5zcmMgPSBzcmM7XG4gICAgICB0cmFja0ltZ3MucHVzaChpbWcpO1xuICAgIH0pO1xuICAgIHJldHVybiB0cmFja0ltZ3M7XG4gIH0sXG5cbiAgcGFyc2VVUkxNYWNyb3M6IGZ1bmN0aW9uIHBhcnNlTWFjcm9zKFVSTE1hY3JvcywgdmFyaWFibGVzKSB7XG4gICAgdmFyIHBhcnNlZFVSTHMgPSBbXTtcblxuICAgIHZhcmlhYmxlcyA9IHZhcmlhYmxlcyB8fCB7fTtcblxuICAgIGlmICghKHZhcmlhYmxlc1tcIkNBQ0hFQlVTVElOR1wiXSkpIHtcbiAgICAgIHZhcmlhYmxlc1tcIkNBQ0hFQlVTVElOR1wiXSA9IE1hdGgucm91bmQoTWF0aC5yYW5kb20oKSAqIDEuMGUrMTApO1xuICAgIH1cblxuICAgIFVSTE1hY3Jvcy5mb3JFYWNoKGZ1bmN0aW9uIChVUkxNYWNybykge1xuICAgICAgcGFyc2VkVVJMcy5wdXNoKHZhc3RVdGlsLl9wYXJzZVVSTE1hY3JvKFVSTE1hY3JvLCB2YXJpYWJsZXMpKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBwYXJzZWRVUkxzO1xuICB9LFxuXG4gIHBhcnNlVVJMTWFjcm86IGZ1bmN0aW9uIHBhcnNlTWFjcm8oVVJMTWFjcm8sIHZhcmlhYmxlcykge1xuICAgIHZhcmlhYmxlcyA9IHZhcmlhYmxlcyB8fCB7fTtcblxuICAgIGlmICghKHZhcmlhYmxlc1tcIkNBQ0hFQlVTVElOR1wiXSkpIHtcbiAgICAgIHZhcmlhYmxlc1tcIkNBQ0hFQlVTVElOR1wiXSA9IE1hdGgucm91bmQoTWF0aC5yYW5kb20oKSAqIDEuMGUrMTApO1xuICAgIH1cblxuICAgIHJldHVybiB2YXN0VXRpbC5fcGFyc2VVUkxNYWNybyhVUkxNYWNybywgdmFyaWFibGVzKTtcbiAgfSxcblxuICBfcGFyc2VVUkxNYWNybzogZnVuY3Rpb24gcGFyc2VNYWNybyhVUkxNYWNybywgdmFyaWFibGVzKSB7XG4gICAgdmFyaWFibGVzID0gdmFyaWFibGVzIHx8IHt9O1xuXG4gICAgdXRpbGl0aWVzLmZvckVhY2godmFyaWFibGVzLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgVVJMTWFjcm8gPSBVUkxNYWNyby5yZXBsYWNlKG5ldyBSZWdFeHAoXCJcXFxcW1wiICsga2V5ICsgXCJcXFxcXFxdXCIsICdnbScpLCB2YWx1ZSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gVVJMTWFjcm87XG4gIH0sXG5cbiAgcGFyc2VEdXJhdGlvbjogZnVuY3Rpb24gcGFyc2VEdXJhdGlvbihkdXJhdGlvblN0cikge1xuICAgIHZhciBkdXJhdGlvblJlZ2V4ID0gLyhcXGRcXGQpOihcXGRcXGQpOihcXGRcXGQpKFxcLihcXGRcXGRcXGQpKT8vO1xuICAgIHZhciBtYXRjaCwgZHVyYXRpb25Jbk1zO1xuXG4gICAgaWYgKHV0aWxpdGllcy5pc1N0cmluZyhkdXJhdGlvblN0cikpIHtcbiAgICAgIG1hdGNoID0gZHVyYXRpb25TdHIubWF0Y2goZHVyYXRpb25SZWdleCk7XG4gICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgZHVyYXRpb25Jbk1zID0gcGFyc2VIb3Vyc1RvTXMobWF0Y2hbMV0pICsgcGFyc2VNaW5Ub01zKG1hdGNoWzJdKSArIHBhcnNlU2VjVG9NcyhtYXRjaFszXSkgKyBwYXJzZUludChtYXRjaFs1XSB8fCAwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gaXNOYU4oZHVyYXRpb25Jbk1zKSA/IG51bGwgOiBkdXJhdGlvbkluTXM7XG5cbiAgICAvKioqIGxvY2FsIGZ1bmN0aW9ucyAqKiovXG4gICAgZnVuY3Rpb24gcGFyc2VIb3Vyc1RvTXMoaG91clN0cikge1xuICAgICAgcmV0dXJuIHBhcnNlSW50KGhvdXJTdHIsIDEwKSAqIDYwICogNjAgKiAxMDAwO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlTWluVG9NcyhtaW5TdHIpIHtcbiAgICAgIHJldHVybiBwYXJzZUludChtaW5TdHIsIDEwKSAqIDYwICogMTAwMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZVNlY1RvTXMoc2VjU3RyKSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQoc2VjU3RyLCAxMCkgKiAxMDAwO1xuICAgIH1cbiAgfSxcblxuICBwYXJzZUltcHJlc3Npb25zOiBmdW5jdGlvbiBwYXJzZUltcHJlc3Npb25zKGltcHJlc3Npb25zKSB7XG4gICAgaWYgKGltcHJlc3Npb25zKSB7XG4gICAgICBpbXByZXNzaW9ucyA9IHV0aWxpdGllcy5pc0FycmF5KGltcHJlc3Npb25zKSA/IGltcHJlc3Npb25zIDogW2ltcHJlc3Npb25zXTtcbiAgICAgIHJldHVybiB1dGlsaXRpZXMudHJhbnNmb3JtQXJyYXkoaW1wcmVzc2lvbnMsIGZ1bmN0aW9uIChpbXByZXNzaW9uKSB7XG4gICAgICAgIGlmICh1dGlsaXRpZXMuaXNOb3RFbXB0eVN0cmluZyhpbXByZXNzaW9uLmtleVZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiBpbXByZXNzaW9uLmtleVZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xuICB9LFxuXG4gIHBhcnNlQ3JlYXRpdmVzOiBmdW5jdGlvbiBwYXJzZUNyZWF0aXZlcyhjcmVhdGl2ZXNKVHJlZSkge1xuICAgIHZhciBjcmVhdGl2ZXMgPSBbXTtcbiAgICB2YXIgY3JlYXRpdmVzRGF0YTtcbiAgICBpZiAodXRpbGl0aWVzLmlzRGVmaW5lZChjcmVhdGl2ZXNKVHJlZSkgJiYgdXRpbGl0aWVzLmlzRGVmaW5lZChjcmVhdGl2ZXNKVHJlZS5jcmVhdGl2ZSkpIHtcbiAgICAgIGNyZWF0aXZlc0RhdGEgPSB1dGlsaXRpZXMuaXNBcnJheShjcmVhdGl2ZXNKVHJlZS5jcmVhdGl2ZSkgPyBjcmVhdGl2ZXNKVHJlZS5jcmVhdGl2ZSA6IFtjcmVhdGl2ZXNKVHJlZS5jcmVhdGl2ZV07XG4gICAgICBjcmVhdGl2ZXNEYXRhLmZvckVhY2goZnVuY3Rpb24gKGNyZWF0aXZlKSB7XG4gICAgICAgIGNyZWF0aXZlcy5wdXNoKG5ldyBDcmVhdGl2ZShjcmVhdGl2ZSkpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBjcmVhdGl2ZXM7XG4gIH0sXG5cbiAgLy9XZSBhc3N1bWUgdGhhdCB0aGUgcHJvZ3Jlc3MgaXMgZ29pbmcgdG8gYXJyaXZlIGluIG1pbGxpc2Vjb25kc1xuICBmb3JtYXRQcm9ncmVzczogZnVuY3Rpb24gZm9ybWF0UHJvZ3Jlc3MocHJvZ3Jlc3MpIHtcbiAgICB2YXIgaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMsIG1pbGxpc2Vjb25kcztcbiAgICBob3VycyA9IHByb2dyZXNzIC8gKDYwICogNjAgKiAxMDAwKTtcbiAgICBob3VycyA9IE1hdGguZmxvb3IoaG91cnMpO1xuICAgIG1pbnV0ZXMgPSAocHJvZ3Jlc3MgLyAoNjAgKiAxMDAwKSkgJSA2MDtcbiAgICBtaW51dGVzID0gTWF0aC5mbG9vcihtaW51dGVzKTtcbiAgICBzZWNvbmRzID0gKHByb2dyZXNzIC8gMTAwMCkgJSA2MDtcbiAgICBzZWNvbmRzID0gTWF0aC5mbG9vcihzZWNvbmRzKTtcbiAgICBtaWxsaXNlY29uZHMgPSBwcm9ncmVzcyAlIDEwMDA7XG4gICAgcmV0dXJuIHV0aWxpdGllcy50b0ZpeGVkRGlnaXRzKGhvdXJzLCAyKSArICc6JyArIHV0aWxpdGllcy50b0ZpeGVkRGlnaXRzKG1pbnV0ZXMsIDIpICsgJzonICsgdXRpbGl0aWVzLnRvRml4ZWREaWdpdHMoc2Vjb25kcywgMikgKyAnLicgKyB1dGlsaXRpZXMudG9GaXhlZERpZ2l0cyhtaWxsaXNlY29uZHMsIDMpO1xuICB9LFxuXG4gIHBhcnNlT2Zmc2V0OiAgIGZ1bmN0aW9uIHBhcnNlT2Zmc2V0KG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICBpZihpc1BlcmNlbnRhZ2Uob2Zmc2V0KSl7XG4gICAgICByZXR1cm4gY2FsY3VsYXRlUGVyY2VudGFnZShvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhc3RVdGlsLnBhcnNlRHVyYXRpb24ob2Zmc2V0KTtcblxuICAgIC8qKiogTG9jYWwgZnVuY3Rpb24gKioqL1xuICAgIGZ1bmN0aW9uIGlzUGVyY2VudGFnZShvZmZzZXQpIHtcbiAgICAgIHZhciBwZXJjZW50YWdlUmVnZXggPSAvXlxcZCsoXFwuXFxkKyk/JSQvZztcbiAgICAgIHJldHVybiBwZXJjZW50YWdlUmVnZXgudGVzdChvZmZzZXQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNhbGN1bGF0ZVBlcmNlbnRhZ2UocGVyY2VudFN0ciwgZHVyYXRpb24pIHtcbiAgICAgIGlmKGR1cmF0aW9uKSB7XG4gICAgICAgIHJldHVybiBjYWxjUGVyY2VudChkdXJhdGlvbiwgcGFyc2VGbG9hdChwZXJjZW50U3RyLnJlcGxhY2UoJyUnLCAnJykpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNhbGNQZXJjZW50KHF1YW50aXR5LCBwZXJjZW50KXtcbiAgICAgIHJldHVybiBxdWFudGl0eSAqIHBlcmNlbnQgLyAxMDA7XG4gICAgfVxuICB9LFxuXG4gIGlzVlBBSUQ6IGZ1bmN0aW9uIGlzVlBBSURNZWRpYUZpbGUobWVkaWFGaWxlKSB7XG4gICAgcmV0dXJuICEhbWVkaWFGaWxlICYmIG1lZGlhRmlsZS5hcGlGcmFtZXdvcmsgPT09ICdWUEFJRCc7XG4gIH1cbn07XG5cblxubW9kdWxlLmV4cG9ydHMgPSB2YXN0VXRpbDsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBWQVNURXJyb3IgPSByZXF1aXJlKCcuLi92YXN0L1ZBU1RFcnJvcicpO1xuXG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucycpO1xuXG5mdW5jdGlvbiBWUEFJREFkVW5pdFdyYXBwZXIodnBhaWRBZFVuaXQsIG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFZQQUlEQWRVbml0V3JhcHBlcikpIHtcbiAgICByZXR1cm4gbmV3IFZQQUlEQWRVbml0V3JhcHBlcih2cGFpZEFkVW5pdCwgb3B0cyk7XG4gIH1cbiAgc2FuaXR5Q2hlY2sodnBhaWRBZFVuaXQsIG9wdHMpO1xuXG4gIHRoaXMub3B0aW9ucyA9IHV0aWxpdGllcy5leHRlbmQoe30sIG9wdHMpO1xuXG4gIHRoaXMuX2FkVW5pdCA9IHZwYWlkQWRVbml0O1xuXG4gIC8qKiogTG9jYWwgRnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gc2FuaXR5Q2hlY2soYWRVbml0LCBvcHRzKSB7XG4gICAgaWYgKCFhZFVuaXQgfHwgIVZQQUlEQWRVbml0V3JhcHBlci5jaGVja1ZQQUlESW50ZXJmYWNlKGFkVW5pdCkpIHtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoJ29uIFZQQUlEQWRVbml0V3JhcHBlciwgdGhlIHBhc3NlZCBWUEFJRCBhZFVuaXQgZG9lcyBub3QgZnVsbHkgaW1wbGVtZW50IHRoZSBWUEFJRCBpbnRlcmZhY2UnKTtcbiAgICB9XG5cbiAgICBpZiAoIXV0aWxpdGllcy5pc09iamVjdChvcHRzKSkge1xuICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcihcIm9uIFZQQUlEQWRVbml0V3JhcHBlciwgZXhwZWN0ZWQgb3B0aW9ucyBoYXNoICBidXQgZ290ICdcIiArIG9wdHMgKyBcIidcIik7XG4gICAgfVxuXG4gICAgaWYgKCEoXCJyZXNwb25zZVRpbWVvdXRcIiBpbiBvcHRzKSB8fCAhdXRpbGl0aWVzLmlzTnVtYmVyKG9wdHMucmVzcG9uc2VUaW1lb3V0KSApe1xuICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcihcIm9uIFZQQUlEQWRVbml0V3JhcHBlciwgZXhwZWN0ZWQgcmVzcG9uc2VUaW1lb3V0IGluIG9wdGlvbnNcIik7XG4gICAgfVxuICB9XG59XG5cblZQQUlEQWRVbml0V3JhcHBlci5jaGVja1ZQQUlESW50ZXJmYWNlID0gZnVuY3Rpb24gY2hlY2tWUEFJREludGVyZmFjZShWUEFJREFkVW5pdCkge1xuICAvL05PVEU6IHNraXBBZCBpcyBub3QgcGFydCBvZiB0aGUgbWV0aG9kIGxpc3QgYmVjYXVzZSBpdCBvbmx5IGFwcGVhcnMgaW4gVlBBSUQgMi4wIGFuZCB3ZSBzdXBwb3J0IFZQQUlEIDEuMFxuICB2YXIgVlBBSURJbnRlcmZhY2VNZXRob2RzID0gW1xuICAgICdoYW5kc2hha2VWZXJzaW9uJywgJ2luaXRBZCcsICdzdGFydEFkJywgJ3N0b3BBZCcsICdyZXNpemVBZCcsICdwYXVzZUFkJywgJ2V4cGFuZEFkJywgJ2NvbGxhcHNlQWQnXG4gIF07XG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IFZQQUlESW50ZXJmYWNlTWV0aG9kcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmICghVlBBSURBZFVuaXQgfHwgIXV0aWxpdGllcy5pc0Z1bmN0aW9uKFZQQUlEQWRVbml0W1ZQQUlESW50ZXJmYWNlTWV0aG9kc1tpXV0pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cblxuICByZXR1cm4gY2FuU3Vic2NyaWJlVG9FdmVudHMoVlBBSURBZFVuaXQpICYmIGNhblVuc3Vic2NyaWJlRnJvbUV2ZW50cyhWUEFJREFkVW5pdCk7XG5cbiAgLyoqKiBMb2NhbCBGdW5jdGlvbnMgKioqL1xuXG4gIGZ1bmN0aW9uIGNhblN1YnNjcmliZVRvRXZlbnRzKGFkVW5pdCkge1xuICAgIHJldHVybiB1dGlsaXRpZXMuaXNGdW5jdGlvbihhZFVuaXQuc3Vic2NyaWJlKSB8fCB1dGlsaXRpZXMuaXNGdW5jdGlvbihhZFVuaXQuYWRkRXZlbnRMaXN0ZW5lcikgfHwgdXRpbGl0aWVzLmlzRnVuY3Rpb24oYWRVbml0Lm9uKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNhblVuc3Vic2NyaWJlRnJvbUV2ZW50cyhhZFVuaXQpIHtcbiAgICByZXR1cm4gdXRpbGl0aWVzLmlzRnVuY3Rpb24oYWRVbml0LnVuc3Vic2NyaWJlKSB8fCB1dGlsaXRpZXMuaXNGdW5jdGlvbihhZFVuaXQucmVtb3ZlRXZlbnRMaXN0ZW5lcikgfHwgdXRpbGl0aWVzLmlzRnVuY3Rpb24oYWRVbml0Lm9mZik7XG5cbiAgfVxufTtcblxuVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZS5hZFVuaXRBc3luY0NhbGwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBhcmdzID0gdXRpbGl0aWVzLmFycmF5TGlrZU9ialRvQXJyYXkoYXJndW1lbnRzKTtcbiAgdmFyIG1ldGhvZCA9IGFyZ3Muc2hpZnQoKTtcbiAgdmFyIGNiID0gYXJncy5wb3AoKTtcbiAgdmFyIHRpbWVvdXRJZDtcblxuICBzYW5pdHlDaGVjayhtZXRob2QsIGNiLCB0aGlzLl9hZFVuaXQpO1xuICBhcmdzLnB1c2god3JhcENhbGxiYWNrKCkpO1xuXG4gIHRoaXMuX2FkVW5pdFttZXRob2RdLmFwcGx5KHRoaXMuX2FkVW5pdCwgYXJncyk7XG4gIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIHRpbWVvdXRJZCA9IG51bGw7XG4gICAgY2IobmV3IFZBU1RFcnJvcihcIm9uIFZQQUlEQWRVbml0V3JhcHBlciwgdGltZW91dCB3aGlsZSB3YWl0aW5nIGZvciBhIHJlc3BvbnNlIG9uIGNhbGwgJ1wiICsgbWV0aG9kICsgXCInXCIpKTtcbiAgICBjYiA9IHV0aWxpdGllcy5ub29wO1xuICB9LCB0aGlzLm9wdGlvbnMucmVzcG9uc2VUaW1lb3V0KTtcblxuICAvKioqIExvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIHNhbml0eUNoZWNrKG1ldGhvZCwgY2IsIGFkVW5pdCkge1xuICAgIGlmICghdXRpbGl0aWVzLmlzU3RyaW5nKG1ldGhvZCkgfHwgIXV0aWxpdGllcy5pc0Z1bmN0aW9uKGFkVW5pdFttZXRob2RdKSkge1xuICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcihcIm9uIFZQQUlEQWRVbml0V3JhcHBlci5hZFVuaXRBc3luY0NhbGwsIGludmFsaWQgbWV0aG9kIG5hbWVcIik7XG4gICAgfVxuXG4gICAgaWYgKCF1dGlsaXRpZXMuaXNGdW5jdGlvbihjYikpIHtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoXCJvbiBWUEFJREFkVW5pdFdyYXBwZXIuYWRVbml0QXN5bmNDYWxsLCBtaXNzaW5nIGNhbGxiYWNrXCIpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHdyYXBDYWxsYmFjaygpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHRpbWVvdXRJZCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgIH1cbiAgICAgIGNiLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfTtcbiAgfVxufTtcblxuVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldnROYW1lLCBoYW5kbGVyKSB7XG4gIHZhciBhZGRFdmVudExpc3RlbmVyID0gdGhpcy5fYWRVbml0LmFkZEV2ZW50TGlzdGVuZXIgfHwgdGhpcy5fYWRVbml0LnN1YnNjcmliZSB8fCB0aGlzLl9hZFVuaXQub247XG4gIGFkZEV2ZW50TGlzdGVuZXIuY2FsbCh0aGlzLl9hZFVuaXQsIGV2dE5hbWUsIGhhbmRsZXIpO1xufTtcblxuVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbiAoZXZ0TmFtZSwgaGFuZGxlcikge1xuICB2YXIgcmVtb3ZlRXZlbnRMaXN0ZW5lciA9IHRoaXMuX2FkVW5pdC5yZW1vdmVFdmVudExpc3RlbmVyIHx8IHRoaXMuX2FkVW5pdC51bnN1YnNjcmliZSB8fCB0aGlzLl9hZFVuaXQub2ZmO1xuICByZW1vdmVFdmVudExpc3RlbmVyLmNhbGwodGhpcy5fYWRVbml0LCBldnROYW1lLCBoYW5kbGVyKTtcbn07XG5cblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUud2FpdEZvckV2ZW50ID0gZnVuY3Rpb24gKGV2dE5hbWUsIGNiLCBjb250ZXh0KSB7XG4gIHZhciB0aW1lb3V0SWQ7XG4gIHNhbml0eUNoZWNrKGV2dE5hbWUsIGNiKTtcbiAgY29udGV4dCA9IGNvbnRleHQgfHwgbnVsbDtcblxuICB0aGlzLm9uKGV2dE5hbWUsIHJlc3BvbnNlTGlzdGVuZXIpO1xuXG4gIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIGNiKG5ldyBWQVNURXJyb3IoXCJvbiBWUEFJREFkVW5pdFdyYXBwZXIud2FpdEZvckV2ZW50LCB0aW1lb3V0IHdoaWxlIHdhaXRpbmcgZm9yIGV2ZW50ICdcIiArIGV2dE5hbWUgKyBcIidcIikpO1xuICAgIHRpbWVvdXRJZCA9IG51bGw7XG4gICAgY2IgPSB1dGlsaXRpZXMubm9vcDtcbiAgfSwgdGhpcy5vcHRpb25zLnJlc3BvbnNlVGltZW91dCk7XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBzYW5pdHlDaGVjayhldnROYW1lLCBjYikge1xuICAgIGlmICghdXRpbGl0aWVzLmlzU3RyaW5nKGV2dE5hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFwib24gVlBBSURBZFVuaXRXcmFwcGVyLndhaXRGb3JFdmVudCwgbWlzc2luZyBldnQgbmFtZVwiKTtcbiAgICB9XG5cbiAgICBpZiAoIXV0aWxpdGllcy5pc0Z1bmN0aW9uKGNiKSkge1xuICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcihcIm9uIFZQQUlEQWRVbml0V3JhcHBlci53YWl0Rm9yRXZlbnQsIG1pc3NpbmcgY2FsbGJhY2tcIik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVzcG9uc2VMaXN0ZW5lcigpIHtcbiAgICB2YXIgYXJncyA9IHV0aWxpdGllcy5hcnJheUxpa2VPYmpUb0FycmF5KGFyZ3VtZW50cyk7XG5cbiAgICBpZiAodGltZW91dElkKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgIHRpbWVvdXRJZCA9IG51bGw7XG4gICAgfVxuXG4gICAgYXJncy51bnNoaWZ0KG51bGwpO1xuICAgIGNiLmFwcGx5KGNvbnRleHQsIGFyZ3MpO1xuICB9XG59O1xuXG4vLyBWUEFJRCBNRVRIT0RTXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLmhhbmRzaGFrZVZlcnNpb24gPSBmdW5jdGlvbiAodmVyc2lvbiwgY2IpIHtcbiAgdGhpcy5hZFVuaXRBc3luY0NhbGwoJ2hhbmRzaGFrZVZlcnNpb24nLCB2ZXJzaW9uLCBjYik7XG59O1xuXG4vKiBqc2hpbnQgbWF4cGFyYW1zOjYgKi9cblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUuaW5pdEFkID0gZnVuY3Rpb24gKHdpZHRoLCBoZWlnaHQsIHZpZXdNb2RlLCBkZXNpcmVkQml0cmF0ZSwgYWRVbml0RGF0YSwgY2IpIHtcbiAgdGhpcy53YWl0Rm9yRXZlbnQoJ0FkTG9hZGVkJywgY2IpO1xuICB0aGlzLl9hZFVuaXQuaW5pdEFkKHdpZHRoLCBoZWlnaHQsIHZpZXdNb2RlLCBkZXNpcmVkQml0cmF0ZSwgYWRVbml0RGF0YSk7XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLnJlc2l6ZUFkID0gZnVuY3Rpb24gKHdpZHRoLCBoZWlnaHQsIHZpZXdNb2RlLCBjYikge1xuICAvLyBOT1RFOiBBZFNpemVDaGFuZ2UgZXZlbnQgaXMgb25seSBzdXBwb3J0ZWQgb24gVlBBSUQgMi4wIHNvIGZvciB0aGUgbW9tZW50IHdlIGFyZSBub3QgZ29pbmcgdG8gdXNlIGl0XG4gIC8vIGFuZCB3aWxsIGFzc3VtZSB0aGF0IGV2ZXJ5dGhpbmcgaXMgZmluZSBhZnRlciB0aGUgYXN5bmMgY2FsbFxuICB0aGlzLmFkVW5pdEFzeW5jQ2FsbCgncmVzaXplQWQnLCB3aWR0aCwgaGVpZ2h0LCB2aWV3TW9kZSwgY2IpO1xufTtcblxuVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZS5zdGFydEFkID0gZnVuY3Rpb24gKGNiKSB7XG4gIHRoaXMud2FpdEZvckV2ZW50KCdBZFN0YXJ0ZWQnLCBjYik7XG4gIHRoaXMuX2FkVW5pdC5zdGFydEFkKCk7XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLnN0b3BBZCA9IGZ1bmN0aW9uIChjYikge1xuICB0aGlzLndhaXRGb3JFdmVudCgnQWRTdG9wcGVkJywgY2IpO1xuICB0aGlzLl9hZFVuaXQuc3RvcEFkKCk7XG59O1xuXG5WUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlLnBhdXNlQWQgPSBmdW5jdGlvbiAoY2IpIHtcbiAgdGhpcy53YWl0Rm9yRXZlbnQoJ0FkUGF1c2VkJywgY2IpO1xuICB0aGlzLl9hZFVuaXQucGF1c2VBZCgpO1xufTtcblxuVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZS5yZXN1bWVBZCA9IGZ1bmN0aW9uIChjYikge1xuICB0aGlzLndhaXRGb3JFdmVudCgnQWRQbGF5aW5nJywgY2IpO1xuICB0aGlzLl9hZFVuaXQucmVzdW1lQWQoKTtcbn07XG5cblZQQUlEQWRVbml0V3JhcHBlci5wcm90b3R5cGUuZXhwYW5kQWQgPSBmdW5jdGlvbiAoY2IpIHtcbiAgdGhpcy53YWl0Rm9yRXZlbnQoJ0FkRXhwYW5kZWRDaGFuZ2UnLCBjYik7XG4gIHRoaXMuX2FkVW5pdC5leHBhbmRBZCgpO1xufTtcblxuVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZS5jb2xsYXBzZUFkID0gZnVuY3Rpb24gKGNiKSB7XG4gIHRoaXMud2FpdEZvckV2ZW50KCdBZEV4cGFuZGVkQ2hhbmdlJywgY2IpO1xuICB0aGlzLl9hZFVuaXQuY29sbGFwc2VBZCgpO1xufTtcblxuVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZS5za2lwQWQgPSBmdW5jdGlvbiAoY2IpIHtcbiAgdGhpcy53YWl0Rm9yRXZlbnQoJ0FkU2tpcHBlZCcsIGNiKTtcbiAgdGhpcy5fYWRVbml0LnNraXBBZCgpO1xufTtcblxuLy9WUEFJRCBwcm9wZXJ0eSBnZXR0ZXJzXG5bXG4gICdhZExpbmVhcicsXG4gICdhZFdpZHRoJyxcbiAgJ2FkSGVpZ2h0JyxcbiAgJ2FkRXhwYW5kZWQnLFxuICAnYWRTa2lwcGFibGVTdGF0ZScsXG4gICdhZFJlbWFpbmluZ1RpbWUnLFxuICAnYWREdXJhdGlvbicsXG4gICdhZFZvbHVtZScsXG4gICdhZENvbXBhbmlvbnMnLFxuICAnYWRJY29ucydcbl0uZm9yRWFjaChmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgdmFyIGdldHRlck5hbWUgPSAnZ2V0JyArIHV0aWxpdGllcy5jYXBpdGFsaXplKHByb3BlcnR5KTtcblxuICBWUEFJREFkVW5pdFdyYXBwZXIucHJvdG90eXBlW2dldHRlck5hbWVdID0gZnVuY3Rpb24gKGNiKSB7XG4gICAgdGhpcy5hZFVuaXRBc3luY0NhbGwoZ2V0dGVyTmFtZSwgY2IpO1xuICB9O1xufSk7XG5cbi8vVlBBSUQgcHJvcGVydHkgc2V0dGVyc1xuVlBBSURBZFVuaXRXcmFwcGVyLnByb3RvdHlwZS5zZXRBZFZvbHVtZSA9IGZ1bmN0aW9uKHZvbHVtZSwgY2Ipe1xuICB0aGlzLmFkVW5pdEFzeW5jQ2FsbCgnc2V0QWRWb2x1bWUnLHZvbHVtZSwgY2IpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBWUEFJREFkVW5pdFdyYXBwZXI7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBWQVNURXJyb3IgPSByZXF1aXJlKCcuLi92YXN0L1ZBU1RFcnJvcicpO1xuXG52YXIgVlBBSURGTEFTSENsaWVudCA9IHJlcXVpcmUoJ1ZQQUlERkxBU0hDbGllbnQvanMvVlBBSURGTEFTSENsaWVudCcpO1xuXG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbGl0eUZ1bmN0aW9ucycpO1xudmFyIGRvbSA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL2RvbScpO1xuXG5mdW5jdGlvbiBWUEFJREZsYXNoVGVjaChtZWRpYUZpbGUsIHNldHRpbmdzKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBWUEFJREZsYXNoVGVjaCkpIHtcbiAgICByZXR1cm4gbmV3IFZQQUlERmxhc2hUZWNoKG1lZGlhRmlsZSk7XG4gIH1cbiAgc2FuaXR5Q2hlY2sobWVkaWFGaWxlKTtcbiAgdGhpcy5uYW1lID0gJ3ZwYWlkLWZsYXNoJztcbiAgdGhpcy5tZWRpYUZpbGUgPSBtZWRpYUZpbGU7XG4gIHRoaXMuY29udGFpbmVyRWwgPSBudWxsO1xuICB0aGlzLnZwYWlkRmxhc2hDbGllbnQgPSBudWxsO1xuICB0aGlzLnNldHRpbmdzID0gc2V0dGluZ3M7XG5cbiAgLyoqKiBsb2NhbCBmdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBzYW5pdHlDaGVjayhtZWRpYUZpbGUpIHtcbiAgICBpZiAoIW1lZGlhRmlsZSB8fCAhdXRpbGl0aWVzLmlzU3RyaW5nKG1lZGlhRmlsZS5zcmMpKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKCdvbiBWUEFJREZsYXNoVGVjaCwgaW52YWxpZCBNZWRpYUZpbGUnKTtcbiAgICB9XG4gIH1cbn1cblxuVlBBSURGbGFzaFRlY2guVlBBSURGTEFTSENsaWVudCA9IFZQQUlERkxBU0hDbGllbnQ7XG5cblZQQUlERmxhc2hUZWNoLnN1cHBvcnRzID0gZnVuY3Rpb24gKHR5cGUpIHtcbiAgcmV0dXJuIHR5cGUgPT09ICdhcHBsaWNhdGlvbi94LXNob2Nrd2F2ZS1mbGFzaCcgJiYgVlBBSURGbGFzaFRlY2guVlBBSURGTEFTSENsaWVudC5pc1N1cHBvcnRlZCgpO1xufTtcblxuVlBBSURGbGFzaFRlY2gucHJvdG90eXBlLmxvYWRBZFVuaXQgPSBmdW5jdGlvbiBsb2FkRmxhc2hDcmVhdGl2ZShjb250YWluZXJFbCwgb2JqZWN0RWwsIGNhbGxiYWNrKSB7XG4gIHZhciB0aGF0ID0gdGhpcztcbiAgdmFyIGZsYXNoQ2xpZW50T3B0cyA9IHRoaXMuc2V0dGluZ3MgJiYgdGhpcy5zZXR0aW5ncy52cGFpZEZsYXNoTG9hZGVyUGF0aCA/IHtkYXRhOiB0aGlzLnNldHRpbmdzLnZwYWlkRmxhc2hMb2FkZXJQYXRofSA6IHVuZGVmaW5lZDtcbiAgc2FuaXR5Q2hlY2soY29udGFpbmVyRWwsIGNhbGxiYWNrKTtcblxuICB0aGlzLmNvbnRhaW5lckVsID0gY29udGFpbmVyRWw7XG4gIHRoaXMudnBhaWRGbGFzaENsaWVudCA9IG5ldyBWUEFJREZsYXNoVGVjaC5WUEFJREZMQVNIQ2xpZW50KGNvbnRhaW5lckVsLCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IpIHtcbiAgICAgIHJldHVybiBjYWxsYmFjayhlcnJvcik7XG4gICAgfVxuXG4gICAgdGhhdC52cGFpZEZsYXNoQ2xpZW50LmxvYWRBZFVuaXQodGhhdC5tZWRpYUZpbGUuc3JjLCBjYWxsYmFjayk7XG4gIH0sIGZsYXNoQ2xpZW50T3B0cyk7XG5cbiAgLyoqKiBMb2NhbCBGdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBzYW5pdHlDaGVjayhjb250YWluZXIsIGNiKSB7XG5cbiAgICBpZiAoIWRvbS5pc0RvbUVsZW1lbnQoY29udGFpbmVyKSkge1xuICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcignb24gVlBBSURGbGFzaFRlY2gubG9hZEFkVW5pdCwgaW52YWxpZCBkb20gY29udGFpbmVyIGVsZW1lbnQnKTtcbiAgICB9XG5cbiAgICBpZiAoIXV0aWxpdGllcy5pc0Z1bmN0aW9uKGNiKSkge1xuICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcignb24gVlBBSURGbGFzaFRlY2gubG9hZEFkVW5pdCwgbWlzc2luZyB2YWxpZCBjYWxsYmFjaycpO1xuICAgIH1cbiAgfVxufTtcblxuVlBBSURGbGFzaFRlY2gucHJvdG90eXBlLnVubG9hZEFkVW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMudnBhaWRGbGFzaENsaWVudCkge1xuICAgIHRyeXtcbiAgICAgIHRoaXMudnBhaWRGbGFzaENsaWVudC5kZXN0cm95KCk7XG4gICAgfSBjYXRjaChlKXtcbiAgICAgIGlmKGNvbnNvbGUgJiYgdXRpbGl0aWVzLmlzRnVuY3Rpb24oY29uc29sZS5sb2cpKXtcbiAgICAgICAgY29uc29sZS5sb2coJ1ZBU1QgRVJST1I6IHRyeWluZyB0byB1bmxvYWQgdGhlIFZQQUlEIGFkdW5pdCcpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnZwYWlkRmxhc2hDbGllbnQgPSBudWxsO1xuICB9XG5cbiAgaWYgKHRoaXMuY29udGFpbmVyRWwpIHtcbiAgICBkb20ucmVtb3ZlKHRoaXMuY29udGFpbmVyRWwpO1xuICAgIHRoaXMuY29udGFpbmVyRWwgPSBudWxsO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZQQUlERmxhc2hUZWNoOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIFZBU1RFcnJvciA9IHJlcXVpcmUoJy4uL3Zhc3QvVkFTVEVycm9yJyk7XG5cbnZhciBWUEFJREhUTUw1Q2xpZW50ID0gcmVxdWlyZSgnVlBBSURIVE1MNUNsaWVudC9qcy9WUEFJREhUTUw1Q2xpZW50Jyk7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi8uLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG52YXIgZG9tID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvZG9tJyk7XG5cbmZ1bmN0aW9uIFZQQUlESFRNTDVUZWNoKG1lZGlhRmlsZSkge1xuXG4gIGlmKCEodGhpcyBpbnN0YW5jZW9mIFZQQUlESFRNTDVUZWNoKSkge1xuICAgIHJldHVybiBuZXcgVlBBSURIVE1MNVRlY2gobWVkaWFGaWxlKTtcbiAgfVxuXG4gIHNhbml0eUNoZWNrKG1lZGlhRmlsZSk7XG5cbiAgdGhpcy5uYW1lID0gJ3ZwYWlkLWh0bWw1JztcbiAgdGhpcy5jb250YWluZXJFbCA9IG51bGw7XG4gIHRoaXMudmlkZW9FbCA9IG51bGw7XG4gIHRoaXMudnBhaWRIVE1MQ2xpZW50ID0gbnVsbDtcblxuICB0aGlzLm1lZGlhRmlsZSA9IG1lZGlhRmlsZTtcblxuICBmdW5jdGlvbiBzYW5pdHlDaGVjayhtZWRpYUZpbGUpIHtcbiAgICAgIGlmICghbWVkaWFGaWxlIHx8ICF1dGlsaXRpZXMuaXNTdHJpbmcobWVkaWFGaWxlLnNyYykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcihWUEFJREhUTUw1VGVjaC5JTlZBTElEX01FRElBX0ZJTEUpO1xuICAgICAgfVxuICB9XG59XG5cblZQQUlESFRNTDVUZWNoLlZQQUlESFRNTDVDbGllbnQgPSBWUEFJREhUTUw1Q2xpZW50O1xuXG5WUEFJREhUTUw1VGVjaC5zdXBwb3J0cyA9IGZ1bmN0aW9uICh0eXBlKSB7XG4gIHJldHVybiAhdXRpbGl0aWVzLmlzT2xkSUUoKSAmJiB0eXBlID09PSAnYXBwbGljYXRpb24vamF2YXNjcmlwdCc7XG59O1xuXG5WUEFJREhUTUw1VGVjaC5wcm90b3R5cGUubG9hZEFkVW5pdCA9IGZ1bmN0aW9uIGxvYWRBZFVuaXQoY29udGFpbmVyRWwsIHZpZGVvRWwsIGNhbGxiYWNrKSB7XG4gIHNhbml0eUNoZWNrKGNvbnRhaW5lckVsLCB2aWRlb0VsLCBjYWxsYmFjayk7XG5cbiAgdGhpcy5jb250YWluZXJFbCA9IGNvbnRhaW5lckVsO1xuICB0aGlzLnZpZGVvRWwgPSB2aWRlb0VsO1xuICB0aGlzLnZwYWlkSFRNTENsaWVudCA9IG5ldyBWUEFJREhUTUw1VGVjaC5WUEFJREhUTUw1Q2xpZW50KGNvbnRhaW5lckVsLCB2aWRlb0VsLCB7fSk7XG4gIHRoaXMudnBhaWRIVE1MQ2xpZW50LmxvYWRBZFVuaXQodGhpcy5tZWRpYUZpbGUuc3JjLCBjYWxsYmFjayk7XG5cbiAgZnVuY3Rpb24gc2FuaXR5Q2hlY2soY29udGFpbmVyLCB2aWRlbywgY2IpIHtcbiAgICBpZiAoIWRvbS5pc0RvbUVsZW1lbnQoY29udGFpbmVyKSkge1xuICAgICAgdGhyb3cgbmV3IFZBU1RFcnJvcihWUEFJREhUTUw1VGVjaC5JTlZBTElEX0RPTV9DT05UQUlORVJfRUwpO1xuICAgIH1cblxuICAgIGlmICghZG9tLmlzRG9tRWxlbWVudCh2aWRlbykgfHwgdmlkZW8udGFnTmFtZS50b0xvd2VyQ2FzZSgpICE9PSAndmlkZW8nKSB7XG4gICAgICB0aHJvdyBuZXcgVkFTVEVycm9yKFZQQUlESFRNTDVUZWNoLklOVkFMSURfRE9NX0NPTlRBSU5FUl9FTCk7XG4gICAgfVxuXG4gICAgaWYgKCF1dGlsaXRpZXMuaXNGdW5jdGlvbihjYikpIHtcbiAgICAgIHRocm93IG5ldyBWQVNURXJyb3IoVlBBSURIVE1MNVRlY2guTUlTU0lOR19DQUxMQkFDSyk7XG4gICAgfVxuICB9XG59O1xuXG5WUEFJREhUTUw1VGVjaC5wcm90b3R5cGUudW5sb2FkQWRVbml0ID0gZnVuY3Rpb24gdW5sb2FkQWRVbml0KCkge1xuICBpZiAodGhpcy52cGFpZEhUTUxDbGllbnQpIHtcbiAgICB0cnkge1xuICAgICAgdGhpcy52cGFpZEhUTUxDbGllbnQuZGVzdHJveSgpO1xuICAgIH0gY2F0Y2goZSkge1xuICAgICAgaWYgKGNvbnNvbGUgJiYgdXRpbGl0aWVzLmlzRnVuY3Rpb24oY29uc29sZS5sb2cpKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdWQVNUIEVSUk9SOiB0cnlpbmcgdG8gdW5sb2FkIHRoZSBWUEFJRCBhZHVuaXQnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnZwYWlkSFRNTENsaWVudCA9IG51bGw7XG4gIH1cblxuICBpZiAodGhpcy5jb250YWluZXJFbCkge1xuICAgIGRvbS5yZW1vdmUodGhpcy5jb250YWluZXJFbCk7XG4gICAgdGhpcy5jb250YWluZXJFbCA9IG51bGw7XG4gIH1cbn07XG5cbnZhciBQUkVGSVggPSAnb24gVlBBSURIVE1MNVRlY2gnO1xuVlBBSURIVE1MNVRlY2guSU5WQUxJRF9NRURJQV9GSUxFID0gUFJFRklYICsgJywgaW52YWxpZCBNZWRpYUZpbGUnO1xuVlBBSURIVE1MNVRlY2guSU5WQUxJRF9ET01fQ09OVEFJTkVSX0VMID0gUFJFRklYICsgJywgaW52YWxpZCBjb250YWluZXIgSHRtbEVsZW1lbnQnO1xuVlBBSURIVE1MNVRlY2guSU5WQUxJRF9ET01fVklERU9fRUwgPSBQUkVGSVggKyAnLCBpbnZhbGlkIEhUTUxWaWRlb0VsZW1lbnQnO1xuVlBBSURIVE1MNVRlY2guTUlTU0lOR19DQUxMQkFDSyA9IFBSRUZJWCArICcsIG1pc3NpbmcgdmFsaWQgY2FsbGJhY2snO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZQQUlESFRNTDVUZWNoOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIFZBU1RFcnJvciA9IHJlcXVpcmUoJy4uL3Zhc3QvVkFTVEVycm9yJyk7XG52YXIgVkFTVFJlc3BvbnNlID0gcmVxdWlyZSgnLi4vdmFzdC9WQVNUUmVzcG9uc2UnKTtcbnZhciBWQVNUVHJhY2tlciA9IHJlcXVpcmUoJy4uL3Zhc3QvVkFTVFRyYWNrZXInKTtcbnZhciB2YXN0VXRpbCA9IHJlcXVpcmUoJy4uL3Zhc3QvdmFzdFV0aWwnKTtcblxudmFyIFZQQUlEQWRVbml0V3JhcHBlciA9IHJlcXVpcmUoJy4vVlBBSURBZFVuaXRXcmFwcGVyJyk7XG52YXIgVlBBSURIVE1MNVRlY2ggPSByZXF1aXJlKCcuL1ZQQUlESFRNTDVUZWNoJyk7XG52YXIgVlBBSURGbGFzaFRlY2ggPSByZXF1aXJlKCcuL1ZQQUlERmxhc2hUZWNoJyk7XG5cbnZhciBhc3luYyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL2FzeW5jJyk7XG52YXIgZG9tID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvZG9tJyk7XG52YXIgcGxheWVyVXRpbHMgPSByZXF1aXJlKCcuLi8uLi91dGlscy9wbGF5ZXJVdGlscycpO1xudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxuZnVuY3Rpb24gVlBBSURJbnRlZ3JhdG9yKHBsYXllciwgc2V0dGluZ3MpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFZQQUlESW50ZWdyYXRvcikpIHtcbiAgICByZXR1cm4gbmV3IFZQQUlESW50ZWdyYXRvcihwbGF5ZXIpO1xuICB9XG5cbiAgdGhpcy5WSUVXX01PREUgPSB7XG4gICAgTk9STUFMOiAnbm9ybWFsJyxcbiAgICBGVUxMU0NSRUVOOiBcImZ1bGxzY3JlZW5cIixcbiAgICBUSFVNQk5BSUw6IFwidGh1bWJuYWlsXCJcbiAgfTtcbiAgdGhpcy5wbGF5ZXIgPSBwbGF5ZXI7XG4gIHRoaXMuY29udGFpbmVyRWwgPSBjcmVhdGVWUEFJRENvbnRhaW5lckVsKHBsYXllcik7XG4gIHRoaXMub3B0aW9ucyA9IHtcbiAgICByZXNwb25zZVRpbWVvdXQ6IDUwMDAsXG4gICAgVlBBSURfVkVSU0lPTjogJzIuMCdcbiAgfTtcbiAgdGhpcy5zZXR0aW5ncyA9IHNldHRpbmdzO1xuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cblxuICBmdW5jdGlvbiBjcmVhdGVWUEFJRENvbnRhaW5lckVsKCkge1xuICAgIHZhciBjb250YWluZXJFbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRvbS5hZGRDbGFzcyhjb250YWluZXJFbCwgJ1ZQQUlELWNvbnRhaW5lcicpO1xuICAgIHBsYXllci5lbCgpLmluc2VydEJlZm9yZShjb250YWluZXJFbCwgcGxheWVyLmNvbnRyb2xCYXIuZWwoKSk7XG4gICAgcmV0dXJuIGNvbnRhaW5lckVsO1xuXG4gIH1cbn1cblxuLy9MaXN0IG9mIHN1cHBvcnRlZCBWUEFJRCB0ZWNobm9sb2dpZXNcblZQQUlESW50ZWdyYXRvci50ZWNocyA9IFtcbiAgVlBBSURGbGFzaFRlY2gsXG4gIFZQQUlESFRNTDVUZWNoXG5dO1xuXG5WUEFJREludGVncmF0b3IucHJvdG90eXBlLnBsYXlBZCA9IGZ1bmN0aW9uIHBsYXlWUGFpZEFkKHZhc3RSZXNwb25zZSwgY2FsbGJhY2spIHtcbiAgdmFyIHRoYXQgPSB0aGlzO1xuICB2YXIgdGVjaDtcbiAgdmFyIHBsYXllciA9IHRoaXMucGxheWVyO1xuXG4gIGNhbGxiYWNrID0gY2FsbGJhY2sgfHwgdXRpbGl0aWVzLm5vb3A7XG4gIGlmICghKHZhc3RSZXNwb25zZSBpbnN0YW5jZW9mIFZBU1RSZXNwb25zZSkpIHtcbiAgICByZXR1cm4gY2FsbGJhY2sobmV3IFZBU1RFcnJvcignb24gVkFTVEludGVncmF0b3IucGxheUFkLCBtaXNzaW5nIHJlcXVpcmVkIFZBU1RSZXNwb25zZScpKTtcbiAgfVxuXG4gIHRlY2ggPSB0aGlzLl9maW5kU3VwcG9ydGVkVGVjaCh2YXN0UmVzcG9uc2UsIHRoaXMuc2V0dGluZ3MpO1xuICBkb20uYWRkQ2xhc3MocGxheWVyLmVsKCksICd2anMtdnBhaWQtYWQnKTtcblxuICBwbGF5ZXIub24oJ3Zhc3QuYWRzQ2FuY2VsJywgdHJpZ2dlclZwYWlkQWRFbmQpO1xuICBwbGF5ZXIub25lKCd2cGFpZC5hZEVuZCcsIGZ1bmN0aW9uKCl7XG4gICAgcGxheWVyLm9mZigndmFzdC5hZHNDYW5jZWwnLCB0cmlnZ2VyVnBhaWRBZEVuZCk7XG4gICAgcmVtb3ZlQWRVbml0KCk7XG4gIH0pO1xuXG4gIGlmICh0ZWNoKSB7XG4gICAgYXN5bmMud2F0ZXJmYWxsKFtcbiAgICAgIGZ1bmN0aW9uIChuZXh0KSB7XG4gICAgICAgIG5leHQobnVsbCwgdGVjaCwgdmFzdFJlc3BvbnNlKTtcbiAgICAgIH0sXG4gICAgICB0aGlzLl9sb2FkQWRVbml0LmJpbmQodGhpcyksXG4gICAgICB0aGlzLl9wbGF5QWRVbml0LmJpbmQodGhpcyksXG4gICAgICB0aGlzLl9maW5pc2hQbGF5aW5nLmJpbmQodGhpcylcblxuICAgIF0sIGZ1bmN0aW9uIChlcnJvciwgYWRVbml0LCB2YXN0UmVzcG9uc2UpIHtcbiAgICAgIGlmIChlcnJvcikge1xuICAgICAgICB0aGF0Ll90cmFja0Vycm9yKHZhc3RSZXNwb25zZSk7XG4gICAgICB9XG4gICAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuYWRFbmQnKTtcbiAgICAgIGNhbGxiYWNrKGVycm9yLCB2YXN0UmVzcG9uc2UpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5fYWRVbml0ID0ge1xuICAgICAgX3BhdXNlZDogdHJ1ZSxcbiAgICAgIHR5cGU6ICdWUEFJRCcsXG4gICAgICBwYXVzZUFkOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLnBhdXNlQWQnKTtcbiAgICAgICAgcGxheWVyLnBhdXNlKHRydWUpOy8vd2UgbWFrZSBzdXJlIHRoYXQgdGhlIHZpZGVvIGNvbnRlbnQgZ2V0cyBzdG9wcGVkLlxuICAgICAgfSxcbiAgICAgIHJlc3VtZUFkOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQucmVzdW1lQWQnKTtcbiAgICAgIH0sXG4gICAgICBpc1BhdXNlZDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXVzZWQ7XG4gICAgICB9LFxuICAgICAgZ2V0U3JjOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRlY2gubWVkaWFGaWxlO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5fYWRVbml0O1xuICB9XG5cbiAgY2FsbGJhY2sobmV3IFZBU1RFcnJvcignb24gVlBBSURJbnRlZ3JhdG9yLnBsYXlBZCwgY291bGQgbm90IGZpbmQgYSBzdXBwb3J0ZWQgbWVkaWFGaWxlJykpO1xuXG4gIHJldHVybiBudWxsO1xuICAvKioqIExvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIHRyaWdnZXJWcGFpZEFkRW5kKCl7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLmFkRW5kJyk7XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVBZFVuaXQoKSB7XG4gICAgaWYgKHRlY2gpIHtcbiAgICAgIHRlY2gudW5sb2FkQWRVbml0KCk7XG4gICAgfVxuICAgIGRvbS5yZW1vdmVDbGFzcyhwbGF5ZXIuZWwoKSwgJ3Zqcy12cGFpZC1hZCcpO1xuICB9XG59O1xuXG5WUEFJREludGVncmF0b3IucHJvdG90eXBlLl9maW5kU3VwcG9ydGVkVGVjaCA9IGZ1bmN0aW9uICh2YXN0UmVzcG9uc2UsIHNldHRpbmdzKSB7XG4gIGlmICghKHZhc3RSZXNwb25zZSBpbnN0YW5jZW9mIFZBU1RSZXNwb25zZSkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciB2cGFpZE1lZGlhRmlsZXMgPSB2YXN0UmVzcG9uc2UubWVkaWFGaWxlcy5maWx0ZXIodmFzdFV0aWwuaXNWUEFJRCk7XG4gIHZhciBpLCBsZW4sIG1lZGlhRmlsZSwgVlBBSURUZWNoO1xuXG4gIGZvciAoaSA9IDAsIGxlbiA9IHZwYWlkTWVkaWFGaWxlcy5sZW5ndGg7IGkgPCBsZW47IGkgKz0gMSkge1xuICAgIG1lZGlhRmlsZSA9IHZwYWlkTWVkaWFGaWxlc1tpXTtcbiAgICBWUEFJRFRlY2ggPSBmaW5kU3VwcG9ydGVkVGVjaChtZWRpYUZpbGUpO1xuICAgIGlmIChWUEFJRFRlY2gpIHtcbiAgICAgIHJldHVybiBuZXcgVlBBSURUZWNoKG1lZGlhRmlsZSwgc2V0dGluZ3MpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcblxuICAvKioqIExvY2FsIGZ1bmN0aW9ucyAqKiovXG4gIGZ1bmN0aW9uIGZpbmRTdXBwb3J0ZWRUZWNoKG1lZGlhZmlsZSkge1xuICAgIHZhciB0eXBlID0gbWVkaWFmaWxlLnR5cGU7XG4gICAgdmFyIGksIGxlbiwgVlBBSURUZWNoO1xuICAgIGZvciAoaSA9IDAsIGxlbiA9IFZQQUlESW50ZWdyYXRvci50ZWNocy5sZW5ndGg7IGkgPCBsZW47IGkgKz0gMSkge1xuICAgICAgVlBBSURUZWNoID0gVlBBSURJbnRlZ3JhdG9yLnRlY2hzW2ldO1xuICAgICAgaWYgKFZQQUlEVGVjaC5zdXBwb3J0cyh0eXBlKSkge1xuICAgICAgICByZXR1cm4gVlBBSURUZWNoO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5fY3JlYXRlVlBBSURBZFVuaXRXcmFwcGVyID0gZnVuY3Rpb24oYWRVbml0LCBzcmMsIHJlc3BvbnNlVGltZW91dCkge1xuICByZXR1cm4gbmV3IFZQQUlEQWRVbml0V3JhcHBlcihhZFVuaXQsIHtzcmM6IHNyYywgcmVzcG9uc2VUaW1lb3V0OiByZXNwb25zZVRpbWVvdXR9KTtcbn07XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUuX2xvYWRBZFVuaXQgPSBmdW5jdGlvbiAodGVjaCwgdmFzdFJlc3BvbnNlLCBuZXh0KSB7XG4gIHZhciB0aGF0ID0gdGhpcztcbiAgdmFyIHBsYXllciA9IHRoaXMucGxheWVyO1xuICB2YXIgdmpzVGVjaEVsID0gcGxheWVyLmVsKCkucXVlcnlTZWxlY3RvcignLnZqcy10ZWNoJyk7XG4gIHZhciByZXNwb25zZVRpbWVvdXQgPSB0aGlzLnNldHRpbmdzLnJlc3BvbnNlVGltZW91dCB8fCB0aGlzLm9wdGlvbnMucmVzcG9uc2VUaW1lb3V0O1xuICB0ZWNoLmxvYWRBZFVuaXQodGhpcy5jb250YWluZXJFbCwgdmpzVGVjaEVsLCBmdW5jdGlvbiAoZXJyb3IsIGFkVW5pdCkge1xuICAgIGlmIChlcnJvcikge1xuICAgICAgcmV0dXJuIG5leHQoZXJyb3IsIGFkVW5pdCwgdmFzdFJlc3BvbnNlKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgdmFyIFdyYXBwZWRBZFVuaXQgPSB0aGF0Ll9jcmVhdGVWUEFJREFkVW5pdFdyYXBwZXIoYWRVbml0LCB0ZWNoLm1lZGlhRmlsZS5zcmMsIHJlc3BvbnNlVGltZW91dCk7XG4gICAgICB2YXIgdGVjaENsYXNzID0gJ3Zqcy0nICsgdGVjaC5uYW1lICsgJy1hZCc7XG4gICAgICBkb20uYWRkQ2xhc3MocGxheWVyLmVsKCksIHRlY2hDbGFzcyk7XG4gICAgICBwbGF5ZXIub25lKCd2cGFpZC5hZEVuZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgICBkb20ucmVtb3ZlQ2xhc3MocGxheWVyLmVsKCksdGVjaENsYXNzKTtcbiAgICAgIH0pO1xuICAgICAgbmV4dChudWxsLCBXcmFwcGVkQWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIG5leHQoZSwgYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuICAgIH1cbiAgfSk7XG59O1xuXG5WUEFJREludGVncmF0b3IucHJvdG90eXBlLl9wbGF5QWRVbml0ID0gZnVuY3Rpb24gKGFkVW5pdCwgdmFzdFJlc3BvbnNlLCBjYWxsYmFjaykge1xuICBhc3luYy53YXRlcmZhbGwoW1xuICAgIGZ1bmN0aW9uIChuZXh0KSB7XG4gICAgICBuZXh0KG51bGwsIGFkVW5pdCwgdmFzdFJlc3BvbnNlKTtcbiAgICB9LFxuICAgIHRoaXMuX2hhbmRzaGFrZS5iaW5kKHRoaXMpLFxuICAgIHRoaXMuX2luaXRBZC5iaW5kKHRoaXMpLFxuICAgIHRoaXMuX3NldHVwRXZlbnRzLmJpbmQodGhpcyksXG4gICAgdGhpcy5fYWRkU2tpcEJ1dHRvbi5iaW5kKHRoaXMpLFxuICAgIHRoaXMuX2xpbmtQbGF5ZXJDb250cm9scy5iaW5kKHRoaXMpLFxuICAgIHRoaXMuX3N0YXJ0QWQuYmluZCh0aGlzKVxuICBdLCBjYWxsYmFjayk7XG59O1xuXG5WUEFJREludGVncmF0b3IucHJvdG90eXBlLl9oYW5kc2hha2UgPSBmdW5jdGlvbiBoYW5kc2hha2UoYWRVbml0LCB2YXN0UmVzcG9uc2UsIG5leHQpIHtcbiAgYWRVbml0LmhhbmRzaGFrZVZlcnNpb24odGhpcy5vcHRpb25zLlZQQUlEX1ZFUlNJT04sIGZ1bmN0aW9uIChlcnJvciwgdmVyc2lvbikge1xuICAgIGlmIChlcnJvcikge1xuICAgICAgcmV0dXJuIG5leHQoZXJyb3IsIGFkVW5pdCwgdmFzdFJlc3BvbnNlKTtcbiAgICB9XG5cbiAgICBpZiAodmVyc2lvbiAmJiBpc1N1cHBvcnRlZFZlcnNpb24odmVyc2lvbikpIHtcbiAgICAgIHJldHVybiBuZXh0KG51bGwsIGFkVW5pdCwgdmFzdFJlc3BvbnNlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV4dChuZXcgVkFTVEVycm9yKCdvbiBWUEFJREludGVncmF0b3IuX2hhbmRzaGFrZSwgdW5zdXBwb3J0ZWQgdmVyc2lvbiBcIicgKyB2ZXJzaW9uICsgJ1wiJyksIGFkVW5pdCwgdmFzdFJlc3BvbnNlKTtcbiAgfSk7XG5cbiAgZnVuY3Rpb24gaXNTdXBwb3J0ZWRWZXJzaW9uKHZlcnNpb24pIHtcbiAgICB2YXIgbWFqb3JOdW0gPSBtYWpvcih2ZXJzaW9uKTtcbiAgICByZXR1cm4gbWFqb3JOdW0gPj0gMSAmJiBtYWpvck51bSA8PSAyO1xuICB9XG5cbiAgZnVuY3Rpb24gbWFqb3IodmVyc2lvbikge1xuICAgIHZhciBwYXJ0cyA9IHZlcnNpb24uc3BsaXQoJy4nKTtcbiAgICByZXR1cm4gcGFyc2VJbnQocGFydHNbMF0sIDEwKTtcbiAgfVxufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5faW5pdEFkID0gZnVuY3Rpb24gKGFkVW5pdCwgdmFzdFJlc3BvbnNlLCBuZXh0KSB7XG4gIHZhciB0ZWNoID0gdGhpcy5wbGF5ZXIuZWwoKS5xdWVyeVNlbGVjdG9yKCcudmpzLXRlY2gnKTtcbiAgdmFyIGRpbWVuc2lvbiA9IGRvbS5nZXREaW1lbnNpb24odGVjaCk7XG4gIGFkVW5pdC5pbml0QWQoZGltZW5zaW9uLndpZHRoLCBkaW1lbnNpb24uaGVpZ2h0LCB0aGlzLlZJRVdfTU9ERS5OT1JNQUwsIC0xLCB7QWRQYXJhbWV0ZXJzOiB2YXN0UmVzcG9uc2UuYWRQYXJhbWV0ZXJzIHx8ICcnfSwgZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgbmV4dChlcnJvciwgYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuICB9KTtcbn07XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUuX2NyZWF0ZVZBU1RUcmFja2VyID0gZnVuY3Rpb24oYWRVbml0U3JjLCB2YXN0UmVzcG9uc2UpIHtcbiAgcmV0dXJuIG5ldyBWQVNUVHJhY2tlcihhZFVuaXRTcmMsIHZhc3RSZXNwb25zZSk7XG59O1xuXG5WUEFJREludGVncmF0b3IucHJvdG90eXBlLl9zZXR1cEV2ZW50cyA9IGZ1bmN0aW9uIChhZFVuaXQsIHZhc3RSZXNwb25zZSwgbmV4dCkge1xuICB2YXIgYWRVbml0U3JjID0gYWRVbml0Lm9wdGlvbnMuc3JjO1xuICB2YXIgdHJhY2tlciA9IHRoaXMuX2NyZWF0ZVZBU1RUcmFja2VyKGFkVW5pdFNyYywgdmFzdFJlc3BvbnNlKTtcbiAgdmFyIHBsYXllciA9IHRoaXMucGxheWVyO1xuICB2YXIgdGhhdCA9IHRoaXM7XG5cbiAgYWRVbml0Lm9uKCdBZFNraXBwZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkU2tpcHBlZCcpO1xuICAgIHRyYWNrZXIudHJhY2tTa2lwKCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRJbXByZXNzaW9uJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZEltcHJlc3Npb24nKTtcbiAgICB0cmFja2VyLnRyYWNrSW1wcmVzc2lvbnMoKTtcbiAgfSk7XG5cbiAgYWRVbml0Lm9uKCdBZFN0YXJ0ZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkU3RhcnRlZCcpO1xuICAgIHRyYWNrZXIudHJhY2tDcmVhdGl2ZVZpZXcoKTtcbiAgICBub3RpZnlQbGF5VG9QbGF5ZXIoKTtcbiAgfSk7XG5cbiAgYWRVbml0Lm9uKCdBZFZpZGVvU3RhcnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkVmlkZW9TdGFydCcpO1xuICAgIHRyYWNrZXIudHJhY2tTdGFydCgpO1xuICAgIG5vdGlmeVBsYXlUb1BsYXllcigpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkUGxheWluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuQWRQbGF5aW5nJyk7XG4gICAgdHJhY2tlci50cmFja1Jlc3VtZSgpO1xuICAgIG5vdGlmeVBsYXlUb1BsYXllcigpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkUGF1c2VkJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFBhdXNlZCcpO1xuICAgIHRyYWNrZXIudHJhY2tQYXVzZSgpO1xuICAgIG5vdGlmeVBhdXNlVG9QbGF5ZXIoKTtcbiAgfSk7XG5cbiAgZnVuY3Rpb24gbm90aWZ5UGxheVRvUGxheWVyKCl7XG4gICAgaWYodGhhdC5fYWRVbml0ICYmIHRoYXQuX2FkVW5pdC5pc1BhdXNlZCgpKXtcbiAgICAgIHRoYXQuX2FkVW5pdC5fcGF1c2VkID0gZmFsc2U7XG4gICAgfVxuICAgIHBsYXllci50cmlnZ2VyKCdwbGF5Jyk7XG5cbiAgfVxuXG4gIGZ1bmN0aW9uIG5vdGlmeVBhdXNlVG9QbGF5ZXIoKSB7XG4gICAgaWYodGhhdC5fYWRVbml0KXtcbiAgICAgIHRoYXQuX2FkVW5pdC5fcGF1c2VkID0gdHJ1ZTtcbiAgICB9XG4gICAgcGxheWVyLnRyaWdnZXIoJ3BhdXNlJyk7XG4gIH1cblxuICBhZFVuaXQub24oJ0FkVmlkZW9GaXJzdFF1YXJ0aWxlJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFZpZGVvRmlyc3RRdWFydGlsZScpO1xuICAgIHRyYWNrZXIudHJhY2tGaXJzdFF1YXJ0aWxlKCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRWaWRlb01pZHBvaW50JywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFZpZGVvTWlkcG9pbnQnKTtcbiAgICB0cmFja2VyLnRyYWNrTWlkcG9pbnQoKTtcbiAgfSk7XG5cbiAgYWRVbml0Lm9uKCdBZFZpZGVvVGhpcmRRdWFydGlsZScsIGZ1bmN0aW9uICgpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuQWRWaWRlb1RoaXJkUXVhcnRpbGUnKTtcbiAgICB0cmFja2VyLnRyYWNrVGhpcmRRdWFydGlsZSgpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkVmlkZW9Db21wbGV0ZScsIGZ1bmN0aW9uICgpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuQWRWaWRlb0NvbXBsZXRlJyk7XG4gICAgdHJhY2tlci50cmFja0NvbXBsZXRlKCk7XG4gIH0pO1xuXG4gIGFkVW5pdC5vbignQWRDbGlja1RocnUnLCBmdW5jdGlvbiAoZGF0YSkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZENsaWNrVGhydScpO1xuICAgIHZhciB1cmwgPSBkYXRhLnVybDtcbiAgICB2YXIgcGxheWVySGFuZGxlcyA9IGRhdGEucGxheWVySGFuZGxlcztcbiAgICB2YXIgY2xpY2tUaHJ1VXJsID0gdXRpbGl0aWVzLmlzTm90RW1wdHlTdHJpbmcodXJsKSA/IHVybCA6IGdlbmVyYXRlQ2xpY2tUaHJvdWdoVVJMKHZhc3RSZXNwb25zZS5jbGlja1Rocm91Z2gpO1xuXG4gICAgdHJhY2tlci50cmFja0NsaWNrKCk7XG4gICAgaWYgKHBsYXllckhhbmRsZXMgJiYgY2xpY2tUaHJ1VXJsKSB7XG4gICAgICB3aW5kb3cub3BlbihjbGlja1RocnVVcmwsICdfYmxhbmsnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZW5lcmF0ZUNsaWNrVGhyb3VnaFVSTChjbGlja1Rocm91Z2hNYWNybykge1xuICAgICAgdmFyIHZhcmlhYmxlcyA9IHtcbiAgICAgICAgQVNTRVRVUkk6IGFkVW5pdC5vcHRpb25zLnNyYyxcbiAgICAgICAgQ09OVEVOVFBMQVlIRUFEOiAwIC8vSW4gVlBBSUQgdGhlcmUgaXMgbm8gbWV0aG9kIHRvIGtub3cgdGhlIGN1cnJlbnQgdGltZSBmcm9tIHRoZSBhZFVuaXRcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiBjbGlja1Rocm91Z2hNYWNybyA/IHZhc3RVdGlsLnBhcnNlVVJMTWFjcm8oY2xpY2tUaHJvdWdoTWFjcm8sIHZhcmlhYmxlcykgOiBudWxsO1xuICAgIH1cbiAgfSk7XG5cbiAgYWRVbml0Lm9uKCdBZFVzZXJBY2NlcHRJbnZpdGF0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFVzZXJBY2NlcHRJbnZpdGF0aW9uJyk7XG4gICAgdHJhY2tlci50cmFja0FjY2VwdEludml0YXRpb24oKTtcbiAgICB0cmFja2VyLnRyYWNrQWNjZXB0SW52aXRhdGlvbkxpbmVhcigpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkVXNlckNsb3NlJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFVzZXJDbG9zZScpO1xuICAgIHRyYWNrZXIudHJhY2tDbG9zZSgpO1xuICAgIHRyYWNrZXIudHJhY2tDbG9zZUxpbmVhcigpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkVXNlck1pbmltaXplJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFVzZXJNaW5pbWl6ZScpO1xuICAgIHRyYWNrZXIudHJhY2tDb2xsYXBzZSgpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkRXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkRXJyb3InKTtcbiAgICAvL05PVEU6IHdlIHRyYWNrIGVycm9ycyBjb2RlIDkwMSwgYXMgbm90ZWQgaW4gVkFTVCAzLjBcbiAgICB0cmFja2VyLnRyYWNrRXJyb3JXaXRoQ29kZSg5MDEpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkVm9sdW1lQ2hhbmdlJywgZnVuY3Rpb24gKCkge1xuICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFZvbHVtZUNoYW5nZScpO1xuICAgIHZhciBsYXN0Vm9sdW1lID0gcGxheWVyLnZvbHVtZSgpO1xuICAgIGFkVW5pdC5nZXRBZFZvbHVtZShmdW5jdGlvbiAoZXJyb3IsIGN1cnJlbnRWb2x1bWUpIHtcbiAgICAgIGlmIChjdXJyZW50Vm9sdW1lID09PSAwICYmIGxhc3RWb2x1bWUgPiAwKSB7XG4gICAgICAgIHRyYWNrZXIudHJhY2tNdXRlKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjdXJyZW50Vm9sdW1lID4gMCAmJiBsYXN0Vm9sdW1lID09PSAwKSB7XG4gICAgICAgIHRyYWNrZXIudHJhY2tVbm11dGUoKTtcbiAgICAgIH1cblxuICAgICAgcGxheWVyLnZvbHVtZShjdXJyZW50Vm9sdW1lKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgdmFyIHVwZGF0ZVZpZXdTaXplID0gcmVzaXplQWQuYmluZCh0aGlzLCBwbGF5ZXIsIGFkVW5pdCwgdGhpcy5WSUVXX01PREUpO1xuICB2YXIgdXBkYXRlVmlld1NpemVUaHJvdHRsZWQgPSB1dGlsaXRpZXMudGhyb3R0bGUodXBkYXRlVmlld1NpemUsIDEwMCk7XG4gIHZhciBhdXRvUmVzaXplID0gdGhpcy5zZXR0aW5ncy5hdXRvUmVzaXplO1xuXG4gIGlmIChhdXRvUmVzaXplKSB7XG4gICAgZG9tLmFkZEV2ZW50TGlzdGVuZXIod2luZG93LCAncmVzaXplJywgdXBkYXRlVmlld1NpemVUaHJvdHRsZWQpO1xuICAgIGRvbS5hZGRFdmVudExpc3RlbmVyKHdpbmRvdywgJ29yaWVudGF0aW9uY2hhbmdlJywgdXBkYXRlVmlld1NpemVUaHJvdHRsZWQpO1xuICB9XG5cbiAgcGxheWVyLm9uKCd2YXN0LnJlc2l6ZScsIHVwZGF0ZVZpZXdTaXplKTtcbiAgcGxheWVyLm9uKCd2cGFpZC5wYXVzZUFkJywgcGF1c2VBZFVuaXQpO1xuICBwbGF5ZXIub24oJ3ZwYWlkLnJlc3VtZUFkJywgcmVzdW1lQWRVbml0KTtcblxuICBwbGF5ZXIub25lKCd2cGFpZC5hZEVuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBwbGF5ZXIub2ZmKCd2YXN0LnJlc2l6ZScsIHVwZGF0ZVZpZXdTaXplKTtcbiAgICBwbGF5ZXIub2ZmKCd2cGFpZC5wYXVzZUFkJywgcGF1c2VBZFVuaXQpO1xuICAgIHBsYXllci5vZmYoJ3ZwYWlkLnJlc3VtZUFkJywgcmVzdW1lQWRVbml0KTtcblxuICAgIGlmIChhdXRvUmVzaXplKSB7XG4gICAgICBkb20ucmVtb3ZlRXZlbnRMaXN0ZW5lcih3aW5kb3csICdyZXNpemUnLCB1cGRhdGVWaWV3U2l6ZVRocm90dGxlZCk7XG4gICAgICBkb20ucmVtb3ZlRXZlbnRMaXN0ZW5lcih3aW5kb3csICdvcmllbnRhdGlvbmNoYW5nZScsIHVwZGF0ZVZpZXdTaXplVGhyb3R0bGVkKTtcbiAgICB9XG4gIH0pO1xuXG4gIG5leHQobnVsbCwgYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuXG4gIC8qKiogTG9jYWwgRnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gcGF1c2VBZFVuaXQoKSB7XG4gICAgYWRVbml0LnBhdXNlQWQodXRpbGl0aWVzLm5vb3ApO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzdW1lQWRVbml0KCkge1xuICAgIGFkVW5pdC5yZXN1bWVBZCh1dGlsaXRpZXMubm9vcCk7XG4gIH1cbn07XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUuX2FkZFNraXBCdXR0b24gPSBmdW5jdGlvbiAoYWRVbml0LCB2YXN0UmVzcG9uc2UsIG5leHQpIHtcbiAgdmFyIHNraXBCdXR0b247XG4gIHZhciBwbGF5ZXIgPSB0aGlzLnBsYXllcjtcblxuICBhZFVuaXQub24oJ0FkU2tpcHBhYmxlU3RhdGVDaGFuZ2UnLCB1cGRhdGVTa2lwQnV0dG9uU3RhdGUpO1xuXG4gIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3Zhc3QuYWRFbmQnLCAndmFzdC5hZHNDYW5jZWwnXSwgcmVtb3ZlU2tpcEJ1dHRvbik7XG5cbiAgbmV4dChudWxsLCBhZFVuaXQsIHZhc3RSZXNwb25zZSk7XG5cbiAgLyoqKiBMb2NhbCBmdW5jdGlvbiAqKiovXG4gIGZ1bmN0aW9uIHVwZGF0ZVNraXBCdXR0b25TdGF0ZSgpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcigndnBhaWQuQWRTa2lwcGFibGVTdGF0ZUNoYW5nZScpO1xuICAgIGFkVW5pdC5nZXRBZFNraXBwYWJsZVN0YXRlKGZ1bmN0aW9uIChlcnJvciwgaXNTa2lwcGFibGUpIHtcbiAgICAgIGlmIChpc1NraXBwYWJsZSkge1xuICAgICAgICBpZiAoIXNraXBCdXR0b24pIHtcbiAgICAgICAgICBhZGRTa2lwQnV0dG9uKHBsYXllcik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlbW92ZVNraXBCdXR0b24ocGxheWVyKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZFNraXBCdXR0b24ocGxheWVyKSB7XG4gICAgc2tpcEJ1dHRvbiA9IGNyZWF0ZVNraXBCdXR0b24ocGxheWVyKTtcbiAgICBwbGF5ZXIuZWwoKS5hcHBlbmRDaGlsZChza2lwQnV0dG9uKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbW92ZVNraXBCdXR0b24oKSB7XG4gICAgZG9tLnJlbW92ZShza2lwQnV0dG9uKTtcbiAgICBza2lwQnV0dG9uID0gbnVsbDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZVNraXBCdXR0b24oKSB7XG4gICAgdmFyIHNraXBCdXR0b24gPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICBkb20uYWRkQ2xhc3Moc2tpcEJ1dHRvbiwgXCJ2YXN0LXNraXAtYnV0dG9uXCIpO1xuICAgIGRvbS5hZGRDbGFzcyhza2lwQnV0dG9uLCBcImVuYWJsZWRcIik7XG4gICAgc2tpcEJ1dHRvbi5pbm5lckhUTUwgPSBcIlNraXAgYWRcIjtcblxuICAgIHNraXBCdXR0b24ub25jbGljayA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICBhZFVuaXQuc2tpcEFkKHV0aWxpdGllcy5ub29wKTsvL1dlIHNraXAgdGhlIGFkVW5pdFxuXG4gICAgICAvL1dlIHByZXZlbnQgZXZlbnQgcHJvcGFnYXRpb24gdG8gYXZvaWQgcHJvYmxlbXMgd2l0aCB0aGUgY2xpY2tUaHJvdWdoIGFuZCBzbyBvblxuICAgICAgaWYgKHdpbmRvdy5FdmVudC5wcm90b3R5cGUuc3RvcFByb3BhZ2F0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIHNraXBCdXR0b247XG4gIH1cbn07XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUuX2xpbmtQbGF5ZXJDb250cm9scyA9IGZ1bmN0aW9uIChhZFVuaXQsIHZhc3RSZXNwb25zZSwgbmV4dCkge1xuICB2YXIgdGhhdCA9IHRoaXM7XG4gIGxpbmtWb2x1bWVDb250cm9sKHRoaXMucGxheWVyLCBhZFVuaXQpO1xuICBsaW5rRnVsbFNjcmVlbkNvbnRyb2wodGhpcy5wbGF5ZXIsIGFkVW5pdCwgdGhpcy5WSUVXX01PREUpO1xuXG4gIG5leHQobnVsbCwgYWRVbml0LCB2YXN0UmVzcG9uc2UpO1xuXG4gIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgZnVuY3Rpb24gbGlua1ZvbHVtZUNvbnRyb2wocGxheWVyLCBhZFVuaXQpIHtcbiAgICBwbGF5ZXIub24oJ3ZvbHVtZWNoYW5nZScsIHVwZGF0ZUFkVW5pdFZvbHVtZSk7XG4gICAgYWRVbml0Lm9uKCdBZFZvbHVtZUNoYW5nZScsIHVwZGF0ZVBsYXllclZvbHVtZSk7XG5cbiAgICBwbGF5ZXIub25lKCd2cGFpZC5hZEVuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHBsYXllci5vZmYoJ3ZvbHVtZWNoYW5nZScsIHVwZGF0ZUFkVW5pdFZvbHVtZSk7XG4gICAgfSk7XG5cblxuICAgIC8qKiogbG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgICBmdW5jdGlvbiB1cGRhdGVBZFVuaXRWb2x1bWUoKSB7XG4gICAgICB2YXIgdm9sID0gcGxheWVyLm11dGVkKCkgPyAwIDogcGxheWVyLnZvbHVtZSgpO1xuICAgICAgYWRVbml0LnNldEFkVm9sdW1lKHZvbCwgbG9nRXJyb3IpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHVwZGF0ZVBsYXllclZvbHVtZSgpIHtcbiAgICAgIHBsYXllci50cmlnZ2VyKCd2cGFpZC5BZFZvbHVtZUNoYW5nZScpO1xuICAgICAgYWRVbml0LmdldEFkVm9sdW1lKGZ1bmN0aW9uIChlcnJvciwgdm9sKSB7XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgIGxvZ0Vycm9yKGVycm9yKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwbGF5ZXIudm9sdW1lKHZvbCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGxpbmtGdWxsU2NyZWVuQ29udHJvbChwbGF5ZXIsIGFkVW5pdCwgVklFV19NT0RFKSB7XG4gICAgdmFyIHVwZGF0ZVZpZXdTaXplID0gcmVzaXplQWQuYmluZCh0aGF0LCBwbGF5ZXIsIGFkVW5pdCwgVklFV19NT0RFKTtcblxuICAgIHBsYXllci5vbignZnVsbHNjcmVlbmNoYW5nZScsIHVwZGF0ZVZpZXdTaXplKTtcblxuICAgIHBsYXllci5vbmUoJ3ZwYWlkLmFkRW5kJywgZnVuY3Rpb24gKCkge1xuICAgICAgcGxheWVyLm9mZignZnVsbHNjcmVlbmNoYW5nZScsIHVwZGF0ZVZpZXdTaXplKTtcbiAgICB9KTtcbiAgfVxufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5fc3RhcnRBZCA9IGZ1bmN0aW9uIChhZFVuaXQsIHZhc3RSZXNwb25zZSwgbmV4dCkge1xuICB2YXIgcGxheWVyID0gdGhpcy5wbGF5ZXI7XG5cbiAgYWRVbml0LnN0YXJ0QWQoZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgaWYgKCFlcnJvcikge1xuICAgICAgcGxheWVyLnRyaWdnZXIoJ3Zhc3QuYWRTdGFydCcpO1xuICAgIH1cbiAgICBuZXh0KGVycm9yLCBhZFVuaXQsIHZhc3RSZXNwb25zZSk7XG4gIH0pO1xufTtcblxuVlBBSURJbnRlZ3JhdG9yLnByb3RvdHlwZS5fZmluaXNoUGxheWluZyA9IGZ1bmN0aW9uIChhZFVuaXQsIHZhc3RSZXNwb25zZSwgbmV4dCkge1xuICB2YXIgcGxheWVyID0gdGhpcy5wbGF5ZXI7XG4gIGFkVW5pdC5vbignQWRTdG9wcGVkJywgZnVuY3Rpb24gKCkge1xuICAgcGxheWVyLnRyaWdnZXIoJ3ZwYWlkLkFkU3RvcHBlZCcpO1xuICAgZmluaXNoUGxheWluZ0FkKG51bGwpO1xuICB9KTtcblxuICBhZFVuaXQub24oJ0FkRXJyb3InLCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICB2YXIgZXJyTXNnID0gZXJyb3I/IGVycm9yLm1lc3NhZ2UgOiAnb24gVlBBSURJbnRlZ3JhdG9yLCBlcnJvciB3aGlsZSB3YWl0aW5nIGZvciB0aGUgYWRVbml0IHRvIGZpbmlzaCBwbGF5aW5nJztcbiAgICBmaW5pc2hQbGF5aW5nQWQobmV3IFZBU1RFcnJvcihlcnJNc2cpKTtcbiAgfSk7XG5cbiAgLyoqKiBsb2NhbCBmdW5jdGlvbnMgKioqL1xuICBmdW5jdGlvbiBmaW5pc2hQbGF5aW5nQWQoZXJyb3IpIHtcbiAgICBuZXh0KGVycm9yLCBhZFVuaXQsIHZhc3RSZXNwb25zZSk7XG4gIH1cbn07XG5cblZQQUlESW50ZWdyYXRvci5wcm90b3R5cGUuX3RyYWNrRXJyb3IgPSBmdW5jdGlvbiB0cmFja0Vycm9yKHJlc3BvbnNlKSB7XG4gIHZhc3RVdGlsLnRyYWNrKHJlc3BvbnNlLmVycm9yVVJMTWFjcm9zLCB7RVJST1JDT0RFOiA5MDF9KTtcbn07XG5cbmZ1bmN0aW9uIHJlc2l6ZUFkKHBsYXllciwgYWRVbml0LCBWSUVXX01PREUpIHtcbiAgdmFyIHRlY2ggPSBwbGF5ZXIuZWwoKS5xdWVyeVNlbGVjdG9yKCcudmpzLXRlY2gnKTtcbiAgdmFyIGRpbWVuc2lvbiA9IGRvbS5nZXREaW1lbnNpb24odGVjaCk7XG4gIHZhciBNT0RFID0gcGxheWVyLmlzRnVsbHNjcmVlbigpID8gVklFV19NT0RFLkZVTExTQ1JFRU4gOiBWSUVXX01PREUuTk9STUFMO1xuICBhZFVuaXQucmVzaXplQWQoZGltZW5zaW9uLndpZHRoLCBkaW1lbnNpb24uaGVpZ2h0LCBNT0RFLCBsb2dFcnJvcik7XG59XG5cbmZ1bmN0aW9uIGxvZ0Vycm9yKGVycm9yKSB7XG4gIGlmIChlcnJvciAmJiBjb25zb2xlICYmIGNvbnNvbGUubG9nKSB7XG4gICAgY29uc29sZS5sb2coJ0VSUk9SOiAnICsgZXJyb3IubWVzc2FnZSwgZXJyb3IpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gVlBBSURJbnRlZ3JhdG9yOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIGRvbSA9IHJlcXVpcmUoJy4uLy4uL3V0aWxzL2RvbScpO1xuXG52YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuZWxlbWVudC5jbGFzc05hbWUgPSAndmpzLWFkcy1sYWJlbCB2anMtY29udHJvbCB2anMtbGFiZWwtaGlkZGVuJztcbmVsZW1lbnQuaW5uZXJIVE1MID0gJ0FkdmVydGlzZW1lbnQnO1xuXG52YXIgQWRzTGFiZWxGYWN0b3J5ID0gZnVuY3Rpb24oYmFzZUNvbXBvbmVudCkge1xuICByZXR1cm4ge1xuICAgIC8qKiBAY29uc3RydWN0b3IgKi9cbiAgICBpbml0OiBmdW5jdGlvbiBpbml0KHBsYXllciwgb3B0aW9ucykge1xuICAgICAgb3B0aW9ucy5lbCA9IGVsZW1lbnQ7XG4gICAgICBiYXNlQ29tcG9uZW50LmNhbGwodGhpcywgcGxheWVyLCBvcHRpb25zKTtcblxuICAgICAgLy8gV2UgYXN5bmNocm9ub3VzbHkgcmVwb3NpdGlvbiB0aGUgYWRzIGxhYmVsIGVsZW1lbnRcbiAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY3VycmVudFRpbWVDb21wID0gcGxheWVyLmNvbnRyb2xCYXIgJiYoIHBsYXllci5jb250cm9sQmFyLmdldENoaWxkKFwidGltZXJDb250cm9sc1wiKSB8fCBwbGF5ZXIuY29udHJvbEJhci5nZXRDaGlsZChcImN1cnJlbnRUaW1lRGlzcGxheVwiKSApO1xuICAgICAgICBpZihjdXJyZW50VGltZUNvbXApIHtcbiAgICAgICAgICBwbGF5ZXIuY29udHJvbEJhci5lbCgpLmluc2VydEJlZm9yZShlbGVtZW50LCBjdXJyZW50VGltZUNvbXAuZWwoKSk7XG4gICAgICAgIH1cbiAgICAgICAgZG9tLnJlbW92ZUNsYXNzKGVsZW1lbnQsICd2anMtbGFiZWwtaGlkZGVuJyk7XG4gICAgICB9LCAwKTtcbiAgICB9LFxuXG4gICAgZWw6IGZ1bmN0aW9uIGdldEVsZW1lbnQoKSB7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFkc0xhYmVsRmFjdG9yeTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBiYXNlVmlkZW9Kc0NvbXBvbmVudCA9IHZpZGVvanMuZ2V0Q29tcG9uZW50KCdDb21wb25lbnQnKTtcblxudmFyIEFkc0xhYmVsID0gcmVxdWlyZSgnLi9hZHMtbGFiZWwnKShiYXNlVmlkZW9Kc0NvbXBvbmVudCk7XG5cbnZpZGVvanMucmVnaXN0ZXJDb21wb25lbnQoJ0Fkc0xhYmVsJywgdmlkZW9qcy5leHRlbmQoYmFzZVZpZGVvSnNDb21wb25lbnQsIEFkc0xhYmVsKSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogVGhlIGNvbXBvbmVudCB0aGF0IHNob3dzIGEgYmxhY2sgc2NyZWVuIHVudGlsIHRoZSBhZHMgcGx1Z2luIGhhcyBkZWNpZGVkIGlmIGl0IGNhbiBvciBpdCBjYW4gbm90IHBsYXkgdGhlIGFkLlxuICpcbiAqIE5vdGU6IEluIGNhc2UgeW91IHdvbmRlciB3aHkgaW5zdGVhZCBvZiB0aGlzIGJsYWNrIHBvc3RlciB3ZSBkb24ndCBqdXN0IHNob3cgdGhlIHNwaW5uZXIgbG9hZGVyLlxuICogICAgICAgSU9TIGRldmljZXMgZG8gbm90IHdvcmsgd2VsbCB3aXRoIGFuaW1hdGlvbnMgYW5kIHRoZSBicm93c2VyIGNocmFzaGVzIGZyb20gdGltZSB0byB0aW1lIFRoYXQgaXMgd2h5IHdlIGNob3NlIHRvXG4gKiAgICAgICBoYXZlIGEgc2Vjb25kYXJ5IGJsYWNrIHBvc3Rlci5cbiAqXG4gKiAgICAgICBJdCBhbHNvIG1ha2VzIGl0IG11Y2ggbW9yZSBlYXNpZXIgZm9yIHRoZSB1c2VycyBvZiB0aGUgcGx1Z2luIHNpbmNlIGl0IGRvZXMgbm90IGNoYW5nZSB0aGUgZGVmYXVsdCBiZWhhdmlvdXIgb2YgdGhlXG4gKiAgICAgICBzcGlubmVyIGFuZCB0aGUgcGxheWVyIHdvcmtzIHRoZSBzYW1lIHdheSB3aXRoIGFuZCB3aXRob3V0IHRoZSBwbHVnaW4uXG4gKlxuICogQHBhcmFtIHt2anMuUGxheWVyfE9iamVjdH0gcGxheWVyXG4gKiBAcGFyYW0ge09iamVjdD19IG9wdGlvbnNcbiAqIEBjb25zdHJ1Y3RvclxuICovXG52YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXG52YXIgQmxhY2tQb3N0ZXJGYWN0b3J5ID0gZnVuY3Rpb24oYmFzZUNvbXBvbmVudCkge1xuICByZXR1cm4ge1xuICAgIC8qKiBAY29uc3RydWN0b3IgKi9cbiAgICBpbml0OiBmdW5jdGlvbiBpbml0KHBsYXllciwgb3B0aW9ucykge1xuICAgICAgb3B0aW9ucy5lbCA9IGVsZW1lbnQ7XG4gICAgICBlbGVtZW50LmNsYXNzTmFtZSA9ICd2anMtYmxhY2stcG9zdGVyJztcbiAgICAgIGJhc2VDb21wb25lbnQuY2FsbCh0aGlzLCBwbGF5ZXIsIG9wdGlvbnMpO1xuXG4gICAgICB2YXIgcG9zdGVySW1nID0gcGxheWVyLmdldENoaWxkKCdwb3N0ZXJJbWFnZScpO1xuXG4gICAgICAvL1dlIG5lZWQgdG8gZG8gaXQgYXN5bmNocm9ub3VzbHkgdG8gYmUgc3VyZSB0aGF0IHRoZSBibGFjayBwb3N0ZXIgZWwgaXMgb24gdGhlIGRvbS5cbiAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmKHBvc3RlckltZyAmJiBwbGF5ZXIgJiYgcGxheWVyLmVsKCkpIHtcbiAgICAgICAgICBwbGF5ZXIuZWwoKS5pbnNlcnRCZWZvcmUoZWxlbWVudCwgcG9zdGVySW1nLmVsKCkpO1xuICAgICAgICB9XG4gICAgICB9LCAwKTtcbiAgICB9LFxuICAgIGVsOiBmdW5jdGlvbiBnZXRFbGVtZW50KCkge1xuICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBCbGFja1Bvc3RlckZhY3Rvcnk7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYmFzZVZpZGVvSnNDb21wb25lbnQgPSB2aWRlb2pzLmdldENvbXBvbmVudCgnQ29tcG9uZW50Jyk7XG5cbnZhciBCbGFja1Bvc3RlciA9IHJlcXVpcmUoJy4vYmxhY2stcG9zdGVyJykoYmFzZVZpZGVvSnNDb21wb25lbnQpO1xuXG52aWRlb2pzLnJlZ2lzdGVyQ29tcG9uZW50KCdCbGFja1Bvc3RlcicsIHZpZGVvanMuZXh0ZW5kKGJhc2VWaWRlb0pzQ29tcG9uZW50LCBCbGFja1Bvc3RlcikpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVkFTVENsaWVudCA9IHJlcXVpcmUoJy4uL2Fkcy92YXN0L1ZBU1RDbGllbnQnKTtcbnZhciBWQVNURXJyb3IgPSByZXF1aXJlKCcuLi9hZHMvdmFzdC9WQVNURXJyb3InKTtcbnZhciB2YXN0VXRpbCA9IHJlcXVpcmUoJy4uL2Fkcy92YXN0L3Zhc3RVdGlsJyk7XG5cbnZhciBWQVNUSW50ZWdyYXRvciA9IHJlcXVpcmUoJy4uL2Fkcy92YXN0L1ZBU1RJbnRlZ3JhdG9yJyk7XG52YXIgVlBBSURJbnRlZ3JhdG9yID0gcmVxdWlyZSgnLi4vYWRzL3ZwYWlkL1ZQQUlESW50ZWdyYXRvcicpO1xuXG52YXIgYXN5bmMgPSByZXF1aXJlKCcuLi91dGlscy9hc3luYycpO1xudmFyIGRvbSA9IHJlcXVpcmUoJy4uL3V0aWxzL2RvbScpO1xudmFyIHBsYXllclV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMvcGxheWVyVXRpbHMnKTtcbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuLi91dGlscy91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVkFTVFBsdWdpbihvcHRpb25zKSB7XG4gIHZhciBzbmFwc2hvdDtcbiAgdmFyIHBsYXllciA9IHRoaXM7XG4gIHZhciB2YXN0ID0gbmV3IFZBU1RDbGllbnQoKTtcbiAgdmFyIGFkc0NhbmNlbGVkID0gZmFsc2U7XG4gIHZhciBkZWZhdWx0T3B0cyA9IHtcbiAgICAvLyBtYXhpbXVtIGFtb3VudCBvZiB0aW1lIGluIG1zIHRvIHdhaXQgdG8gcmVjZWl2ZSBgYWRzcmVhZHlgIGZyb20gdGhlIGFkXG4gICAgLy8gaW1wbGVtZW50YXRpb24gYWZ0ZXIgcGxheSBoYXMgYmVlbiByZXF1ZXN0ZWQuIEFkIGltcGxlbWVudGF0aW9ucyBhcmVcbiAgICAvLyBleHBlY3RlZCB0byBsb2FkIGFueSBkeW5hbWljIGxpYnJhcmllcyBhbmQgbWFrZSBhbnkgcmVxdWVzdHMgdG8gZGV0ZXJtaW5lXG4gICAgLy8gYWQgcG9saWNpZXMgZm9yIGEgdmlkZW8gZHVyaW5nIHRoaXMgdGltZS5cbiAgICB0aW1lb3V0OiA1MDAsXG5cbiAgICAvL1RPRE86ZmluaXNoIHRoaXMgSU9TIEZJWFxuICAgIC8vV2hlbmV2ZXIgeW91IHBsYXkgYW4gYWRkIG9uIElPUywgdGhlIG5hdGl2ZSBwbGF5ZXIga2lja3MgaW4gYW5kIHdlIGxvb3NlIGNvbnRyb2wgb2YgaXQuIE9uIHZlcnkgaGVhdnkgcGFnZXMgdGhlICdwbGF5JyBldmVudFxuICAgIC8vIE1heSBvY2N1ciBhZnRlciB0aGUgdmlkZW8gY29udGVudCBoYXMgYWxyZWFkeSBzdGFydGVkLiBUaGlzIGlzIHdyb25nIGlmIHlvdSB3YW50IHRvIHBsYXkgYSBwcmVyb2xsIGFkIHRoYXQgbmVlZHMgdG8gaGFwcGVuIGJlZm9yZSB0aGUgdXNlclxuICAgIC8vIHN0YXJ0cyB3YXRjaGluZyB0aGUgY29udGVudC4gVG8gcHJldmVudCB0aGlzIHVzZWNcbiAgICBpb3NQcmVyb2xsQ2FuY2VsVGltZW91dDogMjAwMCxcblxuICAgIC8vIG1heGltdW4gYW1vdW50IG9mIHRpbWUgZm9yIHRoZSBhZCB0byBhY3R1YWxseSBzdGFydCBwbGF5aW5nLiBJZiB0aGlzIHRpbWVvdXQgZ2V0c1xuICAgIC8vIHRyaWdnZXJlZCB0aGUgYWRzIHdpbGwgYmUgY2FuY2VsbGVkXG4gICAgYWRDYW5jZWxUaW1lb3V0OiAzMDAwLFxuXG4gICAgLy8gQm9vbGVhbiBmbGFnIHRoYXQgY29uZmlndXJlcyB0aGUgcGxheWVyIHRvIHBsYXkgYSBuZXcgYWQgYmVmb3JlIHRoZSB1c2VyIHNlZXMgdGhlIHZpZGVvIGFnYWluXG4gICAgLy8gdGhlIGN1cnJlbnQgdmlkZW9cbiAgICBwbGF5QWRBbHdheXM6IGZhbHNlLFxuXG4gICAgLy8gRmxhZyB0byBlbmFibGUgb3IgZGlzYWJsZSB0aGUgYWRzIGJ5IGRlZmF1bHQuXG4gICAgYWRzRW5hYmxlZDogdHJ1ZSxcblxuICAgIC8vIEJvb2xlYW4gZmxhZyB0byBlbmFibGUgb3IgZGlzYWJsZSB0aGUgcmVzaXplIHdpdGggd2luZG93LnJlc2l6ZSBvciBvcmllbnRhdGlvbmNoYW5nZVxuICAgIGF1dG9SZXNpemU6IHRydWUsXG5cbiAgICAvLyBQYXRoIHRvIHRoZSBWUEFJRCBmbGFzaCBhZCdzIGxvYWRlclxuICAgIHZwYWlkRmxhc2hMb2FkZXJQYXRoOiAnL1ZQQUlERmxhc2guc3dmJ1xuICB9O1xuXG4gIHZhciBzZXR0aW5ncyA9IHV0aWxpdGllcy5leHRlbmQoe30sIGRlZmF1bHRPcHRzLCBvcHRpb25zIHx8IHt9KTtcblxuICBpZih1dGlsaXRpZXMuaXNVbmRlZmluZWQoc2V0dGluZ3MuYWRUYWdVcmwpICYmIHV0aWxpdGllcy5pc0RlZmluZWQoc2V0dGluZ3MudXJsKSl7XG4gICAgc2V0dGluZ3MuYWRUYWdVcmwgPSBzZXR0aW5ncy51cmw7XG4gIH1cblxuICBpZiAodXRpbGl0aWVzLmlzU3RyaW5nKHNldHRpbmdzLmFkVGFnVXJsKSkge1xuICAgIHNldHRpbmdzLmFkVGFnVXJsID0gdXRpbGl0aWVzLmVjaG9GbihzZXR0aW5ncy5hZFRhZ1VybCk7XG4gIH1cblxuICBpZiAodXRpbGl0aWVzLmlzRGVmaW5lZChzZXR0aW5ncy5hZFRhZ1hNTCkgJiYgIXV0aWxpdGllcy5pc0Z1bmN0aW9uKHNldHRpbmdzLmFkVGFnWE1MKSkge1xuICAgIHJldHVybiB0cmFja0FkRXJyb3IobmV3IFZBU1RFcnJvcignb24gVmlkZW9KUyBWQVNUIHBsdWdpbiwgdGhlIHBhc3NlZCBhZFRhZ1hNTCBvcHRpb24gZG9lcyBub3QgY29udGFpbiBhIGZ1bmN0aW9uJykpO1xuICB9XG5cbiAgaWYgKCF1dGlsaXRpZXMuaXNEZWZpbmVkKHNldHRpbmdzLmFkVGFnVXJsKSAmJiAhdXRpbGl0aWVzLmlzRnVuY3Rpb24oc2V0dGluZ3MuYWRUYWdYTUwpKSB7XG4gICAgcmV0dXJuIHRyYWNrQWRFcnJvcihuZXcgVkFTVEVycm9yKCdvbiBWaWRlb0pTIFZBU1QgcGx1Z2luLCBtaXNzaW5nIGFkVGFnVXJsIG9uIG9wdGlvbnMgb2JqZWN0JykpO1xuICB9XG5cbiAgcGxheWVyVXRpbHMucHJlcGFyZUZvckFkcyhwbGF5ZXIpO1xuXG4gIGlmIChzZXR0aW5ncy5wbGF5QWRBbHdheXMpIHtcbiAgICAvLyBObyBtYXR0ZXIgd2hhdCBoYXBwZW5zIHdlIHBsYXkgYSBuZXcgYWQgYmVmb3JlIHRoZSB1c2VyIHNlZXMgdGhlIHZpZGVvIGFnYWluLlxuICAgIHBsYXllci5vbigndmFzdC5jb250ZW50RW5kJywgZnVuY3Rpb24gKCkge1xuICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHBsYXllci50cmlnZ2VyKCd2YXN0LnJlc2V0Jyk7XG4gICAgICB9LCAwKTtcbiAgICB9KTtcbiAgfVxuXG4gIHBsYXllci5vbigndmFzdC5maXJzdFBsYXknLCB0cnlUb1BsYXlQcmVyb2xsQWQpO1xuXG4gIHBsYXllci5vbigndmFzdC5yZXNldCcsIGZ1bmN0aW9uICgpIHtcbiAgICAvL0lmIHdlIGFyZSByZXNldGluZyB0aGUgcGx1Z2luLCB3ZSBkb24ndCB3YW50IHRvIHJlc3RvcmUgdGhlIGNvbnRlbnRcbiAgICBzbmFwc2hvdCA9IG51bGw7XG4gICAgY2FuY2VsQWRzKCk7XG4gIH0pO1xuXG4gIHBsYXllci52YXN0ID0ge1xuICAgIGlzRW5hYmxlZDogZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIHNldHRpbmdzLmFkc0VuYWJsZWQ7XG4gICAgfSxcblxuICAgIGVuYWJsZTogZnVuY3Rpb24gKCkge1xuICAgICAgc2V0dGluZ3MuYWRzRW5hYmxlZCA9IHRydWU7XG4gICAgfSxcblxuICAgIGRpc2FibGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHNldHRpbmdzLmFkc0VuYWJsZWQgPSBmYWxzZTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHBsYXllci52YXN0O1xuXG4gIC8qKioqIExvY2FsIGZ1bmN0aW9ucyAqKioqL1xuICBmdW5jdGlvbiB0cnlUb1BsYXlQcmVyb2xsQWQoKSB7XG4gICAgLy9XZSByZW1vdmUgdGhlIHBvc3RlciB0byBwcmV2ZW50IGZsaWNrZXJpbmcgd2hlbmV2ZXIgdGhlIGNvbnRlbnQgc3RhcnRzIHBsYXlpbmdcbiAgICBwbGF5ZXJVdGlscy5yZW1vdmVOYXRpdmVQb3N0ZXIocGxheWVyKTtcblxuICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3Zhc3QuYWRzQ2FuY2VsJywgJ3Zhc3QuYWRFbmQnXSwgZnVuY3Rpb24gKCkge1xuICAgICAgcmVtb3ZlQWRVbml0KCk7XG4gICAgICByZXN0b3JlVmlkZW9Db250ZW50KCk7XG4gICAgfSk7XG5cbiAgICBhc3luYy53YXRlcmZhbGwoW1xuICAgICAgY2hlY2tBZHNFbmFibGVkLFxuICAgICAgcHJlcGFyZVBsYXllckZvckFkLFxuICAgICAgc3RhcnRBZENhbmNlbFRpbWVvdXQsXG4gICAgICBwbGF5UHJlcm9sbEFkXG4gICAgXSwgZnVuY3Rpb24gKGVycm9yLCByZXNwb25zZSkge1xuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIHRyYWNrQWRFcnJvcihlcnJvciwgcmVzcG9uc2UpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGxheWVyLnRyaWdnZXIoJ3Zhc3QuYWRFbmQnKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKi9cblxuICAgIGZ1bmN0aW9uIHJlbW92ZUFkVW5pdCgpIHtcbiAgICAgIGlmIChwbGF5ZXIudmFzdCAmJiBwbGF5ZXIudmFzdC5hZFVuaXQpIHtcbiAgICAgICAgcGxheWVyLnZhc3QuYWRVbml0ID0gbnVsbDsgLy9XZSByZW1vdmUgdGhlIGFkVW5pdFxuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlc3RvcmVWaWRlb0NvbnRlbnQoKSB7XG4gICAgICBzZXR1cENvbnRlbnRFdmVudHMoKTtcbiAgICAgIGlmIChzbmFwc2hvdCkge1xuICAgICAgICBwbGF5ZXJVdGlscy5yZXN0b3JlUGxheWVyU25hcHNob3QocGxheWVyLCBzbmFwc2hvdCk7XG4gICAgICAgIHNuYXBzaG90ID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXR1cENvbnRlbnRFdmVudHMoKSB7XG4gICAgICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWydwbGF5aW5nJywgJ3Zhc3QucmVzZXQnLCAndmFzdC5maXJzdFBsYXknXSwgZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBpZiAoZXZ0LnR5cGUgIT09ICdwbGF5aW5nJykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHBsYXllci50cmlnZ2VyKCd2YXN0LmNvbnRlbnRTdGFydCcpO1xuXG4gICAgICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ2VuZGVkJywgJ3Zhc3QucmVzZXQnLCAndmFzdC5maXJzdFBsYXknXSwgZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICAgIGlmIChldnQudHlwZSA9PT0gJ2VuZGVkJykge1xuICAgICAgICAgICAgcGxheWVyLnRyaWdnZXIoJ3Zhc3QuY29udGVudEVuZCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjaGVja0Fkc0VuYWJsZWQobmV4dCkge1xuICAgICAgaWYgKHNldHRpbmdzLmFkc0VuYWJsZWQpIHtcbiAgICAgICAgcmV0dXJuIG5leHQobnVsbCk7XG4gICAgICB9XG4gICAgICBuZXh0KG5ldyBWQVNURXJyb3IoJ0FkcyBhcmUgbm90IGVuYWJsZWQnKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcHJlcGFyZVBsYXllckZvckFkKG5leHQpIHtcbiAgICAgIGlmIChjYW5QbGF5UHJlcm9sbEFkKCkpIHtcbiAgICAgICAgc25hcHNob3QgPSBwbGF5ZXJVdGlscy5nZXRQbGF5ZXJTbmFwc2hvdChwbGF5ZXIpO1xuICAgICAgICBwbGF5ZXIucGF1c2UoKTtcbiAgICAgICAgYWRkU3Bpbm5lckljb24oKTtcblxuICAgICAgICBpZihwbGF5ZXIucGF1c2VkKCkpIHtcbiAgICAgICAgICBuZXh0KG51bGwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3BsYXlpbmcnXSwgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBwbGF5ZXIucGF1c2UoKTtcbiAgICAgICAgICAgIG5leHQobnVsbCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5leHQobmV3IFZBU1RFcnJvcigndmlkZW8gY29udGVudCBoYXMgYmVlbiBwbGF5aW5nIGJlZm9yZSBwcmVyb2xsIGFkJykpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNhblBsYXlQcmVyb2xsQWQoKSB7XG4gICAgICByZXR1cm4gIXV0aWxpdGllcy5pc0lQaG9uZSgpIHx8IHBsYXllci5jdXJyZW50VGltZSgpIDw9IHNldHRpbmdzLmlvc1ByZXJvbGxDYW5jZWxUaW1lb3V0O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN0YXJ0QWRDYW5jZWxUaW1lb3V0KG5leHQpIHtcbiAgICAgIHZhciBhZENhbmNlbFRpbWVvdXRJZDtcbiAgICAgIGFkc0NhbmNlbGVkID0gZmFsc2U7XG5cbiAgICAgIGFkQ2FuY2VsVGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRyYWNrQWRFcnJvcihuZXcgVkFTVEVycm9yKCd0aW1lb3V0IHdoaWxlIHdhaXRpbmcgZm9yIHRoZSB2aWRlbyB0byBzdGFydCBwbGF5aW5nJywgNDAyKSk7XG4gICAgICB9LCBzZXR0aW5ncy5hZENhbmNlbFRpbWVvdXQpO1xuXG4gICAgICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWyd2YXN0LmFkU3RhcnQnLCAndmFzdC5hZHNDYW5jZWwnXSwgY2xlYXJBZENhbmNlbFRpbWVvdXQpO1xuXG4gICAgICAvKioqIGxvY2FsIGZ1bmN0aW9ucyAqKiovXG4gICAgICBmdW5jdGlvbiBjbGVhckFkQ2FuY2VsVGltZW91dCgpIHtcbiAgICAgICAgaWYgKGFkQ2FuY2VsVGltZW91dElkKSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KGFkQ2FuY2VsVGltZW91dElkKTtcbiAgICAgICAgICBhZENhbmNlbFRpbWVvdXRJZCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbmV4dChudWxsKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhZGRTcGlubmVySWNvbigpIHtcbiAgICAgIGRvbS5hZGRDbGFzcyhwbGF5ZXIuZWwoKSwgJ3Zqcy12YXN0LWFkLWxvYWRpbmcnKTtcbiAgICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3Zhc3QuYWRTdGFydCcsICd2YXN0LmFkc0NhbmNlbCddLCByZW1vdmVTcGlubmVySWNvbik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVtb3ZlU3Bpbm5lckljb24oKSB7XG4gICAgICAvL0lNUE9SVEFOVCBOT1RFOiBXZSByZW1vdmUgdGhlIHNwaW5uZXJJY29uIGFzeW5jaHJvbm91c2x5IHRvIGdpdmUgdGltZSB0byB0aGUgYnJvd3NlciB0byBzdGFydCB0aGUgdmlkZW8uXG4gICAgICAvLyBJZiB3ZSByZW1vdmUgaXQgc3luY2hyb25vdXNseSB3ZSBzZWUgYSBmbGFzaCBvZiB0aGUgY29udGVudCB2aWRlbyBiZWZvcmUgdGhlIGFkIHN0YXJ0cyBwbGF5aW5nLlxuICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRvbS5yZW1vdmVDbGFzcyhwbGF5ZXIuZWwoKSwgJ3Zqcy12YXN0LWFkLWxvYWRpbmcnKTtcbiAgICAgIH0sIDEwMCk7XG4gICAgfVxuXG4gIH1cblxuICBmdW5jdGlvbiBjYW5jZWxBZHMoKSB7XG4gICAgcGxheWVyLnRyaWdnZXIoJ3Zhc3QuYWRzQ2FuY2VsJyk7XG4gICAgYWRzQ2FuY2VsZWQgPSB0cnVlO1xuICB9XG5cbiAgZnVuY3Rpb24gcGxheVByZXJvbGxBZChjYWxsYmFjaykge1xuICAgIGFzeW5jLndhdGVyZmFsbChbXG4gICAgICBnZXRWYXN0UmVzcG9uc2UsXG4gICAgICBwbGF5QWRcbiAgICBdLCBjYWxsYmFjayk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRWYXN0UmVzcG9uc2UoY2FsbGJhY2spIHtcbiAgICB2YXN0LmdldFZBU1RSZXNwb25zZShzZXR0aW5ncy5hZFRhZ1VybCA/IHNldHRpbmdzLmFkVGFnVXJsKCkgOiBzZXR0aW5ncy5hZFRhZ1hNTCwgY2FsbGJhY2spO1xuICB9XG5cbiAgZnVuY3Rpb24gcGxheUFkKHZhc3RSZXNwb25zZSwgY2FsbGJhY2spIHtcbiAgICAvL1RPRE86IEZpbmQgYSBiZXR0ZXIgd2F5IHRvIHN0b3AgdGhlIHBsYXkuIFRoZSAncGxheVByZXJvbGxXYXRlcmZhbGwnIGVuZHMgaW4gYW4gaW5jb25zaXN0ZW50IHNpdHVhdGlvblxuICAgIC8vSWYgdGhlIHN0YXRlIGlzIG5vdCAncHJlcm9sbD8nIGl0IG1lYW5zIHRoZSBhZHMgd2VyZSBjYW5jZWxlZCB0aGVyZWZvcmUsIHdlIGJyZWFrIHRoZSB3YXRlcmZhbGxcbiAgICBpZiAoYWRzQ2FuY2VsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgYWRJbnRlZ3JhdG9yID0gaXNWUEFJRCh2YXN0UmVzcG9uc2UpID8gbmV3IFZQQUlESW50ZWdyYXRvcihwbGF5ZXIsIHNldHRpbmdzKSA6IG5ldyBWQVNUSW50ZWdyYXRvcihwbGF5ZXIpO1xuICAgIHZhciBhZEZpbmlzaGVkID0gZmFsc2U7XG5cbiAgICBwbGF5ZXJVdGlscy5vbmNlKHBsYXllciwgWyd2YXN0LmFkU3RhcnQnLCAndmFzdC5hZHNDYW5jZWwnXSwgZnVuY3Rpb24gKGV2dCkge1xuICAgICAgaWYgKGV2dC50eXBlID09PSAndmFzdC5hZFN0YXJ0Jykge1xuICAgICAgICBhZGRBZHNMYWJlbCgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcGxheWVyVXRpbHMub25jZShwbGF5ZXIsIFsndmFzdC5hZEVuZCcsICd2YXN0LmFkc0NhbmNlbCddLCByZW1vdmVBZHNMYWJlbCk7XG5cbiAgICBpZiAodXRpbGl0aWVzLmlzSURldmljZSgpKSB7XG4gICAgICBwcmV2ZW50TWFudWFsUHJvZ3Jlc3MoKTtcbiAgICB9XG5cbiAgICBwbGF5ZXIudmFzdC52YXN0UmVzcG9uc2UgPSB2YXN0UmVzcG9uc2U7XG4gICAgcGxheWVyLnZhc3QuYWRVbml0ID0gYWRJbnRlZ3JhdG9yLnBsYXlBZCh2YXN0UmVzcG9uc2UsIGNhbGxiYWNrKTtcblxuICAgIC8qKiogTG9jYWwgZnVuY3Rpb25zICoqKiovXG4gICAgZnVuY3Rpb24gYWRkQWRzTGFiZWwoKSB7XG4gICAgICBpZiAoYWRGaW5pc2hlZCB8fCBwbGF5ZXIuY29udHJvbEJhci5nZXRDaGlsZCgnQWRzTGFiZWwnKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHBsYXllci5jb250cm9sQmFyLmFkZENoaWxkKCdBZHNMYWJlbCcpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlbW92ZUFkc0xhYmVsKCkge1xuICAgICAgcGxheWVyLmNvbnRyb2xCYXIucmVtb3ZlQ2hpbGQoJ0Fkc0xhYmVsJyk7XG4gICAgICBhZEZpbmlzaGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmV2ZW50TWFudWFsUHJvZ3Jlc3MoKSB7XG4gICAgICAvL0lPUyB2aWRlbyBjbG9jayBpcyB2ZXJ5IHVucmVsaWFibGUgYW5kIHdlIG5lZWQgYSAzIHNlY29uZHMgdGhyZXNob2xkIHRvIGVuc3VyZSB0aGF0IHRoZSB1c2VyIGZvcndhcmRlZC9yZXdvdW5kIHRoZSBhZFxuICAgICAgdmFyIFBST0dSRVNTX1RIUkVTSE9MRCA9IDM7XG4gICAgICB2YXIgcHJldmlvdXNUaW1lID0gMDtcbiAgICAgIHZhciBza2lwYWRfYXR0ZW1wdHMgPSAwO1xuXG4gICAgICBwbGF5ZXIub24oJ3RpbWV1cGRhdGUnLCBhZFRpbWV1cGRhdGVIYW5kbGVyKTtcbiAgICAgIHBsYXllclV0aWxzLm9uY2UocGxheWVyLCBbJ3Zhc3QuYWRFbmQnLCAndmFzdC5hZHNDYW5jZWwnLCAndmFzdC5hZEVycm9yJ10sIHN0b3BQcmV2ZW50TWFudWFsUHJvZ3Jlc3MpO1xuXG4gICAgICAvKioqIExvY2FsIGZ1bmN0aW9ucyAqKiovXG4gICAgICBmdW5jdGlvbiBhZFRpbWV1cGRhdGVIYW5kbGVyKCkge1xuICAgICAgICB2YXIgY3VycmVudFRpbWUgPSBwbGF5ZXIuY3VycmVudFRpbWUoKTtcbiAgICAgICAgdmFyIHByb2dyZXNzRGVsdGEgPSBNYXRoLmFicyhjdXJyZW50VGltZSAtIHByZXZpb3VzVGltZSk7XG5cbiAgICAgICAgaWYgKHByb2dyZXNzRGVsdGEgPiBQUk9HUkVTU19USFJFU0hPTEQpIHtcbiAgICAgICAgICBza2lwYWRfYXR0ZW1wdHMgKz0gMTtcbiAgICAgICAgICBpZiAoc2tpcGFkX2F0dGVtcHRzID49IDIpIHtcbiAgICAgICAgICAgIHBsYXllci5wYXVzZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBwbGF5ZXIuY3VycmVudFRpbWUocHJldmlvdXNUaW1lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcmV2aW91c1RpbWUgPSBjdXJyZW50VGltZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBzdG9wUHJldmVudE1hbnVhbFByb2dyZXNzKCkge1xuICAgICAgICBwbGF5ZXIub2ZmKCd0aW1ldXBkYXRlJywgYWRUaW1ldXBkYXRlSGFuZGxlcik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdHJhY2tBZEVycm9yKGVycm9yLCB2YXN0UmVzcG9uc2UpIHtcbiAgICBwbGF5ZXIudHJpZ2dlcih7dHlwZTogJ3Zhc3QuYWRFcnJvcicsIGVycm9yOiBlcnJvcn0pO1xuICAgIGNhbmNlbEFkcygpO1xuICAgIGlmIChjb25zb2xlICYmIGNvbnNvbGUubG9nKSB7XG4gICAgICBjb25zb2xlLmxvZygnQUQgRVJST1I6JywgZXJyb3IubWVzc2FnZSwgZXJyb3IsIHZhc3RSZXNwb25zZSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaXNWUEFJRCh2YXN0UmVzcG9uc2UpIHtcbiAgICB2YXIgaSwgbGVuO1xuICAgIHZhciBtZWRpYUZpbGVzID0gdmFzdFJlc3BvbnNlLm1lZGlhRmlsZXM7XG4gICAgZm9yIChpID0gMCwgbGVuID0gbWVkaWFGaWxlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgaWYgKHZhc3RVdGlsLmlzVlBBSUQobWVkaWFGaWxlc1tpXSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTsiLCIvL1NtYWxsIHN1YnNldCBvZiBhc3luY1xuXG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbnZhciBhc3luYyA9IHt9O1xuXG5hc3luYy5zZXRJbW1lZGlhdGUgPSBmdW5jdGlvbiAoZm4pIHtcbiAgc2V0VGltZW91dChmbiwgMCk7XG59O1xuXG5hc3luYy5pdGVyYXRvciA9IGZ1bmN0aW9uICh0YXNrcykge1xuICB2YXIgbWFrZUNhbGxiYWNrID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgdmFyIGZuID0gZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHRhc2tzLmxlbmd0aCkge1xuICAgICAgICB0YXNrc1tpbmRleF0uYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmbi5uZXh0KCk7XG4gICAgfTtcbiAgICBmbi5uZXh0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIChpbmRleCA8IHRhc2tzLmxlbmd0aCAtIDEpID8gbWFrZUNhbGxiYWNrKGluZGV4ICsgMSkgOiBudWxsO1xuICAgIH07XG4gICAgcmV0dXJuIGZuO1xuICB9O1xuICByZXR1cm4gbWFrZUNhbGxiYWNrKDApO1xufTtcblxuXG5hc3luYy53YXRlcmZhbGwgPSBmdW5jdGlvbiAodGFza3MsIGNhbGxiYWNrKSB7XG4gIGNhbGxiYWNrID0gY2FsbGJhY2sgfHwgZnVuY3Rpb24gKCkgeyB9O1xuICBpZiAoIXV0aWxpdGllcy5pc0FycmF5KHRhc2tzKSkge1xuICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IHRvIHdhdGVyZmFsbCBtdXN0IGJlIGFuIGFycmF5IG9mIGZ1bmN0aW9ucycpO1xuICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICB9XG4gIGlmICghdGFza3MubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gIH1cbiAgdmFyIHdyYXBJdGVyYXRvciA9IGZ1bmN0aW9uIChpdGVyYXRvcikge1xuICAgIHJldHVybiBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIGNhbGxiYWNrLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gICAgICAgIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgdmFyIG5leHQgPSBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgIGlmIChuZXh0KSB7XG4gICAgICAgICAgYXJncy5wdXNoKHdyYXBJdGVyYXRvcihuZXh0KSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgYXJncy5wdXNoKGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgICAgICBhc3luYy5zZXRJbW1lZGlhdGUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGl0ZXJhdG9yLmFwcGx5KG51bGwsIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9O1xuICB9O1xuICB3cmFwSXRlcmF0b3IoYXN5bmMuaXRlcmF0b3IodGFza3MpKSgpO1xufTtcblxuYXN5bmMud2hlbiA9IGZ1bmN0aW9uIChjb25kaXRpb24sIGNhbGxiYWNrKSB7XG4gIGlmICghdXRpbGl0aWVzLmlzRnVuY3Rpb24oY2FsbGJhY2spKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiYXN5bmMud2hlbiBlcnJvcjogbWlzc2luZyBjYWxsYmFjayBhcmd1bWVudFwiKTtcbiAgfVxuXG4gIHZhciBpc0FsbG93ZWQgPSB1dGlsaXRpZXMuaXNGdW5jdGlvbihjb25kaXRpb24pID8gY29uZGl0aW9uIDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAhIWNvbmRpdGlvbjtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhcmdzID0gdXRpbGl0aWVzLmFycmF5TGlrZU9ialRvQXJyYXkoYXJndW1lbnRzKTtcbiAgICB2YXIgbmV4dCA9IGFyZ3MucG9wKCk7XG5cbiAgICBpZiAoaXNBbGxvd2VkLmFwcGx5KG51bGwsIGFyZ3MpKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2suYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBhcmdzLnVuc2hpZnQobnVsbCk7XG4gICAgcmV0dXJuIG5leHQuYXBwbHkobnVsbCwgYXJncyk7XG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGFzeW5jO1xuXG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxudmFyIGRvbSA9IHt9O1xuXG5kb20uaXNWaXNpYmxlID0gZnVuY3Rpb24gaXNWaXNpYmxlKGVsKSB7XG4gIHZhciBzdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsKTtcbiAgcmV0dXJuIHN0eWxlLnZpc2liaWxpdHkgIT09ICdoaWRkZW4nO1xufTtcblxuZG9tLmlzSGlkZGVuID0gZnVuY3Rpb24gaXNIaWRkZW4oZWwpIHtcbiAgdmFyIHN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWwpO1xuICByZXR1cm4gc3R5bGUuZGlzcGxheSA9PT0gJ25vbmUnO1xufTtcblxuZG9tLmlzU2hvd24gPSBmdW5jdGlvbiBpc1Nob3duKGVsKSB7XG4gIHJldHVybiAhZG9tLmlzSGlkZGVuKGVsKTtcbn07XG5cbmRvbS5oaWRlID0gZnVuY3Rpb24gaGlkZShlbCkge1xuICBlbC5fX3ByZXZfc3R5bGVfZGlzcGxheV8gPSBlbC5zdHlsZS5kaXNwbGF5O1xuICBlbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xufTtcblxuZG9tLnNob3cgPSBmdW5jdGlvbiBzaG93KGVsKSB7XG4gIGlmIChkb20uaXNIaWRkZW4oZWwpKSB7XG4gICAgZWwuc3R5bGUuZGlzcGxheSA9IGVsLl9fcHJldl9zdHlsZV9kaXNwbGF5XztcbiAgfVxuICBlbC5fX3ByZXZfc3R5bGVfZGlzcGxheV8gPSB1bmRlZmluZWQ7XG59O1xuXG5kb20uaGFzQ2xhc3MgPSBmdW5jdGlvbiBoYXNDbGFzcyhlbCwgY3NzQ2xhc3MpIHtcbiAgdmFyIGNsYXNzZXMsIGksIGxlbjtcblxuICBpZiAodXRpbGl0aWVzLmlzTm90RW1wdHlTdHJpbmcoY3NzQ2xhc3MpKSB7XG4gICAgaWYgKGVsLmNsYXNzTGlzdCkge1xuICAgICAgcmV0dXJuIGVsLmNsYXNzTGlzdC5jb250YWlucyhjc3NDbGFzcyk7XG4gICAgfVxuXG4gICAgY2xhc3NlcyA9IHV0aWxpdGllcy5pc1N0cmluZyhlbC5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykpID8gZWwuZ2V0QXR0cmlidXRlKCdjbGFzcycpLnNwbGl0KC9cXHMrLykgOiBbXTtcbiAgICBjc3NDbGFzcyA9IChjc3NDbGFzcyB8fCAnJyk7XG5cbiAgICBmb3IgKGkgPSAwLCBsZW4gPSBjbGFzc2VzLmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKSB7XG4gICAgICBpZiAoY2xhc3Nlc1tpXSA9PT0gY3NzQ2xhc3MpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn07XG5cbmRvbS5hZGRDbGFzcyA9IGZ1bmN0aW9uIChlbCwgY3NzQ2xhc3MpIHtcbiAgdmFyIGNsYXNzZXM7XG5cbiAgaWYgKHV0aWxpdGllcy5pc05vdEVtcHR5U3RyaW5nKGNzc0NsYXNzKSkge1xuICAgIGlmIChlbC5jbGFzc0xpc3QpIHtcbiAgICAgIHJldHVybiBlbC5jbGFzc0xpc3QuYWRkKGNzc0NsYXNzKTtcbiAgICB9XG5cbiAgICBjbGFzc2VzID0gdXRpbGl0aWVzLmlzU3RyaW5nKGVsLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSkgPyBlbC5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykuc3BsaXQoL1xccysvKSA6IFtdO1xuICAgIGlmICh1dGlsaXRpZXMuaXNTdHJpbmcoY3NzQ2xhc3MpICYmIHV0aWxpdGllcy5pc05vdEVtcHR5U3RyaW5nKGNzc0NsYXNzLnJlcGxhY2UoL1xccysvLCAnJykpKSB7XG4gICAgICBjbGFzc2VzLnB1c2goY3NzQ2xhc3MpO1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCdjbGFzcycsIGNsYXNzZXMuam9pbignICcpKTtcbiAgICB9XG4gIH1cbn07XG5cbmRvbS5yZW1vdmVDbGFzcyA9IGZ1bmN0aW9uIChlbCwgY3NzQ2xhc3MpIHtcbiAgdmFyIGNsYXNzZXM7XG5cbiAgaWYgKHV0aWxpdGllcy5pc05vdEVtcHR5U3RyaW5nKGNzc0NsYXNzKSkge1xuICAgIGlmIChlbC5jbGFzc0xpc3QpIHtcbiAgICAgIHJldHVybiBlbC5jbGFzc0xpc3QucmVtb3ZlKGNzc0NsYXNzKTtcbiAgICB9XG5cbiAgICBjbGFzc2VzID0gdXRpbGl0aWVzLmlzU3RyaW5nKGVsLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSkgPyBlbC5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykuc3BsaXQoL1xccysvKSA6IFtdO1xuICAgIHZhciBuZXdDbGFzc2VzID0gW107XG4gICAgdmFyIGksIGxlbjtcbiAgICBpZiAodXRpbGl0aWVzLmlzU3RyaW5nKGNzc0NsYXNzKSAmJiB1dGlsaXRpZXMuaXNOb3RFbXB0eVN0cmluZyhjc3NDbGFzcy5yZXBsYWNlKC9cXHMrLywgJycpKSkge1xuXG4gICAgICBmb3IgKGkgPSAwLCBsZW4gPSBjbGFzc2VzLmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKSB7XG4gICAgICAgIGlmIChjc3NDbGFzcyAhPT0gY2xhc3Nlc1tpXSkge1xuICAgICAgICAgIG5ld0NsYXNzZXMucHVzaChjbGFzc2VzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZWwuc2V0QXR0cmlidXRlKCdjbGFzcycsIG5ld0NsYXNzZXMuam9pbignICcpKTtcbiAgICB9XG4gIH1cbn07XG5cbmRvbS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gYWRkRXZlbnRMaXN0ZW5lcihlbCwgdHlwZSwgaGFuZGxlcikge1xuICBpZih1dGlsaXRpZXMuaXNBcnJheShlbCkpe1xuICAgIHV0aWxpdGllcy5mb3JFYWNoKGVsLCBmdW5jdGlvbihlKSB7XG4gICAgICBkb20uYWRkRXZlbnRMaXN0ZW5lcihlLCB0eXBlLCBoYW5kbGVyKTtcbiAgICB9KTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZih1dGlsaXRpZXMuaXNBcnJheSh0eXBlKSl7XG4gICAgdXRpbGl0aWVzLmZvckVhY2godHlwZSwgZnVuY3Rpb24odCkge1xuICAgICAgZG9tLmFkZEV2ZW50TGlzdGVuZXIoZWwsIHQsIGhhbmRsZXIpO1xuICAgIH0pO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChlbC5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgZWwuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBoYW5kbGVyLCBmYWxzZSk7XG4gIH0gZWxzZSBpZiAoZWwuYXR0YWNoRXZlbnQpIHtcbiAgICAvLyBXQVJOSU5HISEhIHRoaXMgaXMgYSB2ZXJ5IG5haXZlIGltcGxlbWVudGF0aW9uICFcbiAgICAvLyB0aGUgZXZlbnQgb2JqZWN0IHRoYXQgc2hvdWxkIGJlIHBhc3NlZCB0byB0aGUgaGFuZGxlclxuICAgIC8vIHdvdWxkIG5vdCBiZSB0aGVyZSBmb3IgSUU4XG4gICAgLy8gd2Ugc2hvdWxkIHVzZSBcIndpbmRvdy5ldmVudFwiIGFuZCB0aGVuIFwiZXZlbnQuc3JjRWxlbWVudFwiXG4gICAgLy8gaW5zdGVhZCBvZiBcImV2ZW50LnRhcmdldFwiXG4gICAgZWwuYXR0YWNoRXZlbnQoXCJvblwiICsgdHlwZSwgaGFuZGxlcik7XG4gIH1cbn07XG5cbmRvbS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gcmVtb3ZlRXZlbnRMaXN0ZW5lcihlbCwgdHlwZSwgaGFuZGxlcikge1xuICBpZih1dGlsaXRpZXMuaXNBcnJheShlbCkpe1xuICAgIHV0aWxpdGllcy5mb3JFYWNoKGVsLCBmdW5jdGlvbihlKSB7XG4gICAgICBkb20ucmVtb3ZlRXZlbnRMaXN0ZW5lcihlLCB0eXBlLCBoYW5kbGVyKTtcbiAgICB9KTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZih1dGlsaXRpZXMuaXNBcnJheSh0eXBlKSl7XG4gICAgdXRpbGl0aWVzLmZvckVhY2godHlwZSwgZnVuY3Rpb24odCkge1xuICAgICAgZG9tLnJlbW92ZUV2ZW50TGlzdGVuZXIoZWwsIHQsIGhhbmRsZXIpO1xuICAgIH0pO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChlbC5yZW1vdmVFdmVudExpc3RlbmVyKSB7XG4gICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBoYW5kbGVyLCBmYWxzZSk7XG4gIH0gZWxzZSBpZiAoZWwuZGV0YWNoRXZlbnQpIHtcbiAgICBlbC5kZXRhY2hFdmVudChcIm9uXCIgKyB0eXBlLCBoYW5kbGVyKTtcbiAgfSBlbHNlIHtcbiAgICBlbFtcIm9uXCIgKyB0eXBlXSA9IG51bGw7XG4gIH1cbn07XG5cbmRvbS5kaXNwYXRjaEV2ZW50ID0gZnVuY3Rpb24gZGlzcGF0Y2hFdmVudChlbCwgZXZlbnQpIHtcbiAgaWYgKGVsLmRpc3BhdGNoRXZlbnQpIHtcbiAgICBlbC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgfSBlbHNlIHtcbiAgICBlbC5maXJlRXZlbnQoXCJvblwiICsgZXZlbnQuZXZlbnRUeXBlLCBldmVudCk7XG4gIH1cbn07XG5cbmRvbS5pc0Rlc2NlbmRhbnQgPSBmdW5jdGlvbiBpc0Rlc2NlbmRhbnQocGFyZW50LCBjaGlsZCkge1xuICB2YXIgbm9kZSA9IGNoaWxkLnBhcmVudE5vZGU7XG4gIHdoaWxlIChub2RlICE9PSBudWxsKSB7XG4gICAgaWYgKG5vZGUgPT09IHBhcmVudCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuZG9tLmdldFRleHRDb250ZW50ID0gZnVuY3Rpb24gZ2V0VGV4dENvbnRlbnQoZWwpe1xuICByZXR1cm4gZWwudGV4dENvbnRlbnQgfHwgZWwudGV4dDtcbn07XG5cbmRvbS5wcmVwZW5kQ2hpbGQgPSBmdW5jdGlvbiBwcmVwZW5kQ2hpbGQocGFyZW50LCBjaGlsZCkge1xuICBpZihjaGlsZC5wYXJlbnROb2RlKXtcbiAgICBjaGlsZC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGNoaWxkKTtcbiAgfVxuICByZXR1cm4gcGFyZW50Lmluc2VydEJlZm9yZShjaGlsZCwgcGFyZW50LmZpcnN0Q2hpbGQpO1xufTtcblxuZG9tLnJlbW92ZSA9IGZ1bmN0aW9uIHJlbW92ZU5vZGUobm9kZSl7XG4gIGlmKG5vZGUgJiYgbm9kZS5wYXJlbnROb2RlKXtcbiAgICBub2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobm9kZSk7XG4gIH1cbn07XG5cbmRvbS5pc0RvbUVsZW1lbnQgPSBmdW5jdGlvbiBpc0RvbUVsZW1lbnQobykge1xuICByZXR1cm4gbyBpbnN0YW5jZW9mIEVsZW1lbnQ7XG59O1xuXG5kb20uY2xpY2sgPSBmdW5jdGlvbihlbCwgaGFuZGxlcikge1xuICBkb20uYWRkRXZlbnRMaXN0ZW5lcihlbCwgJ2NsaWNrJywgaGFuZGxlcik7XG59O1xuXG5kb20ub25jZSA9IGZ1bmN0aW9uKGVsLCB0eXBlLCBoYW5kbGVyKSB7XG4gIGZ1bmN0aW9uIGhhbmRsZXJXcmFwKCkge1xuICAgIGhhbmRsZXIuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICBkb20ucmVtb3ZlRXZlbnRMaXN0ZW5lcihlbCwgdHlwZSwgaGFuZGxlcldyYXApO1xuICB9XG5cbiAgZG9tLmFkZEV2ZW50TGlzdGVuZXIoZWwsIHR5cGUsIGhhbmRsZXJXcmFwKTtcbn07XG5cbi8vTm90ZTogdGhlcmUgaXMgbm8gZ2V0Qm91bmRpbmdDbGllbnRSZWN0IG9uIGlQYWQgc28gd2UgbmVlZCBhIGZhbGxiYWNrXG5kb20uZ2V0RGltZW5zaW9uID0gZnVuY3Rpb24gZ2V0RGltZW5zaW9uKGVsZW1lbnQpIHtcbiAgdmFyIHJlY3Q7XG5cbiAgLy9PbiBJRTkgYW5kIGJlbG93IGdldEJvdW5kaW5nQ2xpZW50UmVjdCBkb2VzIG5vdCB3b3JrIGNvbnNpc3RlbnRseVxuICBpZighdXRpbGl0aWVzLmlzT2xkSUUoKSAmJiBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCkge1xuICAgIHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHJldHVybiB7XG4gICAgICB3aWR0aDogcmVjdC53aWR0aCxcbiAgICAgIGhlaWdodDogcmVjdC5oZWlnaHRcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB3aWR0aDogZWxlbWVudC5vZmZzZXRXaWR0aCxcbiAgICBoZWlnaHQ6IGVsZW1lbnQub2Zmc2V0SGVpZ2h0XG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRvbTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciB1cmxVdGlscyA9IHJlcXVpcmUoJy4vdXJsVXRpbHMnKTtcbnZhciB1dGlsaXRpZXMgPSByZXF1aXJlKCcuL3V0aWxpdHlGdW5jdGlvbnMnKTtcblxuZnVuY3Rpb24gSHR0cFJlcXVlc3RFcnJvcihtZXNzYWdlKSB7XG4gIHRoaXMubWVzc2FnZSA9ICdIdHRwUmVxdWVzdCBFcnJvcjogJyArIChtZXNzYWdlIHx8ICcnKTtcbn1cbkh0dHBSZXF1ZXN0RXJyb3IucHJvdG90eXBlID0gbmV3IEVycm9yKCk7XG5IdHRwUmVxdWVzdEVycm9yLnByb3RvdHlwZS5uYW1lID0gXCJIdHRwUmVxdWVzdCBFcnJvclwiO1xuXG5mdW5jdGlvbiBIdHRwUmVxdWVzdChjcmVhdGVYaHIpIHtcbiAgaWYgKCF1dGlsaXRpZXMuaXNGdW5jdGlvbihjcmVhdGVYaHIpKSB7XG4gICAgdGhyb3cgbmV3IEh0dHBSZXF1ZXN0RXJyb3IoJ01pc3NpbmcgWE1MSHR0cFJlcXVlc3QgZmFjdG9yeSBtZXRob2QnKTtcbiAgfVxuXG4gIHRoaXMuY3JlYXRlWGhyID0gY3JlYXRlWGhyO1xufVxuXG5IdHRwUmVxdWVzdC5wcm90b3R5cGUucnVuID0gZnVuY3Rpb24gKG1ldGhvZCwgdXJsLCBjYWxsYmFjaywgb3B0aW9ucykge1xuICBzYW5pdHlDaGVjayh1cmwsIGNhbGxiYWNrLCBvcHRpb25zKTtcbiAgdmFyIHRpbWVvdXQsIHRpbWVvdXRJZDtcbiAgdmFyIHhociA9IHRoaXMuY3JlYXRlWGhyKCk7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICB0aW1lb3V0ID0gdXRpbGl0aWVzLmlzTnVtYmVyKG9wdGlvbnMudGltZW91dCkgPyBvcHRpb25zLnRpbWVvdXQgOiAwO1xuXG4gIHhoci5vcGVuKG1ldGhvZCwgdXJsVXRpbHMudXJsUGFydHModXJsKS5ocmVmLCB0cnVlKTtcblxuICBpZiAob3B0aW9ucy5oZWFkZXJzKSB7XG4gICAgc2V0SGVhZGVycyh4aHIsIG9wdGlvbnMuaGVhZGVycyk7XG4gIH1cblxuICBpZiAob3B0aW9ucy53aXRoQ3JlZGVudGlhbHMpIHtcbiAgICB4aHIud2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcbiAgfVxuXG4gIHhoci5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHN0YXR1c1RleHQsIHJlc3BvbnNlLCBzdGF0dXM7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb25seSB3YXkgdG8gZG8gYSBzZWN1cmUgcmVxdWVzdCBvbiBJRTggYW5kIElFOSBpcyB3aXRoIHRoZSBYRG9tYWluUmVxdWVzdCBvYmplY3QuIFVuZm9ydHVuYXRlbHksIG1pY3Jvc29mdCBpc1xuICAgICAqIHNvIG5pY2UgdGhhdCBkZWNpZGVkIHRoYXQgdGhlIHN0YXR1cyBwcm9wZXJ0eSBhbmQgdGhlICdnZXRBbGxSZXNwb25zZUhlYWRlcnMnIG1ldGhvZCB3aGVyZSBub3QgbmVlZGVkIHNvIHdlIGhhdmUgdG9cbiAgICAgKiBmYWtlIHRoZW0uIElmIHRoZSByZXF1ZXN0IGdldHMgZG9uZSB3aXRoIGFuIFhEb21haW5SZXF1ZXN0IGluc3RhbmNlLCB3ZSB3aWxsIGFzc3VtZSB0aGF0IHRoZXJlIGFyZSBubyBoZWFkZXJzIGFuZFxuICAgICAqIHRoZSBzdGF0dXMgd2lsbCBhbHdheXMgYmUgMjAwLiBJZiB5b3UgZG9uJ3QgbGlrZSBpdCwgRE8gTk9UIFVTRSBBTkNJRU5UIEJST1dTRVJTISEhXG4gICAgICpcbiAgICAgKiBGb3IgbW9yIGluZm8gZ28gdG86IGh0dHBzOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvY2MyODgwNjAodj12cy44NSkuYXNweFxuICAgICAqL1xuICAgIGlmICgheGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycykge1xuICAgICAgeGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICgheGhyLnN0YXR1cykge1xuICAgICAgeGhyLnN0YXR1cyA9IDIwMDtcbiAgICB9XG5cbiAgICBpZiAodXRpbGl0aWVzLmlzRGVmaW5lZCh0aW1lb3V0SWQpKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgIHRpbWVvdXRJZCA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBzdGF0dXNUZXh0ID0geGhyLnN0YXR1c1RleHQgfHwgJyc7XG5cbiAgICAvLyByZXNwb25zZVRleHQgaXMgdGhlIG9sZC1zY2hvb2wgd2F5IG9mIHJldHJpZXZpbmcgcmVzcG9uc2UgKHN1cHBvcnRlZCBieSBJRTggJiA5KVxuICAgIC8vIHJlc3BvbnNlL3Jlc3BvbnNlVHlwZSBwcm9wZXJ0aWVzIHdlcmUgaW50cm9kdWNlZCBpbiBYSFIgTGV2ZWwyIHNwZWMgKHN1cHBvcnRlZCBieSBJRTEwKVxuICAgIHJlc3BvbnNlID0gKCdyZXNwb25zZScgaW4geGhyKSA/IHhoci5yZXNwb25zZSA6IHhoci5yZXNwb25zZVRleHQ7XG5cbiAgICAvLyBub3JtYWxpemUgSUU5IGJ1ZyAoaHR0cDovL2J1Z3MuanF1ZXJ5LmNvbS90aWNrZXQvMTQ1MClcbiAgICBzdGF0dXMgPSB4aHIuc3RhdHVzID09PSAxMjIzID8gMjA0IDogeGhyLnN0YXR1cztcblxuICAgIGNhbGxiYWNrKFxuICAgICAgc3RhdHVzLFxuICAgICAgcmVzcG9uc2UsXG4gICAgICB4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCksXG4gICAgICBzdGF0dXNUZXh0KTtcbiAgfTtcblxuICB4aHIub25lcnJvciA9IHJlcXVlc3RFcnJvcjtcbiAgeGhyLm9uYWJvcnQgPSByZXF1ZXN0RXJyb3I7XG5cbiAgeGhyLnNlbmQoKTtcblxuICBpZiAodGltZW91dCA+IDApIHtcbiAgICB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHhociAmJiB4aHIuYWJvcnQoKTtcbiAgICB9LCB0aW1lb3V0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNhbml0eUNoZWNrKHVybCwgY2FsbGJhY2ssIG9wdGlvbnMpIHtcbiAgICBpZiAoIXV0aWxpdGllcy5pc1N0cmluZyh1cmwpIHx8IHV0aWxpdGllcy5pc0VtcHR5U3RyaW5nKHVybCkpIHtcbiAgICAgIHRocm93IG5ldyBIdHRwUmVxdWVzdEVycm9yKFwiSW52YWxpZCB1cmwgJ1wiICsgdXJsICsgXCInXCIpO1xuICAgIH1cblxuICAgIGlmICghdXRpbGl0aWVzLmlzRnVuY3Rpb24oY2FsbGJhY2spKSB7XG4gICAgICB0aHJvdyBuZXcgSHR0cFJlcXVlc3RFcnJvcihcIkludmFsaWQgaGFuZGxlciAnXCIgKyBjYWxsYmFjayArIFwiJyBmb3IgdGhlIGh0dHAgcmVxdWVzdFwiKTtcbiAgICB9XG5cbiAgICBpZiAodXRpbGl0aWVzLmlzRGVmaW5lZChvcHRpb25zKSAmJiAhdXRpbGl0aWVzLmlzT2JqZWN0KG9wdGlvbnMpKSB7XG4gICAgICB0aHJvdyBuZXcgSHR0cFJlcXVlc3RFcnJvcihcIkludmFsaWQgb3B0aW9ucyBtYXAgJ1wiICsgb3B0aW9ucyArIFwiJ1wiKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBzZXRIZWFkZXJzKHhociwgaGVhZGVycykge1xuICAgIHV0aWxpdGllcy5mb3JFYWNoKGhlYWRlcnMsIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICBpZiAodXRpbGl0aWVzLmlzRGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoa2V5LCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiByZXF1ZXN0RXJyb3IoKSB7XG4gICAgY2FsbGJhY2soLTEsIG51bGwsIG51bGwsICcnKTtcbiAgfVxufTtcblxuSHR0cFJlcXVlc3QucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uICh1cmwsIGNhbGxiYWNrLCBvcHRpb25zKSB7XG4gIHRoaXMucnVuKCdHRVQnLCB1cmwsIHByb2Nlc3NSZXNwb25zZSwgb3B0aW9ucyk7XG5cbiAgZnVuY3Rpb24gcHJvY2Vzc1Jlc3BvbnNlKHN0YXR1cywgcmVzcG9uc2UsIGhlYWRlcnNTdHJpbmcsIHN0YXR1c1RleHQpIHtcbiAgICBpZiAoaXNTdWNjZXNzKHN0YXR1cykpIHtcbiAgICAgIGNhbGxiYWNrKG51bGwsIHJlc3BvbnNlLCBzdGF0dXMsIGhlYWRlcnNTdHJpbmcsIHN0YXR1c1RleHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjYWxsYmFjayhuZXcgSHR0cFJlcXVlc3RFcnJvcihzdGF0dXNUZXh0KSwgcmVzcG9uc2UsIHN0YXR1cywgaGVhZGVyc1N0cmluZywgc3RhdHVzVGV4dCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaXNTdWNjZXNzKHN0YXR1cykge1xuICAgIHJldHVybiAyMDAgPD0gc3RhdHVzICYmIHN0YXR1cyA8IDMwMDtcbiAgfVxufTtcblxuZnVuY3Rpb24gY3JlYXRlWGhyKCkge1xuICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gIGlmICghKFwid2l0aENyZWRlbnRpYWxzXCIgaW4geGhyKSkge1xuICAgIC8vIFhEb21haW5SZXF1ZXN0IGZvciBJRS5cbiAgICB4aHIgPSBuZXcgWERvbWFpblJlcXVlc3QoKTtcbiAgfVxuICByZXR1cm4geGhyO1xufVxuXG52YXIgaHR0cCA9IG5ldyBIdHRwUmVxdWVzdChjcmVhdGVYaHIpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgaHR0cDogaHR0cCxcbiAgSHR0cFJlcXVlc3Q6IEh0dHBSZXF1ZXN0LFxuICBIdHRwUmVxdWVzdEVycm9yOiBIdHRwUmVxdWVzdEVycm9yLFxuICBjcmVhdGVYaHI6IGNyZWF0ZVhoclxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGRvbSA9IHJlcXVpcmUoJy4vZG9tJyk7XG52YXIgdXRpbGl0aWVzID0gcmVxdWlyZSgnLi91dGlsaXR5RnVuY3Rpb25zJyk7XG5cbnZhciBwbGF5ZXJVdGlscyA9IHt9O1xuXG4vKipcbiAqIFJldHVybnMgYW4gb2JqZWN0IHRoYXQgY2FwdHVyZXMgdGhlIHBvcnRpb25zIG9mIHBsYXllciBzdGF0ZSByZWxldmFudCB0b1xuICogdmlkZW8gcGxheWJhY2suIFRoZSByZXN1bHQgb2YgdGhpcyBmdW5jdGlvbiBjYW4gYmUgcGFzc2VkIHRvXG4gKiByZXN0b3JlUGxheWVyU25hcHNob3Qgd2l0aCBhIHBsYXllciB0byByZXR1cm4gdGhlIHBsYXllciB0byB0aGUgc3RhdGUgaXRcbiAqIHdhcyBpbiB3aGVuIHRoaXMgZnVuY3Rpb24gd2FzIGludm9rZWQuXG4gKiBAcGFyYW0ge29iamVjdH0gcGxheWVyIFRoZSB2aWRlb2pzIHBsYXllciBvYmplY3RcbiAqL1xucGxheWVyVXRpbHMuZ2V0UGxheWVyU25hcHNob3QgPSBmdW5jdGlvbiBnZXRQbGF5ZXJTbmFwc2hvdChwbGF5ZXIpIHtcbiAgdmFyIHRlY2ggPSBwbGF5ZXIuZWwoKS5xdWVyeVNlbGVjdG9yKCcudmpzLXRlY2gnKTtcblxuICB2YXIgc25hcHNob3QgPSB7XG4gICAgZW5kZWQ6IHBsYXllci5lbmRlZCgpLFxuICAgIHNyYzogcGxheWVyLmN1cnJlbnRTcmMoKSxcbiAgICBjdXJyZW50VGltZTogcGxheWVyLmN1cnJlbnRUaW1lKCksXG4gICAgdHlwZTogcGxheWVyLmN1cnJlbnRUeXBlKCksXG4gICAgcGxheWluZzogIXBsYXllci5wYXVzZWQoKSxcbiAgICBzdXBwcmVzc2VkVHJhY2tzOiBnZXRTdXBwcmVzc2VkVHJhY2tzKHBsYXllcilcbiAgfTtcblxuICBpZiAodGVjaCkge1xuICAgIHNuYXBzaG90Lm5hdGl2ZVBvc3RlciA9IHRlY2gucG9zdGVyO1xuICAgIHNuYXBzaG90LnN0eWxlID0gdGVjaC5nZXRBdHRyaWJ1dGUoJ3N0eWxlJyk7XG4gIH1cbiAgcmV0dXJuIHNuYXBzaG90O1xuXG4gIC8qKioqIExvY2FsIEZ1bmN0aW9ucyAqKioqL1xuICBmdW5jdGlvbiBnZXRTdXBwcmVzc2VkVHJhY2tzKHBsYXllcikge1xuICAgIHZhciB0cmFja3MgPSBwbGF5ZXIucmVtb3RlVGV4dFRyYWNrcyA/IHBsYXllci5yZW1vdGVUZXh0VHJhY2tzKCkgOiBbXTtcblxuICAgIGlmICh0cmFja3MgJiYgdXRpbGl0aWVzLmlzQXJyYXkodHJhY2tzLnRyYWNrc18pKSB7XG4gICAgICB0cmFja3MgPSB0cmFja3MudHJhY2tzXztcbiAgICB9XG5cbiAgICBpZiAoIXV0aWxpdGllcy5pc0FycmF5KHRyYWNrcykpIHtcbiAgICAgIHRyYWNrcyA9IFtdO1xuICAgIH1cblxuICAgIHZhciBzdXBwcmVzc2VkVHJhY2tzID0gW107XG4gICAgdHJhY2tzLmZvckVhY2goZnVuY3Rpb24gKHRyYWNrKSB7XG4gICAgICBzdXBwcmVzc2VkVHJhY2tzLnB1c2goe1xuICAgICAgICB0cmFjazogdHJhY2ssXG4gICAgICAgIG1vZGU6IHRyYWNrLm1vZGVcbiAgICAgIH0pO1xuICAgICAgdHJhY2subW9kZSA9ICdkaXNhYmxlZCc7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc3VwcHJlc3NlZFRyYWNrcztcbiAgfVxufTtcblxuLyoqXG4gKiBBdHRlbXB0cyB0byBtb2RpZnkgdGhlIHNwZWNpZmllZCBwbGF5ZXIgc28gdGhhdCBpdHMgc3RhdGUgaXMgZXF1aXZhbGVudCB0b1xuICogdGhlIHN0YXRlIG9mIHRoZSBzbmFwc2hvdC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBzbmFwc2hvdCAtIHRoZSBwbGF5ZXIgc3RhdGUgdG8gYXBwbHlcbiAqL1xucGxheWVyVXRpbHMucmVzdG9yZVBsYXllclNuYXBzaG90ID0gZnVuY3Rpb24gcmVzdG9yZVBsYXllclNuYXBzaG90KHBsYXllciwgc25hcHNob3QpIHtcbiAgdmFyIHRlY2ggPSBwbGF5ZXIuZWwoKS5xdWVyeVNlbGVjdG9yKCcudmpzLXRlY2gnKTtcbiAgdmFyIGF0dGVtcHRzID0gMjA7IC8vIHRoZSBudW1iZXIgb2YgcmVtYWluaW5nIGF0dGVtcHRzIHRvIHJlc3RvcmUgdGhlIHNuYXBzaG90XG5cbiAgaWYgKHNuYXBzaG90Lm5hdGl2ZVBvc3Rlcikge1xuICAgIHRlY2gucG9zdGVyID0gc25hcHNob3QubmF0aXZlUG9zdGVyO1xuICB9XG5cbiAgaWYgKCdzdHlsZScgaW4gc25hcHNob3QpIHtcbiAgICAvLyBvdmVyd3JpdGUgYWxsIGNzcyBzdHlsZSBwcm9wZXJ0aWVzIHRvIHJlc3RvcmUgc3RhdGUgcHJlY2lzZWx5XG4gICAgdGVjaC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgc25hcHNob3Quc3R5bGUgfHwgJycpO1xuICB9XG5cbiAgaWYgKGhhc1NyY0NoYW5nZWQocGxheWVyLCBzbmFwc2hvdCkpIHtcblxuICAgIC8vIG9uIGlvczcsIGZpZGRsaW5nIHdpdGggdGV4dFRyYWNrcyB0b28gZWFybHkgd2lsbCBjYXVzZSBzYWZhcmkgdG8gY3Jhc2hcbiAgICBwbGF5ZXIub25lKCdjb250ZW50bG9hZGVkbWV0YWRhdGEnLCByZXN0b3JlVHJhY2tzKTtcblxuICAgIHBsYXllci5vbmUoJ2NhbnBsYXknLCB0cnlUb1Jlc3VtZSk7XG4gICAgZW5zdXJlQ2FucGxheUV2dEdldHNGaXJlZCgpO1xuXG4gICAgLy8gaWYgdGhlIHNyYyBjaGFuZ2VkIGZvciBhZCBwbGF5YmFjaywgcmVzZXQgaXRcbiAgICBwbGF5ZXIuc3JjKHtzcmM6IHNuYXBzaG90LnNyYywgdHlwZTogc25hcHNob3QudHlwZX0pO1xuXG4gICAgLy8gc2FmYXJpIHJlcXVpcmVzIGEgY2FsbCB0byBgbG9hZGAgdG8gcGljayB1cCBhIGNoYW5nZWQgc291cmNlXG4gICAgcGxheWVyLmxvYWQoKTtcblxuICB9IGVsc2Uge1xuICAgIHJlc3RvcmVUcmFja3MoKTtcblxuICAgIGlmIChzbmFwc2hvdC5wbGF5aW5nKSB7XG4gICAgICBwbGF5ZXIucGxheSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiogTG9jYWwgRnVuY3Rpb25zICoqKi9cblxuICAvKipcbiAgICogU29tZXRpbWVzIGZpcmVmb3ggZG9lcyBub3QgdHJpZ2dlciB0aGUgJ2NhbnBsYXknIGV2dC5cbiAgICogVGhpcyBjb2RlIGVuc3VyZSB0aGF0IGl0IGFsd2F5cyBnZXRzIHRyaWdnZXJlZCB0cmlnZ2VyZWQuXG4gICAqL1xuICBmdW5jdGlvbiBlbnN1cmVDYW5wbGF5RXZ0R2V0c0ZpcmVkKCkge1xuICAgIHZhciB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgcGxheWVyLnRyaWdnZXIoJ2NhbnBsYXknKTtcbiAgICB9LCAxMDAwKTtcblxuICAgIHBsYXllci5vbmUoJ2NhbnBsYXknLCBmdW5jdGlvbigpe1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIHBsYXllciBuZWVkcyB0byBiZSByZXN0b3JlZCB0byBpdHMgc3RhdGVcbiAgICogYmVmb3JlIGFkIHBsYXliYWNrIGJlZ2FuLiBXaXRoIGEgY3VzdG9tIGFkIGRpc3BsYXkgb3IgYnVybmVkLWluXG4gICAqIGFkcywgdGhlIGNvbnRlbnQgcGxheWVyIHN0YXRlIGhhc24ndCBiZWVuIG1vZGlmaWVkIGFuZCBzbyBub1xuICAgKiByZXN0b3JhdGlvbiBpcyByZXF1aXJlZFxuICAgKi9cbiAgZnVuY3Rpb24gaGFzU3JjQ2hhbmdlZChwbGF5ZXIsIHNuYXBzaG90KSB7XG4gICAgaWYgKHBsYXllci5zcmMoKSkge1xuICAgICAgcmV0dXJuIHBsYXllci5zcmMoKSAhPT0gc25hcHNob3Quc3JjO1xuICAgIH1cbiAgICAvLyB0aGUgcGxheWVyIHdhcyBjb25maWd1cmVkIHRocm91Z2ggc291cmNlIGVsZW1lbnQgY2hpbGRyZW5cbiAgICByZXR1cm4gcGxheWVyLmN1cnJlbnRTcmMoKSAhPT0gc25hcHNob3Quc3JjO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzdG9yZVRyYWNrcygpIHtcbiAgICB2YXIgc3VwcHJlc3NlZFRyYWNrcyA9IHNuYXBzaG90LnN1cHByZXNzZWRUcmFja3M7XG4gICAgc3VwcHJlc3NlZFRyYWNrcy5mb3JFYWNoKGZ1bmN0aW9uICh0cmFja1NuYXBzaG90KSB7XG4gICAgICB0cmFja1NuYXBzaG90LnRyYWNrLm1vZGUgPSB0cmFja1NuYXBzaG90Lm1vZGU7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lIGlmIHRoZSB2aWRlbyBlbGVtZW50IGhhcyBsb2FkZWQgZW5vdWdoIG9mIHRoZSBzbmFwc2hvdCBzb3VyY2VcbiAgICogdG8gYmUgcmVhZHkgdG8gYXBwbHkgdGhlIHJlc3Qgb2YgdGhlIHN0YXRlXG4gICAqL1xuICBmdW5jdGlvbiB0cnlUb1Jlc3VtZSgpIHtcblxuICAgIC8vIGlmIHNvbWUgcGVyaW9kIG9mIHRoZSB2aWRlbyBpcyBzZWVrYWJsZSwgcmVzdW1lIHBsYXliYWNrXG4gICAgLy8gb3RoZXJ3aXNlIGRlbGF5IGEgYml0IGFuZCB0aGVuIGNoZWNrIGFnYWluIHVubGVzcyB3ZSdyZSBvdXQgb2YgYXR0ZW1wdHNcblxuICAgIGlmICghcGxheWVyVXRpbHMuaXNSZWFkeVRvUmVzdW1lKHBsYXllcikgJiYgYXR0ZW1wdHMtLSkge1xuICAgICAgc2V0VGltZW91dCh0cnlUb1Jlc3VtZSwgNTApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0cnkge1xuICAgICAgICBpZihwbGF5ZXIuY3VycmVudFRpbWUoKSAhPT0gc25hcHNob3QuY3VycmVudFRpbWUpIHtcbiAgICAgICAgICBpZiAoc25hcHNob3QucGxheWluZykgeyAvLyBpZiBuZWVkZWQgcmVzdG9yZSBwbGF5aW5nIHN0YXR1cyBhZnRlciBzZWVrIGNvbXBsZXRlc1xuICAgICAgICAgICAgcGxheWVyLm9uZSgnc2Vla2VkJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgIHBsYXllci5wbGF5KCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcGxheWVyLmN1cnJlbnRUaW1lKHNuYXBzaG90LmN1cnJlbnRUaW1lKTtcblxuICAgICAgICB9IGVsc2UgaWYgKHNuYXBzaG90LnBsYXlpbmcpIHtcbiAgICAgICAgICAvLyBpZiBuZWVkZWQgYW5kIG5vIHNlZWsgaGFzIGJlZW4gcGVyZm9ybWVkLCByZXN0b3JlIHBsYXlpbmcgc3RhdHVzIGltbWVkaWF0ZWx5XG4gICAgICAgICAgcGxheWVyLnBsYXkoKTtcbiAgICAgICAgfVxuXG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHZpZGVvanMubG9nLndhcm4oJ0ZhaWxlZCB0byByZXN1bWUgdGhlIGNvbnRlbnQgYWZ0ZXIgYW4gYWR2ZXJ0aXNlbWVudCcsIGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxucGxheWVyVXRpbHMuaXNSZWFkeVRvUmVzdW1lID0gZnVuY3Rpb24gKHBsYXllcikge1xuXG4gIGlmIChwbGF5ZXIucmVhZHlTdGF0ZSgpID4gMSkge1xuICAgIC8vIHNvbWUgYnJvd3NlcnMgYW5kIG1lZGlhIGFyZW4ndCBcInNlZWthYmxlXCIuXG4gICAgLy8gcmVhZHlTdGF0ZSBncmVhdGVyIHRoYW4gMSBhbGxvd3MgZm9yIHNlZWtpbmcgd2l0aG91dCBleGNlcHRpb25zXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBpZiAocGxheWVyLnNlZWthYmxlKCkgPT09IHVuZGVmaW5lZCkge1xuICAgIC8vIGlmIHRoZSBwbGF5ZXIgZG9lc24ndCBleHBvc2UgdGhlIHNlZWthYmxlIHRpbWUgcmFuZ2VzLCB0cnkgdG9cbiAgICAvLyByZXN1bWUgcGxheWJhY2sgaW1tZWRpYXRlbHlcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChwbGF5ZXIuc2Vla2FibGUoKS5sZW5ndGggPiAwKSB7XG4gICAgLy8gaWYgc29tZSBwZXJpb2Qgb2YgdGhlIHZpZGVvIGlzIHNlZWthYmxlLCByZXN1bWUgcGxheWJhY2tcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBwcmVwYXJlcyB0aGUgcGxheWVyIHRvIGRpc3BsYXkgYWRzLlxuICogQWRkaW5nIGNvbnZlbmllbmNlIGV2ZW50cyBsaWtlIHRoZSAndmFzdC5maXJzUGxheScgdGhhdCBnZXRzIGZpcmVkIHdoZW4gdGhlIHZpZGVvIGlzIGZpcnN0IHBsYXllZFxuICogYW5kIGFkcyB0aGUgYmxhY2tQb3N0ZXIgdG8gdGhlIHBsYXllciB0byBwcmV2ZW50IGNvbnRlbnQgZnJvbSBiZWluZyBkaXNwbGF5ZWQgYmVmb3JlIHRoZSBwcmVyb2xsIGFkLlxuICpcbiAqIEBwYXJhbSBwbGF5ZXJcbiAqL1xucGxheWVyVXRpbHMucHJlcGFyZUZvckFkcyA9IGZ1bmN0aW9uIChwbGF5ZXIpIHtcbiAgdmFyIGJsYWNrUG9zdGVyID0gcGxheWVyLmFkZENoaWxkKCdibGFja1Bvc3RlcicpO1xuICB2YXIgX2ZpcnN0UGxheSA9IHRydWU7XG4gIHZhciB2b2x1bWVTbmFwc2hvdDtcblxuXG4gIG1vbmtleVBhdGNoUGxheWVyQXBpKCk7XG5cbiAgcGxheWVyLm9uKCdwbGF5JywgdHJ5VG9UcmlnZ2VyRmlyc3RQbGF5KTtcbiAgcGxheWVyLm9uKCd2YXN0LnJlc2V0JywgcmVzZXRGaXJzdFBsYXkpOy8vRXZlcnkgdGltZSB3ZSBjaGFuZ2UgdGhlIHNvdXJjZXMgd2UgcmVzZXQgdGhlIGZpcnN0IHBsYXkuXG4gIHBsYXllci5vbigndmFzdC5maXJzdFBsYXknLCByZXN0b3JlQ29udGVudFZvbHVtZSk7XG4gIHBsYXllci5vbignZXJyb3InLCBoaWRlQmxhY2tQb3N0ZXIpOy8vSWYgdGhlcmUgaXMgYW4gZXJyb3IgaW4gdGhlIHBsYXllciB3ZSByZW1vdmUgdGhlIGJsYWNrcG9zdGVyIHRvIHNob3cgdGhlIGVyciBtc2dcbiAgcGxheWVyLm9uKCd2YXN0LmFkU3RhcnQnLCBoaWRlQmxhY2tQb3N0ZXIpO1xuICBwbGF5ZXIub24oJ3Zhc3QuYWRzQ2FuY2VsJywgaGlkZUJsYWNrUG9zdGVyKTtcbiAgcGxheWVyLm9uKCd2YXN0LmFkRXJyb3InLCBoaWRlQmxhY2tQb3N0ZXIpO1xuICBwbGF5ZXIub24oJ3Zhc3QuYWRTdGFydCcsIGFkZFN0eWxlcyk7XG4gIHBsYXllci5vbigndmFzdC5hZEVuZCcsIHJlbW92ZVN0eWxlcyk7XG4gIHBsYXllci5vbigndmFzdC5hZHNDYW5jZWwnLCByZW1vdmVTdHlsZXMpO1xuXG4gIC8qKiogTG9jYWwgRnVuY3Rpb25zICoqKi9cblxuICAvKipcbiAgIFdoYXQgdGhpcyBmdW5jdGlvbiBkb2VzIGlzIHVnbHkgYW5kIGhvcnJpYmxlIGFuZCBJIHNob3VsZCB0aGluayB0d2ljZSBiZWZvcmUgY2FsbGluZyBteXNlbGYgYSBnb29kIGRldmVsb3Blci4gV2l0aCB0aGF0IHNhaWQsXG4gICBpdCBpcyB0aGUgYmVzdCBzb2x1dGlvbiBJIGNvdWxkIGZpbmQgdG8gbXV0ZSB0aGUgdmlkZW8gdW50aWwgdGhlICdwbGF5JyBldmVudCBoYXBwZW5zIChvbiBtb2JpbGUgZGV2aWNlcykgYW5kIHRoZSBwbHVnaW4gY2FuIGRlY2lkZSB3aGV0aGVyXG4gICB0byBwbGF5IHRoZSBhZCBvciBub3QuXG5cbiAgIFdlIGFsc28gbmVlZCB0aGlzIG1vbmtleXBhdGNoIHRvIGJlIGFibGUgdG8gcGF1c2UgYW5kIHJlc3VtZSBhbiBhZCB1c2luZyB0aGUgcGxheWVyJ3MgQVBJXG5cbiAgIElmIHlvdSBoYXZlIGEgYmV0dGVyIHNvbHV0aW9uIHBsZWFzZSBkbyB0ZWxsIG1lLlxuICAgKi9cbiAgZnVuY3Rpb24gbW9ua2V5UGF0Y2hQbGF5ZXJBcGkoKSB7XG5cbiAgICAvKipcbiAgICAgKiBNb25rZXkgcGF0Y2ggbmVlZGVkIHRvIGhhbmRsZSBmaXJzdFBsYXkgYW5kIHJlc3VtZSBvZiBwbGF5aW5nIGFkLlxuICAgICAqXG4gICAgICogQHBhcmFtIGNhbGxPcmlnUGxheSBuZWNlc3NhcnkgZmxhZyB0byBwcmV2ZW50IGluZmluaXRlIGxvb3Agd2hlbiB5b3UgYXJlIHJlc3RvcmluZyBhIFZBU1QgYWQuXG4gICAgICogQHJldHVybnMge3BsYXllcn1cbiAgICAgKi9cbiAgICB2YXIgb3JpZ1BsYXkgPSBwbGF5ZXIucGxheTtcbiAgICBwbGF5ZXIucGxheSA9IGZ1bmN0aW9uIChjYWxsT3JpZ1BsYXkpIHtcbiAgICAgIHZhciB0aGF0ID0gdGhpcztcblxuICAgICAgaWYgKGlzRmlyc3RQbGF5KCkpIHtcbiAgICAgICAgZmlyc3RQbGF5KCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bWUoY2FsbE9yaWdQbGF5KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIC8qKiogbG9jYWwgZnVuY3Rpb25zICoqKi9cbiAgICAgIGZ1bmN0aW9uIGZpcnN0UGxheSgpIHtcbiAgICAgICAgaWYgKCF1dGlsaXRpZXMuaXNJUGhvbmUoKSkge1xuICAgICAgICAgIHZvbHVtZVNuYXBzaG90ID0gc2F2ZVZvbHVtZVNuYXBzaG90KCk7XG4gICAgICAgICAgcGxheWVyLm11dGVkKHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgb3JpZ1BsYXkuYXBwbHkodGhhdCwgYXJndW1lbnRzKTtcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gcmVzdW1lKGNhbGxPcmlnUGxheSkge1xuICAgICAgICBpZiAoaXNBZFBsYXlpbmcoKSAmJiAhY2FsbE9yaWdQbGF5KSB7XG4gICAgICAgICAgcGxheWVyLnZhc3QuYWRVbml0LnJlc3VtZUFkKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb3JpZ1BsYXkuYXBwbHkodGhhdCwgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cblxuICAgIC8qKlxuICAgICAqIE5lZWRlZCBtb25rZXkgcGF0Y2ggdG8gaGFuZGxlIHBhdXNlIG9mIHBsYXlpbmcgYWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY2FsbE9yaWdQbGF5IG5lY2Vzc2FyeSBmbGFnIHRvIHByZXZlbnQgaW5maW5pdGUgbG9vcCB3aGVuIHlvdSBhcmUgcGF1c2luZyBhIFZBU1QgYWQuXG4gICAgICogQHJldHVybnMge3BsYXllcn1cbiAgICAgKi9cbiAgICB2YXIgb3JpZ1BhdXNlID0gcGxheWVyLnBhdXNlO1xuICAgIHBsYXllci5wYXVzZSA9IGZ1bmN0aW9uIChjYWxsT3JpZ1BhdXNlKSB7XG4gICAgICBpZiAoaXNBZFBsYXlpbmcoKSAmJiAhY2FsbE9yaWdQYXVzZSkge1xuICAgICAgICBwbGF5ZXIudmFzdC5hZFVuaXQucGF1c2VBZCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3JpZ1BhdXNlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5cbiAgICAvKipcbiAgICAgKiBOZWVkZWQgbW9ua2V5IHBhdGNoIHRvIGhhbmRsZSBwYXVzZWQgc3RhdGUgb2YgdGhlIHBsYXllciB3aGVuIGFkcyBhcmUgcGxheWluZy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBjYWxsT3JpZ1BsYXkgbmVjZXNzYXJ5IGZsYWcgdG8gcHJldmVudCBpbmZpbml0ZSBsb29wIHdoZW4geW91IGFyZSBwYXVzaW5nIGEgVkFTVCBhZC5cbiAgICAgKiBAcmV0dXJucyB7cGxheWVyfVxuICAgICAqL1xuICAgIHZhciBvcmlnUGF1c2VkID0gcGxheWVyLnBhdXNlZDtcbiAgICBwbGF5ZXIucGF1c2VkID0gZnVuY3Rpb24gKGNhbGxPcmlnUGF1c2VkKSB7XG4gICAgICBpZiAoaXNBZFBsYXlpbmcoKSAmJiAhY2FsbE9yaWdQYXVzZWQpIHtcbiAgICAgICAgcmV0dXJuIHBsYXllci52YXN0LmFkVW5pdC5pc1BhdXNlZCgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9yaWdQYXVzZWQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gaXNBZFBsYXlpbmcoKSB7XG4gICAgcmV0dXJuIHBsYXllci52YXN0ICYmIHBsYXllci52YXN0LmFkVW5pdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyeVRvVHJpZ2dlckZpcnN0UGxheSgpIHtcbiAgICBpZiAoaXNGaXJzdFBsYXkoKSkge1xuICAgICAgX2ZpcnN0UGxheSA9IGZhbHNlO1xuICAgICAgcGxheWVyLnRyaWdnZXIoJ3Zhc3QuZmlyc3RQbGF5Jyk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVzZXRGaXJzdFBsYXkoKSB7XG4gICAgX2ZpcnN0UGxheSA9IHRydWU7XG4gICAgYmxhY2tQb3N0ZXIuc2hvdygpO1xuICAgIHJlc3RvcmVDb250ZW50Vm9sdW1lKCk7XG4gIH1cblxuICBmdW5jdGlvbiBpc0ZpcnN0UGxheSgpIHtcbiAgICByZXR1cm4gX2ZpcnN0UGxheTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNhdmVWb2x1bWVTbmFwc2hvdCgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbXV0ZWQ6IHBsYXllci5tdXRlZCgpLFxuICAgICAgdm9sdW1lOiBwbGF5ZXIudm9sdW1lKClcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzdG9yZUNvbnRlbnRWb2x1bWUoKSB7XG4gICAgaWYgKHZvbHVtZVNuYXBzaG90KSB7XG4gICAgICBwbGF5ZXIuY3VycmVudFRpbWUoMCk7XG4gICAgICByZXN0b3JlVm9sdW1lU25hcHNob3Qodm9sdW1lU25hcHNob3QpO1xuICAgICAgdm9sdW1lU25hcHNob3QgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc3RvcmVWb2x1bWVTbmFwc2hvdChzbmFwc2hvdCkge1xuICAgIGlmICh1dGlsaXRpZXMuaXNPYmplY3Qoc25hcHNob3QpKSB7XG4gICAgICBwbGF5ZXIudm9sdW1lKHNuYXBzaG90LnZvbHVtZSk7XG4gICAgICBwbGF5ZXIubXV0ZWQoc25hcHNob3QubXV0ZWQpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGhpZGVCbGFja1Bvc3RlcigpIHtcbiAgICBpZiAoIWRvbS5oYXNDbGFzcyhibGFja1Bvc3Rlci5lbCgpLCAndmpzLWhpZGRlbicpKSB7XG4gICAgICBibGFja1Bvc3Rlci5oaWRlKCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gYWRkU3R5bGVzKCkge1xuICAgIGRvbS5hZGRDbGFzcyhwbGF5ZXIuZWwoKSwgJ3Zqcy1hZC1wbGF5aW5nJyk7XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVTdHlsZXMoKSB7XG4gICAgZG9tLnJlbW92ZUNsYXNzKHBsYXllci5lbCgpLCAndmpzLWFkLXBsYXlpbmcnKTtcbiAgfVxufTtcblxuLyoqXG4gKiBSZW1vdmUgdGhlIHBvc3RlciBhdHRyaWJ1dGUgZnJvbSB0aGUgdmlkZW8gZWxlbWVudCB0ZWNoLCBpZiBwcmVzZW50LiBXaGVuXG4gKiByZXVzaW5nIGEgdmlkZW8gZWxlbWVudCBmb3IgbXVsdGlwbGUgdmlkZW9zLCB0aGUgcG9zdGVyIGltYWdlIHdpbGwgYnJpZWZseVxuICogcmVhcHBlYXIgd2hpbGUgdGhlIG5ldyBzb3VyY2UgbG9hZHMuIFJlbW92aW5nIHRoZSBhdHRyaWJ1dGUgYWhlYWQgb2YgdGltZVxuICogcHJldmVudHMgdGhlIHBvc3RlciBmcm9tIHNob3dpbmcgdXAgYmV0d2VlbiB2aWRlb3MuXG4gKiBAcGFyYW0ge29iamVjdH0gcGxheWVyIFRoZSB2aWRlb2pzIHBsYXllciBvYmplY3RcbiAqL1xucGxheWVyVXRpbHMucmVtb3ZlTmF0aXZlUG9zdGVyID0gZnVuY3Rpb24gKHBsYXllcikge1xuICB2YXIgdGVjaCA9IHBsYXllci5lbCgpLnF1ZXJ5U2VsZWN0b3IoJy52anMtdGVjaCcpO1xuICBpZiAodGVjaCkge1xuICAgIHRlY2gucmVtb3ZlQXR0cmlidXRlKCdwb3N0ZXInKTtcbiAgfVxufTtcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gbGlzdGVuIHRvIG1hbnkgZXZlbnRzIHVudGlsIG9uZSBvZiB0aGVtIGdldHMgZmlyZWQsIHRoZW4gd2VcbiAqIGV4ZWN1dGUgdGhlIGhhbmRsZXIgYW5kIHVuc3Vic2NyaWJlIGFsbCB0aGUgZXZlbnQgbGlzdGVuZXJzO1xuICpcbiAqIEBwYXJhbSBwbGF5ZXIgc3BlY2lmaWMgcGxheWVyIGZyb20gd2hlcmUgdG8gbGlzdGVuIGZvciB0aGUgZXZlbnRzXG4gKiBAcGFyYW0gZXZlbnRzIGFycmF5IG9mIGV2ZW50c1xuICogQHBhcmFtIGhhbmRsZXIgZnVuY3Rpb24gdG8gZXhlY3V0ZSBvbmNlIG9uZSBvZiB0aGUgZXZlbnRzIGZpcmVzXG4gKi9cbnBsYXllclV0aWxzLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHBsYXllciwgZXZlbnRzLCBoYW5kbGVyKSB7XG4gIGZ1bmN0aW9uIGxpc3RlbmVyKCkge1xuICAgIGhhbmRsZXIuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcblxuICAgIGV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgcGxheWVyLm9mZihldmVudCwgbGlzdGVuZXIpO1xuICAgIH0pO1xuICB9XG5cbiAgZXZlbnRzLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgcGxheWVyLm9uKGV2ZW50LCBsaXN0ZW5lcik7XG4gIH0pO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IHBsYXllclV0aWxzOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4vdXRpbGl0eUZ1bmN0aW9ucycpO1xuXG4vKipcbiAqXG4gKiBJTVBPUlRBTlQgTk9URTogVGhpcyBmdW5jdGlvbiBjb21lcyBmcm9tIGFuZ3VsYXJKcyBhbmQgd2FzIG9yaWdpbmFsbHkgY2FsbGVkIHVybFJlc29sdmVcbiAqICAgICAgICAgICAgICAgICB5b3UgY2FuIHRha2UgYSBsb29rIGF0IHRoZSBvcmlnaW5hbCBjb2RlIGhlcmUgaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci5qcy9ibG9iL21hc3Rlci9zcmMvbmcvdXJsVXRpbHMuanNcbiAqXG4gKiBJbXBsZW1lbnRhdGlvbiBOb3RlcyBmb3Igbm9uLUlFIGJyb3dzZXJzXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBBc3NpZ25pbmcgYSBVUkwgdG8gdGhlIGhyZWYgcHJvcGVydHkgb2YgYW4gYW5jaG9yIERPTSBub2RlLCBldmVuIG9uZSBhdHRhY2hlZCB0byB0aGUgRE9NLFxuICogcmVzdWx0cyBib3RoIGluIHRoZSBub3JtYWxpemluZyBhbmQgcGFyc2luZyBvZiB0aGUgVVJMLiAgTm9ybWFsaXppbmcgbWVhbnMgdGhhdCBhIHJlbGF0aXZlXG4gKiBVUkwgd2lsbCBiZSByZXNvbHZlZCBpbnRvIGFuIGFic29sdXRlIFVSTCBpbiB0aGUgY29udGV4dCBvZiB0aGUgYXBwbGljYXRpb24gZG9jdW1lbnQuXG4gKiBQYXJzaW5nIG1lYW5zIHRoYXQgdGhlIGFuY2hvciBub2RlJ3MgaG9zdCwgaG9zdG5hbWUsIHByb3RvY29sLCBwb3J0LCBwYXRobmFtZSBhbmQgcmVsYXRlZFxuICogcHJvcGVydGllcyBhcmUgYWxsIHBvcHVsYXRlZCB0byByZWZsZWN0IHRoZSBub3JtYWxpemVkIFVSTC4gIFRoaXMgYXBwcm9hY2ggaGFzIHdpZGVcbiAqIGNvbXBhdGliaWxpdHkgLSBTYWZhcmkgMSssIE1vemlsbGEgMSssIE9wZXJhIDcrLGUgZXRjLiAgU2VlXG4gKiBodHRwOi8vd3d3LmFwdGFuYS5jb20vcmVmZXJlbmNlL2h0bWwvYXBpL0hUTUxBbmNob3JFbGVtZW50Lmh0bWxcbiAqXG4gKiBJbXBsZW1lbnRhdGlvbiBOb3RlcyBmb3IgSUVcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogSUUgPj0gOCBhbmQgPD0gMTAgbm9ybWFsaXplcyB0aGUgVVJMIHdoZW4gYXNzaWduZWQgdG8gdGhlIGFuY2hvciBub2RlIHNpbWlsYXIgdG8gdGhlIG90aGVyXG4gKiBicm93c2Vycy4gIEhvd2V2ZXIsIHRoZSBwYXJzZWQgY29tcG9uZW50cyB3aWxsIG5vdCBiZSBzZXQgaWYgdGhlIFVSTCBhc3NpZ25lZCBkaWQgbm90IHNwZWNpZnlcbiAqIHRoZW0uICAoZS5nLiBpZiB5b3UgYXNzaWduIGEuaHJlZiA9IFwiZm9vXCIsIHRoZW4gYS5wcm90b2NvbCwgYS5ob3N0LCBldGMuIHdpbGwgYmUgZW1wdHkuKSAgV2VcbiAqIHdvcmsgYXJvdW5kIHRoYXQgYnkgcGVyZm9ybWluZyB0aGUgcGFyc2luZyBpbiBhIDJuZCBzdGVwIGJ5IHRha2luZyBhIHByZXZpb3VzbHkgbm9ybWFsaXplZFxuICogVVJMIChlLmcuIGJ5IGFzc2lnbmluZyB0byBhLmhyZWYpIGFuZCBhc3NpZ25pbmcgaXQgYS5ocmVmIGFnYWluLiAgVGhpcyBjb3JyZWN0bHkgcG9wdWxhdGVzIHRoZVxuICogcHJvcGVydGllcyBzdWNoIGFzIHByb3RvY29sLCBob3N0bmFtZSwgcG9ydCwgZXRjLlxuICpcbiAqIElFNyBkb2VzIG5vdCBub3JtYWxpemUgdGhlIFVSTCB3aGVuIGFzc2lnbmVkIHRvIGFuIGFuY2hvciBub2RlLiAgKEFwcGFyZW50bHksIGl0IGRvZXMsIGlmIG9uZVxuICogdXNlcyB0aGUgaW5uZXIgSFRNTCBhcHByb2FjaCB0byBhc3NpZ24gdGhlIFVSTCBhcyBwYXJ0IG9mIGFuIEhUTUwgc25pcHBldCAtXG4gKiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS80NzI3MjkpICBIb3dldmVyLCBzZXR0aW5nIGltZ1tzcmNdIGRvZXMgbm9ybWFsaXplIHRoZSBVUkwuXG4gKiBVbmZvcnR1bmF0ZWx5LCBzZXR0aW5nIGltZ1tzcmNdIHRvIHNvbWV0aGluZyBsaWtlIFwiamF2YXNjcmlwdDpmb29cIiBvbiBJRSB0aHJvd3MgYW4gZXhjZXB0aW9uLlxuICogU2luY2UgdGhlIHByaW1hcnkgdXNhZ2UgZm9yIG5vcm1hbGl6aW5nIFVSTHMgaXMgdG8gc2FuaXRpemUgc3VjaCBVUkxzLCB3ZSBjYW4ndCB1c2UgdGhhdFxuICogbWV0aG9kIGFuZCBJRSA8IDggaXMgdW5zdXBwb3J0ZWQuXG4gKlxuICogUmVmZXJlbmNlczpcbiAqICAgaHR0cDovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvSFRNTEFuY2hvckVsZW1lbnRcbiAqICAgaHR0cDovL3d3dy5hcHRhbmEuY29tL3JlZmVyZW5jZS9odG1sL2FwaS9IVE1MQW5jaG9yRWxlbWVudC5odG1sXG4gKiAgIGh0dHA6Ly91cmwuc3BlYy53aGF0d2cub3JnLyN1cmx1dGlsc1xuICogICBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyLmpzL3B1bGwvMjkwMlxuICogICBodHRwOi8vamFtZXMucGFkb2xzZXkuY29tL2phdmFzY3JpcHQvcGFyc2luZy11cmxzLXdpdGgtdGhlLWRvbS9cbiAqXG4gKiBAa2luZCBmdW5jdGlvblxuICogQHBhcmFtIHtzdHJpbmd9IHVybCBUaGUgVVJMIHRvIGJlIHBhcnNlZC5cbiAqIEBkZXNjcmlwdGlvbiBOb3JtYWxpemVzIGFuZCBwYXJzZXMgYSBVUkwuXG4gKiBAcmV0dXJucyB7b2JqZWN0fSBSZXR1cm5zIHRoZSBub3JtYWxpemVkIFVSTCBhcyBhIGRpY3Rpb25hcnkuXG4gKlxuICogICB8IG1lbWJlciBuYW1lICAgfCBEZXNjcmlwdGlvbiAgICB8XG4gKiAgIHwtLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLXxcbiAqICAgfCBocmVmICAgICAgICAgIHwgQSBub3JtYWxpemVkIHZlcnNpb24gb2YgdGhlIHByb3ZpZGVkIFVSTCBpZiBpdCB3YXMgbm90IGFuIGFic29sdXRlIFVSTCB8XG4gKiAgIHwgcHJvdG9jb2wgICAgICB8IFRoZSBwcm90b2NvbCBpbmNsdWRpbmcgdGhlIHRyYWlsaW5nIGNvbG9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogICB8IGhvc3QgICAgICAgICAgfCBUaGUgaG9zdCBhbmQgcG9ydCAoaWYgdGhlIHBvcnQgaXMgbm9uLWRlZmF1bHQpIG9mIHRoZSBub3JtYWxpemVkVXJsICAgIHxcbiAqICAgfCBzZWFyY2ggICAgICAgIHwgVGhlIHNlYXJjaCBwYXJhbXMsIG1pbnVzIHRoZSBxdWVzdGlvbiBtYXJrICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgIHwgaGFzaCAgICAgICAgICB8IFRoZSBoYXNoIHN0cmluZywgbWludXMgdGhlIGhhc2ggc3ltYm9sXG4gKiAgIHwgaG9zdG5hbWUgICAgICB8IFRoZSBob3N0bmFtZVxuICogICB8IHBvcnQgICAgICAgICAgfCBUaGUgcG9ydCwgd2l0aG91dCBcIjpcIlxuICogICB8IHBhdGhuYW1lICAgICAgfCBUaGUgcGF0aG5hbWUsIGJlZ2lubmluZyB3aXRoIFwiL1wiXG4gKlxuICovXG5cbnZhciB1cmxQYXJzaW5nTm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJhXCIpO1xuLyoqXG4gKiBkb2N1bWVudE1vZGUgaXMgYW4gSUUtb25seSBwcm9wZXJ0eVxuICogaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2llL2NjMTk2OTg4KHY9dnMuODUpLmFzcHhcbiAqL1xudmFyIG1zaWUgPSBkb2N1bWVudC5kb2N1bWVudE1vZGU7XG5cbmZ1bmN0aW9uIHVybFBhcnRzKHVybCkge1xuICB2YXIgaHJlZiA9IHVybDtcblxuICBpZiAobXNpZSkge1xuICAgIC8vIE5vcm1hbGl6ZSBiZWZvcmUgcGFyc2UuICBSZWZlciBJbXBsZW1lbnRhdGlvbiBOb3RlcyBvbiB3aHkgdGhpcyBpc1xuICAgIC8vIGRvbmUgaW4gdHdvIHN0ZXBzIG9uIElFLlxuICAgIHVybFBhcnNpbmdOb2RlLnNldEF0dHJpYnV0ZShcImhyZWZcIiwgaHJlZik7XG4gICAgaHJlZiA9IHVybFBhcnNpbmdOb2RlLmhyZWY7XG4gIH1cblxuICB1cmxQYXJzaW5nTm9kZS5zZXRBdHRyaWJ1dGUoJ2hyZWYnLCBocmVmKTtcblxuICAvLyB1cmxQYXJzaW5nTm9kZSBwcm92aWRlcyB0aGUgVXJsVXRpbHMgaW50ZXJmYWNlIC0gaHR0cDovL3VybC5zcGVjLndoYXR3Zy5vcmcvI3VybHV0aWxzXG4gIHJldHVybiB7XG4gICAgaHJlZjogdXJsUGFyc2luZ05vZGUuaHJlZixcbiAgICBwcm90b2NvbDogdXJsUGFyc2luZ05vZGUucHJvdG9jb2wgPyB1cmxQYXJzaW5nTm9kZS5wcm90b2NvbC5yZXBsYWNlKC86JC8sICcnKSA6ICcnLFxuICAgIGhvc3Q6IHVybFBhcnNpbmdOb2RlLmhvc3QsXG4gICAgc2VhcmNoOiB1cmxQYXJzaW5nTm9kZS5zZWFyY2ggPyB1cmxQYXJzaW5nTm9kZS5zZWFyY2gucmVwbGFjZSgvXlxcPy8sICcnKSA6ICcnLFxuICAgIGhhc2g6IHVybFBhcnNpbmdOb2RlLmhhc2ggPyB1cmxQYXJzaW5nTm9kZS5oYXNoLnJlcGxhY2UoL14jLywgJycpIDogJycsXG4gICAgaG9zdG5hbWU6IHVybFBhcnNpbmdOb2RlLmhvc3RuYW1lLFxuICAgIHBvcnQ6IHV0aWxpdGllcy5pc05vdEVtcHR5U3RyaW5nKHVybFBhcnNpbmdOb2RlLnBvcnQpPyB1cmxQYXJzaW5nTm9kZS5wb3J0OiA4MCxcbiAgICBwYXRobmFtZTogKHVybFBhcnNpbmdOb2RlLnBhdGhuYW1lLmNoYXJBdCgwKSA9PT0gJy8nKVxuICAgICAgPyB1cmxQYXJzaW5nTm9kZS5wYXRobmFtZVxuICAgICAgOiAnLycgKyB1cmxQYXJzaW5nTm9kZS5wYXRobmFtZVxuICB9O1xufVxuXG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBhY2NlcHRzIGEgcXVlcnkgc3RyaW5nIChzZWFyY2ggcGFydCBvZiBhIHVybCkgYW5kIHJldHVybnMgYSBkaWN0aW9uYXJ5IHdpdGhcbiAqIHRoZSBkaWZmZXJlbnQga2V5IHZhbHVlIHBhaXJzXG4gKiBAcGFyYW0ge3N0cmluZ30gcXMgcXVlcnlTdHJpbmdcbiAqL1xuZnVuY3Rpb24gcXVlcnlTdHJpbmdUb09iaihxcywgY29uZCkge1xuICB2YXIgcGFpcnMsIHFzT2JqO1xuXG4gIGNvbmQgPSB1dGlsaXRpZXMuaXNGdW5jdGlvbihjb25kKT8gY29uZCA6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIHFzID0gcXMudHJpbSgpLnJlcGxhY2UoL15cXD8vLCAnJyk7XG4gIHBhaXJzID0gcXMuc3BsaXQoJyYnKTtcbiAgcXNPYmogPSB7fTtcblxuICB1dGlsaXRpZXMuZm9yRWFjaChwYWlycywgZnVuY3Rpb24gKHBhaXIpIHtcbiAgICB2YXIga2V5VmFsdWUsIGtleSwgdmFsdWU7XG4gICAgaWYgKHBhaXIgIT09ICcnKSB7XG4gICAgICBrZXlWYWx1ZSA9IHBhaXIuc3BsaXQoJz0nKTtcbiAgICAgIGtleSA9IGtleVZhbHVlWzBdO1xuICAgICAgdmFsdWUgPSBrZXlWYWx1ZVsxXTtcbiAgICAgIGlmKGNvbmQoa2V5LCB2YWx1ZSkpe1xuICAgICAgICBxc09ialtrZXldID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gcXNPYmo7XG59XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBhY2NlcHRzIGFuIG9iamVjdCBhbmQgc2VyaWFsaXplcyBpdCBpbnRvIGEgcXVlcnkgc3RyaW5nIHdpdGhvdXQgdGhlIGxlYWRpbmcgJz8nXG4gKiBAcGFyYW0gb2JqXG4gKiBAcmV0dXJucyB7c3RyaW5nfVxuICovXG5mdW5jdGlvbiBvYmpUb1F1ZXJ5U3RyaW5nKG9iaikge1xuICB2YXIgcGFpcnMgPSBbXTtcbiAgdXRpbGl0aWVzLmZvckVhY2gob2JqLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgIHBhaXJzLnB1c2goa2V5ICsgJz0nICsgdmFsdWUpO1xuICB9KTtcbiAgcmV0dXJuIHBhaXJzLmpvaW4oJyYnKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHVybFBhcnRzOiB1cmxQYXJ0cyxcbiAgcXVlcnlTdHJpbmdUb09iajogcXVlcnlTdHJpbmdUb09iaixcbiAgb2JqVG9RdWVyeVN0cmluZzogb2JqVG9RdWVyeVN0cmluZ1xufTtcbiIsIi8qanNoaW50IHVudXNlZDpmYWxzZSAqL1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBOT0RFX1RZUEVfRUxFTUVOVCA9IDE7XG52YXIgU05BS0VfQ0FTRV9SRUdFWFAgPSAvW0EtWl0vZztcbnZhciBFTUFJTF9SRUdFWFAgPSAvXlthLXowLTkhIyQlJicqK1xcLz0/Xl9ge3x9fi4tXStAW2EtejAtOV0oW2EtejAtOS1dKlthLXowLTldKT8oXFwuW2EtejAtOV0oW2EtejAtOS1dKlthLXowLTldKT8pKyQvaTtcbi8qanNsaW50IG1heGxlbjogNTAwICovXG52YXIgSVNPODA4Nl9SRUdFWFAgPSAvXihbXFwrLV0/XFxkezR9KD8hXFxkezJ9XFxiKSkoKC0/KSgoMFsxLTldfDFbMC0yXSkoXFwzKFsxMl1cXGR8MFsxLTldfDNbMDFdKSk/fFcoWzAtNF1cXGR8NVswLTJdKSgtP1sxLTddKT98KDAwWzEtOV18MFsxLTldXFxkfFsxMl1cXGR7Mn18MyhbMC01XVxcZHw2WzEtNl0pKSkoW1RcXHNdKCgoWzAxXVxcZHwyWzAtM10pKCg6PylbMC01XVxcZCk/fDI0XFw6PzAwKShbXFwuLF1cXGQrKD8hOikpPyk/KFxcMTdbMC01XVxcZChbXFwuLF1cXGQrKT8pPyhbelpdfChbXFwrLV0pKFswMV1cXGR8MlswLTNdKTo/KFswLTVdXFxkKT8pPyk/KT8kLztcblxuXG5mdW5jdGlvbiBub29wKCl7IH1cblxuZnVuY3Rpb24gaXNOdWxsKG8pIHtcbiAgcmV0dXJuIG8gPT09IG51bGw7XG59XG5cbmZ1bmN0aW9uIGlzRGVmaW5lZChvKXtcbiAgcmV0dXJuIG8gIT09IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gaXNVbmRlZmluZWQobyl7XG4gIHJldHVybiBvID09PSB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KG9iaikge1xuICByZXR1cm4gdHlwZW9mIG9iaiA9PT0gJ29iamVjdCc7XG59XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oc3RyKXtcbiAgcmV0dXJuIHR5cGVvZiBzdHIgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGlzTnVtYmVyKG51bSl7XG4gIHJldHVybiB0eXBlb2YgbnVtID09PSAnbnVtYmVyJztcbn1cblxuZnVuY3Rpb24gaXNXaW5kb3cob2JqKSB7XG4gIHJldHVybiB1dGlsaXRpZXMuaXNPYmplY3Qob2JqKSAmJiBvYmoud2luZG93ID09PSBvYmo7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXkoYXJyYXkpe1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKCBhcnJheSApID09PSAnW29iamVjdCBBcnJheV0nO1xufVxuXG5mdW5jdGlvbiBpc0FycmF5TGlrZShvYmopIHtcbiAgaWYgKG9iaiA9PT0gbnVsbCB8fCB1dGlsaXRpZXMuaXNXaW5kb3cob2JqKSB8fCB1dGlsaXRpZXMuaXNGdW5jdGlvbihvYmopIHx8IHV0aWxpdGllcy5pc1VuZGVmaW5lZChvYmopKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyIGxlbmd0aCA9IG9iai5sZW5ndGg7XG5cbiAgaWYgKG9iai5ub2RlVHlwZSA9PT0gTk9ERV9UWVBFX0VMRU1FTlQgJiYgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gdXRpbGl0aWVzLmlzU3RyaW5nKG9iaikgfHwgdXRpbGl0aWVzLmlzQXJyYXkob2JqKSB8fCBsZW5ndGggPT09IDAgfHxcbiAgICB0eXBlb2YgbGVuZ3RoID09PSAnbnVtYmVyJyAmJiBsZW5ndGggPiAwICYmIChsZW5ndGggLSAxKSBpbiBvYmo7XG59XG5cbmZ1bmN0aW9uIGlzU3RyaW5nKHN0cil7XG4gIHJldHVybiB0eXBlb2Ygc3RyID09PSAnc3RyaW5nJztcbn1cblxuZnVuY3Rpb24gaXNFbXB0eVN0cmluZyhzdHIpIHtcbiAgcmV0dXJuIHV0aWxpdGllcy5pc1N0cmluZyhzdHIpICYmIHN0ci5sZW5ndGggPT09IDA7XG59XG5cbmZ1bmN0aW9uIGlzTm90RW1wdHlTdHJpbmcoc3RyKSB7XG4gIHJldHVybiB1dGlsaXRpZXMuaXNTdHJpbmcoc3RyKSAmJiBzdHIubGVuZ3RoICE9PSAwO1xufVxuXG5mdW5jdGlvbiBhcnJheUxpa2VPYmpUb0FycmF5KGFyZ3MpIHtcbiAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3MpO1xufVxuXG5mdW5jdGlvbiBmb3JFYWNoKG9iaiwgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgdmFyIGtleSwgbGVuZ3RoO1xuICBpZiAob2JqKSB7XG4gICAgaWYgKGlzRnVuY3Rpb24ob2JqKSkge1xuICAgICAgZm9yIChrZXkgaW4gb2JqKSB7XG4gICAgICAgIC8vIE5lZWQgdG8gY2hlY2sgaWYgaGFzT3duUHJvcGVydHkgZXhpc3RzLFxuICAgICAgICAvLyBhcyBvbiBJRTggdGhlIHJlc3VsdCBvZiBxdWVyeVNlbGVjdG9yQWxsIGlzIGFuIG9iamVjdCB3aXRob3V0IGEgaGFzT3duUHJvcGVydHkgZnVuY3Rpb25cbiAgICAgICAgaWYgKGtleSAhPT0gJ3Byb3RvdHlwZScgJiYga2V5ICE9PSAnbGVuZ3RoJyAmJiBrZXkgIT09ICduYW1lJyAmJiAoIW9iai5oYXNPd25Qcm9wZXJ0eSB8fCBvYmouaGFzT3duUHJvcGVydHkoa2V5KSkpIHtcbiAgICAgICAgICBpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9ialtrZXldLCBrZXksIG9iaik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkob2JqKSkge1xuICAgICAgdmFyIGlzUHJpbWl0aXZlID0gdHlwZW9mIG9iaiAhPT0gJ29iamVjdCc7XG4gICAgICBmb3IgKGtleSA9IDAsIGxlbmd0aCA9IG9iai5sZW5ndGg7IGtleSA8IGxlbmd0aDsga2V5KyspIHtcbiAgICAgICAgaWYgKGlzUHJpbWl0aXZlIHx8IGtleSBpbiBvYmopIHtcbiAgICAgICAgICBpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9ialtrZXldLCBrZXksIG9iaik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG9iai5mb3JFYWNoICYmIG9iai5mb3JFYWNoICE9PSBmb3JFYWNoKSB7XG4gICAgICBvYmouZm9yRWFjaChpdGVyYXRvciwgY29udGV4dCwgb2JqKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChrZXkgaW4gb2JqKSB7XG4gICAgICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgb2JqW2tleV0sIGtleSwgb2JqKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gb2JqO1xufVxuXG5mdW5jdGlvbiBzbmFrZV9jYXNlKG5hbWUsIHNlcGFyYXRvcikge1xuICBzZXBhcmF0b3IgPSBzZXBhcmF0b3IgfHwgJ18nO1xuICByZXR1cm4gbmFtZS5yZXBsYWNlKFNOQUtFX0NBU0VfUkVHRVhQLCBmdW5jdGlvbihsZXR0ZXIsIHBvcykge1xuICAgIHJldHVybiAocG9zID8gc2VwYXJhdG9yIDogJycpICsgbGV0dGVyLnRvTG93ZXJDYXNlKCk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBpc1ZhbGlkRW1haWwoZW1haWwpe1xuICBpZighdXRpbGl0aWVzLmlzU3RyaW5nKGVtYWlsKSl7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIEVNQUlMX1JFR0VYUC50ZXN0KGVtYWlsLnRyaW0oKSk7XG59XG5cbmZ1bmN0aW9uIGV4dGVuZCAob2JqKSB7XG4gIHZhciBhcmcsIGksIGs7XG4gIGZvciAoaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICBhcmcgPSBhcmd1bWVudHNbaV07XG4gICAgZm9yIChrIGluIGFyZykge1xuICAgICAgaWYgKGFyZy5oYXNPd25Qcm9wZXJ0eShrKSkge1xuICAgICAgICBpZihpc09iamVjdChvYmpba10pICYmICFpc051bGwob2JqW2tdKSAmJiBpc09iamVjdChhcmdba10pKXtcbiAgICAgICAgICBvYmpba10gPSBleHRlbmQoe30sIG9ialtrXSwgYXJnW2tdKTtcbiAgICAgICAgfWVsc2Uge1xuICAgICAgICAgIG9ialtrXSA9IGFyZ1trXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gb2JqO1xufVxuXG5mdW5jdGlvbiBjYXBpdGFsaXplKHMpe1xuICByZXR1cm4gcy5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHMuc2xpY2UoMSk7XG59XG5cbmZ1bmN0aW9uIGRlY2FwaXRhbGl6ZShzKSB7XG4gIHJldHVybiBzLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpICsgcy5zbGljZSgxKTtcbn1cblxuLyoqXG4gKiBUaGlzIG1ldGhvZCB3b3JrcyB0aGUgc2FtZSB3YXkgYXJyYXkucHJvdG90eXBlLm1hcCB3b3JrcyBidXQgaWYgdGhlIHRyYW5zZm9ybWVyIHJldHVybnMgdW5kZWZpbmUsIHRoZW5cbiAqIGl0IHdvbid0IGJlIGFkZGVkIHRvIHRoZSB0cmFuc2Zvcm1lZCBBcnJheS5cbiAqL1xuZnVuY3Rpb24gdHJhbnNmb3JtQXJyYXkoYXJyYXksIHRyYW5zZm9ybWVyKSB7XG4gIHZhciB0cmFuc2Zvcm1lZEFycmF5ID0gW107XG5cbiAgYXJyYXkuZm9yRWFjaChmdW5jdGlvbihpdGVtLCBpbmRleCl7XG4gICAgdmFyIHRyYW5zZm9ybWVkSXRlbSA9IHRyYW5zZm9ybWVyKGl0ZW0sIGluZGV4KTtcbiAgICBpZih1dGlsaXRpZXMuaXNEZWZpbmVkKHRyYW5zZm9ybWVkSXRlbSkpIHtcbiAgICAgIHRyYW5zZm9ybWVkQXJyYXkucHVzaCh0cmFuc2Zvcm1lZEl0ZW0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHRyYW5zZm9ybWVkQXJyYXk7XG59XG5cbmZ1bmN0aW9uIHRvRml4ZWREaWdpdHMobnVtLCBkaWdpdHMpIHtcbiAgdmFyIGZvcm1hdHRlZE51bSA9IG51bSArICcnO1xuICBkaWdpdHMgPSB1dGlsaXRpZXMuaXNOdW1iZXIoZGlnaXRzKSA/IGRpZ2l0cyA6IDA7XG4gIG51bSA9IHV0aWxpdGllcy5pc051bWJlcihudW0pID8gbnVtIDogcGFyc2VJbnQobnVtLCAxMCk7XG4gIGlmKHV0aWxpdGllcy5pc051bWJlcihudW0pICYmICFpc05hTihudW0pKXtcbiAgICBmb3JtYXR0ZWROdW0gPSBudW0gKyAnJztcbiAgICB3aGlsZShmb3JtYXR0ZWROdW0ubGVuZ3RoIDwgZGlnaXRzKSB7XG4gICAgICBmb3JtYXR0ZWROdW0gPSAnMCcgKyBmb3JtYXR0ZWROdW07XG4gICAgfVxuICAgIHJldHVybiBmb3JtYXR0ZWROdW07XG4gIH1cbiAgcmV0dXJuIE5hTiArICcnO1xufVxuXG5mdW5jdGlvbiB0aHJvdHRsZShjYWxsYmFjaywgZGVsYXkpIHtcbiAgdmFyIHByZXZpb3VzQ2FsbCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpIC0gKGRlbGF5ICsgMSk7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgIGlmICgodGltZSAtIHByZXZpb3VzQ2FsbCkgPj0gZGVsYXkpIHtcbiAgICAgIHByZXZpb3VzQ2FsbCA9IHRpbWU7XG4gICAgICBjYWxsYmFjay5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gZGVib3VuY2UgKGNhbGxiYWNrLCB3YWl0KSB7XG4gIHZhciB0aW1lb3V0SWQ7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICgpe1xuICAgIGlmKHRpbWVvdXRJZCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgfVxuICAgIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgIGNhbGxiYWNrLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB0aW1lb3V0SWQgPSB1bmRlZmluZWQ7XG4gICAgfSwgd2FpdCk7XG4gIH07XG59XG5cbi8vIGEgZnVuY3Rpb24gZGVzaWduZWQgdG8gYmxvdyB1cCB0aGUgc3RhY2sgaW4gYSBuYWl2ZSB3YXlcbi8vIGJ1dCBpdCBpcyBvayBmb3IgdmlkZW9KcyBjaGlsZHJlbiBjb21wb25lbnRzXG5mdW5jdGlvbiB0cmVlU2VhcmNoKHJvb3QsIGdldENoaWxkcmVuLCBmb3VuZCl7XG4gIHZhciBjaGlsZHJlbiA9IGdldENoaWxkcmVuKHJvb3QpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKXtcbiAgICBpZiAoZm91bmQoY2hpbGRyZW5baV0pKSB7XG4gICAgICByZXR1cm4gY2hpbGRyZW5baV07XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdmFyIGVsID0gdHJlZVNlYXJjaChjaGlsZHJlbltpXSwgZ2V0Q2hpbGRyZW4sIGZvdW5kKTtcbiAgICAgIGlmIChlbCl7XG4gICAgICAgIHJldHVybiBlbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZWNob0ZuKHZhbCkge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB2YWw7XG4gIH07XG59XG5cbi8vTm90ZTogU3VwcG9ydGVkIGZvcm1hdHMgY29tZSBmcm9tIGh0dHA6Ly93d3cudzMub3JnL1RSL05PVEUtZGF0ZXRpbWVcbi8vIGFuZCB0aGUgaXNvODYwMSByZWdleCBjb21lcyBmcm9tIGh0dHA6Ly93d3cucGVsYWdvZGVzaWduLmNvbS9ibG9nLzIwMDkvMDUvMjAvaXNvLTg2MDEtZGF0ZS12YWxpZGF0aW9uLXRoYXQtZG9lc250LXN1Y2svXG5mdW5jdGlvbiBpc0lTTzg2MDEodmFsdWUpIHtcbiAgaWYodXRpbGl0aWVzLmlzTnVtYmVyKHZhbHVlKSl7XG4gICAgdmFsdWUgPSB2YWx1ZSArICcnOyAgLy93ZSBtYWtlIHN1cmUgdGhhdCB3ZSBhcmUgd29ya2luZyB3aXRoIHN0cmluZ3NcbiAgfVxuXG4gIGlmKCF1dGlsaXRpZXMuaXNTdHJpbmcodmFsdWUpKXtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gSVNPODA4Nl9SRUdFWFAudGVzdCh2YWx1ZS50cmltKCkpO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgQnJvd3NlciBpcyBJRTkgYW5kIGJlbG93XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaXNPbGRJRSgpIHtcbiAgdmFyIHZlcnNpb24gPSB1dGlsaXRpZXMuZ2V0SW50ZXJuZXRFeHBsb3JlclZlcnNpb24obmF2aWdhdG9yKTtcbiAgaWYgKHZlcnNpb24gPT09IC0xKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHZlcnNpb24gPCAxMDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSB2ZXJzaW9uIG9mIEludGVybmV0IEV4cGxvcmVyIG9yIGEgLTEgKGluZGljYXRpbmcgdGhlIHVzZSBvZiBhbm90aGVyIGJyb3dzZXIpLlxuICogU291cmNlOiBodHRwczovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L21zNTM3NTA5KHY9dnMuODUpLmFzcHhcbiAqIEByZXR1cm5zIHtudW1iZXJ9IHRoZSB2ZXJzaW9uIG9mIEludGVybmV0IEV4cGxvcmVyIG9yIGEgLTEgKGluZGljYXRpbmcgdGhlIHVzZSBvZiBhbm90aGVyIGJyb3dzZXIpLlxuICovXG5mdW5jdGlvbiBnZXRJbnRlcm5ldEV4cGxvcmVyVmVyc2lvbihuYXZpZ2F0b3IpIHtcbiAgdmFyIHJ2ID0gLTE7XG5cbiAgaWYgKG5hdmlnYXRvci5hcHBOYW1lID09ICdNaWNyb3NvZnQgSW50ZXJuZXQgRXhwbG9yZXInKSB7XG4gICAgdmFyIHVhID0gbmF2aWdhdG9yLnVzZXJBZ2VudDtcbiAgICB2YXIgcmUgPSBuZXcgUmVnRXhwKFwiTVNJRSAoWzAtOV17MSx9W1xcLjAtOV17MCx9KVwiKTtcbiAgICB2YXIgcmVzID0gcmUuZXhlYyh1YSk7XG4gICAgaWYgKHJlcyAhPT0gbnVsbCkge1xuICAgICAgcnYgPSBwYXJzZUZsb2F0KHJlc1sxXSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJ2O1xufVxuXG4vKioqIE1vYmlsZSBVdGlsaXR5IGZ1bmN0aW9ucyAqKiovXG5mdW5jdGlvbiBpc0lEZXZpY2UoKSB7XG4gIHJldHVybiAvaVAoaG9uZXxhZCkvLnRlc3QodXRpbGl0aWVzLl9VQSk7XG59XG5cbmZ1bmN0aW9uIGlzTW9iaWxlKCkge1xuICByZXR1cm4gL2lQKGhvbmV8YWR8b2QpfEFuZHJvaWR8V2luZG93cyBQaG9uZS8udGVzdCh1dGlsaXRpZXMuX1VBKTtcbn1cblxuZnVuY3Rpb24gaXNJUGhvbmUoKSB7XG4gIHJldHVybiAvaVAoaG9uZXxvZCkvLnRlc3QodXRpbGl0aWVzLl9VQSk7XG59XG5cbmZ1bmN0aW9uIGlzQW5kcm9pZCgpIHtcbiAgcmV0dXJuIC9BbmRyb2lkLy50ZXN0KHV0aWxpdGllcy5fVUEpO1xufVxuXG52YXIgdXRpbGl0aWVzID0ge1xuICBfVUE6IG5hdmlnYXRvci51c2VyQWdlbnQsXG4gIG5vb3A6IG5vb3AsXG4gIGlzTnVsbDogaXNOdWxsLFxuICBpc0RlZmluZWQ6IGlzRGVmaW5lZCxcbiAgaXNVbmRlZmluZWQ6IGlzVW5kZWZpbmVkLFxuICBpc09iamVjdDogaXNPYmplY3QsXG4gIGlzRnVuY3Rpb246IGlzRnVuY3Rpb24sXG4gIGlzTnVtYmVyOiBpc051bWJlcixcbiAgaXNXaW5kb3c6IGlzV2luZG93LFxuICBpc0FycmF5OiBpc0FycmF5LFxuICBpc0FycmF5TGlrZTogaXNBcnJheUxpa2UsXG4gIGlzU3RyaW5nOiBpc1N0cmluZyxcbiAgaXNFbXB0eVN0cmluZzogaXNFbXB0eVN0cmluZyxcbiAgaXNOb3RFbXB0eVN0cmluZzogaXNOb3RFbXB0eVN0cmluZyxcbiAgYXJyYXlMaWtlT2JqVG9BcnJheTogYXJyYXlMaWtlT2JqVG9BcnJheSxcbiAgZm9yRWFjaDogZm9yRWFjaCxcbiAgc25ha2VfY2FzZTogc25ha2VfY2FzZSxcbiAgaXNWYWxpZEVtYWlsOiBpc1ZhbGlkRW1haWwsXG4gIGV4dGVuZDogZXh0ZW5kLFxuICBjYXBpdGFsaXplOiBjYXBpdGFsaXplLFxuICBkZWNhcGl0YWxpemU6IGRlY2FwaXRhbGl6ZSxcbiAgdHJhbnNmb3JtQXJyYXk6IHRyYW5zZm9ybUFycmF5LFxuICB0b0ZpeGVkRGlnaXRzOiB0b0ZpeGVkRGlnaXRzLFxuICB0aHJvdHRsZTogdGhyb3R0bGUsXG4gIGRlYm91bmNlOiBkZWJvdW5jZSxcbiAgdHJlZVNlYXJjaDogdHJlZVNlYXJjaCxcbiAgZWNob0ZuOiBlY2hvRm4sXG4gIGlzSVNPODYwMTogaXNJU084NjAxLFxuICBpc09sZElFOiBpc09sZElFLFxuICBnZXRJbnRlcm5ldEV4cGxvcmVyVmVyc2lvbjogZ2V0SW50ZXJuZXRFeHBsb3JlclZlcnNpb24sXG4gIGlzSURldmljZTogaXNJRGV2aWNlLFxuICBpc01vYmlsZTogaXNNb2JpbGUsXG4gIGlzSVBob25lOiBpc0lQaG9uZSxcbiAgaXNBbmRyb2lkOiBpc0FuZHJvaWRcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gdXRpbGl0aWVzOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxpdGllcyA9IHJlcXVpcmUoJy4vdXRpbGl0eUZ1bmN0aW9ucycpO1xuXG52YXIgeG1sID0ge307XG5cbnhtbC5zdHJUb1hNTERvYyA9IGZ1bmN0aW9uIHN0clRvWE1MRG9jKHN0cmluZ0NvbnRhaW5pbmdYTUxTb3VyY2Upe1xuICAvL0lFIDhcbiAgaWYodHlwZW9mIHdpbmRvdy5ET01QYXJzZXIgPT09ICd1bmRlZmluZWQnKXtcbiAgICB2YXIgeG1sRG9jdW1lbnQgPSBuZXcgQWN0aXZlWE9iamVjdCgnTWljcm9zb2Z0LlhNTERPTScpO1xuICAgIHhtbERvY3VtZW50LmFzeW5jID0gZmFsc2U7XG4gICAgeG1sRG9jdW1lbnQubG9hZFhNTChzdHJpbmdDb250YWluaW5nWE1MU291cmNlKTtcbiAgICByZXR1cm4geG1sRG9jdW1lbnQ7XG4gIH1cblxuICByZXR1cm4gcGFyc2VTdHJpbmcoc3RyaW5nQ29udGFpbmluZ1hNTFNvdXJjZSk7XG5cbiAgZnVuY3Rpb24gcGFyc2VTdHJpbmcoc3RyaW5nQ29udGFpbmluZ1hNTFNvdXJjZSl7XG4gICAgdmFyIHBhcnNlciA9IG5ldyBET01QYXJzZXIoKTtcbiAgICB2YXIgcGFyc2VkRG9jdW1lbnQ7XG5cbiAgICAvL05vdGU6IFRoaXMgdHJ5IGNhdGNoIGlzIHRvIGRlYWwgd2l0aCB0aGUgZmFjdCB0aGF0IG9uIElFIHBhcnNlci5wYXJzZUZyb21TdHJpbmcgZG9lcyB0aHJvdyBhbiBlcnJvciBidXQgdGhlIHJlc3Qgb2YgdGhlIGJyb3dzZXJzIGRvbid0LlxuICAgIHRyeSB7XG4gICAgICBwYXJzZWREb2N1bWVudCA9IHBhcnNlci5wYXJzZUZyb21TdHJpbmcoc3RyaW5nQ29udGFpbmluZ1hNTFNvdXJjZSwgXCJhcHBsaWNhdGlvbi94bWxcIik7XG5cbiAgICAgIGlmKGlzUGFyc2VFcnJvcihwYXJzZWREb2N1bWVudCkgfHwgdXRpbGl0aWVzLmlzRW1wdHlTdHJpbmcoc3RyaW5nQ29udGFpbmluZ1hNTFNvdXJjZSkpe1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICAgIH1cbiAgICB9Y2F0Y2goZSl7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ4bWwuc3RyVG9YTUxET0M6IEVycm9yIHBhcnNpbmcgdGhlIHN0cmluZzogJ1wiICsgc3RyaW5nQ29udGFpbmluZ1hNTFNvdXJjZSArIFwiJ1wiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFyc2VkRG9jdW1lbnQ7XG4gIH1cblxuICBmdW5jdGlvbiBpc1BhcnNlRXJyb3IocGFyc2VkRG9jdW1lbnQpIHtcbiAgICB0cnkgeyAvLyBwYXJzZXIgYW5kIHBhcnNlcmVycm9yTlMgY291bGQgYmUgY2FjaGVkIG9uIHN0YXJ0dXAgZm9yIGVmZmljaWVuY3lcbiAgICAgIHZhciBwYXJzZXIgPSBuZXcgRE9NUGFyc2VyKCksXG4gICAgICAgIGVycm9uZW91c1BhcnNlID0gcGFyc2VyLnBhcnNlRnJvbVN0cmluZygnSU5WQUxJRCcsICd0ZXh0L3htbCcpLFxuICAgICAgICBwYXJzZXJlcnJvck5TID0gZXJyb25lb3VzUGFyc2UuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJwYXJzZXJlcnJvclwiKVswXS5uYW1lc3BhY2VVUkk7XG5cbiAgICAgIGlmIChwYXJzZXJlcnJvck5TID09PSAnaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCcpIHtcbiAgICAgICAgLy8gSW4gUGhhbnRvbUpTIHRoZSBwYXJzZWVycm9yIGVsZW1lbnQgZG9lc24ndCBzZWVtIHRvIGhhdmUgYSBzcGVjaWFsIG5hbWVzcGFjZSwgc28gd2UgYXJlIGp1c3QgZ3Vlc3NpbmcgaGVyZSA6KFxuICAgICAgICByZXR1cm4gcGFyc2VkRG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJwYXJzZXJlcnJvclwiKS5sZW5ndGggPiAwO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcGFyc2VkRG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyhwYXJzZXJlcnJvck5TLCAncGFyc2VyZXJyb3InKS5sZW5ndGggPiAwO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vTm90ZSBvbiBJRSBwYXJzZVN0cmluZyB0aHJvd3MgYW4gZXJyb3IgYnkgaXRzZWxmIGFuZCBpdCB3aWxsIG5ldmVyIHJlYWNoIHRoaXMgY29kZS4gQmVjYXVzZSBpdCB3aWxsIGhhdmUgZmFpbGVkIGJlZm9yZVxuICAgIH1cbiAgfVxufTtcblxueG1sLnBhcnNlVGV4dCA9IGZ1bmN0aW9uIHBhcnNlVGV4dCAoc1ZhbHVlKSB7XG4gIGlmICgvXlxccyokLy50ZXN0KHNWYWx1ZSkpIHsgcmV0dXJuIG51bGw7IH1cbiAgaWYgKC9eKD86dHJ1ZXxmYWxzZSkkL2kudGVzdChzVmFsdWUpKSB7IHJldHVybiBzVmFsdWUudG9Mb3dlckNhc2UoKSA9PT0gXCJ0cnVlXCI7IH1cbiAgaWYgKGlzRmluaXRlKHNWYWx1ZSkpIHsgcmV0dXJuIHBhcnNlRmxvYXQoc1ZhbHVlKTsgfVxuICBpZiAodXRpbGl0aWVzLmlzSVNPODYwMShzVmFsdWUpKSB7IHJldHVybiBuZXcgRGF0ZShzVmFsdWUpOyB9XG4gIHJldHVybiBzVmFsdWUudHJpbSgpO1xufTtcblxueG1sLkpYT05UcmVlID0gZnVuY3Rpb24gSlhPTlRyZWUgKG9YTUxQYXJlbnQpIHtcbiAgdmFyIHBhcnNlVGV4dCA9IHhtbC5wYXJzZVRleHQ7XG5cbiAgLy9UaGUgZG9jdW1lbnQgb2JqZWN0IGlzIGFuIGVzcGVjaWFsIG9iamVjdCB0aGF0IGl0IG1heSBtaXNzIHNvbWUgZnVuY3Rpb25zIG9yIGF0dHJzIGRlcGVuZGluZyBvbiB0aGUgYnJvd3Nlci5cbiAgLy9UbyBwcmV2ZW50IHRoaXMgcHJvYmxlbSB3aXRoIGNyZWF0ZSB0aGUgSlhPTlRyZWUgdXNpbmcgdGhlIHJvb3QgY2hpbGROb2RlIHdoaWNoIGlzIGEgZnVsbHkgZmxlc2hlZCBub2RlIG9uIGFsbCBzdXBwb3J0ZWRcbiAgLy9icm93c2Vycy5cbiAgaWYob1hNTFBhcmVudC5kb2N1bWVudEVsZW1lbnQpe1xuICAgIHJldHVybiBuZXcgeG1sLkpYT05UcmVlKG9YTUxQYXJlbnQuZG9jdW1lbnRFbGVtZW50KTtcbiAgfVxuXG4gIGlmIChvWE1MUGFyZW50Lmhhc0NoaWxkTm9kZXMoKSkge1xuICAgIHZhciBzQ29sbGVjdGVkVHh0ID0gXCJcIjtcbiAgICBmb3IgKHZhciBvTm9kZSwgc1Byb3AsIHZDb250ZW50LCBuSXRlbSA9IDA7IG5JdGVtIDwgb1hNTFBhcmVudC5jaGlsZE5vZGVzLmxlbmd0aDsgbkl0ZW0rKykge1xuICAgICAgb05vZGUgPSBvWE1MUGFyZW50LmNoaWxkTm9kZXMuaXRlbShuSXRlbSk7XG4gICAgICAvKmpzaGludCBiaXR3aXNlOiBmYWxzZSovXG4gICAgICBpZiAoKG9Ob2RlLm5vZGVUeXBlIC0gMSB8IDEpID09PSAzKSB7IHNDb2xsZWN0ZWRUeHQgKz0gb05vZGUubm9kZVR5cGUgPT09IDMgPyBvTm9kZS5ub2RlVmFsdWUudHJpbSgpIDogb05vZGUubm9kZVZhbHVlOyB9XG4gICAgICBlbHNlIGlmIChvTm9kZS5ub2RlVHlwZSA9PT0gMSAmJiAhb05vZGUucHJlZml4KSB7XG4gICAgICAgIHNQcm9wID0gdXRpbGl0aWVzLmRlY2FwaXRhbGl6ZShvTm9kZS5ub2RlTmFtZSk7XG4gICAgICAgIHZDb250ZW50ID0gbmV3IHhtbC5KWE9OVHJlZShvTm9kZSk7XG4gICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KHNQcm9wKSkge1xuICAgICAgICAgIGlmICh0aGlzW3NQcm9wXS5jb25zdHJ1Y3RvciAhPT0gQXJyYXkpIHsgdGhpc1tzUHJvcF0gPSBbdGhpc1tzUHJvcF1dOyB9XG4gICAgICAgICAgdGhpc1tzUHJvcF0ucHVzaCh2Q29udGVudCk7XG4gICAgICAgIH0gZWxzZSB7IHRoaXNbc1Byb3BdID0gdkNvbnRlbnQ7IH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHNDb2xsZWN0ZWRUeHQpIHsgdGhpcy5rZXlWYWx1ZSA9IHBhcnNlVGV4dChzQ29sbGVjdGVkVHh0KTsgfVxuICB9XG5cbiAgLy9JRTggU3R1cGlkIGZpeFxuICB2YXIgaGFzQXR0ciA9IHR5cGVvZiBvWE1MUGFyZW50Lmhhc0F0dHJpYnV0ZXMgPT09ICd1bmRlZmluZWQnPyBvWE1MUGFyZW50LmF0dHJpYnV0ZXMubGVuZ3RoID4gMDogb1hNTFBhcmVudC5oYXNBdHRyaWJ1dGVzKCk7XG4gIGlmIChoYXNBdHRyKSB7XG4gICAgdmFyIG9BdHRyaWI7XG4gICAgZm9yICh2YXIgbkF0dHJpYiA9IDA7IG5BdHRyaWIgPCBvWE1MUGFyZW50LmF0dHJpYnV0ZXMubGVuZ3RoOyBuQXR0cmliKyspIHtcbiAgICAgIG9BdHRyaWIgPSBvWE1MUGFyZW50LmF0dHJpYnV0ZXMuaXRlbShuQXR0cmliKTtcbiAgICAgIHRoaXNbXCJAXCIgKyB1dGlsaXRpZXMuZGVjYXBpdGFsaXplKG9BdHRyaWIubmFtZSldID0gcGFyc2VUZXh0KG9BdHRyaWIudmFsdWUudHJpbSgpKTtcbiAgICB9XG4gIH1cbn07XG5cbnhtbC5KWE9OVHJlZS5wcm90b3R5cGUuYXR0ciA9IGZ1bmN0aW9uKGF0dHIpIHtcbiAgcmV0dXJuIHRoaXNbJ0AnICsgdXRpbGl0aWVzLmRlY2FwaXRhbGl6ZShhdHRyKV07XG59O1xuXG54bWwudG9KWE9OVHJlZSA9IGZ1bmN0aW9uIHRvSlhPTlRyZWUoeG1sU3RyaW5nKXtcbiAgdmFyIHhtbERvYyA9IHhtbC5zdHJUb1hNTERvYyh4bWxTdHJpbmcpO1xuICByZXR1cm4gbmV3IHhtbC5KWE9OVHJlZSh4bWxEb2MpO1xufTtcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gZXh0cmFjdCB0aGUga2V5dmFsdWUgb2YgYSBKWE9OVHJlZSBvYmpcbiAqXG4gKiBAcGFyYW0geG1sT2JqIHtKWE9OVHJlZX1cbiAqIHJldHVybiB0aGUga2V5IHZhbHVlIG9yIHVuZGVmaW5lZDtcbiAqL1xueG1sLmtleVZhbHVlID0gZnVuY3Rpb24gZ2V0S2V5VmFsdWUoeG1sT2JqKSB7XG4gIGlmKHhtbE9iail7XG4gICAgcmV0dXJuIHhtbE9iai5rZXlWYWx1ZTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufTtcblxueG1sLmF0dHIgPSBmdW5jdGlvbiBnZXRBdHRyVmFsdWUoeG1sT2JqLCBhdHRyKSB7XG4gIGlmKHhtbE9iaikge1xuICAgIHJldHVybiB4bWxPYmpbJ0AnICsgdXRpbGl0aWVzLmRlY2FwaXRhbGl6ZShhdHRyKV07XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn07XG5cbnhtbC5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGVYTUwoc3RyKSB7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvJi9nLCAnJmFtcDsnKVxuICAgIC5yZXBsYWNlKC88L2csICcmbHQ7JylcbiAgICAucmVwbGFjZSgvPi9nLCAnJmd0OycpXG4gICAgLnJlcGxhY2UoL1wiL2csICcmcXVvdDsnKVxuICAgIC5yZXBsYWNlKC8nL2csICcmYXBvczsnKTtcbn07XG5cbnhtbC5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGVYTUwoc3RyKSB7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvJmFwb3M7L2csIFwiJ1wiKVxuICAgIC5yZXBsYWNlKC8mcXVvdDsvZywgJ1wiJylcbiAgICAucmVwbGFjZSgvJmd0Oy9nLCAnPicpXG4gICAgLnJlcGxhY2UoLyZsdDsvZywgJzwnKVxuICAgIC5yZXBsYWNlKC8mYW1wOy9nLCAnJicpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB4bWw7IiwiJ3VzZSBzdHJpY3QnO1xuXG5yZXF1aXJlKCcuL3BsdWdpbi9jb21wb25lbnRzL2Fkcy1sYWJlbF81Jyk7XG5yZXF1aXJlKCcuL3BsdWdpbi9jb21wb25lbnRzL2JsYWNrLXBvc3Rlcl81Jyk7XG5cbnZhciB2aWRlb0pzVkFTVCA9IHJlcXVpcmUoJy4vcGx1Z2luL3ZpZGVvanMudmFzdC52cGFpZCcpO1xuXG52aWRlb2pzLnBsdWdpbigndmFzdENsaWVudCcsIHZpZGVvSnNWQVNUKTtcbiJdfQ== diff --git a/bin/videojs_5.vast.vpaid.min.js b/bin/videojs_5.vast.vpaid.min.js index 0fb0e383..f62ec91d 100644 --- a/bin/videojs_5.vast.vpaid.min.js +++ b/bin/videojs_5.vast.vpaid.min.js @@ -1,5 +1,4 @@ -(function t(e,n,i){function r(s,o){if(!n[s]){if(!e[s]){var u=typeof require=="function"&&require;if(!o&&u)return u(s,!0);if(a)return a(s,!0);var l=new Error("Cannot find module '"+s+"'");throw l.code="MODULE_NOT_FOUND",l}var c=n[s]={exports:{}};e[s][0].call(c.exports,function(t){var n=e[s][1][t];return r(n?n:t)},c,c.exports,t,e,n,i)}return n[s].exports}var a=typeof require=="function"&&require;for(var s=0;s0){i(e)}},0)}})}},{key:"_callCallback",value:function k(t,e,n,i){var r=this._callbacks.get(e);if(!r){if(n&&e===""){this.trigger(f,n)}return}p.call(this,e,n,i)}},{key:"_handShake",value:function _(t,e){this._ready=true;if(this._handShakeHandler){this._handShakeHandler(t,e);delete this._handShakeHandler}}},{key:"getSize",value:function w(){return{width:this._width,height:this._height}}},{key:"setSize",value:function b(t,e){this._width=s(t,this._width);this._height=s(e,this._height);this._el.setAttribute("width",this._width);this._el.setAttribute("height",this._height)}},{key:"getWidth",value:function E(){return this._width}},{key:"setWidth",value:function T(t){this.setSize(t,this._height)}},{key:"getHeight",value:function S(){return this._height}},{key:"setHeight",value:function V(t){this.setSize(this._width,t)}},{key:"getFlashID",value:function C(){return this._flashID}},{key:"getFlashURL",value:function I(){return this._flashURL}},{key:"isReady",value:function F(){return this._ready}},{key:"destroy",value:function L(){this.offAll();this.removeAllCallbacks();c.removeInstanceByID(this._flashID);if(this._el.parentElement){this._el.parentElement.removeChild(this._el)}}}]);return t}();function p(t,e,n){var i=this;setTimeout(function(){var r=i._callbacks.get(t);if(r){i._callbacks.remove(t);r(e,n)}},0)}Object.defineProperty(h,"VPAID_FLASH_HANDLER",{writable:false,configurable:false,value:d});window[d]=function(t,e,n,i,r,a){var s=c.getInstanceByID(t);if(!s)return;if(n==="handShake"){s._handShake(r,a)}else{if(e!=="event"){s._callCallback(n,i,r,a)}else{s._trigger(n,a)}}}},{"./jsFlashBridgeRegistry":6,"./registry":7,"./utils":8}],6:[function(t,e,n){"use strict";var i=t("./registry").SingleValueRegistry;var r=new i;var a={};Object.defineProperty(a,"addInstance",{writable:false,configurable:false,value:function s(t,e){r.add(t,e)}});Object.defineProperty(a,"getInstanceByID",{writable:false,configurable:false,value:function o(t){return r.get(t)}});Object.defineProperty(a,"removeInstanceByID",{writable:false,configurable:false,value:function u(t){return r.remove(t)}});e.exports=a},{"./registry":7}],7:[function(t,e,n){"use strict";var i=function(){function t(t,e){for(var n=0;n0?t:e}var u=function(){if(String.prototype.endsWith)return String.prototype.endsWith;return function t(e,n){var i=this.toString();if(n===undefined||n>i.length){n=i.length}n-=e.length;var r=i.indexOf(e,n);return r!==-1&&r===n}}();function l(t,e){return u.call(t,e)}function c(t){t.style.position="absolute";t.style.left="-1px";t.style.top="-1px";t.style.width="1px";t.style.height="1px"}},{}],9:[function(t,e,n){"use strict";var i=["handshakeVersion","initAd","startAd","stopAd","skipAd","resizeAd","pauseAd","resumeAd","expandAd","collapseAd","subscribe","unsubscribe"];var r=["AdLoaded","AdStarted","AdStopped","AdSkipped","AdSkippableStateChange","AdSizeChange","AdLinearChange","AdDurationChange","AdExpandedChange","AdRemainingTimeChange","AdVolumeChange","AdImpression","AdVideoStart","AdVideoFirstQuartile","AdVideoMidpoint","AdVideoThirdQuartile","AdVideoComplete","AdClickThru","AdInteraction","AdUserAcceptInvitation","AdUserMinimize","AdUserClose","AdPaused","AdPlaying","AdLog","AdError"];var a=["getAdLinear","getAdWidth","getAdHeight","getAdExpanded","getAdSkippableState","getAdRemainingTime","getAdDuration","getAdVolume","getAdCompanions","getAdIcons"];var s=["setAdVolume"];function o(t,e,n){}o.prototype.handshakeVersion=function(t,e){};o.prototype.initAd=function(t,e,n,i,r,a,s){};o.prototype.startAd=function(t){};o.prototype.stopAd=function(t){};o.prototype.skipAd=function(t){};o.prototype.resizeAd=function(t,e,n,i){};o.prototype.pauseAd=function(t){};o.prototype.resumeAd=function(t){};o.prototype.expandAd=function(t){};o.prototype.collapseAd=function(t){};o.prototype.subscribe=function(t,e,n){};o.prototype.unsubscribe=function(t,e){};o.prototype.getAdLinear=function(t){};o.prototype.getAdWidth=function(t){};o.prototype.getAdHeight=function(t){};o.prototype.getAdExpanded=function(t){};o.prototype.getAdSkippableState=function(t){};o.prototype.getAdRemainingTime=function(t){};o.prototype.getAdDuration=function(t){};o.prototype.getAdVolume=function(t){};o.prototype.getAdCompanions=function(t){};o.prototype.getAdIcons=function(t){};o.prototype.setAdVolume=function(t,e){};l(o,"METHODS",i);l(o,"GETTERS",a);l(o,"SETTERS",s);l(o,"EVENTS",r);var u=i.filter(function(t){return["skipAd"].indexOf(t)===-1});l(o,"checkVPAIDInterface",function c(t){var e=u.every(function(e){return typeof t[e]==="function"});return e});e.exports=o;function l(t,e,n){Object.defineProperty(t,e,{writable:false,configurable:false,value:n})}},{}],10:[function(t,e,n){"use strict";var i=t("./IVPAIDAdUnit");var r=t("./subscriber");var a=i.checkVPAIDInterface;var s=t("./utils");var o=i.METHODS;var u="AdError";var l="AdClickThru";var c=i.EVENTS.filter(function(t){return t!=l});function d(t,e,n,i){this._isValid=a(t);if(this._isValid){this._creative=t;this._el=e;this._videoEl=n;this._iframe=i;this._subscribers=new r;f.call(this)}}d.prototype=Object.create(i.prototype);d.prototype.isValidVPAIDAd=function g(){return this._isValid};i.METHODS.forEach(function(t){var e=["subscribe","unsubscribe","initAd"];if(e.indexOf(t)!==-1)return;d.prototype[t]=function(){var e=i.prototype[t].length;var n=Array.prototype.slice.call(arguments);var r=e===n.length?n.pop():undefined;setTimeout(function(){var e,i=null;try{e=this._creative[t].apply(this._creative,n)}catch(a){i=a}v(r,this._subscribers,i,e)}.bind(this),0)}});d.prototype.initAd=function y(t,e,n,i,r,a,o){r=r||{};a=s.extend({slot:this._el,videoSlot:this._videoEl},a||{});setTimeout(function(){var s;try{this._creative.initAd(t,e,n,i,r,a)}catch(u){s=u}v(o,this._subscribers,s)}.bind(this),0)};d.prototype.subscribe=function m(t,e,n){this._subscribers.subscribe(e,t,n)};d.prototype.unsubscribe=function A(t,e){this._subscribers.unsubscribe(e,t)};d.prototype.on=d.prototype.subscribe;d.prototype.off=d.prototype.unsubscribe;i.GETTERS.forEach(function(t){d.prototype[t]=function(e){setTimeout(function(){var n,i=null;try{n=this._creative[t]()}catch(r){i=r}v(e,this._subscribers,i,n)}.bind(this),0)}});d.prototype.setAdVolume=function k(t,e){setTimeout(function(){var n,i=null;try{this._creative.setAdVolume(t);n=this._creative.getAdVolume()}catch(r){i=r}if(!i){i=s.validate(n===t,"failed to apply volume: "+t)}v(e,this._subscribers,i,n)}.bind(this),0)};d.prototype._destroy=function _(){this.stopAd();this._subscribers.unsubscribeAll()};function f(){c.forEach(function(t){this._creative.subscribe(p.bind(this,t),t)}.bind(this));this._creative.subscribe(h.bind(this),l);if(this._videoEl){var t=this._iframe.contentDocument.documentElement;var e=this._videoEl;t.addEventListener("click",function(n){if(n.target===t){e.click()}})}}function h(t,e,n){this._subscribers.triggerSync(l,{url:t,id:e,playerHandles:n})}function p(t){this._subscribers.trigger(t,Array.prototype.slice(arguments,1))}function v(t,e,n,i){if(t){t(n,i)}else if(n){e.trigger(u,n)}}e.exports=d},{"./IVPAIDAdUnit":9,"./subscriber":12,"./utils":13}],11:[function(t,e,n){"use strict";var i=t("./utils");var r=i.unique("vpaidIframe");var a=t("./VPAIDAdUnit");var s=""+''+''+'
'+''+'"+""+"";var o="AdStopped";function u(t,e,n,a){n=n||{};this._id=r();this._destroyed=false;this._frameContainer=i.createElementInEl(t,"div");this._videoEl=e;this._vpaidOptions=a||{timeout:1e4};this._templateConfig={template:n.template||s,extraOptions:n.extraOptions||{}}}u.prototype.destroy=function y(){if(this._destroyed){return}this._destroyed=true;d.call(this)};u.prototype.isDestroyed=function m(){return this._destroyed};u.prototype.loadAdUnit=function A(t,e){v.call(this);d.call(this);var n=this;var r=i.createIframeWithContent(this._frameContainer,this._templateConfig.template,i.extend({iframeURL_JS:t,iframeID:this.getID(),origin:g()},this._templateConfig.extraOptions));this._frame=r;this._onLoad=i.callbackTimeout(this._vpaidOptions.timeout,s.bind(this),u.bind(this));window.addEventListener("message",this._onLoad);function s(t){if(t.origin!==g())return;var r=JSON.parse(t.data);if(r.id!==n.getID())return;var s,u,l;if(!n._frame.contentWindow){u="the iframe is not anymore in the DOM tree"}else{l=n._frame.contentWindow.getVPAIDAd;u=i.validate(typeof l==="function","the ad didn't return a function to create an ad")}if(!u){var d=n._frame.contentWindow.document.querySelector(".ad-element");s=new a(l(),d,n._videoEl,n._frame);s.subscribe(o,c.bind(n));u=i.validate(s.isValidVPAIDAd(),"the add is not fully complaint with VPAID specification")}n._adUnit=s;h.call(n);e(u,u?null:s);return true}function u(){e("timeout",null)}};u.prototype.unloadAdUnit=function k(){d.call(this)};u.prototype.getID=function(){return this._id};function l(t){var e=this[t];if(e){e.remove();delete this[t]}}function c(){f.call(this);delete this._adUnit}function d(){f.call(this);p.call(this)}function f(){l.call(this,"_frame");h.call(this)}function h(){if(this._onLoad){window.removeEventListener("message",this._onLoad);i.clearCallbackTimeout(this._onLoad);delete this._onLoad}}function p(){if(this._adUnit){this._adUnit.stopAd();delete this._adUnit}}function v(){if(this._destroyed){throw new Error("VPAIDHTML5Client already destroyed!")}}function g(){if(window.location.origin){return window.location.origin}else{return window.location.protocol+"//"+window.location.hostname+(window.location.port?":"+window.location.port:"")}}e.exports=u;window.VPAIDHTML5Client=u},{"./VPAIDAdUnit":10,"./utils":13}],12:[function(t,e,n){"use strict";function i(){this._subscribers={}}i.prototype.subscribe=function r(t,e,n){if(!this.isHandlerAttached(t,e)){this.get(e).push({handler:t,context:n,eventName:e})}};i.prototype.unsubscribe=function a(t,e){this._subscribers[e]=this.get(e).filter(function(e){return t!==e.handler})};i.prototype.unsubscribeAll=function s(){this._subscribers={}};i.prototype.trigger=function(t,e){var n=this;var i=this.get(t).concat(this.get("*"));i.forEach(function(t){setTimeout(function(){if(n.isHandlerAttached(t.handler,t.eventName)){t.handler.call(t.context,e)}},0)})};i.prototype.triggerSync=function(t,e){var n=this.get(t).concat(this.get("*"));n.forEach(function(t){t.handler.call(t.context,e)})};i.prototype.get=function o(t){if(!this._subscribers[t]){this._subscribers[t]=[]}return this._subscribers[t]};i.prototype.isHandlerAttached=function u(t,e){return this.get(e).some(function(e){return t===e.handler})};e.exports=i},{}],13:[function(t,e,n){"use strict";function i(){}function r(t,e){return t?null:new Error(e)}var a={};function s(t){var e=a[t];if(e){clearTimeout(e);delete a[t]}}function o(t,e,n){var r,o;o=setTimeout(function(){e=i;delete o[r];n()},t);r=function(){if(e.apply(this,arguments)){s(r)}};a[r]=o;return r}function u(t,e,n){var i=document.createElement(e);if(n)i.id=n;t.appendChild(i);return i}function l(t,e,n){var i=c(t,null,n.zIndex);if(!f(i,d(e,n)))return;return i}function c(t,e,n){var i=document.createElement("iframe");i.src=e||"about:blank";i.marginWidth="0";i.marginHeight="0";i.frameBorder="0";i.width="100%";i.height="100%";i.style.position="absolute";i.style.left="0";i.style.top="0";i.style.margin="0px";i.style.padding="0px";i.style.border="none";if(n){i.style.zIndex=n}i.setAttribute("SCROLLING","NO");t.innerHTML="";t.appendChild(i);return i}function d(t,e){Object.keys(e).forEach(function(n){var i=typeof i==="object"?JSON.stringify(e[n]):e[n];t=t.replace(new RegExp("{{"+n+"}}","g"),i)});return t}function f(t,e){var n=t.contentWindow&&t.contentWindow.document;if(!n)return false;n.write(e);return true}function h(t,e){Object.keys(e).forEach(function(n){t[n]=e[n]});return t}function p(t){var e=-1;return function(){return t+"_"+ ++e}}e.exports={noop:i,validate:r,clearCallbackTimeout:s,callbackTimeout:o,createElementInEl:u,createIframeWithContent:l,createIframe:c,simpleTemplate:d,setIframeContent:f,extend:h,unique:p}},{}],14:[function(t,e,n){(function(t,n){if(typeof define==="function"&&define.amd){define(n)}else if(typeof e==="object"&&e.exports){e.exports=n()}else{t.swfobject=n()}})(this,function(){var t="undefined",e="object",n="Shockwave Flash",i="ShockwaveFlash.ShockwaveFlash",r="application/x-shockwave-flash",a="SWFObjectExprInst",s="onreadystatechange",o=window,u=document,l=navigator,c=false,d=[],f=[],h=[],p=[],v,g,y,m,A=false,k=false,_,w,b=true,E=false,T=function(){var a=typeof u.getElementById!==t&&typeof u.getElementsByTagName!==t&&typeof u.createElement!==t,s=l.userAgent.toLowerCase(),d=l.platform.toLowerCase(),f=d?/win/.test(d):/win/.test(s),h=d?/mac/.test(d):/mac/.test(s),p=/webkit/.test(s)?parseFloat(s.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,v=l.appName==="Microsoft Internet Explorer",g=[0,0,0],y=null;if(typeof l.plugins!==t&&typeof l.plugins[n]===e){y=l.plugins[n].description;if(y&&(typeof l.mimeTypes!==t&&l.mimeTypes[r]&&l.mimeTypes[r].enabledPlugin)){c=true;v=false;y=y.replace(/^.*\s+(\S+\s+\S+$)/,"$1"); -g[0]=q(y.replace(/^(.*)\..*$/,"$1"));g[1]=q(y.replace(/^.*\.(.*)\s.*$/,"$1"));g[2]=/[a-zA-Z]/.test(y)?q(y.replace(/^.*[a-zA-Z]+(.*)$/,"$1")):0}}else if(typeof o.ActiveXObject!==t){try{var m=new ActiveXObject(i);if(m){y=m.GetVariable("$version");if(y){v=true;y=y.split(" ")[1].split(",");g=[q(y[0]),q(y[1]),q(y[2])]}}}catch(A){}}return{w3:a,pv:g,wk:p,ie:v,win:f,mac:h}}(),S=function(){if(!T.w3){return}if(typeof u.readyState!==t&&(u.readyState==="complete"||u.readyState==="interactive")||typeof u.readyState===t&&(u.getElementsByTagName("body")[0]||u.body)){V()}if(!A){if(typeof u.addEventListener!==t){u.addEventListener("DOMContentLoaded",V,false)}if(T.ie){u.attachEvent(s,function e(){if(u.readyState==="complete"){u.detachEvent(s,e);V()}});if(o==top){(function n(){if(A){return}try{u.documentElement.doScroll("left")}catch(t){setTimeout(n,0);return}V()})()}}if(T.wk){(function i(){if(A){return}if(!/loaded|complete/.test(u.readyState)){setTimeout(i,0);return}V()})()}}}();function V(){if(A||!document.getElementsByTagName("body")[0]){return}try{var t,e=z("span");e.style.display="none";t=u.getElementsByTagName("body")[0].appendChild(e);t.parentNode.removeChild(t);t=null;e=null}catch(n){return}A=true;var i=d.length;for(var r=0;r0){for(var n=0;n0){var s=W(i);if(s){if(J(f[n].swfVersion)&&!(T.wk&&T.wk<312)){Q(i,true);if(r){a.success=true;a.ref=U(i);a.id=i;r(a)}}else if(f[n].expressInstall&&P()){var o={};o.data=f[n].expressInstall;o.width=s.getAttribute("width")||"0";o.height=s.getAttribute("height")||"0";if(s.getAttribute("class")){o.styleclass=s.getAttribute("class")}if(s.getAttribute("align")){o.align=s.getAttribute("align")}var u={};var l=s.getElementsByTagName("param");var c=l.length;for(var d=0;d"+e+"";return n.firstChild}function O(n,i,a){var s,o=W(a);a=B(a);if(T.wk&&T.wk<312){return s}if(o){var u=T.ie?z("div"):z(e),l,c,d;if(typeof n.id===t){n.id=a}for(d in i){if(i.hasOwnProperty(d)&&d.toLowerCase()!=="movie"){N(u,d,i[d])}}if(T.ie){u=R(n.data,u.innerHTML)}for(l in n){if(n.hasOwnProperty(l)){c=l.toLowerCase();if(c==="styleclass"){u.setAttribute("class",n[l])}else if(c!=="classid"&&c!=="data"){u.setAttribute(l,n[l])}}}if(T.ie){h[h.length]=n.id}else{u.setAttribute("type",r);u.setAttribute("data",n.data)}o.parentNode.replaceChild(u,o);s=u}return s}function N(t,e,n){var i=z("param");i.setAttribute("name",e);i.setAttribute("value",n);t.appendChild(i)}function j(t){var e=W(t);if(e&&e.nodeName.toUpperCase()==="OBJECT"){if(T.ie){e.style.display="none";(function n(){if(e.readyState==4){for(var t in e){if(typeof e[t]==="function"){e[t]=null}}e.parentNode.removeChild(e)}else{setTimeout(n,10)}})()}else{e.parentNode.removeChild(e)}}}function H(t){return t&&t.nodeType&&t.nodeType===1}function B(t){return H(t)?t.id:t}function W(t){if(H(t)){return t}var e=null;try{e=u.getElementById(t)}catch(n){}return e}function z(t){return u.createElement(t)}function q(t){return parseInt(t,10)}function X(t,e,n){t.attachEvent(e,n);p[p.length]=[t,e,n]}function J(t){t+="";var e=T.pv,n=t.split(".");n[0]=q(n[0]);n[1]=q(n[1])||0;n[2]=q(n[2])||0;return e[0]>n[0]||e[0]==n[0]&&e[1]>n[1]||e[0]==n[0]&&e[1]==n[1]&&e[2]>=n[2]?true:false}function $(e,n,i,r){var a=u.getElementsByTagName("head")[0];if(!a){return}var s=typeof i==="string"?i:"screen";if(r){_=null;w=null}if(!_||w!=s){var o=z("style");o.setAttribute("type","text/css");o.setAttribute("media",s);_=a.appendChild(o);if(T.ie&&typeof u.styleSheets!==t&&u.styleSheets.length>0){_=u.styleSheets[u.styleSheets.length-1]}w=s}if(_){if(typeof _.addRule!==t){_.addRule(e,n)}else if(typeof u.createTextNode!==t){_.appendChild(u.createTextNode(e+" {"+n+"}"))}}}function Q(t,e){if(!b){return}var n=e?"visible":"hidden",i=W(t);if(A&&i){i.style.visibility=n}else if(typeof t==="string"){$("#"+t,"visibility:"+n)}}function G(e){var n=/[\\\"<>\.;]/;var i=n.exec(e)!==null;return i&&typeof encodeURIComponent!==t?encodeURIComponent(e):e}var K=function(){if(T.ie){window.attachEvent("onunload",function(){var t=p.length;for(var e=0;e0){d(r.shift(),[],a)}else{e(t,i)}}else{e(null,i)}}});function a(t,e){var i=n._requestVASTXml.bind(n,t);o.waterfall([i,s],e)}function s(t,e){var n;try{n=c.toJXONTree(t);if(l.isArray(n.ad)){n.ads=n.ad}else if(n.ad){n.ads=[n.ad]}else{n.ads=[]}e(u(n),n)}catch(i){e(new r("on VASTClient.getVASTAd.buildVastWaterfall, error parsing xml",100),null)}}function u(t){var e=c.attr(t,"version");if(!t.ad){return new r("on VASTClient.getVASTAd.validateVASTTree, no Ad in VAST tree",303)}if(e&&(e!=3&&e!=2)){return new r('on VASTClient.getVASTAd.validateVASTTree, not supported VAST version "'+e+'"',102)}return null}function d(t,e,i){if(e.length>=n.WRAPPER_LIMIT){return i(new r("on VASTClient.getVASTAd.getAd, players wrapper limit reached (the limit is "+n.WRAPPER_LIMIT+")",302),e)}o.waterfall([function(e){if(l.isString(t)){p(t,e)}else{e(null,t)}},f],function(t,n){if(n){e.push(n)}if(t){return i(t,e)}if(n.wrapper){return d(n.wrapper.VASTAdTagURI,e,i)}return i(null,e)})}function f(t,e){try{var n=new i(t);e(h(n),n)}catch(a){e(new r("on VASTClient.getVASTAd.buildAd, error parsing xml",100),null)}}function h(t){var e=t.wrapper;var n=t.inLine;var i="on VASTClient.getVASTAd.validateAd, ";if(n&&e){return new r(i+"InLine and Wrapper both found on the same Ad",101)}if(!n&&!e){return new r(i+"nor wrapper nor inline elements found on the Ad",101)}if(n&&!n.isSupported()){return new r(i+"could not find MediaFile that is supported by this video player",403)}if(e&&!e.VASTAdTagURI){return new r(i+"missing 'VASTAdTagURI' in wrapper",101)}return null}function p(t,e){n._requestVASTXml(t,function(t,n){if(t){return e(t)}try{var i=c.toJXONTree(n);e(u(i),i.ad)}catch(a){e(new r("on VASTClient.getVASTAd.requestVASTAd, error parsing xml",100))}})}};d.prototype._requestVASTXml=function h(t,e){try{if(l.isFunction(t)){t(i)}else{u.get(t,i,{withCredentials:true})}}catch(n){e(n)}function i(t,n,i){if(t){var a=l.isDefined(i)?"on VASTClient.requestVastXML, HTTP request error with status '"+i+"'":"on VASTClient.requestVastXML, Error getting the the VAST XML with he passed adTagXML fn";return e(new r(a,301),null)}e(null,n)}};d.prototype._buildVASTResponse=function p(t){var e=new a;n(e,t);i(e);return e;function n(t,e){e.forEach(function(e){t.addAd(e)})}function i(t){var e=t.trackingEvents.progress;if(!t.hasLinear()){throw new r("on VASTClient._buildVASTResponse, Received an Ad type that is not supported",200)}if(t.duration===undefined){throw new r("on VASTClient._buildVASTResponse, Missing duration field in VAST response",101)}if(e){e.forEach(function(t){if(!l.isNumber(t.offset)){throw new r("on VASTClient._buildVASTResponse, missing or wrong offset attribute on progress tracking event",101)}})}}};d.prototype._trackError=function(t,e){if(!l.isArray(e)||e.length===0){return}var n=[];e.forEach(i);s.track(n,{ERRORCODE:t.code||900});function i(t){if(t.wrapper&&t.wrapper.error){n.push(t.wrapper.error)}if(t.inLine&&t.inLine.error){n.push(t.inLine.error)}}};e.exports=d},{"../../utils/async":40,"../../utils/http":42,"../../utils/utilityFunctions":45,"../../utils/xml":46,"./Ad":15,"./VASTError":23,"./VASTResponse":25,"./vastUtil":30}],23:[function(t,e,n){"use strict";function i(t,e){this.message="VAST Error: "+(t||"");if(e){this.code=e}}i.prototype=new Error;i.prototype.name="VAST Error";e.exports=i},{}],24:[function(t,e,n){"use strict";var i=t("./VASTResponse");var r=t("./VASTError");var a=t("./VASTTracker");var s=t("./vastUtil");var o=t("../../utils/async");var u=t("../../utils/dom");var l=t("../../utils/playerUtils");var c=t("../../utils/utilityFunctions");function d(t){if(!(this instanceof d)){return new d(t)}this.player=t}d.prototype.playAd=function f(t,e){var n=this;e=e||c.noop;if(!(t instanceof i)){return e(new r("On VASTIntegrator, missing required VASTResponse"))}o.waterfall([function(e){e(null,t)},this._selectAdSource.bind(this),this._createVASTTracker.bind(this),this._addClickThrough.bind(this),this._addSkipButton.bind(this),this._setupEvents.bind(this),this._playSelectedAd.bind(this)],function(t,i){if(t&&i){n._trackError(t,i)}e(t,i)});this._adUnit={_src:null,type:"VAST",pauseAd:function(){n.player.pause(true)},resumeAd:function(){n.player.play(true)},isPaused:function(){return n.player.paused(true)},getSrc:function(){return this._src}};return this._adUnit};d.prototype._selectAdSource=function h(t,e){var n;var i=u.getDimension(this.player.el()).width;t.mediaFiles.sort(function a(t,e){var n=Math.abs(i-t.width);var r=Math.abs(i-e.width);return n-r});n=this.player.selectSource(t.mediaFiles).source;if(n){if(this._adUnit){this._adUnit._src=n}return e(null,n,t)}e(new r("Could not find Ad mediafile supported by this player",403),t)};d.prototype._createVASTTracker=function p(t,e,n){try{n(null,t,new a(t.src,e),e)}catch(i){n(i,e)}};d.prototype._setupEvents=function v(t,e,n,i){var r;var a=this.player;a.on("fullscreenchange",o);a.on("vast.adStart",d);a.on("pause",u);a.on("timeupdate",c);a.on("volumechange",f);l.once(a,["vast.adEnd","vast.adsCancel"],s);l.once(a,["vast.adEnd","vast.adsCancel","vast.adSkip"],function(t){if(t.type==="vast.adEnd"){e.trackComplete()}});return i(null,t,n);function s(){a.off("fullscreenchange",o);a.off("vast.adStart",d);a.off("pause",u);a.off("timeupdate",c);a.off("volumechange",f)}function o(){if(a.isFullscreen()){e.trackFullscreen()}else{e.trackExitFullscreen()}}function u(){if(Math.abs(a.duration()-a.currentTime())<2){return}e.trackPause();l.once(a,["play","vast.adEnd","vast.adsCancel"],function(t){if(t.type==="play"){e.trackResume()}})}function c(){var t=a.currentTime()*1e3;e.trackProgress(t)}function d(){e.trackImpressions();e.trackCreativeView()}function f(){var t=a.muted();if(t){e.trackMute()}else if(r){e.trackUnmute()}r=t}};d.prototype._addSkipButton=function g(t,e,n,i){var r;var a=this;if(c.isNumber(n.skipoffset)){r=n.skipoffset/1e3;s(this.player,r)}i(null,t,e,n);function s(t,e){var n=o(t);var i=d.bind(a,n,e,t);t.el().appendChild(n);t.on("timeupdate",i);l.once(t,["vast.adEnd","vast.adsCancel"],r);function r(){t.off("timeupdate",i);u.remove(n)}}function o(t){var n=window.document.createElement("div");u.addClass(n,"vast-skip-button");n.onclick=function(i){if(u.hasClass(n,"enabled")){e.trackSkip();t.trigger("vast.adSkip")}if(window.Event.prototype.stopPropagation!==undefined){i.stopPropagation()}else{return false}};return n}function d(t,e,n){var i=Math.ceil(e-n.currentTime());if(i>0){t.innerHTML="Skip in "+c.toFixedDigits(i,2)+"..."}else{if(!u.hasClass(t,"enabled")){u.addClass(t,"enabled");t.innerHTML="Skip ad"}}}};d.prototype._addClickThrough=function y(t,e,n,i){var r=this.player;var a=d(r,e,n);var o=f.bind(this,a,n,r);r.el().insertBefore(a,r.controlBar.el());r.on("timeupdate",o);l.once(r,["vast.adEnd","vast.adsCancel"],p);return i(null,t,e,n);function d(t,e,n){var i=window.document.createElement("a");var r=n.clickThrough;u.addClass(i,"vast-blocker");i.href=h(r,t);if(c.isString(r)){i.target="_blank"}i.onclick=function(n){if(t.paused()){t.play();if(window.Event.prototype.stopPropagation!==undefined){n.stopPropagation()}return false}t.pause();e.trackClick()};return i}function f(t,e,n){t.href=h(e.clickThrough,n)}function h(e,n){var i={ASSETURI:t.src,CONTENTPLAYHEAD:s.formatProgress(n.currentTime()*1e3)};return e?s.parseURLMacro(e,i):"#"}function p(){r.off("timeupdate",o);u.remove(a)}};d.prototype._playSelectedAd=function m(t,e,n){var i=this.player;i.preload("auto");i.src(t);l.once(i,["durationchange","error","vast.adsCancel"],function(t){if(t.type==="durationchange"){a()}else if(t.type==="error"){n(new r("on VASTIntegrator, Player is unable to play the Ad",400),e)}});function a(){l.once(i,["playing","vast.adsCancel"],function(t){if(t.type==="vast.adsCancel"){return}i.trigger("vast.adStart");i.on("ended",r);i.on("vast.adsCancel",r);i.on("vast.adSkip",r);function r(t){if(t.type==="ended"&&i.duration()-i.currentTime()>3){return}i.off("ended",r);i.off("vast.adsCancel",r);i.off("vast.adSkip",r);if(t.type==="ended"||t.type==="vast.adSkip"){n(null,e)}}});i.play()}};d.prototype._trackError=function A(t,e){s.track(e.errorURLMacros,{ERRORCODE:t.code||900})};e.exports=d},{"../../utils/async":40,"../../utils/dom":41,"../../utils/playerUtils":43,"../../utils/utilityFunctions":45,"./VASTError":23,"./VASTResponse":25,"./VASTTracker":26,"./vastUtil":30}],25:[function(t,e,n){"use strict";var i=t("./Ad");var r=t("./VideoClicks");var a=t("./Linear");var s=t("./InLine");var o=t("./Wrapper");var u=t("../../utils/utilityFunctions");var l=t("../../utils/xml");window.InLine__A=s;function c(){if(!(this instanceof c)){return new c}this._linearAdded=false;this.ads=[];this.errorURLMacros=[];this.impressions=[];this.clickTrackings=[];this.customClicks=[];this.trackingEvents={};this.mediaFiles=[];this.clickThrough=undefined;this.adTitle="";this.duration=undefined;this.skipoffset=undefined}c.prototype.addAd=function(t){var e,n;if(t instanceof i){e=t.inLine;n=t.wrapper;this.ads.push(t);if(e){this._addInLine(e)}if(n){this._addWrapper(n)}}};c.prototype._addErrorTrackUrl=function(t){var e=t instanceof l.JXONTree?l.keyValue(t):t;if(e){this.errorURLMacros.push(e)}};c.prototype._addImpressions=function(t){u.isArray(t)&&d(this.impressions,t)};c.prototype._addClickThrough=function(t){if(u.isNotEmptyString(t)){this.clickThrough=t}};c.prototype._addClickTrackings=function(t){u.isArray(t)&&d(this.clickTrackings,t)};c.prototype._addCustomClicks=function(t){u.isArray(t)&&d(this.customClicks,t)};c.prototype._addTrackingEvents=function(t){var e=this.trackingEvents;if(t){t=u.isArray(t)?t:[t];t.forEach(function(t){if(!e[t.name]){e[t.name]=[]}e[t.name].push(t)})}};c.prototype._addTitle=function(t){if(u.isNotEmptyString(t)){this.adTitle=t}};c.prototype._addDuration=function(t){if(u.isNumber(t)){this.duration=t}};c.prototype._addVideoClicks=function(t){if(t instanceof r){this._addClickThrough(t.clickThrough);this._addClickTrackings(t.clickTrackings);this._addCustomClicks(t.customClicks)}};c.prototype._addMediaFiles=function(t){u.isArray(t)&&d(this.mediaFiles,t)};c.prototype._addSkipoffset=function(t){if(t){this.skipoffset=t}};c.prototype._addAdParameters=function(t){if(t){this.adParameters=t}};c.prototype._addLinear=function(t){if(t instanceof a){this._addDuration(t.duration);this._addTrackingEvents(t.trackingEvents);this._addVideoClicks(t.videoClicks);this._addMediaFiles(t.mediaFiles);this._addSkipoffset(t.skipoffset);this._addAdParameters(t.adParameters);this._linearAdded=true}};c.prototype._addInLine=function(t){var e=this;if(t instanceof s){this._addTitle(t.adTitle);this._addErrorTrackUrl(t.error);this._addImpressions(t.impressions);t.creatives.forEach(function(t){if(t.linear){e._addLinear(t.linear)}})}};c.prototype._addWrapper=function(t){var e=this;if(t instanceof o){this._addErrorTrackUrl(t.error);this._addImpressions(t.impressions);t.creatives.forEach(function(t){var n=t.linear;if(n){e._addVideoClicks(n.videoClicks);e.clickThrough=undefined;e._addTrackingEvents(n.trackingEvents)}})}};c.prototype.hasLinear=function(){return this._linearAdded};function d(t,e){e.forEach(function(e){t.push(e)})}e.exports=c},{"../../utils/utilityFunctions":45,"../../utils/xml":46,"./Ad":15,"./InLine":18,"./Linear":19,"./VideoClicks":27,"./Wrapper":28}],26:[function(t,e,n){"use strict";var i=t("./VASTError");var r=t("./VASTResponse");var a=t("./vastUtil");var s=t("../../utils/utilityFunctions");function o(t,e){if(!(this instanceof o)){return new o(t,e)}this.sanityCheck(t,e);this.initialize(t,e)}o.prototype.initialize=function(t,e){this.response=e;this.assetURI=t;this.progress=0;this.quartiles={firstQuartile:{tracked:false,time:Math.round(25*e.duration)/100},midpoint:{tracked:false,time:Math.round(50*e.duration)/100},thirdQuartile:{tracked:false,time:Math.round(75*e.duration)/100}}};o.prototype.sanityCheck=function(t,e){if(!s.isString(t)||s.isEmptyString(t)){throw new i("on VASTTracker constructor, missing required the URI of the ad asset being played")}if(!(e instanceof r)){throw new i("on VASTTracker constructor, missing required VAST response")}};o.prototype.trackURLs=function u(t,e){if(s.isArray(t)&&t.length>0){e=s.extend({ASSETURI:this.assetURI,CONTENTPLAYHEAD:a.formatProgress(this.progress)},e||{});a.track(t,e)}};o.prototype.trackEvent=function l(t,e){this.trackURLs(n(this.response.trackingEvents[t]));if(e){this.response.trackingEvents[t]=undefined}function n(t){var e;if(t){e=[];t.forEach(function(t){e.push(t.uri)})}return e}};o.prototype.trackProgress=function c(t){var e=this;var n=[];var i=true;var r=false;var a=this.response.trackingEvents;if(s.isNumber(t)){u("start",i,t>0);u("rewind",r,o(this.progress,t));l(t);d(t);f();this.progress=t}function o(e,n){var i=3e3;return e>t&&Math.abs(n-e)>i}function u(t,e,i){if(a[t]&&i){n.push({name:t,trackOnce:!!e})}}function l(t){var n=e.quartiles;var r=e.quartiles.firstQuartile;var a=e.quartiles.midpoint;var s=e.quartiles.thirdQuartile;if(!r.tracked){o("firstQuartile",t)}else if(!a.tracked){o("midpoint",t)}else if(!s.tracked){o("thirdQuartile",t)}function o(t,e){var r=n[t];if(c(r,e)){r.tracked=true;u(t,i,true)}}}function c(t,e){var n=t.time;return e>=n&&e<=n+5e3}function d(t){if(!s.isArray(a.progress)){return}var n=[];a.progress.forEach(function(i){if(i.offset<=t){e.trackURLs([i.uri])}else{n.push(i)}});a.progress=n}function f(){n.forEach(function(t){e.trackEvent(t.name,t.trackOnce)})}};["rewind","fullscreen","exitFullscreen","pause","resume","mute","unmute","acceptInvitation","acceptInvitationLinear","collapse","expand"].forEach(function(t){o.prototype["track"+s.capitalize(t)]=function(){this.trackEvent(t)}});["start","skip","close","closeLinear"].forEach(function(t){o.prototype["track"+s.capitalize(t)]=function(){this.trackEvent(t,true)}});["firstQuartile","midpoint","thirdQuartile"].forEach(function(t){o.prototype["track"+s.capitalize(t)]=function(){this.quartiles[t].tracked=true;this.trackEvent(t,true)}});o.prototype.trackComplete=function(){if(this.quartiles.thirdQuartile.tracked){this.trackEvent("complete",true)}};o.prototype.trackErrorWithCode=function d(t){if(s.isNumber(t)){this.trackURLs(this.response.errorURLMacros,{ERRORCODE:t})}};o.prototype.trackImpressions=function f(){this.trackURLs(this.response.impressions)};o.prototype.trackCreativeView=function h(){this.trackEvent("creativeView")};o.prototype.trackClick=function p(){this.trackURLs(this.response.clickTrackings)};e.exports=o},{"../../utils/utilityFunctions":45,"./VASTError":23,"./VASTResponse":25,"./vastUtil":30}],27:[function(t,e,n){"use strict";var i=t("../../utils/utilityFunctions");var r=t("../../utils/xml");function a(t){if(!(this instanceof a)){return new a(t)}this.clickThrough=r.keyValue(t.clickThrough);this.clickTrackings=e(t.clickTracking);this.customClicks=e(t.customClick);function e(t){var e=[];if(t){t=i.isArray(t)?t:[t];t.forEach(function(t){e.push(r.keyValue(t))})}return e}}e.exports=a},{"../../utils/utilityFunctions":45,"../../utils/xml":46}],28:[function(t,e,n){"use strict";var i=t("./vastUtil");var r=t("./Creative");var a=t("../../utils/utilityFunctions");var s=t("../../utils/xml");function o(t){if(!(this instanceof o)){return new o(t)}this.adSystem=s.keyValue(t.adSystem);this.impressions=i.parseImpressions(t.impression);this.VASTAdTagURI=s.keyValue(t.vASTAdTagURI);this.creatives=r.parseCreatives(t.creatives);this.error=s.keyValue(t.error);this.extensions=t.extensions;this.followAdditionalWrappers=a.isDefined(s.attr(t,"followAdditionalWrappers"))?s.attr(t,"followAdditionalWrappers"):true;this.allowMultipleAds=s.attr(t,"allowMultipleAds");this.fallbackOnNoAd=s.attr(t,"fallbackOnNoAd")}e.exports=o},{"../../utils/utilityFunctions":45,"../../utils/xml":46,"./Creative":17,"./vastUtil":30}],29:[function(t,e,n){"use strict";var i=t("../../utils/utilityFunctions");var r=/(\d\d):(\d\d):(\d\d)(\.(\d\d\d))?/;var a={duration:function s(t){var e,n;if(i.isString(t)){e=t.match(r);if(e){n=a(e[1])+s(e[2])+o(e[3])+parseInt(e[5]||0)}}return isNaN(n)?null:n;function a(t){return parseInt(t,10)*60*60*1e3}function s(t){return parseInt(t,10)*60*1e3}function o(t){return parseInt(t,10)*1e3}},offset:function o(t,e){if(n(t)){return i(t,e)}return a.duration(t);function n(t){var e=/^\d+(\.\d+)?%$/g;return e.test(t)}function i(t,e){if(e){return r(e,parseFloat(t.replace("%","")))}return null}function r(t,e){return t*e/100}}};e.exports=a},{"../../utils/utilityFunctions":45}],30:[function(t,e,n){"use strict";var i=t("../../utils/utilityFunctions");var r=t("../vpaid/VPAIDHTML5Tech");var a=t("../vpaid/VPAIDFlashTech");var s=t("VPAIDFLASHClient/js/VPAIDFLASHClient"); -var o={track:function u(t,e){var n=o.parseURLMacros(t,e);var i=[];n.forEach(function(t){var e=new Image;e.src=t;i.push(e)});return i},parseURLMacros:function l(t,e){var n=[];e=e||{};if(!e["CACHEBUSTING"]){e["CACHEBUSTING"]=Math.round(Math.random()*1e10)}t.forEach(function(t){n.push(o._parseURLMacro(t,e))});return n},parseURLMacro:function c(t,e){e=e||{};if(!e["CACHEBUSTING"]){e["CACHEBUSTING"]=Math.round(Math.random()*1e10)}return o._parseURLMacro(t,e)},_parseURLMacro:function d(t,e){e=e||{};i.forEach(e,function(e,n){t=t.replace(new RegExp("\\["+n+"\\]","gm"),e)});return t},parseDuration:function f(t){var e=/(\d\d):(\d\d):(\d\d)(\.(\d\d\d))?/;var n,r;if(i.isString(t)){n=t.match(e);if(n){r=a(n[1])+s(n[2])+o(n[3])+parseInt(n[5]||0)}}return isNaN(r)?null:r;function a(t){return parseInt(t,10)*60*60*1e3}function s(t){return parseInt(t,10)*60*1e3}function o(t){return parseInt(t,10)*1e3}},parseImpressions:function h(t){if(t){t=i.isArray(t)?t:[t];return i.transformArray(t,function(t){if(i.isNotEmptyString(t.keyValue)){return t.keyValue}return undefined})}return[]},formatProgress:function p(t){var e,n,r,a;e=t/(60*60*1e3);e=Math.floor(e);n=t/(60*1e3)%60;n=Math.floor(n);r=t/1e3%60;r=Math.floor(r);a=t%1e3;return i.toFixedDigits(e,2)+":"+i.toFixedDigits(n,2)+":"+i.toFixedDigits(r,2)+"."+i.toFixedDigits(a,3)},parseOffset:function v(t,e){if(n(t)){return i(t,e)}return o.parseDuration(t);function n(t){var e=/^\d+(\.\d+)?%$/g;return e.test(t)}function i(t,e){if(e){return r(e,parseFloat(t.replace("%","")))}return null}function r(t,e){return t*e/100}},VPAID_techs:[a,r],isVPAID:function g(t){return!!t&&t.apiFramework==="VPAID"},findSupportedVPAIDTech:function y(t){var e,n,i;for(e=0,n=this.VPAID_techs.length;e=1&&e<=2}function a(t){var e=t.split(".");return parseInt(e[0],10)}};f.prototype._initAd=function(t,e,n){var i=this.player.el().querySelector(".vjs-tech");var r=l.getDimension(i);t.initAd(r.width,r.height,this.VIEW_MODE.NORMAL,-1,{AdParameters:e.adParameters||""},function(i){n(i,t,e)})};f.prototype._createVASTTracker=function(t,e){return new a(t,e)};f.prototype._setupEvents=function(t,e,n){var i=t.options.src;var r=this._createVASTTracker(i,e);var a=this.player;var o=this;t.on("AdSkipped",function(){a.trigger("vpaid.AdSkipped");r.trackSkip()});t.on("AdImpression",function(){a.trigger("vpaid.AdImpression");r.trackImpressions()});t.on("AdStarted",function(){a.trigger("vpaid.AdStarted");r.trackCreativeView();u()});t.on("AdVideoStart",function(){a.trigger("vpaid.AdVideoStart");r.trackStart();u()});t.on("AdPlaying",function(){a.trigger("vpaid.AdPlaying");r.trackResume();u()});t.on("AdPaused",function(){a.trigger("vpaid.AdPaused");r.trackPause();c()});function u(){if(o._adUnit&&o._adUnit.isPaused()){o._adUnit._paused=false}a.trigger("play")}function c(){if(o._adUnit){o._adUnit._paused=true}a.trigger("pause")}t.on("AdVideoFirstQuartile",function(){a.trigger("vpaid.AdVideoFirstQuartile");r.trackFirstQuartile()});t.on("AdVideoMidpoint",function(){a.trigger("vpaid.AdVideoMidpoint");r.trackMidpoint()});t.on("AdVideoThirdQuartile",function(){a.trigger("vpaid.AdVideoThirdQuartile");r.trackThirdQuartile()});t.on("AdVideoComplete",function(){a.trigger("vpaid.AdVideoComplete");r.trackComplete()});t.on("AdClickThru",function(n){a.trigger("vpaid.AdClickThru");var i=n.url;var o=n.playerHandles;var u=d.isNotEmptyString(i)?i:l(e.clickThrough);r.trackClick();if(o&&u){window.open(u,"_blank")}function l(e){var n={ASSETURI:t.options.src,CONTENTPLAYHEAD:0};return e?s.parseURLMacro(e,n):null}});t.on("AdUserAcceptInvitation",function(){a.trigger("vpaid.AdUserAcceptInvitation");r.trackAcceptInvitation();r.trackAcceptInvitationLinear()});t.on("AdUserClose",function(){a.trigger("vpaid.AdUserClose");r.trackClose();r.trackCloseLinear()});t.on("AdUserMinimize",function(){a.trigger("vpaid.AdUserMinimize");r.trackCollapse()});t.on("AdError",function(){a.trigger("vpaid.AdError");r.trackErrorWithCode(901)});t.on("AdVolumeChange",function(){a.trigger("vpaid.AdVolumeChange");var e=a.volume();t.getAdVolume(function(t,n){if(n===0&&e>0){r.trackMute()}if(n>0&&e===0){r.trackUnmute()}a.volume(n)})});var f=h.bind(this,a,t,this.VIEW_MODE);var p=d.throttle(f,100);var v=this.settings.autoResize;if(v){l.addEventListener(window,"resize",p);l.addEventListener(window,"orientationchange",p)}a.on("vast.resize",f);a.on("vpaid.pauseAd",g);a.on("vpaid.resumeAd",y);a.one("vpaid.adEnd",function(){a.off("vast.resize",f);a.off("vpaid.pauseAd",g);a.off("vpaid.resumeAd",y);if(v){l.removeEventListener(window,"resize",p);l.removeEventListener(window,"orientationchange",p)}});n(null,t,e);function g(){t.pauseAd(d.noop)}function y(){t.resumeAd(d.noop)}};f.prototype._addSkipButton=function(t,e,n){var i;var r=this.player;t.on("AdSkippableStateChange",a);c.once(r,["vast.adEnd","vast.adsCancel"],o);n(null,t,e);function a(){r.trigger("vpaid.AdSkippableStateChange");t.getAdSkippableState(function(t,e){if(e){if(!i){s(r)}}else{o(r)}})}function s(t){i=u(t);t.el().appendChild(i)}function o(){l.remove(i);i=null}function u(){var e=window.document.createElement("div");l.addClass(e,"vast-skip-button");l.addClass(e,"enabled");e.innerHTML="Skip ad";e.onclick=function(e){t.skipAd(d.noop);if(window.Event.prototype.stopPropagation!==undefined){e.stopPropagation()}else{return false}};return e}};f.prototype._linkPlayerControls=function(t,e,n){var i=this;r(this.player,t);a(this.player,t,this.VIEW_MODE);n(null,t,e);function r(t,e){t.on("volumechange",n);e.on("AdVolumeChange",i);t.one("vpaid.adEnd",function(){t.off("volumechange",n)});function n(){var n=t.muted()?0:t.volume();e.setAdVolume(n,p)}function i(){t.trigger("vpaid.AdVolumeChange");e.getAdVolume(function(e,n){if(e){p(e)}else{t.volume(n)}})}}function a(t,e,n){var r=h.bind(i,t,e,n);t.on("fullscreenchange",r);t.one("vpaid.adEnd",function(){t.off("fullscreenchange",r)})}};f.prototype._startAd=function(t,e,n){var i=this.player;t.startAd(function(r){if(!r){i.trigger("vast.adStart")}n(r,t,e)})};f.prototype._finishPlaying=function(t,e,n){var r=this.player;t.on("AdStopped",function(){r.trigger("vpaid.AdStopped");a(null)});t.on("AdError",function(t){var e=t?t.message:"on VPAIDIntegrator, error while waiting for the adUnit to finish playing";a(new i(e))});function a(i){n(i,t,e)}};f.prototype._trackError=function y(t,e){s.track(t.errorURLMacros,{ERRORCODE:e||901})};function h(t,e,n){var i=t.el().querySelector(".vjs-tech");var r=l.getDimension(i);var a=t.isFullscreen()?n.FULLSCREEN:n.NORMAL;e.resizeAd(r.width,r.height,a,p)}function p(t){if(t&&console&&console.log){console.log("ERROR: "+t.message,t)}}e.exports=f},{"../../utils/async":40,"../../utils/dom":41,"../../utils/playerUtils":43,"../../utils/utilityFunctions":45,"../vast/VASTError":23,"../vast/VASTResponse":25,"../vast/VASTTracker":26,"../vast/vastUtil":30,"./VPAIDAdUnitWrapper":31}],35:[function(t,e,n){"use strict";var i=t("../../utils/dom");var r=document.createElement("div");r.className="vjs-ads-label vjs-control vjs-label-hidden";r.innerHTML="Advertisement";var a=function(t){return{init:function e(n,a){a.el=r;t.call(this,n,a);setTimeout(function(){var t=n.controlBar&&(n.controlBar.getChild("timerControls")||n.controlBar.getChild("currentTimeDisplay"));if(t){n.controlBar.el().insertBefore(r,t.el())}i.removeClass(r,"vjs-label-hidden")},0)},el:function n(){return r}}};e.exports=a},{"../../utils/dom":41}],36:[function(t,e,n){"use strict";var i=videojs.getComponent("Component");var r=t("./ads-label")(i);videojs.registerComponent("AdsLabel",videojs.extend(i,r))},{"./ads-label":35}],37:[function(t,e,n){"use strict";var i=document.createElement("div");var r=function(t){return{init:function e(n,r){r.el=i;i.className="vjs-black-poster";t.call(this,n,r);var a=n.getChild("posterImage");setTimeout(function(){if(a&&n&&n.el()){n.el().insertBefore(i,a.el())}},0)},el:function n(){return i}}};e.exports=r},{}],38:[function(t,e,n){"use strict";var i=videojs.getComponent("Component");var r=t("./black-poster")(i);videojs.registerComponent("BlackPoster",videojs.extend(i,r))},{"./black-poster":37}],39:[function(t,e,n){"use strict";var i=t("../ads/vast/VASTClient");var r=t("../ads/vast/VASTError");var a=t("../ads/vast/vastUtil");var s=t("../ads/vast/VASTIntegrator");var o=t("../ads/vpaid/VPAIDIntegrator");var u=t("../utils/async");var l=t("../utils/dom");var c=t("../utils/playerUtils");var d=t("../utils/utilityFunctions");e.exports=function f(t){var e;var n=this;var f=new i;var h=false;var p={timeout:500,iosPrerollCancelTimeout:2e3,adCancelTimeout:3e3,playAdAlways:false,adsEnabled:true,autoResize:true,vpaidFlashLoaderPath:"/VPAIDFlash.swf"};var v=d.extend({},p,t||{});if(d.isUndefined(v.adTagUrl)&&d.isDefined(v.url)){v.adTagUrl=v.url}if(d.isString(v.adTagUrl)){v.adTagUrl=d.echoFn(v.adTagUrl)}if(d.isDefined(v.adTagXML)&&!d.isFunction(v.adTagXML)){return _(new r("on VideoJS VAST plugin, the passed adTagXML option does not contain a function"))}if(!d.isDefined(v.adTagUrl)&&!d.isFunction(v.adTagXML)){return _(new r("on VideoJS VAST plugin, missing adTagUrl on options object"))}a.runFlashSupportCheck(v.vpaidFlashLoaderPath);c.prepareForAds(n);if(v.playAdAlways){n.on("vast.contentEnd",function(){setTimeout(function(){n.trigger("vast.reset")},0)})}n.on("vast.firstPlay",g);n.on("vast.reset",function(){e=null;y()});n.vast={isEnabled:function(){return v.adsEnabled},enable:function(){v.adsEnabled=true},disable:function(){v.adsEnabled=false}};return n.vast;function g(){c.removeNativePoster(n);c.once(n,["vast.adsCancel","vast.adEnd"],function(){t();i()});u.waterfall([s,o,p,m],function(t,e){if(t){_(t,e)}else{n.trigger("vast.adEnd")}});function t(){if(n.vast&&n.vast.adUnit){n.vast.adUnit=null}}function i(){a();if(e){c.restorePlayerSnapshot(n,e);e=null}}function a(){c.once(n,["playing","vast.reset","vast.firstPlay"],function(t){if(t.type!=="playing"){return}n.trigger("vast.contentStart");c.once(n,["ended","vast.reset","vast.firstPlay"],function(t){if(t.type==="ended"){n.trigger("vast.contentEnd")}})})}function s(t){if(v.adsEnabled){return t(null)}t(new r("Ads are not enabled"))}function o(t){if(f()){e=c.getPlayerSnapshot(n);n.pause();g();if(n.paused()){t(null)}else{c.once(n,["playing"],function(){n.pause();t(null)})}}else{t(new r("video content has been playing before preroll ad"))}}function f(){return!d.isIPhone()||n.currentTime()<=v.iosPrerollCancelTimeout}function p(t){var e;h=false;e=setTimeout(function(){_(new r("timeout while waiting for the video to start playing",402))},v.adCancelTimeout);c.once(n,["vast.adStart","vast.adsCancel"],i);function i(){if(e){clearTimeout(e);e=null}}t(null)}function g(){l.addClass(n.el(),"vjs-vast-ad-loading");c.once(n,["vast.adStart","vast.adsCancel"],y)}function y(){setTimeout(function(){l.removeClass(n.el(),"vjs-vast-ad-loading")},100)}}function y(){n.trigger("vast.adsCancel");h=true}function m(t){u.waterfall([A,k],t)}function A(t){f.getVASTResponse(v.adTagUrl?v.adTagUrl():v.adTagXML,t)}function k(t,e){if(h){return}var i=w(t)?new o(n,v):new s(n);var r=false;c.once(n,["vast.adStart","vast.adsCancel"],function(t){if(t.type==="vast.adStart"){a()}});c.once(n,["vast.adEnd","vast.adsCancel"],u);if(d.isIDevice()){l()}n.vast.vastResponse=t;n.vast.adUnit=i.playAd(t,e);function a(){if(r||n.controlBar.getChild("AdsLabel")){return}n.controlBar.addChild("AdsLabel")}function u(){n.controlBar.removeChild("AdsLabel");r=true}function l(){var t=3;var e=0;var i=0;n.on("timeupdate",a);n.on("ended",r);c.once(n,["vast.adEnd","vast.adsCancel","vast.adError"],s);function r(){if(n.duration()-e>t){n.pause(true);n.play(true);n.currentTime(e)}}function a(){var r=n.currentTime();var a=Math.abs(r-e);if(a>t){i+=1;if(i>=2){n.pause(true)}n.currentTime(e)}else{e=r}}function s(){n.off("timeupdate",a);n.off("ended",r)}}}function _(t,e){n.trigger({type:"vast.adError",error:t});y();if(console&&console.log){console.log("AD ERROR:",t.message,t,e)}}function w(t){var e,n;var i=t.mediaFiles;for(e=0,n=i.length;e0){u=setTimeout(function(){l&&l.abort()},o)}function c(t,e,n){if(!r.isString(t)||r.isEmptyString(t)){throw new a("Invalid url '"+t+"'")}if(!r.isFunction(e)){throw new a("Invalid handler '"+e+"' for the http request")}if(r.isDefined(n)&&!r.isObject(n)){throw new a("Invalid options map '"+n+"'")}}function d(t,e){r.forEach(e,function(e,n){if(r.isDefined(e)){t.setRequestHeader(n,e)}})}function f(){n(-1,null,null,"")}};s.prototype.get=function(t,e,n){this.run("GET",t,i,n);function i(t,n,i,s){if(r(t)){e(null,n,t,i,s)}else{e(new a(s),n,t,i,s)}}function r(t){return 200<=t&&t<300}};function o(){var t=new XMLHttpRequest;if(!("withCredentials"in t)){t=new XDomainRequest}return t}var u=new s(o);e.exports={http:u,HttpRequest:s,HttpRequestError:a,createXhr:o}},{"./urlUtils":44,"./utilityFunctions":45}],43:[function(t,e,n){"use strict";var i=t("./dom");var r=t("./utilityFunctions");var a={};a.getPlayerSnapshot=function s(t){var e=t.el().querySelector(".vjs-tech");var n={ended:t.ended(),src:t.currentSrc(),currentTime:t.currentTime(),type:t.currentType(),playing:!t.paused(),suppressedTracks:i(t)};if(e){n.nativePoster=e.poster;n.style=e.getAttribute("style")}return n;function i(t){var e=t.remoteTextTracks?t.remoteTextTracks():[];if(e&&r.isArray(e.tracks_)){e=e.tracks_}if(!r.isArray(e)){e=[]}var n=[];e.forEach(function(t){n.push({track:t,mode:t.mode});t.mode="disabled"});return n}};a.restorePlayerSnapshot=function o(t,e){var n=t.el().querySelector(".vjs-tech");var i=20;if(e.nativePoster){n.poster=e.nativePoster}if("style"in e){n.setAttribute("style",e.style||"")}if(s(t,e)){t.one("contentloadedmetadata",o);t.one("canplay",u);r();t.src({src:e.src,type:e.type});t.load()}else{o();if(e.playing){t.play()}}function r(){var e=setTimeout(function(){t.trigger("canplay")},1e3);t.one("canplay",function(){clearTimeout(e)})}function s(t,e){if(t.src()){return t.src()!==e.src}return t.currentSrc()!==e.src}function o(){var t=e.suppressedTracks;t.forEach(function(t){t.track.mode=t.mode})}function u(){if(!a.isReadyToResume(t)&&i--){setTimeout(u,50)}else{try{if(t.currentTime()!==e.currentTime){if(e.playing){t.one("seeked",function(){t.play()})}t.currentTime(e.currentTime)}else if(e.playing){t.play()}}catch(n){videojs.log.warn("Failed to resume the content after an advertisement",n)}}}};a.isReadyToResume=function(t){if(t.readyState()>1){return true}if(t.seekable()===undefined){return true}if(t.seekable().length>0){return true}return false};a.prepareForAds=function(t){var e=t.addChild("blackPoster");var n=true;var a;s();t.on("play",u);t.on("vast.reset",l);t.on("vast.firstPlay",f);t.on("error",p);t.on("vast.adStart",p);t.on("vast.adsCancel",p);t.on("vast.adError",p);t.on("vast.adStart",v);t.on("vast.adEnd",g);t.on("vast.adsCancel",g);function s(){var e=t.play;t.play=function(n){var i=this;if(c()){s()}else{u(n)}return this;function s(){if(!r.isIPhone()){a=d();t.muted(true)}e.apply(i,arguments)}function u(n){if(o()&&!n){t.vast.adUnit.resumeAd()}else{e.apply(i,arguments)}}};var n=t.pause;t.pause=function(e){if(o()&&!e){t.vast.adUnit.pauseAd()}else{n.apply(this,arguments)}return this};var i=t.paused;t.paused=function(e){if(o()&&!e){return t.vast.adUnit.isPaused()}return i.apply(this,arguments)}}function o(){return t.vast&&t.vast.adUnit}function u(){if(c()){n=false;t.trigger("vast.firstPlay")}}function l(){n=true;e.show();f()}function c(){return n}function d(){return{muted:t.muted(),volume:t.volume()}}function f(){if(a){t.currentTime(0);h(a);a=null}}function h(e){if(r.isObject(e)){t.volume(e.volume);t.muted(e.muted)}}function p(){if(!i.hasClass(e.el(),"vjs-hidden")){e.hide()}}function v(){i.addClass(t.el(),"vjs-ad-playing")}function g(){i.removeClass(t.el(),"vjs-ad-playing")}};a.removeNativePoster=function(t){var e=t.el().querySelector(".vjs-tech");if(e){e.removeAttribute("poster")}};a.once=function u(t,e,n){function i(){n.apply(null,arguments);e.forEach(function(e){t.off(e,i)})}e.forEach(function(e){t.on(e,i)})};e.exports=a},{"./dom":41,"./utilityFunctions":45}],44:[function(t,e,n){"use strict";var i=t("./utilityFunctions");var r=document.createElement("a");var a=document.documentMode;function s(t){var e=t;if(a){r.setAttribute("href",e);e=r.href}r.setAttribute("href",e);return{href:r.href,protocol:r.protocol?r.protocol.replace(/:$/,""):"",host:r.host,search:r.search?r.search.replace(/^\?/,""):"",hash:r.hash?r.hash.replace(/^#/,""):"",hostname:r.hostname,port:i.isNotEmptyString(r.port)?r.port:80,pathname:r.pathname.charAt(0)==="/"?r.pathname:"/"+r.pathname}}function o(t,e){var n,r;e=i.isFunction(e)?e:function(){return true};t=t.trim().replace(/^\?/,""); -n=t.split("&");r={};i.forEach(n,function(t){var n,i,a;if(t!==""){n=t.split("=");i=n[0];a=n[1];if(e(i,a)){r[i]=a}}});return r}function u(t){var e=[];i.forEach(t,function(t,n){e.push(n+"="+t)});return e.join("&")}e.exports={urlParts:s,queryStringToObj:o,objToQueryString:u}},{"./utilityFunctions":45}],45:[function(t,e,n){"use strict";var i=1;var r=/[A-Z]/g;var a=/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/i;var s=/^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;function o(){}function u(t){return t===null}function l(t){return t!==undefined}function c(t){return t===undefined}function d(t){return typeof t==="object"}function f(t){return typeof t==="function"}function h(t){return typeof t==="number"}function p(t){return j.isObject(t)&&t.window===t}function v(t){return Object.prototype.toString.call(t)==="[object Array]"}function g(t){if(t===null||j.isWindow(t)||j.isFunction(t)||j.isUndefined(t)){return false}var e=t.length;if(t.nodeType===i&&e){return true}return j.isString(t)||j.isArray(t)||e===0||typeof e==="number"&&e>0&&e-1 in t}function y(t){return typeof t==="string"}function m(t){return j.isString(t)&&t.length===0}function A(t){return j.isString(t)&&t.length!==0}function k(t){return Array.prototype.slice.call(t)}function _(t,e,n){var i,r;if(t){if(f(t)){for(i in t){if(i!=="prototype"&&i!=="length"&&i!=="name"&&(!t.hasOwnProperty||t.hasOwnProperty(i))){e.call(n,t[i],i,t)}}}else if(v(t)){var a=typeof t!=="object";for(i=0,r=t.length;i=e){n=i;t.apply(this,arguments)}}}function F(t,e){var n;return function(){if(n){clearTimeout(n)}n=setTimeout(function(){t.apply(this,arguments);n=undefined},e)}}function L(t,e,n){var i=e(t);for(var r=0;r0}return t.getElementsByTagNameNS(i,"parsererror").length>0}catch(r){}}};r.parseText=function s(t){if(/^\s*$/.test(t)){return null}if(/^(?:true|false)$/i.test(t)){return t.toLowerCase()==="true"}if(isFinite(t)){return parseFloat(t)}if(i.isISO8601(t)){return new Date(t)}return t.trim()};r.JXONTree=function o(t){var e=r.parseText;if(t.documentElement){return new r.JXONTree(t.documentElement)}if(t.hasChildNodes()){var n="";for(var a,s,o,u=0;u0:t.hasAttributes();if(l){var c;for(var d=0;d/g,">").replace(/"/g,""").replace(/'/g,"'")};r.decode=function f(t){return t.replace(/'/g,"'").replace(/"/g,'"').replace(/>/g,">").replace(/</g,"<").replace(/&/g,"&")};e.exports=r},{"./utilityFunctions":45}],47:[function(t,e,n){"use strict";t("./plugin/components/ads-label_5");t("./plugin/components/black-poster_5");var i=t("./plugin/videojs.vast.vpaid");videojs.plugin("vastClient",i)},{"./plugin/components/ads-label_5":36,"./plugin/components/black-poster_5":38,"./plugin/videojs.vast.vpaid":39}]},{},[47]); +(function t(e,n,i){function r(s,o){if(!n[s]){if(!e[s]){var u=typeof require=="function"&&require;if(!o&&u)return u(s,!0);if(a)return a(s,!0);var l=new Error("Cannot find module '"+s+"'");throw l.code="MODULE_NOT_FOUND",l}var c=n[s]={exports:{}};e[s][0].call(c.exports,function(t){var n=e[s][1][t];return r(n?n:t)},c,c.exports,t,e,n,i)}return n[s].exports}var a=typeof require=="function"&&require;for(var s=0;s0){i(e)}},0)}})}},{key:"_callCallback",value:function k(t,e,n,i){var r=this._callbacks.get(e);if(!r){if(n&&e===""){this.trigger(f,n)}return}p.call(this,e,n,i)}},{key:"_handShake",value:function _(t,e){this._ready=true;if(this._handShakeHandler){this._handShakeHandler(t,e);delete this._handShakeHandler}}},{key:"getSize",value:function E(){return{width:this._width,height:this._height}}},{key:"setSize",value:function T(t,e){this._width=s(t,this._width);this._height=s(e,this._height);this._el.setAttribute("width",this._width);this._el.setAttribute("height",this._height)}},{key:"getWidth",value:function b(){return this._width}},{key:"setWidth",value:function w(t){this.setSize(t,this._height)}},{key:"getHeight",value:function S(){return this._height}},{key:"setHeight",value:function V(t){this.setSize(this._width,t)}},{key:"getFlashID",value:function C(){return this._flashID}},{key:"getFlashURL",value:function I(){return this._flashURL}},{key:"isReady",value:function L(){return this._ready}},{key:"destroy",value:function F(){this.offAll();this.removeAllCallbacks();c.removeInstanceByID(this._flashID);if(this._el.parentElement){this._el.parentElement.removeChild(this._el)}}}]);return t}();function p(t,e,n){var i=this;setTimeout(function(){var r=i._callbacks.get(t);if(r){i._callbacks.remove(t);r(e,n)}},0)}Object.defineProperty(h,"VPAID_FLASH_HANDLER",{writable:false,configurable:false,value:d});window[d]=function(t,e,n,i,r,a){var s=c.getInstanceByID(t);if(!s)return;if(n==="handShake"){s._handShake(r,a)}else{if(e!=="event"){s._callCallback(n,i,r,a)}else{s._trigger(n,a)}}}},{"./jsFlashBridgeRegistry":5,"./registry":6,"./utils":7}],5:[function(t,e,n){"use strict";var i=t("./registry").SingleValueRegistry;var r=new i;var a={};Object.defineProperty(a,"addInstance",{writable:false,configurable:false,value:function s(t,e){r.add(t,e)}});Object.defineProperty(a,"getInstanceByID",{writable:false,configurable:false,value:function o(t){return r.get(t)}});Object.defineProperty(a,"removeInstanceByID",{writable:false,configurable:false,value:function u(t){return r.remove(t)}});e.exports=a},{"./registry":6}],6:[function(t,e,n){"use strict";var i=function(){function t(t,e){for(var n=0;n0?t:e}var u=function(){if(String.prototype.endsWith)return String.prototype.endsWith;return function t(e,n){var i=this.toString();if(n===undefined||n>i.length){n=i.length}n-=e.length;var r=i.indexOf(e,n);return r!==-1&&r===n}}();function l(t,e){return u.call(t,e)}},{}],8:[function(t,e,n){"use strict";var i=["handshakeVersion","initAd","startAd","stopAd","skipAd","resizeAd","pauseAd","resumeAd","expandAd","collapseAd","subscribe","unsubscribe"];var r=["AdLoaded","AdStarted","AdStopped","AdSkipped","AdSkippableStateChange","AdSizeChange","AdLinearChange","AdDurationChange","AdExpandedChange","AdRemainingTimeChange","AdVolumeChange","AdImpression","AdVideoStart","AdVideoFirstQuartile","AdVideoMidpoint","AdVideoThirdQuartile","AdVideoComplete","AdClickThru","AdInteraction","AdUserAcceptInvitation","AdUserMinimize","AdUserClose","AdPaused","AdPlaying","AdLog","AdError"];var a=["getAdLinear","getAdWidth","getAdHeight","getAdExpanded","getAdSkippableState","getAdRemainingTime","getAdDuration","getAdVolume","getAdCompanions","getAdIcons"];var s=["setAdVolume"];function o(t,e,n){}o.prototype.handshakeVersion=function(t,e){};o.prototype.initAd=function(t,e,n,i,r,a,s){};o.prototype.startAd=function(t){};o.prototype.stopAd=function(t){};o.prototype.skipAd=function(t){};o.prototype.resizeAd=function(t,e,n,i){};o.prototype.pauseAd=function(t){};o.prototype.resumeAd=function(t){};o.prototype.expandAd=function(t){};o.prototype.collapseAd=function(t){};o.prototype.subscribe=function(t,e,n){};o.prototype.unsubscribe=function(t,e){};o.prototype.getAdLinear=function(t){};o.prototype.getAdWidth=function(t){};o.prototype.getAdHeight=function(t){};o.prototype.getAdExpanded=function(t){};o.prototype.getAdSkippableState=function(t){};o.prototype.getAdRemainingTime=function(t){};o.prototype.getAdDuration=function(t){};o.prototype.getAdVolume=function(t){};o.prototype.getAdCompanions=function(t){};o.prototype.getAdIcons=function(t){};o.prototype.setAdVolume=function(t,e){};l(o,"METHODS",i);l(o,"GETTERS",a);l(o,"SETTERS",s);l(o,"EVENTS",r);var u=i.filter(function(t){return["skipAd"].indexOf(t)===-1});l(o,"checkVPAIDInterface",function c(t){var e=u.every(function(e){return typeof t[e]==="function"});return e});e.exports=o;function l(t,e,n){Object.defineProperty(t,e,{writable:false,configurable:false,value:n})}},{}],9:[function(t,e,n){"use strict";var i=t("./IVPAIDAdUnit");var r=t("./subscriber");var a=i.checkVPAIDInterface;var s=t("./utils");var o=i.METHODS;var u="AdError";var l="AdClickThru";var c=i.EVENTS.filter(function(t){return t!=l});function d(t,e,n,i){this._isValid=a(t);if(this._isValid){this._creative=t;this._el=e;this._videoEl=n;this._iframe=i;this._subscribers=new r;f.call(this)}}d.prototype=Object.create(i.prototype);d.prototype.isValidVPAIDAd=function g(){return this._isValid};i.METHODS.forEach(function(t){var e=["subscribe","unsubscribe","initAd"];if(e.indexOf(t)!==-1)return;d.prototype[t]=function(){var e=i.prototype[t].length;var n=Array.prototype.slice.call(arguments);var r=e===n.length?n.pop():undefined;setTimeout(function(){var e,i=null;try{e=this._creative[t].apply(this._creative,n)}catch(a){i=a}v(r,this._subscribers,i,e)}.bind(this),0)}});d.prototype.initAd=function m(t,e,n,i,r,a,o){r=r||{};a=s.extend({slot:this._el,videoSlot:this._videoEl},a||{});setTimeout(function(){var s;try{this._creative.initAd(t,e,n,i,r,a)}catch(u){s=u}v(o,this._subscribers,s)}.bind(this),0)};d.prototype.subscribe=function y(t,e,n){this._subscribers.subscribe(e,t,n)};d.prototype.unsubscribe=function A(t,e){this._subscribers.unsubscribe(e,t)};d.prototype.on=d.prototype.subscribe;d.prototype.off=d.prototype.unsubscribe;i.GETTERS.forEach(function(t){d.prototype[t]=function(e){setTimeout(function(){var n,i=null;try{n=this._creative[t]()}catch(r){i=r}v(e,this._subscribers,i,n)}.bind(this),0)}});d.prototype.setAdVolume=function k(t,e){setTimeout(function(){var n,i=null;try{this._creative.setAdVolume(t);n=this._creative.getAdVolume()}catch(r){i=r}if(!i){i=s.validate(n===t,"failed to apply volume: "+t)}v(e,this._subscribers,i,n)}.bind(this),0)};d.prototype._destroy=function _(){this.stopAd();this._subscribers.unsubscribeAll()};function f(){c.forEach(function(t){this._creative.subscribe(p.bind(this,t),t)}.bind(this));this._creative.subscribe(h.bind(this),l);if(this._videoEl){var t=this._iframe.contentDocument.documentElement;var e=this._videoEl;t.addEventListener("click",function(n){if(n.target===t){e.click()}})}}function h(t,e,n){this._subscribers.triggerSync(l,{url:t,id:e,playerHandles:n})}function p(t){this._subscribers.trigger(t,Array.prototype.slice(arguments,1))}function v(t,e,n,i){if(t){t(n,i)}else if(n){e.trigger(u,n)}}e.exports=d},{"./IVPAIDAdUnit":8,"./subscriber":11,"./utils":12}],10:[function(t,e,n){"use strict";var i=t("./utils");var r=i.unique("vpaidIframe");var a=t("./VPAIDAdUnit");var s='';s+='
';var o="AdStopped";function u(t,e,n,a){n=n||{};this._id=r();this._destroyed=false;this._frameContainer=i.createElementInEl(t,"div");this._videoEl=e;this._vpaidOptions=a||{timeout:1e4};this._templateConfig={template:n.template||s,extraOptions:n.extraOptions||{}}}u.prototype.destroy=function g(){if(this._destroyed){return}this._destroyed=true;d.call(this)};u.prototype.isDestroyed=function m(){return this._destroyed};u.prototype.loadAdUnit=function y(t,e){v.call(this);d.call(this);var n=i.createIframeWithContent(this._frameContainer,this._templateConfig.template,i.extend({iframeURL_JS:t,iframeID:this.getID()},this._templateConfig.extraOptions));this._frame=n;this._onLoad=i.callbackTimeout(this._vpaidOptions.timeout,r.bind(this),s.bind(this));window.addEventListener("message",this._onLoad);function r(t){if(t.origin!==window.location.origin)return;var n=JSON.parse(t.data);if(n.id!==this.getID())return;var r,s,u;if(!this._frame.contentWindow){s="the iframe is not anymore in the DOM tree"}else{u=this._frame.contentWindow.getVPAIDAd;s=i.validate(typeof u==="function","the ad didn't return a function to create an ad")}if(!s){var l=this._frame.contentWindow.document.querySelector(".ad-element");r=new a(u(),l,this._videoEl,this._frame);r.subscribe(o,c.bind(this));s=i.validate(r.isValidVPAIDAd(),"the add is not fully complaint with VPAID specification")}this._adUnit=r;h.call(this);e(s,s?null:r);return true}function s(){e("timeout",null)}};u.prototype.unloadAdUnit=function A(){d.call(this)};u.prototype.getID=function(){return this._id};function l(t){var e=this[t];if(e){e.remove();delete this[t]}}function c(){f.call(this);delete this._adUnit}function d(){f.call(this);p.call(this)}function f(){l.call(this,"_frame");h.call(this)}function h(){if(this._onLoad){window.removeEventListener("message",this._onLoad);i.clearCallbackTimeout(this._onLoad);delete this._onLoad}}function p(){if(this._adUnit){this._adUnit.stopAd();delete this._adUnit}}function v(){if(this._destroyed){throw new Error("VPAIDHTML5Client already destroyed!")}}e.exports=u;window.VPAIDHTML5Client=u},{"./VPAIDAdUnit":9,"./utils":12}],11:[function(t,e,n){"use strict";function i(){this._subscribers={}}i.prototype.subscribe=function r(t,e,n){this.get(e).push({handler:t,context:n})};i.prototype.unsubscribe=function a(t,e){this._subscribers[e]=this.get(e).filter(function(e){return t===e.handler})};i.prototype.unsubscribeAll=function s(){this._subscribers={}};i.prototype.trigger=function(t,e){var n=this;n.get(t).forEach(function(i){setTimeout(function(){if(n.get(t)){i.handler.call(i.context,e)}},0)})};i.prototype.triggerSync=function(t,e){this.get(t).forEach(function(t){t.handler.call(t.context,e)})};i.prototype.get=function o(t){if(!this._subscribers[t]){this._subscribers[t]=[]}return this._subscribers[t]};e.exports=i},{}],12:[function(t,e,n){"use strict";function i(){}function r(t,e){return t?null:new Error(e)}var a={};function s(t){var e=a[t];if(e){clearTimeout(e);delete a[t]}}function o(t,e,n){var r,o;o=setTimeout(function(){e=i;delete o[r];n()},t);r=function(){if(e.apply(this,arguments)){s(r)}};a[r]=o;return r}function u(t,e,n){var i=document.createElement(e);if(n)i.id=n;t.appendChild(i);return i}function l(t,e,n){var i=c(t);if(!f(i,d(e,n)))return;return i}function c(t,e){var n=document.createElement("iframe");n.src=e||"about:blank";n.marginWidth="0";n.marginHeight="0";n.frameBorder="0";n.width="100%";n.height="100%";n.style.position="absolute";n.style.left="0";n.style.top="0";n.style.margin="0px";n.style.padding="0px";n.style.border="none";n.setAttribute("SCROLLING","NO");t.innerHTML="";t.appendChild(n);return n}function d(t,e){Object.keys(e).forEach(function(n){var i=typeof i==="object"?JSON.stringify(e[n]):e[n];t=t.replace(new RegExp("{{"+n+"}}","g"),i)});return t}function f(t,e){var n=t.contentWindow&&t.contentWindow.document;if(!n)return false;n.write(e);return true}function h(t,e){Object.keys(e).forEach(function(n){t[n]=e[n]});return t}function p(t){var e=-1;return function(){return t+"_"+ ++e}}e.exports={noop:i,validate:r,clearCallbackTimeout:s,callbackTimeout:o,createElementInEl:u,createIframeWithContent:l,createIframe:c,simpleTemplate:d,setIframeContent:f,extend:h,unique:p}},{}],13:[function(t,e,n){"use strict";var i=t("./InLine");var r=t("./Wrapper");function a(t){if(!(this instanceof a)){return new a(t)}this.initialize(t)}a.prototype.initialize=function(t){this.id=t.attr("id");this.sequence=t.attr("sequence");if(t.inLine){this.inLine=new i(t.inLine)}if(t.wrapper){this.wrapper=new r(t.wrapper)}};e.exports=a},{"./InLine":16,"./Wrapper":26}],14:[function(t,e,n){"use strict";var i=t("./TrackingEvent");var r=t("../../utils/utilityFunctions");var a=t("../../utils/xml");function s(t){if(!(this instanceof s)){return new s(t)}this.creativeType=a.attr(t.staticResource,"creativeType");this.staticResource=a.keyValue(t.staticResource);var e=null;if(a.keyValue(t.HTMLResource)){e=a.keyValue(t.HTMLResource)}else if(a.keyValue(t.hTMLResource)){e=a.keyValue(t.hTMLResource)}this.htmlResource=e;var n=null;if(a.keyValue(t.IFrameResource)){n=a.keyValue(t.IFrameResource)}else if(a.keyValue(t.iFrameresource)){n=a.keyValue(t.iFrameresource)}this.iframeResource=n;this.id=a.attr(t,"id");this.width=a.attr(t,"width");this.height=a.attr(t,"height");this.expandedWidth=a.attr(t,"expandedWidth");this.expandedHeight=a.attr(t,"expandedHeight");this.scalable=a.attr(t,"scalable");this.maintainAspectRatio=a.attr(t,"maintainAspectRatio");this.minSuggestedDuration=a.attr(t,"minSuggestedDuration");this.apiFramework=a.attr(t,"apiFramework");this.companionClickThrough=a.keyValue(t.companionClickThrough);this.trackingEvents=o(t.trackingEvents&&t.trackingEvents.tracking);function o(t){var e=[];if(r.isDefined(t)){t=r.isArray(t)?t:[t];t.forEach(function(t){e.push(new i(t))})}return e}}e.exports=s},{"../../utils/utilityFunctions":43,"../../utils/xml":44,"./TrackingEvent":19}],15:[function(t,e,n){"use strict";var i=t("./Linear");var r=t("./Companion");var a=t("../../utils/utilityFunctions");function s(t){if(!(this instanceof s)){return new s(t)}this.id=t.attr("id");this.sequence=t.attr("sequence");this.adId=t.attr("adId");this.apiFramework=t.attr("apiFramework");if(t.linear){this.linear=new i(t.linear)}if(t.companionAds){var e=[];var n=t.companionAds&&t.companionAds.companion;n=a.isArray(n)?n:[n];n.forEach(function(t){e.push(new r(t))});this.companionAds=e}}e.exports=s},{"../../utils/utilityFunctions":43,"./Companion":14,"./Linear":17}],16:[function(t,e,n){"use strict";var i=t("./vastUtil");var r=t("../../utils/utilityFunctions");var a=t("../../utils/xml");function s(t){if(!(this instanceof s)){return new s(t)}this.adTitle=a.keyValue(t.adTitle);this.adSystem=a.keyValue(t.adSystem);this.impressions=i.parseImpressions(t.impression);this.creatives=i.parseCreatives(t.creatives);this.description=a.keyValue(t.description);this.advertiser=a.keyValue(t.advertiser);this.surveys=e(t.survey);this.error=a.keyValue(t.error);this.pricing=a.keyValue(t.pricing);this.extensions=t.extensions;function e(t){if(t){return r.transformArray(r.isArray(t)?t:[t],function(t){if(r.isNotEmptyString(t.keyValue)){return{uri:t.keyValue,type:t.attr("type")}}return undefined})}return[]}}e.exports=s},{"../../utils/utilityFunctions":43,"../../utils/xml":44,"./vastUtil":28}],17:[function(t,e,n){"use strict";var i=t("./TrackingEvent");var r=t("./MediaFile");var a=t("./VideoClicks");var s=t("../../utils/utilityFunctions");var o=t("./parsers");var u=t("../../utils/xml");function l(t){if(!(this instanceof l)){return new l(t)}this.duration=o.duration(u.keyValue(t.duration));this.mediaFiles=n(t.mediaFiles&&t.mediaFiles.mediaFile);this.trackingEvents=e(t.trackingEvents&&t.trackingEvents.tracking,this.duration);this.skipoffset=o.offset(u.attr(t,"skipoffset"),this.duration); +if(t.videoClicks){this.videoClicks=new a(t.videoClicks)}if(t.adParameters){this.adParameters=u.keyValue(t.adParameters);if(u.attr(t.adParameters,"xmlEncoded")){this.adParameters=u.decode(this.adParameters)}}function e(t,e){var n=[];if(s.isDefined(t)){t=s.isArray(t)?t:[t];t.forEach(function(t){n.push(new i(t,e))})}return n}function n(t){var e=[];if(s.isDefined(t)){t=s.isArray(t)?t:[t];t.forEach(function(t){e.push(new r(t))})}return e}}e.exports=l},{"../../utils/utilityFunctions":43,"../../utils/xml":44,"./MediaFile":18,"./TrackingEvent":19,"./VideoClicks":25,"./parsers":27}],18:[function(t,e,n){"use strict";var i=t("../../utils/xml");var r=["delivery","type","width","height","codec","id","bitrate","minBitrate","maxBitrate","scalable","maintainAspectRatio","apiFramework"];function a(t){if(!(this instanceof a)){return new a(t)}this.src=i.keyValue(t);for(var e=0;e0){d(r.shift(),[],a)}else{e(t,i)}}else{e(null,i)}}});function a(t,e){var i=n._requestVASTXml.bind(n,t);o.waterfall([i,s],e)}function s(t,e){var n;try{n=c.toJXONTree(t);if(l.isArray(n.ad)){n.ads=n.ad}else if(n.ad){n.ads=[n.ad]}else{n.ads=[]}e(u(n),n)}catch(i){e(new r("on VASTClient.getVASTAd.buildVastWaterfall, error parsing xml",100),null)}}function u(t){var e=c.attr(t,"version");if(!t.ad){return new r("on VASTClient.getVASTAd.validateVASTTree, no Ad in VAST tree",303)}if(e&&(e!=3&&e!=2)){return new r('on VASTClient.getVASTAd.validateVASTTree, not supported VAST version "'+e+'"',102)}return null}function d(t,e,i){if(e.length>=n.WRAPPER_LIMIT){return i(new r("on VASTClient.getVASTAd.getAd, players wrapper limit reached (the limit is "+n.WRAPPER_LIMIT+")",302),e)}o.waterfall([function(e){if(l.isString(t)){p(t,e)}else{e(null,t)}},f],function(t,n){if(n){e.push(n)}if(t){return i(t,e)}if(n.wrapper){return d(n.wrapper.VASTAdTagURI,e,i)}return i(null,e)})}function f(t,e){try{var n=new i(t);e(h(n),n)}catch(a){e(new r("on VASTClient.getVASTAd.buildAd, error parsing xml",100),null)}}function h(t){var e=t.wrapper;var n=t.inLine;var i="on VASTClient.getVASTAd.validateAd, ";if(n&&e){return new r(i+"InLine and Wrapper both found on the same Ad",101)}if(!n&&!e){return new r(i+"nor wrapper nor inline elements found on the Ad",101)}if(n&&n.creatives.length===0){return new r(i+"missing creative in InLine element",101)}if(e&&!e.VASTAdTagURI){return new r(i+"missing 'VASTAdTagURI' in wrapper",101)}}function p(t,e){n._requestVASTXml(t,function(t,n){if(t){return e(t)}try{var i=c.toJXONTree(n);e(u(i),i.ad)}catch(a){e(new r("on VASTClient.getVASTAd.requestVASTAd, error parsing xml",100))}})}};d.prototype._requestVASTXml=function h(t,e){try{if(l.isFunction(t)){t(i)}else{u.get(t,i,{withCredentials:true})}}catch(n){e(n)}function i(t,n,i){if(t){var a=l.isDefined(i)?"on VASTClient.requestVastXML, HTTP request error with status '"+i+"'":"on VASTClient.requestVastXML, Error getting the the VAST XML with he passed adTagXML fn";return e(new r(a,301),null)}e(null,n)}};d.prototype._buildVASTResponse=function p(t){var e=new a;n(e,t);i(e);return e;function n(t,e){e.forEach(function(e){t.addAd(e)})}function i(t){var e=t.trackingEvents.progress;if(!t.hasLinear()){throw new r("on VASTClient._buildVASTResponse, Received an Ad type that is not supported",200)}if(t.duration===undefined){throw new r("on VASTClient._buildVASTResponse, Missing duration field in VAST response",101)}if(e){e.forEach(function(t){if(!l.isNumber(t.offset)){throw new r("on VASTClient._buildVASTResponse, missing or wrong offset attribute on progress tracking event",101)}})}}};d.prototype._trackError=function(t,e){if(!l.isArray(e)||e.length===0){return}var n=[];e.forEach(i);s.track(n,{ERRORCODE:t.code||900});function i(t){if(t.wrapper&&t.wrapper.error){n.push(t.wrapper.error)}if(t.inLine&&t.inLine.error){n.push(t.inLine.error)}}};e.exports=d},{"../../utils/async":38,"../../utils/http":40,"../../utils/utilityFunctions":43,"../../utils/xml":44,"./Ad":13,"./VASTError":21,"./VASTResponse":23,"./vastUtil":28}],21:[function(t,e,n){"use strict";function i(t,e){this.message="VAST Error: "+(t||"");if(e){this.code=e}}i.prototype=new Error;i.prototype.name="VAST Error";e.exports=i},{}],22:[function(t,e,n){"use strict";var i=t("./VASTResponse");var r=t("./VASTError");var a=t("./VASTTracker");var s=t("./vastUtil");var o=t("../../utils/async");var u=t("../../utils/dom");var l=t("../../utils/playerUtils");var c=t("../../utils/utilityFunctions");function d(t){if(!(this instanceof d)){return new d(t)}this.player=t}d.prototype.playAd=function f(t,e){var n=this;e=e||c.noop;if(!(t instanceof i)){return e(new r("On VASTIntegrator, missing required VASTResponse"))}o.waterfall([function(e){e(null,t)},this._selectAdSource.bind(this),this._createVASTTracker.bind(this),this._addClickThrough.bind(this),this._addSkipButton.bind(this),this._setupEvents.bind(this),this._playSelectedAd.bind(this)],function(t,i){if(t&&i){n._trackError(t,i)}e(t,i)});this._adUnit={_src:null,type:"VAST",pauseAd:function(){n.player.pause(true)},resumeAd:function(){n.player.play(true)},isPaused:function(){return n.player.paused(true)},getSrc:function(){return this._src}};return this._adUnit};d.prototype._selectAdSource=function h(t,e){var n;var i=u.getDimension(this.player.el()).width;t.mediaFiles.sort(function a(t,e){var n=Math.abs(i-t.width);var r=Math.abs(i-e.width);return n-r});n=this.player.selectSource(t.mediaFiles).source;if(n){if(this._adUnit){this._adUnit._src=n}return e(null,n,t)}e(new r("Could not find Ad mediafile supported by this player",403),t)};d.prototype._createVASTTracker=function p(t,e,n){try{n(null,t,new a(t.src,e),e)}catch(i){n(i,e)}};d.prototype._setupEvents=function v(t,e,n,i){var r;var a=this.player;a.on("fullscreenchange",o);a.on("vast.adStart",d);a.on("pause",u);a.on("timeupdate",c);a.on("volumechange",f);l.once(a,["vast.adEnd","vast.adsCancel"],s);l.once(a,["vast.adEnd","vast.adsCancel","vast.adSkip"],function(t){if(t.type==="vast.adEnd"){e.trackComplete()}});return i(null,t,n);function s(){a.off("fullscreenchange",o);a.off("vast.adStart",d);a.off("pause",u);a.off("timeupdate",c);a.off("volumechange",f)}function o(){if(a.isFullscreen()){e.trackFullscreen()}else{e.trackExitFullscreen()}}function u(){if(Math.abs(a.duration()-a.currentTime())<2){return}e.trackPause();l.once(a,["play","vast.adEnd","vast.adsCancel"],function(t){if(t.type==="play"){e.trackResume()}})}function c(){var t=a.currentTime()*1e3;e.trackProgress(t)}function d(){e.trackImpressions();e.trackCreativeView()}function f(){var t=a.muted();if(t){e.trackMute()}else if(r){e.trackUnmute()}r=t}};d.prototype._addSkipButton=function g(t,e,n,i){var r;var a=this;if(c.isNumber(n.skipoffset)){r=n.skipoffset/1e3;s(this.player,r)}i(null,t,e,n);function s(t,e){var n=o(t);var i=d.bind(a,n,e,t);t.el().appendChild(n);t.on("timeupdate",i);l.once(t,["vast.adEnd","vast.adsCancel"],r);function r(){t.off("timeupdate",i);u.remove(n)}}function o(t){var n=window.document.createElement("div");u.addClass(n,"vast-skip-button");n.onclick=function(i){if(u.hasClass(n,"enabled")){e.trackSkip();t.trigger("vast.adSkip")}if(window.Event.prototype.stopPropagation!==undefined){i.stopPropagation()}else{return false}};return n}function d(t,e,n){var i=Math.ceil(e-n.currentTime());if(i>0){t.innerHTML="Skip in "+c.toFixedDigits(i,2)+"..."}else{if(!u.hasClass(t,"enabled")){u.addClass(t,"enabled");t.innerHTML="Skip ad"}}}};d.prototype._addClickThrough=function m(t,e,n,i){var r=this.player;var a=d(r,e,n);var o=f.bind(this,a,n,r);r.el().insertBefore(a,r.controlBar.el());r.on("timeupdate",o);l.once(r,["vast.adEnd","vast.adsCancel"],p);return i(null,t,e,n);function d(t,e,n){var i=window.document.createElement("a");var r=n.clickThrough;u.addClass(i,"vast-blocker");i.href=h(r,t);if(c.isString(r)){i.target="_blank"}i.onclick=function(n){if(t.paused()){t.play();if(window.Event.prototype.stopPropagation!==undefined){n.stopPropagation()}return false}t.pause();e.trackClick()};return i}function f(t,e,n){t.href=h(e.clickThrough,n)}function h(e,n){var i={ASSETURI:t.src,CONTENTPLAYHEAD:s.formatProgress(n.currentTime()*1e3)};return e?s.parseURLMacro(e,i):"#"}function p(){r.off("timeupdate",o);u.remove(a)}};d.prototype._playSelectedAd=function y(t,e,n){var i=this.player;i.preload("auto");i.src(t);l.once(i,["durationchange","error","vast.adsCancel"],function(t){if(t.type==="durationchange"){a()}else if(t.type==="error"){n(new r("on VASTIntegrator, Player is unable to play the Ad",400),e)}});function a(){l.once(i,["playing","vast.adsCancel"],function(t){if(t.type==="vast.adsCancel"){return}i.trigger("vast.adStart");l.once(i,["ended","vast.adsCancel","vast.adSkip"],function(t){if(t.type==="ended"||t.type==="vast.adSkip"){n(null,e)}})});i.play()}};d.prototype._trackError=function A(t,e){s.track(e.errorURLMacros,{ERRORCODE:t.code||900})};e.exports=d},{"../../utils/async":38,"../../utils/dom":39,"../../utils/playerUtils":41,"../../utils/utilityFunctions":43,"./VASTError":21,"./VASTResponse":23,"./VASTTracker":24,"./vastUtil":28}],23:[function(t,e,n){"use strict";var i=t("./Ad");var r=t("./VideoClicks");var a=t("./Linear");var s=t("./InLine");var o=t("./Wrapper");var u=t("../../utils/utilityFunctions");var l=t("../../utils/xml");window.InLine__A=s;function c(){if(!(this instanceof c)){return new c}this._linearAdded=false;this.ads=[];this.errorURLMacros=[];this.impressions=[];this.clickTrackings=[];this.customClicks=[];this.trackingEvents={};this.mediaFiles=[];this.clickThrough=undefined;this.adTitle="";this.duration=undefined;this.skipoffset=undefined}c.prototype.addAd=function(t){var e,n;if(t instanceof i){e=t.inLine;n=t.wrapper;this.ads.push(t);if(e){this._addInLine(e)}if(n){this._addWrapper(n)}}};c.prototype._addErrorTrackUrl=function(t){var e=t instanceof l.JXONTree?l.keyValue(t):t;if(e){this.errorURLMacros.push(e)}};c.prototype._addImpressions=function(t){u.isArray(t)&&d(this.impressions,t)};c.prototype._addClickThrough=function(t){if(u.isNotEmptyString(t)){this.clickThrough=t}};c.prototype._addClickTrackings=function(t){u.isArray(t)&&d(this.clickTrackings,t)};c.prototype._addCustomClicks=function(t){u.isArray(t)&&d(this.customClicks,t)};c.prototype._addTrackingEvents=function(t){var e=this.trackingEvents;if(t){t=u.isArray(t)?t:[t];t.forEach(function(t){if(!e[t.name]){e[t.name]=[]}e[t.name].push(t)})}};c.prototype._addTitle=function(t){if(u.isNotEmptyString(t)){this.adTitle=t}};c.prototype._addDuration=function(t){if(u.isNumber(t)){this.duration=t}};c.prototype._addVideoClicks=function(t){if(t instanceof r){this._addClickThrough(t.clickThrough);this._addClickTrackings(t.clickTrackings);this._addCustomClicks(t.customClicks)}};c.prototype._addMediaFiles=function(t){u.isArray(t)&&d(this.mediaFiles,t)};c.prototype._addSkipoffset=function(t){if(t){this.skipoffset=t}};c.prototype._addAdParameters=function(t){if(t){this.adParameters=t}};c.prototype._addLinear=function(t){if(t instanceof a){this._addDuration(t.duration);this._addTrackingEvents(t.trackingEvents);this._addVideoClicks(t.videoClicks);this._addMediaFiles(t.mediaFiles);this._addSkipoffset(t.skipoffset);this._addAdParameters(t.adParameters);this._linearAdded=true}};c.prototype._addInLine=function(t){var e=this;if(t instanceof s){this._addTitle(t.adTitle);this._addErrorTrackUrl(t.error);this._addImpressions(t.impressions);t.creatives.forEach(function(t){if(t.linear){e._addLinear(t.linear)}})}};c.prototype._addWrapper=function(t){var e=this;if(t instanceof o){this._addErrorTrackUrl(t.error);this._addImpressions(t.impressions);t.creatives.forEach(function(t){var n=t.linear;if(n){e._addVideoClicks(n.videoClicks);e.clickThrough=undefined;e._addTrackingEvents(n.trackingEvents)}})}};c.prototype.hasLinear=function(){return this._linearAdded};function d(t,e){e.forEach(function(e){t.push(e)})}e.exports=c},{"../../utils/utilityFunctions":43,"../../utils/xml":44,"./Ad":13,"./InLine":16,"./Linear":17,"./VideoClicks":25,"./Wrapper":26}],24:[function(t,e,n){"use strict";var i=t("./VASTError");var r=t("./VASTResponse");var a=t("./vastUtil");var s=t("../../utils/utilityFunctions");function o(t,e){if(!(this instanceof o)){return new o(t,e)}this.sanityCheck(t,e);this.initialize(t,e)}o.prototype.initialize=function(t,e){this.response=e;this.assetURI=t;this.progress=0;this.quartiles={firstQuartile:{tracked:false,time:Math.round(25*e.duration)/100},midpoint:{tracked:false,time:Math.round(50*e.duration)/100},thirdQuartile:{tracked:false,time:Math.round(75*e.duration)/100}}};o.prototype.sanityCheck=function(t,e){if(!s.isString(t)||s.isEmptyString(t)){throw new i("on VASTTracker constructor, missing required the URI of the ad asset being played")}if(!(e instanceof r)){throw new i("on VASTTracker constructor, missing required VAST response")}};o.prototype.trackURLs=function u(t,e){if(s.isArray(t)&&t.length>0){e=s.extend({ASSETURI:this.assetURI,CONTENTPLAYHEAD:a.formatProgress(this.progress)},e||{});a.track(t,e)}};o.prototype.trackEvent=function l(t,e){this.trackURLs(n(this.response.trackingEvents[t]));if(e){this.response.trackingEvents[t]=undefined}function n(t){var e;if(t){e=[];t.forEach(function(t){e.push(t.uri)})}return e}};o.prototype.trackProgress=function c(t){var e=this;var n=[];var i=true;var r=false;var a=this.response.trackingEvents;if(s.isNumber(t)){u("start",i,t>0);u("rewind",r,o(this.progress,t));l(t);d(t);f();this.progress=t}function o(e,n){var i=3e3;return e>t&&Math.abs(n-e)>i}function u(t,e,i){if(a[t]&&i){n.push({name:t,trackOnce:!!e})}}function l(t){var n=e.quartiles;var r=e.quartiles.firstQuartile;var a=e.quartiles.midpoint;var s=e.quartiles.thirdQuartile;if(!r.tracked){o("firstQuartile",t)}else if(!a.tracked){o("midpoint",t)}else if(!s.tracked){o("thirdQuartile",t)}function o(t,e){var r=n[t];if(c(r,e)){r.tracked=true;u(t,i,true)}}}function c(t,e){var n=t.time;return e>=n&&e<=n+5e3}function d(t){if(!s.isArray(a.progress)){return}var n=[];a.progress.forEach(function(i){if(i.offset<=t){e.trackURLs([i.uri])}else{n.push(i)}});a.progress=n}function f(){n.forEach(function(t){e.trackEvent(t.name,t.trackOnce)})}};["rewind","fullscreen","exitFullscreen","pause","resume","mute","unmute","acceptInvitation","acceptInvitationLinear","collapse","expand"].forEach(function(t){o.prototype["track"+s.capitalize(t)]=function(){this.trackEvent(t)}});["start","skip","close","closeLinear"].forEach(function(t){o.prototype["track"+s.capitalize(t)]=function(){this.trackEvent(t,true)}});["firstQuartile","midpoint","thirdQuartile"].forEach(function(t){o.prototype["track"+s.capitalize(t)]=function(){this.quartiles[t].tracked=true;this.trackEvent(t,true)}});o.prototype.trackComplete=function(){if(this.quartiles.thirdQuartile.tracked){this.trackEvent("complete",true)}};o.prototype.trackErrorWithCode=function d(t){if(s.isNumber(t)){this.trackURLs(this.response.errorURLMacros,{ERRORCODE:t})}};o.prototype.trackImpressions=function f(){this.trackURLs(this.response.impressions)};o.prototype.trackCreativeView=function h(){this.trackEvent("creativeView")};o.prototype.trackClick=function p(){this.trackURLs(this.response.clickTrackings)};e.exports=o},{"../../utils/utilityFunctions":43,"./VASTError":21,"./VASTResponse":23,"./vastUtil":28}],25:[function(t,e,n){"use strict";var i=t("../../utils/utilityFunctions");var r=t("../../utils/xml");function a(t){if(!(this instanceof a)){return new a(t)}this.clickThrough=r.keyValue(t.clickThrough);this.clickTrackings=e(t.clickTracking);this.customClicks=e(t.customClick);function e(t){var e=[];if(t){t=i.isArray(t)?t:[t];t.forEach(function(t){e.push(r.keyValue(t))})}return e}}e.exports=a},{"../../utils/utilityFunctions":43,"../../utils/xml":44}],26:[function(t,e,n){"use strict";var i=t("./vastUtil");var r=t("../../utils/utilityFunctions");var a=t("../../utils/xml");function s(t){if(!(this instanceof s)){return new s(t)}this.adSystem=a.keyValue(t.adSystem);this.impressions=i.parseImpressions(t.impression);this.VASTAdTagURI=a.keyValue(t.vASTAdTagURI);this.creatives=i.parseCreatives(t.creatives);this.error=a.keyValue(t.error);this.extensions=t.extensions;this.followAdditionalWrappers=r.isDefined(a.attr(t,"followAdditionalWrappers"))?a.attr(t,"followAdditionalWrappers"):true;this.allowMultipleAds=a.attr(t,"allowMultipleAds");this.fallbackOnNoAd=a.attr(t,"fallbackOnNoAd")}e.exports=s},{"../../utils/utilityFunctions":43,"../../utils/xml":44,"./vastUtil":28}],27:[function(t,e,n){"use strict";var i=t("../../utils/utilityFunctions");var r=/(\d\d):(\d\d):(\d\d)(\.(\d\d\d))?/;var a={duration:function s(t){var e,n;if(i.isString(t)){e=t.match(r);if(e){n=a(e[1])+s(e[2])+o(e[3])+parseInt(e[5]||0)}}return isNaN(n)?null:n;function a(t){return parseInt(t,10)*60*60*1e3}function s(t){return parseInt(t,10)*60*1e3}function o(t){return parseInt(t,10)*1e3}},offset:function o(t,e){if(n(t)){return i(t,e)}return a.duration(t);function n(t){var e=/^\d+(\.\d+)?%$/g;return e.test(t)}function i(t,e){if(e){return r(e,parseFloat(t.replace("%","")))}return null}function r(t,e){return t*e/100}}};e.exports=a},{"../../utils/utilityFunctions":43}],28:[function(t,e,n){"use strict";var i=t("./Creative");var r=t("../../utils/utilityFunctions");var a={track:function s(t,e){var n=a.parseURLMacros(t,e);var i=[];n.forEach(function(t){var e=new Image;e.src=t;i.push(e)});return i},parseURLMacros:function o(t,e){var n=[];e=e||{};if(!e["CACHEBUSTING"]){e["CACHEBUSTING"]=Math.round(Math.random()*1e10)}t.forEach(function(t){n.push(a._parseURLMacro(t,e))});return n},parseURLMacro:function u(t,e){e=e||{};if(!e["CACHEBUSTING"]){e["CACHEBUSTING"]=Math.round(Math.random()*1e10)}return a._parseURLMacro(t,e)},_parseURLMacro:function l(t,e){e=e||{};r.forEach(e,function(e,n){t=t.replace(new RegExp("\\["+n+"\\]","gm"),e)});return t},parseDuration:function c(t){var e=/(\d\d):(\d\d):(\d\d)(\.(\d\d\d))?/;var n,i;if(r.isString(t)){n=t.match(e);if(n){i=a(n[1])+s(n[2])+o(n[3])+parseInt(n[5]||0)}}return isNaN(i)?null:i;function a(t){return parseInt(t,10)*60*60*1e3}function s(t){return parseInt(t,10)*60*1e3}function o(t){return parseInt(t,10)*1e3}},parseImpressions:function d(t){if(t){t=r.isArray(t)?t:[t];return r.transformArray(t,function(t){if(r.isNotEmptyString(t.keyValue)){return t.keyValue}return undefined})}return[]},parseCreatives:function f(t){var e=[];var n;if(r.isDefined(t)&&r.isDefined(t.creative)){n=r.isArray(t.creative)?t.creative:[t.creative];n.forEach(function(t){e.push(new i(t))})}return e},formatProgress:function h(t){var e,n,i,a;e=t/(60*60*1e3);e=Math.floor(e);n=t/(60*1e3)%60;n=Math.floor(n);i=t/1e3%60;i=Math.floor(i);a=t%1e3;return r.toFixedDigits(e,2)+":"+r.toFixedDigits(n,2)+":"+r.toFixedDigits(i,2)+"."+r.toFixedDigits(a,3)},parseOffset:function p(t,e){if(n(t)){return i(t,e)}return a.parseDuration(t);function n(t){var e=/^\d+(\.\d+)?%$/g;return e.test(t)}function i(t,e){if(e){return r(e,parseFloat(t.replace("%","")))}return null}function r(t,e){return t*e/100}},isVPAID:function v(t){return!!t&&t.apiFramework==="VPAID"}};e.exports=a},{"../../utils/utilityFunctions":43,"./Creative":15}],29:[function(t,e,n){"use strict";var i=t("../vast/VASTError");var r=t("../../utils/utilityFunctions");function a(t,e){if(!(this instanceof a)){return new a(t,e)}n(t,e);this.options=r.extend({},e);this._adUnit=t;function n(t,e){if(!t||!a.checkVPAIDInterface(t)){throw new i("on VPAIDAdUnitWrapper, the passed VPAID adUnit does not fully implement the VPAID interface")}if(!r.isObject(e)){throw new i("on VPAIDAdUnitWrapper, expected options hash but got '"+e+"'")}if(!("responseTimeout"in e)||!r.isNumber(e.responseTimeout)){throw new i("on VPAIDAdUnitWrapper, expected responseTimeout in options")}}}a.checkVPAIDInterface=function s(t){var e=["handshakeVersion","initAd","startAd","stopAd","resizeAd","pauseAd","expandAd","collapseAd"];for(var n=0,i=e.length;n=1&&e<=2}function a(t){var e=t.split(".");return parseInt(e[0],10)}};p.prototype._initAd=function(t,e,n){var i=this.player.el().querySelector(".vjs-tech");var r=d.getDimension(i);t.initAd(r.width,r.height,this.VIEW_MODE.NORMAL,-1,{AdParameters:e.adParameters||""},function(i){n(i,t,e)})};p.prototype._createVASTTracker=function(t,e){return new a(t,e)};p.prototype._setupEvents=function(t,e,n){var i=t.options.src;var r=this._createVASTTracker(i,e);var a=this.player;var o=this;t.on("AdSkipped",function(){a.trigger("vpaid.AdSkipped");r.trackSkip()});t.on("AdImpression",function(){a.trigger("vpaid.AdImpression");r.trackImpressions()});t.on("AdStarted",function(){a.trigger("vpaid.AdStarted");r.trackCreativeView();u()});t.on("AdVideoStart",function(){a.trigger("vpaid.AdVideoStart");r.trackStart();u()});t.on("AdPlaying",function(){a.trigger("vpaid.AdPlaying");r.trackResume();u()});t.on("AdPaused",function(){a.trigger("vpaid.AdPaused");r.trackPause();l()});function u(){if(o._adUnit&&o._adUnit.isPaused()){o._adUnit._paused=false}a.trigger("play")}function l(){if(o._adUnit){o._adUnit._paused=true}a.trigger("pause")}t.on("AdVideoFirstQuartile",function(){a.trigger("vpaid.AdVideoFirstQuartile");r.trackFirstQuartile()});t.on("AdVideoMidpoint",function(){a.trigger("vpaid.AdVideoMidpoint");r.trackMidpoint()});t.on("AdVideoThirdQuartile",function(){a.trigger("vpaid.AdVideoThirdQuartile");r.trackThirdQuartile()});t.on("AdVideoComplete",function(){a.trigger("vpaid.AdVideoComplete");r.trackComplete()});t.on("AdClickThru",function(n){a.trigger("vpaid.AdClickThru");var i=n.url; +var o=n.playerHandles;var u=h.isNotEmptyString(i)?i:l(e.clickThrough);r.trackClick();if(o&&u){window.open(u,"_blank")}function l(e){var n={ASSETURI:t.options.src,CONTENTPLAYHEAD:0};return e?s.parseURLMacro(e,n):null}});t.on("AdUserAcceptInvitation",function(){a.trigger("vpaid.AdUserAcceptInvitation");r.trackAcceptInvitation();r.trackAcceptInvitationLinear()});t.on("AdUserClose",function(){a.trigger("vpaid.AdUserClose");r.trackClose();r.trackCloseLinear()});t.on("AdUserMinimize",function(){a.trigger("vpaid.AdUserMinimize");r.trackCollapse()});t.on("AdError",function(){a.trigger("vpaid.AdError");r.trackErrorWithCode(901)});t.on("AdVolumeChange",function(){a.trigger("vpaid.AdVolumeChange");var e=a.volume();t.getAdVolume(function(t,n){if(n===0&&e>0){r.trackMute()}if(n>0&&e===0){r.trackUnmute()}a.volume(n)})});var c=v.bind(this,a,t,this.VIEW_MODE);var f=h.throttle(c,100);var p=this.settings.autoResize;if(p){d.addEventListener(window,"resize",f);d.addEventListener(window,"orientationchange",f)}a.on("vast.resize",c);a.on("vpaid.pauseAd",g);a.on("vpaid.resumeAd",m);a.one("vpaid.adEnd",function(){a.off("vast.resize",c);a.off("vpaid.pauseAd",g);a.off("vpaid.resumeAd",m);if(p){d.removeEventListener(window,"resize",f);d.removeEventListener(window,"orientationchange",f)}});n(null,t,e);function g(){t.pauseAd(h.noop)}function m(){t.resumeAd(h.noop)}};p.prototype._addSkipButton=function(t,e,n){var i;var r=this.player;t.on("AdSkippableStateChange",a);f.once(r,["vast.adEnd","vast.adsCancel"],o);n(null,t,e);function a(){r.trigger("vpaid.AdSkippableStateChange");t.getAdSkippableState(function(t,e){if(e){if(!i){s(r)}}else{o(r)}})}function s(t){i=u(t);t.el().appendChild(i)}function o(){d.remove(i);i=null}function u(){var e=window.document.createElement("div");d.addClass(e,"vast-skip-button");d.addClass(e,"enabled");e.innerHTML="Skip ad";e.onclick=function(e){t.skipAd(h.noop);if(window.Event.prototype.stopPropagation!==undefined){e.stopPropagation()}else{return false}};return e}};p.prototype._linkPlayerControls=function(t,e,n){var i=this;r(this.player,t);a(this.player,t,this.VIEW_MODE);n(null,t,e);function r(t,e){t.on("volumechange",n);e.on("AdVolumeChange",i);t.one("vpaid.adEnd",function(){t.off("volumechange",n)});function n(){var n=t.muted()?0:t.volume();e.setAdVolume(n,g)}function i(){t.trigger("vpaid.AdVolumeChange");e.getAdVolume(function(e,n){if(e){g(e)}else{t.volume(n)}})}}function a(t,e,n){var r=v.bind(i,t,e,n);t.on("fullscreenchange",r);t.one("vpaid.adEnd",function(){t.off("fullscreenchange",r)})}};p.prototype._startAd=function(t,e,n){var i=this.player;t.startAd(function(r){if(!r){i.trigger("vast.adStart")}n(r,t,e)})};p.prototype._finishPlaying=function(t,e,n){var r=this.player;t.on("AdStopped",function(){r.trigger("vpaid.AdStopped");a(null)});t.on("AdError",function(t){var e=t?t.message:"on VPAIDIntegrator, error while waiting for the adUnit to finish playing";a(new i(e))});function a(i){n(i,t,e)}};p.prototype._trackError=function A(t){s.track(t.errorURLMacros,{ERRORCODE:901})};function v(t,e,n){var i=t.el().querySelector(".vjs-tech");var r=d.getDimension(i);var a=t.isFullscreen()?n.FULLSCREEN:n.NORMAL;e.resizeAd(r.width,r.height,a,g)}function g(t){if(t&&console&&console.log){console.log("ERROR: "+t.message,t)}}e.exports=p},{"../../utils/async":38,"../../utils/dom":39,"../../utils/playerUtils":41,"../../utils/utilityFunctions":43,"../vast/VASTError":21,"../vast/VASTResponse":23,"../vast/VASTTracker":24,"../vast/vastUtil":28,"./VPAIDAdUnitWrapper":29,"./VPAIDFlashTech":30,"./VPAIDHTML5Tech":31}],33:[function(t,e,n){"use strict";var i=t("../../utils/dom");var r=document.createElement("div");r.className="vjs-ads-label vjs-control vjs-label-hidden";r.innerHTML="Advertisement";var a=function(t){return{init:function e(n,a){a.el=r;t.call(this,n,a);setTimeout(function(){var t=n.controlBar&&(n.controlBar.getChild("timerControls")||n.controlBar.getChild("currentTimeDisplay"));if(t){n.controlBar.el().insertBefore(r,t.el())}i.removeClass(r,"vjs-label-hidden")},0)},el:function n(){return r}}};e.exports=a},{"../../utils/dom":39}],34:[function(t,e,n){"use strict";var i=videojs.getComponent("Component");var r=t("./ads-label")(i);videojs.registerComponent("AdsLabel",videojs.extend(i,r))},{"./ads-label":33}],35:[function(t,e,n){"use strict";var i=document.createElement("div");var r=function(t){return{init:function e(n,r){r.el=i;i.className="vjs-black-poster";t.call(this,n,r);var a=n.getChild("posterImage");setTimeout(function(){if(a&&n&&n.el()){n.el().insertBefore(i,a.el())}},0)},el:function n(){return i}}};e.exports=r},{}],36:[function(t,e,n){"use strict";var i=videojs.getComponent("Component");var r=t("./black-poster")(i);videojs.registerComponent("BlackPoster",videojs.extend(i,r))},{"./black-poster":35}],37:[function(t,e,n){"use strict";var i=t("../ads/vast/VASTClient");var r=t("../ads/vast/VASTError");var a=t("../ads/vast/vastUtil");var s=t("../ads/vast/VASTIntegrator");var o=t("../ads/vpaid/VPAIDIntegrator");var u=t("../utils/async");var l=t("../utils/dom");var c=t("../utils/playerUtils");var d=t("../utils/utilityFunctions");e.exports=function f(t){var e;var n=this;var f=new i;var h=false;var p={timeout:500,iosPrerollCancelTimeout:2e3,adCancelTimeout:3e3,playAdAlways:false,adsEnabled:true,autoResize:true,vpaidFlashLoaderPath:"/VPAIDFlash.swf"};var v=d.extend({},p,t||{});if(d.isUndefined(v.adTagUrl)&&d.isDefined(v.url)){v.adTagUrl=v.url}if(d.isString(v.adTagUrl)){v.adTagUrl=d.echoFn(v.adTagUrl)}if(d.isDefined(v.adTagXML)&&!d.isFunction(v.adTagXML)){return _(new r("on VideoJS VAST plugin, the passed adTagXML option does not contain a function"))}if(!d.isDefined(v.adTagUrl)&&!d.isFunction(v.adTagXML)){return _(new r("on VideoJS VAST plugin, missing adTagUrl on options object"))}c.prepareForAds(n);if(v.playAdAlways){n.on("vast.contentEnd",function(){setTimeout(function(){n.trigger("vast.reset")},0)})}n.on("vast.firstPlay",g);n.on("vast.reset",function(){e=null;m()});n.vast={isEnabled:function(){return v.adsEnabled},enable:function(){v.adsEnabled=true},disable:function(){v.adsEnabled=false}};return n.vast;function g(){c.removeNativePoster(n);c.once(n,["vast.adsCancel","vast.adEnd"],function(){t();i()});u.waterfall([s,o,p,y],function(t,e){if(t){_(t,e)}else{n.trigger("vast.adEnd")}});function t(){if(n.vast&&n.vast.adUnit){n.vast.adUnit=null}}function i(){a();if(e){c.restorePlayerSnapshot(n,e);e=null}}function a(){c.once(n,["playing","vast.reset","vast.firstPlay"],function(t){if(t.type!=="playing"){return}n.trigger("vast.contentStart");c.once(n,["ended","vast.reset","vast.firstPlay"],function(t){if(t.type==="ended"){n.trigger("vast.contentEnd")}})})}function s(t){if(v.adsEnabled){return t(null)}t(new r("Ads are not enabled"))}function o(t){if(f()){e=c.getPlayerSnapshot(n);n.pause();g();if(n.paused()){t(null)}else{c.once(n,["playing"],function(){n.pause();t(null)})}}else{t(new r("video content has been playing before preroll ad"))}}function f(){return!d.isIPhone()||n.currentTime()<=v.iosPrerollCancelTimeout}function p(t){var e;h=false;e=setTimeout(function(){_(new r("timeout while waiting for the video to start playing",402))},v.adCancelTimeout);c.once(n,["vast.adStart","vast.adsCancel"],i);function i(){if(e){clearTimeout(e);e=null}}t(null)}function g(){l.addClass(n.el(),"vjs-vast-ad-loading");c.once(n,["vast.adStart","vast.adsCancel"],m)}function m(){setTimeout(function(){l.removeClass(n.el(),"vjs-vast-ad-loading")},100)}}function m(){n.trigger("vast.adsCancel");h=true}function y(t){u.waterfall([A,k],t)}function A(t){f.getVASTResponse(v.adTagUrl?v.adTagUrl():v.adTagXML,t)}function k(t,e){if(h){return}var i=E(t)?new o(n,v):new s(n);var r=false;c.once(n,["vast.adStart","vast.adsCancel"],function(t){if(t.type==="vast.adStart"){a()}});c.once(n,["vast.adEnd","vast.adsCancel"],u);if(d.isIDevice()){l()}n.vast.vastResponse=t;n.vast.adUnit=i.playAd(t,e);function a(){if(r||n.controlBar.getChild("AdsLabel")){return}n.controlBar.addChild("AdsLabel")}function u(){n.controlBar.removeChild("AdsLabel");r=true}function l(){var t=3;var e=0;var i=0;n.on("timeupdate",r);c.once(n,["vast.adEnd","vast.adsCancel","vast.adError"],a);function r(){var r=n.currentTime();var a=Math.abs(r-e);if(a>t){i+=1;if(i>=2){n.pause()}n.currentTime(e)}else{e=r}}function a(){n.off("timeupdate",r)}}}function _(t,e){n.trigger({type:"vast.adError",error:t});m();if(console&&console.log){console.log("AD ERROR:",t.message,t,e)}}function E(t){var e,n;var i=t.mediaFiles;for(e=0,n=i.length;e0){u=setTimeout(function(){l&&l.abort()},o)}function c(t,e,n){if(!r.isString(t)||r.isEmptyString(t)){throw new a("Invalid url '"+t+"'")}if(!r.isFunction(e)){throw new a("Invalid handler '"+e+"' for the http request")}if(r.isDefined(n)&&!r.isObject(n)){throw new a("Invalid options map '"+n+"'")}}function d(t,e){r.forEach(e,function(e,n){if(r.isDefined(e)){t.setRequestHeader(n,e)}})}function f(){n(-1,null,null,"")}};s.prototype.get=function(t,e,n){this.run("GET",t,i,n);function i(t,n,i,s){if(r(t)){e(null,n,t,i,s)}else{e(new a(s),n,t,i,s)}}function r(t){return 200<=t&&t<300}};function o(){var t=new XMLHttpRequest;if(!("withCredentials"in t)){t=new XDomainRequest}return t}var u=new s(o);e.exports={http:u,HttpRequest:s,HttpRequestError:a,createXhr:o}},{"./urlUtils":42,"./utilityFunctions":43}],41:[function(t,e,n){"use strict";var i=t("./dom");var r=t("./utilityFunctions");var a={};a.getPlayerSnapshot=function s(t){var e=t.el().querySelector(".vjs-tech");var n={ended:t.ended(),src:t.currentSrc(),currentTime:t.currentTime(),type:t.currentType(),playing:!t.paused(),suppressedTracks:i(t)};if(e){n.nativePoster=e.poster;n.style=e.getAttribute("style")}return n;function i(t){var e=t.remoteTextTracks?t.remoteTextTracks():[];if(e&&r.isArray(e.tracks_)){e=e.tracks_}if(!r.isArray(e)){e=[]}var n=[];e.forEach(function(t){n.push({track:t,mode:t.mode});t.mode="disabled"});return n}};a.restorePlayerSnapshot=function o(t,e){var n=t.el().querySelector(".vjs-tech");var i=20;if(e.nativePoster){n.poster=e.nativePoster}if("style"in e){n.setAttribute("style",e.style||"")}if(s(t,e)){t.one("contentloadedmetadata",o);t.one("canplay",u);r();t.src({src:e.src,type:e.type});t.load()}else{o();if(e.playing){t.play()}}function r(){var e=setTimeout(function(){t.trigger("canplay")},1e3);t.one("canplay",function(){clearTimeout(e)})}function s(t,e){if(t.src()){return t.src()!==e.src}return t.currentSrc()!==e.src}function o(){var t=e.suppressedTracks;t.forEach(function(t){t.track.mode=t.mode})}function u(){if(!a.isReadyToResume(t)&&i--){setTimeout(u,50)}else{try{if(t.currentTime()!==e.currentTime){if(e.playing){t.one("seeked",function(){t.play()})}t.currentTime(e.currentTime)}else if(e.playing){t.play()}}catch(n){videojs.log.warn("Failed to resume the content after an advertisement",n)}}}};a.isReadyToResume=function(t){if(t.readyState()>1){return true}if(t.seekable()===undefined){return true}if(t.seekable().length>0){return true}return false};a.prepareForAds=function(t){var e=t.addChild("blackPoster");var n=true;var a;s();t.on("play",u);t.on("vast.reset",l);t.on("vast.firstPlay",f);t.on("error",p);t.on("vast.adStart",p);t.on("vast.adsCancel",p);t.on("vast.adError",p);t.on("vast.adStart",v);t.on("vast.adEnd",g);t.on("vast.adsCancel",g);function s(){var e=t.play;t.play=function(n){var i=this;if(c()){s()}else{u(n)}return this;function s(){if(!r.isIPhone()){a=d();t.muted(true)}e.apply(i,arguments)}function u(n){if(o()&&!n){t.vast.adUnit.resumeAd()}else{e.apply(i,arguments)}}};var n=t.pause;t.pause=function(e){if(o()&&!e){t.vast.adUnit.pauseAd()}else{n.apply(this,arguments)}return this};var i=t.paused;t.paused=function(e){if(o()&&!e){return t.vast.adUnit.isPaused()}return i.apply(this,arguments)}}function o(){return t.vast&&t.vast.adUnit}function u(){if(c()){n=false;t.trigger("vast.firstPlay")}}function l(){n=true;e.show();f()}function c(){return n}function d(){return{muted:t.muted(),volume:t.volume()}}function f(){if(a){t.currentTime(0);h(a);a=null}}function h(e){if(r.isObject(e)){t.volume(e.volume);t.muted(e.muted)}}function p(){if(!i.hasClass(e.el(),"vjs-hidden")){e.hide()}}function v(){i.addClass(t.el(),"vjs-ad-playing")}function g(){i.removeClass(t.el(),"vjs-ad-playing")}};a.removeNativePoster=function(t){var e=t.el().querySelector(".vjs-tech");if(e){e.removeAttribute("poster")}};a.once=function u(t,e,n){function i(){n.apply(null,arguments);e.forEach(function(e){t.off(e,i)})}e.forEach(function(e){t.on(e,i)})};e.exports=a},{"./dom":39,"./utilityFunctions":43}],42:[function(t,e,n){"use strict";var i=t("./utilityFunctions");var r=document.createElement("a");var a=document.documentMode;function s(t){var e=t;if(a){r.setAttribute("href",e);e=r.href}r.setAttribute("href",e);return{href:r.href,protocol:r.protocol?r.protocol.replace(/:$/,""):"",host:r.host,search:r.search?r.search.replace(/^\?/,""):"",hash:r.hash?r.hash.replace(/^#/,""):"",hostname:r.hostname,port:i.isNotEmptyString(r.port)?r.port:80,pathname:r.pathname.charAt(0)==="/"?r.pathname:"/"+r.pathname}}function o(t,e){var n,r;e=i.isFunction(e)?e:function(){return true};t=t.trim().replace(/^\?/,"");n=t.split("&");r={};i.forEach(n,function(t){var n,i,a;if(t!==""){n=t.split("=");i=n[0];a=n[1];if(e(i,a)){r[i]=a}}});return r}function u(t){var e=[];i.forEach(t,function(t,n){e.push(n+"="+t)});return e.join("&")}e.exports={urlParts:s,queryStringToObj:o,objToQueryString:u}},{"./utilityFunctions":43}],43:[function(t,e,n){"use strict";var i=1;var r=/[A-Z]/g;var a=/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/i;var s=/^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;function o(){}function u(t){return t===null}function l(t){return t!==undefined}function c(t){return t===undefined}function d(t){return typeof t==="object"}function f(t){return typeof t==="function"}function h(t){return typeof t==="number"}function p(t){return j.isObject(t)&&t.window===t}function v(t){return Object.prototype.toString.call(t)==="[object Array]"}function g(t){if(t===null||j.isWindow(t)||j.isFunction(t)||j.isUndefined(t)){return false}var e=t.length;if(t.nodeType===i&&e){return true}return j.isString(t)||j.isArray(t)||e===0||typeof e==="number"&&e>0&&e-1 in t}function m(t){return typeof t==="string"}function y(t){return j.isString(t)&&t.length===0}function A(t){return j.isString(t)&&t.length!==0}function k(t){return Array.prototype.slice.call(t)}function _(t,e,n){var i,r;if(t){if(f(t)){for(i in t){if(i!=="prototype"&&i!=="length"&&i!=="name"&&(!t.hasOwnProperty||t.hasOwnProperty(i))){e.call(n,t[i],i,t)}}}else if(v(t)){var a=typeof t!=="object";for(i=0,r=t.length;i=e){n=i;t.apply(this,arguments)}}}function L(t,e){var n;return function(){if(n){clearTimeout(n)}n=setTimeout(function(){t.apply(this,arguments);n=undefined},e)}}function F(t,e,n){var i=e(t);for(var r=0;r0}return t.getElementsByTagNameNS(i,"parsererror").length>0}catch(r){}}};r.parseText=function s(t){if(/^\s*$/.test(t)){return null}if(/^(?:true|false)$/i.test(t)){return t.toLowerCase()==="true"}if(isFinite(t)){return parseFloat(t)}if(i.isISO8601(t)){return new Date(t)}return t.trim()};r.JXONTree=function o(t){var e=r.parseText;if(t.documentElement){return new r.JXONTree(t.documentElement)}if(t.hasChildNodes()){var n="";for(var a,s,o,u=0;u0:t.hasAttributes();if(l){var c;for(var d=0;d/g,">").replace(/"/g,""").replace(/'/g,"'")};r.decode=function f(t){return t.replace(/'/g,"'").replace(/"/g,'"').replace(/>/g,">").replace(/</g,"<").replace(/&/g,"&")};e.exports=r},{"./utilityFunctions":43}],45:[function(t,e,n){"use strict";t("./plugin/components/ads-label_5");t("./plugin/components/black-poster_5");var i=t("./plugin/videojs.vast.vpaid");videojs.plugin("vastClient",i)},{"./plugin/components/ads-label_5":34,"./plugin/components/black-poster_5":36,"./plugin/videojs.vast.vpaid":37}]},{},[45]); //# sourceMappingURL=videojs_5.vast.vpaid.min.js.map diff --git a/bin/videojs_5.vast.vpaid.min.js.map b/bin/videojs_5.vast.vpaid.min.js.map index 49ba98d2..70df0556 100644 --- a/bin/videojs_5.vast.vpaid.min.js.map +++ b/bin/videojs_5.vast.vpaid.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["node_modules/browser-pack/_prelude.js","bower_components/VPAIDFLASHClient/js/IVPAIDAdUnit.js","videojs_5.vast.vpaid.js","bower_components/VPAIDFLASHClient/js/VPAIDAdUnit.js","bower_components/VPAIDFLASHClient/js/VPAIDFLASHClient.js","bower_components/VPAIDFLASHClient/js/flashTester.js","bower_components/VPAIDFLASHClient/js/jsFlashBridge.js","bower_components/VPAIDFLASHClient/js/jsFlashBridgeRegistry.js","bower_components/VPAIDFLASHClient/js/registry.js","bower_components/VPAIDFLASHClient/js/utils.js","bower_components/VPAIDHTML5Client/js/IVPAIDAdUnit.js","bower_components/VPAIDHTML5Client/js/VPAIDAdUnit.js","bower_components/VPAIDHTML5Client/js/VPAIDHTML5Client.js","bower_components/VPAIDHTML5Client/js/subscriber.js","bower_components/VPAIDHTML5Client/js/utils.js","bower_components/swfobject/swfobject/src/swfobject.js","src/scripts/ads/vast/Ad.js","src/scripts/ads/vast/Companion.js","src/scripts/ads/vast/Creative.js","src/scripts/ads/vast/InLine.js","src/scripts/ads/vast/Linear.js","src/scripts/ads/vast/MediaFile.js","src/scripts/ads/vast/TrackingEvent.js","src/scripts/ads/vast/VASTClient.js","src/scripts/ads/vast/VASTError.js","src/scripts/ads/vast/VASTIntegrator.js","src/scripts/ads/vast/VASTResponse.js","src/scripts/ads/vast/VASTTracker.js","src/scripts/ads/vast/VideoClicks.js","src/scripts/ads/vast/Wrapper.js","src/scripts/ads/vast/parsers.js","src/scripts/ads/vast/vastUtil.js","src/scripts/ads/vpaid/VPAIDAdUnitWrapper.js","src/scripts/ads/vpaid/VPAIDFlashTech.js","src/scripts/ads/vpaid/VPAIDHTML5Tech.js","src/scripts/ads/vpaid/VPAIDIntegrator.js","src/scripts/plugin/components/ads-label.js","src/scripts/plugin/components/ads-label_5.js","src/scripts/plugin/components/black-poster.js","src/scripts/plugin/components/black-poster_5.js","src/scripts/plugin/videojs.vast.vpaid.js","src/scripts/utils/async.js","src/scripts/utils/dom.js","src/scripts/utils/http.js","src/scripts/utils/playerUtils.js","src/scripts/utils/urlUtils.js","src/scripts/utils/utilityFunctions.js","src/scripts/utils/xml.js","src/scripts/videojs_5.vast.vpaid.js"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length",1,"module","_createClass","defineProperties","target","props","descriptor","enumerable","configurable","writable","Object","defineProperty","key","Constructor","protoProps","staticProps","prototype","value","_classCallCheck","instance","TypeError","IVPAIDAdUnit","this","handshakeVersion","playerVPAIDVersion","arguments","undefined","callback","initAd","width","height","viewMode","desiredBitrate","creativeData","AdParameters","environmentVars","flashVars","resizeAd","startAd","stopAd","pauseAd","resumeAd","expandAd","collapseAd","skipAd","getAdLinear","getAdWidth","getAdHeight","getAdExpanded","getAdSkippableState","getAdRemainingTime","getAdDuration","setAdVolume","soundVolume","getAdVolume","getAdCompanions","getAdIcons",2,"_typeof","Symbol","iterator","obj","constructor","_possibleConstructorReturn","self","ReferenceError","_inherits","subClass","superClass","create","setPrototypeOf","__proto__","ALL_VPAID_METHODS","getOwnPropertyNames","filter","property","indexOf","VPAIDAdUnit","_IVPAIDAdUnit","flash","_this","getPrototypeOf","_destroyed","_flash","_destroy","_this2","forEach","methodName","removeCallbackByMethodName","EVENTS","event","offEvent","isDestroyed","on","eventName","off","callFlashMethod","setSize","getWidth","getHeight","volume","./IVPAIDAdUnit",3,"swfobject","JSFlashBridge","noop","callbackTimeout","isPositiveInt","createElementWithID","uniqueVPAID","unique","createFlashTester","ERROR","FLASH_VERSION","flashTester","isSupported","VPAIDFLASHClient","vpaidParentEl","swfConfig","data","params","wmode","salign","align","allowScriptAccess","scale","allowFullScreen","quality","vpaidOptions","debug","timeout","me","_vpaidParentEl","_flashID","movie","FlashVars","VPAID_FLASH_HANDLER","onError","el","createSWF","handler","err","$loadPendedAdUnit","error","setTimeout","destroy","_destroyAdUnit","_loadLater","_adUnitLoad","removeCallback","_adUnit","loadAdUnit","adURL","$throwIfDestroyed","isReady","message","url","unloadAdUnit","getFlashID","getFlashURL","setStaticProperty","hasFlashPlayerVersion","document","body","propertyName","./VPAIDAdUnit","./flashTester.js","./jsFlashBridge","./utils",4,"FLASH_TEST","FLASH_TEST_EL","utils","MultipleValuesRegistry","FlashTester","parent","parentEl","hideFlashEl","_handlers","_isSupported","support","get","add","window","./registry",5,"stringEndsWith","SingleValueRegistry","registry","flashURL","flashID","loadHandShake","_el","_flashURL","_width","_height","_callbacks","_uniqueMethodIdentifier","_ready","_handShakeHandler","addInstance","remove","removeByKey","offAll","removeAll","args","callbackID","concat","$asyncCallback","_trigger","removeByValue","suffix","filterKeys","removeAllCallbacks","_callCallback","result","trigger","_handShake","getSize","newWidth","newHeight","setAttribute","setWidth","setHeight","removeInstanceByID","parentElement","removeChild","_this3","typeID","typeName","getInstanceByID","./jsFlashBridgeRegistry",6,"instances","JSFlashBridgeRegistry","id",7,"_registries","push","keys","findByValue","index","splice","old","map","size","_this4",8,"prefix","count","timer","onSuccess","onTimeout","clearTimeout","apply","cleanContent","nEl","createElement","innerHTML","appendChild","newVal","oldVal","isNaN","parseFloat","isFinite","endsWith","String","searchString","position","subjectString","toString","lastIndex","string","search","style","left","top",9,"METHODS","GETTERS","SETTERS","creative","video","VPAIDVersion","subscribe","context","unsubscribe","addStaticToInterface","VPAID1_METHODS","method","checkVPAIDInterface","every","Interface","name",10,"Subscriber","AD_CLICK","FILTERED_EVENTS","VPAIDCreative","iframe","_isValid","_creative","_videoEl","_iframe","_subscribers","$addEventsSubscribers","isValidVPAIDAd","ignores","ariaty","Array","slice","pop","callOrTriggerEvent","bind","extend","slot","videoSlot","getter","validate","unsubscribeAll","$trigger","$clickThruHook","documentElement","contentDocument","videoEl","addEventListener","click","playerHandles","triggerSync","subscribers","./subscriber",11,"defaultTemplate","AD_STOPPED","VPAIDHTML5Client","templateConfig","_id","_frameContainer","createElementInEl","_vpaidOptions","_templateConfig","template","extraOptions","$unloadPreviousAdUnit","that","frame","createIframeWithContent","iframeURL_JS","iframeID","getID","origin","getOrigin","_frame","_onLoad","onLoad","JSON","parse","adUnit","createAd","contentWindow","getVPAIDAd","adEl","querySelector","$adDestroyed","$destroyLoadListener","$removeEl","$removeAdElements","$destroyAdUnit","removeEventListener","clearCallbackTimeout","location","protocol","hostname","port",12,"isHandlerAttached","subscriber","some",13,"isValid","timeouts","func","tagName","createIframe","zIndex","setIframeContent","simpleTemplate","src","marginWidth","marginHeight","frameBorder","margin","padding","border","stringify","replace","RegExp","iframeEl","content","iframeDoc","write","toExtend","fromSource",14,"root","factory","define","amd","UNDEF","OBJECT","SHOCKWAVE_FLASH","SHOCKWAVE_FLASH_AX","FLASH_MIME_TYPE","EXPRESS_INSTALL_ID","ON_READY_STATE_CHANGE","win","doc","nav","navigator","plugin","domLoadFnArr","regObjArr","objIdArr","listenersArr","storedFbContent","storedFbContentId","storedCallbackFn","storedCallbackObj","isDomLoaded","isExpressInstallActive","dynamicStylesheet","dynamicStylesheetMedia","autoHideShow","encodeURIEnabled","ua","w3cdom","getElementById","getElementsByTagName","userAgent","toLowerCase","p","platform","windows","test","mac","webkit","ie","appName","playerVersion","d","plugins","description","mimeTypes","enabledPlugin","toInt","ActiveXObject","GetVariable","split","w3","pv","wk","onDomLoad","readyState","callDomLoadFunctions","attachEvent","detach","detachEvent","checkDomLoadedIE","doScroll","checkDomLoadedWK","span","display","parentNode","dl","addDomLoadEvent","fn","addLoadEvent","addListener","onload","fnOld","testPlayerVersion","b","counter","checkGetVariable","matchVersions","rl","cb","callbackFn","cbObj","success","hasPlayerVersion","swfVersion","setVisibility","ref","getObjectById","expressInstall","canExpressInstall","att","getAttribute","styleclass","par","pl","j","showExpressInstall","displayFbContent","SetVariable","objectIdStr","nodeName","toUpperCase","replaceElemIdStr","getId","abstractFbContent","pt","fv","encodeURIComponent","title","flashvars","newObj","insertBefore","removeSWF","replaceChild","ac","nestedObj","c","childNodes","cl","nodeType","cloneNode","createIeObject","paramStr","div","firstChild","attObj","parObj","attr","attrLower","param","hasOwnProperty","createObjParam","pName","pValue","removeSWFInIE","isElement","thing","str","parseInt","eventType","rv","v","createCSS","sel","decl","media","newStyle","h","m","styleSheets","addRule","createTextNode","isVisible","visibility","urlEncodeIfNecessary","regex","hasBadChars","exec","cleanup","ll","il","k","registerObject","swfVersionStr","xiSwfUrlStr","regObj","embedSWF","swfUrlStr","widthStr","heightStr","flashvarsObj","callbackObj","switchOffAutoHideShow","enableUriEncoding","bool","getFlashPlayerVersion","major","minor","release","objElemIdStr","selStr","declStr","mediaStr","newStyleBoolean","getQueryParamValue","q","hash","pairs","substring","expressInstallCallback","version",15,"InLine","Wrapper","Ad","adJTree","initialize","sequence","inLine","wrapper","./InLine","./Wrapper",16,"TrackingEvent","utilities","xml","Companion","companionJTree","creativeType","staticResource","keyValue","htmlResource","HTMLResource","hTMLResource","iframeResource","IFrameResource","iFrameresource","expandedWidth","expandedHeight","scalable","maintainAspectRatio","minSuggestedDuration","apiFramework","companionClickThrough","trackingEvents","parseTrackingEvents","tracking","trackings","isDefined","isArray","trackingData","../../utils/utilityFunctions","../../utils/xml","./TrackingEvent",17,"Linear","Creative","creativeJTree","adId","linear","companionAds","companions","companion","companionData","parseCreatives","creativesJTree","creatives","creativesData","./Companion","./Linear",18,"vastUtil","inlineJTree","adTitle","adSystem","impressions","parseImpressions","impression","advertiser","surveys","parseSurveys","survey","pricing","extensions","inlineSurveys","transformArray","isNotEmptyString","uri","type","len","./Creative","./vastUtil",19,"MediaFile","VideoClicks","parsers","linearJTree","duration","mediaFiles","parseMediaFiles","mediaFile","skipoffset","offset","videoClicks","adParameters","decode","mediaFilesJxonTree","mfData","./MediaFile","./VideoClicks","./parsers",20,"attributesList","mediaFileJTree","x","attribute","isVPAID","findSupportedVPAIDTech","isFlashSupported",21,"trackingJTree",22,"VASTError","VASTResponse","async","http","VASTClient","options","defaultOptions","WRAPPER_LIMIT","settings","errorURLMacros","getVASTResponse","adTagUrl","sanityCheck","isFunction","waterfall","_getVASTAd","buildVASTResponse","adsChain","response","_buildVASTResponse","getAdWaterfall","vastTree","waterfallAds","ads","_trackError","getAd","shift","waterfallHandler","adChain","requestVastXML","_requestVASTXml","buildVastWaterfall","xmlStr","toJXONTree","ad","validateVASTTree","vastVersion","next","isString","requestVASTAd","buildAd","VASTAdTagURI","adJxonTree","validateAd","errMsgPrefix","requestVASTXml","requestHandler","withCredentials","status","errMsg","addAdsToResponse","validateResponse","addAd","progressEvents","progress","hasLinear","progressEvent","isNumber","addErrorUrlMacros","track","ERRORCODE","../../utils/async","../../utils/http","./Ad","./VASTError","./VASTResponse",23,24,"VASTTracker","dom","playerUtils","VASTIntegrator","player","playAd","vastResponse","_selectAdSource","_createVASTTracker","_addClickThrough","_addSkipButton","_setupEvents","_playSelectedAd","_src","pause","play","isPaused","paused","getSrc","selectAdSource","source","playerWidth","getDimension","sort","compareTo","deltaA","Math","abs","deltaB","selectSource","createVASTTracker","adMediaFile","setupEvents","tracker","previouslyMuted","trackFullscreenChange","trackImpressions","trackPause","trackProgress","trackVolumeChange","once","unbindEvents","evt","trackComplete","isFullscreen","trackFullscreen","trackExitFullscreen","currentTime","trackResume","currentTimeInMs","trackCreativeView","muted","trackMute","trackUnmute","addSkipButton","skipOffsetInSec","addSkipButtonToPlayer","skipOffset","skipButton","createSkipButton","updateSkipButton","updateSkipButtonState","removeSkipButton","addClass","onclick","hasClass","trackSkip","Event","stopPropagation","timeLeft","ceil","toFixedDigits","addClickThrough","blocker","createClickThroughBlocker","updateBlocker","updateBlockerURL","controlBar","removeBlocker","clickThroughMacro","clickThrough","href","generateClickThroughURL","trackClick","variables","ASSETURI","CONTENTPLAYHEAD","formatProgress","parseURLMacro","playSelectedAd","preload","proceed","trackError","../../utils/dom","../../utils/playerUtils","./VASTTracker",25,"InLine__A","_linearAdded","clickTrackings","customClicks","_addInLine","_addWrapper","_addErrorTrackUrl","errorURL","JXONTree","_addImpressions","appendToArray","_addClickTrackings","_addCustomClicks","_addTrackingEvents","eventsMap","trackingEvent","_addTitle","_addDuration","_addVideoClicks","_addMediaFiles","_addSkipoffset","_addAdParameters","_addLinear","array","items","item",26,"assetURI","quartiles","firstQuartile","tracked","time","round","midpoint","thirdQuartile","isEmptyString","trackURLs","urls","trackEvent","trackOnce","getEventUris","uris","newProgressInMs","events","ONCE","ALWAYS","addTrackEvent","hasRewound","addQuartileEvents","trackProgressEvents","trackEvents","currentProgress","newProgress","REWIND_THRESHOLD","canBeAdded","trackQuartile","quartileName","quartile","canBeTracked","quartileTime","pendingProgressEvts","capitalize","trackErrorWithCode","errorcode",27,"videoClickJTree","parseClickTrackings","clickTracking","customClick","clickTrackingData",28,"wrapperJTree","vASTAdTagURI","followAdditionalWrappers","allowMultipleAds","fallbackOnNoAd",29,"durationRegex","parseDuration","durationStr","match","durationInMs","parseHoursToMs","parseMinToMs","parseSecToMs","hourStr","minStr","secStr","parseOffset","isPercentage","calculatePercentage","percentageRegex","percentStr","calcPercent","quantity","percent",30,"VPAIDHTML5Tech","VPAIDFlashTech","URLMacros","sources","parseURLMacros","trackImgs","img","Image","parseMacros","parsedURLs","random","URLMacro","_parseURLMacro","parseMacro","hours","minutes","seconds","milliseconds","floor","VPAID_techs","isVPAIDMediaFile","mimeType","VPAIDTech","supports","runFlashSupportCheck","vpaidFlashLoaderPath","runFlashTest","../vpaid/VPAIDFlashTech","../vpaid/VPAIDHTML5Tech","VPAIDFLASHClient/js/VPAIDFLASHClient",31,"VPAIDAdUnitWrapper","vpaidAdUnit","opts","isObject","responseTimeout","VPAIDInterfaceMethods","canSubscribeToEvents","canUnsubscribeFromEvents","adUnitAsyncCall","arrayLikeObjToArray","timeoutId","wrapCallback","evtName","waitForEvent","responseListener","unshift","adUnitData","getterName","../vast/VASTError",32,"containerEl","vpaidFlashClient","loadFlashCreative","objectEl","flashClientOpts","container","isDomElement","console","log",33,"vpaidHTMLClient","INVALID_MEDIA_FILE","isOldIE","INVALID_DOM_CONTAINER_EL","MISSING_CALLBACK","PREFIX","INVALID_DOM_VIDEO_EL","VPAIDHTML5Client/js/VPAIDHTML5Client",34,"VPAIDIntegrator","VIEW_MODE","NORMAL","FULLSCREEN","THUMBNAIL","createVPAIDContainerEl","VPAID_VERSION","playVPaidAd","tech","_findSupportedTech","triggerVpaidAdEnd","one","removeAdUnit","_loadAdUnit","_playAdUnit","_finishPlaying","adComplete","_paused","removeClass","vpaidMediaFiles","_createVPAIDAdUnitWrapper","vjsTechEl","WrappedAdUnit","techClass","_handshake","_initAd","_linkPlayerControls","_startAd","handshake","isSupportedVersion","majorNum","parts","dimension","adUnitSrc","notifyPlayToPlayer","trackStart","notifyPauseToPlayer","trackFirstQuartile","trackMidpoint","trackThirdQuartile","clickThruUrl","open","trackAcceptInvitation","trackAcceptInvitationLinear","trackClose","trackCloseLinear","trackCollapse","lastVolume","currentVolume","updateViewSize","updateViewSizeThrottled","throttle","autoResize","pauseAdUnit","resumeAdUnit","isSkippable","linkVolumeControl","linkFullScreenControl","updateAdUnitVolume","updatePlayerVolume","vol","logError","finishPlayingAd","errorCode","MODE","../vast/VASTResponse","../vast/VASTTracker","../vast/vastUtil","./VPAIDAdUnitWrapper",35,"element","className","AdsLabelFactory","baseComponent","init","currentTimeComp","getChild","getElement",36,"baseVideoJsComponent","videojs","getComponent","AdsLabel","registerComponent","./ads-label",37,"BlackPosterFactory","posterImg",38,"BlackPoster","./black-poster",39,"VASTPlugin","snapshot","vast","adsCanceled","defaultOpts","iosPrerollCancelTimeout","adCancelTimeout","playAdAlways","adsEnabled","isUndefined","echoFn","adTagXML","trackAdError","prepareForAds","tryToPlayPrerollAd","cancelAds","isEnabled","enable","disable","removeNativePoster","restoreVideoContent","checkAdsEnabled","preparePlayerForAd","startAdCancelTimeout","playPrerollAd","setupContentEvents","restorePlayerSnapshot","canPlayPrerollAd","getPlayerSnapshot","addSpinnerIcon","isIPhone","adCancelTimeoutId","clearAdCancelTimeout","removeSpinnerIcon","getVastResponse","adIntegrator","adFinished","addAdsLabel","removeAdsLabel","isIDevice","preventManualProgress","addChild","PROGRESS_THRESHOLD","previousTime","skipad_attempts","preventAdSeek","preventAdSkip","stopPreventManualProgress","progressDelta","../ads/vast/VASTClient","../ads/vast/VASTError","../ads/vast/VASTIntegrator","../ads/vast/vastUtil","../ads/vpaid/VPAIDIntegrator","../utils/async","../utils/dom","../utils/playerUtils","../utils/utilityFunctions",40,"setImmediate","tasks","makeCallback","wrapIterator","when","condition","isAllowed","./utilityFunctions",41,"getComputedStyle","isHidden","isShown","hide","__prev_style_display_","show","cssClass","classes","classList","contains","join","newClasses","dispatchEvent","fireEvent","isDescendant","child","node","getTextContent","textContent","text","prependChild","removeNode","Element","handlerWrap","rect","getBoundingClientRect","offsetWidth","offsetHeight",42,"urlUtils","HttpRequestError","HttpRequest","createXhr","run","xhr","urlParts","headers","setHeaders","statusText","getAllResponseHeaders","responseText","onerror","requestError","onabort","send","abort","setRequestHeader","processResponse","headersString","isSuccess","XMLHttpRequest","XDomainRequest","./urlUtils",43,"ended","currentSrc","currentType","playing","suppressedTracks","getSuppressedTracks","nativePoster","poster","tracks","remoteTextTracks","tracks_","mode","attempts","hasSrcChanged","restoreTracks","tryToResume","ensureCanplayEvtGetsFired","load","trackSnapshot","isReadyToResume","warn","seekable","blackPoster","_firstPlay","volumeSnapshot","monkeyPatchPlayerApi","tryToTriggerFirstPlay","resetFirstPlay","restoreContentVolume","hideBlackPoster","addStyles","removeStyles","origPlay","callOrigPlay","isFirstPlay","firstPlay","resume","saveVolumeSnapshot","isAdPlaying","origPause","callOrigPause","origPaused","callOrigPaused","restoreVolumeSnapshot","removeAttribute","listener","./dom",44,"urlParsingNode","msie","documentMode","host","pathname","charAt","queryStringToObj","qs","cond","qsObj","trim","pair","objToQueryString",45,"NODE_TYPE_ELEMENT","SNAKE_CASE_REGEXP","EMAIL_REGEXP","ISO8086_REGEXP","isNull","num","isWindow","isArrayLike","isPrimitive","snake_case","separator","letter","pos","isValidEmail","email","arg","decapitalize","transformer","transformedArray","transformedItem","digits","formattedNum","NaN","delay","previousCall","Date","getTime","debounce","wait","treeSearch","getChildren","found","children","val","isISO8601","getInternetExplorerVersion","re","res","_UA","isMobile","isAndroid",46,"strToXMLDoc","stringContainingXMLSource","DOMParser","xmlDocument","loadXML","parseString","parser","parsedDocument","parseFromString","isParseError","erroneousParse","parsererrorNS","namespaceURI","getElementsByTagNameNS","parseText","sValue","oXMLParent","hasChildNodes","sCollectedTxt","oNode","sProp","vContent","nItem","nodeValue","hasAttr","hasAttributes","attributes","oAttrib","nAttrib","xmlString","xmlDoc","getKeyValue","xmlObj","getAttrValue","encode","encodeXML","decodeXML",47,"videoJsVAST","./plugin/components/ads-label_5","./plugin/components/black-poster_5","./plugin/videojs.vast.vpaid"],"mappings":"CAAA,QAAAA,GAAAC,EAAAC,EAAAC,GAAA,QAAAC,GAAAC,EAAAC,GAAA,IAAAJ,EAAAG,GAAA,CAAA,IAAAJ,EAAAI,GAAA,CAAA,GAAAE,SAAAC,UAAA,YAAAA,OAAA,KAAAF,GAAAC,EAAA,MAAAA,GAAAF,GAAA,EAAA,IAAAI,EAAA,MAAAA,GAAAJ,GAAA,EAAA,IAAAK,GAAA,GAAAC,OAAA,uBAAAN,EAAA,IAAA,MAAAK,GAAAE,KAAA,mBAAAF,EAAA,GAAAG,GAAAX,EAAAG,IAAAS,WAAAb,GAAAI,GAAA,GAAAU,KAAAF,EAAAC,QAAA,SAAAd,GAAA,GAAAE,GAAAD,EAAAI,GAAA,GAAAL,EAAA,OAAAI,GAAAF,EAAAA,EAAAF,IAAAa,EAAAA,EAAAC,QAAAd,EAAAC,EAAAC,EAAAC,GAAA,MAAAD,GAAAG,GAAAS,QAAA,GAAAL,SAAAD,UAAA,YAAAA,OAAA,KAAA,GAAAH,GAAA,EAAAA,EAAAF,EAAAa,OAAAX,IAAAD,EAAAD,EAAAE,GAAA,OAAAD,MAAAa,GAAA,SAAAT,EAAAU,EAAAJ,GCAA,YCKA,IAAIK,GAAe,WACf,QAASC,GAAiBC,EAAQC,GAC9B,IAAK,GAAIb,GAAI,EAAGA,EAAIa,EAAMN,OAAQP,IAAK,CACnC,GAAIc,GAAaD,EAAMb,EAAGc,GAAWC,WAAaD,EAAWC,YAAc,KAAMD,GAAWE,aAAe,IAAK,IAAI,SAAWF,GAAYA,EAAWG,SAAW,IAAKC,QAAOC,eAAeP,EAAQE,EAAWM,IAAKN,IAE3N,MAAO,UAAUO,EAAaC,EAAYC,GACvC,GAAID,EAAYX,EAAiBU,EAAYG,UAAWF,EAAY,IAAIC,EAAaZ,EAAiBU,EAAaE,EAAa,OAAOF,MAI/IH,QAAOC,eAAed,EAAS,cAC3BoB,MAAO,MAGX,SAASC,GAAgBC,EAAUN,GAC/B,KAAMM,YAAoBN,IAAc,CACpC,KAAM,IAAIO,WAAU,sCAI5B,GDtBaC,GAAAxB,EAAAwB,aAAA,WCuBT,QAASA,KACLH,EAAgBI,KAAMD,GAG1BnB,EAAamB,IACTT,IAAK,mBAILK,MAAO,QAASM,KACZ,GD7BSC,GAAAC,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAqB,MAAAD,UAA6B,EC8B3D,ID9BqCE,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,MCoC/Db,IAAK,SACLK,MAAO,QAASW,GDlCZC,EAAOC,EAAQC,EAAUC,GCmCzB,GDnCyCC,GAAAR,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,WAAgBQ,aAAA,IAAAT,UAA2E,ECoCpI,IDpC2EU,GAAAV,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,WAAmBU,UAAA,IAAAX,UAAsC,ECqCpI,IDrC8GE,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,MCwCxIb,IAAK,WACLK,MAAO,QAASoB,GDxCXR,EAAOC,EAAQC,GCyChB,GDzC0BJ,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,MC4CpDb,IAAK,UACLK,MAAO,QAASqB,KACZ,GD5CAX,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,MC+C1Bb,IAAK,SACLK,MAAO,QAASsB,KACZ,GDhDDZ,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,MCmDzBb,IAAK,UACLK,MAAO,QAASuB,KACZ,GDpDAb,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,MCuD1Bb,IAAK,WACLK,MAAO,QAASwB,KACZ,GDxDCd,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,MC2D3Bb,IAAK,WACLK,MAAO,QAASyB,KACZ,GD5DCf,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,MC+D3Bb,IAAK,aACLK,MAAO,QAAS0B,KACZ,GDhEGhB,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,MCmE7Bb,IAAK,SACLK,MAAO,QAAS2B,KACZ,GDpEDjB,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,MC0EzBb,IAAK,cACLK,MAAO,QAAS4B,GDxERlB,OC0ERf,IAAK,aACLK,MAAO,QAAS6B,GD1ETnB,OC4EPf,IAAK,cACLK,MAAO,QAAS8B,GD5ERpB,OC8ERf,IAAK,gBACLK,MAAO,QAAS+B,GD9ENrB,OCgFVf,IAAK,sBACLK,MAAO,QAASgC,GDhFAtB,OCkFhBf,IAAK,qBACLK,MAAO,QAASiC,GDlFDvB,OCoFff,IAAK,gBACLK,MAAO,QAASkC,GDpFNxB,OCsFVf,IAAK,cACLK,MAAO,QAASmC,GDtFRC,GCuFJ,GDvFiB1B,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,MC0F3Cb,IAAK,cACLK,MAAO,QAASqC,GD1FR3B,OC4FRf,IAAK,kBACLK,MAAO,QAASsC,GD5FJ5B,OC8FZf,IAAK,aACLK,MAAO,QAASuC,GD9FT7B,OCiGX,OD9HSN,KAgCbX,QAAAC,eAAAU,EAAA,UCkGIZ,SDjGA,MCkGAD,aDjGA,MCkGAS,ODjGO,WAAA,YAAA,YAAA,YAAA,yBAAA,eAAA,iBAAA,mBAAA,mBAAA,wBAAA,iBAAA,eAAA,eAAA,uBAAA,kBAAA,uBAAA,kBAAA,cAAA,gBAAA,yBAAA,iBAAA,cAAA,WAAA,YAAA,QAHX,kBC4GMwC,GAAG,SAASlE,EAAQU,EAAOJ,GC/IjC,YDkJA,IAAI6D,SAAiBC,UAAW,kBAAqBA,QAAOC,WAAa,SAAW,SAAUC,GAAO,aAAcA,IAAS,SAAUA,GAAO,MAAOA,UAAcF,UAAW,YAAcE,EAAIC,cAAgBH,OAAS,eAAkBE,GAE1O,IAAI3D,GAAe,WACf,QAASC,GAAiBC,EAAQC,GAC9B,IAAK,GAAIb,GAAI,EAAGA,EAAIa,EAAMN,OAAQP,IAAK,CACnC,GAAIc,GAAaD,EAAMb,EAAGc,GAAWC,WAAaD,EAAWC,YAAc,KAAMD,GAAWE,aAAe,IAAK,IAAI,SAAWF,GAAYA,EAAWG,SAAW,IAAKC,QAAOC,eAAeP,EAAQE,EAAWM,IAAKN,IAE3N,MAAO,UAAUO,EAAaC,EAAYC,GACvC,GAAID,EAAYX,EAAiBU,EAAYG,UAAWF,EAAY,IAAIC,EAAaZ,EAAiBU,EAAaE,EAAa,OAAOF,MAI/IH,QAAOC,eAAed,EAAS,cAC3BoB,MAAO,MAGX,SAASC,GAAgBC,EAAUN,GAC/B,KAAMM,YAAoBN,IAAc,CACpC,KAAM,IAAIO,WAAU,sCAI5B,QAAS2C,GAA2BC,EAAMlE,GACtC,IAAKkE,EAAM,CACP,KAAM,IAAIC,gBAAe,6DAC5B,MAAOnE,YAAiBA,KAAS,YAAc,YAAc4D,EAAQ5D,MAAW,gBAAmBA,KAAS,YAAcA,EAAOkE,EAGtI,QAASE,GAAUC,EAAUC,GACzB,SAAWA,KAAe,YAAcA,IAAe,KAAM,CACzD,KAAM,IAAIhD,WAAU,kEAAqEgD,KAAe,YAAc,YAAcV,EAAQU,KAC/ID,EAASnD,UAAYN,OAAO2D,OAAOD,GAAcA,EAAWpD,WAAa8C,aAAe7C,MAAOkD,EAAU5D,WAAY,MAAOE,SAAU,KAAMD,aAAc,OAAU,IAAI4D,EAAY1D,OAAO4D,eAAiB5D,OAAO4D,eAAeH,EAAUC,GAAcD,EAASI,UAAYH,EC/KpR,GAAI/C,GAAe9B,EAAA,kBAAA8B,YACnB,IAAAmD,GAAwB9D,OAAA+D,oBAA2BpD,EAA3BL,WAAA0D,OAAA,SAA0DC,GDmL9E,OClLO,eAAAC,QAAAD,MADP,GDsLJ,IClLaE,GAAAhF,EAAAgF,YAAA,SAAAC,GDmLTZ,EAAUW,EClLVC,EDoLA,SCrLSD,GACTE,GDqLI7D,EAAgBI,KCtLXuD,EDwLL,IAAIG,GAAQjB,EAA2BzC,KAAMZ,OAAOuE,eCxL/CJ,GAAA/E,KACWwB,MDyLhB0D,GCvLAE,WAFgB,KD0LhBF,GCvLAG,OAHgBJ,CD2LhB,OC3LJC,GD8LA9E,EC/LS2E,IDgMLjE,IAAK,WACLK,MAAO,QAASmE,KACZ,GAAIC,GC1LR/D,ID4LIA,MC5LJ4D,WADO,ID8LHV,GC5LJc,QAAA,SAA0BC,GD6LlBF,EC5LJF,OAAAK,2BAHGD,IDiMHlE,GC5LJoE,OAAAH,QAAA,SAA4BI,GD6LpBL,EC5LJF,OAAAQ,SANGD,IDqMHpE,MC5LJ6D,OATO,QDwMPvE,IAAK,cACLK,MAAO,QAAS2E,KACZ,MC7LGtE,MADI4D,cDiMXtE,IAAK,KACLK,MAAO,QAAS4E,GC9LjBC,EAAWnE,GD+LNL,KC9LJ6D,OAAAU,GAAAC,EADoBnE,MDkMpBf,IAAK,MACLK,MAAO,QAAS8E,GC/LhBD,EAAWnE,GDgMPL,KC/LJ6D,OAAAY,IAAAD,EADqBnE,MDsMrBf,IAAK,mBACLK,MAAO,QAASM,KACZ,GCnMSC,GAAAC,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAqB,MAAAD,UAA6B,EDoM3D,ICpMqCE,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,EDsM3DH,MCrMJ6D,OAAAa,gBAAA,oBAAAxE,GAD+DG,MDyM/Df,IAAK,SACLK,MAAO,QAASW,GCvMZC,EAAOC,EAAQC,EAAUC,GDwMzB,GCxMyCC,GAAAR,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,WAAgBQ,aAAA,IAAAT,UAA4E,EDyMrI,ICzM4EU,GAAAV,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,WAAmBU,UAAA,IAAAX,UAAsC,ED0MrI,IC1M+GE,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,EAAAH,MAEzI6D,OAAAc,QAAApE,EAFyIC,ED8MrIG,GC3MWA,IAAiBC,aAHyG,GD+MrIC,GC3McA,IAAoBC,UAJmG,GDiNrId,MC3MJ6D,OAAAa,gBAAA,UAAuC1E,KAAA6D,OAADe,WAAyB5E,KAAA6D,OAAzBgB,YAAApE,EAAAC,EAA4EC,EAAAC,cAAA,GAAiCC,EAAAC,WAAnJ,IANyIT,MDoNzIf,IAAK,WACLK,MAAO,QAASoB,GC7MXR,EAAOC,EAAQC,GD8MhB,GC9M0BJ,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,EAAAH,MAEpD6D,OAAAc,QAAApE,EAFoDC,EDoNhDR,MC/MJ6D,OAAAa,gBAAA,YAAyC1E,KAAA6D,OAADe,WAAyB5E,KAAA6D,OAAzBgB,YAAxCpE,GALoDJ,MDuNpDf,IAAK,UACLK,MAAO,QAASqB,KACZ,GClNAX,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,EDoNtBH,MCnNJ6D,OAAAa,gBAAA,aAD0BrE,MDuN1Bf,IAAK,SACLK,MAAO,QAASsB,KACZ,GCtNDZ,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,EDwNrBH,MCvNJ6D,OAAAa,gBAAA,YADyBrE,MD2NzBf,IAAK,UACLK,MAAO,QAASuB,KACZ,GC1NAb,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,ED4NtBH,MC3NJ6D,OAAAa,gBAAA,aAD0BrE,MD+N1Bf,IAAK,WACLK,MAAO,QAASwB,KACZ,GC9NCd,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,EDgOvBH,MC/NJ6D,OAAAa,gBAAA,cAD2BrE,MDmO3Bf,IAAK,WACLK,MAAO,QAASyB,KACZ,GClOCf,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,EDoOvBH,MCnOJ6D,OAAAa,gBAAA,cAD2BrE,MDuO3Bf,IAAK,aACLK,MAAO,QAAS0B,KACZ,GCtOGhB,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,EDwOzBH,MCvOJ6D,OAAAa,gBAAA,gBAD6BrE,MD2O7Bf,IAAK,SACLK,MAAO,QAAS2B,KACZ,GC1ODjB,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,ED4OrBH,MC3OJ6D,OAAAa,gBAAA,YADyBrE,MDkPzBf,IAAK,cACLK,MAAO,QAAS4B,GC9ORlB,GD+OJL,KC9OJ6D,OAAAa,gBAAA,iBADkBrE,MDkPlBf,IAAK,aACLK,MAAO,QAAS6B,GChPTnB,GDiPHL,KChPJ6D,OAAAa,gBAAA,gBADiBrE,MDoPjBf,IAAK,cACLK,MAAO,QAAS8B,GClPRpB,GDmPJL,KClPJ6D,OAAAa,gBAAA,iBADkBrE,MDsPlBf,IAAK,gBACLK,MAAO,QAAS+B,GCpPNrB,GDqPNL,KCpPJ6D,OAAAa,gBAAA,mBADoBrE,MDwPpBf,IAAK,sBACLK,MAAO,QAASgC,GCtPAtB,GDuPZL,KCtPJ6D,OAAAa,gBAAA,yBAD0BrE,MD0P1Bf,IAAK,qBACLK,MAAO,QAASiC,GCxPDvB,GDyPXL,KCxPJ6D,OAAAa,gBAAA,wBADyBrE,MD4PzBf,IAAK,gBACLK,MAAO,QAASkC,GC1PNxB,GD2PNL,KC1PJ6D,OAAAa,gBAAA,mBADoBrE,MD8PpBf,IAAK,cACLK,MAAO,QAASmC,GC5PRgD,GD6PJ,GC7PYzE,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,ED+PlCH,MC9PJ6D,OAAAa,gBAAA,eAAAI,GADsCzE,MDkQtCf,IAAK,cACLK,MAAO,QAASqC,GChQR3B,GDiQJL,KChQJ6D,OAAAa,gBAAA,iBADkBrE,MDoQlBf,IAAK,kBACLK,MAAO,QAASsC,GClQJ5B,GDmQRL,KClQJ6D,OAAAa,gBAAA,qBADsBrE,MDsQtBf,IAAK,aACLK,MAAO,QAASuC,GCpQT7B,GDqQHL,KCpQJ6D,OAAAa,gBAAA,gBADiBrE,MDyQrB,OChXSkD,IAAoBxD,KDmX9BgF,iBAAiB,IAAIC,GAAG,SAAS/G,EAAQU,EAAOJ,GE1XnD,YF6XA,IAAIK,GAAe,WACf,QAASC,GAAiBC,EAAQC,GAC9B,IAAK,GAAIb,GAAI,EAAGA,EAAIa,EAAMN,OAAQP,IAAK,CACnC,GAAIc,GAAaD,EAAMb,EAAGc,GAAWC,WAAaD,EAAWC,YAAc,KAAMD,GAAWE,aAAe,IAAK,IAAI,SAAWF,GAAYA,EAAWG,SAAW,IAAKC,QAAOC,eAAeP,EAAQE,EAAWM,IAAKN,IAE3N,MAAO,UAAUO,EAAaC,EAAYC,GACvC,GAAID,EAAYX,EAAiBU,EAAYG,UAAWF,EAAY,IAAIC,EAAaZ,EAAiBU,EAAaE,EAAa,OAAOF,MAI/I,SAASK,GAAgBC,EAAUN,GAC/B,KAAMM,YAAoBN,IAAc,CACpC,KAAM,IAAIO,WAAU,sCEvY5B,GAAMmF,GAAYhH,EAAZ,YAEN,IAAMiH,GAAgBjH,EAAA,mBAAAiH,aACtB,IAAM3B,GAActF,EAAA,iBAAAsF,WAEpB,IAAM4B,GAAOlH,EAAA,WAAAkH,IACb,IAAMC,GAAkBnH,EAAA,WAAAmH,eACxB,IAAMC,GAAgBpH,EAAA,WAAAoH,aACtB,IAAMC,GAAsBrH,EAAA,WAAAqH,mBAC5B,IAAMC,GAActH,EAAA,WAAAuH,OAAd,QACN,IAAMC,GAAoBxH,EAAA,oBAAAwH,iBAE1B,IAAMC,GAAA,OACN,IAAMC,GAAA,QAEN,IAAIC,IAAeC,YAAA,QAAAA,KF4YX,ME5YJ,OF+YJ,IAAIC,GAAmB,WACnB,QE9YEA,GACFC,EAAA1F,GF8YI,GE9YkC2F,GAAA7F,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,WAAa6F,KAAA,iBAAwB1F,MAAA,IAAYC,OAAA,KAAAL,UAAuN,EFgZ1S,IAAIuD,GAAQ1D,IAEZ,IElZiGkG,GAAA/F,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,WAAW+F,MAAA,cAAsBC,OAAA,KAAcC,MAAA,OAAeC,kBAAA,SAA6BC,MAAA,UAAkBC,gBAAA,OAAyBC,QAAA,QAAAtG,UAAmE,EFmZ1S,IEnZyPuG,GAAAvG,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,WAAiBuG,MAAA,MAAcC,QAAA,KAAAzG,UAAkB,EFqZ1SP,GAAgBI,KEtZlB8F,EFwZE,IErZIe,GAFsS7G,IFyZ1SA,MErZA8G,eAJ0Sf,CF0Z1S/F,MErZA+G,SAL0SxB,GF2Z1SvF,MErZA4D,WAN0S,KF4Z1SvD,GErZWA,GAP+R8E,CF8Z1Sa,GErZAzF,MAAkB8E,EAAcW,EAAAzF,MAT0Q,IF+Z1SyF,GErZAxF,OAAmB6E,EAAcW,EAAAxF,OAVyQ,IFia1S8E,GErZAS,EAAmC/F,KAAA+G,SAZuQ,KFma1Sb,GErZAc,MAAehB,EAd2RC,IFoa1SC,GErZAe,UAAA,WAA8BjH,KAAA+G,SAAA,YAAyB7B,EAAAgC,oBAAA,UAA2CR,EAAAC,MAAA,WAA6BT,EAf2KE,MFsa1S,KErZKN,EAADD,cAAiC,CFsZjC,MErZOsB,GAAQ,kFADnBxB,GFyZA3F,KErZAoH,GAAUnC,EAAAoC,UAAArB,EAAAE,EAAuClG,KArByP+G,SF4a1S,KErZK/G,KAAAoH,GAAS,CFsZV,MErZOD,GADX,gDFyZA,GAAIG,GErZUlC,EAAgBsB,EAAAE,QAAA,SAC1BW,EAAAtB,GFqZAuB,EEpZIhJ,KADWkF,EFsZfrD,GEpZIkH,EAFJtB,IAAA,WFwZA5F,EEpZa,4BAA8BqG,EAhC2PE,UFub1S5G,MEnZA6D,OAAc,GAAAqB,GAAkBlF,KAAAoH,GAASpB,EAAAC,KAAgBjG,KAAA+G,SAAef,EAAAzF,MAAiByF,EAAAxF,OApCiN8G,EFyb1S,SEnZAH,GAAAM,GFoZIC,WAAW,WACPrH,EEnZS,GAAAjC,OADFqJ,KADS,EFuZpB,OE7bRZ,IFicAjI,EElcEkH,IFmcExG,IAAK,UACLK,MAAO,QAASgI,KACZ3H,KErZG4H,gBFuZH,IEpZA5H,KAAA6D,OAAa,CFqZT7D,KEpZJ6D,OADa8D,SFsZT3H,MEpZJ6D,OAFJ,KFwZI7D,KEpZJoH,GAPO,IF4ZHpH,MEpZJ4D,WARO,QF+ZPtE,IAAK,cACLK,MAAO,QAAS2E,KACZ,MErZGtE,MADI4D,cFyZXtE,IAAK,iBACLK,MAAO,QAASiI,WErZT5H,MADM6H,UFyZT,IEtZA7H,KAAA8H,YAAkB,CFuZd9H,KEtZJ8H,YADkB,IFwZd9H,MEtZJ6D,OAAAkE,eAA2B/H,KAF/B8H,aF2ZI,GEtZA9H,KAAAgI,QAAc,CFuZVhI,KEtZJgI,QADclE,UFwZV9D,MEtZJgI,QAFJ,SF4ZA1I,IAAK,aACLK,MAAO,QAASsI,GEvZTC,EAAO7H,GFwZV,GAAI0D,GEvZR/D,IFyZImI,GEzZJ3J,KADwBwB,KF4ZpB,IEzZAA,KAAAgI,QAAc,CF0ZVhI,KE1ZR4H,iBF6ZI,GEzZA5H,KAAA6D,OAAJuE,UAAA,CF0ZQpI,KEzZJ8H,YAAA,SAAmBP,EAAAc,GF0ZX,IEzZAd,EAAM,CF0ZFxD,EEzZJiE,QAAe,GAAAzE,GAAgBQ,EADnCF,QF4ZIE,EEzZJ+D,YAJiC,IF8Z7BzH,GEzZJkH,EAAcxD,EANKiE,SFkanBhI,MEzZJ6D,OAAAa,gBAAA,cAAAwD,GAAmDlI,KATvD8H,iBAUM,CF0ZE9H,KEzZJ6H,YAAmBS,IAAAJ,EAAY7H,SAXnCA,OFwaAf,IAAK,eACLK,MAAO,QAAS4I,KACZ,GE3ZKlI,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,EF6Z3BgI,GE5ZJ3J,KAD+BwB,KF+Z3BA,ME/Z2B4H,gBFga3B5H,ME5ZJ6D,OAAAa,gBAAA,kBAJ+BrE,MFma/Bf,IAAK,aACLK,MAAO,QAAS6I,KACZL,EE9ZJ3J,KADSwB,KFgaL,OE9ZGA,MAAA6D,OAFE2E,gBFmaTlJ,IAAK,cACLK,MAAO,QAAS8I,KACZN,EEhaJ3J,KADUwB,KFkaN,OEhaGA,MAAA6D,OAFG4E,iBFsad,OEnhBE3C,KAmHN4C,GAAA,cAAA,WFoaI,MEnaOzD,GAAA0D,sBAAAhD,IAAkDC,EAD5BC,eAAjC,KAIA6C,GAAA,eAAA,SAAkC1C,GFoa9BJ,EEnacH,EAAkBmD,SAAAC,KADpC7C,IAIA,SAAAmC,KFoaI,GEnaGnI,KAAA4D,WAAiB,CFoahB,KEnaM,IAAAxF,OAFd,iCAMA,QAAAoJ,KFoaI,GEnaIxH,KAAA6H,WAAiB,CFoajB7H,KEnaAiI,WAAgBjI,KAAA6H,WAAAS,IAAqBtI,KAAA6H,WADpBxH,gBAEVL,MAHf6H,YAOA,QAAAa,GAAAI,EAAAnJ,GFoaI,GEpa4CR,GAAAgB,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAW,MAAAD,UAAO,EFsa9Df,QEraAC,eAAAyG,EAAAgD,GFsaI3J,SEraAA,EFsaAD,aEraA,MFsaAS,MEzaRA,IAQAmG,EAAAb,UAAAA,CAEAtG,GAAAJ,QAAAuH,IFuaGiD,gBAAgB,EAAEC,mBAAmB,EAAEC,kBAAkB,EAAEC,UAAU,EAAEjE,UAAY,KAAKkE,GAAG,SAASlL,EAAQU,EAAOJ,GG5kBtH,YH+kBA,IAAIK,GAAe,WACf,QAASC,GAAiBC,EAAQC,GAC9B,IAAK,GAAIb,GAAI,EAAGA,EAAIa,EAAMN,OAAQP,IAAK,CACnC,GAAIc,GAAaD,EAAMb,EAAGc,GAAWC,WAAaD,EAAWC,YAAc,KAAMD,GAAWE,aAAe,IAAK,IAAI,SAAWF,GAAYA,EAAWG,SAAW,IAAKC,QAAOC,eAAeP,EAAQE,EAAWM,IAAKN,IAE3N,MAAO,UAAUO,EAAaC,EAAYC,GACvC,GAAID,EAAYX,EAAiBU,EAAYG,UAAWF,EAAY,IAAIC,EAAaZ,EAAiBU,EAAaE,EAAa,OAAOF,MAI/IH,QAAOC,eAAed,EAAS,cAC3BoB,MAAO,MAGX,SAASC,GAAgBC,EAAUN,GAC/B,KAAMM,YAAoBN,IAAc,CACpC,KAAM,IAAIO,WAAU,sCG7lB5B,GAAMmF,GAAYhH,EAAZ,YAEN,IAAMmL,GAAA,0BACN,IAAMC,GAAA,6BACN,IAAMnE,GAAgBjH,EAAA,mBAAAiH,aACtB,IAAMoE,GAAQrL,EAAR,UACN,IAAMsL,GAAyBtL,EAAA,cAAAsL,sBHmmB/B,IAAIC,GAAc,WACd,QGlmBEA,GACFC,GHkmBI,GAAI/F,GAAQ1D,IAEZ,IGpmBgBgG,GAAA7F,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,WAAa6F,KAAA,iBAAwB1F,MAAA,IAAYC,OAAA,KAAAL,UAAc,EHsmB/EP,GAAgBI,KGvmBlBwJ,EHymBExJ,MGvmBA0J,SAAgBJ,EAAAhE,oBAAAmE,EAD+DJ,EAAAC,GAE/EK,YAAkB3J,KAF6D0J,SH0mB/E,IGvmBIxD,KHwmBJA,GGvmBAc,MAAehB,EAJgEC,IH4mB/EC,GGvmBAe,UAAA,WAA8BoC,EAAA,YAAyBnE,EALwBgC,mBH8mB/ElH,MGvmBAoH,GAAUnC,EAAAoC,UAAArB,EAAAE,EAPqEmD,EH+mB/ErJ,MGvmBA4J,UAAiB,GAR8DL,EHgnB/EvJ,MGvmBA6J,aAT+E,KHinB/E,IGvmBI7J,KAAAoH,GAAA,CHwmBAkC,EGvmBAK,YAAkB3J,KADToH,GHymBTpH,MGvmBA6D,OAAc,GAAAqB,GAAkBlF,KAAAoH,GAASpB,EAAAC,KAA3BoD,EAAA,IAAA,IAAA,WHwmBV,GGvmBMS,GAD6E,IHymBnFpG,GGvmBAmG,aAFmFC,CH0mBnFpG,GGvmBAkG,UAAAG,IAAA,UAAA/F,QAAA,SAAqC3D,GHwmBjCqH,WAAW,WACPrH,EGvmBA,SADOyJ,IAhB3B,QH+nBAlL,EGhoBE4K,IHioBElK,IAAK,cACLK,MAAO,QAASkG,KACZ,MG1mBG7F,MADG6J,gBH8mBVvK,IAAK,KACLK,MAAO,QAAS4E,GG5mBjBC,EAAWnE,GH6mBNL,KG5mBJ4J,UAAAI,IAAAxF,EADoBnE,MHinBxB,OG5oBEmJ,KAgCC,IAAI/D,GAAAlH,EAAAkH,kBAAA,QAAoBA,GAAA2B,EAAApB,GHgnB3B,IG/mBKiE,OAADb,GAAqB,CHgnBrBa,OG/mBAb,GAAqB,GAAAI,GAAApC,EADzBpB,GHknBA,MG/mBOiE,QAJoBb,MHsnB5BH,kBAAkB,EAAEiB,aAAa,EAAEhB,UAAU,EAAEjE,UAAY,KAAKkF,GAAG,SAASlM,EAAQU,EAAOJ,GIhqB9F,YJmqBA,IAAIK,GAAe,WACf,QAASC,GAAiBC,EAAQC,GAC9B,IAAK,GAAIb,GAAI,EAAGA,EAAIa,EAAMN,OAAQP,IAAK,CACnC,GAAIc,GAAaD,EAAMb,EAAGc,GAAWC,WAAaD,EAAWC,YAAc,KAAMD,GAAWE,aAAe,IAAK,IAAI,SAAWF,GAAYA,EAAWG,SAAW,IAAKC,QAAOC,eAAeP,EAAQE,EAAWM,IAAKN,IAE3N,MAAO,UAAUO,EAAaC,EAAYC,GACvC,GAAID,EAAYX,EAAiBU,EAAYG,UAAWF,EAAY,IAAIC,EAAaZ,EAAiBU,EAAaE,EAAa,OAAOF,MAI/IH,QAAOC,eAAed,EAAS,cAC3BoB,MAAO,MAGX,SAASC,GAAgBC,EAAUN,GAC/B,KAAMM,YAAoBN,IAAc,CACpC,KAAM,IAAIO,WAAU,sCIjrB5B,GAAI0F,GAASvH,EAAA,WAAAuH,MACb,IAAIH,GAAgBpH,EAAA,WAAAoH,aACpB,IAAI+E,GAAiBnM,EAAA,WAAAmM,cACrB,IAAIC,GAAsBpM,EAAA,cAAAoM,mBAC1B,IAAId,GAAyBtL,EAAA,cAAAsL,sBAC7B,IAAMe,GAAWrM,EAAX,0BACN,IAAMiJ,GAAA,2BACN,IAAMxB,GAAA,SJurBN,IIrrBaR,GAAA3G,EAAA2G,cAAA,WJsrBT,QItrBSA,GACTkC,EAAAmD,EAAAC,EAAAjK,EAAAC,EAAAiK,GJsrBI7K,EAAgBI,KIvrBXkF,EJyrBLlF,MIvrBA0K,IAD8DtD,CJyrB9DpH,MIvrBA+G,SAF8DyD,CJ0rB9DxK,MIvrBA2K,UAH8DJ,CJ2rB9DvK,MIvrBA4K,OAJ8DrK,CJ4rB9DP,MIvrBA6K,QAL8DrK,CJ6rB9DR,MIvrBA4J,UAAiB,GAN6CL,EJ8rB9DvJ,MIvrBA8K,WAAkB,GAP4CT,EJ+rB9DrK,MIvrBA+K,wBAA+BvF,EAAOxF,KARwB+G,SJgsB9D/G,MIvrBAgL,OAT8D,KJisB9DhL,MIvrBAiL,kBAV8DR,CJmsB9DH,GIvrBAY,YAAqBlL,KAAA+G,SAZzB/G,MJssBApB,EIvsBSsG,IJwsBL5F,IAAK,KACLK,MAAO,QAAS4E,GIzrBjBC,EAAWnE,GJ0rBNL,KIzrBJ4J,UAAAI,IAAAxF,EADoBnE,MJ6rBpBf,IAAK,MACLK,MAAO,QAAS8E,GI1rBhBD,EAAWnE,GJ2rBP,MI1rBGL,MAAA4J,UAAAuB,OAAA3G,EADcnE,MJ8rBrBf,IAAK,WACLK,MAAO,QAAS0E,GI3rBXG,GJ4rBD,MI3rBGxE,MAAA4J,UAAAwB,YADS5G,MJ+rBhBlF,IAAK,SACLK,MAAO,QAAS0L,KACZ,MI5rBGrL,MAAA4J,UADF0B,eJgsBLhM,IAAK,kBACLK,MAAO,QAAS+E,GI7rBJT,GJ8rBR,GI9rBoBsH,GAAApL,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,aAAOD,UAA0B,EJ+rBrD,II/rB+BE,GAAAF,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAWA,UAAAD,UAAW,EJisBrD,IIhsBAqL,GADqD,EAAA,IAGzDnL,EAAc,CJisBNmL,EIhsBYxL,KAAA+K,0BAAA,IADN9G,CJksBNjE,MIhsBJ8K,WAAAd,IAAAwB,EAFJnL,GJqsBI,IAGIL,KI/rBJ0K,IAAAzG,IAAqBuH,GAAAC,OAHzBF,IJmsBM,MI9rBJ9N,GJ+rBM,GI9rBJ4C,EAAc,CJ+rBNqL,EI9rBJlN,KAAAwB,KAAAwL,EADJ/N,OAEO,CJisBCuC,KI9rBJ2L,SAAAjG,EANNjI,QJysBF6B,IAAK,iBACLK,MAAO,QAASoI,GI/rBL1H,GJgsBP,MI/rBGL,MAAA8K,WAAAc,cADcvL,MJmsBrBf,IAAK,6BACLK,MAAO,QAASuE,GIhsBO2H,GJisBnB,GAAInI,GIhsBR1D,IJksBIA,MIlsBJ8K,WAAAgB,WAAA,SAA2BxM,GJmsBnB,MIlsBG8K,GAAA9K,EADXuM,KAAA7H,QAAA,SAEW1E,GJmsBHoE,EIlsBJoH,WAAAK,OAJ2B7L,QJ0sB/BA,IAAK,qBACLK,MAAO,QAASoM,KACZ,MInsBG/L,MAAA8K,WADUQ,eJusBjBhM,IAAK,WACLK,MAAO,QAASgM,GIpsBXnH,EAAWJ,GJqsBZ,GAAIL,GIpsBR/D,IJssBIA,MItsBJ4J,UAAAG,IAAAvF,GAAAR,QAAA,SAAsC3D,GJwsB9B,GItsBAmE,IAAA,cAAA,CJusBInE,EIvsBR+D,OAEO,CJusBCsD,WAAW,WACP,GItsBA3D,EAAA6F,UAAAG,IAAAvF,GAAA/F,OAAA,EAAA,CJusBI4B,EIxsBD+D,KANI,SJqtBvB9E,IAAK,gBACLK,MAAO,QAASqM,GIvsBN/H,EAAYuH,EAAYjE,EAAK0E,GJysBnC,GIvsBA5L,GAAWL,KAAA8K,WAAAf,IAFgCyB,EAAA,KAM3CnL,EAAA,CJwsBI,GIvsBAkH,GAAOiE,IAAA,GAAA,CJwsBHxL,KIvsBJkM,QAAAxG,EADJ6B,GADJ,OJ8sBImE,EIvsBJlN,KAAAwB,KAAAwL,EAAAjE,EAb+C0E,MJutB/C3M,IAAK,aACLK,MAAO,QAASwM,GIvsBT5E,EAAKtB,GJwsBRjG,KIvsBJgL,OADkB,IJysBd,IIvsBAhL,KAAAiL,kBAAwB,CJwsBpBjL,KIvsBJiL,kBAAA1D,EADwBtB,SAEjBjG,MAFXiL,sBJgtBA3L,IAAK,UACLK,MAAO,QAASyM,KACZ,OI1sBI7L,MAAOP,KAAA4K,OAAapK,OAAQR,KAD9B6K,YJ8sBNvL,IAAK,UACLK,MAAO,QAASgF,GI5sBZ0H,EAAUC,GJ6sBVtM,KI5sBJ4K,OAAcvF,EAAAgH,EAAwBrM,KADb4K,OJ8sBrB5K,MI5sBJ6K,QAAexF,EAAAiH,EAAyBtM,KAFf6K,QJ+sBrB7K,MI5sBJ0K,IAAA6B,aAAA,QAA+BvM,KAHN4K,OJgtBrB5K,MI5sBJ0K,IAAA6B,aAAA,SAAgCvM,KAJP6K,YJmtBzBvL,IAAK,WACLK,MAAO,QAASiF,KACZ,MI9sBG5E,MADA4K,UJktBPtL,IAAK,WACLK,MAAO,QAAS6M,GIhtBXH,GJitBDrM,KIhtBJ2E,QAAA0H,EAAuBrM,KADR6K,YJotBfvL,IAAK,YACLK,MAAO,QAASkF,KACZ,MIltBG7E,MADC6K,WJstBRvL,IAAK,YACLK,MAAO,QAAS8M,GIptBVH,GJqtBFtM,KIptBJ2E,QAAa3E,KAAA4K,OADI0B,MJwtBjBhN,IAAK,aACLK,MAAO,QAAS6I,KACZ,MIttBGxI,MADE+G,YJ0tBTzH,IAAK,cACLK,MAAO,QAAS8I,KACZ,MIxtBGzI,MADG2K,aJ4tBVrL,IAAK,UACLK,MAAO,QAASyI,KACZ,MI1tBGpI,MADDgL,UJ8tBN1L,IAAK,UACLK,MAAO,QAASgI,KACZ3H,KI7tBEqL,QJ8tBFrL,MI9tBE+L,oBJ+tBFzB,GI5tBJoC,mBAA4B1M,KAHtB+G,SJguBF,II5tBA/G,KAAA0K,IAAAiC,cAAwB,CJ6tBpB3M,KI5tBJ0K,IAAAiC,cAAAC,YAAmC5M,KADvC0K,SJkuBJ,OIt3BSxF,KA0Jb,SAAAwG,GAAAF,EAAAjE,EAAA0E,GJguBI,GAAIY,GI/tBJ7M,IJiuBA0H,YAAW,WACP,GIjuBIrH,GAAWwM,EAAA/B,WAAAf,IADFyB,EJmuBb,IIjuBAnL,EAAc,CJkuBVwM,EIjuBA/B,WAAAK,OADUK,EJmuBVnL,GIjuBAkH,EAJG0E,KADf,GAUA7M,OAAAC,eAAA6F,EAAA,uBJkuBI/F,SIjuBA,MJkuBAD,aIjuBA,MJkuBAS,MIpuBJuH,GAgBA+C,QAAA/C,GAAA,SAA8BsD,EAAAsC,EAAAC,EAAAvB,EAAA/D,EAAAxB,GJkuB1B,GIjuBIpG,GAAWyK,EAAA0C,gBADmExC,EJmuBlF,KIjuBI3K,EAAJ,MJkuBA,IIjuBIkN,IAAA,YAA0B,CJkuB1BlN,EIjuBAsM,WAAA1E,EADJxB,OAEO,CJkuBH,GIjuBI6G,IAAA,QAAoB,CJkuBpBjN,EIjuBAmM,cAAAe,EAAAvB,EAAA/D,EADJxB,OAEO,CJkuBHpG,EIjuBA8L,SAAAoB,EATkB9G,QJ+uB3BgH,0BAA0B,EAAE/C,aAAa,EAAEhB,UAAU,IAAIgE,GAAG,SAASjP,EAAQU,EAAOJ,GK96BvF,YAEA,IAAI8L,GAAsBpM,EAAA,cAAAoM,mBAC1B,IAAI8C,GAAY,GAAZ9C,EAEJ,IAAM+C,KACNhO,QAAAC,eAAA+N,EAAA,eLg7BIjO,SK/6BA,MLg7BAD,aK/6BA,MLg7BAS,MAAO,QAASA,GK/6BT0N,EAAAxN,GLg7BHsN,EK/6BAnD,IAAAqD,EAJRxN,KAQAT,QAAAC,eAAA+N,EAAA,mBLg7BIjO,SK/6BA,MLg7BAD,aK/6BA,MLg7BAS,MAAO,QAASA,GK/6BT0N,GLg7BH,MK/6BOF,GAAApD,IAJfsD,KAQAjO,QAAAC,eAAA+N,EAAA,sBLg7BIjO,SK/6BA,MLg7BAD,aK/6BA,MLg7BAS,MAAO,QAASA,GK/6BT0N,GLg7BH,MK/6BOF,GAAAhC,OAJfkC,KAQA1O,GAAAJ,QAAA6O,ILi7BGlD,aAAa,IAAIoD,GAAG,SAASrP,EAAQU,EAAOJ,GM/8B/C,YNk9BA,IAAIK,GAAe,WACf,QAASC,GAAiBC,EAAQC,GAC9B,IAAK,GAAIb,GAAI,EAAGA,EAAIa,EAAMN,OAAQP,IAAK,CACnC,GAAIc,GAAaD,EAAMb,EAAGc,GAAWC,WAAaD,EAAWC,YAAc,KAAMD,GAAWE,aAAe,IAAK,IAAI,SAAWF,GAAYA,EAAWG,SAAW,IAAKC,QAAOC,eAAeP,EAAQE,EAAWM,IAAKN,IAE3N,MAAO,UAAUO,EAAaC,EAAYC,GACvC,GAAID,EAAYX,EAAiBU,EAAYG,UAAWF,EAAY,IAAIC,EAAaZ,EAAiBU,EAAaE,EAAa,OAAOF,MAI/IH,QAAOC,eAAed,EAAS,cAC3BoB,MAAO,MAGX,SAASC,GAAgBC,EAAUN,GAC/B,KAAMM,YAAoBN,IAAc,CACpC,KAAM,IAAIO,WAAU,sCAI5B,GMp+BayJ,GAAAhL,EAAAgL,uBAAA,WNq+BT,QMr+BSA,KNs+BL3J,EAAgBI,KMt+BXuJ,ENw+BLvJ,MMt+BAuN,eNy+BJ3O,EM3+BS2K,IN4+BLjK,IAAK,MACLK,MAAO,QAASqK,GMz+BfqD,EAAI1N,GN0+BD,IMz+BCK,KAAAuN,YAADF,GAAuB,CN0+BnBrN,KMz+BJuN,YAAAF,MN2+BA,GMz+BArN,KAAAuN,YAAAF,GAAA/J,QAAA3D,MAAwC,EAAA,CN0+BpCK,KMz+BJuN,YAAAF,GAAAG,KADJ7N,ON8+BAL,IAAK,MACLK,MAAO,QAASoK,GM3+BfsD,GN4+BG,MM3+BGrN,MAAAuN,YAAAF,UN8+BP/N,IAAK,aACLK,MAAO,QAASmM,GM7+BRxE,GN8+BJ,MM7+BGlI,QAAAqO,KAAYzN,KAAZuN,aAAAnK,OADUkE,MNi/BjBhI,IAAK,cACLK,MAAO,QAAS+N,GM/+BP/N,GNg/BL,GAAI+D,GM/+BR1D,INi/BI,IAAIyN,GMj/BGrO,OAAAqO,KAAYzN,KAAZuN,aAAAnK,OAAA,SAAqC9D,GNk/BxC,MMj/BGoE,GAAA6J,YAAAjO,GAAAgE,QAAA3D,MAFK,GNs/BZ,OMt/BY8N,MNy/BhBnO,IAAK,SACLK,MAAO,QAASwL,GMn/Bb7L,EAAKK,GNo/BJ,IMn/BCK,KAAAuN,YAADjO,GAAA,CAAJ,ONu/BI,GMr/BAqO,GAAQ3N,KAAAuN,YAAAjO,GAAAgE,QAHG3D,EN0/BX,IMr/BAgO,EAAA,EAAA,CAAJ,ONw/BI,MMv/BG3N,MAAAuN,YAAAjO,GAAAsO,OAAAD,EANQ,MNggCfrO,IAAK,cACLK,MAAO,QAASyL,GMz/BPiC,GN0/BL,GMz/BAQ,GAAM7N,KAAAuN,YADGF,SAENrN,MAAAuN,YAFMF,EN4/BT,OM5/BSQ,MN+/BbvO,IAAK,gBACLK,MAAO,QAASiM,GM3/BLjM,GN4/BP,GAAIoE,GM3/BR/D,IN6/BI,IM7/BAyN,GAAOzN,KAAA0N,YADO/N,EN+/Bd,OM7/BG8N,GAAAK,IAAA,SAASxO,GN8/BR,MM7/BGyE,GAAAoH,OAAA7L,EAHOK,QNogClBL,IAAK,YACLK,MAAO,QAAS2L,KACZ,GM//BAuC,GAAM7N,KADFuN,WNigCJvN,MM//BJuN,cNggCI,OMlgCIM,MNqgCRvO,IAAK,OACLK,MAAO,QAASoO,KACZ,MMjgCG3O,QAAAqO,KAAYzN,KAAZuN,aADJ9O,UNsgCP,OMvjCS8K,KN0jCb,IMpgCac,GAAA9L,EAAA8L,oBAAA,WNqgCT,QMrgCSA,KNsgCLzK,EAAgBI,KMtgCXqK,ENwgCLrK,MMtgCAuN,eNygCJ3O,EM3gCSyL,IN4gCL/K,IAAK,MACLK,MAAO,QAASqK,GMzgCfqD,EAAI1N,GN0gCDK,KMzgCJuN,YAAAF,GADY1N,KN6gCZL,IAAK,MACLK,MAAO,QAASoK,GM3gCfsD,GN4gCG,MM3gCGrN,MAAAuN,YADFF,MN+gCL/N,IAAK,aACLK,MAAO,QAASmM,GM7gCRxE,GN8gCJ,MM7gCGlI,QAAAqO,KAAYzN,KAAZuN,aAAAnK,OADUkE,MNihCjBhI,IAAK,cACLK,MAAO,QAAS+N,GM/gCP/N,GNghCL,GAAIkN,GM/gCR7M,INihCI,IAAIyN,GMjhCGrO,OAAAqO,KAAYzN,KAAZuN,aAAAnK,OAAA,SAAqC9D,GNkhCxC,MMjhCGuN,GAAAU,YAAAjO,KAFKK,GNshCZ,OMthCY8N,MNyhChBnO,IAAK,SACLK,MAAO,QAASwL,GMnhCZkC,GNohCA,GMnhCAQ,GAAM7N,KAAAuN,YADFF,SAEDrN,MAAAuN,YAFCF,ENshCJ,OMthCIQ,MNyhCRvO,IAAK,gBACLK,MAAO,QAASiM,GMrhCLjM,GNshCP,GAAIqO,GMrhCRhO,INuhCI,IMvhCAyN,GAAOzN,KAAA0N,YADO/N,ENyhCd,OMvhCG8N,GAAAK,IAAA,SAASxO,GNwhCR,MMvhCG0O,GAAA7C,OAHO7L,QN8hClBA,IAAK,YACLK,MAAO,QAAS2L,KACZ,GMzhCAuC,GAAM7N,KADFuN,WN2hCJvN,MMzhCJuN,cN0hCI,OM5hCIM,MN+hCRvO,IAAK,OACLK,MAAO,QAASoO,KACZ,MM3hCG3O,QAAAqO,KAAYzN,KAAZuN,aADJ9O,UNgiCP,OMpkCS4L,WNukCP4D,GAAG,SAAShQ,EAAQU,EAAOJ,GO/nCjC,YPkoCAa,QAAOC,eAAed,EAAS,cAC3BoB,MAAO,MAEXpB,GOnoCgBiH,OAAAA,CPooChBjH,GO7nCgB4G,KAAAA,CP8nChB5G,GO1nCgB6G,gBAAAA,CP2nChB7G,GO3mCgB+G,oBAAAA,CP4mChB/G,GOlmCgB8G,cAAAA,CPmmChB9G,GOllCgB6L,eAAAA,CPmlChB7L,GO/kCgBoL,YAAAA,CA1DT,SAAAnE,GAAA0I,GP2oCH,GO1oCIC,IADuB,CP4oC3B,OAAO,UAAUhQ,GACb,MO1oCU+P,GAAA,OAHXC,GAOA,QAAAhJ,MAIA,QAAAC,GAAAgJ,EAAAC,EAAAC,GP0oCH,GOxoCI1H,GAAAc,WAAA,WP0oCA2G,EO1oC2BlJ,CAANmJ,MAFgCF,EPgpCzD,OAAO,YACHG,aOxoCe3H,EPyoCfyH,GOvoCAG,MAAAxO,KAXDG,YAgBA,QAAAmF,GAAAmE,EAAA4D,GPuoCH,GOvoC4CoB,GAAAtO,UAAA1B,QAAA,GAAA0B,UAAA,KAAAC,UAAe,MAAAD,UAAO,EPyoClE,IOxoCIuO,GAAM9F,SAAA+F,cADwD,MP0oClED,GOxoCArB,GAFkEA,CP2oClE,IOxoCAoB,EAAkB,CPyoCdhF,EOxoCAmF,UADJ,GP2oCAnF,EOxoCAoF,YANkEH,EP+oClE,OO/oCGA,GAUA,QAAArJ,GAAAyJ,EAAAC,GPyoCH,OOxoCQC,MAAMC,WAAPH,KAA8BI,SAA9BJ,IAAkDA,EAAA,EAAlDA,EADJC,EAIP,GAAAI,GAAA,WPyoCI,GOxoCIC,OAAA1P,UAAAyP,SAA2B,MAAOC,QAAA1P,UAAtCyP,QPyoCA,OAAO,SOxoCAA,GAAAE,EAAAC,GPyoCH,GOxoCIC,GAAgBvP,KAD0BwP,UP0oC9C,IOxoCIF,IAAAlP,WAA0BkP,EAAWC,EAAA9Q,OAAA,CPyoCrC6Q,EOxoCWC,EADf9Q,OP2oCA6Q,GOxoCYD,EALkC5Q,MP8oC9C,IOxoCIgR,GAAYF,EAAAjM,QAAA+L,EAN8BC,EP+oC9C,OOxoCOG,MAAc,GAAMA,IAT/BH,KAaG,SAAAlF,GAAAsF,EAAAC,GPyoCH,MOxoCOR,GAAA3Q,KAAAkR,EADJC,GAIA,QAAAhG,GAAAvC,GP0oCHA,EOxoCAwI,MAAAN,SAF4B,UP2oC5BlI,GOxoCAwI,MAAAC,KAH4B,MP4oC5BzI,GOxoCAwI,MAAAE,IAJ4B,MP6oC5B1I,GOxoCAwI,MAAArP,MAL4B,KP8oC5B6G,GOxoCAwI,MAAApP,OANG,YPipCDuP,GAAG,SAAS9R,EAAQU,EAAOJ,GQ7sCjC,YAEA,IAAAyR,IACA,mBACA,SACA,UACA,SACA,SACA,WACA,UACA,WACA,WACA,aACA,YACA,cAGA,IAAA7L,IACA,WACA,YACA,YACA,YACA,yBACA,eACA,iBACA,mBACA,mBACA,wBACA,iBACA,eACA,eACA,uBACA,kBACA,uBACA,kBACA,cACA,gBACA,yBACA,iBACA,cACA,WACA,YACA,QACA,UAGA,IAAA8L,IACA,cACA,aACA,cACA,gBACA,sBACA,qBACA,gBACA,cACA,kBACA,aAGA,IAAAC,IACA,cAqBA,SAAAnQ,GAAAoQ,EAAA/I,EAAAgJ,IASArQ,EAAAL,UAAAO,iBAAA,SAAAoQ,EAAAhQ,IAaAN,GAAAL,UAAAY,OAAA,SAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAE,EAAAR,IAOAN,GAAAL,UAAAsB,QAAA,SAAAX,IAOAN,GAAAL,UAAAuB,OAAA,SAAAZ,IAOAN,GAAAL,UAAA4B,OAAA,SAAAjB,IAOAN,GAAAL,UAAAqB,SAAA,SAAAR,EAAAC,EAAAC,EAAAJ,IAOAN,GAAAL,UAAAwB,QAAA,SAAAb,IAOAN,GAAAL,UAAAyB,SAAA,SAAAd,IAOAN,GAAAL,UAAA0B,SAAA,SAAAf,IAOAN,GAAAL,UAAA2B,WAAA,SAAAhB,IASAN,GAAAL,UAAA4Q,UAAA,SAAAlM,EAAAkD,EAAAiJ,IAQAxQ,GAAAL,UAAA8Q,YAAA,SAAApM,EAAAkD,IASAvH,GAAAL,UAAA6B,YAAA,SAAAlB,IAOAN,GAAAL,UAAA8B,WAAA,SAAAnB,IAOAN,GAAAL,UAAA+B,YAAA,SAAApB,IAOAN,GAAAL,UAAAgC,cAAA,SAAArB,IAOAN,GAAAL,UAAAiC,oBAAA,SAAAtB,IAOAN,GAAAL,UAAAkC,mBAAA,SAAAvB,IAOAN,GAAAL,UAAAmC,cAAA,SAAAxB,IAOAN,GAAAL,UAAAsC,YAAA,SAAA3B,IAOAN,GAAAL,UAAAuC,gBAAA,SAAA5B,IAOAN,GAAAL,UAAAwC,WAAA,SAAA7B,IAQAN,GAAAL,UAAAoC,YAAA,SAAAgD,EAAAzE,IAEAoQ,GAAA1Q,EAAA,UAAAiQ,EACAS,GAAA1Q,EAAA,UAAAkQ,EACAQ,GAAA1Q,EAAA,UAAAmQ,EACAO,GAAA1Q,EAAA,SAAAoE,EAGA,IAAAuM,GAAAV,EAAA5M,OAAA,SAAAuN,GACA,OAAA,UAAArN,QAAAqN,MAAA,GAGAF,GAAA1Q,EAAA,sBAAA,QAAA6Q,GAAAT,GACA,GAAAlE,GAAAyE,EAAAG,MAAA,SAAAvR,GACA,aAAA6Q,GAAA7Q,KAAA,YAEA,OAAA2M,IAGAtN,GAAAJ,QAAAwB,CAEA,SAAA0Q,GAAAK,EAAAC,EAAApR,GACAP,OAAAC,eAAAyR,EAAAC,GACA5R,SAAA,MACAD,aAAA,MACAS,MAAAA,URmtCMqR,IAAI,SAAS/S,EAAQU,EAAOJ,GS5+ClC,YAEA,IAAAwB,GAAA9B,EAAA,iBACA,IAAAgT,GAAAhT,EAAA,eACA,IAAA2S,GAAA7Q,EAAA6Q,mBACA,IAAAtH,GAAArL,EAAA,UACA,IAAA+R,GAAAjQ,EAAAiQ,OACA,IAAAtK,GAAA,SACA,IAAAwL,GAAA,aACA,IAAAC,GAAApR,EAAAoE,OAAAf,OAAA,SAAAgB,GACA,MAAAA,IAAA8M,GAmBA,SAAA3N,GAAA6N,EAAAhK,EAAAgJ,EAAAiB,GACArR,KAAAsR,SAAAV,EAAAQ,EACA,IAAApR,KAAAsR,SAAA,CACAtR,KAAAuR,UAAAH,CACApR,MAAA0K,IAAAtD,CACApH,MAAAwR,SAAApB,CACApQ,MAAAyR,QAAAJ,CACArR,MAAA0R,aAAA,GAAAT,EACAU,GAAAnT,KAAAwB,OAIAuD,EAAA7D,UAAAN,OAAA2D,OAAAhD,EAAAL,UAOA6D,GAAA7D,UAAAkS,eAAA,QAAAA,KACA,MAAA5R,MAAAsR,SAGAvR,GAAAiQ,QAAAhM,QAAA,SAAA2M,GAEA,GAAAkB,IACA,YACA,cACA,SAGA,IAAAA,EAAAvO,QAAAqN,MAAA,EAAA,MAEApN,GAAA7D,UAAAiR,GAAA,WACA,GAAAmB,GAAA/R,EAAAL,UAAAiR,GAAAlS,MAGA,IAAA8M,GAAAwG,MAAArS,UAAAsS,MAAAxT,KAAA2B,UACA,IAAAE,GAAAyR,IAAAvG,EAAA9M,OAAA8M,EAAA0G,MAAA7R,SAEAsH,YAAA,WACA,GAAAuE,GAAAxE,EAAA,IACA,KACAwE,EAAAjM,KAAAuR,UAAAZ,GAAAnC,MAAAxO,KAAAuR,UAAAhG,GACA,MAAA9N,GACAgK,EAAAhK,EAGAyU,EAAA7R,EAAAL,KAAA0R,aAAAjK,EAAAwE,IACAkG,KAAAnS,MAAA,KAgBAuD,GAAA7D,UAAAY,OAAA,QAAAA,GAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAE,EAAAR,GACAM,EAAAA,KACAE,GAAAyI,EAAA8I,QACAC,KAAArS,KAAA0K,IACA4H,UAAAtS,KAAAwR,UACA3Q,MAEA6G,YAAA,WACA,GAAAD,EACA,KACAzH,KAAAuR,UAAAjR,OAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAE,GACA,MAAApD,GACAgK,EAAAhK,EAGAyU,EAAA7R,EAAAL,KAAA0R,aAAAjK,IACA0K,KAAAnS,MAAA,GAUAuD,GAAA7D,UAAA4Q,UAAA,QAAAA,GAAAlM,EAAAkD,EAAAiJ,GACAvQ,KAAA0R,aAAApB,UAAAhJ,EAAAlD,EAAAmM,GAUAhN,GAAA7D,UAAA8Q,YAAA,QAAAA,GAAApM,EAAAkD,GACAtH,KAAA0R,aAAAlB,YAAAlJ,EAAAlD,GAIAb,GAAA7D,UAAA6E,GAAAhB,EAAA7D,UAAA4Q,SACA/M,GAAA7D,UAAA+E,IAAAlB,EAAA7D,UAAA8Q,WAEAzQ,GAAAkQ,QAAAjM,QAAA,SAAAuO,GACAhP,EAAA7D,UAAA6S,GAAA,SAAAlS,GACAqH,WAAA,WAEA,GAAAuE,GAAAxE,EAAA,IACA,KACAwE,EAAAjM,KAAAuR,UAAAgB,KACA,MAAA9U,GACAgK,EAAAhK,EAGAyU,EAAA7R,EAAAL,KAAA0R,aAAAjK,EAAAwE,IACAkG,KAAAnS,MAAA,KAUAuD,GAAA7D,UAAAoC,YAAA,QAAAA,GAAAgD,EAAAzE,GACAqH,WAAA,WAEA,GAAAuE,GAAAxE,EAAA,IACA,KACAzH,KAAAuR,UAAAzP,YAAAgD,EACAmH,GAAAjM,KAAAuR,UAAAvP,cACA,MAAAvE,GACAgK,EAAAhK,EAGA,IAAAgK,EAAA,CACAA,EAAA6B,EAAAkJ,SAAAvG,IAAAnH,EAAA,2BAAAA,GAEAoN,EAAA7R,EAAAL,KAAA0R,aAAAjK,EAAAwE,IACAkG,KAAAnS,MAAA,GAGAuD,GAAA7D,UAAAoE,SAAA,QAAA6D,KACA3H,KAAAiB,QACAjB,MAAA0R,aAAAe,iBAGA,SAAAd,KAIAR,EAAAnN,QAAA,SAAAI,GACApE,KAAAuR,UAAAjB,UAAAoC,EAAAP,KAAAnS,KAAAoE,GAAAA,IACA+N,KAAAnS,MAIAA,MAAAuR,UAAAjB,UAAAqC,EAAAR,KAAAnS,MAAAkR,EAIA,IAAAlR,KAAAwR,SAAA,CACA,GAAAoB,GAAA5S,KAAAyR,QAAAoB,gBAAAD,eACA,IAAAE,GAAA9S,KAAAwR,QACAoB,GAAAG,iBAAA,QAAA,SAAAtV,GACA,GAAAA,EAAAqB,SAAA8T,EAAA,CACAE,EAAAE,YAMA,QAAAL,GAAArK,EAAA+E,EAAA4F,GACAjT,KAAA0R,aAAAwB,YAAAhC,GAAA5I,IAAAA,EAAA+E,GAAAA,EAAA4F,cAAAA,IAGA,QAAAP,GAAAtO,GAGApE,KAAA0R,aAAAxF,QAAA9H,EAAA2N,MAAArS,UAAAsS,MAAA7R,UAAA,IAGA,QAAA+R,GAAA7R,EAAA8S,EAAA1L,EAAAwE,GACA,GAAA5L,EAAA,CACAA,EAAAoH,EAAAwE,OACA,IAAAxE,EAAA,CACA0L,EAAAjH,QAAAxG,EAAA+B,IAIA9I,EAAAJ,QAAAgF,ITg/CGwB,iBAAiB,EAAEqO,eAAe,GAAGlK,UAAU,KAAKmK,IAAI,SAASpV,EAAQU,EAAOJ,GUntDnF,YAEA,IAAA+K,GAAArL,EAAA,UACA,IAAAuH,GAAA8D,EAAA9D,OAAA,cACA,IAAAjC,GAAAtF,EAAA,gBAEA,IAAAqV,GAAA,kBACA,mBACA,sCACA,kEACA,kEACA,kCACA,2FACA,YACA,UACA,SAEA,IAAAC,GAAA,WAkBA,SAAAC,GAAApM,EAAAgJ,EAAAqD,EAAA/M,GACA+M,EAAAA,KAEAzT,MAAA0T,IAAAlO,GACAxF,MAAA4D,WAAA,KAEA5D,MAAA2T,gBAAArK,EAAAsK,kBAAAxM,EAAA,MACApH,MAAAwR,SAAApB,CACApQ,MAAA6T,cAAAnN,IAAAE,QAAA,IAEA5G,MAAA8T,iBACAC,SAAAN,EAAAM,UAAAT,EACAU,aAAAP,EAAAO,kBAQAR,EAAA9T,UAAAiI,QAAA,QAAAA,KACA,GAAA3H,KAAA4D,WAAA,CACA,OAEA5D,KAAA4D,WAAA,IACAqQ,GAAAzV,KAAAwB,MAQAwT,GAAA9T,UAAA4E,YAAA,QAAAA,KACA,MAAAtE,MAAA4D,WASA4P,GAAA9T,UAAAuI,WAAA,QAAAA,GAAAC,EAAA7H,GACA8H,EAAA3J,KAAAwB,KACAiU,GAAAzV,KAAAwB,KACA,IAAAkU,GAAAlU,IAEA,IAAAmU,GAAA7K,EAAA8K,wBACApU,KAAA2T,gBACA3T,KAAA8T,gBAAAC,SACAzK,EAAA8I,QACAiC,aAAAnM,EACAoM,SAAAtU,KAAAuU,QACAC,OAAAC,KACAzU,KAAA8T,gBAAAE,cAGAhU,MAAA0U,OAAAP,CAEAnU,MAAA2U,QAAArL,EAAAlE,gBACApF,KAAA6T,cAAAjN,QACAgO,EAAAzC,KAAAnS,MACAsO,EAAA6D,KAAAnS,MAGAiK,QAAA8I,iBAAA,UAAA/S,KAAA2U,QAEA,SAAAC,GAAAnX,GAGA,GAAAA,EAAA+W,SAAAC,IAAA,MACA,IAAAxI,GAAA4I,KAAAC,MAAArX,EAAAwI,KAGA,IAAAgG,EAAAoB,KAAA6G,EAAAK,QAAA,MAEA,IAAAQ,GAAAtN,EAAAuN,CACA,KAAAd,EAAAQ,OAAAO,cAAA,CAEAxN,EAAA,gDAEA,CACAuN,EAAAd,EAAAQ,OAAAO,cAAAC,UACAzN,GAAA6B,EAAAkJ,eAAAwC,KAAA,WAAA,mDAGA,IAAAvN,EAAA,CACA,GAAA0N,GAAAjB,EAAAQ,OAAAO,cAAArM,SAAAwM,cAAA,cACAL,GAAA,GAAAxR,GAAAyR,IAAAG,EAAAjB,EAAA1C,SAAA0C,EAAAQ,OACAK,GAAAzE,UAAAiD,EAAA8B,EAAAlD,KAAA+B,GACAzM,GAAA6B,EAAAkJ,SAAAuC,EAAAnD,iBAAA,2DAGAsC,EAAAlM,QAAA+M,CACAO,GAAA9W,KAAA0V,EACA7T,GAAAoH,EAAAA,EAAA,KAAAsN,EAGA,OAAA,MAGA,QAAAzG,KACAjO,EAAA,UAAA,OAQAmT,GAAA9T,UAAA6I,aAAA,QAAAA,KACA0L,EAAAzV,KAAAwB,MAQAwT,GAAA9T,UAAA6U,MAAA,WACA,MAAAvU,MAAA0T,IASA,SAAA6B,GAAAjW,GACA,GAAA8H,GAAApH,KAAAV,EACA,IAAA8H,EAAA,CACAA,EAAA+D,eACAnL,MAAAV,IAIA,QAAA+V,KACAG,EAAAhX,KAAAwB,YACAA,MAAAgI,QAGA,QAAAiM,KACAuB,EAAAhX,KAAAwB,KACAyV,GAAAjX,KAAAwB,MAGA,QAAAwV,KACAD,EAAA/W,KAAAwB,KAAA,SACAsV,GAAA9W,KAAAwB,MAOA,QAAAsV,KACA,GAAAtV,KAAA2U,QAAA,CACA1K,OAAAyL,oBAAA,UAAA1V,KAAA2U,QACArL,GAAAqM,qBAAA3V,KAAA2U,eACA3U,MAAA2U,SAKA,QAAAc,KACA,GAAAzV,KAAAgI,QAAA,CACAhI,KAAAgI,QAAA/G,eACAjB,MAAAgI,SAQA,QAAAG,KACA,GAAAnI,KAAA4D,WAAA,CACA,KAAA,IAAAxF,OAAA,wCAIA,QAAAqW,KACA,GAAAxK,OAAA2L,SAAApB,OAAA,CACA,MAAAvK,QAAA2L,SAAApB,WAEA,CACA,MAAAvK,QAAA2L,SAAAC,SAAA,KACA5L,OAAA2L,SAAAE,UACA7L,OAAA2L,SAAAG,KAAA,IAAA9L,OAAA2L,SAAAG,KAAA,KAIApX,EAAAJ,QAAAiV,CACAvJ,QAAAuJ,iBAAAA,IVutDGzK,gBAAgB,GAAGG,UAAU,KAAK8M,IAAI,SAAS/X,EAAQU,EAAOJ,GW77DjE,YAEA,SAAA0S,KACAjR,KAAA0R,gBAGAT,EAAAvR,UAAA4Q,UAAA,QAAAA,GAAAhJ,EAAA9C,EAAA+L,GACA,IAAAvQ,KAAAiW,kBAAA3O,EAAA9C,GAAA,CACAxE,KAAA+J,IAAAvF,GAAAgJ,MAAAlG,QAAAA,EAAAiJ,QAAAA,EAAA/L,UAAAA,KAIAyM,GAAAvR,UAAA8Q,YAAA,QAAAA,GAAAlJ,EAAA9C,GACAxE,KAAA0R,aAAAlN,GAAAxE,KAAA+J,IAAAvF,GAAApB,OAAA,SAAA8S,GACA,MAAA5O,KAAA4O,EAAA5O,UAIA2J,GAAAvR,UAAA+S,eAAA,QAAAA,KACAzS,KAAA0R,gBAGAT,GAAAvR,UAAAwM,QAAA,SAAA1H,EAAAyB,GACA,GAAAiO,GAAAlU,IACA,IAAAmT,GAAAnT,KAAA+J,IAAAvF,GACAiH,OAAAzL,KAAA+J,IAAA,KAEAoJ,GAAAnP,QAAA,SAAAkS,GACAxO,WAAA,WACA,GAAAwM,EAAA+B,kBAAAC,EAAA5O,QAAA4O,EAAA1R,WAAA,CACA0R,EAAA5O,QAAA9I,KAAA0X,EAAA3F,QAAAtK,KAEA,KAIAgL,GAAAvR,UAAAwT,YAAA,SAAA1O,EAAAyB,GACA,GAAAkN,GAAAnT,KAAA+J,IAAAvF,GACAiH,OAAAzL,KAAA+J,IAAA,KAEAoJ,GAAAnP,QAAA,SAAAkS,GACAA,EAAA5O,QAAA9I,KAAA0X,EAAA3F,QAAAtK,KAIAgL,GAAAvR,UAAAqK,IAAA,QAAAA,GAAAvF,GACA,IAAAxE,KAAA0R,aAAAlN,GAAA,CACAxE,KAAA0R,aAAAlN,MAEA,MAAAxE,MAAA0R,aAAAlN,GAGAyM,GAAAvR,UAAAuW,kBAAA,QAAAA,GAAA3O,EAAA9C,GACA,MAAAxE,MAAA+J,IAAAvF,GAAA2R,KAAA,SAAAD,GACA,MAAA5O,KAAA4O,EAAA5O,UAIA3I,GAAAJ,QAAA0S,OXi8DMmF,IAAI,SAASnY,EAAQU,EAAOJ,GY3/DlC,YAKA,SAAA4G,MAQA,QAAAqN,GAAA6D,EAAAhO,GACA,MAAAgO,GAAA,KAAA,GAAAjY,OAAAiK,GAGA,GAAAiO,KAMA,SAAAX,GAAAY,GACA,GAAA3P,GAAA0P,EAAAC,EACA,IAAA3P,EAAA,CACA2H,aAAA3H,SACA0P,GAAAC,IAWA,QAAAnR,GAAAgJ,EAAAC,EAAAC,GACA,GAAAjO,GAAAuG,CAEAA,GAAAc,WAAA,WACA2G,EAAAlJ,QACAyB,GAAAvG,EACAiO,MACAF,EAEA/N,GAAA,WAGA,GAAAgO,EAAAG,MAAAxO,KAAAG,WAAA,CACAwV,EAAAtV,IAIAiW,GAAAjW,GAAAuG,CAEA,OAAAvG,GAWA,QAAAuT,GAAAnK,EAAA+M,EAAAnJ,GACA,GAAAqB,GAAA9F,SAAA+F,cAAA6H,EACA,IAAAnJ,EAAAqB,EAAArB,GAAAA,CACA5D,GAAAoF,YAAAH,EACA,OAAAA,GAUA,QAAA0F,GAAA3K,EAAAsK,EAAA9N,GACA,GAAAoL,GAAAoF,EAAAhN,EAAA,KAAAxD,EAAAyQ,OACA,KAAAC,EAAAtF,EAAAuF,EAAA7C,EAAA9N,IAAA,MACA,OAAAoL,GASA,QAAAoF,GAAAhN,EAAAnB,EAAAoO,GACA,GAAAhI,GAAA9F,SAAA+F,cAAA,SACAD,GAAAmI,IAAAvO,GAAA,aACAoG,GAAAoI,YAAA,GACApI,GAAAqI,aAAA,GACArI,GAAAsI,YAAA,GACAtI,GAAAnO,MAAA,MACAmO,GAAAlO,OAAA,MACAkO,GAAAkB,MAAAN,SAAA,UACAZ,GAAAkB,MAAAC,KAAA,GACAnB,GAAAkB,MAAAE,IAAA,GACApB,GAAAkB,MAAAqH,OAAA,KACAvI,GAAAkB,MAAAsH,QAAA,KACAxI,GAAAkB,MAAAuH,OAAA,MAEA,IAAAT,EAAA,CACAhI,EAAAkB,MAAA8G,OAAAA,EAGAhI,EAAAnC,aAAA,YAAA,KACA9C,GAAAmF,UAAA,EACAnF,GAAAoF,YAAAH,EACA,OAAAA,GASA,QAAAkI,GAAA7C,EAAA9N,GACA7G,OAAAqO,KAAAxH,GAAAjC,QAAA,SAAA1E,GACA,GAAAK,SAAAA,KAAA,SAAAkV,KAAAuC,UAAAnR,EAAA3G,IAAA2G,EAAA3G,EACAyU,GAAAA,EAAAsD,QAAA,GAAAC,QAAA,KAAAhY,EAAA,KAAA,KAAAK,IAEA,OAAAoU,GASA,QAAA4C,GAAAY,EAAAC,GACA,GAAAC,GAAAF,EAAAtC,eAAAsC,EAAAtC,cAAArM,QACA,KAAA6O,EAAA,MAAA,MAEAA,GAAAC,MAAAF,EAEA,OAAA,MAUA,QAAApF,GAAAuF,EAAAC,GACAxY,OAAAqO,KAAAmK,GAAA5T,QAAA,SAAA1E,GACAqY,EAAArY,GAAAsY,EAAAtY,IAEA,OAAAqY,GASA,QAAAnS,GAAA0I,GACA,GAAAC,IAAA,CACA,OAAA,YACA,MAAAD,GAAA,OAAAC,GAIAxP,EAAAJ,SACA4G,KAAAA,EACAqN,SAAAA,EACAmD,qBAAAA,EACAvQ,gBAAAA,EACAwO,kBAAAA,EACAQ,wBAAAA,EACAqC,aAAAA,EACAG,eAAAA,EACAD,iBAAAA,EACAvE,OAAAA,EACA5M,OAAAA,QZggEMqS,IAAI,SAAS5Z,EAAQU,EAAOJ,IaprElC,SAAAuZ,EAAAC,GACA,SAAAC,UAAA,YAAAA,OAAAC,IAAA,CAEAD,OAAAD,OACA,UAAApZ,KAAA,UAAAA,EAAAJ,QAAA,CAEAI,EAAAJ,QAAAwZ,QACA,CAEAD,EAAA7S,UAAA8S,OAEA/X,KAAA,WAEA,GAAAkY,GAAA,YACAC,EAAA,SACAC,EAAA,kBACAC,EAAA,gCACAC,EAAA,gCACAC,EAAA,oBACAC,EAAA,qBAEAC,EAAAxO,OACAyO,EAAA9P,SACA+P,EAAAC,UAEAC,EAAA,MACAC,KACAC,KACAC,KACAC,KACAC,EACAC,EACAC,EACAC,EACAC,EAAA,MACAC,EAAA,MACAC,EACAC,EACAC,EAAA,KACAC,EAAA,MAMAC,EAAA,WACA,GAAAC,SAAAnB,GAAAoB,iBAAA5B,SAAAQ,GAAAqB,uBAAA7B,SAAAQ,GAAA/J,gBAAAuJ,EACAna,EAAA4a,EAAAqB,UAAAC,cACAC,EAAAvB,EAAAwB,SAAAF,cACAG,EAAAF,EAAA,MAAAG,KAAAH,GAAA,MAAAG,KAAAtc,GACAuc,EAAAJ,EAAA,MAAAG,KAAAH,GAAA,MAAAG,KAAAtc,GACAwc,EAAA,SAAAF,KAAAtc,GAAAkR,WAAAlR,EAAAsZ,QAAA,8BAAA,OAAA,MACAmD,EAAA7B,EAAA8B,UAAA,8BACAC,GAAA,EAAA,EAAA,GACAC,EAAA,IACA,UAAAhC,GAAAiC,UAAA1C,SAAAS,GAAAiC,QAAAxC,KAAAD,EAAA,CACAwC,EAAAhC,EAAAiC,QAAAxC,GAAAyC,WAEA,IAAAF,UAAAhC,GAAAmC,YAAA5C,GAAAS,EAAAmC,UAAAxC,IAAAK,EAAAmC,UAAAxC,GAAAyC,eAAA,CACAlC,EAAA,IACA2B,GAAA,KACAG,GAAAA,EAAAtD,QAAA,qBAAA;AACAqD,EAAA,GAAAM,EAAAL,EAAAtD,QAAA,aAAA,MACAqD,GAAA,GAAAM,EAAAL,EAAAtD,QAAA,iBAAA,MACAqD,GAAA,GAAA,WAAAL,KAAAM,GAAAK,EAAAL,EAAAtD,QAAA,oBAAA,OAAA,OAGA,UAAAoB,GAAAwC,gBAAA/C,EAAA,CACA,IACA,GAAAla,GAAA,GAAAid,eAAA5C,EACA,IAAAra,EAAA,CACA2c,EAAA3c,EAAAkd,YAAA,WACA,IAAAP,EAAA,CACAH,EAAA,IACAG,GAAAA,EAAAQ,MAAA,KAAA,GAAAA,MAAA,IACAT,IAAAM,EAAAL,EAAA,IAAAK,EAAAL,EAAA,IAAAK,EAAAL,EAAA,OAIA,MAAAld,KAEA,OAAA2d,GAAAvB,EAAAwB,GAAAX,EAAAY,GAAAf,EAAAC,GAAAA,EAAA/B,IAAA2B,EAAAE,IAAAA,MAQAiB,EAAA,WACA,IAAA3B,EAAAwB,GAAA,CAAA,OACA,SAAA1C,GAAA8C,aAAAtD,IAAAQ,EAAA8C,aAAA,YAAA9C,EAAA8C,aAAA,sBAAA9C,GAAA8C,aAAAtD,IAAAQ,EAAAqB,qBAAA,QAAA,IAAArB,EAAA7P,MAAA,CACA4S,IAEA,IAAAnC,EAAA,CACA,SAAAZ,GAAA3F,mBAAAmF,EAAA,CACAQ,EAAA3F,iBAAA,mBAAA0I,EAAA,OAEA,GAAA7B,EAAAY,GAAA,CACA9B,EAAAgD,YAAAlD,EAAA,QAAAmD,KACA,GAAAjD,EAAA8C,aAAA,WAAA,CACA9C,EAAAkD,YAAApD,EAAAmD,EACAF,OAGA,IAAAhD,GAAA3I,IAAA,EACA,QAAA+L,KACA,GAAAvC,EAAA,CAAA,OACA,IACAZ,EAAA9F,gBAAAkJ,SAAA,QAEA,MAAAre,GACAiK,WAAAmU,EAAA,EACA,QAEAJ,SAIA,GAAA7B,EAAA0B,GAAA,EACA,QAAAS,KACA,GAAAzC,EAAA,CAAA,OACA,IAAA,kBAAAe,KAAA3B,EAAA8C,YAAA,CACA9T,WAAAqU,EAAA,EACA,QAEAN,YAMA,SAAAA,KACA,GAAAnC,IAAA1Q,SAAAmR,qBAAA,QAAA,GAAA,CAAA,OACA,IACA,GAAArc,GAAAse,EAAArN,EAAA,OACAqN,GAAApM,MAAAqM,QAAA,MACAve,GAAAgb,EAAAqB,qBAAA,QAAA,GAAAlL,YAAAmN,EACAte,GAAAwe,WAAAtP,YAAAlP,EACAA,GAAA,IACAse,GAAA,KAEA,MAAAve,GAAA,OACA6b,EAAA,IACA,IAAA6C,GAAArD,EAAAra,MACA,KAAA,GAAAP,GAAA,EAAAA,EAAAie,EAAAje,IAAA,CACA4a,EAAA5a,MAIA,QAAAke,GAAAC,GACA,GAAA/C,EAAA,CACA+C,QAEA,CACAvD,EAAAA,EAAAra,QAAA4d,GAQA,QAAAC,GAAAD,GACA,SAAA5D,GAAA1F,mBAAAmF,EAAA,CACAO,EAAA1F,iBAAA,OAAAsJ,EAAA,WAEA,UAAA3D,GAAA3F,mBAAAmF,EAAA,CACAQ,EAAA3F,iBAAA,OAAAsJ,EAAA,WAEA,UAAA5D,GAAAiD,cAAAxD,EAAA,CACAqE,EAAA9D,EAAA,SAAA4D,OAEA,UAAA5D,GAAA+D,SAAA,WAAA,CACA,GAAAC,GAAAhE,EAAA+D,MACA/D,GAAA+D,OAAA,WACAC,GACAJ,UAGA,CACA5D,EAAA+D,OAAAH,GAWA,QAAAK,KACA,GAAAC,GAAAjE,EAAAqB,qBAAA,QAAA,EACA,IAAAjc,GAAA6Q,EAAAwJ,EACAra,GAAAyO,aAAA,QAAA,sBACAzO,GAAAyO,aAAA,OAAA+L,EACA,IAAA5a,GAAAif,EAAA9N,YAAA/Q,EACA,IAAAJ,EAAA,CACA,GAAAkf,GAAA,GACA,QAAAC,KACA,SAAAnf,GAAAwd,cAAAhD,EAAA,CACA,IACA,GAAAyC,GAAAjd,EAAAwd,YAAA,WACA,IAAAP,EAAA,CACAA,EAAAA,EAAAQ,MAAA,KAAA,GAAAA,MAAA,IACAvB,GAAAyB,IAAAL,EAAAL,EAAA,IAAAK,EAAAL,EAAA,IAAAK,EAAAL,EAAA,MAEA,MAAAld,GAGAmc,EAAAyB,IAAA,EAAA,EAAA,QAGA,IAAAuB,EAAA,GAAA,CACAA,GACAlV,YAAAmV,EAAA,GACA,QAEAF,EAAA/P,YAAA9O,EACAJ,GAAA,IACAof,aAGA,CACAA,KAMA,QAAAA,KACA,GAAAC,GAAAhE,EAAAta,MACA,IAAAse,EAAA,EAAA,CACA,IAAA,GAAA7e,GAAA,EAAAA,EAAA6e,EAAA7e,IAAA,CACA,GAAAmP,GAAA0L,EAAA7a,GAAAmP,EACA,IAAA2P,GAAAjE,EAAA7a,GAAA+e,UACA,IAAAC,IAAAC,QAAA,MAAA9P,GAAAA,EACA,IAAAuM,EAAAyB,GAAA,GAAA,EAAA,CACA,GAAA9Y,GAAAuX,EAAAzM,EACA,IAAA9K,EAAA,CACA,GAAA6a,EAAArE,EAAA7a,GAAAmf,eAAAzD,EAAA0B,IAAA1B,EAAA0B,GAAA,KAAA,CACAgC,EAAAjQ,EAAA,KACA,IAAA2P,EAAA,CACAE,EAAAC,QAAA,IACAD,GAAAK,IAAAC,EAAAnQ,EACA6P,GAAA7P,GAAAA,CACA2P,GAAAE,QAGA,IAAAnE,EAAA7a,GAAAuf,gBAAAC,IAAA,CACA,GAAAC,KACAA,GAAA1X,KAAA8S,EAAA7a,GAAAuf,cACAE,GAAApd,MAAAgC,EAAAqb,aAAA,UAAA,GACAD,GAAAnd,OAAA+B,EAAAqb,aAAA,WAAA,GACA,IAAArb,EAAAqb,aAAA,SAAA,CAAAD,EAAAE,WAAAtb,EAAAqb,aAAA,SACA,GAAArb,EAAAqb,aAAA,SAAA,CAAAD,EAAAtX,MAAA9D,EAAAqb,aAAA,SAEA,GAAAE,KACA,IAAA5D,GAAA3X,EAAAwX,qBAAA,QACA,IAAAgE,GAAA7D,EAAAzb,MACA,KAAA,GAAAuf,GAAA,EAAAA,EAAAD,EAAAC,IAAA,CACA,GAAA9D,EAAA8D,GAAAJ,aAAA,QAAA3D,gBAAA,QAAA,CACA6D,EAAA5D,EAAA8D,GAAAJ,aAAA,SAAA1D,EAAA8D,GAAAJ,aAAA,UAGAK,EAAAN,EAAAG,EAAAzQ,EAAA2P,OAEA,CACAkB,EAAA3b,EACA,IAAAya,EAAA,CAAAA,EAAAE,UAIA,CACAI,EAAAjQ,EAAA,KACA,IAAA2P,EAAA,CACA,GAAAlf,GAAA0f,EAAAnQ,EACA,IAAAvP,SAAAA,GAAAqgB,cAAAjG,EAAA,CACAgF,EAAAC,QAAA,IACAD,GAAAK,IAAAzf,CACAof,GAAA7P,GAAAvP,EAAAuP,GAEA2P,EAAAE,OAUApE,EAAA,GAAA,WACA,GAAAD,EAAA,CACA6D,QAEA,CACAI,KAIA,SAAAU,GAAAY,GACA,GAAAxgB,GAAA,KACAE,EAAAgc,EAAAsE,EAEA,IAAAtgB,GAAAA,EAAAugB,SAAAC,gBAAA,SAAA,CAEA,SAAAxgB,GAAAqgB,cAAAjG,EAAA,CACAta,EAAAE,MACA,CAOAF,EAAAE,EAAAic,qBAAA5B,GAAA,IAAAra,GAIA,MAAAF,GASA,QAAA8f,KACA,OAAAnE,GAAA6D,EAAA,YAAAxD,EAAAnB,KAAAmB,EAAAU,QAAAV,EAAA0B,IAAA1B,EAAA0B,GAAA,KAMA,QAAA2C,GAAAN,EAAAG,EAAAS,EAAAtB,GAEA,GAAA1a,GAAAuX,EAAAyE,EAGAA,GAAAC,EAAAD,EAEAhF,GAAA,IACAH,GAAA6D,GAAA,IACA5D,IAAA8D,QAAA,MAAA9P,GAAAkR,EAEA,IAAAhc,EAAA,CACA,GAAAA,EAAA8b,SAAAC,gBAAA,SAAA,CACApF,EAAAuF,EAAAlc,EACA4W,GAAA,SAEA,CACAD,EAAA3W,CACA4W,GAAAoF,EAEAZ,EAAAtQ,GAAAkL,CACA,UAAAoF,GAAApd,QAAA2X,IAAA,KAAAmC,KAAAsD,EAAApd,QAAAya,EAAA2C,EAAApd,OAAA,IAAA,CAAAod,EAAApd,MAAA,MACA,SAAAod,GAAAnd,SAAA0X,IAAA,KAAAmC,KAAAsD,EAAAnd,SAAAwa,EAAA2C,EAAAnd,QAAA,IAAA,CAAAmd,EAAAnd,OAAA,MACA,GAAAke,GAAA9E,EAAAY,GAAA,UAAA,SACAmE,EAAA,iBAAAC,mBAAAnG,EAAA7C,SAAApG,WAAA6H,QAAA,KAAA,QAAA,iBAAAqH,EAAA,eAAAE,mBAAAlG,EAAAmG,MAAA7M,MAAA,EAAA,IAAA,+BACA,UAAA8L,GAAAgB,YAAA5G,EAAA,CACA4F,EAAAgB,WAAA,IAAAH,MAEA,CACAb,EAAAgB,UAAAH,EAIA,GAAA/E,EAAAY,IAAAjY,EAAAiZ,YAAA,EAAA,CACA,GAAAuD,GAAApQ,EAAA,MACA4P,IAAA,cACAQ,GAAAxS,aAAA,KAAAgS,EACAhc,GAAA2Z,WAAA8C,aAAAD,EAAAxc,EACAA,GAAAqN,MAAAqM,QAAA,MACAgD,GAAA1c,GAEA8E,EAAAsW,EAAAG,EAAAS,IAMA,QAAAL,GAAA3b,GACA,GAAAqX,EAAAY,IAAAjY,EAAAiZ,YAAA,EAAA,CAGAjZ,EAAAqN,MAAAqM,QAAA,MACA,IAAA7U,GAAAuH,EAAA,MACApM,GAAA2Z,WAAA8C,aAAA5X,EAAA7E,EACA6E,GAAA8U,WAAAgD,aAAAT,EAAAlc,GAAA6E,EACA6X,GAAA1c,OAEA,CACAA,EAAA2Z,WAAAgD,aAAAT,EAAAlc,GAAAA,IAIA,QAAAkc,GAAAlc,GACA,GAAA4c,GAAAxQ,EAAA,MACA,IAAAiL,EAAAnB,KAAAmB,EAAAY,GAAA,CACA2E,EAAAvQ,UAAArM,EAAAqM,cAEA,CACA,GAAAwQ,GAAA7c,EAAAwX,qBAAA5B,GAAA,EACA,IAAAiH,EAAA,CACA,GAAAC,GAAAD,EAAAE,UACA,IAAAD,EAAA,CACA,GAAAE,GAAAF,EAAA5gB,MACA,KAAA,GAAAP,GAAA,EAAAA,EAAAqhB,EAAArhB,IAAA,CACA,KAAAmhB,EAAAnhB,GAAAshB,UAAA,GAAAH,EAAAnhB,GAAAmgB,WAAA,YAAAgB,EAAAnhB,GAAAshB,UAAA,GAAA,CACAL,EAAAtQ,YAAAwQ,EAAAnhB,GAAAuhB,UAAA,WAMA,MAAAN,GAGA,QAAAO,GAAApX,EAAAqX,GACA,GAAAC,GAAAjR,EAAA,MACAiR,GAAAhR,UAAA,2FAAAtG,EAAA,KAAAqX,EAAA,WACA,OAAAC,GAAAC,WAKA,QAAAxY,GAAAyY,EAAAC,EAAA1S,GACA,GAAAzP,GAAAwJ,EAAA0S,EAAAzM,EACAA,GAAAmR,EAAAnR,EAEA,IAAAuM,EAAA0B,IAAA1B,EAAA0B,GAAA,IAAA,CAAA,MAAA1d,GAEA,GAAAwJ,EAAA,CACA,GAAAtJ,GAAA8b,EAAA,GAAAjL,EAAA,OAAAA,EAAAwJ,GACA6H,EACAC,EACAC,CAEA,UAAAJ,GAAAzS,KAAA6K,EAAA,CACA4H,EAAAzS,GAAAA,EAIA,IAAA6S,IAAAH,GAAA,CAEA,GAAAA,EAAAI,eAAAD,IAAAA,EAAAjG,gBAAA,QAAA,CACAmG,EAAAtiB,EAAAoiB,EAAAH,EAAAG,KAKA,GAAAtG,EAAAY,GAAA,CAAA1c,EAAA4hB,EAAAI,EAAA7Z,KAAAnI,EAAA8Q,WAGA,IAAAoR,IAAAF,GAAA,CACA,GAAAA,EAAAK,eAAAH,GAAA,CACAC,EAAAD,EAAA/F,aAGA,IAAAgG,IAAA,aAAA,CACAniB,EAAAyO,aAAA,QAAAuT,EAAAE,QACA,IAAAC,IAAA,WAAAA,IAAA,OAAA,CACAniB,EAAAyO,aAAAyT,EAAAF,EAAAE,MAKA,GAAApG,EAAAY,GAAA,CACAxB,EAAAA,EAAAva,QAAAqhB,EAAAzS,OACA,CACAvP,EAAAyO,aAAA,OAAA+L,EACAxa,GAAAyO,aAAA,OAAAuT,EAAA7Z,MAGAmB,EAAA8U,WAAAgD,aAAAphB,EAAAsJ,EACAxJ,GAAAE,EAGA,MAAAF,GAGA,QAAAwiB,GAAAhZ,EAAAiZ,EAAAC,GACA,GAAApG,GAAAvL,EAAA,QACAuL,GAAA3N,aAAA,OAAA8T,EACAnG,GAAA3N,aAAA,QAAA+T,EACAlZ,GAAAyH,YAAAqL,GAMA,QAAA+E,GAAA5R,GACA,GAAA9K,GAAAuX,EAAAzM,EACA,IAAA9K,GAAAA,EAAA8b,SAAAC,gBAAA,SAAA,CACA,GAAA1E,EAAAY,GAAA,CACAjY,EAAAqN,MAAAqM,QAAA,QACA,QAAAsE,KACA,GAAAhe,EAAAiZ,YAAA,EAAA,CAEA,IAAA,GAAAtd,KAAAqE,GAAA,CACA,SAAAA,GAAArE,KAAA,WAAA,CACAqE,EAAArE,GAAA,MAGAqE,EAAA2Z,WAAAtP,YAAArK,OACA,CACAmF,WAAA6Y,EAAA,aAIA,CACAhe,EAAA2Z,WAAAtP,YAAArK,KAKA,QAAAie,GAAAnT,GACA,MAAAA,IAAAA,EAAAmS,UAAAnS,EAAAmS,WAAA,EAGA,QAAAhB,GAAAiC,GACA,MAAAD,GAAAC,GAAAA,EAAApT,GAAAoT,EAKA,QAAA3G,GAAAzM,GAGA,GAAAmT,EAAAnT,GAAA,CAAA,MAAAA,GAEA,GAAAjG,GAAA,IACA,KACAA,EAAAsR,EAAAoB,eAAAzM,GAEA,MAAA5P,IACA,MAAA2J,GAGA,QAAAuH,GAAAvH,GACA,MAAAsR,GAAA/J,cAAAvH,GAIA,QAAA4T,GAAA0F,GACA,MAAAC,UAAAD,EAAA,IAMA,QAAAnE,GAAAzd,EAAA8hB,EAAAvE,GACAvd,EAAA4c,YAAAkF,EAAAvE,EACApD,GAAAA,EAAAxa,SAAAK,EAAA8hB,EAAAvE,GAKA,QAAAe,GAAAyD,GACAA,GAAA,EACA,IAAAxF,GAAAzB,EAAAyB,GAAAyF,EAAAD,EAAA1F,MAAA,IACA2F,GAAA,GAAA9F,EAAA8F,EAAA,GACAA,GAAA,GAAA9F,EAAA8F,EAAA,KAAA,CACAA,GAAA,GAAA9F,EAAA8F,EAAA,KAAA,CACA,OAAAzF,GAAA,GAAAyF,EAAA,IAAAzF,EAAA,IAAAyF,EAAA,IAAAzF,EAAA,GAAAyF,EAAA,IAAAzF,EAAA,IAAAyF,EAAA,IAAAzF,EAAA,IAAAyF,EAAA,IAAAzF,EAAA,IAAAyF,EAAA,GAAA,KAAA,MAMA,QAAAC,GAAAC,EAAAC,EAAAC,EAAAC,GACA,GAAAC,GAAA1I,EAAAqB,qBAAA,QAAA,EACA,KAAAqH,EAAA,CAAA,OACA,GAAAC,SAAAH,KAAA,SAAAA,EAAA,QACA,IAAAC,EAAA,CACA3H,EAAA,IACAC,GAAA,KAEA,IAAAD,GAAAC,GAAA4H,EAAA,CAEA,GAAAxjB,GAAA8Q,EAAA,QACA9Q,GAAA0O,aAAA,OAAA,WACA1O,GAAA0O,aAAA,QAAA8U,EACA7H,GAAA4H,EAAAvS,YAAAhR,EACA,IAAA+b,EAAAY,UAAA9B,GAAA4I,cAAApJ,GAAAQ,EAAA4I,YAAA7iB,OAAA,EAAA,CACA+a,EAAAd,EAAA4I,YAAA5I,EAAA4I,YAAA7iB,OAAA,GAEAgb,EAAA4H,EAGA,GAAA7H,EAAA,CACA,SAAAA,GAAA+H,UAAArJ,EAAA,CACAsB,EAAA+H,QAAAP,EAAAC,OACA,UAAAvI,GAAA8I,iBAAAtJ,EAAA,CACAsB,EAAA3K,YAAA6J,EAAA8I,eAAAR,EAAA,KAAAC,EAAA,QAKA,QAAA3D,GAAAjQ,EAAAoU,GACA,IAAA/H,EAAA,CAAA,OACA,GAAAoH,GAAAW,EAAA,UAAA,SACAra,EAAA0S,EAAAzM,EACA,IAAAiM,GAAAlS,EAAA,CACAA,EAAAwI,MAAA8R,WAAAZ,MACA,UAAAzT,KAAA,SAAA,CACA0T,EAAA,IAAA1T,EAAA,cAAAyT,IAMA,QAAAa,GAAA9jB,GACA,GAAA+jB,GAAA,aACA,IAAAC,GAAAD,EAAAE,KAAAjkB,KAAA,IACA,OAAAgkB,UAAAjD,sBAAA1G,EAAA0G,mBAAA/gB,GAAAA,EAKA,GAAAkkB,GAAA,WACA,GAAAnI,EAAAY,GAAA,CACAvQ,OAAAyR,YAAA,WAAA,WAEA,GAAAsG,GAAA/I,EAAAxa,MACA,KAAA,GAAAP,GAAA,EAAAA,EAAA8jB,EAAA9jB,IAAA,CACA+a,EAAA/a,GAAA,GAAA0d,YAAA3C,EAAA/a,GAAA,GAAA+a,EAAA/a,GAAA,IAGA,GAAA+jB,GAAAjJ,EAAAva,MACA,KAAA,GAAAuf,GAAA,EAAAA,EAAAiE,EAAAjE,IAAA,CACAiB,EAAAjG,EAAAgF,IAGA,IAAA,GAAAkE,KAAAtI,GAAA,CACAA,EAAAsI,GAAA,KAEAtI,EAAA,IACA,KAAA,GAAAtb,KAAA2G,WAAA,CACAA,UAAA3G,GAAA,KAEA2G,UAAA,UAKA,QAIAkd,eAAA,SAAA/D,EAAAgE,EAAAC,EAAApF,GACA,GAAArD,EAAAwB,IAAAgD,GAAAgE,EAAA,CACA,GAAAE,KACAA,GAAAjV,GAAA+Q,CACAkE,GAAAjF,WAAA+E,CACAE,GAAA7E,eAAA4E,CACAC,GAAArF,WAAAA,CACAlE,GAAAA,EAAAta,QAAA6jB,CACAhF,GAAAc,EAAA,WAEA,IAAAnB,EAAA,CACAA,GAAAE,QAAA,MAAA9P,GAAA+Q,MAIAZ,cAAA,SAAAY,GACA,GAAAxE,EAAAwB,GAAA,CACA,MAAAoC,GAAAY,KAIAmE,SAAA,SAAAC,EAAAjE,EAAAkE,EAAAC,EAAAN,EAAAC,EAAAM,EAAA5C,EAAAD,EAAA7C,GAEA,GAAA5P,GAAAmR,EAAAD,GACAqE,GAAAzF,QAAA,MAAA9P,GAAAA,EAEA,IAAAuM,EAAAwB,MAAAxB,EAAA0B,IAAA1B,EAAA0B,GAAA,MAAAkH,GAAAjE,GAAAkE,GAAAC,GAAAN,EAAA,CACA9E,EAAAjQ,EAAA,MACA+O,GAAA,WACAqG,GAAA,EACAC,IAAA,EACA,IAAA/E,KACA,IAAAmC,SAAAA,KAAA3H,EAAA,CACA,IAAA,GAAAja,KAAA4hB,GAAA,CACAnC,EAAAzf,GAAA4hB,EAAA5hB,IAGAyf,EAAA1X,KAAAuc,CACA7E,GAAApd,MAAAkiB,CACA9E,GAAAnd,OAAAkiB,CACA,IAAA5E,KACA,IAAAiC,SAAAA,KAAA5H,EAAA,CACA,IAAA,GAAA6F,KAAA+B,GAAA,CACAjC,EAAAE,GAAA+B,EAAA/B,IAGA,GAAA2E,SAAAA,KAAAxK,EAAA,CACA,IAAA,GAAA+J,KAAAS,GAAA,CACA,GAAAA,EAAAxC,eAAA+B,GAAA,CAEA,GAAA5iB,GAAA,EAAAsf,mBAAAsD,GAAAA,EACAviB,EAAA,EAAAif,mBAAA+D,EAAAT,IAAAS,EAAAT,EAEA,UAAApE,GAAAgB,YAAA5G,EAAA,CACA4F,EAAAgB,WAAA,IAAAxf,EAAA,IAAAK,MAEA,CACAme,EAAAgB,UAAAxf,EAAA,IAAAK,KAMA,GAAAyd,EAAAgF,GAAA,CACA,GAAA7f,GAAA8E,EAAAsW,EAAAG,EAAAS,EACA,IAAAZ,EAAAtQ,IAAAA,EAAA,CACAiQ,EAAAjQ,EAAA,MAEAuV,EAAAzF,QAAA,IACAyF,GAAArF,IAAAhb,CACAqgB,GAAAvV,GAAA9K,EAAA8K,OAEA,IAAAgV,GAAA3E,IAAA,CACAC,EAAA1X,KAAAoc,CACApE,GAAAN,EAAAG,EAAAS,EAAAtB,EACA,YAEA,CACAK,EAAAjQ,EAAA,MAEA,GAAA4P,EAAA,CAAAA,EAAA2F,UAGA,IAAA3F,EAAA,CAAAA,EAAA2F,KAGAC,sBAAA,WACAnJ,EAAA,OAGAoJ,kBAAA,SAAAC,GACApJ,QAAAoJ,KAAA7K,EAAA,KAAA6K,GAGAnJ,GAAAA,EAEAoJ,sBAAA,WACA,OAAAC,MAAArJ,EAAAyB,GAAA,GAAA6H,MAAAtJ,EAAAyB,GAAA,GAAA8H,QAAAvJ,EAAAyB,GAAA,KAGA1S,sBAAAyU,EAEA/V,UAAA,SAAAyY,EAAAC,EAAAxB,GACA,GAAA3E,EAAAwB,GAAA,CACA,MAAA/T,GAAAyY,EAAAC,EAAAxB,OAEA,CACA,MAAAne,aAIA6d,mBAAA,SAAAN,EAAAG,EAAAS,EAAAtB,GACA,GAAArD,EAAAwB,IAAAsC,IAAA,CACAO,EAAAN,EAAAG,EAAAS,EAAAtB,KAIAgC,UAAA,SAAAmE,GACA,GAAAxJ,EAAAwB,GAAA,CACA6D,EAAAmE,KAIArC,UAAA,SAAAsC,EAAAC,EAAAC,EAAAC,GACA,GAAA5J,EAAAwB,GAAA,CACA2F,EAAAsC,EAAAC,EAAAC,EAAAC,KAIApH,gBAAAA,EAEAE,aAAAA,EAEAmH,mBAAA,SAAAvD,GACA,GAAAwD,GAAAhL,EAAA9C,SAAAjG,QAAA+I,EAAA9C,SAAA+N,IACA,IAAAD,EAAA,CACA,GAAA,KAAArJ,KAAAqJ,GAAA,CAAAA,EAAAA,EAAAvI,MAAA,KAAA,GACA,IAAA+E,EAAA,CACA,MAAAyB,GAAA+B,GAEA,GAAAE,GAAAF,EAAAvI,MAAA,IACA,KAAA,GAAAjd,GAAA,EAAAA,EAAA0lB,EAAAnlB,OAAAP,IAAA,CACA,GAAA0lB,EAAA1lB,GAAA2lB,UAAA,EAAAD,EAAA1lB,GAAAoF,QAAA,OAAA4c,EAAA,CACA,MAAAyB,GAAAiC,EAAA1lB,GAAA2lB,UAAAD,EAAA1lB,GAAAoF,QAAA,KAAA,MAIA,MAAA,IAIAwgB,uBAAA,WACA,GAAAvK,EAAA,CACA,GAAAhX,GAAAuX,EAAAvB,EACA,IAAAhW,GAAA2W,EAAA,CACA3W,EAAA2Z,WAAAgD,aAAAhG,EAAA3W,EACA,IAAA4W,EAAA,CACAmE,EAAAnE,EAAA,KACA,IAAAS,EAAAY,GAAA,CAAAtB,EAAAtJ,MAAAqM,QAAA,SAEA,GAAA7C,EAAA,CAAAA,EAAAC,IAEAE,EAAA,QAIAwK,QAAA,cbgsEMC,IAAI,SAAS/lB,EAAQU,EAAOJ,Gcz/FlC,YAEA,IAAA0lB,GAAAhmB,EAAA,WACA,IAAAimB,GAAAjmB,EAAA,YAEA,SAAAkmB,GAAAC,GACA,KAAApkB,eAAAmkB,IAAA,CACA,MAAA,IAAAA,GAAAC,GAEApkB,KAAAqkB,WAAAD,GAGAD,EAAAzkB,UAAA2kB,WAAA,SAAAD,GACApkB,KAAAqN,GAAA+W,EAAApE,KAAA,KACAhgB,MAAAskB,SAAAF,EAAApE,KAAA,WAEA,IAAAoE,EAAAG,OAAA,CACAvkB,KAAAukB,OAAA,GAAAN,GAAAG,EAAAG,QAGA,GAAAH,EAAAI,QAAA,CACAxkB,KAAAwkB,QAAA,GAAAN,GAAAE,EAAAI,UAIA7lB,GAAAJ,QAAA4lB,Id2/FGM,WAAW,GAAGC,YAAY,KAAKC,IAAI,SAAS1mB,EAAQU,EAAOJ,GephG9D,YAEA,IAAAqmB,GAAA3mB,EAAA,kBAEA,IAAA4mB,GAAA5mB,EAAA,+BAEA,IAAA6mB,GAAA7mB,EAAA,kBAGA,SAAA8mB,GAAAC,GACA,KAAAhlB,eAAA+kB,IAAA,CACA,MAAA,IAAAA,GAAAC,GAIAhlB,KAAAilB,aAAAH,EAAA9E,KAAAgF,EAAAE,eAAA,eACAllB,MAAAklB,eAAAJ,EAAAK,SAAAH,EAAAE,eAGA,IAAAE,GAAA,IACA,IAAAN,EAAAK,SAAAH,EAAAK,cAAA,CACAD,EAAAN,EAAAK,SAAAH,EAAAK,kBACA,IAAAP,EAAAK,SAAAH,EAAAM,cAAA,CACAF,EAAAN,EAAAK,SAAAH,EAAAM,cAEAtlB,KAAAolB,aAAAA,CAEA,IAAAG,GAAA,IACA,IAAAT,EAAAK,SAAAH,EAAAQ,gBAAA,CACAD,EAAAT,EAAAK,SAAAH,EAAAQ,oBACA,IAAAV,EAAAK,SAAAH,EAAAS,gBAAA,CACAF,EAAAT,EAAAK,SAAAH,EAAAS,gBAEAzlB,KAAAulB,eAAAA,CAGAvlB,MAAAqN,GAAAyX,EAAA9E,KAAAgF,EAAA,KACAhlB,MAAAO,MAAAukB,EAAA9E,KAAAgF,EAAA,QACAhlB,MAAAQ,OAAAskB,EAAA9E,KAAAgF,EAAA,SACAhlB,MAAA0lB,cAAAZ,EAAA9E,KAAAgF,EAAA,gBACAhlB,MAAA2lB,eAAAb,EAAA9E,KAAAgF,EAAA,iBACAhlB,MAAA4lB,SAAAd,EAAA9E,KAAAgF,EAAA,WACAhlB,MAAA6lB,oBAAAf,EAAA9E,KAAAgF,EAAA,sBACAhlB,MAAA8lB,qBAAAhB,EAAA9E,KAAAgF,EAAA,uBACAhlB,MAAA+lB,aAAAjB,EAAA9E,KAAAgF,EAAA,eACAhlB,MAAAgmB,sBAAAlB,EAAAK,SAAAH,EAAAgB,sBACAhmB,MAAAimB,eAAAC,EAAAlB,EAAAiB,gBAAAjB,EAAAiB,eAAAE,SAGA,SAAAD,GAAAD,GACA,GAAAG,KACA,IAAAvB,EAAAwB,UAAAJ,GAAA,CACAA,EAAApB,EAAAyB,QAAAL,GAAAA,GAAAA,EACAA,GAAAjiB,QAAA,SAAAuiB,GACAH,EAAA5Y,KAAA,GAAAoX,GAAA2B,MAGA,MAAAH,IAIAznB,EAAAJ,QAAAwmB,IfshGGyB,+BAA+B,GAAGC,kBAAkB,GAAGC,kBAAkB,KAAKC,IAAI,SAAS1oB,EAAQU,EAAOJ,GgBnlG7G,YAEA,IAAAqoB,GAAA3oB,EAAA,WACA,IAAA8mB,GAAA9mB,EAAA,cACA,IAAA4mB,GAAA5mB,EAAA,+BAEA,SAAA4oB,GAAAC,GACA,KAAA9mB,eAAA6mB,IAAA,CACA,MAAA,IAAAA,GAAAC,GAGA9mB,KAAAqN,GAAAyZ,EAAA9G,KAAA,KACAhgB,MAAAskB,SAAAwC,EAAA9G,KAAA,WACAhgB,MAAA+mB,KAAAD,EAAA9G,KAAA,OACAhgB,MAAA+lB,aAAAe,EAAA9G,KAAA,eAEA,IAAA8G,EAAAE,OAAA,CACAhnB,KAAAgnB,OAAA,GAAAJ,GAAAE,EAAAE,QAGA,GAAAF,EAAAG,aAAA,CACA,GAAAC,KACA,IAAAD,GAAAH,EAAAG,cAAAH,EAAAG,aAAAE,SACA,IAAAtC,EAAAwB,UAAAY,GAAA,CACAA,EAAApC,EAAAyB,QAAAW,GAAAA,GAAAA,EACAA,GAAAjjB,QAAA,SAAAojB,GACAF,EAAA1Z,KAAA,GAAAuX,GAAAqC,MAGApnB,KAAAinB,aAAAC,GAOAL,EAAAnnB,UAAAmG,YAAA,WACA,GAAA7F,KAAAgnB,OAAA,CACA,MAAAhnB,MAAAgnB,OAAAnhB,cAGA,MAAA,MAGAghB,GAAAQ,eAAA,QAAAA,GAAAC,GACA,GAAAC,KACA,IAAAC,EACA,IAAA3C,EAAAwB,UAAAiB,IAAAzC,EAAAwB,UAAAiB,EAAAnX,UAAA,CACAqX,EAAA3C,EAAAyB,QAAAgB,EAAAnX,UAAAmX,EAAAnX,UAAAmX,EAAAnX,SACAqX,GAAAxjB,QAAA,SAAAmM,GACAoX,EAAA/Z,KAAA,GAAAqZ,GAAA1W,MAGA,MAAAoX,GAGA5oB,GAAAJ,QAAAsoB,IhBslGGL,+BAA+B,GAAGiB,cAAc,GAAGC,WAAW,KAAKC,IAAI,SAAS1pB,EAAQU,EAAOJ,GiB9oGlG,YAEA,IAAAqpB,GAAA3pB,EAAA,aACA,IAAA4oB,GAAA5oB,EAAA,aAEA,IAAA4mB,GAAA5mB,EAAA,+BACA,IAAA6mB,GAAA7mB,EAAA,kBAEA,SAAAgmB,GAAA4D,GACA,KAAA7nB,eAAAikB,IAAA,CACA,MAAA,IAAAA,GAAA4D,GAIA7nB,KAAA8nB,QAAAhD,EAAAK,SAAA0C,EAAAC,QACA9nB,MAAA+nB,SAAAjD,EAAAK,SAAA0C,EAAAE,SACA/nB,MAAAgoB,YAAAJ,EAAAK,iBAAAJ,EAAAK,WACAloB,MAAAunB,UAAAV,EAAAQ,eAAAQ,EAAAN,UAGAvnB,MAAA6a,YAAAiK,EAAAK,SAAA0C,EAAAhN,YACA7a,MAAAmoB,WAAArD,EAAAK,SAAA0C,EAAAM,WACAnoB,MAAAooB,QAAAC,EAAAR,EAAAS,OACAtoB,MAAAyH,MAAAqd,EAAAK,SAAA0C,EAAApgB,MACAzH,MAAAuoB,QAAAzD,EAAAK,SAAA0C,EAAAU,QACAvoB,MAAAwoB,WAAAX,EAAAW,UAGA,SAAAH,GAAAI,GACA,GAAAA,EAAA,CACA,MAAA5D,GAAA6D,eAAA7D,EAAAyB,QAAAmC,GAAAA,GAAAA,GAAA,SAAAH,GACA,GAAAzD,EAAA8D,iBAAAL,EAAAnD,UAAA,CACA,OACAyD,IAAAN,EAAAnD,SACA0D,KAAAP,EAAAtI,KAAA,SAIA,MAAA5f,aAGA,UAQA6jB,EAAAvkB,UAAAmG,YAAA,WACA,GAAA3H,GAAA4qB,CAEA,IAAA9oB,KAAAunB,UAAA9oB,SAAA,EAAA,CACA,MAAA,OAGA,IAAAP,EAAA,EAAA4qB,EAAA9oB,KAAAunB,UAAA9oB,OAAAP,EAAA4qB,EAAA5qB,GAAA,EAAA,CACA,IAAA8B,KAAAunB,UAAArpB,GAAA2H,cAAA,CACA,MAAA,QAGA,MAAA,MAGAlH,GAAAJ,QAAA0lB,IjBipGGuC,+BAA+B,GAAGC,kBAAkB,GAAGsC,aAAa,GAAGC,aAAa,KAAKC,IAAI,SAAShrB,EAAQU,EAAOJ,GkBjtGxH,YAEA,IAAAqmB,GAAA3mB,EAAA,kBACA,IAAAirB,GAAAjrB,EAAA,cACA,IAAAkrB,GAAAlrB,EAAA,gBAEA,IAAA4mB,GAAA5mB,EAAA,+BACA,IAAAmrB,GAAAnrB,EAAA,YAEA,IAAA6mB,GAAA7mB,EAAA,kBAGA,SAAA2oB,GAAAyC,GACA,KAAArpB,eAAA4mB,IAAA,CACA,MAAA,IAAAA,GAAAyC,GAIArpB,KAAAspB,SAAAF,EAAAE,SAAAxE,EAAAK,SAAAkE,EAAAC,UACAtpB,MAAAupB,WAAAC,EAAAH,EAAAE,YAAAF,EAAAE,WAAAE,UAGAzpB,MAAAimB,eAAAC,EAAAmD,EAAApD,gBAAAoD,EAAApD,eAAAE,SAAAnmB,KAAAspB,SACAtpB,MAAA0pB,WAAAN,EAAAO,OAAA7E,EAAA9E,KAAAqJ,EAAA,cAAArpB,KAAAspB,SAEA,IAAAD,EAAAO,YAAA,CACA5pB,KAAA4pB,YAAA,GAAAT,GAAAE,EAAAO,aAGA,GAAAP,EAAAQ,aAAA,CACA7pB,KAAA6pB,aAAA/E,EAAAK,SAAAkE,EAAAQ,aAEA,IAAA/E,EAAA9E,KAAAqJ,EAAAQ,aAAA,cAAA,CACA7pB,KAAA6pB,aAAA/E,EAAAgF,OAAA9pB,KAAA6pB,eAKA,QAAA3D,GAAAD,EAAAqD,GACA,GAAAlD,KACA,IAAAvB,EAAAwB,UAAAJ,GAAA,CACAA,EAAApB,EAAAyB,QAAAL,GAAAA,GAAAA,EACAA,GAAAjiB,QAAA,SAAAuiB,GACAH,EAAA5Y,KAAA,GAAAoX,GAAA2B,EAAA+C,MAGA,MAAAlD,GAGA,QAAAoD,GAAAO,GACA,GAAAR,KACA,IAAA1E,EAAAwB,UAAA0D,GAAA,CACAA,EAAAlF,EAAAyB,QAAAyD,GAAAA,GAAAA,EAEAA,GAAA/lB,QAAA,SAAAgmB,GACAT,EAAA/b,KAAA,GAAA0b,GAAAc,MAGA,MAAAT,IAOA3C,EAAAlnB,UAAAmG,YAAA,WACA,GAAA3H,GAAA4qB,CACA,KAAA5qB,EAAA,EAAA4qB,EAAA9oB,KAAAupB,WAAA9qB,OAAAP,EAAA4qB,EAAA5qB,GAAA,EAAA,CACA,GAAA8B,KAAAupB,WAAArrB,GAAA2H,cAAA,CACA,MAAA,OAIA,MAAA,OAGAlH,GAAAJ,QAAAqoB,IlBmtGGJ,+BAA+B,GAAGC,kBAAkB,GAAGwD,cAAc,GAAGvD,kBAAkB,GAAGwD,gBAAgB,GAAGC,YAAY,KAAKC,IAAI,SAASnsB,EAAQU,EAAOJ,GmB/xGhK,YAEA,IAAAumB,GAAA7mB,EAAA,kBACA,IAAA2pB,GAAA3pB,EAAA,aAEA,IAAAosB,IAEA,WACA,OACA,QACA,SAEA,QACA,KACA,UACA,aACA,aACA,WACA,sBACA,eAGA,SAAAnB,GAAAoB,GACA,KAAAtqB,eAAAkpB,IAAA,CACA,MAAA,IAAAA,GAAAoB,GAIAtqB,KAAA6W,IAAAiO,EAAAK,SAAAmF,EAEA,KAAA,GAAAC,GAAA,EAAAA,EAAAF,EAAA5rB,OAAA8rB,IAAA,CACA,GAAAC,GAAAH,EAAAE,EACAvqB,MAAAwqB,GAAAF,EAAAtK,KAAAwK,IAIAtB,EAAAxpB,UAAAmG,YAAA,WACA,GAAA+hB,EAAA6C,QAAAzqB,MAAA,CACA,QAAA4nB,EAAA8C,uBAAA1qB,KAAA6oB,MAGA,GAAA7oB,KAAA6oB,OAAA,cAAA,CACA,MAAAjB,GAAA+C,mBAGA,MAAA,MAGAhsB,GAAAJ,QAAA2qB,InBkyGGzC,kBAAkB,GAAGuC,aAAa,KAAK4B,IAAI,SAAS3sB,EAAQU,EAAOJ,GoBl1GtE,YAEA,IAAA6qB,GAAAnrB,EAAA,YAEA,IAAA6mB,GAAA7mB,EAAA,kBAEA,SAAA2mB,GAAAiG,EAAAvB,GACA,KAAAtpB,eAAA4kB,IAAA,CACA,MAAA,IAAAA,GAAAiG,EAAAvB,GAGAtpB,KAAA+Q,KAAA8Z,EAAA7K,KAAA,QACAhgB,MAAA4oB,IAAA9D,EAAAK,SAAA0F,EAEA,IAAA,aAAA7qB,KAAA+Q,KAAA,CACA/Q,KAAA2pB,OAAAP,EAAAO,OAAAkB,EAAA7K,KAAA,UAAAsJ,IAIA3qB,EAAAJ,QAAAqmB,IpBo1GG6B,kBAAkB,GAAG0D,YAAY,KAAKW,IAAI,SAAS7sB,EAAQU,EAAOJ,GqBv2GrE,YAEA,IAAA4lB,GAAAlmB,EAAA,OACA,IAAA8sB,GAAA9sB,EAAA,cACA,IAAA+sB,GAAA/sB,EAAA,iBACA,IAAA2pB,GAAA3pB,EAAA,aAEA,IAAAgtB,GAAAhtB,EAAA,oBACA,IAAAitB,GAAAjtB,EAAA,oBAAAitB,IACA,IAAArG,GAAA5mB,EAAA,+BACA,IAAA6mB,GAAA7mB,EAAA,kBAEA,SAAAktB,GAAAC,GACA,KAAAprB,eAAAmrB,IAAA,CACA,MAAA,IAAAA,GAAAC,GAEA,GAAAC,IACAC,cAAA,EAGAF,GAAAA,KACAprB,MAAAurB,SAAA1G,EAAAzS,UAAAgZ,EAAAC,EACArrB,MAAAwrB,kBAGAL,EAAAzrB,UAAA+rB,gBAAA,QAAAA,GAAAC,EAAArrB,GACA,GAAA6T,GAAAlU,IAEA,IAAAyH,GAAAkkB,EAAAD,EAAArrB,EACA,IAAAoH,EAAA,CACA,GAAAod,EAAA+G,WAAAvrB,GAAA,CACA,MAAAA,GAAAoH,GAEA,KAAAA,GAGAwjB,EAAAY,WACA7rB,KAAA8rB,WAAA3Z,KAAAnS,KAAA0rB,GACAK,GAEA1rB,EAGA,SAAA0rB,GAAAC,EAAAhP,GACA,IACA,GAAAiP,GAAA/X,EAAAgY,mBAAAF,EACAhP,GAAA,KAAAiP,GACA,MAAAxuB,GACAuf,EAAAvf,IAIA,QAAAkuB,GAAAD,EAAA1O,GACA,IAAA0O,EAAA,CACA,MAAA,IAAAX,GAAA,qDAGA,IAAAlG,EAAA+G,WAAA5O,GAAA,CACA,MAAA,IAAA+N,GAAA,8DAKAI,GAAAzrB,UAAAosB,WAAA,SAAAJ,EAAArrB,GACA,GAAA6T,GAAAlU,IAEAmsB,GAAAT,EAAA,SAAAjkB,EAAA2kB,GACA,GAAAC,GAAAD,GAAAvH,EAAAyB,QAAA8F,EAAAE,KAAAF,EAAAE,IAAA,IACA,IAAA7kB,EAAA,CACAyM,EAAAqY,YAAA9kB,EAAA4kB,EACA,OAAAhsB,GAAAoH,EAAA4kB,GAGAG,EAAAH,EAAAI,WAAAC,EAGA,SAAAA,GAAAjlB,EAAAklB,GACA,GAAAllB,EAAA,CACAyM,EAAAqY,YAAA9kB,EAAAklB,EACA,IAAAN,EAAA5tB,OAAA,EAAA,CACA+tB,EAAAH,EAAAI,WAAAC,OACA,CACArsB,EAAAoH,EAAAklB,QAEA,CACAtsB,EAAA,KAAAssB,MAMA,SAAAR,GAAAT,EAAArrB,GACA,GAAAusB,GAAA1Y,EAAA2Y,gBAAA1a,KAAA+B,EAAAwX,EACAT,GAAAY,WACAe,EACAE,GACAzsB,GAGA,QAAAysB,GAAAC,EAAA1sB,GACA,GAAA+rB,EACA,KACAA,EAAAtH,EAAAkI,WAAAD,EAEA,IAAAlI,EAAAyB,QAAA8F,EAAAa,IAAA,CACAb,EAAAE,IAAAF,EAAAa,OACA,IAAAb,EAAAa,GAAA,CACAb,EAAAE,KAAAF,EAAAa,QACA,CACAb,EAAAE,OAEAjsB,EAAA6sB,EAAAd,GAAAA,GAEA,MAAA3uB,GACA4C,EAAA,GAAA0qB,GAAA,gEAAA,KAAA,OAIA,QAAAmC,GAAAd,GACA,GAAAe,GAAArI,EAAA9E,KAAAoM,EAAA,UAEA,KAAAA,EAAAa,GAAA,CACA,MAAA,IAAAlC,GAAA,+DAAA,KAGA,GAAAoC,IAAAA,GAAA,GAAAA,GAAA,GAAA,CACA,MAAA,IAAApC,GAAA,yEAAAoC,EAAA,IAAA,KAGA,MAAA,MAGA,QAAAX,GAAAd,EAAAiB,EAAAtsB,GACA,GAAAssB,EAAAluB,QAAAyV,EAAAoX,cAAA,CACA,MAAAjrB,GAAA,GAAA0qB,GAAA,8EAAA7W,EAAAoX,cAAA,IAAA,KAAAqB,GAGA1B,EAAAY,WACA,SAAAuB,GACA,GAAAvI,EAAAwI,SAAA3B,GAAA,CACA4B,EAAA5B,EAAA0B,OACA,CACAA,EAAA,KAAA1B,KAGA6B,GACA,SAAA9lB,EAAAwlB,GACA,GAAAA,EAAA,CACAN,EAAAnf,KAAAyf,GAGA,GAAAxlB,EAAA,CACA,MAAApH,GAAAoH,EAAAklB,GAGA,GAAAM,EAAAzI,QAAA,CACA,MAAAgI,GAAAS,EAAAzI,QAAAgJ,aAAAb,EAAAtsB,GAGA,MAAAA,GAAA,KAAAssB,KAIA,QAAAY,GAAAE,EAAAptB,GACA,IACA,GAAA4sB,GAAA,GAAA9I,GAAAsJ,EACAptB,GAAAqtB,EAAAT,GAAAA,GACA,MAAAxvB,GACA4C,EAAA,GAAA0qB,GAAA,qDAAA,KAAA,OAIA,QAAA2C,GAAAT,GACA,GAAAzI,GAAAyI,EAAAzI,OACA,IAAAD,GAAA0I,EAAA1I,MACA,IAAAoJ,GAAA,sCAEA,IAAApJ,GAAAC,EAAA,CACA,MAAA,IAAAuG,GAAA4C,EAAA,+CAAA,KAGA,IAAApJ,IAAAC,EAAA,CACA,MAAA,IAAAuG,GAAA4C,EAAA,kDAAA,KAGA,GAAApJ,IAAAA,EAAA1e,cAAA,CACA,MAAA,IAAAklB,GAAA4C,EAAA,kEAAA,KAGA,GAAAnJ,IAAAA,EAAAgJ,aAAA,CACA,MAAA,IAAAzC,GAAA4C,EAAA,oCAAA,KAGA,MAAA,MAGA,QAAAL,GAAA5B,EAAArrB,GACA6T,EAAA2Y,gBAAAnB,EAAA,SAAAjkB,EAAAslB,GACA,GAAAtlB,EAAA,CACA,MAAApH,GAAAoH,GAEA,IACA,GAAA2kB,GAAAtH,EAAAkI,WAAAD,EACA1sB,GAAA6sB,EAAAd,GAAAA,EAAAa,IACA,MAAAxvB,GACA4C,EAAA,GAAA0qB,GAAA,2DAAA,UAMAI,GAAAzrB,UAAAmtB,gBAAA,QAAAe,GAAAlC,EAAArrB,GACA,IACA,GAAAwkB,EAAA+G,WAAAF,GAAA,CACAA,EAAAmC,OACA,CACA3C,EAAAnhB,IAAA2hB,EAAAmC,GACAC,gBAAA,QAGA,MAAArwB,GACA4C,EAAA5C,GAIA,QAAAowB,GAAApmB,EAAAwkB,EAAA8B,GACA,GAAAtmB,EAAA,CACA,GAAAumB,GAAAnJ,EAAAwB,UAAA0H,GACA,iEAAAA,EAAA,IACA,yFACA,OAAA1tB,GAAA,GAAA0qB,GAAAiD,EAAA,KAAA,MAGA3tB,EAAA,KAAA4rB,IAIAd,GAAAzrB,UAAAwsB,mBAAA,QAAAH,GAAAC,GACA,GAAAC,GAAA,GAAAjB,EACAiD,GAAAhC,EAAAD,EACAkC,GAAAjC,EAEA,OAAAA,EAGA,SAAAgC,GAAAhC,EAAAK,GACAA,EAAAtoB,QAAA,SAAAipB,GACAhB,EAAAkC,MAAAlB,KAIA,QAAAiB,GAAAjC,GACA,GAAAmC,GAAAnC,EAAAhG,eAAAoI,QAEA,KAAApC,EAAAqC,YAAA,CACA,KAAA,IAAAvD,GAAA,8EAAA,KAGA,GAAAkB,EAAA3C,WAAAlpB,UAAA,CACA,KAAA,IAAA2qB,GAAA,4EAAA,KAGA,GAAAqD,EAAA,CACAA,EAAApqB,QAAA,SAAAuqB,GACA,IAAA1J,EAAA2J,SAAAD,EAAA5E,QAAA,CACA,KAAA,IAAAoB,GAAA,iGAAA,UAOAI,GAAAzrB,UAAA6sB,YAAA,SAAA9kB,EAAAklB,GACA,IAAA9H,EAAAyB,QAAAqG,IAAAA,EAAAluB,SAAA,EAAA,CACA,OAGA,GAAA+sB,KACAmB,GAAA3oB,QAAAyqB,EACA7G,GAAA8G,MAAAlD,GAAAmD,UAAAlnB,EAAApJ,MAAA,KAGA,SAAAowB,GAAAxB,GACA,GAAAA,EAAAzI,SAAAyI,EAAAzI,QAAA/c,MAAA,CACA+jB,EAAAhe,KAAAyf,EAAAzI,QAAA/c,OAGA,GAAAwlB,EAAA1I,QAAA0I,EAAA1I,OAAA9c,MAAA,CACA+jB,EAAAhe,KAAAyf,EAAA1I,OAAA9c,SAKA9I,GAAAJ,QAAA4sB,IrB02GGyD,oBAAoB,GAAGC,mBAAmB,GAAGrI,+BAA+B,GAAGC,kBAAkB,GAAGqI,OAAO,GAAGC,cAAc,GAAGC,iBAAiB,GAAGhG,aAAa,KAAKiG,IAAI,SAAShxB,EAAQU,EAAOJ,GsB/oHpM,YAEA,SAAAwsB,GAAA1iB,EAAAhK,GACA2B,KAAAqI,QAAA,gBAAAA,GAAA,GACA,IAAAhK,EAAA,CACA2B,KAAA3B,KAAAA,GAIA0sB,EAAArrB,UAAA,GAAAtB,MACA2sB,GAAArrB,UAAAqR,KAAA,YAEApS,GAAAJ,QAAAwsB,OtBipHMmE,IAAI,SAASjxB,EAAQU,EAAOJ,GuB7pHlC,YAWA,IAAAysB,GAAA/sB,EAAA,iBACA,IAAA8sB,GAAA9sB,EAAA,cACA,IAAAkxB,GAAAlxB,EAAA,gBACA,IAAA2pB,GAAA3pB,EAAA,aAEA,IAAAgtB,GAAAhtB,EAAA,oBACA,IAAAmxB,GAAAnxB,EAAA,kBACA,IAAAoxB,GAAApxB,EAAA,0BACA,IAAA4mB,GAAA5mB,EAAA,+BAEA,SAAAqxB,GAAAC,GACA,KAAAvvB,eAAAsvB,IAAA,CACA,MAAA,IAAAA,GAAAC,GAGAvvB,KAAAuvB,OAAAA,EAGAD,EAAA5vB,UAAA8vB,OAAA,QAAAA,GAAAC,EAAApvB,GACA,GAAA6T,GAAAlU,IACAK,GAAAA,GAAAwkB,EAAA1f,IAEA,MAAAsqB,YAAAzE,IAAA,CACA,MAAA3qB,GAAA,GAAA0qB,GAAA,qDAGAE,EAAAY,WACA,SAAAuB,GACAA,EAAA,KAAAqC,IAEAzvB,KAAA0vB,gBAAAvd,KAAAnS,MACAA,KAAA2vB,mBAAAxd,KAAAnS,MACAA,KAAA4vB,iBAAAzd,KAAAnS,MACAA,KAAA6vB,eAAA1d,KAAAnS,MACAA,KAAA8vB,aAAA3d,KAAAnS,MACAA,KAAA+vB,gBAAA5d,KAAAnS,OACA,SAAAyH,EAAAwkB,GACA,GAAAxkB,GAAAwkB,EAAA,CACA/X,EAAAqY,YAAA9kB,EAAAwkB,GAEA5rB,EAAAoH,EAAAwkB,IAGAjsB,MAAAgI,SACAgoB,KAAA,KACAnH,KAAA,OACA3nB,QAAA,WACAgT,EAAAqb,OAAAU,MAAA,OAGA9uB,SAAA,WACA+S,EAAAqb,OAAAW,KAAA,OAGAC,SAAA,WACA,MAAAjc,GAAAqb,OAAAa,OAAA,OAGAC,OAAA,WACA,MAAArwB,MAAAgwB,MAIA,OAAAhwB,MAAAgI,QAGAsnB,GAAA5vB,UAAAgwB,gBAAA,QAAAY,GAAArE,EAAA5rB,GACA,GAAAkwB,EAEA,IAAAC,GAAApB,EAAAqB,aAAAzwB,KAAAuvB,OAAAnoB,MAAA7G,KACA0rB,GAAA1C,WAAAmH,KAAA,QAAAC,GAAA3yB,EAAA2e,GACA,GAAAiU,GAAAC,KAAAC,IAAAN,EAAAxyB,EAAAuC,MACA,IAAAwwB,GAAAF,KAAAC,IAAAN,EAAA7T,EAAApc,MACA,OAAAqwB,GAAAG,GAGAR,GAAAvwB,KAAAuvB,OAAAyB,aAAA/E,EAAA1C,YAAAgH,MAEA,IAAAA,EAAA,CACA,GAAAvwB,KAAAgI,QAAA,CACAhI,KAAAgI,QAAAgoB,KAAAO,EAEA,MAAAlwB,GAAA,KAAAkwB,EAAAtE,GAIA5rB,EAAA,GAAA0qB,GAAA,uDAAA,KAAAkB,GAGAqD,GAAA5vB,UAAAiwB,mBAAA,QAAAsB,GAAAC,EAAAjF,EAAA5rB,GACA,IACAA,EAAA,KAAA6wB,EAAA,GAAA/B,GAAA+B,EAAAra,IAAAoV,GAAAA,GACA,MAAAxuB,GACA4C,EAAA5C,EAAAwuB,IAIAqD,GAAA5vB,UAAAowB,aAAA,QAAAqB,GAAAD,EAAAE,EAAAnF,EAAA5rB,GACA,GAAAgxB,EACA,IAAA9B,GAAAvvB,KAAAuvB,MACAA,GAAAhrB,GAAA,mBAAA+sB,EACA/B,GAAAhrB,GAAA,eAAAgtB,EACAhC,GAAAhrB,GAAA,QAAAitB,EACAjC,GAAAhrB,GAAA,aAAAktB,EACAlC,GAAAhrB,GAAA,eAAAmtB,EAEArC,GAAAsC,KAAApC,GAAA,aAAA,kBAAAqC,EACAvC,GAAAsC,KAAApC,GAAA,aAAA,iBAAA,eAAA,SAAAsC,GACA,GAAAA,EAAAhJ,OAAA,aAAA,CACAuI,EAAAU,kBAIA,OAAAzxB,GAAA,KAAA6wB,EAAAjF,EAGA,SAAA2F,KACArC,EAAA9qB,IAAA,mBAAA6sB,EACA/B,GAAA9qB,IAAA,eAAA8sB,EACAhC,GAAA9qB,IAAA,QAAA+sB,EACAjC,GAAA9qB,IAAA,aAAAgtB,EACAlC,GAAA9qB,IAAA,eAAAitB,GAGA,QAAAJ,KACA,GAAA/B,EAAAwC,eAAA,CACAX,EAAAY,sBACA,CACAZ,EAAAa,uBAIA,QAAAT,KAIA,GAAAX,KAAAC,IAAAvB,EAAAjG,WAAAiG,EAAA2C,eAAA,EAAA,CACA,OAGAd,EAAAI,YACAnC,GAAAsC,KAAApC,GAAA,OAAA,aAAA,kBAAA,SAAAsC,GACA,GAAAA,EAAAhJ,OAAA,OAAA,CACAuI,EAAAe,iBAKA,QAAAV,KACA,GAAAW,GAAA7C,EAAA2C,cAAA,GACAd,GAAAK,cAAAW,GAGA,QAAAb,KACAH,EAAAG,kBACAH,GAAAiB,oBAGA,QAAAX,KACA,GAAAY,GAAA/C,EAAA+C,OACA,IAAAA,EAAA,CACAlB,EAAAmB,gBACA,IAAAlB,EAAA,CACAD,EAAAoB,cAEAnB,EAAAiB,GAIAhD,GAAA5vB,UAAAmwB,eAAA,QAAA4C,GAAAlC,EAAAa,EAAAnF,EAAA5rB,GACA,GAAAqyB,EACA,IAAAxe,GAAAlU,IAEA,IAAA6kB,EAAA2J,SAAAvC,EAAAvC,YAAA,CACAgJ,EAAAzG,EAAAvC,WAAA,GACAiJ,GAAA3yB,KAAAuvB,OAAAmD,GAEAryB,EAAA,KAAAkwB,EAAAa,EAAAnF,EAGA,SAAA0G,GAAApD,EAAAqD,GACA,GAAAC,GAAAC,EAAAvD,EACA,IAAAwD,GAAAC,EAAA7gB,KAAA+B,EAAA2e,EAAAD,EAAArD,EAEAA,GAAAnoB,KAAAyH,YAAAgkB,EACAtD,GAAAhrB,GAAA,aAAAwuB,EAEA1D,GAAAsC,KAAApC,GAAA,aAAA,kBAAA0D,EAEA,SAAAA,KACA1D,EAAA9qB,IAAA,aAAAsuB,EACA3D,GAAAjkB,OAAA0nB,IAIA,QAAAC,GAAAvD,GACA,GAAAsD,GAAA5oB,OAAArB,SAAA+F,cAAA,MACAygB,GAAA8D,SAAAL,EAAA,mBAEAA,GAAAM,QAAA,SAAA11B,GACA,GAAA2xB,EAAAgE,SAAAP,EAAA,WAAA,CACAzB,EAAAiC,WACA9D,GAAArjB,QAAA,eAIA,GAAAjC,OAAAqpB,MAAA5zB,UAAA6zB,kBAAAnzB,UAAA,CACA3C,EAAA81B,sBACA,CACA,MAAA,QAIA,OAAAV,GAGA,QAAAG,GAAAH,EAAAD,EAAArD,GACA,GAAAiE,GAAA3C,KAAA4C,KAAAb,EAAArD,EAAA2C,cACA,IAAAsB,EAAA,EAAA,CACAX,EAAAjkB,UAAA,WAAAiW,EAAA6O,cAAAF,EAAA,GAAA,UACA,CACA,IAAApE,EAAAgE,SAAAP,EAAA,WAAA,CACAzD,EAAA8D,SAAAL,EAAA,UACAA,GAAAjkB,UAAA,aAMA0gB,GAAA5vB,UAAAkwB,iBAAA,QAAA+D,GAAAlK,EAAA2H,EAAAnF,EAAA5rB,GACA,GAAAkvB,GAAAvvB,KAAAuvB,MACA,IAAAqE,GAAAC,EAAAtE,EAAA6B,EAAAnF,EACA,IAAA6H,GAAAC,EAAA5hB,KAAAnS,KAAA4zB,EAAA3H,EAAAsD,EAEAA,GAAAnoB,KAAA4X,aAAA4U,EAAArE,EAAAyE,WAAA5sB,KACAmoB,GAAAhrB,GAAA,aAAAuvB,EACAzE,GAAAsC,KAAApC,GAAA,aAAA,kBAAA0E,EAEA,OAAA5zB,GAAA,KAAAopB,EAAA2H,EAAAnF,EAIA,SAAA4H,GAAAtE,EAAA6B,EAAAnF,GACA,GAAA2H,GAAA3pB,OAAArB,SAAA+F,cAAA,IACA,IAAAulB,GAAAjI,EAAAkI,YAEA/E,GAAA8D,SAAAU,EAAA,eACAA,GAAAQ,KAAAC,EAAAH,EAAA3E,EAEA,IAAA1K,EAAAwI,SAAA6G,GAAA,CACAN,EAAA90B,OAAA,SAGA80B,EAAAT,QAAA,SAAA11B,GACA,GAAA8xB,EAAAa,SAAA,CACAb,EAAAW,MAGA,IAAAjmB,OAAAqpB,MAAA5zB,UAAA6zB,kBAAAnzB,UAAA,CACA3C,EAAA81B,kBAEA,MAAA,OAGAhE,EAAAU,OACAmB,GAAAkD,aAGA,OAAAV,GAGA,QAAAG,GAAAH,EAAA3H,EAAAsD,GACAqE,EAAAQ,KAAAC,EAAApI,EAAAkI,aAAA5E,GAGA,QAAA8E,GAAAH,EAAA3E,GACA,GAAAgF,IACAC,SAAA/K,EAAA5S,IACA4d,gBAAA7M,EAAA8M,eAAAnF,EAAA2C,cAAA,KAGA,OAAAgC,GAAAtM,EAAA+M,cAAAT,EAAAK,GAAA,IAGA,QAAAN,KACA1E,EAAA9qB,IAAA,aAAAqvB,EACA1E,GAAAjkB,OAAAyoB,IAIAtE,GAAA5vB,UAAAqwB,gBAAA,QAAA6E,GAAArE,EAAAtE,EAAA5rB,GACA,GAAAkvB,GAAAvvB,KAAAuvB,MAEAA,GAAAsF,QAAA,OACAtF,GAAA1Y,IAAA0Z,EAEAlB,GAAAsC,KAAApC,GAAA,iBAAA,QAAA,kBAAA,SAAAsC,GACA,GAAAA,EAAAhJ,OAAA,iBAAA,CACA2G,QACA,IAAAqC,EAAAhJ,OAAA,QAAA,CACAxoB,EAAA,GAAA0qB,GAAA,qDAAA,KAAAkB,KAMA,SAAAuD,KAEAH,EAAAsC,KAAApC,GAAA,UAAA,kBAAA,SAAAsC,GACA,GAAAA,EAAAhJ,OAAA,iBAAA,CACA,OAGA0G,EAAArjB,QAAA,eAEAqjB,GAAAhrB,GAAA,QAAAuwB,EACAvF,GAAAhrB,GAAA,iBAAAuwB,EACAvF,GAAAhrB,GAAA,cAAAuwB,EAEA,SAAAA,GAAAjD,GAEA,GAAAA,EAAAhJ,OAAA,SAAA0G,EAAAjG,WAAAiG,EAAA2C,cAAA,EAAA,CAGA,OAGA3C,EAAA9qB,IAAA,QAAAqwB,EACAvF,GAAA9qB,IAAA,iBAAAqwB,EACAvF,GAAA9qB,IAAA,cAAAqwB,EAGA,IAAAjD,EAAAhJ,OAAA,SAAAgJ,EAAAhJ,OAAA,cAAA,CACAxoB,EAAA,KAAA4rB,MAKAsD,GAAAW,QAIAZ,GAAA5vB,UAAA6sB,YAAA,QAAAwI,GAAAttB,EAAAwkB,GACArE,EAAA8G,MAAAzC,EAAAT,gBAAAmD,UAAAlnB,EAAApJ,MAAA,MAGAM,GAAAJ,QAAA+wB,IvB+pHGV,oBAAoB,GAAGoG,kBAAkB,GAAGC,0BAA0B,GAAGzO,+BAA+B,GAAGuI,cAAc,GAAGC,iBAAiB,GAAGkG,gBAAgB,GAAGlM,aAAa,KAAKmM,IAAI,SAASl3B,EAAQU,EAAOJ,GwBpgIpN,YAEA,IAAA4lB,GAAAlmB,EAAA,OACA,IAAAkrB,GAAAlrB,EAAA,gBACA,IAAA2oB,GAAA3oB,EAAA,WACA,IAAAgmB,GAAAhmB,EAAA,WACA,IAAAimB,GAAAjmB,EAAA,YAEA,IAAA4mB,GAAA5mB,EAAA,+BACA,IAAA6mB,GAAA7mB,EAAA,kBAEAgM,QAAAmrB,UAAAnR,CACA,SAAA+G,KACA,KAAAhrB,eAAAgrB,IAAA,CACA,MAAA,IAAAA,GAGAhrB,KAAAq1B,aAAA,KACAr1B,MAAAssB,MACAtsB,MAAAwrB,iBACAxrB,MAAAgoB,cACAhoB,MAAAs1B,iBACAt1B,MAAAu1B,eACAv1B,MAAAimB,iBACAjmB,MAAAupB,aACAvpB,MAAAm0B,aAAA/zB,SACAJ,MAAA8nB,QAAA,EACA9nB,MAAAspB,SAAAlpB,SACAJ,MAAA0pB,WAAAtpB,UAGA4qB,EAAAtrB,UAAAyuB,MAAA,SAAAlB,GACA,GAAA1I,GAAAC,CACA,IAAAyI,YAAA9I,GAAA,CACAI,EAAA0I,EAAA1I,MACAC,GAAAyI,EAAAzI,OAEAxkB,MAAAssB,IAAA9e,KAAAyf,EAEA,IAAA1I,EAAA,CACAvkB,KAAAw1B,WAAAjR,GAGA,GAAAC,EAAA,CACAxkB,KAAAy1B,YAAAjR,KAKAwG,GAAAtrB,UAAAg2B,kBAAA,SAAAjuB,GACA,GAAAkuB,GAAAluB,YAAAqd,GAAA8Q,SAAA9Q,EAAAK,SAAA1d,GAAAA,CACA,IAAAkuB,EAAA,CACA31B,KAAAwrB,eAAAhe,KAAAmoB,IAIA3K,GAAAtrB,UAAAm2B,gBAAA,SAAA7N,GACAnD,EAAAyB,QAAA0B,IAAA8N,EAAA91B,KAAAgoB,YAAAA,GAGAgD,GAAAtrB,UAAAkwB,iBAAA,SAAAuE,GACA,GAAAtP,EAAA8D,iBAAAwL,GAAA,CACAn0B,KAAAm0B,aAAAA,GAIAnJ,GAAAtrB,UAAAq2B,mBAAA,SAAAT,GACAzQ,EAAAyB,QAAAgP,IAAAQ,EAAA91B,KAAAs1B,eAAAA,GAGAtK,GAAAtrB,UAAAs2B,iBAAA,SAAAT,GACA1Q,EAAAyB,QAAAiP,IAAAO,EAAA91B,KAAAu1B,aAAAA,GAGAvK,GAAAtrB,UAAAu2B,mBAAA,SAAAhQ,GACA,GAAAiQ,GAAAl2B,KAAAimB,cAEA,IAAAA,EAAA,CACAA,EAAApB,EAAAyB,QAAAL,GAAAA,GAAAA,EACAA,GAAAjiB,QAAA,SAAAmyB,GACA,IAAAD,EAAAC,EAAAplB,MAAA,CACAmlB,EAAAC,EAAAplB,SAEAmlB,EAAAC,EAAAplB,MAAAvD,KAAA2oB,MAKAnL,GAAAtrB,UAAA02B,UAAA,SAAAvX,GACA,GAAAgG,EAAA8D,iBAAA9J,GAAA,CACA7e,KAAA8nB,QAAAjJ,GAIAmM,GAAAtrB,UAAA22B,aAAA,SAAA/M,GACA,GAAAzE,EAAA2J,SAAAlF,GAAA,CACAtpB,KAAAspB,SAAAA,GAIA0B,GAAAtrB,UAAA42B,gBAAA,SAAA1M,GACA,GAAAA,YAAAT,GAAA,CACAnpB,KAAA4vB,iBAAAhG,EAAAuK,aACAn0B,MAAA+1B,mBAAAnM,EAAA0L,eACAt1B,MAAAg2B,iBAAApM,EAAA2L,eAIAvK,GAAAtrB,UAAA62B,eAAA,SAAAhN,GACA1E,EAAAyB,QAAAiD,IAAAuM,EAAA91B,KAAAupB,WAAAA,GAGAyB,GAAAtrB,UAAA82B,eAAA,SAAA7M,GACA,GAAAA,EAAA,CACA3pB,KAAA0pB,WAAAC,GAIAqB,GAAAtrB,UAAA+2B,iBAAA,SAAA5M,GACA,GAAAA,EAAA,CACA7pB,KAAA6pB,aAAAA,GAIAmB,GAAAtrB,UAAAg3B,WAAA,SAAA1P,GACA,GAAAA,YAAAJ,GAAA,CACA5mB,KAAAq2B,aAAArP,EAAAsC,SACAtpB,MAAAi2B,mBAAAjP,EAAAf,eACAjmB,MAAAs2B,gBAAAtP,EAAA4C,YACA5pB,MAAAu2B,eAAAvP,EAAAuC,WACAvpB,MAAAw2B,eAAAxP,EAAA0C,WACA1pB,MAAAy2B,iBAAAzP,EAAA6C,aACA7pB,MAAAq1B,aAAA,MAIArK,GAAAtrB,UAAA81B,WAAA,SAAAjR,GACA,GAAArQ,GAAAlU,IAEA,IAAAukB,YAAAN,GAAA,CACAjkB,KAAAo2B,UAAA7R,EAAAuD,QACA9nB,MAAA01B,kBAAAnR,EAAA9c,MACAzH,MAAA61B,gBAAAtR,EAAAyD,YAEAzD,GAAAgD,UAAAvjB,QAAA,SAAAmM,GACA,GAAAA,EAAA6W,OAAA,CACA9S,EAAAwiB,WAAAvmB,EAAA6W,YAMAgE,GAAAtrB,UAAA+1B,YAAA,SAAAjR,GACA,GAAAtQ,GAAAlU,IAEA,IAAAwkB,YAAAN,GAAA,CACAlkB,KAAA01B,kBAAAlR,EAAA/c,MACAzH,MAAA61B,gBAAArR,EAAAwD,YAEAxD,GAAA+C,UAAAvjB,QAAA,SAAAmM,GACA,GAAA6W,GAAA7W,EAAA6W,MACA,IAAAA,EAAA,CACA9S,EAAAoiB,gBAAAtP,EAAA4C,YACA1V,GAAAigB,aAAA/zB,SACA8T,GAAA+hB,mBAAAjP,EAAAf,oBAMA+E,GAAAtrB,UAAA4uB,UAAA,WACA,MAAAtuB,MAAAq1B,aAGA,SAAAS,GAAAa,EAAAC,GACAA,EAAA5yB,QAAA,SAAA6yB,GACAF,EAAAnpB,KAAAqpB,KAIAl4B,EAAAJ,QAAAysB,IxBwgIGxE,+BAA+B,GAAGC,kBAAkB,GAAGqI,OAAO,GAAGrK,WAAW,GAAGiD,WAAW,GAAGwC,gBAAgB,GAAGxF,YAAY,KAAKoS,IAAI,SAAS74B,EAAQU,EAAOJ,GyB5rIhK,YAEA,IAAAwsB,GAAA9sB,EAAA,cACA,IAAA+sB,GAAA/sB,EAAA,iBACA,IAAA2pB,GAAA3pB,EAAA,aACA,IAAA4mB,GAAA5mB,EAAA,+BAEA,SAAAkxB,GAAA4H,EAAAtH,GACA,KAAAzvB,eAAAmvB,IAAA,CACA,MAAA,IAAAA,GAAA4H,EAAAtH,GAGAzvB,KAAA2rB,YAAAoL,EAAAtH,EACAzvB,MAAAqkB,WAAA0S,EAAAtH,GAIAN,EAAAzvB,UAAA2kB,WAAA,SAAA0S,EAAAtH,GACAzvB,KAAAisB,SAAAwD,CACAzvB,MAAA+2B,SAAAA,CACA/2B,MAAAquB,SAAA,CACAruB,MAAAg3B,WACAC,eAAAC,QAAA,MAAAC,KAAAtG,KAAAuG,MAAA,GAAA3H,EAAAnG,UAAA,KACA+N,UAAAH,QAAA,MAAAC,KAAAtG,KAAAuG,MAAA,GAAA3H,EAAAnG,UAAA,KACAgO,eAAAJ,QAAA,MAAAC,KAAAtG,KAAAuG,MAAA,GAAA3H,EAAAnG,UAAA,MAIA6F,GAAAzvB,UAAAisB,YAAA,SAAAoL,EAAAtH,GACA,IAAA5K,EAAAwI,SAAA0J,IAAAlS,EAAA0S,cAAAR,GAAA,CACA,KAAA,IAAAhM,GAAA,qFAGA,KAAA0E,YAAAzE,IAAA,CACA,KAAA,IAAAD,GAAA,+DAIAoE,GAAAzvB,UAAA83B,UAAA,QAAAA,GAAAC,EAAAlD,GACA,GAAA1P,EAAAyB,QAAAmR,IAAAA,EAAAh5B,OAAA,EAAA,CACA81B,EAAA1P,EAAAzS,QACAoiB,SAAAx0B,KAAA+2B,SACAtC,gBAAA7M,EAAA8M,eAAA10B,KAAAquB,WACAkG,MAEA3M,GAAA8G,MAAA+I,EAAAlD,IAIApF,GAAAzvB,UAAAg4B,WAAA,QAAAA,GAAAlzB,EAAAmzB,GACA33B,KAAAw3B,UAAAI,EAAA53B,KAAAisB,SAAAhG,eAAAzhB,IACA,IAAAmzB,EAAA,CACA33B,KAAAisB,SAAAhG,eAAAzhB,GAAApE,UAIA,QAAAw3B,GAAA3R,GACA,GAAA4R,EAEA,IAAA5R,EAAA,CACA4R,IACA5R,GAAAjiB,QAAA,SAAAI,GACAyzB,EAAArqB,KAAApJ,EAAAwkB,OAGA,MAAAiP,IAIA1I,GAAAzvB,UAAA+xB,cAAA,QAAAA,GAAAqG,GACA,GAAA5jB,GAAAlU,IACA,IAAA+3B,KACA,IAAAC,GAAA,IACA,IAAAC,GAAA,KACA,IAAAhS,GAAAjmB,KAAAisB,SAAAhG,cAEA,IAAApB,EAAA2J,SAAAsJ,GAAA,CACAI,EAAA,QAAAF,EAAAF,EAAA,EACAI,GAAA,SAAAD,EAAAE,EAAAn4B,KAAAquB,SAAAyJ,GACAM,GAAAN,EACAO,GAAAP,EACAQ,IACAt4B,MAAAquB,SAAAyJ,EAIA,QAAAK,GAAAI,EAAAC,GACA,GAAAC,GAAA,GACA,OAAAF,GAAAT,GAAAjH,KAAAC,IAAA0H,EAAAD,GAAAE,EAGA,QAAAP,GAAA1zB,EAAAmzB,EAAAe,GACA,GAAAzS,EAAAzhB,IAAAk0B,EAAA,CACAX,EAAAvqB,MACAuD,KAAAvM,EACAmzB,YAAAA,KAKA,QAAAS,GAAA/J,GACA,GAAA2I,GAAA9iB,EAAA8iB,SACA,IAAAC,GAAA/iB,EAAA8iB,UAAAC,aACA,IAAAI,GAAAnjB,EAAA8iB,UAAAK,QACA,IAAAC,GAAApjB,EAAA8iB,UAAAM,aAEA,KAAAL,EAAAC,QAAA,CACAyB,EAAA,gBAAAtK,OACA,KAAAgJ,EAAAH,QAAA,CACAyB,EAAA,WAAAtK,OACA,KAAAiJ,EAAAJ,QAAA,CACAyB,EAAA,gBAAAtK,GAIA,QAAAsK,GAAAC,EAAAvK,GACA,GAAAwK,GAAA7B,EAAA4B,EACA,IAAAE,EAAAD,EAAAxK,GAAA,CACAwK,EAAA3B,QAAA,IACAgB,GAAAU,EAAAZ,EAAA,QAKA,QAAAc,GAAAD,EAAAxK,GACA,GAAA0K,GAAAF,EAAA1B,IAEA,OAAA9I,IAAA0K,GAAA1K,GAAA0K,EAAA,IAGA,QAAAV,GAAAhK,GACA,IAAAxJ,EAAAyB,QAAAL,EAAAoI,UAAA,CACA,OAGA,GAAA2K,KAEA/S,GAAAoI,SAAArqB,QAAA,SAAA6tB,GACA,GAAAA,EAAAlI,QAAA0E,EAAA,CACAna,EAAAsjB,WAAA3F,EAAAjJ,UACA,CACAoQ,EAAAxrB,KAAAqkB,KAGA5L,GAAAoI,SAAA2K,EAGA,QAAAV,KACAP,EAAA/zB,QAAA,SAAAI,GACA8P,EAAAwjB,WAAAtzB,EAAA2M,KAAA3M,EAAAuzB,gBAMA,SACA,aACA,iBACA,QACA,SACA,OACA,SACA,mBACA,yBACA,WACA,UACA3zB,QAAA,SAAAQ,GACA2qB,EAAAzvB,UAAA,QAAAmlB,EAAAoU,WAAAz0B,IAAA,WACAxE,KAAA03B,WAAAlzB,OAKA,QACA,OACA,QACA,eACAR,QAAA,SAAAQ,GACA2qB,EAAAzvB,UAAA,QAAAmlB,EAAAoU,WAAAz0B,IAAA,WACAxE,KAAA03B,WAAAlzB,EAAA,UAKA,gBACA,WACA,iBACAR,QAAA,SAAA60B,GACA1J,EAAAzvB,UAAA,QAAAmlB,EAAAoU,WAAAJ,IAAA,WACA74B,KAAAg3B,UAAA6B,GAAA3B,QAAA,IACAl3B,MAAA03B,WAAAmB,EAAA,QAIA1J,GAAAzvB,UAAAoyB,cAAA,WACA,GAAA9xB,KAAAg3B,UAAAM,cAAAJ,QAAA,CACAl3B,KAAA03B,WAAA,WAAA,OAIAvI,GAAAzvB,UAAAw5B,mBAAA,QAAAA,GAAAC,GACA,GAAAtU,EAAA2J,SAAA2K,GAAA,CACAn5B,KAAAw3B,UAAAx3B,KAAAisB,SAAAT,gBAAAmD,UAAAwK,KAIAhK,GAAAzvB,UAAA6xB,iBAAA,QAAAA,KACAvxB,KAAAw3B,UAAAx3B,KAAAisB,SAAAjE,aAGAmH,GAAAzvB,UAAA2yB,kBAAA,QAAAA,KACAryB,KAAA03B,WAAA,gBAGAvI,GAAAzvB,UAAA40B,WAAA,QAAAA,KACAt0B,KAAAw3B,UAAAx3B,KAAAisB,SAAAqJ,gBAGA32B,GAAAJ,QAAA4wB,IzB+rIG3I,+BAA+B,GAAGuI,cAAc,GAAGC,iBAAiB,GAAGhG,aAAa,KAAKoQ,IAAI,SAASn7B,EAAQU,EAAOJ,G0Bz5IxH,YAEA,IAAAsmB,GAAA5mB,EAAA,+BACA,IAAA6mB,GAAA7mB,EAAA,kBAEA,SAAAkrB,GAAAkQ,GACA,KAAAr5B,eAAAmpB,IAAA,CACA,MAAA,IAAAA,GAAAkQ,GAGAr5B,KAAAm0B,aAAArP,EAAAK,SAAAkU,EAAAlF,aACAn0B,MAAAs1B,eAAAgE,EAAAD,EAAAE,cACAv5B,MAAAu1B,aAAA+D,EAAAD,EAAAG,YAGA,SAAAF,GAAA/S,GACA,GAAA+O,KACA,IAAA/O,EAAA,CACAA,EAAA1B,EAAAyB,QAAAC,GAAAA,GAAAA,EACAA,GAAAviB,QAAA,SAAAy1B,GACAnE,EAAA9nB,KAAAsX,EAAAK,SAAAsU,MAGA,MAAAnE,IAIA32B,EAAAJ,QAAA4qB,I1B25IG3C,+BAA+B,GAAGC,kBAAkB,KAAKiT,IAAI,SAASz7B,EAAQU,EAAOJ,G2Bt7IxF,YAEA,IAAAqpB,GAAA3pB,EAAA,aACA,IAAA4oB,GAAA5oB,EAAA,aAEA,IAAA4mB,GAAA5mB,EAAA,+BACA,IAAA6mB,GAAA7mB,EAAA,kBAEA,SAAAimB,GAAAyV,GACA,KAAA35B,eAAAkkB,IAAA,CACA,MAAA,IAAAA,GAAAyV,GAIA35B,KAAA+nB,SAAAjD,EAAAK,SAAAwU,EAAA5R,SACA/nB,MAAAgoB,YAAAJ,EAAAK,iBAAA0R,EAAAzR,WACAloB,MAAAwtB,aAAA1I,EAAAK,SAAAwU,EAAAC,aAGA55B,MAAAunB,UAAAV,EAAAQ,eAAAsS,EAAApS,UACAvnB,MAAAyH,MAAAqd,EAAAK,SAAAwU,EAAAlyB,MACAzH,MAAAwoB,WAAAmR,EAAAnR,UAGAxoB,MAAA65B,yBAAAhV,EAAAwB,UAAAvB,EAAA9E,KAAA2Z,EAAA,6BAAA7U,EAAA9E,KAAA2Z,EAAA,4BAAA,IACA35B,MAAA85B,iBAAAhV,EAAA9E,KAAA2Z,EAAA,mBACA35B,MAAA+5B,eAAAjV,EAAA9E,KAAA2Z,EAAA,kBAGAh7B,EAAAJ,QAAA2lB,I3By7IGsC,+BAA+B,GAAGC,kBAAkB,GAAGsC,aAAa,GAAGC,aAAa,KAAKgR,IAAI,SAAS/7B,EAAQU,EAAOJ,G4Bt9IxH,YAEA,IAAAsmB,GAAA5mB,EAAA,+BAEA,IAAAg8B,GAAA,mCAEA,IAAA7Q,IAEAE,SAAA,QAAA4Q,GAAAC,GAEA,GAAAC,GAAAC,CAEA,IAAAxV,EAAAwI,SAAA8M,GAAA,CACAC,EAAAD,EAAAC,MAAAH,EACA,IAAAG,EAAA,CACAC,EAAAC,EAAAF,EAAA,IAAAG,EAAAH,EAAA,IAAAI,EAAAJ,EAAA,IAAAzZ,SAAAyZ,EAAA,IAAA,IAIA,MAAAprB,OAAAqrB,GAAA,KAAAA,CAGA,SAAAC,GAAAG,GACA,MAAA9Z,UAAA8Z,EAAA,IAAA,GAAA,GAAA,IAGA,QAAAF,GAAAG,GACA,MAAA/Z,UAAA+Z,EAAA,IAAA,GAAA,IAGA,QAAAF,GAAAG,GACA,MAAAha,UAAAga,EAAA,IAAA,MAIAhR,OAAA,QAAAiR,GAAAjR,EAAAL,GACA,GAAAuR,EAAAlR,GAAA,CACA,MAAAmR,GAAAnR,EAAAL,GAEA,MAAAF,GAAAE,SAAAK,EAGA,SAAAkR,GAAAlR,GACA,GAAAoR,GAAA,iBACA,OAAAA,GAAA1gB,KAAAsP,GAGA,QAAAmR,GAAAE,EAAA1R,GACA,GAAAA,EAAA,CACA,MAAA2R,GAAA3R,EAAAra,WAAA+rB,EAAA3jB,QAAA,IAAA,MAEA,MAAA,MAGA,QAAA4jB,GAAAC,EAAAC,GACA,MAAAD,GAAAC,EAAA,MAOAx8B,GAAAJ,QAAA6qB,I5Bw9IG5C,+BAA+B,KAAK4U,IAAI,SAASn9B,EAAQU,EAAOJ,G6BthJnE,YAEA,IAAAsmB,GAAA5mB,EAAA,+BACA,IAAAo9B,GAAAp9B,EAAA,0BACA,IAAAq9B,GAAAr9B,EAAA,0BACA,IAAA6H,GAAA7H,EAAA;AAEA,GAAA2pB,IAEA8G,MAAA,QAAAA,GAAA6M,EAAAhH,GACA,GAAAiH,GAAA5T,EAAA6T,eAAAF,EAAAhH,EACA,IAAAmH,KACAF,GAAAx3B,QAAA,SAAA6S,GACA,GAAA8kB,GAAA,GAAAC,MACAD,GAAA9kB,IAAAA,CACA6kB,GAAAluB,KAAAmuB,IAEA,OAAAD,IAGAD,eAAA,QAAAI,GAAAN,EAAAhH,GACA,GAAAuH,KAEAvH,GAAAA,KAEA,KAAAA,EAAA,gBAAA,CACAA,EAAA,gBAAA1D,KAAAuG,MAAAvG,KAAAkL,SAAA,MAGAR,EAAAv3B,QAAA,SAAAg4B,GACAF,EAAAtuB,KAAAoa,EAAAqU,eAAAD,EAAAzH,KAGA,OAAAuH,IAGAnH,cAAA,QAAAuH,GAAAF,EAAAzH,GACAA,EAAAA,KAEA,KAAAA,EAAA,gBAAA,CACAA,EAAA,gBAAA1D,KAAAuG,MAAAvG,KAAAkL,SAAA,MAGA,MAAAnU,GAAAqU,eAAAD,EAAAzH,IAGA0H,eAAA,QAAAC,GAAAF,EAAAzH,GACAA,EAAAA,KAEA1P,GAAA7gB,QAAAuwB,EAAA,SAAA50B,EAAAL,GACA08B,EAAAA,EAAA3kB,QAAA,GAAAC,QAAA,MAAAhY,EAAA,MAAA,MAAAK,IAGA,OAAAq8B,IAGA9B,cAAA,QAAAA,GAAAC,GACA,GAAAF,GAAA,mCACA,IAAAG,GAAAC,CAEA,IAAAxV,EAAAwI,SAAA8M,GAAA,CACAC,EAAAD,EAAAC,MAAAH,EACA,IAAAG,EAAA,CACAC,EAAAC,EAAAF,EAAA,IAAAG,EAAAH,EAAA,IAAAI,EAAAJ,EAAA,IAAAzZ,SAAAyZ,EAAA,IAAA,IAIA,MAAAprB,OAAAqrB,GAAA,KAAAA,CAGA,SAAAC,GAAAG,GACA,MAAA9Z,UAAA8Z,EAAA,IAAA,GAAA,GAAA,IAGA,QAAAF,GAAAG,GACA,MAAA/Z,UAAA+Z,EAAA,IAAA,GAAA,IAGA,QAAAF,GAAAG,GACA,MAAAha,UAAAga,EAAA,IAAA,MAIA1S,iBAAA,QAAAA,GAAAD,GACA,GAAAA,EAAA,CACAA,EAAAnD,EAAAyB,QAAA0B,GAAAA,GAAAA,EACA,OAAAnD,GAAA6D,eAAAV,EAAA,SAAAE,GACA,GAAArD,EAAA8D,iBAAAT,EAAA/C,UAAA,CACA,MAAA+C,GAAA/C,SAEA,MAAA/kB,aAGA,UAKAs0B,eAAA,QAAAA,GAAArG,GACA,GAAA8N,GAAAC,EAAAC,EAAAC,CACAH,GAAA9N,GAAA,GAAA,GAAA,IACA8N,GAAAtL,KAAA0L,MAAAJ,EACAC,GAAA/N,GAAA,GAAA,KAAA,EACA+N,GAAAvL,KAAA0L,MAAAH,EACAC,GAAAhO,EAAA,IAAA,EACAgO,GAAAxL,KAAA0L,MAAAF,EACAC,GAAAjO,EAAA,GACA,OAAAxJ,GAAA6O,cAAAyI,EAAA,GAAA,IAAAtX,EAAA6O,cAAA0I,EAAA,GAAA,IAAAvX,EAAA6O,cAAA2I,EAAA,GAAA,IAAAxX,EAAA6O,cAAA4I,EAAA,IAGA1B,YAAA,QAAAA,GAAAjR,EAAAL,GACA,GAAAuR,EAAAlR,GAAA,CACA,MAAAmR,GAAAnR,EAAAL,GAEA,MAAA1B,GAAAsS,cAAAvQ,EAGA,SAAAkR,GAAAlR,GACA,GAAAoR,GAAA,iBACA,OAAAA,GAAA1gB,KAAAsP,GAGA,QAAAmR,GAAAE,EAAA1R,GACA,GAAAA,EAAA,CACA,MAAA2R,GAAA3R,EAAAra,WAAA+rB,EAAA3jB,QAAA,IAAA,MAEA,MAAA,MAGA,QAAA4jB,GAAAC,EAAAC,GACA,MAAAD,GAAAC,EAAA,MAMAqB,aACAlB,EACAD,GAGA5Q,QAAA,QAAAgS,GAAAhT,GACA,QAAAA,GAAAA,EAAA1D,eAAA,SAGA2E,uBAAA,QAAAA,GAAAgS,GACA,GAAAx+B,GAAA4qB,EAAA6T,CAEA,KAAAz+B,EAAA,EAAA4qB,EAAA9oB,KAAAw8B,YAAA/9B,OAAAP,EAAA4qB,EAAA5qB,GAAA,EAAA,CACAy+B,EAAA38B,KAAAw8B,YAAAt+B,EACA,IAAAy+B,EAAAC,SAAAF,GAAA,CACA,MAAAC,IAGA,MAAA,OAGAhS,iBAAA,QAAAA,KACA,MAAA7kB,GAAAD,eASAg3B,qBAAA,QAAAA,GAAAC,GACAh3B,EAAAi3B,cAAA92B,KAAA62B,KAKAn+B,GAAAJ,QAAAqpB,I7ByhJGpB,+BAA+B,GAAGwW,0BAA0B,GAAGC,0BAA0B,GAAGC,uCAAuC,IAAIC,IAAI,SAASl/B,EAAQU,EAAOJ,G8BtsJtK,YAEA,IAAAwsB,GAAA9sB,EAAA,oBAEA,IAAA4mB,GAAA5mB,EAAA,+BAEA,SAAAm/B,GAAAC,EAAAC,GACA,KAAAt9B,eAAAo9B,IAAA,CACA,MAAA,IAAAA,GAAAC,EAAAC,GAEA3R,EAAA0R,EAAAC,EAEAt9B,MAAAorB,QAAAvG,EAAAzS,UAAAkrB,EAEAt9B,MAAAgI,QAAAq1B,CAGA,SAAA1R,GAAA5W,EAAAuoB,GACA,IAAAvoB,IAAAqoB,EAAAxsB,oBAAAmE,GAAA,CACA,KAAA,IAAAgW,GAAA,+FAGA,IAAAlG,EAAA0Y,SAAAD,GAAA,CACA,KAAA,IAAAvS,GAAA,0DAAAuS,EAAA,KAGA,KAAA,mBAAAA,MAAAzY,EAAA2J,SAAA8O,EAAAE,iBAAA,CACA,KAAA,IAAAzS,GAAA,gEAKAqS,EAAAxsB,oBAAA,QAAAA,GAAArN,GAEA,GAAAk6B,IACA,mBAAA,SAAA,UAAA,SAAA,WAAA,UAAA,WAAA,aAGA,KAAA,GAAAv/B,GAAA,EAAA4qB,EAAA2U,EAAAh/B,OAAAP,EAAA4qB,EAAA5qB,IAAA,CACA,IAAAqF,IAAAshB,EAAA+G,WAAAroB,EAAAk6B,EAAAv/B,KAAA,CACA,MAAA,QAKA,MAAAw/B,GAAAn6B,IAAAo6B,EAAAp6B,EAIA,SAAAm6B,GAAA3oB,GACA,MAAA8P,GAAA+G,WAAA7W,EAAAzE,YAAAuU,EAAA+G,WAAA7W,EAAAhC,mBAAA8R,EAAA+G,WAAA7W,EAAAxQ,IAGA,QAAAo5B,GAAA5oB,GACA,MAAA8P,GAAA+G,WAAA7W,EAAAvE,cAAAqU,EAAA+G,WAAA7W,EAAAW,sBAAAmP,EAAA+G,WAAA7W,EAAAtQ,MAKA24B,GAAA19B,UAAAk+B,gBAAA,WACA,GAAAryB,GAAAsZ,EAAAgZ,oBAAA19B,UACA,IAAAwQ,GAAApF,EAAAkhB,OACA,IAAAzP,GAAAzR,EAAA0G,KACA,IAAA6rB,EAEAnS,GAAAhb,EAAAqM,EAAAhd,KAAAgI,QACAuD,GAAAiC,KAAAuwB,IAEA/9B,MAAAgI,QAAA2I,GAAAnC,MAAAxO,KAAAgI,QAAAuD,EACAuyB,GAAAp2B,WAAA,WACAo2B,EAAA,IACA9gB,GAAA,GAAA+N,GAAA,wEAAApa,EAAA,KACAqM,GAAA6H,EAAA1f,MACAnF,KAAAorB,QAAAoS,gBAGA,SAAA7R,GAAAhb,EAAAqM,EAAAjI,GACA,IAAA8P,EAAAwI,SAAA1c,KAAAkU,EAAA+G,WAAA7W,EAAApE,IAAA,CACA,KAAA,IAAAoa,GAAA,8DAGA,IAAAlG,EAAA+G,WAAA5O,GAAA,CACA,KAAA,IAAA+N,GAAA,4DAIA,QAAAgT,KACA,MAAA,YACA,GAAAD,EAAA,CACAvvB,aAAAuvB,GAEA9gB,EAAAxO,MAAAxO,KAAAG,aAKAi9B,GAAA19B,UAAA6E,GAAA,SAAAy5B,EAAA12B,GACA,GAAAyL,GAAA/S,KAAAgI,QAAA+K,kBAAA/S,KAAAgI,QAAAsI,WAAAtQ,KAAAgI,QAAAzD,EACAwO,GAAAvU,KAAAwB,KAAAgI,QAAAg2B,EAAA12B,GAGA81B,GAAA19B,UAAA+E,IAAA,SAAAu5B,EAAA12B,GACA,GAAAoO,GAAA1V,KAAAgI,QAAA0N,qBAAA1V,KAAAgI,QAAAwI,aAAAxQ,KAAAgI,QAAAvD,GACAiR,GAAAlX,KAAAwB,KAAAgI,QAAAg2B,EAAA12B,GAGA81B,GAAA19B,UAAAu+B,aAAA,SAAAD,EAAAhhB,EAAAzM,GACA,GAAAutB,EACAnS,GAAAqS,EAAAhhB,EACAzM,GAAAA,GAAA,IAEAvQ,MAAAuE,GAAAy5B,EAAAE,EAEAJ,GAAAp2B,WAAA,WACAsV,EAAA,GAAA+N,GAAA,wEAAAiT,EAAA,KACAF,GAAA,IACA9gB,GAAA6H,EAAA1f,MACAnF,KAAAorB,QAAAoS,gBAGA,SAAA7R,GAAAqS,EAAAhhB,GACA,IAAA6H,EAAAwI,SAAA2Q,GAAA,CACA,KAAA,IAAAjT,GAAA,wDAGA,IAAAlG,EAAA+G,WAAA5O,GAAA,CACA,KAAA,IAAA+N,GAAA,yDAIA,QAAAmT,KACA,GAAA3yB,GAAAsZ,EAAAgZ,oBAAA19B,UAEA,IAAA29B,EAAA,CACAvvB,aAAAuvB,EACAA,GAAA,KAGAvyB,EAAA4yB,QAAA,KACAnhB,GAAAxO,MAAA+B,EAAAhF,IAKA6xB,GAAA19B,UAAAO,iBAAA,SAAA8jB,EAAA/G,GACAhd,KAAA49B,gBAAA,mBAAA7Z,EAAA/G,GAIAogB,GAAA19B,UAAAY,OAAA,SAAAC,EAAAC,EAAAC,EAAAC,EAAA09B,EAAAphB,GACAhd,KAAAi+B,aAAA,WAAAjhB,EACAhd,MAAAgI,QAAA1H,OAAAC,EAAAC,EAAAC,EAAAC,EAAA09B,GAGAhB,GAAA19B,UAAAqB,SAAA,SAAAR,EAAAC,EAAAC,EAAAuc,GAGAhd,KAAA49B,gBAAA,WAAAr9B,EAAAC,EAAAC,EAAAuc,GAGAogB,GAAA19B,UAAAsB,QAAA,SAAAgc,GACAhd,KAAAi+B,aAAA,YAAAjhB,EACAhd,MAAAgI,QAAAhH,UAGAo8B,GAAA19B,UAAAuB,OAAA,SAAA+b,GACAhd,KAAAi+B,aAAA,YAAAjhB,EACAhd,MAAAgI,QAAA/G,SAGAm8B,GAAA19B,UAAAwB,QAAA,SAAA8b,GACAhd,KAAAi+B,aAAA,WAAAjhB,EACAhd,MAAAgI,QAAA9G,UAGAk8B,GAAA19B,UAAAyB,SAAA,SAAA6b,GACAhd,KAAAi+B,aAAA,YAAAjhB,EACAhd,MAAAgI,QAAA7G,WAGAi8B,GAAA19B,UAAA0B,SAAA,SAAA4b,GACAhd,KAAAi+B,aAAA,mBAAAjhB,EACAhd,MAAAgI,QAAA5G,WAGAg8B,GAAA19B,UAAA2B,WAAA,SAAA2b,GACAhd,KAAAi+B,aAAA,mBAAAjhB,EACAhd,MAAAgI,QAAA3G,aAGA+7B,GAAA19B,UAAA4B,OAAA,SAAA0b,GACAhd,KAAAi+B,aAAA,YAAAjhB,EACAhd,MAAAgI,QAAA1G,WAKA,WACA,UACA,WACA,aACA,mBACA,kBACA,aACA,WACA,eACA,WACA0C,QAAA,SAAAX,GACA,GAAAg7B,GAAA,MAAAxZ,EAAAoU,WAAA51B,EAEA+5B,GAAA19B,UAAA2+B,GAAA,SAAArhB,GACAhd,KAAA49B,gBAAAS,EAAArhB,KAKAogB,GAAA19B,UAAAoC,YAAA,SAAAgD,EAAAkY,GACAhd,KAAA49B,gBAAA,cAAA94B,EAAAkY,GAGAre,GAAAJ,QAAA6+B,I9BysJG5W,+BAA+B,GAAG8X,oBAAoB,KAAKC,IAAI,SAAStgC,EAAQU,EAAOJ,G+Br6J1F,YAEA,IAAAwsB,GAAA9sB,EAAA,oBAEA,IAAA6H,GAAA7H,EAAA,uCAEA,IAAA4mB,GAAA5mB,EAAA,+BACA,IAAAmxB,GAAAnxB,EAAA,kBAEA,SAAAq9B,GAAA7R,EAAA8B,GACA,KAAAvrB,eAAAs7B,IAAA,CACA,MAAA,IAAAA,GAAA7R,GAEAkC,EAAAlC,EACAzpB,MAAA+Q,KAAA,aACA/Q,MAAAypB,UAAAA,CACAzpB,MAAAw+B,YAAA,IACAx+B,MAAAy+B,iBAAA,IACAz+B,MAAAurB,SAAAA,CAGA,SAAAI,GAAAlC,GACA,IAAAA,IAAA5E,EAAAwI,SAAA5D,EAAA5S,KAAA,CACA,KAAA,IAAAkU,GAAA,0CAKAuQ,EAAAx1B,iBAAAA,CAEAw1B,GAAAsB,SAAA,SAAA/T,GACA,MAAAA,KAAA,iCAAAyS,EAAAx1B,iBAAAD,cAGAy1B,GAAA57B,UAAAuI,WAAA,QAAAy2B,GAAAF,EAAAG,EAAAt+B,GACA,GAAA6T,GAAAlU,IACA,IAAA4+B,GAAA5+B,KAAAurB,UAAAvrB,KAAAurB,SAAAuR,sBAAA72B,KAAAjG,KAAAurB,SAAAuR,sBAAA18B,SACAurB,GAAA6S,EAAAn+B,EAEAL,MAAAw+B,YAAAA,CACAx+B,MAAAy+B,iBAAA,GAAAnD,GAAAx1B,iBAAA04B,EAAA,SAAA/2B,GACA,GAAAA,EAAA,CACA,MAAApH,GAAAoH,GAGAyM,EAAAuqB,iBAAAx2B,WAAAiM,EAAAuV,UAAA5S,IAAAxW,IACAu+B,EAGA,SAAAjT,GAAAkT,EAAA7hB,GAEA,IAAAoS,EAAA0P,aAAAD,GAAA,CACA,KAAA,IAAA9T,GAAA,+DAGA,IAAAlG,EAAA+G,WAAA5O,GAAA,CACA,KAAA,IAAA+N,GAAA,0DAKAuQ,GAAA57B,UAAA6I,aAAA,WACA,GAAAvI,KAAAy+B,iBAAA,CACA,IACAz+B,KAAAy+B,iBAAA92B,UACA,MAAAlK,GACA,GAAAshC,SAAAla,EAAA+G,WAAAmT,QAAAC,KAAA,CACAD,QAAAC,IAAA,kDAGAh/B,KAAAy+B,iBAAA,KAGA,GAAAz+B,KAAAw+B,YAAA,CACApP,EAAAjkB,OAAAnL,KAAAw+B,YACAx+B,MAAAw+B,YAAA,MAIA7/B,GAAAJ,QAAA+8B,I/Bw6JGtG,kBAAkB,GAAGxO,+BAA+B,GAAG8X,oBAAoB,GAAGpB,uCAAuC,IAAI+B,IAAI,SAAShhC,EAAQU,EAAOJ,GgCv/JxJ,YAEA,IAAAwsB,GAAA9sB,EAAA,oBAEA,IAAAuV,GAAAvV,EAAA,uCAEA,IAAA4mB,GAAA5mB,EAAA,+BACA,IAAAmxB,GAAAnxB,EAAA,kBAEA,SAAAo9B,GAAA5R,GAEA,KAAAzpB,eAAAq7B,IAAA,CACA,MAAA,IAAAA,GAAA5R,GAGAkC,EAAAlC,EAEAzpB,MAAA+Q,KAAA,aACA/Q,MAAAw+B,YAAA,IACAx+B,MAAA8S,QAAA,IACA9S,MAAAk/B,gBAAA,IAEAl/B,MAAAypB,UAAAA,CAEA,SAAAkC,GAAAlC,GACA,IAAAA,IAAA5E,EAAAwI,SAAA5D,EAAA5S,KAAA,CACA,KAAA,IAAAkU,GAAAsQ,EAAA8D,sBAKA9D,EAAA7nB,iBAAAA,CAEA6nB,GAAAuB,SAAA,SAAA/T,GACA,OAAAhE,EAAAua,WAAAvW,IAAA,yBAGAwS,GAAA37B,UAAAuI,WAAA,QAAAA,GAAAu2B,EAAA1rB,EAAAzS,GACAsrB,EAAA6S,EAAA1rB,EAAAzS,EAEAL,MAAAw+B,YAAAA,CACAx+B,MAAA8S,QAAAA,CACA9S,MAAAk/B,gBAAA,GAAA7D,GAAA7nB,iBAAAgrB,EAAA1rB,KACA9S,MAAAk/B,gBAAAj3B,WAAAjI,KAAAypB,UAAA5S,IAAAxW,EAEA,SAAAsrB,GAAAkT,EAAAzuB,EAAA4M,GACA,IAAAoS,EAAA0P,aAAAD,GAAA,CACA,KAAA,IAAA9T,GAAAsQ,EAAAgE,0BAGA,IAAAjQ,EAAA0P,aAAA1uB,IAAAA,EAAAoG,QAAAyD,gBAAA,QAAA,CACA,KAAA,IAAA8Q,GAAAsQ,EAAAgE,0BAGA,IAAAxa,EAAA+G,WAAA5O,GAAA,CACA,KAAA,IAAA+N,GAAAsQ,EAAAiE,oBAKAjE,GAAA37B,UAAA6I,aAAA,QAAAA,KACA,GAAAvI,KAAAk/B,gBAAA,CACA,IACAl/B,KAAAk/B,gBAAAv3B,UACA,MAAAlK,GACA,GAAAshC,SAAAla,EAAA+G,WAAAmT,QAAAC,KAAA,CACAD,QAAAC,IAAA,kDAIAh/B,KAAAk/B,gBAAA,KAGA,GAAAl/B,KAAAw+B,YAAA,CACApP,EAAAjkB,OAAAnL,KAAAw+B,YACAx+B,MAAAw+B,YAAA,MAIA,IAAAe,GAAA,mBACAlE,GAAA8D,mBAAAI,EAAA,qBACAlE,GAAAgE,yBAAAE,EAAA,iCACAlE,GAAAmE,qBAAAD,EAAA,4BACAlE,GAAAiE,iBAAAC,EAAA,0BAEA5gC,GAAAJ,QAAA88B,IhCy/JGrG,kBAAkB,GAAGxO,+BAA+B,GAAG8X,oBAAoB,GAAGmB,uCAAuC,KAAKC,IAAI,SAASzhC,EAAQU,EAAOJ,GiC9kKzJ,YAEA,IAAAwsB,GAAA9sB,EAAA,oBACA,IAAA+sB,GAAA/sB,EAAA,uBACA,IAAAkxB,GAAAlxB,EAAA,sBACA,IAAA2pB,GAAA3pB,EAAA,mBAEA,IAAAm/B,GAAAn/B,EAAA,uBAEA,IAAAgtB,GAAAhtB,EAAA,oBACA,IAAAmxB,GAAAnxB,EAAA,kBACA,IAAAoxB,GAAApxB,EAAA,0BACA,IAAA4mB,GAAA5mB,EAAA,+BAEA,SAAA0hC,GAAApQ,EAAAhE,GACA,KAAAvrB,eAAA2/B,IAAA,CACA,MAAA,IAAAA,GAAApQ,GAGAvvB,KAAA4/B,WACAC,OAAA,SACAC,WAAA,aACAC,UAAA,YAEA//B,MAAAuvB,OAAAA,CACAvvB,MAAAw+B,YAAAwB,EAAAzQ,EACAvvB,MAAAorB,SACAoS,gBAAA,IACAyC,cAAA,MAEAjgC,MAAAurB,SAAAA,CAIA,SAAAyU,KACA,GAAAxB,GAAA51B,SAAA+F,cAAA,MACAygB,GAAA8D,SAAAsL,EAAA,kBACAjP,GAAAnoB,KAAA4X,aAAAwf,EAAAjP,EAAAyE,WAAA5sB,KACA,OAAAo3B,IAKAmB,EAAAjgC,UAAA8vB,OAAA,QAAA0Q,GAAAzQ,EAAApvB,GACA,KAAAovB,YAAAzE,IAAA,CACA,MAAA3qB,GAAA,GAAA0qB,GAAA,4DAGA,GAAA7W,GAAAlU,IACA,IAAAuvB,GAAAvvB,KAAAuvB,MACA,IAAA4Q,GAAAngC,KAAAogC,mBAAA3Q,EAAAzvB,KAAAurB,SAEAlrB,GAAAA,GAAAwkB,EAAA1f,IAEAnF,MAAAgI,QAAA,IAEAonB,GAAA8D,SAAA3D,EAAAnoB,KAAA,eAEAmoB,GAAAhrB,GAAA,iBAAA87B,EACA9Q,GAAA+Q,IAAA,cAAA,WACA/Q,EAAA9qB,IAAA,iBAAA47B,EACAE,MAGA,IAAAJ,EAAA,CACAlV,EAAAY,WACA,SAAAuB,GACAA,EAAA,KAAA+S,EAAA1Q,IAEAzvB,KAAAwgC,YAAAruB,KAAAnS,MACAA,KAAAygC,YAAAtuB,KAAAnS,MACAA,KAAA0gC,eAAAvuB,KAAAnS,OAEA2gC,EAEA3gC,MAAAgI,SACA44B,QAAA,KACA/X,KAAA,QACA3nB,QAAA,WACAquB,EAAArjB,QAAA,gBACAqjB,GAAAU,MAAA,OAEA9uB,SAAA,WACAouB,EAAArjB,QAAA,mBAEAikB,SAAA,WACA,MAAAnwB,MAAA4gC,SAEAvQ,OAAA,WACA,MAAA8P,GAAA1W,gBAIA,CACA,GAAAhiB,GAAA,GAAAsjB,GAAA,kEAAA,IACA4V,GAAAl5B,EAAAzH,KAAAgI,QAAAynB,GAGA,MAAAzvB,MAAAgI,OAGA,SAAA24B,GAAAl5B,EAAAsN,EAAA0a,GACA,GAAAhoB,GAAAgoB,EAAA,CACAvb,EAAAqY,YAAAkD,EAAAhoB,EAAApJ,MAEAkxB,EAAArjB,QAAA,cACA7L,GAAAoH,EAAAgoB,GAGA,QAAA4Q,KACA9Q,EAAArjB,QAAA,eAGA,QAAAq0B,KACA,GAAAJ,EAAA,CACAA,EAAA53B,eAEA6mB,EAAAyR,YAAAtR,EAAAnoB,KAAA,iBAIAu4B,GAAAjgC,UAAA0gC,mBAAA,SAAA3Q,EAAAlE,GACA,KAAAkE,YAAAzE,IAAA,CACA,MAAA,MAGA,GAAA8V,GAAArR,EAAAlG,WAAAnmB,OAAAwkB,EAAA6C,QACA,IAAAvsB,GAAA4qB,EAAAW,EAAAkT,CAEA,KAAAz+B,EAAA,EAAA4qB,EAAAgY,EAAAriC,OAAAP,EAAA4qB,EAAA5qB,GAAA,EAAA,CACAurB,EAAAqX,EAAA5iC,EACAy+B,GAAA/U,EAAA8C,uBAAAjB,EAAAZ,KACA,IAAA8T,EAAA,CACA,MAAA,IAAAA,GAAAlT,EAAA8B,IAGA,MAAA,MAGAoU,GAAAjgC,UAAAqhC,0BAAA,SAAAhsB,EAAA8B,EAAA2mB,GACA,MAAA,IAAAJ,GAAAroB,GAAA8B,IAAAA,EAAA2mB,gBAAAA,IAGAmC,GAAAjgC,UAAA8gC,YAAA,SAAAL,EAAA1Q,EAAArC,GACA,GAAAlZ,GAAAlU,IACA,IAAAuvB,GAAAvvB,KAAAuvB,MACA,IAAAyR,GAAAzR,EAAAnoB,KAAAgO,cAAA,YACA,IAAAooB,GAAAx9B,KAAAurB,SAAAiS,iBAAAx9B,KAAAorB,QAAAoS,eACA2C,GAAAl4B,WAAAjI,KAAAw+B,YAAAwC,EAAA,SAAAv5B,EAAAsN,GACA,GAAAtN,EAAA,CACA,MAAA2lB,GAAA3lB,EAAAsN,EAAA0a,GAGA,IACA,GAAAwR,GAAA/sB,EAAA6sB,0BAAAhsB,EAAAorB,EAAA1W,UAAA5S,IAAA2mB,EACA,IAAA0D,GAAA,OAAAf,EAAApvB,KAAA,KACAqe,GAAA8D,SAAA3D,EAAAnoB,KAAA85B,EACA3R,GAAA+Q,IAAA,cAAA,WACAlR,EAAAyR,YAAAtR,EAAAnoB,KAAA85B,IAEA9T,GAAA,KAAA6T,EAAAxR,GACA,MAAAhyB,GACA2vB,EAAA3vB,EAAAsX,EAAA0a,MAKAkQ,GAAAjgC,UAAA+gC,YAAA,SAAA1rB,EAAA0a,EAAApvB,GACA4qB,EAAAY,WACA,SAAAuB,GACAA,EAAA,KAAArY,EAAA0a,IAEAzvB,KAAAmhC,WAAAhvB,KAAAnS,MACAA,KAAAohC,QAAAjvB,KAAAnS,MACAA,KAAA8vB,aAAA3d,KAAAnS,MACAA,KAAA6vB,eAAA1d,KAAAnS,MACAA,KAAAqhC,oBAAAlvB,KAAAnS,MACAA,KAAAshC,SAAAnvB,KAAAnS,OACAK,GAGAs/B,GAAAjgC,UAAAyhC,WAAA,QAAAI,GAAAxsB,EAAA0a,EAAArC,GACArY,EAAA9U,iBAAAD,KAAAorB,QAAA6U,cAAA,SAAAx4B,EAAAsc,GACA,GAAAtc,EAAA,CACA,MAAA2lB,GAAA3lB,EAAAsN,EAAA0a,GAGA,GAAA1L,GAAAyd,EAAAzd,GAAA,CACA,MAAAqJ,GAAA,KAAArY,EAAA0a,GAGA,MAAArC,GAAA,GAAArC,GAAA,uDAAAhH,EAAA,KAAAhP,EAAA0a,IAGA,SAAA+R,GAAAzd,GACA,GAAA0d,GAAAxe,EAAAc,EACA,OAAA0d,IAAA,GAAAA,GAAA,EAGA,QAAAxe,GAAAc,GACA,GAAA2d,GAAA3d,EAAA5I,MAAA,IACA,OAAAwF,UAAA+gB,EAAA,GAAA,KAIA/B,GAAAjgC,UAAA0hC,QAAA,SAAArsB,EAAA0a,EAAArC,GACA,GAAA+S,GAAAngC,KAAAuvB,OAAAnoB,KAAAgO,cAAA,YACA,IAAAusB,GAAAvS,EAAAqB,aAAA0P,EACAprB,GAAAzU,OAAAqhC,EAAAphC,MAAAohC,EAAAnhC,OAAAR,KAAA4/B,UAAAC,QAAA,GAAAj/B,aAAA6uB,EAAA5F,cAAA,IAAA,SAAApiB,GACA2lB,EAAA3lB,EAAAsN,EAAA0a,KAIAkQ,GAAAjgC,UAAAiwB,mBAAA,SAAAiS,EAAAnS,GACA,MAAA,IAAAN,GAAAyS,EAAAnS,GAGAkQ,GAAAjgC,UAAAowB,aAAA,SAAA/a,EAAA0a,EAAArC,GACA,GAAAwU,GAAA7sB,EAAAqW,QAAAvU,GACA,IAAAua,GAAApxB,KAAA2vB,mBAAAiS,EAAAnS,EACA,IAAAF,GAAAvvB,KAAAuvB,MACA,IAAArb,GAAAlU,IAEA+U,GAAAxQ,GAAA,YAAA,WACAgrB,EAAArjB,QAAA,kBACAklB,GAAAiC,aAGAte,GAAAxQ,GAAA,eAAA,WACAgrB,EAAArjB,QAAA,qBACAklB,GAAAG,oBAGAxc,GAAAxQ,GAAA,YAAA,WACAgrB,EAAArjB,QAAA,kBACAklB,GAAAiB,mBACAwP,MAGA9sB,GAAAxQ,GAAA,eAAA,WACAgrB,EAAArjB,QAAA,qBACAklB,GAAA0Q,YACAD,MAGA9sB,GAAAxQ,GAAA,YAAA,WACAgrB,EAAArjB,QAAA,kBACAklB,GAAAe,aACA0P,MAGA9sB,GAAAxQ,GAAA,WAAA,WACAgrB,EAAArjB,QAAA,iBACAklB,GAAAI,YACAuQ,MAGA,SAAAF,KACA,GAAA3tB,EAAAlM,SAAAkM,EAAAlM,QAAAmoB,WAAA,CACAjc,EAAAlM,QAAA44B,QAAA,MAEArR,EAAArjB,QAAA,QAIA,QAAA61B,KACA,GAAA7tB,EAAAlM,QAAA,CACAkM,EAAAlM,QAAA44B,QAAA,KAEArR,EAAArjB,QAAA,SAGA6I,EAAAxQ,GAAA,uBAAA,WACAgrB,EAAArjB,QAAA,6BACAklB,GAAA4Q,sBAGAjtB,GAAAxQ,GAAA,kBAAA,WACAgrB,EAAArjB,QAAA,wBACAklB,GAAA6Q,iBAGAltB,GAAAxQ,GAAA,uBAAA,WACAgrB,EAAArjB,QAAA,6BACAklB,GAAA8Q,sBAGAntB,GAAAxQ,GAAA,kBAAA,WACAgrB,EAAArjB,QAAA,wBACAklB,GAAAU,iBAGA/c,GAAAxQ,GAAA,cAAA,SAAA0B,GACAspB,EAAArjB,QAAA,oBACA,IAAA5D,GAAArC,EAAAqC,GACA,IAAA2K,GAAAhN,EAAAgN,aACA,IAAAkvB,GAAAtd,EAAA8D,iBAAArgB,GAAAA,EAAA+rB,EAAA5E,EAAA0E,aAEA/C,GAAAkD,YACA,IAAArhB,GAAAkvB,EAAA,CACAl4B,OAAAm4B,KAAAD,EAAA,UAGA,QAAA9N,GAAAH,GACA,GAAAK,IACAC,SAAAzf,EAAAqW,QAAAvU,IACA4d,gBAAA,EAGA,OAAAP,GAAAtM,EAAA+M,cAAAT,EAAAK,GAAA,OAIAxf,GAAAxQ,GAAA,yBAAA,WACAgrB,EAAArjB,QAAA,+BACAklB,GAAAiR,uBACAjR,GAAAkR,+BAGAvtB,GAAAxQ,GAAA,cAAA,WACAgrB,EAAArjB,QAAA,oBACAklB,GAAAmR,YACAnR,GAAAoR,oBAGAztB,GAAAxQ,GAAA,iBAAA,WACAgrB,EAAArjB,QAAA,uBACAklB,GAAAqR,iBAGA1tB,GAAAxQ,GAAA,UAAA,WACAgrB,EAAArjB,QAAA,gBAEAklB,GAAA8H,mBAAA,MAGAnkB,GAAAxQ,GAAA,iBAAA,WACAgrB,EAAArjB,QAAA,uBACA,IAAAw2B,GAAAnT,EAAAzqB,QACAiQ,GAAA/S,YAAA,SAAAyF,EAAAk7B,GACA,GAAAA,IAAA,GAAAD,EAAA,EAAA,CACAtR,EAAAmB,YAGA,GAAAoQ,EAAA,GAAAD,IAAA,EAAA,CACAtR,EAAAoB,cAGAjD,EAAAzqB,OAAA69B,MAIA,IAAAC,GAAA7hC,EAAAoR,KAAAnS,KAAAuvB,EAAAxa,EAAA/U,KAAA4/B,UACA,IAAAiD,GAAAhe,EAAAie,SAAAF,EAAA,IACA,IAAAG,GAAA/iC,KAAAurB,SAAAwX,UAEA,IAAAA,EAAA,CACA3T,EAAArc,iBAAA9I,OAAA,SAAA44B,EACAzT,GAAArc,iBAAA9I,OAAA,oBAAA44B,GAGAtT,EAAAhrB,GAAA,cAAAq+B,EACArT,GAAAhrB,GAAA,gBAAAy+B,EACAzT,GAAAhrB,GAAA,iBAAA0+B,EAEA1T,GAAA+Q,IAAA,cAAA,WACA/Q,EAAA9qB,IAAA,cAAAm+B,EACArT,GAAA9qB,IAAA,gBAAAu+B,EACAzT,GAAA9qB,IAAA,iBAAAw+B,EAEA,IAAAF,EAAA,CACA3T,EAAA1Z,oBAAAzL,OAAA,SAAA44B,EACAzT,GAAA1Z,oBAAAzL,OAAA,oBAAA44B,KAIAzV,GAAA,KAAArY,EAAA0a,EAGA,SAAAuT,KACAjuB,EAAA7T,QAAA2jB,EAAA1f,MAGA,QAAA89B,KACAluB,EAAA5T,SAAA0jB,EAAA1f,OAIAw6B,GAAAjgC,UAAAmwB,eAAA,SAAA9a,EAAA0a,EAAArC,GACA,GAAAyF,EACA,IAAAtD,GAAAvvB,KAAAuvB,MAEAxa,GAAAxQ,GAAA,yBAAAyuB,EAEA3D,GAAAsC,KAAApC,GAAA,aAAA,kBAAA0D,EAEA7F,GAAA,KAAArY,EAAA0a,EAGA,SAAAuD,KACAzD,EAAArjB,QAAA,+BACA6I,GAAApT,oBAAA,SAAA8F,EAAAy7B,GACA,GAAAA,EAAA,CACA,IAAArQ,EAAA,CACAJ,EAAAlD,QAEA,CACA0D,EAAA1D,MAKA,QAAAkD,GAAAlD,GACAsD,EAAAC,EAAAvD,EACAA,GAAAnoB,KAAAyH,YAAAgkB,GAGA,QAAAI,KACA7D,EAAAjkB,OAAA0nB,EACAA,GAAA,KAGA,QAAAC,KACA,GAAAD,GAAA5oB,OAAArB,SAAA+F,cAAA,MACAygB,GAAA8D,SAAAL,EAAA,mBACAzD,GAAA8D,SAAAL,EAAA,UACAA,GAAAjkB,UAAA,SAEAikB,GAAAM,QAAA,SAAA11B,GACAsX,EAAAzT,OAAAujB,EAAA1f,KAGA,IAAA8E,OAAAqpB,MAAA5zB,UAAA6zB,kBAAAnzB,UAAA,CACA3C,EAAA81B,sBACA,CACA,MAAA,QAIA,OAAAV,IAIA8M,GAAAjgC,UAAA2hC,oBAAA,SAAAtsB,EAAA0a,EAAArC,GACA,GAAAlZ,GAAAlU,IACAmjC,GAAAnjC,KAAAuvB,OAAAxa,EACAquB,GAAApjC,KAAAuvB,OAAAxa,EAAA/U,KAAA4/B,UAEAxS,GAAA,KAAArY,EAAA0a,EAGA,SAAA0T,GAAA5T,EAAAxa,GACAwa,EAAAhrB,GAAA,eAAA8+B,EACAtuB,GAAAxQ,GAAA,iBAAA++B,EAEA/T,GAAA+Q,IAAA,cAAA,WACA/Q,EAAA9qB,IAAA,eAAA4+B,IAKA,SAAAA,KACA,GAAAE,GAAAhU,EAAA+C,QAAA,EAAA/C,EAAAzqB,QACAiQ,GAAAjT,YAAAyhC,EAAAC,GAGA,QAAAF,KACA/T,EAAArjB,QAAA,uBACA6I,GAAA/S,YAAA,SAAAyF,EAAA87B,GACA,GAAA97B,EAAA,CACA+7B,EAAA/7B,OACA,CACA8nB,EAAAzqB,OAAAy+B,OAMA,QAAAH,GAAA7T,EAAAxa,EAAA6qB,GACA,GAAAgD,GAAA7hC,EAAAoR,KAAA+B,EAAAqb,EAAAxa,EAAA6qB,EAEArQ,GAAAhrB,GAAA,mBAAAq+B,EAEArT,GAAA+Q,IAAA,cAAA,WACA/Q,EAAA9qB,IAAA,mBAAAm+B,MAKAjD,GAAAjgC,UAAA4hC,SAAA,SAAAvsB,EAAA0a,EAAArC,GACA,GAAAmC,GAAAvvB,KAAAuvB,MAEAxa,GAAA/T,QAAA,SAAAyG,GACA,IAAAA,EAAA,CACA8nB,EAAArjB,QAAA,gBAEAkhB,EAAA3lB,EAAAsN,EAAA0a,KAIAkQ,GAAAjgC,UAAAghC,eAAA,SAAA3rB,EAAA0a,EAAArC,GACA,GAAAmC,GAAAvvB,KAAAuvB,MACAxa,GAAAxQ,GAAA,YAAA,WACAgrB,EAAArjB,QAAA,kBACAu3B,GAAA,OAGA1uB,GAAAxQ,GAAA,UAAA,SAAAkD,GACA,GAAAumB,GAAAvmB,EAAAA,EAAAY,QAAA,0EACAo7B,GAAA,GAAA1Y,GAAAiD,KAIA,SAAAyV,GAAAh8B,GACA2lB,EAAA3lB,EAAAsN,EAAA0a,IAIAkQ,GAAAjgC,UAAA6sB,YAAA,QAAAwI,GAAA9I,EAAAyX,GACA9b,EAAA8G,MAAAzC,EAAAT,gBAAAmD,UAAA+U,GAAA,MAGA,SAAA3iC,GAAAwuB,EAAAxa,EAAA6qB,GACA,GAAAO,GAAA5Q,EAAAnoB,KAAAgO,cAAA,YACA,IAAAusB,GAAAvS,EAAAqB,aAAA0P,EACA,IAAAwD,GAAApU,EAAAwC,eAAA6N,EAAAE,WAAAF,EAAAC,MACA9qB,GAAAhU,SAAA4gC,EAAAphC,MAAAohC,EAAAnhC,OAAAmjC,EAAAH,GAGA,QAAAA,GAAA/7B,GACA,GAAAA,GAAAs3B,SAAAA,QAAAC,IAAA,CACAD,QAAAC,IAAA,UAAAv3B,EAAAY,QAAAZ,IAIA9I,EAAAJ,QAAAohC,IjCglKG/Q,oBAAoB,GAAGoG,kBAAkB,GAAGC,0BAA0B,GAAGzO,+BAA+B,GAAG8X,oBAAoB,GAAGsF,uBAAuB,GAAGC,sBAAsB,GAAGC,mBAAmB,GAAGC,uBAAuB,KAAKC,IAAI,SAAS/lC,EAAQU,EAAOJ,GkCvmLtQ,YAEA,IAAA6wB,GAAAnxB,EAAA,kBAEA,IAAAgmC,GAAAr7B,SAAA+F,cAAA,MACAs1B,GAAAC,UAAA,4CACAD,GAAAr1B,UAAA,eAEA,IAAAu1B,GAAA,SAAAC,GACA,OAEAC,KAAA,QAAAA,GAAA9U,EAAAnE,GACAA,EAAAhkB,GAAA68B,CACAG,GAAA5lC,KAAAwB,KAAAuvB,EAAAnE,EAGA1jB,YAAA,WACA,GAAA48B,GAAA/U,EAAAyE,aAAAzE,EAAAyE,WAAAuQ,SAAA,kBAAAhV,EAAAyE,WAAAuQ,SAAA,sBACA,IAAAD,EAAA,CACA/U,EAAAyE,WAAA5sB,KAAA4X,aAAAilB,EAAAK,EAAAl9B,MAEAgoB,EAAAyR,YAAAoD,EAAA,qBACA,IAGA78B,GAAA,QAAAo9B,KACA,MAAAP,KAKAtlC,GAAAJ,QAAA4lC,IlCymLGnP,kBAAkB,KAAKyP,IAAI,SAASxmC,EAAQU,EAAOJ,GmCxoLtD,YAEA,IAAAmmC,GAAAC,QAAAC,aAAA,YAEA,IAAAC,GAAA5mC,EAAA,eAAAymC,EAEAC,SAAAG,kBAAA,WAAAH,QAAAvyB,OAAAsyB,EAAAG,MnC2oLGE,cAAc,KAAKC,IAAI,SAAS/mC,EAAQU,EAAOJ,GoCjpLlD,YAgBA,IAAA0lC,GAAAr7B,SAAA+F,cAAA,MAEA,IAAAs2B,GAAA,SAAAb,GACA,OAEAC,KAAA,QAAAA,GAAA9U,EAAAnE,GACAA,EAAAhkB,GAAA68B,CACAA,GAAAC,UAAA,kBACAE,GAAA5lC,KAAAwB,KAAAuvB,EAAAnE,EAEA,IAAA8Z,GAAA3V,EAAAgV,SAAA,cAGA78B,YAAA,WACA,GAAAw9B,GAAA3V,GAAAA,EAAAnoB,KAAA,CACAmoB,EAAAnoB,KAAA4X,aAAAilB,EAAAiB,EAAA99B,QAEA,IAEAA,GAAA,QAAAo9B,KACA,MAAAP,KAKAtlC,GAAAJ,QAAA0mC,OpCmpLME,IAAI,SAASlnC,EAAQU,EAAOJ,GqC5rLlC,YAEA,IAAAmmC,GAAAC,QAAAC,aAAA,YAEA,IAAAQ,GAAAnnC,EAAA,kBAAAymC,EAEAC,SAAAG,kBAAA,cAAAH,QAAAvyB,OAAAsyB,EAAAU,MrC+rLGC,iBAAiB,KAAKC,IAAI,SAASrnC,EAAQU,EAAOJ,GsCrsLrD,YAEA,IAAA4sB,GAAAltB,EAAA,yBACA,IAAA8sB,GAAA9sB,EAAA,wBACA,IAAA2pB,GAAA3pB,EAAA,uBAEA,IAAAqxB,GAAArxB,EAAA,6BACA,IAAA0hC,GAAA1hC,EAAA,+BAEA,IAAAgtB,GAAAhtB,EAAA,iBACA,IAAAmxB,GAAAnxB,EAAA,eACA,IAAAoxB,GAAApxB,EAAA,uBACA,IAAA4mB,GAAA5mB,EAAA,4BAEAU,GAAAJ,QAAA,QAAAgnC,GAAAna,GACA,GAAAoa,EACA,IAAAjW,GAAAvvB,IACA,IAAAylC,GAAA,GAAAta,EACA,IAAAua,GAAA,KACA,IAAAC,IAKA/+B,QAAA,IAMAg/B,wBAAA,IAIAC,gBAAA,IAIAC,aAAA,MAGAC,WAAA,KAGAhD,WAAA,KAGAjG,qBAAA,kBAGA,IAAAvR,GAAA1G,EAAAzS,UAAAuzB,EAAAva,MAEA,IAAAvG,EAAAmhB,YAAAza,EAAAG,WAAA7G,EAAAwB,UAAAkF,EAAAjjB,KAAA,CACAijB,EAAAG,SAAAH,EAAAjjB,IAGA,GAAAuc,EAAAwI,SAAA9B,EAAAG,UAAA,CACAH,EAAAG,SAAA7G,EAAAohB,OAAA1a,EAAAG,UAGA,GAAA7G,EAAAwB,UAAAkF,EAAA2a,YAAArhB,EAAA+G,WAAAL,EAAA2a,UAAA,CACA,MAAAC,GAAA,GAAApb,GAAA,mFAGA,IAAAlG,EAAAwB,UAAAkF,EAAAG,YAAA7G,EAAA+G,WAAAL,EAAA2a,UAAA,CACA,MAAAC,GAAA,GAAApb,GAAA,+DAGAnD,EAAAiV,qBAAAtR,EAAAuR,qBAEAzN,GAAA+W,cAAA7W,EAEA,IAAAhE,EAAAua,aAAA,CAEAvW,EAAAhrB,GAAA,kBAAA,WACAmD,WAAA,WACA6nB,EAAArjB,QAAA,eACA,KAIAqjB,EAAAhrB,GAAA,iBAAA8hC,EAEA9W,GAAAhrB,GAAA,aAAA,WAEAihC,EAAA,IACAc,MAGA/W,GAAAkW,MACAc,UAAA,WACA,MAAAhb,GAAAwa,YAGAS,OAAA,WACAjb,EAAAwa,WAAA,MAGAU,QAAA,WACAlb,EAAAwa,WAAA,OAIA,OAAAxW,GAAAkW,IAGA,SAAAY,KAEAhX,EAAAqX,mBAAAnX,EAEAF,GAAAsC,KAAApC,GAAA,iBAAA,cAAA,WACAgR,GACAoG,MAGA1b,GAAAY,WACA+a,EACAC,EACAC,EACAC,GACA,SAAAt/B,EAAAwkB,GACA,GAAAxkB,EAAA,CACA0+B,EAAA1+B,EAAAwkB,OACA,CACAsD,EAAArjB,QAAA,gBAMA,SAAAq0B,KACA,GAAAhR,EAAAkW,MAAAlW,EAAAkW,KAAA1wB,OAAA,CACAwa,EAAAkW,KAAA1wB,OAAA,MAIA,QAAA4xB,KACAK,GACA,IAAAxB,EAAA,CACAnW,EAAA4X,sBAAA1X,EAAAiW,EACAA,GAAA,MAIA,QAAAwB,KACA3X,EAAAsC,KAAApC,GAAA,UAAA,aAAA,kBAAA,SAAAsC,GACA,GAAAA,EAAAhJ,OAAA,UAAA,CACA,OAGA0G,EAAArjB,QAAA,oBAEAmjB,GAAAsC,KAAApC,GAAA,QAAA,aAAA,kBAAA,SAAAsC,GACA,GAAAA,EAAAhJ,OAAA,QAAA,CACA0G,EAAArjB,QAAA,wBAMA,QAAA06B,GAAAxZ,GACA,GAAA7B,EAAAwa,WAAA,CACA,MAAA3Y,GAAA,MAEAA,EAAA,GAAArC,GAAA,wBAGA,QAAA8b,GAAAzZ,GACA,GAAA8Z,IAAA,CACA1B,EAAAnW,EAAA8X,kBAAA5X,EACAA,GAAAU,OACAmX,IAEA,IAAA7X,EAAAa,SAAA,CACAhD,EAAA,UACA,CACAiC,EAAAsC,KAAApC,GAAA,WAAA,WACAA,EAAAU,OACA7C,GAAA,aAGA,CACAA,EAAA,GAAArC,GAAA,sDAIA,QAAAmc,KACA,OAAAriB,EAAAwiB,YAAA9X,EAAA2C,eAAA3G,EAAAqa,wBAGA,QAAAkB,GAAA1Z,GACA,GAAAka,EACA5B,GAAA,KAEA4B,GAAA5/B,WAAA,WACAy+B,EAAA,GAAApb,GAAA,uDAAA,OACAQ,EAAAsa,gBAEAxW,GAAAsC,KAAApC,GAAA,eAAA,kBAAAgY,EAGA,SAAAA,KACA,GAAAD,EAAA,CACA/4B,aAAA+4B,EACAA,GAAA,MAIAla,EAAA,MAGA,QAAAga,KACAhY,EAAA8D,SAAA3D,EAAAnoB,KAAA,sBACAioB,GAAAsC,KAAApC,GAAA,eAAA,kBAAAiY,GAGA,QAAAA,KAGA9/B,WAAA,WACA0nB,EAAAyR,YAAAtR,EAAAnoB,KAAA,wBACA,MAKA,QAAAk/B,KACA/W,EAAArjB,QAAA,iBACAw5B,GAAA,KAGA,QAAAqB,GAAA1mC,GACA4qB,EAAAY,WACA4b,EACAjY,GACAnvB,GAGA,QAAAonC,GAAApnC,GACAolC,EAAAha,gBAAAF,EAAAG,SAAAH,EAAAG,WAAAH,EAAA2a,SAAA7lC,GAGA,QAAAmvB,GAAAC,EAAApvB,GAGA,GAAAqlC,EAAA,CACA,OAGA,GAAAgC,GAAAjd,EAAAgF,GAAA,GAAAkQ,GAAApQ,EAAAhE,GAAA,GAAA+D,GAAAC,EACA,IAAAoY,GAAA,KAEAtY,GAAAsC,KAAApC,GAAA,eAAA,kBAAA,SAAAsC,GACA,GAAAA,EAAAhJ,OAAA,eAAA,CACA+e,MAIAvY,GAAAsC,KAAApC,GAAA,aAAA,kBAAAsY,EAEA,IAAAhjB,EAAAijB,YAAA,CACAC,IAGAxY,EAAAkW,KAAAhW,aAAAA,CACAF,GAAAkW,KAAA1wB,OAAA2yB,EAAAlY,OAAAC,EAAApvB,EAGA,SAAAunC,KACA,GAAAD,GAAApY,EAAAyE,WAAAuQ,SAAA,YAAA,CACA,OAGAhV,EAAAyE,WAAAgU,SAAA,YAGA,QAAAH,KACAtY,EAAAyE,WAAApnB,YAAA,WACA+6B,GAAA,KAGA,QAAAI,KAEA,GAAAE,GAAA,CACA,IAAAC,GAAA,CACA,IAAAC,GAAA,CAEA5Y,GAAAhrB,GAAA,aAAA6jC,EACA7Y,GAAAhrB,GAAA,QAAA8jC,EAEAhZ,GAAAsC,KAAApC,GAAA,aAAA,iBAAA,gBAAA+Y,EAGA,SAAAD,KAGA,GAAA9Y,EAAAjG,WAAA4e,EAAAD,EAAA,CACA1Y,EAAAU,MAAA,KACAV,GAAAW,KAAA,KACAX,GAAA2C,YAAAgW,IAIA,QAAAE,KACA,GAAAlW,GAAA3C,EAAA2C,aACA,IAAAqW,GAAA1X,KAAAC,IAAAoB,EAAAgW,EACA,IAAAK,EAAAN,EAAA,CACAE,GAAA,CACA,IAAAA,GAAA,EAAA,CACA5Y,EAAAU,MAAA,MAEAV,EAAA2C,YAAAgW,OACA,CACAA,EAAAhW,GAIA,QAAAoW,KACA/Y,EAAA9qB,IAAA,aAAA2jC,EACA7Y,GAAA9qB,IAAA,QAAA4jC,KAKA,QAAAlC,GAAA1+B,EAAAgoB,GACAF,EAAArjB,SAAA2c,KAAA,eAAAphB,MAAAA,GACA6+B,IACA,IAAAvH,SAAAA,QAAAC,IAAA,CACAD,QAAAC,IAAA,YAAAv3B,EAAAY,QAAAZ,EAAAgoB,IAIA,QAAAhF,GAAAgF,GACA,GAAAvxB,GAAA4qB,CACA,IAAAS,GAAAkG,EAAAlG,UACA,KAAArrB,EAAA,EAAA4qB,EAAAS,EAAA9qB,OAAAP,EAAA4qB,EAAA5qB,IAAA,CACA,GAAA0pB,EAAA6C,QAAAlB,EAAArrB,IAAA,CACA,MAAA,OAGA,MAAA,WtC0sLGsqC,yBAAyB,GAAGC,wBAAwB,GAAGC,6BAA6B,GAAGC,uBAAuB,GAAGC,+BAA+B,GAAGC,iBAAiB,GAAGC,eAAe,GAAGC,uBAAuB,GAAGC,4BAA4B,KAAKC,IAAI,SAAShrC,EAAQU,EAAOJ,GuC5hMnR,GAAAsmB,GAAA5mB,EAAA,qBAEA,IAAAgtB,KAEAA,GAAAie,aAAA,SAAA7sB,GACA3U,WAAA2U,EAAA,GAGA4O,GAAA3oB,SAAA,SAAA6mC,GACA,GAAAC,GAAA,SAAAz7B,GACA,GAAA0O,GAAA,WACA,GAAA8sB,EAAA1qC,OAAA,CACA0qC,EAAAx7B,GAAAa,MAAA,KAAArO,WAEA,MAAAkc,GAAA+Q,OAEA/Q,GAAA+Q,KAAA,WACA,MAAAzf,GAAAw7B,EAAA1qC,OAAA,EAAA2qC,EAAAz7B,EAAA,GAAA,KAEA,OAAA0O,GAEA,OAAA+sB,GAAA,GAIAne,GAAAY,UAAA,SAAAsd,EAAA9oC,GACAA,EAAAA,GAAA,YACA,KAAAwkB,EAAAyB,QAAA6iB,GAAA,CACA,GAAA5hC,GAAA,GAAAnJ,OAAA,4DACA,OAAAiC,GAAAkH,GAEA,IAAA4hC,EAAA1qC,OAAA,CACA,MAAA4B,KAEA,GAAAgpC,GAAA,SAAA/mC,GACA,MAAA,UAAAiF,GACA,GAAAA,EAAA,CACAlH,EAAAmO,MAAA,KAAArO,UACAE,GAAA,iBAGA,CACA,GAAAkL,GAAAwG,MAAArS,UAAAsS,MAAAxT,KAAA2B,UAAA,EACA,IAAAitB,GAAA9qB,EAAA8qB,MACA,IAAAA,EAAA,CACA7hB,EAAAiC,KAAA67B,EAAAjc,QAEA,CACA7hB,EAAAiC,KAAAnN,GAEA4qB,EAAAie,aAAA,WACA5mC,EAAAkM,MAAA,KAAAjD,OAKA89B,GAAApe,EAAA3oB,SAAA6mC,MAGAle,GAAAqe,KAAA,SAAAC,EAAAlpC,GACA,IAAAwkB,EAAA+G,WAAAvrB,GAAA,CACA,KAAA,IAAAjC,OAAA,+CAGA,GAAAorC,GAAA3kB,EAAA+G,WAAA2d,GAAAA,EAAA,WACA,QAAAA,EAGA,OAAA,YACA,GAAAh+B,GAAAsZ,EAAAgZ,oBAAA19B,UACA,IAAAitB,GAAA7hB,EAAA0G,KAEA,IAAAu3B,EAAAh7B,MAAA,KAAAjD,GAAA,CACA,MAAAlL,GAAAmO,MAAAxO,KAAAG,WAGAoL,EAAA4yB,QAAA,KACA,OAAA/Q,GAAA5e,MAAA,KAAAjD,IAIA5M,GAAAJ,QAAA0sB,IvCkiMGwe,qBAAqB,KAAKC,IAAI,SAASzrC,EAAQU,EAAOJ,GwCrnMzD,YAEA,IAAAsmB,GAAA5mB,EAAA,qBAEA,IAAAmxB,KAEAA,GAAA3N,UAAA,QAAAA,GAAAra,GACA,GAAAwI,GAAA3F,OAAA0/B,iBAAAviC,EACA,OAAAwI,GAAA8R,aAAA,SAGA0N,GAAAwa,SAAA,QAAAA,GAAAxiC,GACA,GAAAwI,GAAA3F,OAAA0/B,iBAAAviC,EACA,OAAAwI,GAAAqM,UAAA,OAGAmT,GAAAya,QAAA,QAAAA,GAAAziC,GACA,OAAAgoB,EAAAwa,SAAAxiC,GAGAgoB,GAAA0a,KAAA,QAAAA,GAAA1iC,GACAA,EAAA2iC,sBAAA3iC,EAAAwI,MAAAqM,OACA7U,GAAAwI,MAAAqM,QAAA,OAGAmT,GAAA4a,KAAA,QAAAA,GAAA5iC,GACA,GAAAgoB,EAAAwa,SAAAxiC,GAAA,CACAA,EAAAwI,MAAAqM,QAAA7U,EAAA2iC,sBAEA3iC,EAAA2iC,sBAAA3pC,UAGAgvB,GAAAgE,SAAA,QAAAA,GAAAhsB,EAAA6iC,GACA,GAAAC,GAAAhsC,EAAA4qB,CAEA,IAAAjE,EAAA8D,iBAAAshB,GAAA,CACA,GAAA7iC,EAAA+iC,UAAA,CACA,MAAA/iC,GAAA+iC,UAAAC,SAAAH,GAGAC,EAAArlB,EAAAwI,SAAAjmB,EAAAwW,aAAA,UAAAxW,EAAAwW,aAAA,SAAAzC,MAAA,SACA8uB,GAAAA,GAAA,EAEA,KAAA/rC,EAAA,EAAA4qB,EAAAohB,EAAAzrC,OAAAP,EAAA4qB,EAAA5qB,GAAA,EAAA,CACA,GAAAgsC,EAAAhsC,KAAA+rC,EAAA,CACA,MAAA,QAIA,MAAA,OAGA7a,GAAA8D,SAAA,SAAA9rB,EAAA6iC,GACA,GAAAC,EAEA,IAAArlB,EAAA8D,iBAAAshB,GAAA,CACA,GAAA7iC,EAAA+iC,UAAA,CACA,MAAA/iC,GAAA+iC,UAAAngC,IAAAigC,GAGAC,EAAArlB,EAAAwI,SAAAjmB,EAAAwW,aAAA,UAAAxW,EAAAwW,aAAA,SAAAzC,MAAA,SACA,IAAA0J,EAAAwI,SAAA4c,IAAAplB,EAAA8D,iBAAAshB,EAAA5yB,QAAA,MAAA,KAAA,CACA6yB,EAAA18B,KAAAy8B,EACA7iC,GAAAmF,aAAA,QAAA29B,EAAAG,KAAA,QAKAjb,GAAAyR,YAAA,SAAAz5B,EAAA6iC,GACA,GAAAC,EAEA,IAAArlB,EAAA8D,iBAAAshB,GAAA,CACA,GAAA7iC,EAAA+iC,UAAA,CACA,MAAA/iC,GAAA+iC,UAAAh/B,OAAA8+B,GAGAC,EAAArlB,EAAAwI,SAAAjmB,EAAAwW,aAAA,UAAAxW,EAAAwW,aAAA,SAAAzC,MAAA,SACA,IAAAmvB,KACA,IAAApsC,GAAA4qB,CACA,IAAAjE,EAAAwI,SAAA4c,IAAAplB,EAAA8D,iBAAAshB,EAAA5yB,QAAA,MAAA,KAAA,CAEA,IAAAnZ,EAAA,EAAA4qB,EAAAohB,EAAAzrC,OAAAP,EAAA4qB,EAAA5qB,GAAA,EAAA,CACA,GAAA+rC,IAAAC,EAAAhsC,GAAA,CACAosC,EAAA98B,KAAA08B,EAAAhsC,KAGAkJ,EAAAmF,aAAA,QAAA+9B,EAAAD,KAAA,QAKAjb,GAAArc,iBAAA,QAAAA,GAAA3L,EAAAyhB,EAAAvhB,GACA,GAAAud,EAAAyB,QAAAlf,GAAA,CACAyd,EAAA7gB,QAAAoD,EAAA,SAAA3J,GACA2xB,EAAArc,iBAAAtV,EAAAorB,EAAAvhB,IAEA,QAGA,GAAAud,EAAAyB,QAAAuC,GAAA,CACAhE,EAAA7gB,QAAA6kB,EAAA,SAAAnrB,GACA0xB,EAAArc,iBAAA3L,EAAA1J,EAAA4J,IAEA,QAGA,GAAAF,EAAA2L,iBAAA,CACA3L,EAAA2L,iBAAA8V,EAAAvhB,EAAA,WACA,IAAAF,EAAAsU,YAAA,CAMAtU,EAAAsU,YAAA,KAAAmN,EAAAvhB,IAIA8nB,GAAA1Z,oBAAA,QAAAA,GAAAtO,EAAAyhB,EAAAvhB,GACA,GAAAud,EAAAyB,QAAAlf,GAAA,CACAyd,EAAA7gB,QAAAoD,EAAA,SAAA3J,GACA2xB,EAAA1Z,oBAAAjY,EAAAorB,EAAAvhB,IAEA,QAGA,GAAAud,EAAAyB,QAAAuC,GAAA,CACAhE,EAAA7gB,QAAA6kB,EAAA,SAAAnrB,GACA0xB,EAAA1Z,oBAAAtO,EAAA1J,EAAA4J,IAEA,QAGA,GAAAF,EAAAsO,oBAAA,CACAtO,EAAAsO,oBAAAmT,EAAAvhB,EAAA,WACA,IAAAF,EAAAwU,YAAA,CACAxU,EAAAwU,YAAA,KAAAiN,EAAAvhB,OACA,CACAF,EAAA,KAAAyhB,GAAA,MAIAuG,GAAAmb,cAAA,QAAAA,GAAAnjC,EAAAhD,GACA,GAAAgD,EAAAmjC,cAAA,CACAnjC,EAAAmjC,cAAAnmC,OACA,CACAgD,EAAAojC,UAAA,KAAApmC,EAAAwc,UAAAxc,IAIAgrB,GAAAqb,aAAA,QAAAA,GAAAhhC,EAAAihC,GACA,GAAAC,GAAAD,EAAAxuB,UACA,OAAAyuB,IAAA,KAAA,CACA,GAAAA,IAAAlhC,EAAA,CACA,MAAA,MAEAkhC,EAAAA,EAAAzuB,WAEA,MAAA,OAGAkT,GAAAwb,eAAA,QAAAA,GAAAxjC,GACA,MAAAA,GAAAyjC,aAAAzjC,EAAA0jC,KAGA1b,GAAA2b,aAAA,QAAAA,GAAAthC,EAAAihC,GACA,GAAAA,EAAAxuB,WAAA,CACAwuB,EAAAxuB,WAAAtP,YAAA89B,GAEA,MAAAjhC,GAAAuV,aAAA0rB,EAAAjhC,EAAAoW,YAGAuP,GAAAjkB,OAAA,QAAA6/B,GAAAL,GACA,GAAAA,GAAAA,EAAAzuB,WAAA,CACAyuB,EAAAzuB,WAAAtP,YAAA+9B,IAIAvb,GAAA0P,aAAA,QAAAA,GAAAhhC,GACA,MAAAA,aAAAmtC,SAGA7b,GAAApc,MAAA,SAAA5L,EAAAE,GACA8nB,EAAArc,iBAAA3L,EAAA,QAAAE,GAGA8nB,GAAAuC,KAAA,SAAAvqB,EAAAyhB,EAAAvhB,GACA,QAAA4jC,KACA5jC,EAAAkH,MAAA,KAAArO,UACAivB,GAAA1Z,oBAAAtO,EAAAyhB,EAAAqiB,GAGA9b,EAAArc,iBAAA3L,EAAAyhB,EAAAqiB,GAIA9b,GAAAqB,aAAA,QAAAA,GAAAwT,GACA,GAAAkH,EAGA,KAAAtmB,EAAAua,WAAA6E,EAAAmH,sBAAA,CACAD,EAAAlH,EAAAmH,uBACA,QACA7qC,MAAA4qC,EAAA5qC,MACAC,OAAA2qC,EAAA3qC,QAIA,OACAD,MAAA0jC,EAAAoH,YACA7qC,OAAAyjC,EAAAqH,cAIA3sC,GAAAJ,QAAA6wB,IxCunMGqa,qBAAqB,KAAK8B,IAAI,SAASttC,EAAQU,EAAOJ,GyC70MzD,YAEA,IAAAitC,GAAAvtC,EAAA,aACA,IAAA4mB,GAAA5mB,EAAA,qBAEA,SAAAwtC,GAAApjC,GACArI,KAAAqI,QAAA,uBAAAA,GAAA,IAEAojC,EAAA/rC,UAAA,GAAAtB,MACAqtC,GAAA/rC,UAAAqR,KAAA,mBAEA,SAAA26B,GAAAC,GACA,IAAA9mB,EAAA+G,WAAA+f,GAAA,CACA,KAAA,IAAAF,GAAA,yCAGAzrC,KAAA2rC,UAAAA,EAGAD,EAAAhsC,UAAAksC,IAAA,SAAAj7B,EAAArI,EAAAjI,EAAA+qB,GACAO,EAAArjB,EAAAjI,EAAA+qB,EACA,IAAAxkB,GAAAk3B,CACA,IAAA+N,GAAA7rC,KAAA2rC,WACAvgB,GAAAA,KACAxkB,GAAAie,EAAA2J,SAAApD,EAAAxkB,SAAAwkB,EAAAxkB,QAAA,CAEAilC,GAAAzJ,KAAAzxB,EAAA66B,EAAAM,SAAAxjC,GAAA8rB,KAAA,KAEA,IAAAhJ,EAAA2gB,QAAA,CACAC,EAAAH,EAAAzgB,EAAA2gB,SAGA,GAAA3gB,EAAA0C,gBAAA,CACA+d,EAAA/d,gBAAA,KAGA+d,EAAArvB,OAAA,WACA,GAAAyvB,GAAAhgB,EAAA8B,CAUA,KAAA8d,EAAAK,sBAAA,CACAL,EAAAK,sBAAA,WACA,MAAA,OAIA,IAAAL,EAAA9d,OAAA,CACA8d,EAAA9d,OAAA,IAGA,GAAAlJ,EAAAwB,UAAAyX,GAAA,CACAvvB,aAAAuvB,EACAA,GAAA19B,UAGA6rC,EAAAJ,EAAAI,YAAA,EAIAhgB,GAAA,YAAA4f,GAAAA,EAAA5f,SAAA4f,EAAAM,YAGApe,GAAA8d,EAAA9d,SAAA,KAAA,IAAA8d,EAAA9d,MAEA1tB,GACA0tB,EACA9B,EACA4f,EAAAK,wBACAD,GAGAJ,GAAAO,QAAAC,CACAR,GAAAS,QAAAD,CAEAR,GAAAU,MAEA,IAAA3lC,EAAA,EAAA,CACAk3B,EAAAp2B,WAAA,WACAmkC,GAAAA,EAAAW,SACA5lC,GAGA,QAAA+kB,GAAArjB,EAAAjI,EAAA+qB,GACA,IAAAvG,EAAAwI,SAAA/kB,IAAAuc,EAAA0S,cAAAjvB,GAAA,CACA,KAAA,IAAAmjC,GAAA,gBAAAnjC,EAAA,KAGA,IAAAuc,EAAA+G,WAAAvrB,GAAA,CACA,KAAA,IAAAorC,GAAA,oBAAAprC,EAAA,0BAGA,GAAAwkB,EAAAwB,UAAA+E,KAAAvG,EAAA0Y,SAAAnS,GAAA,CACA,KAAA,IAAAqgB,GAAA,wBAAArgB,EAAA,MAIA,QAAA4gB,GAAAH,EAAAE,GACAlnB,EAAA7gB,QAAA+nC,EAAA,SAAApsC,EAAAL,GACA,GAAAulB,EAAAwB,UAAA1mB,GAAA,CACAksC,EAAAY,iBAAAntC,EAAAK,MAKA,QAAA0sC,KACAhsC,GAAA,EAAA,KAAA,KAAA,KAIAqrC,GAAAhsC,UAAAqK,IAAA,SAAAzB,EAAAjI,EAAA+qB,GACAprB,KAAA4rC,IAAA,MAAAtjC,EAAAokC,EAAAthB,EAEA,SAAAshB,GAAA3e,EAAA9B,EAAA0gB,EAAAV,GACA,GAAAW,EAAA7e,GAAA,CACA1tB,EAAA,KAAA4rB,EAAA8B,EAAA4e,EAAAV,OACA,CACA5rC,EAAA,GAAAorC,GAAAQ,GAAAhgB,EAAA8B,EAAA4e,EAAAV,IAIA,QAAAW,GAAA7e,GACA,MAAA,MAAAA,GAAAA,EAAA,KAIA,SAAA4d,KACA,GAAAE,GAAA,GAAAgB,eACA,MAAA,mBAAAhB,IAAA,CAEAA,EAAA,GAAAiB,gBAEA,MAAAjB,GAGA,GAAA3gB,GAAA,GAAAwgB,GAAAC,EAEAhtC,GAAAJ,SACA2sB,KAAAA,EACAwgB,YAAAA,EACAD,iBAAAA,EACAE,UAAAA,KzCi1MGoB,aAAa,GAAGtD,qBAAqB,KAAKuD,IAAI,SAAS/uC,EAAQU,EAAOJ,G0Cp+MzE,YAEA,IAAA6wB,GAAAnxB,EAAA,QACA,IAAA4mB,GAAA5mB,EAAA,qBAEA,IAAAoxB,KASAA,GAAA8X,kBAAA,QAAAA,GAAA5X,GACA,GAAA4Q,GAAA5Q,EAAAnoB,KAAAgO,cAAA,YAEA,IAAAowB,IACAyH,MAAA1d,EAAA0d,QACAp2B,IAAA0Y,EAAA2d,aACAhb,YAAA3C,EAAA2C,cACArJ,KAAA0G,EAAA4d,cACAC,SAAA7d,EAAAa,SACAid,iBAAAC,EAAA/d,GAGA,IAAA4Q,EAAA,CACAqF,EAAA+H,aAAApN,EAAAqN,MACAhI,GAAA51B,MAAAuwB,EAAAviB,aAAA,SAEA,MAAA4nB,EAGA,SAAA8H,GAAA/d,GACA,GAAAke,GAAAle,EAAAme,iBAAAne,EAAAme,qBAEA,IAAAD,GAAA5oB,EAAAyB,QAAAmnB,EAAAE,SAAA,CACAF,EAAAA,EAAAE,QAGA,IAAA9oB,EAAAyB,QAAAmnB,GAAA,CACAA,KAGA,GAAAJ,KACAI,GAAAzpC,QAAA,SAAA0qB,GACA2e,EAAA7/B,MACAkhB,MAAAA,EACAkf,KAAAlf,EAAAkf,MAEAlf,GAAAkf,KAAA,YAGA,OAAAP,IASAhe,GAAA4X,sBAAA,QAAAA,GAAA1X,EAAAiW,GACA,GAAArF,GAAA5Q,EAAAnoB,KAAAgO,cAAA,YACA,IAAAy4B,GAAA,EAEA,IAAArI,EAAA+H,aAAA,CACApN,EAAAqN,OAAAhI,EAAA+H,aAGA,GAAA,SAAA/H,GAAA,CAEArF,EAAA5zB,aAAA,QAAAi5B,EAAA51B,OAAA,IAGA,GAAAk+B,EAAAve,EAAAiW,GAAA,CAGAjW,EAAA+Q,IAAA,wBAAAyN,EAEAxe,GAAA+Q,IAAA,UAAA0N,EACAC,IAGA1e,GAAA1Y,KAAAA,IAAA2uB,EAAA3uB,IAAAgS,KAAA2c,EAAA3c,MAGA0G,GAAA2e,WAEA,CACAH,GAEA,IAAAvI,EAAA4H,QAAA,CACA7d,EAAAW,QAUA,QAAA+d,KACA,GAAAnQ,GAAAp2B,WAAA,WACA6nB,EAAArjB,QAAA,YACA,IAEAqjB,GAAA+Q,IAAA,UAAA,WACA/xB,aAAAuvB,KAUA,QAAAgQ,GAAAve,EAAAiW,GACA,GAAAjW,EAAA1Y,MAAA,CACA,MAAA0Y,GAAA1Y,QAAA2uB,EAAA3uB,IAGA,MAAA0Y,GAAA2d,eAAA1H,EAAA3uB,IAGA,QAAAk3B,KACA,GAAAV,GAAA7H,EAAA6H,gBACAA,GAAArpC,QAAA,SAAAmqC,GACAA,EAAAzf,MAAAkf,KAAAO,EAAAP,OAQA,QAAAI,KAKA,IAAA3e,EAAA+e,gBAAA7e,IAAAse,IAAA,CACAnmC,WAAAsmC,EAAA,QACA,CACA,IACA,GAAAze,EAAA2C,gBAAAsT,EAAAtT,YAAA,CACA,GAAAsT,EAAA4H,QAAA,CACA7d,EAAA+Q,IAAA,SAAA,WACA/Q,EAAAW,SAGAX,EAAA2C,YAAAsT,EAAAtT,iBAEA,IAAAsT,EAAA4H,QAAA,CAEA7d,EAAAW,QAGA,MAAAzyB,GACAknC,QAAA3F,IAAAqP,KAAA,sDAAA5wC,MAMA4xB,GAAA+e,gBAAA,SAAA7e,GAEA,GAAAA,EAAA/T,aAAA,EAAA,CAGA,MAAA,MAGA,GAAA+T,EAAA+e,aAAAluC,UAAA,CAGA,MAAA,MAGA,GAAAmvB,EAAA+e,WAAA7vC,OAAA,EAAA,CAEA,MAAA,MAGA,MAAA,OAUA4wB,GAAA+W,cAAA,SAAA7W,GACA,GAAAgf,GAAAhf,EAAAyY,SAAA,cACA,IAAAwG,GAAA,IACA,IAAAC,EAGAC,IAEAnf,GAAAhrB,GAAA,OAAAoqC,EACApf,GAAAhrB,GAAA,aAAAqqC,EACArf,GAAAhrB,GAAA,iBAAAsqC,EACAtf,GAAAhrB,GAAA,QAAAuqC,EACAvf,GAAAhrB,GAAA,eAAAuqC,EACAvf,GAAAhrB,GAAA,iBAAAuqC,EACAvf,GAAAhrB,GAAA,eAAAuqC,EACAvf,GAAAhrB,GAAA,eAAAwqC,EACAxf,GAAAhrB,GAAA,aAAAyqC,EACAzf,GAAAhrB,GAAA,iBAAAyqC,EAaA,SAAAN,KAQA,GAAAO,GAAA1f,EAAAW,IACAX,GAAAW,KAAA,SAAAgf,GACA,GAAAh7B,GAAAlU,IAEA,IAAAmvC,IAAA,CACAC,QACA,CACAC,EAAAH,GAGA,MAAAlvC,KAGA,SAAAovC,KACA,IAAAvqB,EAAAwiB,WAAA,CACAoH,EAAAa,GACA/f,GAAA+C,MAAA,MAGA2c,EAAAzgC,MAAA0F,EAAA/T,WAGA,QAAAkvC,GAAAH,GACA,GAAAK,MAAAL,EAAA,CACA3f,EAAAkW,KAAA1wB,OAAA5T,eACA,CACA8tC,EAAAzgC,MAAA0F,EAAA/T,aAYA,IAAAqvC,GAAAjgB,EAAAU,KACAV,GAAAU,MAAA,SAAAwf,GACA,GAAAF,MAAAE,EAAA,CACAlgB,EAAAkW,KAAA1wB,OAAA7T,cACA,CACAsuC,EAAAhhC,MAAAxO,KAAAG,WAEA,MAAAH,MAUA,IAAA0vC,GAAAngB,EAAAa,MACAb,GAAAa,OAAA,SAAAuf,GACA,GAAAJ,MAAAI,EAAA,CACA,MAAApgB,GAAAkW,KAAA1wB,OAAAob,WAEA,MAAAuf,GAAAlhC,MAAAxO,KAAAG,YAIA,QAAAovC,KACA,MAAAhgB,GAAAkW,MAAAlW,EAAAkW,KAAA1wB,OAGA,QAAA45B,KACA,GAAAQ,IAAA,CACAX,EAAA,KACAjf,GAAArjB,QAAA,mBAIA,QAAA0iC,KACAJ,EAAA,IACAD,GAAAvE,MACA6E,KAGA,QAAAM,KACA,MAAAX,GAGA,QAAAc,KACA,OACAhd,MAAA/C,EAAA+C,QACAxtB,OAAAyqB,EAAAzqB,UAIA,QAAA+pC,KACA,GAAAJ,EAAA,CACAlf,EAAA2C,YAAA,EACA0d,GAAAnB,EACAA,GAAA,MAIA,QAAAmB,GAAApK,GACA,GAAA3gB,EAAA0Y,SAAAiI,GAAA,CACAjW,EAAAzqB,OAAA0gC,EAAA1gC,OACAyqB,GAAA+C,MAAAkT,EAAAlT,QAIA,QAAAwc,KACA,IAAA1f,EAAAgE,SAAAmb,EAAAnnC,KAAA,cAAA,CACAmnC,EAAAzE,QAIA,QAAAiF,KACA3f,EAAA8D,SAAA3D,EAAAnoB,KAAA,kBAGA,QAAA4nC,KACA5f,EAAAyR,YAAAtR,EAAAnoB,KAAA,mBAWAioB,GAAAqX,mBAAA,SAAAnX,GACA,GAAA4Q,GAAA5Q,EAAAnoB,KAAAgO,cAAA,YACA,IAAA+qB,EAAA,CACAA,EAAA0P,gBAAA,WAYAxgB,GAAAsC,KAAA,QAAAA,GAAApC,EAAAwI,EAAAzwB,GACA,QAAAwoC,KACAxoC,EAAAkH,MAAA,KAAArO,UAEA43B,GAAA/zB,QAAA,SAAAI,GACAmrB,EAAA9qB,IAAAL,EAAA0rC,KAIA/X,EAAA/zB,QAAA,SAAAI,GACAmrB,EAAAhrB,GAAAH,EAAA0rC,KAKAnxC,GAAAJ,QAAA8wB,I1Cs+MG0gB,QAAQ,GAAGtG,qBAAqB,KAAKuG,IAAI,SAAS/xC,EAAQU,EAAOJ,G2C/2NpE,YAEA,IAAAsmB,GAAA5mB,EAAA,qBA0DA,IAAAgyC,GAAArnC,SAAA+F,cAAA,IAKA,IAAAuhC,GAAAtnC,SAAAunC,YAEA,SAAArE,GAAAxjC,GACA,GAAA8rB,GAAA9rB,CAEA,IAAA4nC,EAAA,CAGAD,EAAA1jC,aAAA,OAAA6nB,EACAA,GAAA6b,EAAA7b,KAGA6b,EAAA1jC,aAAA,OAAA6nB,EAGA,QACAA,KAAA6b,EAAA7b,KACAve,SAAAo6B,EAAAp6B,SAAAo6B,EAAAp6B,SAAAwB,QAAA,KAAA,IAAA,GACA+4B,KAAAH,EAAAG,KACAzgC,OAAAsgC,EAAAtgC,OAAAsgC,EAAAtgC,OAAA0H,QAAA,MAAA,IAAA,GACAsM,KAAAssB,EAAAtsB,KAAAssB,EAAAtsB,KAAAtM,QAAA,KAAA,IAAA,GACAvB,SAAAm6B,EAAAn6B,SACAC,KAAA8O,EAAA8D,iBAAAsnB,EAAAl6B,MAAAk6B,EAAAl6B,KAAA,GACAs6B,SAAAJ,EAAAI,SAAAC,OAAA,KAAA,IACAL,EAAAI,SACA,IAAAJ,EAAAI,UAUA,QAAAE,GAAAC,EAAAC,GACA,GAAA7sB,GAAA8sB,CAEAD,GAAA5rB,EAAA+G,WAAA6kB,GAAAA,EAAA,WACA,MAAA,MAGAD,GAAAA,EAAAG,OAAAt5B,QAAA,MAAA;AACAuM,EAAA4sB,EAAAr1B,MAAA,IACAu1B,KAEA7rB,GAAA7gB,QAAA4f,EAAA,SAAAgtB,GACA,GAAAzrB,GAAA7lB,EAAAK,CACA,IAAAixC,IAAA,GAAA,CACAzrB,EAAAyrB,EAAAz1B,MAAA,IACA7b,GAAA6lB,EAAA,EACAxlB,GAAAwlB,EAAA,EACA,IAAAsrB,EAAAnxC,EAAAK,GAAA,CACA+wC,EAAApxC,GAAAK,KAKA,OAAA+wC,GAQA,QAAAG,GAAAtuC,GACA,GAAAqhB,KACAiB,GAAA7gB,QAAAzB,EAAA,SAAA5C,EAAAL,GACAskB,EAAApW,KAAAlO,EAAA,IAAAK,IAEA,OAAAikB,GAAAymB,KAAA,KAGA1rC,EAAAJ,SACAutC,SAAAA,EACAyE,iBAAAA,EACAM,iBAAAA,K3Cm3NGpH,qBAAqB,KAAKqH,IAAI,SAAS7yC,EAAQU,EAAOJ,G4ChgOzD,YAEA,IAAAwyC,GAAA,CACA,IAAAC,GAAA,QACA,IAAAC,GAAA,mGAEA,IAAAC,GAAA,6RAGA,SAAA/rC,MAEA,QAAAgsC,GAAArzC,GACA,MAAAA,KAAA,KAGA,QAAAuoB,GAAAvoB,GACA,MAAAA,KAAAsC,UAGA,QAAA4lC,GAAAloC,GACA,MAAAA,KAAAsC,UAGA,QAAAm9B,GAAAh7B,GACA,aAAAA,KAAA,SAGA,QAAAqpB,GAAAlL,GACA,aAAAA,KAAA,WAGA,QAAA8N,GAAA4iB,GACA,aAAAA,KAAA,SAGA,QAAAC,GAAA9uC,GACA,MAAAsiB,GAAA0Y,SAAAh7B,IAAAA,EAAA0H,SAAA1H,EAGA,QAAA+jB,GAAAqQ,GACA,MAAAv3B,QAAAM,UAAA8P,SAAAhR,KAAAm4B,KAAA,iBAGA,QAAA2a,GAAA/uC,GACA,GAAAA,IAAA,MAAAsiB,EAAAwsB,SAAA9uC,IAAAsiB,EAAA+G,WAAArpB,IAAAsiB,EAAAmhB,YAAAzjC,GAAA,CACA,MAAA,OAGA,GAAA9D,GAAA8D,EAAA9D,MAEA,IAAA8D,EAAAid,WAAAuxB,GAAAtyC,EAAA,CACA,MAAA,MAGA,MAAAomB,GAAAwI,SAAA9qB,IAAAsiB,EAAAyB,QAAA/jB,IAAA9D,IAAA,SACAA,KAAA,UAAAA,EAAA,GAAAA,EAAA,IAAA8D,GAGA,QAAA8qB,GAAA3M,GACA,aAAAA,KAAA,SAGA,QAAA6W,GAAA7W,GACA,MAAAmE,GAAAwI,SAAA3M,IAAAA,EAAAjiB,SAAA,EAGA,QAAAkqB,GAAAjI,GACA,MAAAmE,GAAAwI,SAAA3M,IAAAA,EAAAjiB,SAAA,EAGA,QAAAo/B,GAAAtyB,GACA,MAAAwG,OAAArS,UAAAsS,MAAAxT,KAAA+M,GAGA,QAAAvH,GAAAzB,EAAAD,EAAAiO,GACA,GAAAjR,GAAAb,CACA,IAAA8D,EAAA,CACA,GAAAqpB,EAAArpB,GAAA,CACA,IAAAjD,IAAAiD,GAAA,CAGA,GAAAjD,IAAA,aAAAA,IAAA,UAAAA,IAAA,UAAAiD,EAAA4d,gBAAA5d,EAAA4d,eAAA7gB,IAAA,CACAgD,EAAA9D,KAAA+R,EAAAhO,EAAAjD,GAAAA,EAAAiD,SAGA,IAAA+jB,EAAA/jB,GAAA,CACA,GAAAgvC,SAAAhvC,KAAA,QACA,KAAAjD,EAAA,EAAAb,EAAA8D,EAAA9D,OAAAa,EAAAb,EAAAa,IAAA,CACA,GAAAiyC,GAAAjyC,IAAAiD,GAAA,CACAD,EAAA9D,KAAA+R,EAAAhO,EAAAjD,GAAAA,EAAAiD,SAGA,IAAAA,EAAAyB,SAAAzB,EAAAyB,UAAAA,EAAA,CACAzB,EAAAyB,QAAA1B,EAAAiO,EAAAhO,OACA,CACA,IAAAjD,IAAAiD,GAAA,CACA,GAAAA,EAAA4d,eAAA7gB,GAAA,CACAgD,EAAA9D,KAAA+R,EAAAhO,EAAAjD,GAAAA,EAAAiD,MAKA,MAAAA,GAGA,QAAAivC,GAAAzgC,EAAA0gC,GACAA,EAAAA,GAAA,GACA,OAAA1gC,GAAAsG,QAAA25B,EAAA,SAAAU,EAAAC,GACA,OAAAA,EAAAF,EAAA,IAAAC,EAAAz3B,gBAIA,QAAA23B,GAAAC,GACA,IAAAhtB,EAAAwI,SAAAwkB,GAAA,CACA,MAAA,OAGA,MAAAZ,GAAA52B,KAAAw3B,EAAAlB,QAGA,QAAAv+B,GAAA7P,GACA,GAAAuvC,GAAA5zC,EAAAgkB,CACA,KAAAhkB,EAAA,EAAAA,EAAAiC,UAAA1B,OAAAP,IAAA,CACA4zC,EAAA3xC,UAAAjC,EACA,KAAAgkB,IAAA4vB,GAAA,CACA,GAAAA,EAAA3xB,eAAA+B,GAAA,CACA,GAAAqb,EAAAh7B,EAAA2f,MAAAivB,EAAA5uC,EAAA2f,KAAAqb,EAAAuU,EAAA5vB,IAAA,CACA3f,EAAA2f,GAAA9P,KAAA7P,EAAA2f,GAAA4vB,EAAA5vB,QACA,CACA3f,EAAA2f,GAAA4vB,EAAA5vB,MAKA,MAAA3f,GAGA,QAAA02B,GAAAp7B,GACA,MAAAA,GAAAyyC,OAAA,GAAAhyB,cAAAzgB,EAAAmU,MAAA,GAGA,QAAA+/B,GAAAl0C,GACA,MAAAA,GAAAyyC,OAAA,GAAAr2B,cAAApc,EAAAmU,MAAA,GAOA,QAAA0W,GAAAiO,EAAAqb,GACA,GAAAC,KAEAtb,GAAA3yB,QAAA,SAAA6yB,EAAAlpB,GACA,GAAAukC,GAAAF,EAAAnb,EAAAlpB,EACA,IAAAkX,EAAAwB,UAAA6rB,GAAA,CACAD,EAAAzkC,KAAA0kC,KAIA,OAAAD,GAGA,QAAAve,GAAA0d,EAAAe,GACA,GAAAC,GAAAhB,EAAA,EACAe,GAAAttB,EAAA2J,SAAA2jB,GAAAA,EAAA,CACAf,GAAAvsB,EAAA2J,SAAA4iB,GAAAA,EAAAzwB,SAAAywB,EAAA,GACA,IAAAvsB,EAAA2J,SAAA4iB,KAAApiC,MAAAoiC,GAAA,CACAgB,EAAAhB,EAAA,EACA,OAAAgB,EAAA3zC,OAAA0zC,EAAA,CACAC,EAAA,IAAAA,EAEA,MAAAA,GAEA,MAAAC,KAAA,GAGA,QAAAvP,GAAAziC,EAAAiyC,GACA,GAAAC,IAAA,GAAAC,OAAAC,WAAAH,EAAA,EACA,OAAA,YACA,GAAAnb,IAAA,GAAAqb,OAAAC,SACA,IAAAtb,EAAAob,GAAAD,EAAA,CACAC,EAAApb,CACA92B,GAAAmO,MAAAxO,KAAAG,aAKA,QAAAuyC,GAAAryC,EAAAsyC,GACA,GAAA7U,EAEA,OAAA,YACA,GAAAA,EAAA,CACAvvB,aAAAuvB,GAEAA,EAAAp2B,WAAA,WACArH,EAAAmO,MAAAxO,KAAAG,UACA29B,GAAA19B,WACAuyC,IAMA,QAAAC,GAAA96B,EAAA+6B,EAAAC,GACA,GAAAC,GAAAF,EAAA/6B,EACA,KAAA,GAAA5Z,GAAA,EAAAA,EAAA60C,EAAAt0C,OAAAP,IAAA,CACA,GAAA40C,EAAAC,EAAA70C,IAAA,CACA,MAAA60C,GAAA70C,OAEA,CACA,GAAAkJ,GAAAwrC,EAAAG,EAAA70C,GAAA20C,EAAAC,EACA,IAAA1rC,EAAA,CACA,MAAAA,MAMA,QAAA6+B,GAAA+M,GACA,MAAA,YACA,MAAAA,IAMA,QAAAC,GAAAtzC,GACA,GAAAklB,EAAA2J,SAAA7uB,GAAA,CACAA,EAAAA,EAAA,GAGA,IAAAklB,EAAAwI,SAAA1tB,GAAA,CACA,MAAA,OAGA,MAAAuxC,GAAA72B,KAAA1a,EAAAgxC,QAOA,QAAAvR,KACA,GAAArb,GAAAc,EAAAquB,2BAAAt6B,UACA,IAAAmL,KAAA,EAAA,CACA,MAAA,OAGA,MAAAA,GAAA,GAQA,QAAAmvB,GAAAt6B,GACA,GAAAiI,IAAA,CAEA,IAAAjI,EAAA6B,SAAA,8BAAA,CACA,GAAAb,GAAAhB,EAAAoB,SACA,IAAAm5B,GAAA,GAAA77B,QAAA,6BACA,IAAA87B,GAAAD,EAAArxB,KAAAlI,EACA,IAAAw5B,IAAA,KAAA,CACAvyB,EAAA5R,WAAAmkC,EAAA,KAIA,MAAAvyB,GAIA,QAAAinB,KACA,MAAA,cAAAztB,KAAAwK,EAAAwuB,KAGA,QAAAC,KACA,MAAA,uCAAAj5B,KAAAwK,EAAAwuB,KAGA,QAAAhM,KACA,MAAA,cAAAhtB,KAAAwK,EAAAwuB,KAGA,QAAAE,KACA,MAAA,UAAAl5B,KAAAwK,EAAAwuB,KAGA,GAAAxuB,IACAwuB,IAAAz6B,UAAAoB,UACA7U,KAAAA,EACAgsC,OAAAA,EACA9qB,UAAAA,EACA2f,YAAAA,EACAzI,SAAAA,EACA3R,WAAAA,EACA4C,SAAAA,EACA6iB,SAAAA,EACA/qB,QAAAA,EACAgrB,YAAAA,EACAjkB,SAAAA,EACAkK,cAAAA,EACA5O,iBAAAA,EACAkV,oBAAAA,EACA75B,QAAAA,EACAwtC,WAAAA,EACAI,aAAAA,EACAx/B,OAAAA,EACA6mB,WAAAA,EACA8Y,aAAAA,EACArpB,eAAAA,EACAgL,cAAAA,EACAoP,SAAAA,EACA4P,SAAAA,EACAE,WAAAA,EACA3M,OAAAA,EACAgN,UAAAA,EACA7T,QAAAA,EACA8T,2BAAAA,EACApL,UAAAA,EACAwL,SAAAA,EACAjM,SAAAA,EACAkM,UAAAA,EAGA50C,GAAAJ,QAAAsmB,O5CmgOM2uB,IAAI,SAASv1C,EAAQU,EAAOJ,G6Cz0OlC,YAEA,IAAAsmB,GAAA5mB,EAAA,qBAEA,IAAA6mB,KAEAA,GAAA2uB,YAAA,QAAAA,GAAAC,GAEA,SAAAzpC,QAAA0pC,YAAA,YAAA,CACA,GAAAC,GAAA,GAAA34B,eAAA,mBACA24B,GAAA3oB,MAAA,KACA2oB,GAAAC,QAAAH,EACA,OAAAE,GAGA,MAAAE,GAAAJ,EAEA,SAAAI,GAAAJ,GACA,GAAAK,GAAA,GAAAJ,UACA,IAAAK,EAGA,KACAA,EAAAD,EAAAE,gBAAAP,EAAA,kBAEA,IAAAQ,EAAAF,IAAAnvB,EAAA0S,cAAAmc,GAAA,CACA,KAAA,IAAAt1C,QAEA,MAAAX,GACA,KAAA,IAAAW,OAAA,+CAAAs1C,EAAA,KAGA,MAAAM,GAGA,QAAAE,GAAAF,GACA,IACA,GAAAD,GAAA,GAAAJ,WACAQ,EAAAJ,EAAAE,gBAAA,UAAA,YACAG,EAAAD,EAAAp6B,qBAAA,eAAA,GAAAs6B,YAEA,IAAAD,IAAA,+BAAA,CAEA,MAAAJ,GAAAj6B,qBAAA,eAAAtb,OAAA,EAGA,MAAAu1C,GAAAM,uBAAAF,EAAA,eAAA31C,OAAA,EACA,MAAAhB,MAMAqnB,GAAAyvB,UAAA,QAAAA,GAAAC,GACA,GAAA,QAAAn6B,KAAAm6B,GAAA,CAAA,MAAA,MACA,GAAA,oBAAAn6B,KAAAm6B,GAAA,CAAA,MAAAA,GAAAv6B,gBAAA,OACA,GAAA/K,SAAAslC,GAAA,CAAA,MAAAvlC,YAAAulC,GACA,GAAA3vB,EAAAouB,UAAAuB,GAAA,CAAA,MAAA,IAAAhC,MAAAgC,GACA,MAAAA,GAAA7D,OAGA7rB,GAAA8Q,SAAA,QAAAA,GAAA6e,GACA,GAAAF,GAAAzvB,EAAAyvB,SAKA,IAAAE,EAAA7hC,gBAAA,CACA,MAAA,IAAAkS,GAAA8Q,SAAA6e,EAAA7hC,iBAGA,GAAA6hC,EAAAC,gBAAA,CACA,GAAAC,GAAA,EACA,KAAA,GAAAC,GAAAC,EAAAC,EAAAC,EAAA,EAAAA,EAAAN,EAAAn1B,WAAA7gB,OAAAs2C,IAAA,CACAH,EAAAH,EAAAn1B,WAAAuX,KAAAke,EAEA,KAAAH,EAAAp1B,SAAA,EAAA,KAAA,EAAA,CAAAm1B,GAAAC,EAAAp1B,WAAA,EAAAo1B,EAAAI,UAAArE,OAAAiE,EAAAI,cACA,IAAAJ,EAAAp1B,WAAA,IAAAo1B,EAAA1mC,OAAA,CACA2mC,EAAAhwB,EAAAktB,aAAA6C,EAAAv2B,SACAy2B,GAAA,GAAAhwB,GAAA8Q,SAAAgf,EACA,IAAA50C,KAAAmgB,eAAA00B,GAAA,CACA,GAAA70C,KAAA60C,GAAAryC,cAAAuP,MAAA,CAAA/R,KAAA60C,IAAA70C,KAAA60C,IACA70C,KAAA60C,GAAArnC,KAAAsnC,OACA,CAAA90C,KAAA60C,GAAAC,IAGA,GAAAH,EAAA,CAAA30C,KAAAmlB,SAAAovB,EAAAI,IAIA,GAAAM,SAAAR,GAAAS,gBAAA,YAAAT,EAAAU,WAAA12C,OAAA,EAAAg2C,EAAAS,eACA,IAAAD,EAAA,CACA,GAAAG,EACA,KAAA,GAAAC,GAAA,EAAAA,EAAAZ,EAAAU,WAAA12C,OAAA42C,IAAA,CACAD,EAAAX,EAAAU,WAAAte,KAAAwe,EACAr1C,MAAA,IAAA6kB,EAAAktB,aAAAqD,EAAArkC,OAAAwjC,EAAAa,EAAAz1C,MAAAgxC,UAKA7rB,GAAA8Q,SAAAl2B,UAAAsgB,KAAA,SAAAA,GACA,MAAAhgB,MAAA,IAAA6kB,EAAAktB,aAAA/xB,IAGA8E,GAAAkI,WAAA,QAAAA,GAAAsoB,GACA,GAAAC,GAAAzwB,EAAA2uB,YAAA6B,EACA,OAAA,IAAAxwB,GAAA8Q,SAAA2f,GASAzwB,GAAAK,SAAA,QAAAqwB,GAAAC,GACA,GAAAA,EAAA,CACA,MAAAA,GAAAtwB,SAEA,MAAA/kB,WAGA0kB,GAAA9E,KAAA,QAAA01B,GAAAD,EAAAz1B,GACA,GAAAy1B,EAAA,CACA,MAAAA,GAAA,IAAA5wB,EAAAktB,aAAA/xB,IAEA,MAAA5f,WAGA0kB,GAAA6wB,OAAA,QAAAC,GAAAl1B,GACA,MAAAA,GAAArJ,QAAA,KAAA,SACAA,QAAA,KAAA,QACAA,QAAA,KAAA,QACAA,QAAA,KAAA,UACAA,QAAA,KAAA,UAGAyN,GAAAgF,OAAA,QAAA+rB,GAAAn1B,GACA,MAAAA,GAAArJ,QAAA,UAAA,KACAA,QAAA,UAAA,KACAA,QAAA,QAAA,KACAA,QAAA,QAAA,KACAA,QAAA,SAAA,KAGA1Y,GAAAJ,QAAAumB,I7C20OG2kB,qBAAqB,KAAKqM,IAAI,SAAS73C,EAAQU,EAAOJ,G8C59OzD,YAEAN,GAAA,kCACAA,GAAA,qCAEA,IAAA83C,GAAA93C,EAAA,8BAEA0mC,SAAA9rB,OAAA,aAAAk9B,K9C+9OGC,kCAAkC,GAAGC,qCAAqC,GAAGC,8BAA8B,UAAU","file":"videojs_5.vast.vpaid.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o 0) {\n callback(event);\n }\n }, 0);\n }\n });\n }\n }, {\n key: '_callCallback',\n value: function _callCallback(methodName, callbackID, err, result) {\n\n var callback = this._callbacks.get(callbackID);\n\n //not all methods callback's are mandatory\n //but if there exist an error, fire the error event\n if (!callback) {\n if (err && callbackID === '') {\n this.trigger(ERROR, err);\n }\n return;\n }\n\n $asyncCallback.call(this, callbackID, err, result);\n }\n }, {\n key: '_handShake',\n value: function _handShake(err, data) {\n this._ready = true;\n if (this._handShakeHandler) {\n this._handShakeHandler(err, data);\n delete this._handShakeHandler;\n }\n }\n\n //methods like properties specific to this implementation of VPAID\n\n }, {\n key: 'getSize',\n value: function getSize() {\n return { width: this._width, height: this._height };\n }\n }, {\n key: 'setSize',\n value: function setSize(newWidth, newHeight) {\n this._width = isPositiveInt(newWidth, this._width);\n this._height = isPositiveInt(newHeight, this._height);\n this._el.setAttribute('width', this._width);\n this._el.setAttribute('height', this._height);\n }\n }, {\n key: 'getWidth',\n value: function getWidth() {\n return this._width;\n }\n }, {\n key: 'setWidth',\n value: function setWidth(newWidth) {\n this.setSize(newWidth, this._height);\n }\n }, {\n key: 'getHeight',\n value: function getHeight() {\n return this._height;\n }\n }, {\n key: 'setHeight',\n value: function setHeight(newHeight) {\n this.setSize(this._width, newHeight);\n }\n }, {\n key: 'getFlashID',\n value: function getFlashID() {\n return this._flashID;\n }\n }, {\n key: 'getFlashURL',\n value: function getFlashURL() {\n return this._flashURL;\n }\n }, {\n key: 'isReady',\n value: function isReady() {\n return this._ready;\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.offAll();\n this.removeAllCallbacks();\n registry.removeInstanceByID(this._flashID);\n if (this._el.parentElement) {\n this._el.parentElement.removeChild(this._el);\n }\n }\n }]);\n\n return JSFlashBridge;\n}();\n\nfunction $asyncCallback(callbackID, err, result) {\n var _this3 = this;\n\n setTimeout(function () {\n var callback = _this3._callbacks.get(callbackID);\n if (callback) {\n _this3._callbacks.remove(callbackID);\n callback(err, result);\n }\n }, 0);\n}\n\nObject.defineProperty(JSFlashBridge, 'VPAID_FLASH_HANDLER', {\n writable: false,\n configurable: false,\n value: VPAID_FLASH_HANDLER\n});\n\n/**\n * External interface handler\n *\n * @param {string} flashID identifier of the flash who call this\n * @param {string} typeID what type of message is, can be 'event' or 'callback'\n * @param {string} typeName if the typeID is a event the typeName will be the eventName, if is a callback the typeID is the methodName that is related this callback\n * @param {string} callbackID only applies when the typeID is 'callback', identifier of the callback to call\n * @param {object} error error object\n * @param {object} data\n */\nwindow[VPAID_FLASH_HANDLER] = function (flashID, typeID, typeName, callbackID, error, data) {\n var instance = registry.getInstanceByID(flashID);\n if (!instance) return;\n if (typeName === 'handShake') {\n instance._handShake(error, data);\n } else {\n if (typeID !== 'event') {\n instance._callCallback(typeName, callbackID, error, data);\n } else {\n instance._trigger(typeName, data);\n }\n }\n};\n\n},{\"./jsFlashBridgeRegistry\":6,\"./registry\":7,\"./utils\":8}],6:[function(require,module,exports){\n'use strict';\n\nvar SingleValueRegistry = require('./registry').SingleValueRegistry;\nvar instances = new SingleValueRegistry();\n\nvar JSFlashBridgeRegistry = {};\nObject.defineProperty(JSFlashBridgeRegistry, 'addInstance', {\n writable: false,\n configurable: false,\n value: function value(id, instance) {\n instances.add(id, instance);\n }\n});\n\nObject.defineProperty(JSFlashBridgeRegistry, 'getInstanceByID', {\n writable: false,\n configurable: false,\n value: function value(id) {\n return instances.get(id);\n }\n});\n\nObject.defineProperty(JSFlashBridgeRegistry, 'removeInstanceByID', {\n writable: false,\n configurable: false,\n value: function value(id) {\n return instances.remove(id);\n }\n});\n\nmodule.exports = JSFlashBridgeRegistry;\n\n},{\"./registry\":7}],7:[function(require,module,exports){\n'use strict';\n\nvar _createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if (\"value\" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);\n }\n }return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;\n };\n}();\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nfunction _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}\n\nvar MultipleValuesRegistry = exports.MultipleValuesRegistry = function () {\n function MultipleValuesRegistry() {\n _classCallCheck(this, MultipleValuesRegistry);\n\n this._registries = {};\n }\n\n _createClass(MultipleValuesRegistry, [{\n key: 'add',\n value: function add(id, value) {\n if (!this._registries[id]) {\n this._registries[id] = [];\n }\n if (this._registries[id].indexOf(value) === -1) {\n this._registries[id].push(value);\n }\n }\n }, {\n key: 'get',\n value: function get(id) {\n return this._registries[id] || [];\n }\n }, {\n key: 'filterKeys',\n value: function filterKeys(handler) {\n return Object.keys(this._registries).filter(handler);\n }\n }, {\n key: 'findByValue',\n value: function findByValue(value) {\n var _this = this;\n\n var keys = Object.keys(this._registries).filter(function (key) {\n return _this._registries[key].indexOf(value) !== -1;\n });\n\n return keys;\n }\n }, {\n key: 'remove',\n value: function remove(key, value) {\n if (!this._registries[key]) {\n return;\n }\n\n var index = this._registries[key].indexOf(value);\n\n if (index < 0) {\n return;\n }\n return this._registries[key].splice(index, 1);\n }\n }, {\n key: 'removeByKey',\n value: function removeByKey(id) {\n var old = this._registries[id];\n delete this._registries[id];\n return old;\n }\n }, {\n key: 'removeByValue',\n value: function removeByValue(value) {\n var _this2 = this;\n\n var keys = this.findByValue(value);\n return keys.map(function (key) {\n return _this2.remove(key, value);\n });\n }\n }, {\n key: 'removeAll',\n value: function removeAll() {\n var old = this._registries;\n this._registries = {};\n return old;\n }\n }, {\n key: 'size',\n value: function size() {\n return Object.keys(this._registries).length;\n }\n }]);\n\n return MultipleValuesRegistry;\n}();\n\nvar SingleValueRegistry = exports.SingleValueRegistry = function () {\n function SingleValueRegistry() {\n _classCallCheck(this, SingleValueRegistry);\n\n this._registries = {};\n }\n\n _createClass(SingleValueRegistry, [{\n key: 'add',\n value: function add(id, value) {\n this._registries[id] = value;\n }\n }, {\n key: 'get',\n value: function get(id) {\n return this._registries[id];\n }\n }, {\n key: 'filterKeys',\n value: function filterKeys(handler) {\n return Object.keys(this._registries).filter(handler);\n }\n }, {\n key: 'findByValue',\n value: function findByValue(value) {\n var _this3 = this;\n\n var keys = Object.keys(this._registries).filter(function (key) {\n return _this3._registries[key] === value;\n });\n\n return keys;\n }\n }, {\n key: 'remove',\n value: function remove(id) {\n var old = this._registries[id];\n delete this._registries[id];\n return old;\n }\n }, {\n key: 'removeByValue',\n value: function removeByValue(value) {\n var _this4 = this;\n\n var keys = this.findByValue(value);\n return keys.map(function (key) {\n return _this4.remove(key);\n });\n }\n }, {\n key: 'removeAll',\n value: function removeAll() {\n var old = this._registries;\n this._registries = {};\n return old;\n }\n }, {\n key: 'size',\n value: function size() {\n return Object.keys(this._registries).length;\n }\n }]);\n\n return SingleValueRegistry;\n}();\n\n},{}],8:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.unique = unique;\nexports.noop = noop;\nexports.callbackTimeout = callbackTimeout;\nexports.createElementWithID = createElementWithID;\nexports.isPositiveInt = isPositiveInt;\nexports.stringEndsWith = stringEndsWith;\nexports.hideFlashEl = hideFlashEl;\nfunction unique(prefix) {\n var count = -1;\n return function (f) {\n return prefix + '_' + ++count;\n };\n}\n\nfunction noop() {}\n\nfunction callbackTimeout(timer, onSuccess, onTimeout) {\n\n var timeout = setTimeout(function () {\n\n onSuccess = noop;\n onTimeout();\n }, timer);\n\n return function () {\n clearTimeout(timeout);\n onSuccess.apply(this, arguments);\n };\n}\n\nfunction createElementWithID(parent, id) {\n var cleanContent = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n var nEl = document.createElement('div');\n nEl.id = id;\n if (cleanContent) {\n parent.innerHTML = '';\n }\n parent.appendChild(nEl);\n return nEl;\n}\n\nfunction isPositiveInt(newVal, oldVal) {\n return !isNaN(parseFloat(newVal)) && isFinite(newVal) && newVal > 0 ? newVal : oldVal;\n}\n\nvar endsWith = function () {\n if (String.prototype.endsWith) return String.prototype.endsWith;\n return function endsWith(searchString, position) {\n var subjectString = this.toString();\n if (position === undefined || position > subjectString.length) {\n position = subjectString.length;\n }\n position -= searchString.length;\n var lastIndex = subjectString.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n };\n}();\n\nfunction stringEndsWith(string, search) {\n return endsWith.call(string, search);\n}\n\nfunction hideFlashEl(el) {\n // can't use display none or visibility none because will block flash in some browsers\n el.style.position = 'absolute';\n el.style.left = '-1px';\n el.style.top = '-1px';\n el.style.width = '1px';\n el.style.height = '1px';\n}\n\n},{}],9:[function(require,module,exports){\n'use strict';\n\nvar METHODS = [\n 'handshakeVersion',\n 'initAd',\n 'startAd',\n 'stopAd',\n 'skipAd', // VPAID 2.0 new method\n 'resizeAd',\n 'pauseAd',\n 'resumeAd',\n 'expandAd',\n 'collapseAd',\n 'subscribe',\n 'unsubscribe'\n];\n\nvar EVENTS = [\n 'AdLoaded',\n 'AdStarted',\n 'AdStopped',\n 'AdSkipped',\n 'AdSkippableStateChange', // VPAID 2.0 new event\n 'AdSizeChange', // VPAID 2.0 new event\n 'AdLinearChange',\n 'AdDurationChange', // VPAID 2.0 new event\n 'AdExpandedChange',\n 'AdRemainingTimeChange', // [Deprecated in 2.0] but will be still fired for backwards compatibility\n 'AdVolumeChange',\n 'AdImpression',\n 'AdVideoStart',\n 'AdVideoFirstQuartile',\n 'AdVideoMidpoint',\n 'AdVideoThirdQuartile',\n 'AdVideoComplete',\n 'AdClickThru',\n 'AdInteraction', // VPAID 2.0 new event\n 'AdUserAcceptInvitation',\n 'AdUserMinimize',\n 'AdUserClose',\n 'AdPaused',\n 'AdPlaying',\n 'AdLog',\n 'AdError'\n];\n\nvar GETTERS = [\n 'getAdLinear',\n 'getAdWidth', // VPAID 2.0 new getter\n 'getAdHeight', // VPAID 2.0 new getter\n 'getAdExpanded',\n 'getAdSkippableState', // VPAID 2.0 new getter\n 'getAdRemainingTime',\n 'getAdDuration', // VPAID 2.0 new getter\n 'getAdVolume',\n 'getAdCompanions', // VPAID 2.0 new getter\n 'getAdIcons' // VPAID 2.0 new getter\n];\n\nvar SETTERS = [\n 'setAdVolume'\n];\n\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n\n/**\n * IVPAIDAdUnit\n *\n * @class\n *\n * @param {object} creative\n * @param {HTMLElement} el\n * @param {HTMLVideoElement} video\n */\nfunction IVPAIDAdUnit(creative, el, video) {}\n\n\n/**\n * handshakeVersion\n *\n * @param {string} VPAIDVersion\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.handshakeVersion = function (VPAIDVersion, callback) {};\n\n/**\n * initAd\n *\n * @param {number} width\n * @param {number} height\n * @param {string} viewMode can be 'normal', 'thumbnail' or 'fullscreen'\n * @param {number} desiredBitrate indicates the desired bitrate in kbps\n * @param {object} [creativeData] used for additional initialization data\n * @param {object} [environmentVars] used for passing implementation-specific of js version\n * @param {NodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.initAd = function(width, height, viewMode, desiredBitrate, creativeData, environmentVars, callback) {};\n\n/**\n * startAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.startAd = function(callback) {};\n\n/**\n * stopAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.stopAd = function(callback) {};\n\n/**\n * skipAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.skipAd = function(callback) {};\n\n/**\n * resizeAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.resizeAd = function(width, height, viewMode, callback) {};\n\n/**\n * pauseAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.pauseAd = function(callback) {};\n\n/**\n * resumeAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.resumeAd = function(callback) {};\n\n/**\n * expandAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.expandAd = function(callback) {};\n\n/**\n * collapseAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.collapseAd = function(callback) {};\n\n/**\n * subscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n * @param {object} context\n */\nIVPAIDAdUnit.prototype.subscribe = function(event, handler, context) {};\n\n/**\n * startAd\n *\n * @param {string} event\n * @param {function} handler\n */\nIVPAIDAdUnit.prototype.unsubscribe = function(event, handler) {};\n\n\n\n/**\n * getAdLinear\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdLinear = function(callback) {};\n\n/**\n * getAdWidth\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdWidth = function(callback) {};\n\n/**\n * getAdHeight\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdHeight = function(callback) {};\n\n/**\n * getAdExpanded\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdExpanded = function(callback) {};\n\n/**\n * getAdSkippableState\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdSkippableState = function(callback) {};\n\n/**\n * getAdRemainingTime\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdRemainingTime = function(callback) {};\n\n/**\n * getAdDuration\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdDuration = function(callback) {};\n\n/**\n * getAdVolume\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdVolume = function(callback) {};\n\n/**\n * getAdCompanions\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdCompanions = function(callback) {};\n\n/**\n * getAdIcons\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdIcons = function(callback) {};\n\n/**\n * setAdVolume\n *\n * @param {number} volume\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.setAdVolume = function(volume, callback) {};\n\naddStaticToInterface(IVPAIDAdUnit, 'METHODS', METHODS);\naddStaticToInterface(IVPAIDAdUnit, 'GETTERS', GETTERS);\naddStaticToInterface(IVPAIDAdUnit, 'SETTERS', SETTERS);\naddStaticToInterface(IVPAIDAdUnit, 'EVENTS', EVENTS);\n\n\nvar VPAID1_METHODS = METHODS.filter(function(method) {\n return ['skipAd'].indexOf(method) === -1;\n});\n\naddStaticToInterface(IVPAIDAdUnit, 'checkVPAIDInterface', function checkVPAIDInterface (creative) {\n var result = VPAID1_METHODS.every(function(key) {\n return typeof creative[key] === 'function';\n });\n return result;\n});\n\nmodule.exports = IVPAIDAdUnit;\n\nfunction addStaticToInterface(Interface, name, value) {\n Object.defineProperty(Interface, name, {\n writable: false,\n configurable: false,\n value: value\n });\n}\n\n\n},{}],10:[function(require,module,exports){\n'use strict';\n\nvar IVPAIDAdUnit = require('./IVPAIDAdUnit');\nvar Subscriber = require('./subscriber');\nvar checkVPAIDInterface = IVPAIDAdUnit.checkVPAIDInterface;\nvar utils = require('./utils');\nvar METHODS = IVPAIDAdUnit.METHODS;\nvar ERROR = 'AdError';\nvar AD_CLICK = 'AdClickThru';\nvar FILTERED_EVENTS = IVPAIDAdUnit.EVENTS.filter(function (event) {\n return event != AD_CLICK;\n});\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n\n/**\n * VPAIDAdUnit\n * @class\n *\n * @param VPAIDCreative\n * @param {HTMLElement} [el] this will be used in initAd environmentVars.slot if defined\n * @param {HTMLVideoElement} [video] this will be used in initAd environmentVars.videoSlot if defined\n */\nfunction VPAIDAdUnit(VPAIDCreative, el, video, iframe) {\n this._isValid = checkVPAIDInterface(VPAIDCreative);\n if (this._isValid) {\n this._creative = VPAIDCreative;\n this._el = el;\n this._videoEl = video;\n this._iframe = iframe;\n this._subscribers = new Subscriber();\n $addEventsSubscribers.call(this);\n }\n}\n\nVPAIDAdUnit.prototype = Object.create(IVPAIDAdUnit.prototype);\n\n/**\n * isValidVPAIDAd will return if the VPAIDCreative passed in constructor is valid or not\n *\n * @return {boolean}\n */\nVPAIDAdUnit.prototype.isValidVPAIDAd = function isValidVPAIDAd() {\n return this._isValid;\n};\n\nIVPAIDAdUnit.METHODS.forEach(function(method) {\n //NOTE: this methods arguments order are implemented differently from the spec\n var ignores = [\n 'subscribe',\n 'unsubscribe',\n 'initAd'\n ];\n\n if (ignores.indexOf(method) !== -1) return;\n\n VPAIDAdUnit.prototype[method] = function () {\n var ariaty = IVPAIDAdUnit.prototype[method].length;\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n var args = Array.prototype.slice.call(arguments);\n var callback = (ariaty === args.length) ? args.pop() : undefined;\n\n setTimeout(function () {\n var result, error = null;\n try {\n result = this._creative[method].apply(this._creative, args);\n } catch(e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n };\n});\n\n\n/**\n * initAd concreate implementation\n *\n * @param {number} width\n * @param {number} height\n * @param {string} viewMode can be 'normal', 'thumbnail' or 'fullscreen'\n * @param {number} desiredBitrate indicates the desired bitrate in kbps\n * @param {object} [creativeData] used for additional initialization data\n * @param {object} [environmentVars] used for passing implementation-specific of js version, if el & video was used in constructor slot & videoSlot will be added to the object\n * @param {NodeStyleCallback} callback\n */\nVPAIDAdUnit.prototype.initAd = function initAd(width, height, viewMode, desiredBitrate, creativeData, environmentVars, callback) {\n creativeData = creativeData || {};\n environmentVars = utils.extend({\n slot: this._el,\n videoSlot: this._videoEl\n }, environmentVars || {});\n\n setTimeout(function () {\n var error;\n try {\n this._creative.initAd(width, height, viewMode, desiredBitrate, creativeData, environmentVars);\n } catch (e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error);\n }.bind(this), 0);\n};\n\n/**\n * subscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n * @param {object} context\n */\nVPAIDAdUnit.prototype.subscribe = function subscribe(event, handler, context) {\n this._subscribers.subscribe(handler, event, context);\n};\n\n\n/**\n * unsubscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n */\nVPAIDAdUnit.prototype.unsubscribe = function unsubscribe(event, handler) {\n this._subscribers.unsubscribe(handler, event);\n};\n\n//alias\nVPAIDAdUnit.prototype.on = VPAIDAdUnit.prototype.subscribe;\nVPAIDAdUnit.prototype.off = VPAIDAdUnit.prototype.unsubscribe;\n\nIVPAIDAdUnit.GETTERS.forEach(function(getter) {\n VPAIDAdUnit.prototype[getter] = function (callback) {\n setTimeout(function () {\n\n var result, error = null;\n try {\n result = this._creative[getter]();\n } catch(e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n };\n});\n\n/**\n * setAdVolume\n *\n * @param volume\n * @param {nodeStyleCallback} callback\n */\nVPAIDAdUnit.prototype.setAdVolume = function setAdVolume(volume, callback) {\n setTimeout(function () {\n\n var result, error = null;\n try {\n this._creative.setAdVolume(volume);\n result = this._creative.getAdVolume();\n } catch(e) {\n error = e;\n }\n\n if (!error) {\n error = utils.validate(result === volume, 'failed to apply volume: ' + volume);\n }\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n};\n\nVPAIDAdUnit.prototype._destroy = function destroy() {\n this.stopAd();\n this._subscribers.unsubscribeAll();\n};\n\nfunction $addEventsSubscribers() {\n // some ads implement\n // so they only handle one subscriber\n // to handle this we create our one\n FILTERED_EVENTS.forEach(function (event) {\n this._creative.subscribe($trigger.bind(this, event), event);\n }.bind(this));\n\n // map the click event to be an object instead of depending of the order of the arguments\n // and to be consistent with the flash\n this._creative.subscribe($clickThruHook.bind(this), AD_CLICK);\n\n // because we are adding the element inside the iframe\n // the user is not able to click in the video\n if (this._videoEl) {\n var documentElement = this._iframe.contentDocument.documentElement;\n var videoEl = this._videoEl;\n documentElement.addEventListener('click', function(e) {\n if (e.target === documentElement) {\n videoEl.click();\n }\n });\n }\n}\n\nfunction $clickThruHook(url, id, playerHandles) {\n this._subscribers.triggerSync(AD_CLICK, {url: url, id: id, playerHandles: playerHandles});\n}\n\nfunction $trigger(event) {\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n this._subscribers.trigger(event, Array.prototype.slice(arguments, 1));\n}\n\nfunction callOrTriggerEvent(callback, subscribers, error, result) {\n if (callback) {\n callback(error, result);\n } else if (error) {\n subscribers.trigger(ERROR, error);\n }\n}\n\nmodule.exports = VPAIDAdUnit;\n\n\n},{\"./IVPAIDAdUnit\":9,\"./subscriber\":12,\"./utils\":13}],11:[function(require,module,exports){\n'use strict';\n\nvar utils = require('./utils');\nvar unique = utils.unique('vpaidIframe');\nvar VPAIDAdUnit = require('./VPAIDAdUnit');\n\nvar defaultTemplate = '' +\n '' +\n '' +\n '
' +\n '' +\n '' +\n '' +\n '';\n\nvar AD_STOPPED = 'AdStopped';\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n/**\n * VPAIDHTML5Client\n * @class\n *\n * @param {HTMLElement} el that will contain the iframe to load adUnit and a el to add to adUnit slot\n * @param {HTMLVideoElement} video default video element to be used by adUnit\n * @param {object} [templateConfig] template: html template to be used instead of the default, extraOptions: to be used when rendering the template\n * @param {object} [vpaidOptions] timeout: when loading adUnit\n */\nfunction VPAIDHTML5Client(el, video, templateConfig, vpaidOptions) {\n templateConfig = templateConfig || {};\n\n this._id = unique();\n this._destroyed = false;\n\n this._frameContainer = utils.createElementInEl(el, 'div');\n this._videoEl = video;\n this._vpaidOptions = vpaidOptions || {timeout: 10000};\n\n this._templateConfig = {\n template: templateConfig.template || defaultTemplate,\n extraOptions: templateConfig.extraOptions || {}\n };\n}\n\n/**\n * destroy\n *\n */\nVPAIDHTML5Client.prototype.destroy = function destroy() {\n if (this._destroyed) {\n return;\n }\n this._destroyed = true;\n $unloadPreviousAdUnit.call(this);\n};\n\n/**\n * isDestroyed\n *\n * @return {boolean}\n */\nVPAIDHTML5Client.prototype.isDestroyed = function isDestroyed() {\n return this._destroyed;\n};\n\n/**\n * loadAdUnit\n *\n * @param {string} adURL url of the js of the adUnit\n * @param {nodeStyleCallback} callback\n */\nVPAIDHTML5Client.prototype.loadAdUnit = function loadAdUnit(adURL, callback) {\n $throwIfDestroyed.call(this);\n $unloadPreviousAdUnit.call(this);\n var that = this;\n\n var frame = utils.createIframeWithContent(\n this._frameContainer,\n this._templateConfig.template,\n utils.extend({\n iframeURL_JS: adURL,\n iframeID: this.getID(),\n origin: getOrigin()\n }, this._templateConfig.extraOptions)\n );\n\n this._frame = frame;\n\n this._onLoad = utils.callbackTimeout(\n this._vpaidOptions.timeout,\n onLoad.bind(this),\n onTimeout.bind(this)\n );\n\n window.addEventListener('message', this._onLoad);\n\n function onLoad (e) {\n /*jshint validthis: false */\n //don't clear timeout\n if (e.origin !== getOrigin()) return;\n var result = JSON.parse(e.data);\n\n //don't clear timeout\n if (result.id !== that.getID()) return;\n\n var adUnit, error, createAd;\n if (!that._frame.contentWindow) {\n\n error = 'the iframe is not anymore in the DOM tree';\n\n } else {\n createAd = that._frame.contentWindow.getVPAIDAd;\n error = utils.validate(typeof createAd === 'function', 'the ad didn\\'t return a function to create an ad');\n }\n\n if (!error) {\n var adEl = that._frame.contentWindow.document.querySelector('.ad-element');\n adUnit = new VPAIDAdUnit(createAd(), adEl, that._videoEl, that._frame);\n adUnit.subscribe(AD_STOPPED, $adDestroyed.bind(that));\n error = utils.validate(adUnit.isValidVPAIDAd(), 'the add is not fully complaint with VPAID specification');\n }\n\n that._adUnit = adUnit;\n $destroyLoadListener.call(that);\n callback(error, error ? null : adUnit);\n\n //clear timeout\n return true;\n }\n\n function onTimeout() {\n callback('timeout', null);\n }\n};\n\n/**\n * unloadAdUnit\n *\n */\nVPAIDHTML5Client.prototype.unloadAdUnit = function unloadAdUnit() {\n $unloadPreviousAdUnit.call(this);\n};\n\n/**\n * getID will return the unique id\n *\n * @return {string}\n */\nVPAIDHTML5Client.prototype.getID = function () {\n return this._id;\n};\n\n\n/**\n * $removeEl\n *\n * @param {string} key\n */\nfunction $removeEl(key) {\n var el = this[key];\n if (el) {\n el.remove();\n delete this[key];\n }\n}\n\nfunction $adDestroyed() {\n $removeAdElements.call(this);\n delete this._adUnit;\n}\n\nfunction $unloadPreviousAdUnit() {\n $removeAdElements.call(this);\n $destroyAdUnit.call(this);\n}\n\nfunction $removeAdElements() {\n $removeEl.call(this, '_frame');\n $destroyLoadListener.call(this);\n}\n\n/**\n * $destroyLoadListener\n *\n */\nfunction $destroyLoadListener() {\n if (this._onLoad) {\n window.removeEventListener('message', this._onLoad);\n utils.clearCallbackTimeout(this._onLoad);\n delete this._onLoad;\n }\n}\n\n\nfunction $destroyAdUnit() {\n if (this._adUnit) {\n this._adUnit.stopAd();\n delete this._adUnit;\n }\n}\n\n/**\n * $throwIfDestroyed\n *\n */\nfunction $throwIfDestroyed() {\n if (this._destroyed) {\n throw new Error ('VPAIDHTML5Client already destroyed!');\n }\n}\n\nfunction getOrigin() {\n if( window.location.origin ) {\n return window.location.origin;\n }\n else {\n return window.location.protocol + \"//\" +\n window.location.hostname +\n (window.location.port ? ':' + window.location.port: '');\n }\n}\n\nmodule.exports = VPAIDHTML5Client;\nwindow.VPAIDHTML5Client = VPAIDHTML5Client;\n\n\n},{\"./VPAIDAdUnit\":10,\"./utils\":13}],12:[function(require,module,exports){\n'use strict';\n\nfunction Subscriber() {\n this._subscribers = {};\n}\n\nSubscriber.prototype.subscribe = function subscribe(handler, eventName, context) {\n if (!this.isHandlerAttached(handler, eventName)) {\n this.get(eventName).push({handler: handler, context: context, eventName: eventName});\n }\n};\n\nSubscriber.prototype.unsubscribe = function unsubscribe(handler, eventName) {\n this._subscribers[eventName] = this.get(eventName).filter(function (subscriber) {\n return handler !== subscriber.handler;\n });\n};\n\nSubscriber.prototype.unsubscribeAll = function unsubscribeAll() {\n this._subscribers = {};\n};\n\nSubscriber.prototype.trigger = function(eventName, data) {\n var that = this;\n var subscribers = this.get(eventName)\n .concat(this.get('*'));\n\n subscribers.forEach(function (subscriber) {\n setTimeout(function () {\n if (that.isHandlerAttached(subscriber.handler, subscriber.eventName)) {\n subscriber.handler.call(subscriber.context, data);\n }\n }, 0);\n });\n};\n\nSubscriber.prototype.triggerSync = function(eventName, data) {\n var subscribers = this.get(eventName)\n .concat(this.get('*'));\n\n subscribers.forEach(function (subscriber) {\n subscriber.handler.call(subscriber.context, data);\n });\n};\n\nSubscriber.prototype.get = function get(eventName) {\n if (!this._subscribers[eventName]) {\n this._subscribers[eventName] = [];\n }\n return this._subscribers[eventName];\n};\n\nSubscriber.prototype.isHandlerAttached = function isHandlerAttached(handler, eventName) {\n return this.get(eventName).some(function(subscriber) {\n return handler === subscriber.handler;\n })\n};\n\nmodule.exports = Subscriber;\n\n\n},{}],13:[function(require,module,exports){\n'use strict';\n\n/**\n * noop a empty function\n */\nfunction noop() {}\n\n/**\n * validate if is not validate will return an Error with the message\n *\n * @param {boolean} isValid\n * @param {string} message\n */\nfunction validate(isValid, message) {\n return isValid ? null : new Error(message);\n}\n\nvar timeouts = {};\n/**\n * clearCallbackTimeout\n *\n * @param {function} func handler to remove\n */\nfunction clearCallbackTimeout(func) {\n var timeout = timeouts[func];\n if (timeout) {\n clearTimeout(timeout);\n delete timeouts[func];\n }\n}\n\n/**\n * callbackTimeout if the onSuccess is not called and returns true in the timelimit then onTimeout will be called\n *\n * @param {number} timer\n * @param {function} onSuccess\n * @param {function} onTimeout\n */\nfunction callbackTimeout(timer, onSuccess, onTimeout) {\n var callback, timeout;\n\n timeout = setTimeout(function () {\n onSuccess = noop;\n delete timeout[callback];\n onTimeout();\n }, timer);\n\n callback = function () {\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n if (onSuccess.apply(this, arguments)) {\n clearCallbackTimeout(callback);\n }\n };\n\n timeouts[callback] = timeout;\n\n return callback;\n}\n\n\n/**\n * createElementInEl\n *\n * @param {HTMLElement} parent\n * @param {string} tagName\n * @param {string} id\n */\nfunction createElementInEl(parent, tagName, id) {\n var nEl = document.createElement(tagName);\n if (id) nEl.id = id;\n parent.appendChild(nEl);\n return nEl;\n}\n\n/**\n * createIframeWithContent\n *\n * @param {HTMLElement} parent\n * @param {string} template simple template using {{var}}\n * @param {object} data\n */\nfunction createIframeWithContent(parent, template, data) {\n var iframe = createIframe(parent, null, data.zIndex);\n if (!setIframeContent(iframe, simpleTemplate(template, data))) return;\n return iframe;\n}\n\n/**\n * createIframe\n *\n * @param {HTMLElement} parent\n * @param {string} url\n */\nfunction createIframe(parent, url, zIndex) {\n var nEl = document.createElement('iframe');\n nEl.src = url || 'about:blank';\n nEl.marginWidth = '0';\n nEl.marginHeight = '0';\n nEl.frameBorder = '0';\n nEl.width = '100%';\n nEl.height = '100%';\n nEl.style.position = 'absolute';\n nEl.style.left = '0';\n nEl.style.top = '0';\n nEl.style.margin = '0px';\n nEl.style.padding = '0px';\n nEl.style.border = 'none';\n\n if(zIndex){\n nEl.style.zIndex = zIndex;\n }\n\n nEl.setAttribute('SCROLLING','NO');\n parent.innerHTML = '';\n parent.appendChild(nEl);\n return nEl;\n}\n\n/**\n * simpleTemplate\n *\n * @param {string} template\n * @param {object} data\n */\nfunction simpleTemplate(template, data) {\n Object.keys(data).forEach(function (key) {\n var value = (typeof value === 'object') ? JSON.stringify(data[key]) : data[key];\n template = template.replace(new RegExp('{{' + key + '}}', 'g'), value);\n });\n return template;\n}\n\n/**\n * setIframeContent\n *\n * @param {HTMLIframeElement} iframeEl\n * @param content\n */\nfunction setIframeContent(iframeEl, content) {\n var iframeDoc = iframeEl.contentWindow && iframeEl.contentWindow.document;\n if (!iframeDoc) return false;\n\n iframeDoc.write(content);\n\n return true;\n}\n\n\n/**\n * extend object with keys from another object\n *\n * @param {object} toExtend\n * @param {object} fromSource\n */\nfunction extend(toExtend, fromSource) {\n Object.keys(fromSource).forEach(function(key) {\n toExtend[key] = fromSource[key];\n });\n return toExtend;\n}\n\n\n/**\n * unique will create a unique string everytime is called, sequentially and prefixed\n *\n * @param {string} prefix\n */\nfunction unique(prefix) {\n var count = -1;\n return function () {\n return prefix + '_' + (++count);\n };\n}\n\nmodule.exports = {\n noop: noop,\n validate: validate,\n clearCallbackTimeout: clearCallbackTimeout,\n callbackTimeout: callbackTimeout,\n createElementInEl: createElementInEl,\n createIframeWithContent: createIframeWithContent,\n createIframe: createIframe,\n simpleTemplate: simpleTemplate,\n setIframeContent: setIframeContent,\n extend: extend,\n unique: unique\n};\n\n\n},{}],14:[function(require,module,exports){\n/*! SWFObject v2.3.20130521 \r\n is released under the MIT License \r\n*/\r\n\r\n/* global ActiveXObject: false */\r\n\r\n(function (root, factory) {\r\n if (typeof define === 'function' && define.amd) {\r\n // AMD\r\n define(factory);\r\n } else if (typeof module === 'object' && module.exports) {\r\n // Node, CommonJS-like\r\n module.exports = factory();\r\n } else {\r\n // Browser globals (root is window)\r\n root.swfobject = factory();\r\n }\r\n}(this, function () {\r\n\r\n var UNDEF = \"undefined\",\r\n OBJECT = \"object\",\r\n SHOCKWAVE_FLASH = \"Shockwave Flash\",\r\n SHOCKWAVE_FLASH_AX = \"ShockwaveFlash.ShockwaveFlash\",\r\n FLASH_MIME_TYPE = \"application/x-shockwave-flash\",\r\n EXPRESS_INSTALL_ID = \"SWFObjectExprInst\",\r\n ON_READY_STATE_CHANGE = \"onreadystatechange\",\r\n\r\n win = window,\r\n doc = document,\r\n nav = navigator,\r\n\r\n plugin = false,\r\n domLoadFnArr = [],\r\n regObjArr = [],\r\n objIdArr = [],\r\n listenersArr = [],\r\n storedFbContent,\r\n storedFbContentId,\r\n storedCallbackFn,\r\n storedCallbackObj,\r\n isDomLoaded = false,\r\n isExpressInstallActive = false,\r\n dynamicStylesheet,\r\n dynamicStylesheetMedia,\r\n autoHideShow = true,\r\n encodeURIEnabled = false,\r\n\r\n /* Centralized function for browser feature detection\r\n - User agent string detection is only used when no good alternative is possible\r\n - Is executed directly for optimal performance\r\n */\r\n ua = function () {\r\n var w3cdom = typeof doc.getElementById !== UNDEF && typeof doc.getElementsByTagName !== UNDEF && typeof doc.createElement !== UNDEF,\r\n u = nav.userAgent.toLowerCase(),\r\n p = nav.platform.toLowerCase(),\r\n windows = p ? /win/.test(p) : /win/.test(u),\r\n mac = p ? /mac/.test(p) : /mac/.test(u),\r\n webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\\/(\\d+(\\.\\d+)?).*$/, \"$1\")) : false, // returns either the webkit version or false if not webkit\r\n ie = nav.appName === \"Microsoft Internet Explorer\",\r\n playerVersion = [0, 0, 0],\r\n d = null;\r\n if (typeof nav.plugins !== UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] === OBJECT) {\r\n d = nav.plugins[SHOCKWAVE_FLASH].description;\r\n // nav.mimeTypes[\"application/x-shockwave-flash\"].enabledPlugin indicates whether plug-ins are enabled or disabled in Safari 3+\r\n if (d && (typeof nav.mimeTypes !== UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) {\r\n plugin = true;\r\n ie = false; // cascaded feature detection for Internet Explorer\r\n d = d.replace(/^.*\\s+(\\S+\\s+\\S+$)/, \"$1\");\r\n playerVersion[0] = toInt(d.replace(/^(.*)\\..*$/, \"$1\"));\r\n playerVersion[1] = toInt(d.replace(/^.*\\.(.*)\\s.*$/, \"$1\"));\r\n playerVersion[2] = /[a-zA-Z]/.test(d) ? toInt(d.replace(/^.*[a-zA-Z]+(.*)$/, \"$1\")) : 0;\r\n }\r\n }\r\n else if (typeof win.ActiveXObject !== UNDEF) {\r\n try {\r\n var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);\r\n if (a) { // a will return null when ActiveX is disabled\r\n d = a.GetVariable(\"$version\");\r\n if (d) {\r\n ie = true; // cascaded feature detection for Internet Explorer\r\n d = d.split(\" \")[1].split(\",\");\r\n playerVersion = [toInt(d[0]), toInt(d[1]), toInt(d[2])];\r\n }\r\n }\r\n }\r\n catch (e) {}\r\n }\r\n return {w3: w3cdom, pv: playerVersion, wk: webkit, ie: ie, win: windows, mac: mac};\r\n }(),\r\n\r\n /* Cross-browser onDomLoad\r\n - Will fire an event as soon as the DOM of a web page is loaded\r\n - Internet Explorer workaround based on Diego Perini's solution: http://javascript.nwbox.com/IEContentLoaded/\r\n - Regular onload serves as fallback\r\n */\r\n onDomLoad = function () {\r\n if (!ua.w3) { return; }\r\n if ((typeof doc.readyState !== UNDEF && (doc.readyState === \"complete\" || doc.readyState === \"interactive\")) || (typeof doc.readyState === UNDEF && (doc.getElementsByTagName(\"body\")[0] || doc.body))) { // function is fired after onload, e.g. when script is inserted dynamically\r\n callDomLoadFunctions();\r\n }\r\n if (!isDomLoaded) {\r\n if (typeof doc.addEventListener !== UNDEF) {\r\n doc.addEventListener(\"DOMContentLoaded\", callDomLoadFunctions, false);\r\n }\r\n if (ua.ie) {\r\n doc.attachEvent(ON_READY_STATE_CHANGE, function detach() {\r\n if (doc.readyState === \"complete\") {\r\n doc.detachEvent(ON_READY_STATE_CHANGE, detach);\r\n callDomLoadFunctions();\r\n }\r\n });\r\n if (win == top) { // if not inside an iframe\r\n (function checkDomLoadedIE() {\r\n if (isDomLoaded) { return; }\r\n try {\r\n doc.documentElement.doScroll(\"left\");\r\n }\r\n catch (e) {\r\n setTimeout(checkDomLoadedIE, 0);\r\n return;\r\n }\r\n callDomLoadFunctions();\r\n }());\r\n }\r\n }\r\n if (ua.wk) {\r\n (function checkDomLoadedWK() {\r\n if (isDomLoaded) { return; }\r\n if (!/loaded|complete/.test(doc.readyState)) {\r\n setTimeout(checkDomLoadedWK, 0);\r\n return;\r\n }\r\n callDomLoadFunctions();\r\n }());\r\n }\r\n }\r\n }();\r\n\r\n function callDomLoadFunctions() {\r\n if (isDomLoaded || !document.getElementsByTagName(\"body\")[0]) { return; }\r\n try { // test if we can really add/remove elements to/from the DOM; we don't want to fire it too early\r\n var t, span = createElement(\"span\");\r\n span.style.display = \"none\"; //hide the span in case someone has styled spans via CSS\r\n t = doc.getElementsByTagName(\"body\")[0].appendChild(span);\r\n t.parentNode.removeChild(t);\r\n t = null; //clear the variables\r\n span = null;\r\n }\r\n catch (e) { return; }\r\n isDomLoaded = true;\r\n var dl = domLoadFnArr.length;\r\n for (var i = 0; i < dl; i++) {\r\n domLoadFnArr[i]();\r\n }\r\n }\r\n\r\n function addDomLoadEvent(fn) {\r\n if (isDomLoaded) {\r\n fn();\r\n }\r\n else {\r\n domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+\r\n }\r\n }\r\n\r\n /* Cross-browser onload\r\n - Based on James Edwards' solution: http://brothercake.com/site/resources/scripts/onload/\r\n - Will fire an event as soon as a web page including all of its assets are loaded\r\n */\r\n function addLoadEvent(fn) {\r\n if (typeof win.addEventListener !== UNDEF) {\r\n win.addEventListener(\"load\", fn, false);\r\n }\r\n else if (typeof doc.addEventListener !== UNDEF) {\r\n doc.addEventListener(\"load\", fn, false);\r\n }\r\n else if (typeof win.attachEvent !== UNDEF) {\r\n addListener(win, \"onload\", fn);\r\n }\r\n else if (typeof win.onload === \"function\") {\r\n var fnOld = win.onload;\r\n win.onload = function () {\r\n fnOld();\r\n fn();\r\n };\r\n }\r\n else {\r\n win.onload = fn;\r\n }\r\n }\r\n\r\n /* Detect the Flash Player version for non-Internet Explorer browsers\r\n - Detecting the plug-in version via the object element is more precise than using the plugins collection item's description:\r\n a. Both release and build numbers can be detected\r\n b. Avoid wrong descriptions by corrupt installers provided by Adobe\r\n c. Avoid wrong descriptions by multiple Flash Player entries in the plugin Array, caused by incorrect browser imports\r\n - Disadvantage of this method is that it depends on the availability of the DOM, while the plugins collection is immediately available\r\n */\r\n function testPlayerVersion() {\r\n var b = doc.getElementsByTagName(\"body\")[0];\r\n var o = createElement(OBJECT);\r\n o.setAttribute(\"style\", \"visibility: hidden;\");\r\n o.setAttribute(\"type\", FLASH_MIME_TYPE);\r\n var t = b.appendChild(o);\r\n if (t) {\r\n var counter = 0;\r\n (function checkGetVariable() {\r\n if (typeof t.GetVariable !== UNDEF) {\r\n try {\r\n var d = t.GetVariable(\"$version\");\r\n if (d) {\r\n d = d.split(\" \")[1].split(\",\");\r\n ua.pv = [toInt(d[0]), toInt(d[1]), toInt(d[2])];\r\n }\r\n } catch (e) {\r\n //t.GetVariable(\"$version\") is known to fail in Flash Player 8 on Firefox\r\n //If this error is encountered, assume FP8 or lower. Time to upgrade.\r\n ua.pv = [8, 0, 0];\r\n }\r\n }\r\n else if (counter < 10) {\r\n counter++;\r\n setTimeout(checkGetVariable, 10);\r\n return;\r\n }\r\n b.removeChild(o);\r\n t = null;\r\n matchVersions();\r\n }());\r\n }\r\n else {\r\n matchVersions();\r\n }\r\n }\r\n\r\n /* Perform Flash Player and SWF version matching; static publishing only\r\n */\r\n function matchVersions() {\r\n var rl = regObjArr.length;\r\n if (rl > 0) {\r\n for (var i = 0; i < rl; i++) { // for each registered object element\r\n var id = regObjArr[i].id;\r\n var cb = regObjArr[i].callbackFn;\r\n var cbObj = {success: false, id: id};\r\n if (ua.pv[0] > 0) {\r\n var obj = getElementById(id);\r\n if (obj) {\r\n if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { // Flash Player version >= published SWF version: Houston, we have a match!\r\n setVisibility(id, true);\r\n if (cb) {\r\n cbObj.success = true;\r\n cbObj.ref = getObjectById(id);\r\n cbObj.id = id;\r\n cb(cbObj);\r\n }\r\n }\r\n else if (regObjArr[i].expressInstall && canExpressInstall()) { // show the Adobe Express Install dialog if set by the web page author and if supported\r\n var att = {};\r\n att.data = regObjArr[i].expressInstall;\r\n att.width = obj.getAttribute(\"width\") || \"0\";\r\n att.height = obj.getAttribute(\"height\") || \"0\";\r\n if (obj.getAttribute(\"class\")) { att.styleclass = obj.getAttribute(\"class\"); }\r\n if (obj.getAttribute(\"align\")) { att.align = obj.getAttribute(\"align\"); }\r\n // parse HTML object param element's name-value pairs\r\n var par = {};\r\n var p = obj.getElementsByTagName(\"param\");\r\n var pl = p.length;\r\n for (var j = 0; j < pl; j++) {\r\n if (p[j].getAttribute(\"name\").toLowerCase() !== \"movie\") {\r\n par[p[j].getAttribute(\"name\")] = p[j].getAttribute(\"value\");\r\n }\r\n }\r\n showExpressInstall(att, par, id, cb);\r\n }\r\n else { // Flash Player and SWF version mismatch or an older Webkit engine that ignores the HTML object element's nested param elements: display fallback content instead of SWF\r\n displayFbContent(obj);\r\n if (cb) { cb(cbObj); }\r\n }\r\n }\r\n }\r\n else { // if no Flash Player is installed or the fp version cannot be detected we let the HTML object element do its job (either show a SWF or fallback content)\r\n setVisibility(id, true);\r\n if (cb) {\r\n var o = getObjectById(id); // test whether there is an HTML object element or not\r\n if (o && typeof o.SetVariable !== UNDEF) {\r\n cbObj.success = true;\r\n cbObj.ref = o;\r\n cbObj.id = o.id;\r\n }\r\n cb(cbObj);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /* Main function\r\n - Will preferably execute onDomLoad, otherwise onload (as a fallback)\r\n */\r\n domLoadFnArr[0] = function () {\r\n if (plugin) {\r\n testPlayerVersion();\r\n }\r\n else {\r\n matchVersions();\r\n }\r\n };\r\n\r\n function getObjectById(objectIdStr) {\r\n var r = null,\r\n o = getElementById(objectIdStr);\r\n\r\n if (o && o.nodeName.toUpperCase() === \"OBJECT\") {\r\n //If targeted object is valid Flash file\r\n if (typeof o.SetVariable !== UNDEF) {\r\n r = o;\r\n } else {\r\n //If SetVariable is not working on targeted object but a nested object is\r\n //available, assume classic nested object markup. Return nested object.\r\n\r\n //If SetVariable is not working on targeted object and there is no nested object,\r\n //return the original object anyway. This is probably new simplified markup.\r\n\r\n r = o.getElementsByTagName(OBJECT)[0] || o;\r\n }\r\n }\r\n\r\n return r;\r\n }\r\n\r\n /* Requirements for Adobe Express Install\r\n - only one instance can be active at a time\r\n - fp 6.0.65 or higher\r\n - Win/Mac OS only\r\n - no Webkit engines older than version 312\r\n */\r\n function canExpressInstall() {\r\n return !isExpressInstallActive && hasPlayerVersion(\"6.0.65\") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);\r\n }\r\n\r\n /* Show the Adobe Express Install dialog\r\n - Reference: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75\r\n */\r\n function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {\r\n\r\n var obj = getElementById(replaceElemIdStr);\r\n\r\n //Ensure that replaceElemIdStr is really a string and not an element\r\n replaceElemIdStr = getId(replaceElemIdStr);\r\n\r\n isExpressInstallActive = true;\r\n storedCallbackFn = callbackFn || null;\r\n storedCallbackObj = {success: false, id: replaceElemIdStr};\r\n\r\n if (obj) {\r\n if (obj.nodeName.toUpperCase() === \"OBJECT\") { // static publishing\r\n storedFbContent = abstractFbContent(obj);\r\n storedFbContentId = null;\r\n }\r\n else { // dynamic publishing\r\n storedFbContent = obj;\r\n storedFbContentId = replaceElemIdStr;\r\n }\r\n att.id = EXPRESS_INSTALL_ID;\r\n if (typeof att.width === UNDEF || (!/%$/.test(att.width) && toInt(att.width) < 310)) { att.width = \"310\"; }\r\n if (typeof att.height === UNDEF || (!/%$/.test(att.height) && toInt(att.height) < 137)) { att.height = \"137\"; }\r\n var pt = ua.ie ? \"ActiveX\" : \"PlugIn\",\r\n fv = \"MMredirectURL=\" + encodeURIComponent(win.location.toString().replace(/&/g, \"%26\")) + \"&MMplayerType=\" + pt + \"&MMdoctitle=\" + encodeURIComponent(doc.title.slice(0, 47) + \" - Flash Player Installation\");\r\n if (typeof par.flashvars !== UNDEF) {\r\n par.flashvars += \"&\" + fv;\r\n }\r\n else {\r\n par.flashvars = fv;\r\n }\r\n // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it,\r\n // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work\r\n if (ua.ie && obj.readyState != 4) {\r\n var newObj = createElement(\"div\");\r\n replaceElemIdStr += \"SWFObjectNew\";\r\n newObj.setAttribute(\"id\", replaceElemIdStr);\r\n obj.parentNode.insertBefore(newObj, obj); // insert placeholder div that will be replaced by the object element that loads expressinstall.swf\r\n obj.style.display = \"none\";\r\n removeSWF(obj); //removeSWF accepts elements now\r\n }\r\n createSWF(att, par, replaceElemIdStr);\r\n }\r\n }\r\n\r\n /* Functions to abstract and display fallback content\r\n */\r\n function displayFbContent(obj) {\r\n if (ua.ie && obj.readyState != 4) {\r\n // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it,\r\n // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work\r\n obj.style.display = \"none\";\r\n var el = createElement(\"div\");\r\n obj.parentNode.insertBefore(el, obj); // insert placeholder div that will be replaced by the fallback content\r\n el.parentNode.replaceChild(abstractFbContent(obj), el);\r\n removeSWF(obj); //removeSWF accepts elements now\r\n }\r\n else {\r\n obj.parentNode.replaceChild(abstractFbContent(obj), obj);\r\n }\r\n }\r\n\r\n function abstractFbContent(obj) {\r\n var ac = createElement(\"div\");\r\n if (ua.win && ua.ie) {\r\n ac.innerHTML = obj.innerHTML;\r\n }\r\n else {\r\n var nestedObj = obj.getElementsByTagName(OBJECT)[0];\r\n if (nestedObj) {\r\n var c = nestedObj.childNodes;\r\n if (c) {\r\n var cl = c.length;\r\n for (var i = 0; i < cl; i++) {\r\n if (!(c[i].nodeType == 1 && c[i].nodeName === \"PARAM\") && !(c[i].nodeType == 8)) {\r\n ac.appendChild(c[i].cloneNode(true));\r\n }\r\n }\r\n }\r\n }\r\n }\r\n return ac;\r\n }\r\n\r\n function createIeObject(url, paramStr) {\r\n var div = createElement(\"div\");\r\n div.innerHTML = \"\" + paramStr + \"\";\r\n return div.firstChild;\r\n }\r\n\r\n /* Cross-browser dynamic SWF creation\r\n */\r\n function createSWF(attObj, parObj, id) {\r\n var r, el = getElementById(id);\r\n id = getId(id); // ensure id is truly an ID and not an element\r\n\r\n if (ua.wk && ua.wk < 312) { return r; }\r\n\r\n if (el) {\r\n var o = (ua.ie) ? createElement(\"div\") : createElement(OBJECT),\r\n attr,\r\n attrLower,\r\n param;\r\n\r\n if (typeof attObj.id === UNDEF) { // if no 'id' is defined for the object element, it will inherit the 'id' from the fallback content\r\n attObj.id = id;\r\n }\r\n\r\n //Add params\r\n for (param in parObj) {\r\n //filter out prototype additions from other potential libraries and IE specific param element\r\n if (parObj.hasOwnProperty(param) && param.toLowerCase() !== \"movie\") {\r\n createObjParam(o, param, parObj[param]);\r\n }\r\n }\r\n\r\n //Create IE object, complete with param nodes\r\n if (ua.ie) { o = createIeObject(attObj.data, o.innerHTML); }\r\n\r\n //Add attributes to object\r\n for (attr in attObj) {\r\n if (attObj.hasOwnProperty(attr)) { // filter out prototype additions from other potential libraries\r\n attrLower = attr.toLowerCase();\r\n\r\n // 'class' is an ECMA4 reserved keyword\r\n if (attrLower === \"styleclass\") {\r\n o.setAttribute(\"class\", attObj[attr]);\r\n } else if (attrLower !== \"classid\" && attrLower !== \"data\") {\r\n o.setAttribute(attr, attObj[attr]);\r\n }\r\n }\r\n }\r\n\r\n if (ua.ie) {\r\n objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on unload (dynamic publishing only)\r\n } else {\r\n o.setAttribute(\"type\", FLASH_MIME_TYPE);\r\n o.setAttribute(\"data\", attObj.data);\r\n }\r\n\r\n el.parentNode.replaceChild(o, el);\r\n r = o;\r\n }\r\n\r\n return r;\r\n }\r\n\r\n function createObjParam(el, pName, pValue) {\r\n var p = createElement(\"param\");\r\n p.setAttribute(\"name\", pName);\r\n p.setAttribute(\"value\", pValue);\r\n el.appendChild(p);\r\n }\r\n\r\n /* Cross-browser SWF removal\r\n - Especially needed to safely and completely remove a SWF in Internet Explorer\r\n */\r\n function removeSWF(id) {\r\n var obj = getElementById(id);\r\n if (obj && obj.nodeName.toUpperCase() === \"OBJECT\") {\r\n if (ua.ie) {\r\n obj.style.display = \"none\";\r\n (function removeSWFInIE() {\r\n if (obj.readyState == 4) {\r\n //This step prevents memory leaks in Internet Explorer\r\n for (var i in obj) {\r\n if (typeof obj[i] === \"function\") {\r\n obj[i] = null;\r\n }\r\n }\r\n obj.parentNode.removeChild(obj);\r\n } else {\r\n setTimeout(removeSWFInIE, 10);\r\n }\r\n }());\r\n }\r\n else {\r\n obj.parentNode.removeChild(obj);\r\n }\r\n }\r\n }\r\n\r\n function isElement(id) {\r\n return (id && id.nodeType && id.nodeType === 1);\r\n }\r\n\r\n function getId(thing) {\r\n return (isElement(thing)) ? thing.id : thing;\r\n }\r\n\r\n /* Functions to optimize JavaScript compression\r\n */\r\n function getElementById(id) {\r\n\r\n //Allow users to pass an element OR an element's ID\r\n if (isElement(id)) { return id; }\r\n\r\n var el = null;\r\n try {\r\n el = doc.getElementById(id);\r\n }\r\n catch (e) {}\r\n return el;\r\n }\r\n\r\n function createElement(el) {\r\n return doc.createElement(el);\r\n }\r\n\r\n //To aid compression; replaces 14 instances of pareseInt with radix\r\n function toInt(str) {\r\n return parseInt(str, 10);\r\n }\r\n\r\n /* Updated attachEvent function for Internet Explorer\r\n - Stores attachEvent information in an Array, so on unload the detachEvent functions can be called to avoid memory leaks\r\n */\r\n function addListener(target, eventType, fn) {\r\n target.attachEvent(eventType, fn);\r\n listenersArr[listenersArr.length] = [target, eventType, fn];\r\n }\r\n\r\n /* Flash Player and SWF content version matching\r\n */\r\n function hasPlayerVersion(rv) {\r\n rv += \"\"; //Coerce number to string, if needed.\r\n var pv = ua.pv, v = rv.split(\".\");\r\n v[0] = toInt(v[0]);\r\n v[1] = toInt(v[1]) || 0; // supports short notation, e.g. \"9\" instead of \"9.0.0\"\r\n v[2] = toInt(v[2]) || 0;\r\n return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;\r\n }\r\n\r\n /* Cross-browser dynamic CSS creation\r\n - Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php\r\n */\r\n function createCSS(sel, decl, media, newStyle) {\r\n var h = doc.getElementsByTagName(\"head\")[0];\r\n if (!h) { return; } // to also support badly authored HTML pages that lack a head element\r\n var m = (typeof media === \"string\") ? media : \"screen\";\r\n if (newStyle) {\r\n dynamicStylesheet = null;\r\n dynamicStylesheetMedia = null;\r\n }\r\n if (!dynamicStylesheet || dynamicStylesheetMedia != m) {\r\n // create dynamic stylesheet + get a global reference to it\r\n var s = createElement(\"style\");\r\n s.setAttribute(\"type\", \"text/css\");\r\n s.setAttribute(\"media\", m);\r\n dynamicStylesheet = h.appendChild(s);\r\n if (ua.ie && typeof doc.styleSheets !== UNDEF && doc.styleSheets.length > 0) {\r\n dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];\r\n }\r\n dynamicStylesheetMedia = m;\r\n }\r\n // add style rule\r\n if (dynamicStylesheet) {\r\n if (typeof dynamicStylesheet.addRule !== UNDEF) {\r\n dynamicStylesheet.addRule(sel, decl);\r\n } else if (typeof doc.createTextNode !== UNDEF) {\r\n dynamicStylesheet.appendChild(doc.createTextNode(sel + \" {\" + decl + \"}\"));\r\n }\r\n }\r\n }\r\n\r\n function setVisibility(id, isVisible) {\r\n if (!autoHideShow) { return; }\r\n var v = isVisible ? \"visible\" : \"hidden\",\r\n el = getElementById(id);\r\n if (isDomLoaded && el) {\r\n el.style.visibility = v;\r\n } else if (typeof id === \"string\") {\r\n createCSS(\"#\" + id, \"visibility:\" + v);\r\n }\r\n }\r\n\r\n /* Filter to avoid XSS attacks\r\n */\r\n function urlEncodeIfNecessary(s) {\r\n var regex = /[\\\\\\\"<>\\.;]/;\r\n var hasBadChars = regex.exec(s) !== null;\r\n return hasBadChars && typeof encodeURIComponent !== UNDEF ? encodeURIComponent(s) : s;\r\n }\r\n\r\n /* Release memory to avoid memory leaks caused by closures, fix hanging audio/video threads and force open sockets/NetConnections to disconnect (Internet Explorer only)\r\n */\r\n var cleanup = function () {\r\n if (ua.ie) {\r\n window.attachEvent(\"onunload\", function () {\r\n // remove listeners to avoid memory leaks\r\n var ll = listenersArr.length;\r\n for (var i = 0; i < ll; i++) {\r\n listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);\r\n }\r\n // cleanup dynamically embedded objects to fix audio/video threads and force open sockets and NetConnections to disconnect\r\n var il = objIdArr.length;\r\n for (var j = 0; j < il; j++) {\r\n removeSWF(objIdArr[j]);\r\n }\r\n // cleanup library's main closures to avoid memory leaks\r\n for (var k in ua) {\r\n ua[k] = null;\r\n }\r\n ua = null;\r\n for (var l in swfobject) {\r\n swfobject[l] = null;\r\n }\r\n swfobject = null;\r\n });\r\n }\r\n }();\r\n\r\n return {\r\n /* Public API\r\n - Reference: http://code.google.com/p/swfobject/wiki/documentation\r\n */\r\n registerObject: function (objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {\r\n if (ua.w3 && objectIdStr && swfVersionStr) {\r\n var regObj = {};\r\n regObj.id = objectIdStr;\r\n regObj.swfVersion = swfVersionStr;\r\n regObj.expressInstall = xiSwfUrlStr;\r\n regObj.callbackFn = callbackFn;\r\n regObjArr[regObjArr.length] = regObj;\r\n setVisibility(objectIdStr, false);\r\n }\r\n else if (callbackFn) {\r\n callbackFn({success: false, id: objectIdStr});\r\n }\r\n },\r\n\r\n getObjectById: function (objectIdStr) {\r\n if (ua.w3) {\r\n return getObjectById(objectIdStr);\r\n }\r\n },\r\n\r\n embedSWF: function (swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {\r\n\r\n var id = getId(replaceElemIdStr),\r\n callbackObj = {success: false, id: id};\r\n\r\n if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {\r\n setVisibility(id, false);\r\n addDomLoadEvent(function () {\r\n widthStr += \"\"; // auto-convert to string\r\n heightStr += \"\";\r\n var att = {};\r\n if (attObj && typeof attObj === OBJECT) {\r\n for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs\r\n att[i] = attObj[i];\r\n }\r\n }\r\n att.data = swfUrlStr;\r\n att.width = widthStr;\r\n att.height = heightStr;\r\n var par = {};\r\n if (parObj && typeof parObj === OBJECT) {\r\n for (var j in parObj) { // copy object to avoid the use of references, because web authors often reuse parObj for multiple SWFs\r\n par[j] = parObj[j];\r\n }\r\n }\r\n if (flashvarsObj && typeof flashvarsObj === OBJECT) {\r\n for (var k in flashvarsObj) { // copy object to avoid the use of references, because web authors often reuse flashvarsObj for multiple SWFs\r\n if (flashvarsObj.hasOwnProperty(k)) {\r\n\r\n var key = (encodeURIEnabled) ? encodeURIComponent(k) : k,\r\n value = (encodeURIEnabled) ? encodeURIComponent(flashvarsObj[k]) : flashvarsObj[k];\r\n\r\n if (typeof par.flashvars !== UNDEF) {\r\n par.flashvars += \"&\" + key + \"=\" + value;\r\n }\r\n else {\r\n par.flashvars = key + \"=\" + value;\r\n }\r\n\r\n }\r\n }\r\n }\r\n if (hasPlayerVersion(swfVersionStr)) { // create SWF\r\n var obj = createSWF(att, par, replaceElemIdStr);\r\n if (att.id == id) {\r\n setVisibility(id, true);\r\n }\r\n callbackObj.success = true;\r\n callbackObj.ref = obj;\r\n callbackObj.id = obj.id;\r\n }\r\n else if (xiSwfUrlStr && canExpressInstall()) { // show Adobe Express Install\r\n att.data = xiSwfUrlStr;\r\n showExpressInstall(att, par, replaceElemIdStr, callbackFn);\r\n return;\r\n }\r\n else { // show fallback content\r\n setVisibility(id, true);\r\n }\r\n if (callbackFn) { callbackFn(callbackObj); }\r\n });\r\n }\r\n else if (callbackFn) { callbackFn(callbackObj); }\r\n },\r\n\r\n switchOffAutoHideShow: function () {\r\n autoHideShow = false;\r\n },\r\n\r\n enableUriEncoding: function (bool) {\r\n encodeURIEnabled = (typeof bool === UNDEF) ? true : bool;\r\n },\r\n\r\n ua: ua,\r\n\r\n getFlashPlayerVersion: function () {\r\n return {major: ua.pv[0], minor: ua.pv[1], release: ua.pv[2]};\r\n },\r\n\r\n hasFlashPlayerVersion: hasPlayerVersion,\r\n\r\n createSWF: function (attObj, parObj, replaceElemIdStr) {\r\n if (ua.w3) {\r\n return createSWF(attObj, parObj, replaceElemIdStr);\r\n }\r\n else {\r\n return undefined;\r\n }\r\n },\r\n\r\n showExpressInstall: function (att, par, replaceElemIdStr, callbackFn) {\r\n if (ua.w3 && canExpressInstall()) {\r\n showExpressInstall(att, par, replaceElemIdStr, callbackFn);\r\n }\r\n },\r\n\r\n removeSWF: function (objElemIdStr) {\r\n if (ua.w3) {\r\n removeSWF(objElemIdStr);\r\n }\r\n },\r\n\r\n createCSS: function (selStr, declStr, mediaStr, newStyleBoolean) {\r\n if (ua.w3) {\r\n createCSS(selStr, declStr, mediaStr, newStyleBoolean);\r\n }\r\n },\r\n\r\n addDomLoadEvent: addDomLoadEvent,\r\n\r\n addLoadEvent: addLoadEvent,\r\n\r\n getQueryParamValue: function (param) {\r\n var q = doc.location.search || doc.location.hash;\r\n if (q) {\r\n if (/\\?/.test(q)) { q = q.split(\"?\")[1]; } // strip question mark\r\n if (!param) {\r\n return urlEncodeIfNecessary(q);\r\n }\r\n var pairs = q.split(\"&\");\r\n for (var i = 0; i < pairs.length; i++) {\r\n if (pairs[i].substring(0, pairs[i].indexOf(\"=\")) == param) {\r\n return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf(\"=\") + 1)));\r\n }\r\n }\r\n }\r\n return \"\";\r\n },\r\n\r\n // For internal usage only\r\n expressInstallCallback: function () {\r\n if (isExpressInstallActive) {\r\n var obj = getElementById(EXPRESS_INSTALL_ID);\r\n if (obj && storedFbContent) {\r\n obj.parentNode.replaceChild(storedFbContent, obj);\r\n if (storedFbContentId) {\r\n setVisibility(storedFbContentId, true);\r\n if (ua.ie) { storedFbContent.style.display = \"block\"; }\r\n }\r\n if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }\r\n }\r\n isExpressInstallActive = false;\r\n }\r\n },\r\n\r\n version: \"2.3\"\r\n\r\n };\r\n}));\r\n\n},{}],15:[function(require,module,exports){\n'use strict';\n\nvar InLine = require('./InLine');\nvar Wrapper = require('./Wrapper');\n\nfunction Ad(adJTree) {\n if (!(this instanceof Ad)) {\n return new Ad(adJTree);\n }\n this.initialize(adJTree);\n}\n\nAd.prototype.initialize = function(adJTree) {\n this.id = adJTree.attr('id');\n this.sequence = adJTree.attr('sequence');\n\n if(adJTree.inLine) {\n this.inLine = new InLine(adJTree.inLine);\n }\n\n if(adJTree.wrapper){\n this.wrapper = new Wrapper(adJTree.wrapper);\n }\n};\n\nmodule.exports = Ad;\n},{\"./InLine\":18,\"./Wrapper\":28}],16:[function(require,module,exports){\n'use strict';\n\nvar TrackingEvent = require('./TrackingEvent');\n\nvar utilities = require('../../utils/utilityFunctions');\n\nvar xml = require('../../utils/xml');\n\n\nfunction Companion(companionJTree) {\n if (!(this instanceof Companion)) {\n return new Companion(companionJTree);\n }\n\n //Required Elements\n this.creativeType = xml.attr(companionJTree.staticResource, 'creativeType');\n this.staticResource = xml.keyValue(companionJTree.staticResource);\n\n // Weird bug when the JXON tree is built it doesn't handle casing properly in this situation...\n var htmlResource = null;\n if (xml.keyValue(companionJTree.HTMLResource)) {\n htmlResource = xml.keyValue(companionJTree.HTMLResource);\n } else if (xml.keyValue(companionJTree.hTMLResource)) {\n htmlResource = xml.keyValue(companionJTree.hTMLResource);\n }\n this.htmlResource = htmlResource;\n\n var iframeResource = null;\n if (xml.keyValue(companionJTree.IFrameResource)) {\n iframeResource = xml.keyValue(companionJTree.IFrameResource);\n } else if (xml.keyValue(companionJTree.iFrameresource)) {\n iframeResource = xml.keyValue(companionJTree.iFrameresource);\n }\n this.iframeResource = iframeResource;\n\n //Optional fields\n this.id = xml.attr(companionJTree, 'id');\n this.width = xml.attr(companionJTree, 'width');\n this.height = xml.attr(companionJTree, 'height');\n this.expandedWidth = xml.attr(companionJTree, 'expandedWidth');\n this.expandedHeight = xml.attr(companionJTree, 'expandedHeight');\n this.scalable = xml.attr(companionJTree, 'scalable');\n this.maintainAspectRatio = xml.attr(companionJTree, 'maintainAspectRatio');\n this.minSuggestedDuration = xml.attr(companionJTree, 'minSuggestedDuration');\n this.apiFramework = xml.attr(companionJTree, 'apiFramework');\n this.companionClickThrough = xml.keyValue(companionJTree.companionClickThrough);\n this.trackingEvents = parseTrackingEvents(companionJTree.trackingEvents && companionJTree.trackingEvents.tracking);\n\n /*** Local functions ***/\n function parseTrackingEvents(trackingEvents) {\n var trackings = [];\n if (utilities.isDefined(trackingEvents)) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingData) {\n trackings.push(new TrackingEvent(trackingData));\n });\n }\n return trackings;\n }\n}\n\nmodule.exports = Companion;\n},{\"../../utils/utilityFunctions\":45,\"../../utils/xml\":46,\"./TrackingEvent\":21}],17:[function(require,module,exports){\n'use strict';\n\nvar Linear = require('./Linear');\nvar Companion = require('./Companion');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction Creative(creativeJTree) {\n if(!(this instanceof Creative)) {\n return new Creative(creativeJTree);\n }\n\n this.id = creativeJTree.attr('id');\n this.sequence = creativeJTree.attr('sequence');\n this.adId = creativeJTree.attr('adId');\n this.apiFramework = creativeJTree.attr('apiFramework');\n\n if(creativeJTree.linear) {\n this.linear = new Linear(creativeJTree.linear);\n }\n\n if (creativeJTree.companionAds) {\n var companions = [];\n var companionAds = creativeJTree.companionAds && creativeJTree.companionAds.companion;\n if (utilities.isDefined(companionAds)) {\n companionAds = utilities.isArray(companionAds) ? companionAds : [companionAds];\n companionAds.forEach(function (companionData) {\n companions.push(new Companion(companionData));\n });\n }\n this.companionAds = companions;\n }\n}\n\n/**\n * Returns true if the browser supports at the creative.\n */\nCreative.prototype.isSupported = function(){\n if(this.linear) {\n return this.linear.isSupported();\n }\n\n return true;\n};\n\nCreative.parseCreatives = function parseCreatives(creativesJTree) {\n var creatives = [];\n var creativesData;\n if (utilities.isDefined(creativesJTree) && utilities.isDefined(creativesJTree.creative)) {\n creativesData = utilities.isArray(creativesJTree.creative) ? creativesJTree.creative : [creativesJTree.creative];\n creativesData.forEach(function (creative) {\n creatives.push(new Creative(creative));\n });\n }\n return creatives;\n};\n\nmodule.exports = Creative;\n\n},{\"../../utils/utilityFunctions\":45,\"./Companion\":16,\"./Linear\":19}],18:[function(require,module,exports){\n'use strict';\n\nvar vastUtil = require('./vastUtil');\nvar Creative = require('./Creative');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction InLine(inlineJTree) {\n if (!(this instanceof InLine)) {\n return new InLine(inlineJTree);\n }\n\n //Required Fields\n this.adTitle = xml.keyValue(inlineJTree.adTitle);\n this.adSystem = xml.keyValue(inlineJTree.adSystem);\n this.impressions = vastUtil.parseImpressions(inlineJTree.impression);\n this.creatives = Creative.parseCreatives(inlineJTree.creatives);\n\n //Optional Fields\n this.description = xml.keyValue(inlineJTree.description);\n this.advertiser = xml.keyValue(inlineJTree.advertiser);\n this.surveys = parseSurveys(inlineJTree.survey);\n this.error = xml.keyValue(inlineJTree.error);\n this.pricing = xml.keyValue(inlineJTree.pricing);\n this.extensions = inlineJTree.extensions;\n\n /*** Local Functions ***/\n function parseSurveys(inlineSurveys) {\n if (inlineSurveys) {\n return utilities.transformArray(utilities.isArray(inlineSurveys) ? inlineSurveys : [inlineSurveys], function (survey) {\n if(utilities.isNotEmptyString(survey.keyValue)){\n return {\n uri: survey.keyValue,\n type: survey.attr('type')\n };\n }\n\n return undefined;\n });\n }\n return [];\n }\n}\n\n\n/**\n * Returns true if the browser supports all the creatives.\n */\nInLine.prototype.isSupported = function(){\n var i,len;\n\n if(this.creatives.length === 0) {\n return false;\n }\n\n for(i = 0, len = this.creatives.length; i< len; i+=1){\n if(!this.creatives[i].isSupported()){\n return false;\n }\n }\n return true;\n};\n\nmodule.exports = InLine;\n\n},{\"../../utils/utilityFunctions\":45,\"../../utils/xml\":46,\"./Creative\":17,\"./vastUtil\":30}],19:[function(require,module,exports){\n'use strict';\n\nvar TrackingEvent = require('./TrackingEvent');\nvar MediaFile = require('./MediaFile');\nvar VideoClicks = require('./VideoClicks');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar parsers = require('./parsers');\n\nvar xml = require('../../utils/xml');\n\n\nfunction Linear(linearJTree) {\n if (!(this instanceof Linear)) {\n return new Linear(linearJTree);\n }\n\n //Required Elements\n this.duration = parsers.duration(xml.keyValue(linearJTree.duration));\n this.mediaFiles = parseMediaFiles(linearJTree.mediaFiles && linearJTree.mediaFiles.mediaFile);\n\n //Optional fields\n this.trackingEvents = parseTrackingEvents(linearJTree.trackingEvents && linearJTree.trackingEvents.tracking, this.duration);\n this.skipoffset = parsers.offset(xml.attr(linearJTree, 'skipoffset'), this.duration);\n\n if (linearJTree.videoClicks) {\n this.videoClicks = new VideoClicks(linearJTree.videoClicks);\n }\n\n if(linearJTree.adParameters) {\n this.adParameters = xml.keyValue(linearJTree.adParameters);\n\n if(xml.attr(linearJTree.adParameters, 'xmlEncoded')){\n this.adParameters = xml.decode(this.adParameters);\n }\n }\n\n /*** Local functions ***/\n function parseTrackingEvents(trackingEvents, duration) {\n var trackings = [];\n if (utilities.isDefined(trackingEvents)) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingData) {\n trackings.push(new TrackingEvent(trackingData, duration));\n });\n }\n return trackings;\n }\n\n function parseMediaFiles(mediaFilesJxonTree) {\n var mediaFiles = [];\n if (utilities.isDefined(mediaFilesJxonTree)) {\n mediaFilesJxonTree = utilities.isArray(mediaFilesJxonTree) ? mediaFilesJxonTree : [mediaFilesJxonTree];\n\n mediaFilesJxonTree.forEach(function (mfData) {\n mediaFiles.push(new MediaFile(mfData));\n });\n }\n return mediaFiles;\n }\n}\n\n/**\n * Must return true if at least one of the MediaFiles' type is supported\n */\nLinear.prototype.isSupported = function () {\n var i, len;\n for(i=0, len=this.mediaFiles.length; i 0) {\n getAd(waterfallAds.shift(),[], waterfallHandler);\n } else {\n callback(error, adChain);\n }\n } else {\n callback(null, adChain);\n }\n }\n });\n\n /*** Local functions ***/\n function getAdWaterfall(adTagUrl, callback) {\n var requestVastXML = that._requestVASTXml.bind(that, adTagUrl);\n async.waterfall([\n requestVastXML,\n buildVastWaterfall\n ], callback);\n }\n\n function buildVastWaterfall(xmlStr, callback) {\n var vastTree;\n try {\n vastTree = xml.toJXONTree(xmlStr);\n\n if(utilities.isArray(vastTree.ad)) {\n vastTree.ads = vastTree.ad;\n } else if(vastTree.ad){\n vastTree.ads = [vastTree.ad];\n } else {\n vastTree.ads = [];\n }\n callback(validateVASTTree(vastTree), vastTree);\n\n } catch (e) {\n callback(new VASTError(\"on VASTClient.getVASTAd.buildVastWaterfall, error parsing xml\", 100), null);\n }\n }\n\n function validateVASTTree(vastTree) {\n var vastVersion = xml.attr(vastTree, 'version');\n\n if (!vastTree.ad) {\n return new VASTError('on VASTClient.getVASTAd.validateVASTTree, no Ad in VAST tree', 303);\n }\n\n if (vastVersion && (vastVersion != 3 && vastVersion != 2)) {\n return new VASTError('on VASTClient.getVASTAd.validateVASTTree, not supported VAST version \"' + vastVersion + '\"', 102);\n }\n\n return null;\n }\n\n function getAd(adTagUrl, adChain, callback) {\n if (adChain.length >= that.WRAPPER_LIMIT) {\n return callback(new VASTError(\"on VASTClient.getVASTAd.getAd, players wrapper limit reached (the limit is \" + that.WRAPPER_LIMIT + \")\", 302), adChain);\n }\n\n async.waterfall([\n function (next) {\n if (utilities.isString(adTagUrl)) {\n requestVASTAd(adTagUrl, next);\n } else {\n next(null, adTagUrl);\n }\n },\n buildAd\n ], function (error, ad) {\n if (ad) {\n adChain.push(ad);\n }\n\n if (error) {\n return callback(error, adChain);\n }\n\n if (ad.wrapper) {\n return getAd(ad.wrapper.VASTAdTagURI, adChain, callback);\n }\n\n return callback(null, adChain);\n });\n }\n\n function buildAd(adJxonTree, callback) {\n try {\n var ad = new Ad(adJxonTree);\n callback(validateAd(ad), ad);\n } catch (e) {\n callback(new VASTError('on VASTClient.getVASTAd.buildAd, error parsing xml', 100), null);\n }\n }\n\n function validateAd(ad) {\n var wrapper = ad.wrapper;\n var inLine = ad.inLine;\n var errMsgPrefix = 'on VASTClient.getVASTAd.validateAd, ';\n\n if (inLine && wrapper) {\n return new VASTError(errMsgPrefix +\"InLine and Wrapper both found on the same Ad\", 101);\n }\n\n if (!inLine && !wrapper) {\n return new VASTError(errMsgPrefix + \"nor wrapper nor inline elements found on the Ad\", 101);\n }\n\n if (inLine && !inLine.isSupported()) {\n return new VASTError(errMsgPrefix + \"could not find MediaFile that is supported by this video player\", 403);\n }\n\n if (wrapper && !wrapper.VASTAdTagURI) {\n return new VASTError(errMsgPrefix + \"missing 'VASTAdTagURI' in wrapper\", 101);\n }\n\n return null;\n }\n\n function requestVASTAd(adTagUrl, callback) {\n that._requestVASTXml(adTagUrl, function (error, xmlStr) {\n if (error) {\n return callback(error);\n }\n try {\n var vastTree = xml.toJXONTree(xmlStr);\n callback(validateVASTTree(vastTree), vastTree.ad);\n } catch (e) {\n callback(new VASTError(\"on VASTClient.getVASTAd.requestVASTAd, error parsing xml\", 100));\n }\n });\n }\n};\n\nVASTClient.prototype._requestVASTXml = function requestVASTXml(adTagUrl, callback) {\n try {\n if (utilities.isFunction(adTagUrl)) {\n adTagUrl(requestHandler);\n } else {\n http.get(adTagUrl, requestHandler, {\n withCredentials: true\n });\n }\n } catch (e) {\n callback(e);\n }\n\n /*** Local functions ***/\n function requestHandler(error, response, status) {\n if (error) {\n var errMsg = utilities.isDefined(status) ?\n \"on VASTClient.requestVastXML, HTTP request error with status '\" + status + \"'\" :\n \"on VASTClient.requestVastXML, Error getting the the VAST XML with he passed adTagXML fn\";\n return callback(new VASTError(errMsg, 301), null);\n }\n\n callback(null, response);\n }\n};\n\nVASTClient.prototype._buildVASTResponse = function buildVASTResponse(adsChain) {\n var response = new VASTResponse();\n addAdsToResponse(response, adsChain);\n validateResponse(response);\n\n return response;\n\n //*** Local function ****\n function addAdsToResponse(response, ads) {\n ads.forEach(function (ad) {\n response.addAd(ad);\n });\n }\n\n function validateResponse(response) {\n var progressEvents = response.trackingEvents.progress;\n\n if (!response.hasLinear()) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, Received an Ad type that is not supported\", 200);\n }\n\n if (response.duration === undefined) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, Missing duration field in VAST response\", 101);\n }\n\n if (progressEvents) {\n progressEvents.forEach(function (progressEvent) {\n if (!utilities.isNumber(progressEvent.offset)) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, missing or wrong offset attribute on progress tracking event\", 101);\n }\n });\n }\n }\n};\n\nVASTClient.prototype._trackError = function (error, adChain) {\n if (!utilities.isArray(adChain) || adChain.length === 0) { //There is nothing to track\n return;\n }\n\n var errorURLMacros = [];\n adChain.forEach(addErrorUrlMacros);\n vastUtil.track(errorURLMacros, {ERRORCODE: error.code || 900}); //900 <== Undefined error\n\n /*** Local functions ***/\n function addErrorUrlMacros(ad) {\n if (ad.wrapper && ad.wrapper.error) {\n errorURLMacros.push(ad.wrapper.error);\n }\n\n if (ad.inLine && ad.inLine.error) {\n errorURLMacros.push(ad.inLine.error);\n }\n }\n};\n\nmodule.exports = VASTClient;\n\n},{\"../../utils/async\":40,\"../../utils/http\":42,\"../../utils/utilityFunctions\":45,\"../../utils/xml\":46,\"./Ad\":15,\"./VASTError\":23,\"./VASTResponse\":25,\"./vastUtil\":30}],23:[function(require,module,exports){\n'use strict';\n\nfunction VASTError(message, code) {\n this.message = 'VAST Error: ' + (message || '');\n if (code) {\n this.code = code;\n }\n}\n\nVASTError.prototype = new Error();\nVASTError.prototype.name = \"VAST Error\";\n\nmodule.exports = VASTError;\n},{}],24:[function(require,module,exports){\n'use strict';\n\n/**\n * Inner helper class that deals with the logic of the individual steps needed to setup an ad in the player.\n *\n * @param player {object} instance of the player that will play the ad. It assumes that the videojs-contrib-ads plugin\n * has been initialized when you use its utility functions.\n *\n * @constructor\n */\n\nvar VASTResponse = require('./VASTResponse');\nvar VASTError = require('./VASTError');\nvar VASTTracker = require('./VASTTracker');\nvar vastUtil = require('./vastUtil');\n\nvar async = require('../../utils/async');\nvar dom = require('../../utils/dom');\nvar playerUtils = require('../../utils/playerUtils');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VASTIntegrator(player) {\n if (!(this instanceof VASTIntegrator)) {\n return new VASTIntegrator(player);\n }\n\n this.player = player;\n}\n\nVASTIntegrator.prototype.playAd = function playAd(vastResponse, callback) {\n var that = this;\n callback = callback || utilities.noop;\n\n if (!(vastResponse instanceof VASTResponse)) {\n return callback(new VASTError('On VASTIntegrator, missing required VASTResponse'));\n }\n\n async.waterfall([\n function (next) {\n next(null, vastResponse);\n },\n this._selectAdSource.bind(this),\n this._createVASTTracker.bind(this),\n this._addClickThrough.bind(this),\n this._addSkipButton.bind(this),\n this._setupEvents.bind(this),\n this._playSelectedAd.bind(this)\n ], function (error, response) {\n if (error && response) {\n that._trackError(error, response);\n }\n callback(error, response);\n });\n\n this._adUnit = {\n _src: null,\n type: 'VAST',\n pauseAd: function () {\n that.player.pause(true);\n },\n\n resumeAd: function () {\n that.player.play(true);\n },\n\n isPaused: function () {\n return that.player.paused(true);\n },\n\n getSrc: function () {\n return this._src;\n }\n };\n\n return this._adUnit;\n};\n\nVASTIntegrator.prototype._selectAdSource = function selectAdSource(response, callback) {\n var source;\n\n var playerWidth = dom.getDimension(this.player.el()).width;\n response.mediaFiles.sort(function compareTo(a, b) {\n var deltaA = Math.abs(playerWidth - a.width);\n var deltaB = Math.abs(playerWidth - b.width);\n return deltaA - deltaB;\n });\n\n source = this.player.selectSource(response.mediaFiles).source;\n\n if (source) {\n if (this._adUnit) {\n this._adUnit._src = source;\n }\n return callback(null, source, response);\n }\n\n // code 403 <== Couldn't find MediaFile that is supported by this video player\n callback(new VASTError(\"Could not find Ad mediafile supported by this player\", 403), response);\n};\n\nVASTIntegrator.prototype._createVASTTracker = function createVASTTracker(adMediaFile, response, callback) {\n try {\n callback(null, adMediaFile, new VASTTracker(adMediaFile.src, response), response);\n } catch (e) {\n callback(e, response);\n }\n};\n\nVASTIntegrator.prototype._setupEvents = function setupEvents(adMediaFile, tracker, response, callback) {\n var previouslyMuted;\n var player = this.player;\n player.on('fullscreenchange', trackFullscreenChange);\n player.on('vast.adStart', trackImpressions);\n player.on('pause', trackPause);\n player.on('timeupdate', trackProgress);\n player.on('volumechange', trackVolumeChange);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], unbindEvents);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel', 'vast.adSkip'], function(evt){\n if(evt.type === 'vast.adEnd'){\n tracker.trackComplete();\n }\n });\n\n return callback(null, adMediaFile, response);\n\n /*** Local Functions ***/\n function unbindEvents() {\n player.off('fullscreenchange', trackFullscreenChange);\n player.off('vast.adStart', trackImpressions);\n player.off('pause', trackPause);\n player.off('timeupdate', trackProgress);\n player.off('volumechange', trackVolumeChange);\n }\n\n function trackFullscreenChange() {\n if (player.isFullscreen()) {\n tracker.trackFullscreen();\n } else {\n tracker.trackExitFullscreen();\n }\n }\n\n function trackPause() {\n //NOTE: whenever a video ends the video Element triggers a 'pause' event before the 'ended' event.\n // We should not track this pause event because it makes the VAST tracking confusing again we use a\n // Threshold of 2 seconds to prevent false positives on IOS.\n if (Math.abs(player.duration() - player.currentTime()) < 2) {\n return;\n }\n\n tracker.trackPause();\n playerUtils.once(player, ['play', 'vast.adEnd', 'vast.adsCancel'], function (evt) {\n if(evt.type === 'play'){\n tracker.trackResume();\n }\n });\n }\n\n function trackProgress() {\n var currentTimeInMs = player.currentTime() * 1000;\n tracker.trackProgress(currentTimeInMs);\n }\n\n function trackImpressions() {\n tracker.trackImpressions();\n tracker.trackCreativeView();\n }\n\n function trackVolumeChange() {\n var muted = player.muted();\n if (muted) {\n tracker.trackMute();\n } else if (previouslyMuted) {\n tracker.trackUnmute();\n }\n previouslyMuted = muted;\n }\n};\n\nVASTIntegrator.prototype._addSkipButton = function addSkipButton(source, tracker, response, callback) {\n var skipOffsetInSec;\n var that = this;\n\n if (utilities.isNumber(response.skipoffset)) {\n skipOffsetInSec = response.skipoffset / 1000;\n addSkipButtonToPlayer(this.player, skipOffsetInSec);\n }\n callback(null, source, tracker, response);\n\n /*** Local function ***/\n function addSkipButtonToPlayer(player, skipOffset) {\n var skipButton = createSkipButton(player);\n var updateSkipButton = updateSkipButtonState.bind(that, skipButton, skipOffset, player);\n\n player.el().appendChild(skipButton);\n player.on('timeupdate', updateSkipButton);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeSkipButton);\n\n function removeSkipButton() {\n player.off('timeupdate', updateSkipButton);\n dom.remove(skipButton);\n }\n }\n\n function createSkipButton(player) {\n var skipButton = window.document.createElement(\"div\");\n dom.addClass(skipButton, \"vast-skip-button\");\n\n skipButton.onclick = function (e) {\n if (dom.hasClass(skipButton, 'enabled')) {\n tracker.trackSkip();\n player.trigger('vast.adSkip');\n }\n\n //We prevent event propagation to avoid problems with the clickThrough and so on\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n } else {\n return false;\n }\n };\n\n return skipButton;\n }\n\n function updateSkipButtonState(skipButton, skipOffset, player) {\n var timeLeft = Math.ceil(skipOffset - player.currentTime());\n if (timeLeft > 0) {\n skipButton.innerHTML = \"Skip in \" + utilities.toFixedDigits(timeLeft, 2) + \"...\";\n } else {\n if (!dom.hasClass(skipButton, 'enabled')) {\n dom.addClass(skipButton, 'enabled');\n skipButton.innerHTML = \"Skip ad\";\n }\n }\n }\n};\n\nVASTIntegrator.prototype._addClickThrough = function addClickThrough(mediaFile, tracker, response, callback) {\n var player = this.player;\n var blocker = createClickThroughBlocker(player, tracker, response);\n var updateBlocker = updateBlockerURL.bind(this, blocker, response, player);\n\n player.el().insertBefore(blocker, player.controlBar.el());\n player.on('timeupdate', updateBlocker);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeBlocker);\n\n return callback(null, mediaFile, tracker, response);\n\n /*** Local Functions ***/\n\n function createClickThroughBlocker(player, tracker, response) {\n var blocker = window.document.createElement(\"a\");\n var clickThroughMacro = response.clickThrough;\n\n dom.addClass(blocker, 'vast-blocker');\n blocker.href = generateClickThroughURL(clickThroughMacro, player);\n\n if (utilities.isString(clickThroughMacro)) {\n blocker.target = \"_blank\";\n }\n\n blocker.onclick = function (e) {\n if (player.paused()) {\n player.play();\n\n //We prevent event propagation to avoid problems with the player's normal pause mechanism\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n }\n return false;\n }\n\n player.pause();\n tracker.trackClick();\n };\n\n return blocker;\n }\n\n function updateBlockerURL(blocker, response, player) {\n blocker.href = generateClickThroughURL(response.clickThrough, player);\n }\n\n function generateClickThroughURL(clickThroughMacro, player) {\n var variables = {\n ASSETURI: mediaFile.src,\n CONTENTPLAYHEAD: vastUtil.formatProgress(player.currentTime() * 1000)\n };\n\n return clickThroughMacro ? vastUtil.parseURLMacro(clickThroughMacro, variables) : '#';\n }\n\n function removeBlocker() {\n player.off('timeupdate', updateBlocker);\n dom.remove(blocker);\n }\n};\n\nVASTIntegrator.prototype._playSelectedAd = function playSelectedAd(source, response, callback) {\n var player = this.player;\n\n player.preload(\"auto\"); //without preload=auto the durationchange event is never fired\n player.src(source);\n\n playerUtils.once(player, ['durationchange', 'error', 'vast.adsCancel'], function (evt) {\n if (evt.type === 'durationchange') {\n playAd();\n } else if(evt.type === 'error') {\n callback(new VASTError(\"on VASTIntegrator, Player is unable to play the Ad\", 400), response);\n }\n //NOTE: If the ads get canceled we do nothing/\n });\n\n /**** local functions ******/\n function playAd() {\n\n playerUtils.once(player, ['playing', 'vast.adsCancel'], function (evt) {\n if(evt.type === 'vast.adsCancel'){\n return;\n }\n\n player.trigger('vast.adStart');\n\n player.on('ended', proceed);\n player.on('vast.adsCancel', proceed);\n player.on('vast.adSkip', proceed);\n\n function proceed(evt) {\n\n if(evt.type === 'ended' && (player.duration() - player.currentTime()) > 3 ) {\n // Ignore ended event if the Ad time was not 'near' the end\n // avoids issues where IOS controls could skip the Ad\n return;\n }\n\n player.off('ended', proceed);\n player.off('vast.adsCancel', proceed);\n player.off('vast.adSkip', proceed);\n\n //NOTE: if the ads get cancel we do nothing apart removing the listners\n if(evt.type === 'ended' || evt.type === 'vast.adSkip'){\n callback(null, response);\n }\n }\n });\n\n player.play();\n }\n};\n\nVASTIntegrator.prototype._trackError = function trackError(error, response) {\n vastUtil.track(response.errorURLMacros, {ERRORCODE: error.code || 900});\n};\n\nmodule.exports = VASTIntegrator;\n},{\"../../utils/async\":40,\"../../utils/dom\":41,\"../../utils/playerUtils\":43,\"../../utils/utilityFunctions\":45,\"./VASTError\":23,\"./VASTResponse\":25,\"./VASTTracker\":26,\"./vastUtil\":30}],25:[function(require,module,exports){\n'use strict';\n\nvar Ad = require('./Ad');\nvar VideoClicks = require('./VideoClicks');\nvar Linear = require('./Linear');\nvar InLine = require('./InLine');\nvar Wrapper = require('./Wrapper');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nwindow.InLine__A = InLine;\nfunction VASTResponse() {\n if (!(this instanceof VASTResponse)) {\n return new VASTResponse();\n }\n\n this._linearAdded = false;\n this.ads = [];\n this.errorURLMacros = [];\n this.impressions = [];\n this.clickTrackings = [];\n this.customClicks = [];\n this.trackingEvents = {};\n this.mediaFiles = [];\n this.clickThrough = undefined;\n this.adTitle = '';\n this.duration = undefined;\n this.skipoffset = undefined;\n}\n\nVASTResponse.prototype.addAd = function (ad) {\n var inLine, wrapper;\n if (ad instanceof Ad) {\n inLine = ad.inLine;\n wrapper = ad.wrapper;\n\n this.ads.push(ad);\n\n if (inLine) {\n this._addInLine(inLine);\n }\n\n if (wrapper) {\n this._addWrapper(wrapper);\n }\n }\n};\n\nVASTResponse.prototype._addErrorTrackUrl = function (error) {\n var errorURL = error instanceof xml.JXONTree ? xml.keyValue(error) : error;\n if (errorURL) {\n this.errorURLMacros.push(errorURL);\n }\n};\n\nVASTResponse.prototype._addImpressions = function (impressions) {\n utilities.isArray(impressions) && appendToArray(this.impressions, impressions);\n};\n\nVASTResponse.prototype._addClickThrough = function (clickThrough) {\n if (utilities.isNotEmptyString(clickThrough)) {\n this.clickThrough = clickThrough;\n }\n};\n\nVASTResponse.prototype._addClickTrackings = function (clickTrackings) {\n utilities.isArray(clickTrackings) && appendToArray(this.clickTrackings, clickTrackings);\n};\n\nVASTResponse.prototype._addCustomClicks = function (customClicks) {\n utilities.isArray(customClicks) && appendToArray(this.customClicks, customClicks);\n};\n\nVASTResponse.prototype._addTrackingEvents = function (trackingEvents) {\n var eventsMap = this.trackingEvents;\n\n if (trackingEvents) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingEvent) {\n if (!eventsMap[trackingEvent.name]) {\n eventsMap[trackingEvent.name] = [];\n }\n eventsMap[trackingEvent.name].push(trackingEvent);\n });\n }\n};\n\nVASTResponse.prototype._addTitle = function (title) {\n if (utilities.isNotEmptyString(title)) {\n this.adTitle = title;\n }\n};\n\nVASTResponse.prototype._addDuration = function (duration) {\n if (utilities.isNumber(duration)) {\n this.duration = duration;\n }\n};\n\nVASTResponse.prototype._addVideoClicks = function (videoClicks) {\n if (videoClicks instanceof VideoClicks) {\n this._addClickThrough(videoClicks.clickThrough);\n this._addClickTrackings(videoClicks.clickTrackings);\n this._addCustomClicks(videoClicks.customClicks);\n }\n};\n\nVASTResponse.prototype._addMediaFiles = function (mediaFiles) {\n utilities.isArray(mediaFiles) && appendToArray(this.mediaFiles, mediaFiles);\n};\n\nVASTResponse.prototype._addSkipoffset = function (offset) {\n if (offset) {\n this.skipoffset = offset;\n }\n};\n\nVASTResponse.prototype._addAdParameters = function (adParameters) {\n if (adParameters) {\n this.adParameters = adParameters;\n }\n};\n\nVASTResponse.prototype._addLinear = function (linear) {\n if (linear instanceof Linear) {\n this._addDuration(linear.duration);\n this._addTrackingEvents(linear.trackingEvents);\n this._addVideoClicks(linear.videoClicks);\n this._addMediaFiles(linear.mediaFiles);\n this._addSkipoffset(linear.skipoffset);\n this._addAdParameters(linear.adParameters);\n this._linearAdded = true;\n }\n};\n\nVASTResponse.prototype._addInLine = function (inLine) {\n var that = this;\n\n if (inLine instanceof InLine) {\n this._addTitle(inLine.adTitle);\n this._addErrorTrackUrl(inLine.error);\n this._addImpressions(inLine.impressions);\n\n inLine.creatives.forEach(function (creative) {\n if (creative.linear) {\n that._addLinear(creative.linear);\n }\n });\n }\n};\n\nVASTResponse.prototype._addWrapper = function (wrapper) {\n var that = this;\n\n if (wrapper instanceof Wrapper) {\n this._addErrorTrackUrl(wrapper.error);\n this._addImpressions(wrapper.impressions);\n\n wrapper.creatives.forEach(function (creative) {\n var linear = creative.linear;\n if (linear) {\n that._addVideoClicks(linear.videoClicks);\n that.clickThrough = undefined;//We ensure that no clickThrough has been added\n that._addTrackingEvents(linear.trackingEvents);\n }\n });\n }\n};\n\nVASTResponse.prototype.hasLinear = function(){\n return this._linearAdded;\n};\n\nfunction appendToArray(array, items) {\n items.forEach(function (item) {\n array.push(item);\n });\n}\n\nmodule.exports = VASTResponse;\n\n\n},{\"../../utils/utilityFunctions\":45,\"../../utils/xml\":46,\"./Ad\":15,\"./InLine\":18,\"./Linear\":19,\"./VideoClicks\":27,\"./Wrapper\":28}],26:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('./VASTError');\nvar VASTResponse = require('./VASTResponse');\nvar vastUtil = require('./vastUtil');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VASTTracker(assetURI, vastResponse) {\n if (!(this instanceof VASTTracker)) {\n return new VASTTracker(assetURI, vastResponse);\n }\n\n this.sanityCheck(assetURI, vastResponse);\n this.initialize(assetURI, vastResponse);\n\n}\n\nVASTTracker.prototype.initialize = function(assetURI, vastResponse) {\n this.response = vastResponse;\n this.assetURI = assetURI;\n this.progress = 0;\n this.quartiles = {\n firstQuartile: {tracked: false, time: Math.round(25 * vastResponse.duration) / 100},\n midpoint: {tracked: false, time: Math.round(50 * vastResponse.duration) / 100},\n thirdQuartile: {tracked: false, time: Math.round(75 * vastResponse.duration) / 100}\n };\n};\n\nVASTTracker.prototype.sanityCheck = function(assetURI, vastResponse) {\n if (!utilities.isString(assetURI) || utilities.isEmptyString(assetURI)) {\n throw new VASTError('on VASTTracker constructor, missing required the URI of the ad asset being played');\n }\n\n if (!(vastResponse instanceof VASTResponse)) {\n throw new VASTError('on VASTTracker constructor, missing required VAST response');\n }\n};\n\nVASTTracker.prototype.trackURLs = function trackURLs(urls, variables) {\n if (utilities.isArray(urls) && urls.length > 0) {\n variables = utilities.extend({\n ASSETURI: this.assetURI,\n CONTENTPLAYHEAD: vastUtil.formatProgress(this.progress)\n }, variables || {});\n\n vastUtil.track(urls, variables);\n }\n};\n\nVASTTracker.prototype.trackEvent = function trackEvent(eventName, trackOnce) {\n this.trackURLs(getEventUris(this.response.trackingEvents[eventName]));\n if (trackOnce) {\n this.response.trackingEvents[eventName] = undefined;\n }\n\n /*** Local function ***/\n function getEventUris(trackingEvents) {\n var uris;\n\n if (trackingEvents) {\n uris = [];\n trackingEvents.forEach(function (event) {\n uris.push(event.uri);\n });\n }\n return uris;\n }\n};\n\nVASTTracker.prototype.trackProgress = function trackProgress(newProgressInMs) {\n var that = this;\n var events = [];\n var ONCE = true;\n var ALWAYS = false;\n var trackingEvents = this.response.trackingEvents;\n\n if (utilities.isNumber(newProgressInMs)) {\n addTrackEvent('start', ONCE, newProgressInMs > 0);\n addTrackEvent('rewind', ALWAYS, hasRewound(this.progress, newProgressInMs));\n addQuartileEvents(newProgressInMs);\n trackProgressEvents(newProgressInMs);\n trackEvents();\n this.progress = newProgressInMs;\n }\n\n /*** Local function ***/\n function hasRewound(currentProgress, newProgress) {\n var REWIND_THRESHOLD = 3000; //IOS video clock is very unreliable and we need a 3 seconds threshold to ensure that there was a rewind an that it was on purpose.\n return currentProgress > newProgressInMs && Math.abs(newProgress - currentProgress) > REWIND_THRESHOLD;\n }\n\n function addTrackEvent(eventName, trackOnce, canBeAdded) {\n if (trackingEvents[eventName] && canBeAdded) {\n events.push({\n name: eventName,\n trackOnce: !!trackOnce\n });\n }\n }\n\n function addQuartileEvents(progress) {\n var quartiles = that.quartiles;\n var firstQuartile = that.quartiles.firstQuartile;\n var midpoint = that.quartiles.midpoint;\n var thirdQuartile = that.quartiles.thirdQuartile;\n\n if (!firstQuartile.tracked) {\n trackQuartile('firstQuartile', progress);\n } else if (!midpoint.tracked) {\n trackQuartile('midpoint', progress);\n } else if (!thirdQuartile.tracked){\n trackQuartile('thirdQuartile', progress);\n }\n\n /*** Local function ***/\n function trackQuartile(quartileName, progress){\n var quartile = quartiles[quartileName];\n if(canBeTracked(quartile, progress)){\n quartile.tracked = true;\n addTrackEvent(quartileName, ONCE, true);\n }\n }\n }\n\n function canBeTracked(quartile, progress) {\n var quartileTime = quartile.time;\n //We only fire the quartile event if the progress is bigger than the quartile time by 5 seconds at most.\n return progress >= quartileTime && progress <= (quartileTime + 5000);\n }\n\n function trackProgressEvents(progress) {\n if (!utilities.isArray(trackingEvents.progress)) {\n return; //Nothing to track\n }\n\n var pendingProgressEvts = [];\n\n trackingEvents.progress.forEach(function (evt) {\n if (evt.offset <= progress) {\n that.trackURLs([evt.uri]);\n } else {\n pendingProgressEvts.push(evt);\n }\n });\n trackingEvents.progress = pendingProgressEvts;\n }\n\n function trackEvents() {\n events.forEach(function (event) {\n that.trackEvent(event.name, event.trackOnce);\n });\n }\n};\n\n[\n 'rewind',\n 'fullscreen',\n 'exitFullscreen',\n 'pause',\n 'resume',\n 'mute',\n 'unmute',\n 'acceptInvitation',\n 'acceptInvitationLinear',\n 'collapse',\n 'expand'\n].forEach(function (eventName) {\n VASTTracker.prototype['track' + utilities.capitalize(eventName)] = function () {\n this.trackEvent(eventName);\n };\n });\n\n[\n 'start',\n 'skip',\n 'close',\n 'closeLinear'\n].forEach(function (eventName) {\n VASTTracker.prototype['track' + utilities.capitalize(eventName)] = function () {\n this.trackEvent(eventName, true);\n };\n });\n\n[\n 'firstQuartile',\n 'midpoint',\n 'thirdQuartile'\n].forEach(function (quartile) {\n VASTTracker.prototype['track' + utilities.capitalize(quartile)] = function () {\n this.quartiles[quartile].tracked = true;\n this.trackEvent(quartile, true);\n };\n });\n\nVASTTracker.prototype.trackComplete = function () {\n if(this.quartiles.thirdQuartile.tracked){\n this.trackEvent('complete', true);\n }\n};\n\nVASTTracker.prototype.trackErrorWithCode = function trackErrorWithCode(errorcode) {\n if (utilities.isNumber(errorcode)) {\n this.trackURLs(this.response.errorURLMacros, {ERRORCODE: errorcode});\n }\n};\n\nVASTTracker.prototype.trackImpressions = function trackImpressions() {\n this.trackURLs(this.response.impressions);\n};\n\nVASTTracker.prototype.trackCreativeView = function trackCreativeView() {\n this.trackEvent('creativeView');\n};\n\nVASTTracker.prototype.trackClick = function trackClick() {\n this.trackURLs(this.response.clickTrackings);\n};\n\nmodule.exports = VASTTracker;\n\n},{\"../../utils/utilityFunctions\":45,\"./VASTError\":23,\"./VASTResponse\":25,\"./vastUtil\":30}],27:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction VideoClicks(videoClickJTree) {\n if (!(this instanceof VideoClicks)) {\n return new VideoClicks(videoClickJTree);\n }\n\n this.clickThrough = xml.keyValue(videoClickJTree.clickThrough);\n this.clickTrackings = parseClickTrackings(videoClickJTree.clickTracking);\n this.customClicks = parseClickTrackings(videoClickJTree.customClick);\n\n /*** Local functions ***/\n function parseClickTrackings(trackingData) {\n var clickTrackings = [];\n if (trackingData) {\n trackingData = utilities.isArray(trackingData) ? trackingData : [trackingData];\n trackingData.forEach(function (clickTrackingData) {\n clickTrackings.push(xml.keyValue(clickTrackingData));\n });\n }\n return clickTrackings;\n }\n}\n\nmodule.exports = VideoClicks;\n},{\"../../utils/utilityFunctions\":45,\"../../utils/xml\":46}],28:[function(require,module,exports){\n'use strict';\n\nvar vastUtil = require('./vastUtil');\nvar Creative = require('./Creative');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction Wrapper(wrapperJTree) {\n if(!(this instanceof Wrapper)) {\n return new Wrapper(wrapperJTree);\n }\n\n //Required elements\n this.adSystem = xml.keyValue(wrapperJTree.adSystem);\n this.impressions = vastUtil.parseImpressions(wrapperJTree.impression);\n this.VASTAdTagURI = xml.keyValue(wrapperJTree.vASTAdTagURI);\n\n //Optional elements\n this.creatives = Creative.parseCreatives(wrapperJTree.creatives);\n this.error = xml.keyValue(wrapperJTree.error);\n this.extensions = wrapperJTree.extensions;\n\n //Optional attrs\n this.followAdditionalWrappers = utilities.isDefined(xml.attr(wrapperJTree, 'followAdditionalWrappers'))? xml.attr(wrapperJTree, 'followAdditionalWrappers'): true;\n this.allowMultipleAds = xml.attr(wrapperJTree, 'allowMultipleAds');\n this.fallbackOnNoAd = xml.attr(wrapperJTree, 'fallbackOnNoAd');\n}\n\nmodule.exports = Wrapper;\n\n},{\"../../utils/utilityFunctions\":45,\"../../utils/xml\":46,\"./Creative\":17,\"./vastUtil\":30}],29:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\n\nvar durationRegex = /(\\d\\d):(\\d\\d):(\\d\\d)(\\.(\\d\\d\\d))?/;\n\nvar parsers = {\n\n duration: function parseDuration(durationStr) {\n\n var match, durationInMs;\n\n if (utilities.isString(durationStr)) {\n match = durationStr.match(durationRegex);\n if (match) {\n durationInMs = parseHoursToMs(match[1]) + parseMinToMs(match[2]) + parseSecToMs(match[3]) + parseInt(match[5] || 0);\n }\n }\n\n return isNaN(durationInMs) ? null : durationInMs;\n\n /*** local functions ***/\n function parseHoursToMs(hourStr) {\n return parseInt(hourStr, 10) * 60 * 60 * 1000;\n }\n\n function parseMinToMs(minStr) {\n return parseInt(minStr, 10) * 60 * 1000;\n }\n\n function parseSecToMs(secStr) {\n return parseInt(secStr, 10) * 1000;\n }\n },\n\n offset: function parseOffset(offset, duration) {\n if(isPercentage(offset)){\n return calculatePercentage(offset, duration);\n }\n return parsers.duration(offset);\n\n /*** Local function ***/\n function isPercentage(offset) {\n var percentageRegex = /^\\d+(\\.\\d+)?%$/g;\n return percentageRegex.test(offset);\n }\n\n function calculatePercentage(percentStr, duration) {\n if(duration) {\n return calcPercent(duration, parseFloat(percentStr.replace('%', '')));\n }\n return null;\n }\n\n function calcPercent(quantity, percent){\n return quantity * percent / 100;\n }\n }\n\n};\n\n\nmodule.exports = parsers;\n},{\"../../utils/utilityFunctions\":45}],30:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\nvar VPAIDHTML5Tech = require('../vpaid/VPAIDHTML5Tech');\nvar VPAIDFlashTech = require('../vpaid/VPAIDFlashTech');\nvar VPAIDFLASHClient = require('VPAIDFLASHClient/js/VPAIDFLASHClient');\n\nvar vastUtil = {\n\n track: function track(URLMacros, variables) {\n var sources = vastUtil.parseURLMacros(URLMacros, variables);\n var trackImgs = [];\n sources.forEach(function (src) {\n var img = new Image();\n img.src = src;\n trackImgs.push(img);\n });\n return trackImgs;\n },\n\n parseURLMacros: function parseMacros(URLMacros, variables) {\n var parsedURLs = [];\n\n variables = variables || {};\n\n if (!(variables[\"CACHEBUSTING\"])) {\n variables[\"CACHEBUSTING\"] = Math.round(Math.random() * 1.0e+10);\n }\n\n URLMacros.forEach(function (URLMacro) {\n parsedURLs.push(vastUtil._parseURLMacro(URLMacro, variables));\n });\n\n return parsedURLs;\n },\n\n parseURLMacro: function parseMacro(URLMacro, variables) {\n variables = variables || {};\n\n if (!(variables[\"CACHEBUSTING\"])) {\n variables[\"CACHEBUSTING\"] = Math.round(Math.random() * 1.0e+10);\n }\n\n return vastUtil._parseURLMacro(URLMacro, variables);\n },\n\n _parseURLMacro: function parseMacro(URLMacro, variables) {\n variables = variables || {};\n\n utilities.forEach(variables, function (value, key) {\n URLMacro = URLMacro.replace(new RegExp(\"\\\\[\" + key + \"\\\\\\]\", 'gm'), value);\n });\n\n return URLMacro;\n },\n\n parseDuration: function parseDuration(durationStr) {\n var durationRegex = /(\\d\\d):(\\d\\d):(\\d\\d)(\\.(\\d\\d\\d))?/;\n var match, durationInMs;\n\n if (utilities.isString(durationStr)) {\n match = durationStr.match(durationRegex);\n if (match) {\n durationInMs = parseHoursToMs(match[1]) + parseMinToMs(match[2]) + parseSecToMs(match[3]) + parseInt(match[5] || 0);\n }\n }\n\n return isNaN(durationInMs) ? null : durationInMs;\n\n /*** local functions ***/\n function parseHoursToMs(hourStr) {\n return parseInt(hourStr, 10) * 60 * 60 * 1000;\n }\n\n function parseMinToMs(minStr) {\n return parseInt(minStr, 10) * 60 * 1000;\n }\n\n function parseSecToMs(secStr) {\n return parseInt(secStr, 10) * 1000;\n }\n },\n\n parseImpressions: function parseImpressions(impressions) {\n if (impressions) {\n impressions = utilities.isArray(impressions) ? impressions : [impressions];\n return utilities.transformArray(impressions, function (impression) {\n if (utilities.isNotEmptyString(impression.keyValue)) {\n return impression.keyValue;\n }\n return undefined;\n });\n }\n return [];\n },\n\n\n //We assume that the progress is going to arrive in milliseconds\n formatProgress: function formatProgress(progress) {\n var hours, minutes, seconds, milliseconds;\n hours = progress / (60 * 60 * 1000);\n hours = Math.floor(hours);\n minutes = (progress / (60 * 1000)) % 60;\n minutes = Math.floor(minutes);\n seconds = (progress / 1000) % 60;\n seconds = Math.floor(seconds);\n milliseconds = progress % 1000;\n return utilities.toFixedDigits(hours, 2) + ':' + utilities.toFixedDigits(minutes, 2) + ':' + utilities.toFixedDigits(seconds, 2) + '.' + utilities.toFixedDigits(milliseconds, 3);\n },\n\n parseOffset: function parseOffset(offset, duration) {\n if (isPercentage(offset)) {\n return calculatePercentage(offset, duration);\n }\n return vastUtil.parseDuration(offset);\n\n /*** Local function ***/\n function isPercentage(offset) {\n var percentageRegex = /^\\d+(\\.\\d+)?%$/g;\n return percentageRegex.test(offset);\n }\n\n function calculatePercentage(percentStr, duration) {\n if (duration) {\n return calcPercent(duration, parseFloat(percentStr.replace('%', '')));\n }\n return null;\n }\n\n function calcPercent(quantity, percent) {\n return quantity * percent / 100;\n }\n },\n\n\n //List of supported VPAID technologies\n VPAID_techs: [\n VPAIDFlashTech,\n VPAIDHTML5Tech\n ],\n\n isVPAID: function isVPAIDMediaFile(mediaFile) {\n return !!mediaFile && mediaFile.apiFramework === 'VPAID';\n },\n\n findSupportedVPAIDTech: function findSupportedVPAIDTech(mimeType) {\n var i, len, VPAIDTech;\n\n for (i = 0, len = this.VPAID_techs.length; i < len; i += 1) {\n VPAIDTech = this.VPAID_techs[i];\n if (VPAIDTech.supports(mimeType)) {\n return VPAIDTech;\n }\n }\n return null;\n },\n\n isFlashSupported: function isFlashSupported() {\n return VPAIDFLASHClient.isSupported();\n },\n\n /**\n * Necessary step for VPAIDFLAShClient to know if flash is supported and not blocked.\n * IMPORTANT NOTE: This is an async test and needs to be run as soon as possible.\n *\n * @param vpaidFlashLoaderPath the path to the vpaidFlashLoader swf obj.\n */\n runFlashSupportCheck: function runFlashSupportCheck(vpaidFlashLoaderPath) {\n VPAIDFLASHClient.runFlashTest({data: vpaidFlashLoaderPath});\n }\n\n};\n\nmodule.exports = vastUtil;\n\n},{\"../../utils/utilityFunctions\":45,\"../vpaid/VPAIDFlashTech\":32,\"../vpaid/VPAIDHTML5Tech\":33,\"VPAIDFLASHClient/js/VPAIDFLASHClient\":3}],31:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VPAIDAdUnitWrapper(vpaidAdUnit, opts) {\n if (!(this instanceof VPAIDAdUnitWrapper)) {\n return new VPAIDAdUnitWrapper(vpaidAdUnit, opts);\n }\n sanityCheck(vpaidAdUnit, opts);\n\n this.options = utilities.extend({}, opts);\n\n this._adUnit = vpaidAdUnit;\n\n /*** Local Functions ***/\n function sanityCheck(adUnit, opts) {\n if (!adUnit || !VPAIDAdUnitWrapper.checkVPAIDInterface(adUnit)) {\n throw new VASTError('on VPAIDAdUnitWrapper, the passed VPAID adUnit does not fully implement the VPAID interface');\n }\n\n if (!utilities.isObject(opts)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper, expected options hash but got '\" + opts + \"'\");\n }\n\n if (!(\"responseTimeout\" in opts) || !utilities.isNumber(opts.responseTimeout) ){\n throw new VASTError(\"on VPAIDAdUnitWrapper, expected responseTimeout in options\");\n }\n }\n}\n\nVPAIDAdUnitWrapper.checkVPAIDInterface = function checkVPAIDInterface(VPAIDAdUnit) {\n //NOTE: skipAd is not part of the method list because it only appears in VPAID 2.0 and we support VPAID 1.0\n var VPAIDInterfaceMethods = [\n 'handshakeVersion', 'initAd', 'startAd', 'stopAd', 'resizeAd', 'pauseAd', 'expandAd', 'collapseAd'\n ];\n\n for (var i = 0, len = VPAIDInterfaceMethods.length; i < len; i++) {\n if (!VPAIDAdUnit || !utilities.isFunction(VPAIDAdUnit[VPAIDInterfaceMethods[i]])) {\n return false;\n }\n }\n\n\n return canSubscribeToEvents(VPAIDAdUnit) && canUnsubscribeFromEvents(VPAIDAdUnit);\n\n /*** Local Functions ***/\n\n function canSubscribeToEvents(adUnit) {\n return utilities.isFunction(adUnit.subscribe) || utilities.isFunction(adUnit.addEventListener) || utilities.isFunction(adUnit.on);\n }\n\n function canUnsubscribeFromEvents(adUnit) {\n return utilities.isFunction(adUnit.unsubscribe) || utilities.isFunction(adUnit.removeEventListener) || utilities.isFunction(adUnit.off);\n\n }\n};\n\nVPAIDAdUnitWrapper.prototype.adUnitAsyncCall = function () {\n var args = utilities.arrayLikeObjToArray(arguments);\n var method = args.shift();\n var cb = args.pop();\n var timeoutId;\n\n sanityCheck(method, cb, this._adUnit);\n args.push(wrapCallback());\n\n this._adUnit[method].apply(this._adUnit, args);\n timeoutId = setTimeout(function () {\n timeoutId = null;\n cb(new VASTError(\"on VPAIDAdUnitWrapper, timeout while waiting for a response on call '\" + method + \"'\"));\n cb = utilities.noop;\n }, this.options.responseTimeout);\n\n /*** Local functions ***/\n function sanityCheck(method, cb, adUnit) {\n if (!utilities.isString(method) || !utilities.isFunction(adUnit[method])) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.adUnitAsyncCall, invalid method name\");\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.adUnitAsyncCall, missing callback\");\n }\n }\n\n function wrapCallback() {\n return function () {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n cb.apply(this, arguments);\n };\n }\n};\n\nVPAIDAdUnitWrapper.prototype.on = function (evtName, handler) {\n var addEventListener = this._adUnit.addEventListener || this._adUnit.subscribe || this._adUnit.on;\n addEventListener.call(this._adUnit, evtName, handler);\n};\n\nVPAIDAdUnitWrapper.prototype.off = function (evtName, handler) {\n var removeEventListener = this._adUnit.removeEventListener || this._adUnit.unsubscribe || this._adUnit.off;\n removeEventListener.call(this._adUnit, evtName, handler);\n};\n\nVPAIDAdUnitWrapper.prototype.waitForEvent = function (evtName, cb, context) {\n var timeoutId;\n sanityCheck(evtName, cb);\n context = context || null;\n\n this.on(evtName, responseListener);\n\n timeoutId = setTimeout(function () {\n cb(new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, timeout while waiting for event '\" + evtName + \"'\"));\n timeoutId = null;\n cb = utilities.noop;\n }, this.options.responseTimeout);\n\n /*** Local functions ***/\n function sanityCheck(evtName, cb) {\n if (!utilities.isString(evtName)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, missing evt name\");\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, missing callback\");\n }\n }\n\n function responseListener() {\n var args = utilities.arrayLikeObjToArray(arguments);\n\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n\n args.unshift(null);\n cb.apply(context, args);\n }\n};\n\n// VPAID METHODS\nVPAIDAdUnitWrapper.prototype.handshakeVersion = function (version, cb) {\n this.adUnitAsyncCall('handshakeVersion', version, cb);\n};\n\n/* jshint maxparams:6 */\nVPAIDAdUnitWrapper.prototype.initAd = function (width, height, viewMode, desiredBitrate, adUnitData, cb) {\n this.waitForEvent('AdLoaded', cb);\n this._adUnit.initAd(width, height, viewMode, desiredBitrate, adUnitData);\n};\n\nVPAIDAdUnitWrapper.prototype.resizeAd = function (width, height, viewMode, cb) {\n // NOTE: AdSizeChange event is only supported on VPAID 2.0 so for the moment we are not going to use it\n // and will assume that everything is fine after the async call\n this.adUnitAsyncCall('resizeAd', width, height, viewMode, cb);\n};\n\nVPAIDAdUnitWrapper.prototype.startAd = function (cb) {\n this.waitForEvent('AdStarted', cb);\n this._adUnit.startAd();\n};\n\nVPAIDAdUnitWrapper.prototype.stopAd = function (cb) {\n this.waitForEvent('AdStopped', cb);\n this._adUnit.stopAd();\n};\n\nVPAIDAdUnitWrapper.prototype.pauseAd = function (cb) {\n this.waitForEvent('AdPaused', cb);\n this._adUnit.pauseAd();\n};\n\nVPAIDAdUnitWrapper.prototype.resumeAd = function (cb) {\n this.waitForEvent('AdPlaying', cb);\n this._adUnit.resumeAd();\n};\n\nVPAIDAdUnitWrapper.prototype.expandAd = function (cb) {\n this.waitForEvent('AdExpandedChange', cb);\n this._adUnit.expandAd();\n};\n\nVPAIDAdUnitWrapper.prototype.collapseAd = function (cb) {\n this.waitForEvent('AdExpandedChange', cb);\n this._adUnit.collapseAd();\n};\n\nVPAIDAdUnitWrapper.prototype.skipAd = function (cb) {\n this.waitForEvent('AdSkipped', cb);\n this._adUnit.skipAd();\n};\n\n//VPAID property getters\n[\n 'adLinear',\n 'adWidth',\n 'adHeight',\n 'adExpanded',\n 'adSkippableState',\n 'adRemainingTime',\n 'adDuration',\n 'adVolume',\n 'adCompanions',\n 'adIcons'\n].forEach(function (property) {\n var getterName = 'get' + utilities.capitalize(property);\n\n VPAIDAdUnitWrapper.prototype[getterName] = function (cb) {\n this.adUnitAsyncCall(getterName, cb);\n };\n});\n\n//VPAID property setters\nVPAIDAdUnitWrapper.prototype.setAdVolume = function(volume, cb){\n this.adUnitAsyncCall('setAdVolume',volume, cb);\n};\n\nmodule.exports = VPAIDAdUnitWrapper;\n\n},{\"../../utils/utilityFunctions\":45,\"../vast/VASTError\":23}],32:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar VPAIDFLASHClient = require('VPAIDFLASHClient/js/VPAIDFLASHClient');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar dom = require('../../utils/dom');\n\nfunction VPAIDFlashTech(mediaFile, settings) {\n if (!(this instanceof VPAIDFlashTech)) {\n return new VPAIDFlashTech(mediaFile);\n }\n sanityCheck(mediaFile);\n this.name = 'vpaid-flash';\n this.mediaFile = mediaFile;\n this.containerEl = null;\n this.vpaidFlashClient = null;\n this.settings = settings;\n\n /*** local functions ***/\n function sanityCheck(mediaFile) {\n if (!mediaFile || !utilities.isString(mediaFile.src)) {\n throw new VASTError('on VPAIDFlashTech, invalid MediaFile');\n }\n }\n}\n\nVPAIDFlashTech.VPAIDFLASHClient = VPAIDFLASHClient;\n\nVPAIDFlashTech.supports = function (type) {\n return type === 'application/x-shockwave-flash' && VPAIDFlashTech.VPAIDFLASHClient.isSupported();\n};\n\nVPAIDFlashTech.prototype.loadAdUnit = function loadFlashCreative(containerEl, objectEl, callback) {\n var that = this;\n var flashClientOpts = this.settings && this.settings.vpaidFlashLoaderPath ? {data: this.settings.vpaidFlashLoaderPath} : undefined;\n sanityCheck(containerEl, callback);\n\n this.containerEl = containerEl;\n this.vpaidFlashClient = new VPAIDFlashTech.VPAIDFLASHClient(containerEl, function (error) {\n if (error) {\n return callback(error);\n }\n\n that.vpaidFlashClient.loadAdUnit(that.mediaFile.src, callback);\n }, flashClientOpts);\n\n /*** Local Functions ***/\n function sanityCheck(container, cb) {\n\n if (!dom.isDomElement(container)) {\n throw new VASTError('on VPAIDFlashTech.loadAdUnit, invalid dom container element');\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError('on VPAIDFlashTech.loadAdUnit, missing valid callback');\n }\n }\n};\n\nVPAIDFlashTech.prototype.unloadAdUnit = function () {\n if (this.vpaidFlashClient) {\n try{\n this.vpaidFlashClient.destroy();\n } catch(e){\n if(console && utilities.isFunction(console.log)){\n console.log('VAST ERROR: trying to unload the VPAID adunit');\n }\n }\n this.vpaidFlashClient = null;\n }\n\n if (this.containerEl) {\n dom.remove(this.containerEl);\n this.containerEl = null;\n }\n};\n\nmodule.exports = VPAIDFlashTech;\n\n},{\"../../utils/dom\":41,\"../../utils/utilityFunctions\":45,\"../vast/VASTError\":23,\"VPAIDFLASHClient/js/VPAIDFLASHClient\":3}],33:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar VPAIDHTML5Client = require('VPAIDHTML5Client/js/VPAIDHTML5Client');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar dom = require('../../utils/dom');\n\nfunction VPAIDHTML5Tech(mediaFile) {\n\n if(!(this instanceof VPAIDHTML5Tech)) {\n return new VPAIDHTML5Tech(mediaFile);\n }\n\n sanityCheck(mediaFile);\n\n this.name = 'vpaid-html5';\n this.containerEl = null;\n this.videoEl = null;\n this.vpaidHTMLClient = null;\n\n this.mediaFile = mediaFile;\n\n function sanityCheck(mediaFile) {\n if (!mediaFile || !utilities.isString(mediaFile.src)) {\n throw new VASTError(VPAIDHTML5Tech.INVALID_MEDIA_FILE);\n }\n }\n}\n\nVPAIDHTML5Tech.VPAIDHTML5Client = VPAIDHTML5Client;\n\nVPAIDHTML5Tech.supports = function (type) {\n return !utilities.isOldIE() && type === 'application/javascript';\n};\n\nVPAIDHTML5Tech.prototype.loadAdUnit = function loadAdUnit(containerEl, videoEl, callback) {\n sanityCheck(containerEl, videoEl, callback);\n\n this.containerEl = containerEl;\n this.videoEl = videoEl;\n this.vpaidHTMLClient = new VPAIDHTML5Tech.VPAIDHTML5Client(containerEl, videoEl, {});\n this.vpaidHTMLClient.loadAdUnit(this.mediaFile.src, callback);\n\n function sanityCheck(container, video, cb) {\n if (!dom.isDomElement(container)) {\n throw new VASTError(VPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL);\n }\n\n if (!dom.isDomElement(video) || video.tagName.toLowerCase() !== 'video') {\n throw new VASTError(VPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL);\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(VPAIDHTML5Tech.MISSING_CALLBACK);\n }\n }\n};\n\nVPAIDHTML5Tech.prototype.unloadAdUnit = function unloadAdUnit() {\n if (this.vpaidHTMLClient) {\n try {\n this.vpaidHTMLClient.destroy();\n } catch(e) {\n if (console && utilities.isFunction(console.log)) {\n console.log('VAST ERROR: trying to unload the VPAID adunit');\n }\n }\n\n this.vpaidHTMLClient = null;\n }\n\n if (this.containerEl) {\n dom.remove(this.containerEl);\n this.containerEl = null;\n }\n};\n\nvar PREFIX = 'on VPAIDHTML5Tech';\nVPAIDHTML5Tech.INVALID_MEDIA_FILE = PREFIX + ', invalid MediaFile';\nVPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL = PREFIX + ', invalid container HtmlElement';\nVPAIDHTML5Tech.INVALID_DOM_VIDEO_EL = PREFIX + ', invalid HTMLVideoElement';\nVPAIDHTML5Tech.MISSING_CALLBACK = PREFIX + ', missing valid callback';\n\nmodule.exports = VPAIDHTML5Tech;\n},{\"../../utils/dom\":41,\"../../utils/utilityFunctions\":45,\"../vast/VASTError\":23,\"VPAIDHTML5Client/js/VPAIDHTML5Client\":11}],34:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('../vast/VASTError');\nvar VASTResponse = require('../vast/VASTResponse');\nvar VASTTracker = require('../vast/VASTTracker');\nvar vastUtil = require('../vast/vastUtil');\n\nvar VPAIDAdUnitWrapper = require('./VPAIDAdUnitWrapper');\n\nvar async = require('../../utils/async');\nvar dom = require('../../utils/dom');\nvar playerUtils = require('../../utils/playerUtils');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VPAIDIntegrator(player, settings) {\n if (!(this instanceof VPAIDIntegrator)) {\n return new VPAIDIntegrator(player);\n }\n\n this.VIEW_MODE = {\n NORMAL: 'normal',\n FULLSCREEN: \"fullscreen\",\n THUMBNAIL: \"thumbnail\"\n };\n this.player = player;\n this.containerEl = createVPAIDContainerEl(player);\n this.options = {\n responseTimeout: 5000,\n VPAID_VERSION: '2.0'\n };\n this.settings = settings;\n\n /*** Local functions ***/\n\n function createVPAIDContainerEl() {\n var containerEl = document.createElement('div');\n dom.addClass(containerEl, 'VPAID-container');\n player.el().insertBefore(containerEl, player.controlBar.el());\n return containerEl;\n\n }\n}\n\nVPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) {\n if (!(vastResponse instanceof VASTResponse)) {\n return callback(new VASTError('on VASTIntegrator.playAd, missing required VASTResponse'));\n }\n\n var that = this;\n var player = this.player;\n var tech = this._findSupportedTech(vastResponse, this.settings);\n\n callback = callback || utilities.noop;\n\n this._adUnit = null;\n\n dom.addClass(player.el(), 'vjs-vpaid-ad');\n\n player.on('vast.adsCancel', triggerVpaidAdEnd);\n player.one('vpaid.adEnd', function(){\n player.off('vast.adsCancel', triggerVpaidAdEnd);\n removeAdUnit();\n });\n\n if (tech) {\n async.waterfall([\n function (next) {\n next(null, tech, vastResponse);\n },\n this._loadAdUnit.bind(this),\n this._playAdUnit.bind(this),\n this._finishPlaying.bind(this)\n\n ], adComplete);\n\n this._adUnit = {\n _paused: true,\n type: 'VPAID',\n pauseAd: function() {\n player.trigger('vpaid.pauseAd');\n player.pause(true);//we make sure that the video content gets stopped.\n },\n resumeAd: function() {\n player.trigger('vpaid.resumeAd');\n },\n isPaused: function() {\n return this._paused;\n },\n getSrc: function() {\n return tech.mediaFile;\n }\n };\n\n } else {\n var error = new VASTError('on VPAIDIntegrator.playAd, could not find a supported mediaFile', 403);\n adComplete(error, this._adUnit, vastResponse);\n }\n\n return this._adUnit;\n\n /*** Local functions ***/\n function adComplete(error, adUnit, vastResponse) {\n if (error && vastResponse) {\n that._trackError(vastResponse, error.code);\n }\n player.trigger('vpaid.adEnd');\n callback(error, vastResponse);\n }\n\n function triggerVpaidAdEnd(){\n player.trigger('vpaid.adEnd');\n }\n\n function removeAdUnit() {\n if (tech) {\n tech.unloadAdUnit();\n }\n dom.removeClass(player.el(), 'vjs-vpaid-ad');\n }\n};\n\nVPAIDIntegrator.prototype._findSupportedTech = function (vastResponse, settings) {\n if (!(vastResponse instanceof VASTResponse)) {\n return null;\n }\n\n var vpaidMediaFiles = vastResponse.mediaFiles.filter(vastUtil.isVPAID);\n var i, len, mediaFile, VPAIDTech;\n\n for (i = 0, len = vpaidMediaFiles.length; i < len; i += 1) {\n mediaFile = vpaidMediaFiles[i];\n VPAIDTech = vastUtil.findSupportedVPAIDTech(mediaFile.type);\n if (VPAIDTech) {\n return new VPAIDTech(mediaFile, settings);\n }\n }\n return null;\n};\n\nVPAIDIntegrator.prototype._createVPAIDAdUnitWrapper = function(adUnit, src, responseTimeout) {\n return new VPAIDAdUnitWrapper(adUnit, {src: src, responseTimeout: responseTimeout});\n};\n\nVPAIDIntegrator.prototype._loadAdUnit = function (tech, vastResponse, next) {\n var that = this;\n var player = this.player;\n var vjsTechEl = player.el().querySelector('.vjs-tech');\n var responseTimeout = this.settings.responseTimeout || this.options.responseTimeout;\n tech.loadAdUnit(this.containerEl, vjsTechEl, function (error, adUnit) {\n if (error) {\n return next(error, adUnit, vastResponse);\n }\n\n try {\n var WrappedAdUnit = that._createVPAIDAdUnitWrapper(adUnit, tech.mediaFile.src, responseTimeout);\n var techClass = 'vjs-' + tech.name + '-ad';\n dom.addClass(player.el(), techClass);\n player.one('vpaid.adEnd', function() {\n dom.removeClass(player.el(),techClass);\n });\n next(null, WrappedAdUnit, vastResponse);\n } catch (e) {\n next(e, adUnit, vastResponse);\n }\n });\n};\n\nVPAIDIntegrator.prototype._playAdUnit = function (adUnit, vastResponse, callback) {\n async.waterfall([\n function (next) {\n next(null, adUnit, vastResponse);\n },\n this._handshake.bind(this),\n this._initAd.bind(this),\n this._setupEvents.bind(this),\n this._addSkipButton.bind(this),\n this._linkPlayerControls.bind(this),\n this._startAd.bind(this)\n ], callback);\n};\n\nVPAIDIntegrator.prototype._handshake = function handshake(adUnit, vastResponse, next) {\n adUnit.handshakeVersion(this.options.VPAID_VERSION, function (error, version) {\n if (error) {\n return next(error, adUnit, vastResponse);\n }\n\n if (version && isSupportedVersion(version)) {\n return next(null, adUnit, vastResponse);\n }\n\n return next(new VASTError('on VPAIDIntegrator._handshake, unsupported version \"' + version + '\"'), adUnit, vastResponse);\n });\n\n function isSupportedVersion(version) {\n var majorNum = major(version);\n return majorNum >= 1 && majorNum <= 2;\n }\n\n function major(version) {\n var parts = version.split('.');\n return parseInt(parts[0], 10);\n }\n};\n\nVPAIDIntegrator.prototype._initAd = function (adUnit, vastResponse, next) {\n var tech = this.player.el().querySelector('.vjs-tech');\n var dimension = dom.getDimension(tech);\n adUnit.initAd(dimension.width, dimension.height, this.VIEW_MODE.NORMAL, -1, {AdParameters: vastResponse.adParameters || ''}, function (error) {\n next(error, adUnit, vastResponse);\n });\n};\n\nVPAIDIntegrator.prototype._createVASTTracker = function(adUnitSrc, vastResponse) {\n return new VASTTracker(adUnitSrc, vastResponse);\n};\n\nVPAIDIntegrator.prototype._setupEvents = function (adUnit, vastResponse, next) {\n var adUnitSrc = adUnit.options.src;\n var tracker = this._createVASTTracker(adUnitSrc, vastResponse);\n var player = this.player;\n var that = this;\n\n adUnit.on('AdSkipped', function () {\n player.trigger('vpaid.AdSkipped');\n tracker.trackSkip();\n });\n\n adUnit.on('AdImpression', function () {\n player.trigger('vpaid.AdImpression');\n tracker.trackImpressions();\n });\n\n adUnit.on('AdStarted', function () {\n player.trigger('vpaid.AdStarted');\n tracker.trackCreativeView();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdVideoStart', function () {\n player.trigger('vpaid.AdVideoStart');\n tracker.trackStart();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdPlaying', function () {\n player.trigger('vpaid.AdPlaying');\n tracker.trackResume();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdPaused', function () {\n player.trigger('vpaid.AdPaused');\n tracker.trackPause();\n notifyPauseToPlayer();\n });\n\n function notifyPlayToPlayer(){\n if(that._adUnit && that._adUnit.isPaused()){\n that._adUnit._paused = false;\n }\n player.trigger('play');\n\n }\n\n function notifyPauseToPlayer() {\n if(that._adUnit){\n that._adUnit._paused = true;\n }\n player.trigger('pause');\n }\n\n adUnit.on('AdVideoFirstQuartile', function () {\n player.trigger('vpaid.AdVideoFirstQuartile');\n tracker.trackFirstQuartile();\n });\n\n adUnit.on('AdVideoMidpoint', function () {\n player.trigger('vpaid.AdVideoMidpoint');\n tracker.trackMidpoint();\n });\n\n adUnit.on('AdVideoThirdQuartile', function () {\n player.trigger('vpaid.AdVideoThirdQuartile');\n tracker.trackThirdQuartile();\n });\n\n adUnit.on('AdVideoComplete', function () {\n player.trigger('vpaid.AdVideoComplete');\n tracker.trackComplete();\n });\n\n adUnit.on('AdClickThru', function (data) {\n player.trigger('vpaid.AdClickThru');\n var url = data.url;\n var playerHandles = data.playerHandles;\n var clickThruUrl = utilities.isNotEmptyString(url) ? url : generateClickThroughURL(vastResponse.clickThrough);\n\n tracker.trackClick();\n if (playerHandles && clickThruUrl) {\n window.open(clickThruUrl, '_blank');\n }\n\n function generateClickThroughURL(clickThroughMacro) {\n var variables = {\n ASSETURI: adUnit.options.src,\n CONTENTPLAYHEAD: 0 //In VPAID there is no method to know the current time from the adUnit\n };\n\n return clickThroughMacro ? vastUtil.parseURLMacro(clickThroughMacro, variables) : null;\n }\n });\n\n adUnit.on('AdUserAcceptInvitation', function () {\n player.trigger('vpaid.AdUserAcceptInvitation');\n tracker.trackAcceptInvitation();\n tracker.trackAcceptInvitationLinear();\n });\n\n adUnit.on('AdUserClose', function () {\n player.trigger('vpaid.AdUserClose');\n tracker.trackClose();\n tracker.trackCloseLinear();\n });\n\n adUnit.on('AdUserMinimize', function () {\n player.trigger('vpaid.AdUserMinimize');\n tracker.trackCollapse();\n });\n\n adUnit.on('AdError', function () {\n player.trigger('vpaid.AdError');\n //NOTE: we track errors code 901, as noted in VAST 3.0\n tracker.trackErrorWithCode(901);\n });\n\n adUnit.on('AdVolumeChange', function () {\n player.trigger('vpaid.AdVolumeChange');\n var lastVolume = player.volume();\n adUnit.getAdVolume(function (error, currentVolume) {\n if (currentVolume === 0 && lastVolume > 0) {\n tracker.trackMute();\n }\n\n if (currentVolume > 0 && lastVolume === 0) {\n tracker.trackUnmute();\n }\n\n player.volume(currentVolume);\n });\n });\n\n var updateViewSize = resizeAd.bind(this, player, adUnit, this.VIEW_MODE);\n var updateViewSizeThrottled = utilities.throttle(updateViewSize, 100);\n var autoResize = this.settings.autoResize;\n\n if (autoResize) {\n dom.addEventListener(window, 'resize', updateViewSizeThrottled);\n dom.addEventListener(window, 'orientationchange', updateViewSizeThrottled);\n }\n\n player.on('vast.resize', updateViewSize);\n player.on('vpaid.pauseAd', pauseAdUnit);\n player.on('vpaid.resumeAd', resumeAdUnit);\n\n player.one('vpaid.adEnd', function () {\n player.off('vast.resize', updateViewSize);\n player.off('vpaid.pauseAd', pauseAdUnit);\n player.off('vpaid.resumeAd', resumeAdUnit);\n\n if (autoResize) {\n dom.removeEventListener(window, 'resize', updateViewSizeThrottled);\n dom.removeEventListener(window, 'orientationchange', updateViewSizeThrottled);\n }\n });\n\n next(null, adUnit, vastResponse);\n\n /*** Local Functions ***/\n function pauseAdUnit() {\n adUnit.pauseAd(utilities.noop);\n }\n\n function resumeAdUnit() {\n adUnit.resumeAd(utilities.noop);\n }\n};\n\nVPAIDIntegrator.prototype._addSkipButton = function (adUnit, vastResponse, next) {\n var skipButton;\n var player = this.player;\n\n adUnit.on('AdSkippableStateChange', updateSkipButtonState);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeSkipButton);\n\n next(null, adUnit, vastResponse);\n\n /*** Local function ***/\n function updateSkipButtonState() {\n player.trigger('vpaid.AdSkippableStateChange');\n adUnit.getAdSkippableState(function (error, isSkippable) {\n if (isSkippable) {\n if (!skipButton) {\n addSkipButton(player);\n }\n } else {\n removeSkipButton(player);\n }\n });\n }\n\n function addSkipButton(player) {\n skipButton = createSkipButton(player);\n player.el().appendChild(skipButton);\n }\n\n function removeSkipButton() {\n dom.remove(skipButton);\n skipButton = null;\n }\n\n function createSkipButton() {\n var skipButton = window.document.createElement(\"div\");\n dom.addClass(skipButton, \"vast-skip-button\");\n dom.addClass(skipButton, \"enabled\");\n skipButton.innerHTML = \"Skip ad\";\n\n skipButton.onclick = function (e) {\n adUnit.skipAd(utilities.noop);//We skip the adUnit\n\n //We prevent event propagation to avoid problems with the clickThrough and so on\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n } else {\n return false;\n }\n };\n\n return skipButton;\n }\n};\n\nVPAIDIntegrator.prototype._linkPlayerControls = function (adUnit, vastResponse, next) {\n var that = this;\n linkVolumeControl(this.player, adUnit);\n linkFullScreenControl(this.player, adUnit, this.VIEW_MODE);\n\n next(null, adUnit, vastResponse);\n\n /*** Local functions ***/\n function linkVolumeControl(player, adUnit) {\n player.on('volumechange', updateAdUnitVolume);\n adUnit.on('AdVolumeChange', updatePlayerVolume);\n\n player.one('vpaid.adEnd', function () {\n player.off('volumechange', updateAdUnitVolume);\n });\n\n\n /*** local functions ***/\n function updateAdUnitVolume() {\n var vol = player.muted() ? 0 : player.volume();\n adUnit.setAdVolume(vol, logError);\n }\n\n function updatePlayerVolume() {\n player.trigger('vpaid.AdVolumeChange');\n adUnit.getAdVolume(function (error, vol) {\n if (error) {\n logError(error);\n } else {\n player.volume(vol);\n }\n });\n }\n }\n\n function linkFullScreenControl(player, adUnit, VIEW_MODE) {\n var updateViewSize = resizeAd.bind(that, player, adUnit, VIEW_MODE);\n\n player.on('fullscreenchange', updateViewSize);\n\n player.one('vpaid.adEnd', function () {\n player.off('fullscreenchange', updateViewSize);\n });\n }\n};\n\nVPAIDIntegrator.prototype._startAd = function (adUnit, vastResponse, next) {\n var player = this.player;\n\n adUnit.startAd(function (error) {\n if (!error) {\n player.trigger('vast.adStart');\n }\n next(error, adUnit, vastResponse);\n });\n};\n\nVPAIDIntegrator.prototype._finishPlaying = function (adUnit, vastResponse, next) {\n var player = this.player;\n adUnit.on('AdStopped', function () {\n player.trigger('vpaid.AdStopped');\n finishPlayingAd(null);\n });\n\n adUnit.on('AdError', function (error) {\n var errMsg = error? error.message : 'on VPAIDIntegrator, error while waiting for the adUnit to finish playing';\n finishPlayingAd(new VASTError(errMsg));\n });\n\n /*** local functions ***/\n function finishPlayingAd(error) {\n next(error, adUnit, vastResponse);\n }\n};\n\nVPAIDIntegrator.prototype._trackError = function trackError(response, errorCode) {\n vastUtil.track(response.errorURLMacros, {ERRORCODE: errorCode || 901});\n};\n\nfunction resizeAd(player, adUnit, VIEW_MODE) {\n var tech = player.el().querySelector('.vjs-tech');\n var dimension = dom.getDimension(tech);\n var MODE = player.isFullscreen() ? VIEW_MODE.FULLSCREEN : VIEW_MODE.NORMAL;\n adUnit.resizeAd(dimension.width, dimension.height, MODE, logError);\n}\n\nfunction logError(error) {\n if (error && console && console.log) {\n console.log('ERROR: ' + error.message, error);\n }\n}\n\nmodule.exports = VPAIDIntegrator;\n},{\"../../utils/async\":40,\"../../utils/dom\":41,\"../../utils/playerUtils\":43,\"../../utils/utilityFunctions\":45,\"../vast/VASTError\":23,\"../vast/VASTResponse\":25,\"../vast/VASTTracker\":26,\"../vast/vastUtil\":30,\"./VPAIDAdUnitWrapper\":31}],35:[function(require,module,exports){\n'use strict';\n\nvar dom = require('../../utils/dom');\n\nvar element = document.createElement('div');\nelement.className = 'vjs-ads-label vjs-control vjs-label-hidden';\nelement.innerHTML = 'Advertisement';\n\nvar AdsLabelFactory = function(baseComponent) {\n return {\n /** @constructor */\n init: function init(player, options) {\n options.el = element;\n baseComponent.call(this, player, options);\n\n // We asynchronously reposition the ads label element\n setTimeout(function () {\n var currentTimeComp = player.controlBar &&( player.controlBar.getChild(\"timerControls\") || player.controlBar.getChild(\"currentTimeDisplay\") );\n if(currentTimeComp) {\n player.controlBar.el().insertBefore(element, currentTimeComp.el());\n }\n dom.removeClass(element, 'vjs-label-hidden');\n }, 0);\n },\n\n el: function getElement() {\n return element;\n }\n };\n};\n\nmodule.exports = AdsLabelFactory;\n},{\"../../utils/dom\":41}],36:[function(require,module,exports){\n'use strict';\n\nvar baseVideoJsComponent = videojs.getComponent('Component');\n\nvar AdsLabel = require('./ads-label')(baseVideoJsComponent);\n\nvideojs.registerComponent('AdsLabel', videojs.extend(baseVideoJsComponent, AdsLabel));\n\n},{\"./ads-label\":35}],37:[function(require,module,exports){\n'use strict';\n\n/**\n * The component that shows a black screen until the ads plugin has decided if it can or it can not play the ad.\n *\n * Note: In case you wonder why instead of this black poster we don't just show the spinner loader.\n * IOS devices do not work well with animations and the browser chrashes from time to time That is why we chose to\n * have a secondary black poster.\n *\n * It also makes it much more easier for the users of the plugin since it does not change the default behaviour of the\n * spinner and the player works the same way with and without the plugin.\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvar element = document.createElement('div');\n\nvar BlackPosterFactory = function(baseComponent) {\n return {\n /** @constructor */\n init: function init(player, options) {\n options.el = element;\n element.className = 'vjs-black-poster';\n baseComponent.call(this, player, options);\n\n var posterImg = player.getChild('posterImage');\n\n //We need to do it asynchronously to be sure that the black poster el is on the dom.\n setTimeout(function() {\n if(posterImg && player && player.el()) {\n player.el().insertBefore(element, posterImg.el());\n }\n }, 0);\n },\n el: function getElement() {\n return element;\n }\n };\n};\n\nmodule.exports = BlackPosterFactory;\n},{}],38:[function(require,module,exports){\n'use strict';\n\nvar baseVideoJsComponent = videojs.getComponent('Component');\n\nvar BlackPoster = require('./black-poster')(baseVideoJsComponent);\n\nvideojs.registerComponent('BlackPoster', videojs.extend(baseVideoJsComponent, BlackPoster));\n\n},{\"./black-poster\":37}],39:[function(require,module,exports){\n'use strict';\n\nvar VASTClient = require('../ads/vast/VASTClient');\nvar VASTError = require('../ads/vast/VASTError');\nvar vastUtil = require('../ads/vast/vastUtil');\n\nvar VASTIntegrator = require('../ads/vast/VASTIntegrator');\nvar VPAIDIntegrator = require('../ads/vpaid/VPAIDIntegrator');\n\nvar async = require('../utils/async');\nvar dom = require('../utils/dom');\nvar playerUtils = require('../utils/playerUtils');\nvar utilities = require('../utils/utilityFunctions');\n\nmodule.exports = function VASTPlugin(options) {\n var snapshot;\n var player = this;\n var vast = new VASTClient();\n var adsCanceled = false;\n var defaultOpts = {\n // maximum amount of time in ms to wait to receive `adsready` from the ad\n // implementation after play has been requested. Ad implementations are\n // expected to load any dynamic libraries and make any requests to determine\n // ad policies for a video during this time.\n timeout: 500,\n\n //TODO:finish this IOS FIX\n //Whenever you play an add on IOS, the native player kicks in and we loose control of it. On very heavy pages the 'play' event\n // May occur after the video content has already started. This is wrong if you want to play a preroll ad that needs to happen before the user\n // starts watching the content. To prevent this usec\n iosPrerollCancelTimeout: 2000,\n\n // maximun amount of time for the ad to actually start playing. If this timeout gets\n // triggered the ads will be cancelled\n adCancelTimeout: 3000,\n\n // Boolean flag that configures the player to play a new ad before the user sees the video again\n // the current video\n playAdAlways: false,\n\n // Flag to enable or disable the ads by default.\n adsEnabled: true,\n\n // Boolean flag to enable or disable the resize with window.resize or orientationchange\n autoResize: true,\n\n // Path to the VPAID flash ad's loader\n vpaidFlashLoaderPath: '/VPAIDFlash.swf'\n };\n\n var settings = utilities.extend({}, defaultOpts, options || {});\n\n if(utilities.isUndefined(settings.adTagUrl) && utilities.isDefined(settings.url)){\n settings.adTagUrl = settings.url;\n }\n\n if (utilities.isString(settings.adTagUrl)) {\n settings.adTagUrl = utilities.echoFn(settings.adTagUrl);\n }\n\n if (utilities.isDefined(settings.adTagXML) && !utilities.isFunction(settings.adTagXML)) {\n return trackAdError(new VASTError('on VideoJS VAST plugin, the passed adTagXML option does not contain a function'));\n }\n\n if (!utilities.isDefined(settings.adTagUrl) && !utilities.isFunction(settings.adTagXML)) {\n return trackAdError(new VASTError('on VideoJS VAST plugin, missing adTagUrl on options object'));\n }\n\n vastUtil.runFlashSupportCheck(settings.vpaidFlashLoaderPath);// Necessary step for VPAIDFLASHClient to work.\n\n playerUtils.prepareForAds(player);\n\n if (settings.playAdAlways) {\n // No matter what happens we play a new ad before the user sees the video again.\n player.on('vast.contentEnd', function () {\n setTimeout(function () {\n player.trigger('vast.reset');\n }, 0);\n });\n }\n\n player.on('vast.firstPlay', tryToPlayPrerollAd);\n\n player.on('vast.reset', function () {\n //If we are reseting the plugin, we don't want to restore the content\n snapshot = null;\n cancelAds();\n });\n\n player.vast = {\n isEnabled: function () {\n return settings.adsEnabled;\n },\n\n enable: function () {\n settings.adsEnabled = true;\n },\n\n disable: function () {\n settings.adsEnabled = false;\n }\n };\n\n return player.vast;\n\n /**** Local functions ****/\n function tryToPlayPrerollAd() {\n //We remove the poster to prevent flickering whenever the content starts playing\n playerUtils.removeNativePoster(player);\n\n playerUtils.once(player, ['vast.adsCancel', 'vast.adEnd'], function () {\n removeAdUnit();\n restoreVideoContent();\n });\n\n async.waterfall([\n checkAdsEnabled,\n preparePlayerForAd,\n startAdCancelTimeout,\n playPrerollAd\n ], function (error, response) {\n if (error) {\n trackAdError(error, response);\n } else {\n player.trigger('vast.adEnd');\n }\n });\n\n /*** Local functions ***/\n\n function removeAdUnit() {\n if (player.vast && player.vast.adUnit) {\n player.vast.adUnit = null; //We remove the adUnit\n }\n }\n\n function restoreVideoContent() {\n setupContentEvents();\n if (snapshot) {\n playerUtils.restorePlayerSnapshot(player, snapshot);\n snapshot = null;\n }\n }\n\n function setupContentEvents() {\n playerUtils.once(player, ['playing', 'vast.reset', 'vast.firstPlay'], function (evt) {\n if (evt.type !== 'playing') {\n return;\n }\n\n player.trigger('vast.contentStart');\n\n playerUtils.once(player, ['ended', 'vast.reset', 'vast.firstPlay'], function (evt) {\n if (evt.type === 'ended') {\n player.trigger('vast.contentEnd');\n }\n });\n });\n }\n\n function checkAdsEnabled(next) {\n if (settings.adsEnabled) {\n return next(null);\n }\n next(new VASTError('Ads are not enabled'));\n }\n\n function preparePlayerForAd(next) {\n if (canPlayPrerollAd()) {\n snapshot = playerUtils.getPlayerSnapshot(player);\n player.pause();\n addSpinnerIcon();\n\n if(player.paused()) {\n next(null);\n } else {\n playerUtils.once(player, ['playing'], function() {\n player.pause();\n next(null);\n });\n }\n } else {\n next(new VASTError('video content has been playing before preroll ad'));\n }\n }\n\n function canPlayPrerollAd() {\n return !utilities.isIPhone() || player.currentTime() <= settings.iosPrerollCancelTimeout;\n }\n\n function startAdCancelTimeout(next) {\n var adCancelTimeoutId;\n adsCanceled = false;\n\n adCancelTimeoutId = setTimeout(function () {\n trackAdError(new VASTError('timeout while waiting for the video to start playing', 402));\n }, settings.adCancelTimeout);\n\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], clearAdCancelTimeout);\n\n /*** local functions ***/\n function clearAdCancelTimeout() {\n if (adCancelTimeoutId) {\n clearTimeout(adCancelTimeoutId);\n adCancelTimeoutId = null;\n }\n }\n\n next(null);\n }\n\n function addSpinnerIcon() {\n dom.addClass(player.el(), 'vjs-vast-ad-loading');\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], removeSpinnerIcon);\n }\n\n function removeSpinnerIcon() {\n //IMPORTANT NOTE: We remove the spinnerIcon asynchronously to give time to the browser to start the video.\n // If we remove it synchronously we see a flash of the content video before the ad starts playing.\n setTimeout(function () {\n dom.removeClass(player.el(), 'vjs-vast-ad-loading');\n }, 100);\n }\n\n }\n\n function cancelAds() {\n player.trigger('vast.adsCancel');\n adsCanceled = true;\n }\n\n function playPrerollAd(callback) {\n async.waterfall([\n getVastResponse,\n playAd\n ], callback);\n }\n\n function getVastResponse(callback) {\n vast.getVASTResponse(settings.adTagUrl ? settings.adTagUrl() : settings.adTagXML, callback);\n }\n\n function playAd(vastResponse, callback) {\n //TODO: Find a better way to stop the play. The 'playPrerollWaterfall' ends in an inconsistent situation\n //If the state is not 'preroll?' it means the ads were canceled therefore, we break the waterfall\n if (adsCanceled) {\n return;\n }\n\n var adIntegrator = isVPAID(vastResponse) ? new VPAIDIntegrator(player, settings) : new VASTIntegrator(player);\n var adFinished = false;\n\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], function (evt) {\n if (evt.type === 'vast.adStart') {\n addAdsLabel();\n }\n });\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeAdsLabel);\n\n if (utilities.isIDevice()) {\n preventManualProgress();\n }\n\n player.vast.vastResponse = vastResponse;\n player.vast.adUnit = adIntegrator.playAd(vastResponse, callback);\n\n /*** Local functions ****/\n function addAdsLabel() {\n if (adFinished || player.controlBar.getChild('AdsLabel')) {\n return;\n }\n\n player.controlBar.addChild('AdsLabel');\n }\n\n function removeAdsLabel() {\n player.controlBar.removeChild('AdsLabel');\n adFinished = true;\n }\n\n function preventManualProgress() {\n //IOS video clock is very unreliable and we need a 3 seconds threshold to ensure that the user forwarded/rewound the ad\n var PROGRESS_THRESHOLD = 3;\n var previousTime = 0;\n var skipad_attempts = 0;\n\n player.on('timeupdate', preventAdSeek);\n player.on('ended', preventAdSkip);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel', 'vast.adError'], stopPreventManualProgress);\n\n /*** Local functions ***/\n function preventAdSkip() {\n // Ignore ended event if the Ad time was not 'near' the end\n // and revert time to the previous 'valid' time\n if ((player.duration() - previousTime) > PROGRESS_THRESHOLD) {\n player.pause(true); // this reduce the video jitter if the IOS skip button is pressed\n player.play(true); // we need to trigger the play to put the video element back in a valid state\n player.currentTime(previousTime);\n }\n }\n\n function preventAdSeek() {\n var currentTime = player.currentTime();\n var progressDelta = Math.abs(currentTime - previousTime);\n if (progressDelta > PROGRESS_THRESHOLD) {\n skipad_attempts += 1;\n if (skipad_attempts >= 2) {\n player.pause(true);\n }\n player.currentTime(previousTime);\n } else {\n previousTime = currentTime;\n }\n }\n\n function stopPreventManualProgress() {\n player.off('timeupdate', preventAdSeek);\n player.off('ended', preventAdSkip);\n }\n }\n }\n\n function trackAdError(error, vastResponse) {\n player.trigger({type: 'vast.adError', error: error});\n cancelAds();\n if (console && console.log) {\n console.log('AD ERROR:', error.message, error, vastResponse);\n }\n }\n\n function isVPAID(vastResponse) {\n var i, len;\n var mediaFiles = vastResponse.mediaFiles;\n for (i = 0, len = mediaFiles.length; i < len; i++) {\n if (vastUtil.isVPAID(mediaFiles[i])) {\n return true;\n }\n }\n return false;\n }\n};\n\n},{\"../ads/vast/VASTClient\":22,\"../ads/vast/VASTError\":23,\"../ads/vast/VASTIntegrator\":24,\"../ads/vast/vastUtil\":30,\"../ads/vpaid/VPAIDIntegrator\":34,\"../utils/async\":40,\"../utils/dom\":41,\"../utils/playerUtils\":43,\"../utils/utilityFunctions\":45}],40:[function(require,module,exports){\n//Small subset of async\n\nvar utilities = require('./utilityFunctions');\n\nvar async = {};\n\nasync.setImmediate = function (fn) {\n setTimeout(fn, 0);\n};\n\nasync.iterator = function (tasks) {\n var makeCallback = function (index) {\n var fn = function () {\n if (tasks.length) {\n tasks[index].apply(null, arguments);\n }\n return fn.next();\n };\n fn.next = function () {\n return (index < tasks.length - 1) ? makeCallback(index + 1) : null;\n };\n return fn;\n };\n return makeCallback(0);\n};\n\n\nasync.waterfall = function (tasks, callback) {\n callback = callback || function () { };\n if (!utilities.isArray(tasks)) {\n var err = new Error('First argument to waterfall must be an array of functions');\n return callback(err);\n }\n if (!tasks.length) {\n return callback();\n }\n var wrapIterator = function (iterator) {\n return function (err) {\n if (err) {\n callback.apply(null, arguments);\n callback = function () {\n };\n }\n else {\n var args = Array.prototype.slice.call(arguments, 1);\n var next = iterator.next();\n if (next) {\n args.push(wrapIterator(next));\n }\n else {\n args.push(callback);\n }\n async.setImmediate(function () {\n iterator.apply(null, args);\n });\n }\n };\n };\n wrapIterator(async.iterator(tasks))();\n};\n\nasync.when = function (condition, callback) {\n if (!utilities.isFunction(callback)) {\n throw new Error(\"async.when error: missing callback argument\");\n }\n\n var isAllowed = utilities.isFunction(condition) ? condition : function () {\n return !!condition;\n };\n\n return function () {\n var args = utilities.arrayLikeObjToArray(arguments);\n var next = args.pop();\n\n if (isAllowed.apply(null, args)) {\n return callback.apply(this, arguments);\n }\n\n args.unshift(null);\n return next.apply(null, args);\n };\n};\n\nmodule.exports = async;\n\n\n},{\"./utilityFunctions\":45}],41:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('./utilityFunctions');\n\nvar dom = {};\n\ndom.isVisible = function isVisible(el) {\n var style = window.getComputedStyle(el);\n return style.visibility !== 'hidden';\n};\n\ndom.isHidden = function isHidden(el) {\n var style = window.getComputedStyle(el);\n return style.display === 'none';\n};\n\ndom.isShown = function isShown(el) {\n return !dom.isHidden(el);\n};\n\ndom.hide = function hide(el) {\n el.__prev_style_display_ = el.style.display;\n el.style.display = 'none';\n};\n\ndom.show = function show(el) {\n if (dom.isHidden(el)) {\n el.style.display = el.__prev_style_display_;\n }\n el.__prev_style_display_ = undefined;\n};\n\ndom.hasClass = function hasClass(el, cssClass) {\n var classes, i, len;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.contains(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n cssClass = (cssClass || '');\n\n for (i = 0, len = classes.length; i < len; i += 1) {\n if (classes[i] === cssClass) {\n return true;\n }\n }\n }\n return false;\n};\n\ndom.addClass = function (el, cssClass) {\n var classes;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.add(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n if (utilities.isString(cssClass) && utilities.isNotEmptyString(cssClass.replace(/\\s+/, ''))) {\n classes.push(cssClass);\n el.setAttribute('class', classes.join(' '));\n }\n }\n};\n\ndom.removeClass = function (el, cssClass) {\n var classes;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.remove(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n var newClasses = [];\n var i, len;\n if (utilities.isString(cssClass) && utilities.isNotEmptyString(cssClass.replace(/\\s+/, ''))) {\n\n for (i = 0, len = classes.length; i < len; i += 1) {\n if (cssClass !== classes[i]) {\n newClasses.push(classes[i]);\n }\n }\n el.setAttribute('class', newClasses.join(' '));\n }\n }\n};\n\ndom.addEventListener = function addEventListener(el, type, handler) {\n if(utilities.isArray(el)){\n utilities.forEach(el, function(e) {\n dom.addEventListener(e, type, handler);\n });\n return;\n }\n\n if(utilities.isArray(type)){\n utilities.forEach(type, function(t) {\n dom.addEventListener(el, t, handler);\n });\n return;\n }\n\n if (el.addEventListener) {\n el.addEventListener(type, handler, false);\n } else if (el.attachEvent) {\n // WARNING!!! this is a very naive implementation !\n // the event object that should be passed to the handler\n // would not be there for IE8\n // we should use \"window.event\" and then \"event.srcElement\"\n // instead of \"event.target\"\n el.attachEvent(\"on\" + type, handler);\n }\n};\n\ndom.removeEventListener = function removeEventListener(el, type, handler) {\n if(utilities.isArray(el)){\n utilities.forEach(el, function(e) {\n dom.removeEventListener(e, type, handler);\n });\n return;\n }\n\n if(utilities.isArray(type)){\n utilities.forEach(type, function(t) {\n dom.removeEventListener(el, t, handler);\n });\n return;\n }\n\n if (el.removeEventListener) {\n el.removeEventListener(type, handler, false);\n } else if (el.detachEvent) {\n el.detachEvent(\"on\" + type, handler);\n } else {\n el[\"on\" + type] = null;\n }\n};\n\ndom.dispatchEvent = function dispatchEvent(el, event) {\n if (el.dispatchEvent) {\n el.dispatchEvent(event);\n } else {\n el.fireEvent(\"on\" + event.eventType, event);\n }\n};\n\ndom.isDescendant = function isDescendant(parent, child) {\n var node = child.parentNode;\n while (node !== null) {\n if (node === parent) {\n return true;\n }\n node = node.parentNode;\n }\n return false;\n};\n\ndom.getTextContent = function getTextContent(el){\n return el.textContent || el.text;\n};\n\ndom.prependChild = function prependChild(parent, child) {\n if(child.parentNode){\n child.parentNode.removeChild(child);\n }\n return parent.insertBefore(child, parent.firstChild);\n};\n\ndom.remove = function removeNode(node){\n if(node && node.parentNode){\n node.parentNode.removeChild(node);\n }\n};\n\ndom.isDomElement = function isDomElement(o) {\n return o instanceof Element;\n};\n\ndom.click = function(el, handler) {\n dom.addEventListener(el, 'click', handler);\n};\n\ndom.once = function(el, type, handler) {\n function handlerWrap() {\n handler.apply(null, arguments);\n dom.removeEventListener(el, type, handlerWrap);\n }\n\n dom.addEventListener(el, type, handlerWrap);\n};\n\n//Note: there is no getBoundingClientRect on iPad so we need a fallback\ndom.getDimension = function getDimension(element) {\n var rect;\n\n //On IE9 and below getBoundingClientRect does not work consistently\n if(!utilities.isOldIE() && element.getBoundingClientRect) {\n rect = element.getBoundingClientRect();\n return {\n width: rect.width,\n height: rect.height\n };\n }\n\n return {\n width: element.offsetWidth,\n height: element.offsetHeight\n };\n};\n\nmodule.exports = dom;\n},{\"./utilityFunctions\":45}],42:[function(require,module,exports){\n'use strict';\n\nvar urlUtils = require('./urlUtils');\nvar utilities = require('./utilityFunctions');\n\nfunction HttpRequestError(message) {\n this.message = 'HttpRequest Error: ' + (message || '');\n}\nHttpRequestError.prototype = new Error();\nHttpRequestError.prototype.name = \"HttpRequest Error\";\n\nfunction HttpRequest(createXhr) {\n if (!utilities.isFunction(createXhr)) {\n throw new HttpRequestError('Missing XMLHttpRequest factory method');\n }\n\n this.createXhr = createXhr;\n}\n\nHttpRequest.prototype.run = function (method, url, callback, options) {\n sanityCheck(url, callback, options);\n var timeout, timeoutId;\n var xhr = this.createXhr();\n options = options || {};\n timeout = utilities.isNumber(options.timeout) ? options.timeout : 0;\n\n xhr.open(method, urlUtils.urlParts(url).href, true);\n\n if (options.headers) {\n setHeaders(xhr, options.headers);\n }\n\n if (options.withCredentials) {\n xhr.withCredentials = true;\n }\n\n xhr.onload = function () {\n var statusText, response, status;\n\n /**\n * The only way to do a secure request on IE8 and IE9 is with the XDomainRequest object. Unfortunately, microsoft is\n * so nice that decided that the status property and the 'getAllResponseHeaders' method where not needed so we have to\n * fake them. If the request gets done with an XDomainRequest instance, we will assume that there are no headers and\n * the status will always be 200. If you don't like it, DO NOT USE ANCIENT BROWSERS!!!\n *\n * For mor info go to: https://msdn.microsoft.com/en-us/library/cc288060(v=vs.85).aspx\n */\n if (!xhr.getAllResponseHeaders) {\n xhr.getAllResponseHeaders = function () {\n return null;\n };\n }\n\n if (!xhr.status) {\n xhr.status = 200;\n }\n\n if (utilities.isDefined(timeoutId)) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n\n statusText = xhr.statusText || '';\n\n // responseText is the old-school way of retrieving response (supported by IE8 & 9)\n // response/responseType properties were introduced in XHR Level2 spec (supported by IE10)\n response = ('response' in xhr) ? xhr.response : xhr.responseText;\n\n // normalize IE9 bug (http://bugs.jquery.com/ticket/1450)\n status = xhr.status === 1223 ? 204 : xhr.status;\n\n callback(\n status,\n response,\n xhr.getAllResponseHeaders(),\n statusText);\n };\n\n xhr.onerror = requestError;\n xhr.onabort = requestError;\n\n xhr.send();\n\n if (timeout > 0) {\n timeoutId = setTimeout(function () {\n xhr && xhr.abort();\n }, timeout);\n }\n\n function sanityCheck(url, callback, options) {\n if (!utilities.isString(url) || utilities.isEmptyString(url)) {\n throw new HttpRequestError(\"Invalid url '\" + url + \"'\");\n }\n\n if (!utilities.isFunction(callback)) {\n throw new HttpRequestError(\"Invalid handler '\" + callback + \"' for the http request\");\n }\n\n if (utilities.isDefined(options) && !utilities.isObject(options)) {\n throw new HttpRequestError(\"Invalid options map '\" + options + \"'\");\n }\n }\n\n function setHeaders(xhr, headers) {\n utilities.forEach(headers, function (value, key) {\n if (utilities.isDefined(value)) {\n xhr.setRequestHeader(key, value);\n }\n });\n }\n\n function requestError() {\n callback(-1, null, null, '');\n }\n};\n\nHttpRequest.prototype.get = function (url, callback, options) {\n this.run('GET', url, processResponse, options);\n\n function processResponse(status, response, headersString, statusText) {\n if (isSuccess(status)) {\n callback(null, response, status, headersString, statusText);\n } else {\n callback(new HttpRequestError(statusText), response, status, headersString, statusText);\n }\n }\n\n function isSuccess(status) {\n return 200 <= status && status < 300;\n }\n};\n\nfunction createXhr() {\n var xhr = new XMLHttpRequest();\n if (!(\"withCredentials\" in xhr)) {\n // XDomainRequest for IE.\n xhr = new XDomainRequest();\n }\n return xhr;\n}\n\nvar http = new HttpRequest(createXhr);\n\nmodule.exports = {\n http: http,\n HttpRequest: HttpRequest,\n HttpRequestError: HttpRequestError,\n createXhr: createXhr\n};\n\n},{\"./urlUtils\":44,\"./utilityFunctions\":45}],43:[function(require,module,exports){\n'use strict';\n\nvar dom = require('./dom');\nvar utilities = require('./utilityFunctions');\n\nvar playerUtils = {};\n\n/**\n * Returns an object that captures the portions of player state relevant to\n * video playback. The result of this function can be passed to\n * restorePlayerSnapshot with a player to return the player to the state it\n * was in when this function was invoked.\n * @param {object} player The videojs player object\n */\nplayerUtils.getPlayerSnapshot = function getPlayerSnapshot(player) {\n var tech = player.el().querySelector('.vjs-tech');\n\n var snapshot = {\n ended: player.ended(),\n src: player.currentSrc(),\n currentTime: player.currentTime(),\n type: player.currentType(),\n playing: !player.paused(),\n suppressedTracks: getSuppressedTracks(player)\n };\n\n if (tech) {\n snapshot.nativePoster = tech.poster;\n snapshot.style = tech.getAttribute('style');\n }\n return snapshot;\n\n /**** Local Functions ****/\n function getSuppressedTracks(player) {\n var tracks = player.remoteTextTracks ? player.remoteTextTracks() : [];\n\n if (tracks && utilities.isArray(tracks.tracks_)) {\n tracks = tracks.tracks_;\n }\n\n if (!utilities.isArray(tracks)) {\n tracks = [];\n }\n\n var suppressedTracks = [];\n tracks.forEach(function (track) {\n suppressedTracks.push({\n track: track,\n mode: track.mode\n });\n track.mode = 'disabled';\n });\n\n return suppressedTracks;\n }\n};\n\n/**\n * Attempts to modify the specified player so that its state is equivalent to\n * the state of the snapshot.\n * @param {object} snapshot - the player state to apply\n */\nplayerUtils.restorePlayerSnapshot = function restorePlayerSnapshot(player, snapshot) {\n var tech = player.el().querySelector('.vjs-tech');\n var attempts = 20; // the number of remaining attempts to restore the snapshot\n\n if (snapshot.nativePoster) {\n tech.poster = snapshot.nativePoster;\n }\n\n if ('style' in snapshot) {\n // overwrite all css style properties to restore state precisely\n tech.setAttribute('style', snapshot.style || '');\n }\n\n if (hasSrcChanged(player, snapshot)) {\n\n // on ios7, fiddling with textTracks too early will cause safari to crash\n player.one('contentloadedmetadata', restoreTracks);\n\n player.one('canplay', tryToResume);\n ensureCanplayEvtGetsFired();\n\n // if the src changed for ad playback, reset it\n player.src({src: snapshot.src, type: snapshot.type});\n\n // safari requires a call to `load` to pick up a changed source\n player.load();\n\n } else {\n restoreTracks();\n\n if (snapshot.playing) {\n player.play();\n }\n }\n\n /*** Local Functions ***/\n\n /**\n * Sometimes firefox does not trigger the 'canplay' evt.\n * This code ensure that it always gets triggered triggered.\n */\n function ensureCanplayEvtGetsFired() {\n var timeoutId = setTimeout(function() {\n player.trigger('canplay');\n }, 1000);\n\n player.one('canplay', function(){\n clearTimeout(timeoutId);\n });\n }\n\n /**\n * Determine whether the player needs to be restored to its state\n * before ad playback began. With a custom ad display or burned-in\n * ads, the content player state hasn't been modified and so no\n * restoration is required\n */\n function hasSrcChanged(player, snapshot) {\n if (player.src()) {\n return player.src() !== snapshot.src;\n }\n // the player was configured through source element children\n return player.currentSrc() !== snapshot.src;\n }\n\n function restoreTracks() {\n var suppressedTracks = snapshot.suppressedTracks;\n suppressedTracks.forEach(function (trackSnapshot) {\n trackSnapshot.track.mode = trackSnapshot.mode;\n });\n }\n\n /**\n * Determine if the video element has loaded enough of the snapshot source\n * to be ready to apply the rest of the state\n */\n function tryToResume() {\n\n // if some period of the video is seekable, resume playback\n // otherwise delay a bit and then check again unless we're out of attempts\n\n if (!playerUtils.isReadyToResume(player) && attempts--) {\n setTimeout(tryToResume, 50);\n } else {\n try {\n if(player.currentTime() !== snapshot.currentTime) {\n if (snapshot.playing) { // if needed restore playing status after seek completes\n player.one('seeked', function() {\n player.play();\n });\n }\n player.currentTime(snapshot.currentTime);\n\n } else if (snapshot.playing) {\n // if needed and no seek has been performed, restore playing status immediately\n player.play();\n }\n\n } catch (e) {\n videojs.log.warn('Failed to resume the content after an advertisement', e);\n }\n }\n }\n};\n\nplayerUtils.isReadyToResume = function (player) {\n\n if (player.readyState() > 1) {\n // some browsers and media aren't \"seekable\".\n // readyState greater than 1 allows for seeking without exceptions\n return true;\n }\n\n if (player.seekable() === undefined) {\n // if the player doesn't expose the seekable time ranges, try to\n // resume playback immediately\n return true;\n }\n\n if (player.seekable().length > 0) {\n // if some period of the video is seekable, resume playback\n return true;\n }\n\n return false;\n};\n\n/**\n * This function prepares the player to display ads.\n * Adding convenience events like the 'vast.firsPlay' that gets fired when the video is first played\n * and ads the blackPoster to the player to prevent content from being displayed before the preroll ad.\n *\n * @param player\n */\nplayerUtils.prepareForAds = function (player) {\n var blackPoster = player.addChild('blackPoster');\n var _firstPlay = true;\n var volumeSnapshot;\n\n\n monkeyPatchPlayerApi();\n\n player.on('play', tryToTriggerFirstPlay);\n player.on('vast.reset', resetFirstPlay);//Every time we change the sources we reset the first play.\n player.on('vast.firstPlay', restoreContentVolume);\n player.on('error', hideBlackPoster);//If there is an error in the player we remove the blackposter to show the err msg\n player.on('vast.adStart', hideBlackPoster);\n player.on('vast.adsCancel', hideBlackPoster);\n player.on('vast.adError', hideBlackPoster);\n player.on('vast.adStart', addStyles);\n player.on('vast.adEnd', removeStyles);\n player.on('vast.adsCancel', removeStyles);\n\n /*** Local Functions ***/\n\n /**\n What this function does is ugly and horrible and I should think twice before calling myself a good developer. With that said,\n it is the best solution I could find to mute the video until the 'play' event happens (on mobile devices) and the plugin can decide whether\n to play the ad or not.\n\n We also need this monkeypatch to be able to pause and resume an ad using the player's API\n\n If you have a better solution please do tell me.\n */\n function monkeyPatchPlayerApi() {\n\n /**\n * Monkey patch needed to handle firstPlay and resume of playing ad.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are restoring a VAST ad.\n * @returns {player}\n */\n var origPlay = player.play;\n player.play = function (callOrigPlay) {\n var that = this;\n\n if (isFirstPlay()) {\n firstPlay();\n } else {\n resume(callOrigPlay);\n }\n\n return this;\n\n /*** local functions ***/\n function firstPlay() {\n if (!utilities.isIPhone()) {\n volumeSnapshot = saveVolumeSnapshot();\n player.muted(true);\n }\n\n origPlay.apply(that, arguments);\n }\n\n function resume(callOrigPlay) {\n if (isAdPlaying() && !callOrigPlay) {\n player.vast.adUnit.resumeAd();\n } else {\n origPlay.apply(that, arguments);\n }\n }\n };\n\n\n /**\n * Needed monkey patch to handle pause of playing ad.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are pausing a VAST ad.\n * @returns {player}\n */\n var origPause = player.pause;\n player.pause = function (callOrigPause) {\n if (isAdPlaying() && !callOrigPause) {\n player.vast.adUnit.pauseAd();\n } else {\n origPause.apply(this, arguments);\n }\n return this;\n };\n\n\n /**\n * Needed monkey patch to handle paused state of the player when ads are playing.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are pausing a VAST ad.\n * @returns {player}\n */\n var origPaused = player.paused;\n player.paused = function (callOrigPaused) {\n if (isAdPlaying() && !callOrigPaused) {\n return player.vast.adUnit.isPaused();\n }\n return origPaused.apply(this, arguments);\n };\n }\n\n function isAdPlaying() {\n return player.vast && player.vast.adUnit;\n }\n\n function tryToTriggerFirstPlay() {\n if (isFirstPlay()) {\n _firstPlay = false;\n player.trigger('vast.firstPlay');\n }\n }\n\n function resetFirstPlay() {\n _firstPlay = true;\n blackPoster.show();\n restoreContentVolume();\n }\n\n function isFirstPlay() {\n return _firstPlay;\n }\n\n function saveVolumeSnapshot() {\n return {\n muted: player.muted(),\n volume: player.volume()\n };\n }\n\n function restoreContentVolume() {\n if (volumeSnapshot) {\n player.currentTime(0);\n restoreVolumeSnapshot(volumeSnapshot);\n volumeSnapshot = null;\n }\n }\n\n function restoreVolumeSnapshot(snapshot) {\n if (utilities.isObject(snapshot)) {\n player.volume(snapshot.volume);\n player.muted(snapshot.muted);\n }\n }\n\n function hideBlackPoster() {\n if (!dom.hasClass(blackPoster.el(), 'vjs-hidden')) {\n blackPoster.hide();\n }\n }\n\n function addStyles() {\n dom.addClass(player.el(), 'vjs-ad-playing');\n }\n\n function removeStyles() {\n dom.removeClass(player.el(), 'vjs-ad-playing');\n }\n};\n\n/**\n * Remove the poster attribute from the video element tech, if present. When\n * reusing a video element for multiple videos, the poster image will briefly\n * reappear while the new source loads. Removing the attribute ahead of time\n * prevents the poster from showing up between videos.\n * @param {object} player The videojs player object\n */\nplayerUtils.removeNativePoster = function (player) {\n var tech = player.el().querySelector('.vjs-tech');\n if (tech) {\n tech.removeAttribute('poster');\n }\n};\n\n/**\n * Helper function to listen to many events until one of them gets fired, then we\n * execute the handler and unsubscribe all the event listeners;\n *\n * @param player specific player from where to listen for the events\n * @param events array of events\n * @param handler function to execute once one of the events fires\n */\nplayerUtils.once = function once(player, events, handler) {\n function listener() {\n handler.apply(null, arguments);\n\n events.forEach(function (event) {\n player.off(event, listener);\n });\n }\n\n events.forEach(function (event) {\n player.on(event, listener);\n });\n};\n\n\nmodule.exports = playerUtils;\n},{\"./dom\":41,\"./utilityFunctions\":45}],44:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('./utilityFunctions');\n\n/**\n *\n * IMPORTANT NOTE: This function comes from angularJs and was originally called urlResolve\n * you can take a look at the original code here https://github.com/angular/angular.js/blob/master/src/ng/urlUtils.js\n *\n * Implementation Notes for non-IE browsers\n * ----------------------------------------\n * Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM,\n * results both in the normalizing and parsing of the URL. Normalizing means that a relative\n * URL will be resolved into an absolute URL in the context of the application document.\n * Parsing means that the anchor node's host, hostname, protocol, port, pathname and related\n * properties are all populated to reflect the normalized URL. This approach has wide\n * compatibility - Safari 1+, Mozilla 1+, Opera 7+,e etc. See\n * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n *\n * Implementation Notes for IE\n * ---------------------------\n * IE >= 8 and <= 10 normalizes the URL when assigned to the anchor node similar to the other\n * browsers. However, the parsed components will not be set if the URL assigned did not specify\n * them. (e.g. if you assign a.href = \"foo\", then a.protocol, a.host, etc. will be empty.) We\n * work around that by performing the parsing in a 2nd step by taking a previously normalized\n * URL (e.g. by assigning to a.href) and assigning it a.href again. This correctly populates the\n * properties such as protocol, hostname, port, etc.\n *\n * IE7 does not normalize the URL when assigned to an anchor node. (Apparently, it does, if one\n * uses the inner HTML approach to assign the URL as part of an HTML snippet -\n * http://stackoverflow.com/a/472729) However, setting img[src] does normalize the URL.\n * Unfortunately, setting img[src] to something like \"javascript:foo\" on IE throws an exception.\n * Since the primary usage for normalizing URLs is to sanitize such URLs, we can't use that\n * method and IE < 8 is unsupported.\n *\n * References:\n * http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement\n * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n * http://url.spec.whatwg.org/#urlutils\n * https://github.com/angular/angular.js/pull/2902\n * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/\n *\n * @kind function\n * @param {string} url The URL to be parsed.\n * @description Normalizes and parses a URL.\n * @returns {object} Returns the normalized URL as a dictionary.\n *\n * | member name | Description |\n * |---------------|----------------|\n * | href | A normalized version of the provided URL if it was not an absolute URL |\n * | protocol | The protocol including the trailing colon |\n * | host | The host and port (if the port is non-default) of the normalizedUrl |\n * | search | The search params, minus the question mark |\n * | hash | The hash string, minus the hash symbol\n * | hostname | The hostname\n * | port | The port, without \":\"\n * | pathname | The pathname, beginning with \"/\"\n *\n */\n\nvar urlParsingNode = document.createElement(\"a\");\n/**\n * documentMode is an IE-only property\n * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx\n */\nvar msie = document.documentMode;\n\nfunction urlParts(url) {\n var href = url;\n\n if (msie) {\n // Normalize before parse. Refer Implementation Notes on why this is\n // done in two steps on IE.\n urlParsingNode.setAttribute(\"href\", href);\n href = urlParsingNode.href;\n }\n\n urlParsingNode.setAttribute('href', href);\n\n // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n return {\n href: urlParsingNode.href,\n protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n host: urlParsingNode.host,\n search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n hostname: urlParsingNode.hostname,\n port: utilities.isNotEmptyString(urlParsingNode.port)? urlParsingNode.port: 80,\n pathname: (urlParsingNode.pathname.charAt(0) === '/')\n ? urlParsingNode.pathname\n : '/' + urlParsingNode.pathname\n };\n}\n\n\n/**\n * This function accepts a query string (search part of a url) and returns a dictionary with\n * the different key value pairs\n * @param {string} qs queryString\n */\nfunction queryStringToObj(qs, cond) {\n var pairs, qsObj;\n\n cond = utilities.isFunction(cond)? cond : function() {\n return true;\n };\n\n qs = qs.trim().replace(/^\\?/, '');\n pairs = qs.split('&');\n qsObj = {};\n\n utilities.forEach(pairs, function (pair) {\n var keyValue, key, value;\n if (pair !== '') {\n keyValue = pair.split('=');\n key = keyValue[0];\n value = keyValue[1];\n if(cond(key, value)){\n qsObj[key] = value;\n }\n }\n });\n\n return qsObj;\n}\n\n/**\n * This function accepts an object and serializes it into a query string without the leading '?'\n * @param obj\n * @returns {string}\n */\nfunction objToQueryString(obj) {\n var pairs = [];\n utilities.forEach(obj, function (value, key) {\n pairs.push(key + '=' + value);\n });\n return pairs.join('&');\n}\n\nmodule.exports = {\n urlParts: urlParts,\n queryStringToObj: queryStringToObj,\n objToQueryString: objToQueryString\n};\n\n},{\"./utilityFunctions\":45}],45:[function(require,module,exports){\n/*jshint unused:false */\n\"use strict\";\n\nvar NODE_TYPE_ELEMENT = 1;\nvar SNAKE_CASE_REGEXP = /[A-Z]/g;\nvar EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/i;\n/*jslint maxlen: 500 */\nvar ISO8086_REGEXP = /^([\\+-]?\\d{4}(?!\\d{2}\\b))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))([T\\s]((([01]\\d|2[0-3])((:?)[0-5]\\d)?|24\\:?00)([\\.,]\\d+(?!:))?)?(\\17[0-5]\\d([\\.,]\\d+)?)?([zZ]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)?$/;\n\n\nfunction noop(){ }\n\nfunction isNull(o) {\n return o === null;\n}\n\nfunction isDefined(o){\n return o !== undefined;\n}\n\nfunction isUndefined(o){\n return o === undefined;\n}\n\nfunction isObject(obj) {\n return typeof obj === 'object';\n}\n\nfunction isFunction(str){\n return typeof str === 'function';\n}\n\nfunction isNumber(num){\n return typeof num === 'number';\n}\n\nfunction isWindow(obj) {\n return utilities.isObject(obj) && obj.window === obj;\n}\n\nfunction isArray(array){\n return Object.prototype.toString.call( array ) === '[object Array]';\n}\n\nfunction isArrayLike(obj) {\n if (obj === null || utilities.isWindow(obj) || utilities.isFunction(obj) || utilities.isUndefined(obj)) {\n return false;\n }\n\n var length = obj.length;\n\n if (obj.nodeType === NODE_TYPE_ELEMENT && length) {\n return true;\n }\n\n return utilities.isString(obj) || utilities.isArray(obj) || length === 0 ||\n typeof length === 'number' && length > 0 && (length - 1) in obj;\n}\n\nfunction isString(str){\n return typeof str === 'string';\n}\n\nfunction isEmptyString(str) {\n return utilities.isString(str) && str.length === 0;\n}\n\nfunction isNotEmptyString(str) {\n return utilities.isString(str) && str.length !== 0;\n}\n\nfunction arrayLikeObjToArray(args) {\n return Array.prototype.slice.call(args);\n}\n\nfunction forEach(obj, iterator, context) {\n var key, length;\n if (obj) {\n if (isFunction(obj)) {\n for (key in obj) {\n // Need to check if hasOwnProperty exists,\n // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function\n if (key !== 'prototype' && key !== 'length' && key !== 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n } else if (isArray(obj)) {\n var isPrimitive = typeof obj !== 'object';\n for (key = 0, length = obj.length; key < length; key++) {\n if (isPrimitive || key in obj) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n } else if (obj.forEach && obj.forEach !== forEach) {\n obj.forEach(iterator, context, obj);\n } else {\n for (key in obj) {\n if (obj.hasOwnProperty(key)) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n }\n }\n return obj;\n}\n\nfunction snake_case(name, separator) {\n separator = separator || '_';\n return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {\n return (pos ? separator : '') + letter.toLowerCase();\n });\n}\n\nfunction isValidEmail(email){\n if(!utilities.isString(email)){\n return false;\n }\n\n return EMAIL_REGEXP.test(email.trim());\n}\n\nfunction extend (obj) {\n var arg, i, k;\n for (i = 1; i < arguments.length; i++) {\n arg = arguments[i];\n for (k in arg) {\n if (arg.hasOwnProperty(k)) {\n if(isObject(obj[k]) && !isNull(obj[k]) && isObject(arg[k])){\n obj[k] = extend({}, obj[k], arg[k]);\n }else {\n obj[k] = arg[k];\n }\n }\n }\n }\n return obj;\n}\n\nfunction capitalize(s){\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nfunction decapitalize(s) {\n return s.charAt(0).toLowerCase() + s.slice(1);\n}\n\n/**\n * This method works the same way array.prototype.map works but if the transformer returns undefine, then\n * it won't be added to the transformed Array.\n */\nfunction transformArray(array, transformer) {\n var transformedArray = [];\n\n array.forEach(function(item, index){\n var transformedItem = transformer(item, index);\n if(utilities.isDefined(transformedItem)) {\n transformedArray.push(transformedItem);\n }\n });\n\n return transformedArray;\n}\n\nfunction toFixedDigits(num, digits) {\n var formattedNum = num + '';\n digits = utilities.isNumber(digits) ? digits : 0;\n num = utilities.isNumber(num) ? num : parseInt(num, 10);\n if(utilities.isNumber(num) && !isNaN(num)){\n formattedNum = num + '';\n while(formattedNum.length < digits) {\n formattedNum = '0' + formattedNum;\n }\n return formattedNum;\n }\n return NaN + '';\n}\n\nfunction throttle(callback, delay) {\n var previousCall = new Date().getTime() - (delay + 1);\n return function() {\n var time = new Date().getTime();\n if ((time - previousCall) >= delay) {\n previousCall = time;\n callback.apply(this, arguments);\n }\n };\n}\n\nfunction debounce (callback, wait) {\n var timeoutId;\n\n return function (){\n if(timeoutId) {\n clearTimeout(timeoutId);\n }\n timeoutId = setTimeout(function(){\n callback.apply(this, arguments);\n timeoutId = undefined;\n }, wait);\n };\n}\n\n// a function designed to blow up the stack in a naive way\n// but it is ok for videoJs children components\nfunction treeSearch(root, getChildren, found){\n var children = getChildren(root);\n for (var i = 0; i < children.length; i++){\n if (found(children[i])) {\n return children[i];\n }\n else {\n var el = treeSearch(children[i], getChildren, found);\n if (el){\n return el;\n }\n }\n }\n}\n\nfunction echoFn(val) {\n return function () {\n return val;\n };\n}\n\n//Note: Supported formats come from http://www.w3.org/TR/NOTE-datetime\n// and the iso8601 regex comes from http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/\nfunction isISO8601(value) {\n if(utilities.isNumber(value)){\n value = value + ''; //we make sure that we are working with strings\n }\n\n if(!utilities.isString(value)){\n return false;\n }\n\n return ISO8086_REGEXP.test(value.trim());\n}\n\n/**\n * Checks if the Browser is IE9 and below\n * @returns {boolean}\n */\nfunction isOldIE() {\n var version = utilities.getInternetExplorerVersion(navigator);\n if (version === -1) {\n return false;\n }\n\n return version < 10;\n}\n\n/**\n * Returns the version of Internet Explorer or a -1 (indicating the use of another browser).\n * Source: https://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx\n * @returns {number} the version of Internet Explorer or a -1 (indicating the use of another browser).\n */\nfunction getInternetExplorerVersion(navigator) {\n var rv = -1;\n\n if (navigator.appName == 'Microsoft Internet Explorer') {\n var ua = navigator.userAgent;\n var re = new RegExp(\"MSIE ([0-9]{1,}[\\.0-9]{0,})\");\n var res = re.exec(ua);\n if (res !== null) {\n rv = parseFloat(res[1]);\n }\n }\n\n return rv;\n}\n\n/*** Mobile Utility functions ***/\nfunction isIDevice() {\n return /iP(hone|ad)/.test(utilities._UA);\n}\n\nfunction isMobile() {\n return /iP(hone|ad|od)|Android|Windows Phone/.test(utilities._UA);\n}\n\nfunction isIPhone() {\n return /iP(hone|od)/.test(utilities._UA);\n}\n\nfunction isAndroid() {\n return /Android/.test(utilities._UA);\n}\n\nvar utilities = {\n _UA: navigator.userAgent,\n noop: noop,\n isNull: isNull,\n isDefined: isDefined,\n isUndefined: isUndefined,\n isObject: isObject,\n isFunction: isFunction,\n isNumber: isNumber,\n isWindow: isWindow,\n isArray: isArray,\n isArrayLike: isArrayLike,\n isString: isString,\n isEmptyString: isEmptyString,\n isNotEmptyString: isNotEmptyString,\n arrayLikeObjToArray: arrayLikeObjToArray,\n forEach: forEach,\n snake_case: snake_case,\n isValidEmail: isValidEmail,\n extend: extend,\n capitalize: capitalize,\n decapitalize: decapitalize,\n transformArray: transformArray,\n toFixedDigits: toFixedDigits,\n throttle: throttle,\n debounce: debounce,\n treeSearch: treeSearch,\n echoFn: echoFn,\n isISO8601: isISO8601,\n isOldIE: isOldIE,\n getInternetExplorerVersion: getInternetExplorerVersion,\n isIDevice: isIDevice,\n isMobile: isMobile,\n isIPhone: isIPhone,\n isAndroid: isAndroid\n};\n\nmodule.exports = utilities;\n},{}],46:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('./utilityFunctions');\n\nvar xml = {};\n\nxml.strToXMLDoc = function strToXMLDoc(stringContainingXMLSource){\n //IE 8\n if(typeof window.DOMParser === 'undefined'){\n var xmlDocument = new ActiveXObject('Microsoft.XMLDOM');\n xmlDocument.async = false;\n xmlDocument.loadXML(stringContainingXMLSource);\n return xmlDocument;\n }\n\n return parseString(stringContainingXMLSource);\n\n function parseString(stringContainingXMLSource){\n var parser = new DOMParser();\n var parsedDocument;\n\n //Note: This try catch is to deal with the fact that on IE parser.parseFromString does throw an error but the rest of the browsers don't.\n try {\n parsedDocument = parser.parseFromString(stringContainingXMLSource, \"application/xml\");\n\n if(isParseError(parsedDocument) || utilities.isEmptyString(stringContainingXMLSource)){\n throw new Error();\n }\n }catch(e){\n throw new Error(\"xml.strToXMLDOC: Error parsing the string: '\" + stringContainingXMLSource + \"'\");\n }\n\n return parsedDocument;\n }\n\n function isParseError(parsedDocument) {\n try { // parser and parsererrorNS could be cached on startup for efficiency\n var parser = new DOMParser(),\n erroneousParse = parser.parseFromString('INVALID', 'text/xml'),\n parsererrorNS = erroneousParse.getElementsByTagName(\"parsererror\")[0].namespaceURI;\n\n if (parsererrorNS === 'http://www.w3.org/1999/xhtml') {\n // In PhantomJS the parseerror element doesn't seem to have a special namespace, so we are just guessing here :(\n return parsedDocument.getElementsByTagName(\"parsererror\").length > 0;\n }\n\n return parsedDocument.getElementsByTagNameNS(parsererrorNS, 'parsererror').length > 0;\n } catch (e) {\n //Note on IE parseString throws an error by itself and it will never reach this code. Because it will have failed before\n }\n }\n};\n\nxml.parseText = function parseText (sValue) {\n if (/^\\s*$/.test(sValue)) { return null; }\n if (/^(?:true|false)$/i.test(sValue)) { return sValue.toLowerCase() === \"true\"; }\n if (isFinite(sValue)) { return parseFloat(sValue); }\n if (utilities.isISO8601(sValue)) { return new Date(sValue); }\n return sValue.trim();\n};\n\nxml.JXONTree = function JXONTree (oXMLParent) {\n var parseText = xml.parseText;\n\n //The document object is an especial object that it may miss some functions or attrs depending on the browser.\n //To prevent this problem with create the JXONTree using the root childNode which is a fully fleshed node on all supported\n //browsers.\n if(oXMLParent.documentElement){\n return new xml.JXONTree(oXMLParent.documentElement);\n }\n\n if (oXMLParent.hasChildNodes()) {\n var sCollectedTxt = \"\";\n for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {\n oNode = oXMLParent.childNodes.item(nItem);\n /*jshint bitwise: false*/\n if ((oNode.nodeType - 1 | 1) === 3) { sCollectedTxt += oNode.nodeType === 3 ? oNode.nodeValue.trim() : oNode.nodeValue; }\n else if (oNode.nodeType === 1 && !oNode.prefix) {\n sProp = utilities.decapitalize(oNode.nodeName);\n vContent = new xml.JXONTree(oNode);\n if (this.hasOwnProperty(sProp)) {\n if (this[sProp].constructor !== Array) { this[sProp] = [this[sProp]]; }\n this[sProp].push(vContent);\n } else { this[sProp] = vContent; }\n }\n }\n if (sCollectedTxt) { this.keyValue = parseText(sCollectedTxt); }\n }\n\n //IE8 Stupid fix\n var hasAttr = typeof oXMLParent.hasAttributes === 'undefined'? oXMLParent.attributes.length > 0: oXMLParent.hasAttributes();\n if (hasAttr) {\n var oAttrib;\n for (var nAttrib = 0; nAttrib < oXMLParent.attributes.length; nAttrib++) {\n oAttrib = oXMLParent.attributes.item(nAttrib);\n this[\"@\" + utilities.decapitalize(oAttrib.name)] = parseText(oAttrib.value.trim());\n }\n }\n};\n\nxml.JXONTree.prototype.attr = function(attr) {\n return this['@' + utilities.decapitalize(attr)];\n};\n\nxml.toJXONTree = function toJXONTree(xmlString){\n var xmlDoc = xml.strToXMLDoc(xmlString);\n return new xml.JXONTree(xmlDoc);\n};\n\n/**\n * Helper function to extract the keyvalue of a JXONTree obj\n *\n * @param xmlObj {JXONTree}\n * return the key value or undefined;\n */\nxml.keyValue = function getKeyValue(xmlObj) {\n if(xmlObj){\n return xmlObj.keyValue;\n }\n return undefined;\n};\n\nxml.attr = function getAttrValue(xmlObj, attr) {\n if(xmlObj) {\n return xmlObj['@' + utilities.decapitalize(attr)];\n }\n return undefined;\n};\n\nxml.encode = function encodeXML(str) {\n return str.replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n};\n\nxml.decode = function decodeXML(str) {\n return str.replace(/'/g, \"'\")\n .replace(/"/g, '\"')\n .replace(/>/g, '>')\n .replace(/</g, '<')\n .replace(/&/g, '&');\n};\n\nmodule.exports = xml;\n},{\"./utilityFunctions\":45}],47:[function(require,module,exports){\n'use strict';\n\nrequire('./plugin/components/ads-label_5');\nrequire('./plugin/components/black-poster_5');\n\nvar videoJsVAST = require('./plugin/videojs.vast.vpaid');\n\nvideojs.plugin('vastClient', videoJsVAST);\n\n},{\"./plugin/components/ads-label_5\":36,\"./plugin/components/black-poster_5\":38,\"./plugin/videojs.vast.vpaid\":39}]},{},[47])\n\n","'use strict';\n\nlet IVPAIDAdUnit = require('./IVPAIDAdUnit').IVPAIDAdUnit;\nlet ALL_VPAID_METHODS = Object.getOwnPropertyNames(IVPAIDAdUnit.prototype).filter(function (property) {\n return ['constructor'].indexOf(property) === -1;\n});\n\nexport class VPAIDAdUnit extends IVPAIDAdUnit {\n constructor (flash) {\n super();\n this._destroyed = false;\n this._flash = flash;\n }\n\n _destroy() {\n this._destroyed = true;\n ALL_VPAID_METHODS.forEach((methodName) => {\n this._flash.removeCallbackByMethodName(methodName);\n });\n IVPAIDAdUnit.EVENTS.forEach((event) => {\n this._flash.offEvent(event);\n });\n\n this._flash = null;\n }\n\n isDestroyed () {\n return this._destroyed;\n }\n\n on(eventName, callback) {\n this._flash.on(eventName, callback);\n }\n\n off(eventName, callback) {\n this._flash.off(eventName, callback);\n }\n\n //VPAID interface\n handshakeVersion(playerVPAIDVersion = '2.0', callback = undefined) {\n this._flash.callFlashMethod('handshakeVersion', [playerVPAIDVersion], callback);\n }\n initAd (width, height, viewMode, desiredBitrate, creativeData = {AdParameters: ''}, environmentVars = {flashVars: ''}, callback = undefined) {\n //resize element that has the flash object\n this._flash.setSize(width, height);\n creativeData = creativeData || {AdParameters: ''};\n environmentVars = environmentVars || {flashVars: ''};\n\n this._flash.callFlashMethod('initAd', [this._flash.getWidth(), this._flash.getHeight(), viewMode, desiredBitrate, creativeData.AdParameters || '', environmentVars.flashVars || ''], callback);\n }\n resizeAd(width, height, viewMode, callback = undefined) {\n //resize element that has the flash object\n this._flash.setSize(width, height);\n\n //resize ad inside the flash\n this._flash.callFlashMethod('resizeAd', [this._flash.getWidth(), this._flash.getHeight(), viewMode], callback);\n }\n startAd(callback = undefined) {\n this._flash.callFlashMethod('startAd', [], callback);\n }\n stopAd(callback = undefined) {\n this._flash.callFlashMethod('stopAd', [], callback);\n }\n pauseAd(callback = undefined) {\n this._flash.callFlashMethod('pauseAd', [], callback);\n }\n resumeAd(callback = undefined) {\n this._flash.callFlashMethod('resumeAd', [], callback);\n }\n expandAd(callback = undefined) {\n this._flash.callFlashMethod('expandAd', [], callback);\n }\n collapseAd(callback = undefined) {\n this._flash.callFlashMethod('collapseAd', [], callback);\n }\n skipAd(callback = undefined) {\n this._flash.callFlashMethod('skipAd', [], callback);\n }\n\n //properties that will be treat as async methods\n getAdLinear(callback) {\n this._flash.callFlashMethod('getAdLinear', [], callback);\n }\n getAdWidth(callback) {\n this._flash.callFlashMethod('getAdWidth', [], callback);\n }\n getAdHeight(callback) {\n this._flash.callFlashMethod('getAdHeight', [], callback);\n }\n getAdExpanded(callback) {\n this._flash.callFlashMethod('getAdExpanded', [], callback);\n }\n getAdSkippableState(callback) {\n this._flash.callFlashMethod('getAdSkippableState', [], callback);\n }\n getAdRemainingTime(callback) {\n this._flash.callFlashMethod('getAdRemainingTime', [], callback);\n }\n getAdDuration(callback) {\n this._flash.callFlashMethod('getAdDuration', [], callback);\n }\n setAdVolume(volume, callback = undefined) {\n this._flash.callFlashMethod('setAdVolume', [volume], callback);\n }\n getAdVolume(callback) {\n this._flash.callFlashMethod('getAdVolume', [], callback);\n }\n getAdCompanions(callback) {\n this._flash.callFlashMethod('getAdCompanions', [], callback);\n }\n getAdIcons(callback) {\n this._flash.callFlashMethod('getAdIcons', [], callback);\n }\n}\n\n","'use strict';\n\nconst swfobject = require('swfobject');\n\nconst JSFlashBridge = require('./jsFlashBridge').JSFlashBridge;\nconst VPAIDAdUnit = require('./VPAIDAdUnit').VPAIDAdUnit;\n\nconst noop = require('./utils').noop;\nconst callbackTimeout = require('./utils').callbackTimeout;\nconst isPositiveInt = require('./utils').isPositiveInt;\nconst createElementWithID = require('./utils').createElementWithID;\nconst uniqueVPAID = require('./utils').unique('vpaid');\nconst createFlashTester = require('./flashTester.js').createFlashTester;\n\nconst ERROR = 'error';\nconst FLASH_VERSION = '10.1.0';\n\nlet flashTester = {isSupported: ()=> true}; // if the runFlashTest is not run the flashTester will always return true\n\nclass VPAIDFLASHClient {\n constructor (vpaidParentEl, callback, swfConfig = {data: 'VPAIDFlash.swf', width: 800, height: 400}, params = { wmode: 'transparent', salign: 'tl', align: 'left', allowScriptAccess: 'always', scale: 'noScale', allowFullScreen: 'true', quality: 'high'}, vpaidOptions = { debug: false, timeout: 10000 }) {\n\n var me = this;\n\n this._vpaidParentEl = vpaidParentEl;\n this._flashID = uniqueVPAID();\n this._destroyed = false;\n callback = callback || noop;\n\n swfConfig.width = isPositiveInt(swfConfig.width, 800);\n swfConfig.height = isPositiveInt(swfConfig.height, 400);\n\n createElementWithID(vpaidParentEl, this._flashID, true);\n\n params.movie = swfConfig.data;\n params.FlashVars = `flashid=${this._flashID}&handler=${JSFlashBridge.VPAID_FLASH_HANDLER}&debug=${vpaidOptions.debug}&salign=${params.salign}`;\n\n if (!VPAIDFLASHClient.isSupported()) {\n return onError('user don\\'t support flash or doesn\\'t have the minimum required version of flash ' + FLASH_VERSION);\n }\n\n this.el = swfobject.createSWF(swfConfig, params, this._flashID);\n\n if (!this.el) {\n return onError( 'swfobject failed to create object in element' );\n }\n\n var handler = callbackTimeout(vpaidOptions.timeout,\n (err, data) => {\n $loadPendedAdUnit.call(this);\n callback(err, data);\n }, () => {\n callback('vpaid flash load timeout ' + vpaidOptions.timeout);\n }\n );\n\n this._flash = new JSFlashBridge(this.el, swfConfig.data, this._flashID, swfConfig.width, swfConfig.height, handler);\n\n function onError(error) {\n setTimeout(() => {\n callback(new Error(error));\n }, 0);\n return me;\n }\n\n }\n\n destroy () {\n this._destroyAdUnit();\n\n if (this._flash) {\n this._flash.destroy();\n this._flash = null;\n }\n this.el = null;\n this._destroyed = true;\n }\n\n isDestroyed () {\n return this._destroyed;\n }\n\n _destroyAdUnit() {\n delete this._loadLater;\n\n if (this._adUnitLoad) {\n this._adUnitLoad = null;\n this._flash.removeCallback(this._adUnitLoad);\n }\n\n if (this._adUnit) {\n this._adUnit._destroy();\n this._adUnit = null;\n }\n }\n\n loadAdUnit(adURL, callback) {\n $throwIfDestroyed.call(this);\n\n if (this._adUnit) {\n this._destroyAdUnit();\n }\n\n if (this._flash.isReady()) {\n this._adUnitLoad = (err, message) => {\n if (!err) {\n this._adUnit = new VPAIDAdUnit(this._flash);\n }\n this._adUnitLoad = null;\n callback(err, this._adUnit);\n };\n\n this._flash.callFlashMethod('loadAdUnit', [adURL], this._adUnitLoad);\n }else {\n this._loadLater = {url: adURL, callback};\n }\n }\n\n unloadAdUnit(callback = undefined) {\n $throwIfDestroyed.call(this);\n\n this._destroyAdUnit();\n this._flash.callFlashMethod('unloadAdUnit', [], callback);\n }\n getFlashID() {\n $throwIfDestroyed.call(this);\n return this._flash.getFlashID();\n }\n getFlashURL() {\n $throwIfDestroyed.call(this);\n return this._flash.getFlashURL();\n }\n}\n\nsetStaticProperty('isSupported', () => {\n return swfobject.hasFlashPlayerVersion(FLASH_VERSION) && flashTester.isSupported();\n}, true);\n\nsetStaticProperty('runFlashTest', (swfConfig) => {\n flashTester = createFlashTester(document.body, swfConfig);\n});\n\nfunction $throwIfDestroyed() {\n if(this._destroyed) {\n throw new Error('VPAIDFlashToJS is destroyed!');\n }\n}\n\nfunction $loadPendedAdUnit() {\n if (this._loadLater) {\n this.loadAdUnit(this._loadLater.url, this._loadLater.callback);\n delete this._loadLater;\n }\n}\n\nfunction setStaticProperty(propertyName, value, writable = false) {\n Object.defineProperty(VPAIDFLASHClient, propertyName, {\n writable: writable,\n configurable: false,\n value: value\n });\n}\n\nVPAIDFLASHClient.swfobject = swfobject;\n\nmodule.exports = VPAIDFLASHClient;\n","'use strict';\n\nconst swfobject = require('swfobject');\n\nconst FLASH_TEST = 'vpaid_video_flash_tester';\nconst FLASH_TEST_EL = 'vpaid_video_flash_tester_el';\nconst JSFlashBridge = require('./jsFlashBridge').JSFlashBridge;\nconst utils = require('./utils');\nconst MultipleValuesRegistry = require('./registry').MultipleValuesRegistry;\n\nclass FlashTester {\n constructor(parent, swfConfig = {data: 'VPAIDFlash.swf', width: 800, height: 400}) {\n this.parentEl = utils.createElementWithID(parent, FLASH_TEST_EL); // some browsers create global variables using the element id http://stackoverflow.com/questions/3434278/do-dom-tree-elements-with-ids-become-global-variables\n utils.hideFlashEl(this.parentEl);\n var params = {};\n params.movie = swfConfig.data;\n params.FlashVars = `flashid=${FLASH_TEST_EL}&handler=${JSFlashBridge.VPAID_FLASH_HANDLER}`;\n\n this.el = swfobject.createSWF(swfConfig, params, FLASH_TEST_EL);\n this._handlers = new MultipleValuesRegistry();\n this._isSupported = false;\n if (this.el) {\n utils.hideFlashEl(this.el);\n this._flash = new JSFlashBridge(this.el, swfConfig.data, FLASH_TEST_EL, 400, 400, ()=> {\n const support = true;\n this._isSupported = support;\n this._handlers.get('change').forEach((callback) => {\n setTimeout(()=> {\n callback('change', support);\n }, 0);\n });\n });\n }\n }\n isSupported() {\n return this._isSupported;\n }\n on(eventName, callback) {\n this._handlers.add(eventName, callback);\n }\n}\n\nexport var createFlashTester = function createFlashTester(el, swfConfig) {\n if (!window[FLASH_TEST]) {\n window[FLASH_TEST] = new FlashTester(el, swfConfig);\n }\n return window[FLASH_TEST];\n};\n","'use strict';\n\nlet unique = require('./utils').unique;\nlet isPositiveInt = require('./utils').isPositiveInt;\nlet stringEndsWith = require('./utils').stringEndsWith;\nlet SingleValueRegistry = require('./registry').SingleValueRegistry;\nlet MultipleValuesRegistry = require('./registry').MultipleValuesRegistry;\nconst registry = require('./jsFlashBridgeRegistry');\nconst VPAID_FLASH_HANDLER = 'vpaid_video_flash_handler';\nconst ERROR = 'AdError';\n\nexport class JSFlashBridge {\n constructor (el, flashURL, flashID, width, height, loadHandShake) {\n this._el = el;\n this._flashID = flashID;\n this._flashURL = flashURL;\n this._width = width;\n this._height = height;\n this._handlers = new MultipleValuesRegistry();\n this._callbacks = new SingleValueRegistry();\n this._uniqueMethodIdentifier = unique(this._flashID);\n this._ready = false;\n this._handShakeHandler = loadHandShake;\n\n registry.addInstance(this._flashID, this);\n }\n\n on(eventName, callback) {\n this._handlers.add(eventName, callback);\n }\n\n off(eventName, callback) {\n return this._handlers.remove(eventName, callback);\n }\n\n offEvent(eventName) {\n return this._handlers.removeByKey(eventName);\n }\n\n offAll() {\n return this._handlers.removeAll();\n }\n\n callFlashMethod(methodName, args = [], callback = undefined) {\n var callbackID = '';\n // if no callback, some methods the return is void so they don't need callback\n if (callback) {\n callbackID = `${this._uniqueMethodIdentifier()}_${methodName}`;\n this._callbacks.add(callbackID, callback);\n }\n\n\n try {\n //methods are created by ExternalInterface.addCallback in as3 code, if for some reason it failed\n //this code will throw an error\n this._el[methodName]([callbackID].concat(args));\n\n } catch (e) {\n if (callback) {\n $asyncCallback.call(this, callbackID, e);\n } else {\n\n //if there isn't any callback to return error use error event handler\n this._trigger(ERROR, e);\n }\n }\n }\n\n removeCallback(callback) {\n return this._callbacks.removeByValue(callback);\n }\n\n removeCallbackByMethodName(suffix) {\n this._callbacks.filterKeys((key) => {\n return stringEndsWith(key, suffix);\n }).forEach((key) => {\n this._callbacks.remove(key);\n });\n }\n\n removeAllCallbacks() {\n return this._callbacks.removeAll();\n }\n\n _trigger(eventName, event) {\n this._handlers.get(eventName).forEach((callback) => {\n //clickThru has to be sync, if not will be block by the popupblocker\n if (eventName === 'AdClickThru') {\n callback(event);\n } else {\n setTimeout(() => {\n if (this._handlers.get(eventName).length > 0) {\n callback(event);\n }\n }, 0);\n }\n });\n }\n\n _callCallback(methodName, callbackID, err, result) {\n\n let callback = this._callbacks.get(callbackID);\n\n //not all methods callback's are mandatory\n //but if there exist an error, fire the error event\n if (!callback) {\n if (err && callbackID === '') {\n this.trigger(ERROR, err);\n }\n return;\n }\n\n $asyncCallback.call(this, callbackID, err, result);\n\n }\n\n _handShake(err, data) {\n this._ready = true;\n if (this._handShakeHandler) {\n this._handShakeHandler(err, data);\n delete this._handShakeHandler;\n }\n }\n\n //methods like properties specific to this implementation of VPAID\n getSize() {\n return {width: this._width, height: this._height};\n }\n setSize(newWidth, newHeight) {\n this._width = isPositiveInt(newWidth, this._width);\n this._height = isPositiveInt(newHeight, this._height);\n this._el.setAttribute('width', this._width);\n this._el.setAttribute('height', this._height);\n }\n getWidth() {\n return this._width;\n }\n setWidth(newWidth) {\n this.setSize(newWidth, this._height);\n }\n getHeight() {\n return this._height;\n }\n setHeight(newHeight) {\n this.setSize(this._width, newHeight);\n }\n getFlashID() {\n return this._flashID;\n }\n getFlashURL() {\n return this._flashURL;\n }\n isReady() {\n return this._ready;\n }\n destroy() {\n this.offAll();\n this.removeAllCallbacks();\n registry.removeInstanceByID(this._flashID);\n if (this._el.parentElement) {\n this._el.parentElement.removeChild(this._el);\n }\n }\n}\n\nfunction $asyncCallback(callbackID, err, result) {\n setTimeout(() => {\n let callback = this._callbacks.get(callbackID);\n if (callback) {\n this._callbacks.remove(callbackID);\n callback(err, result);\n }\n }, 0);\n}\n\nObject.defineProperty(JSFlashBridge, 'VPAID_FLASH_HANDLER', {\n writable: false,\n configurable: false,\n value: VPAID_FLASH_HANDLER\n});\n\n/**\n * External interface handler\n *\n * @param {string} flashID identifier of the flash who call this\n * @param {string} typeID what type of message is, can be 'event' or 'callback'\n * @param {string} typeName if the typeID is a event the typeName will be the eventName, if is a callback the typeID is the methodName that is related this callback\n * @param {string} callbackID only applies when the typeID is 'callback', identifier of the callback to call\n * @param {object} error error object\n * @param {object} data\n */\nwindow[VPAID_FLASH_HANDLER] = (flashID, typeID, typeName, callbackID, error, data) => {\n let instance = registry.getInstanceByID(flashID);\n if (!instance) return;\n if (typeName === 'handShake') {\n instance._handShake(error, data);\n } else {\n if (typeID !== 'event') {\n instance._callCallback(typeName, callbackID, error, data);\n } else {\n instance._trigger(typeName, data);\n }\n }\n};\n\n","'use strict';\n\nlet SingleValueRegistry = require('./registry').SingleValueRegistry;\nlet instances = new SingleValueRegistry();\n\nconst JSFlashBridgeRegistry = {};\nObject.defineProperty(JSFlashBridgeRegistry, 'addInstance', {\n writable: false,\n configurable: false,\n value: function (id, instance) {\n instances.add(id, instance);\n }\n});\n\nObject.defineProperty(JSFlashBridgeRegistry, 'getInstanceByID', {\n writable: false,\n configurable: false,\n value: function (id) {\n return instances.get(id);\n }\n});\n\nObject.defineProperty(JSFlashBridgeRegistry, 'removeInstanceByID', {\n writable: false,\n configurable: false,\n value: function (id) {\n return instances.remove(id);\n }\n});\n\nmodule.exports = JSFlashBridgeRegistry;\n\n","'use strict';\n\nexport class MultipleValuesRegistry {\n constructor () {\n this._registries = {};\n }\n add (id, value) {\n if (!this._registries[id]) {\n this._registries[id] = [];\n }\n if (this._registries[id].indexOf(value) === -1) {\n this._registries[id].push(value);\n }\n }\n get (id) {\n return this._registries[id] || [];\n }\n filterKeys (handler) {\n return Object.keys(this._registries).filter(handler);\n }\n findByValue (value) {\n var keys = Object.keys(this._registries).filter((key) => {\n return this._registries[key].indexOf(value) !== -1;\n });\n\n return keys;\n }\n remove(key, value) {\n if (!this._registries[key]) { return; }\n\n var index = this._registries[key].indexOf(value);\n\n if (index < 0) { return; }\n return this._registries[key].splice(index, 1);\n }\n removeByKey (id) {\n let old = this._registries[id];\n delete this._registries[id];\n return old;\n }\n removeByValue (value) {\n let keys = this.findByValue(value);\n return keys.map((key) => {\n return this.remove(key, value);\n });\n }\n removeAll() {\n let old = this._registries;\n this._registries = {};\n return old;\n }\n size() {\n return Object.keys(this._registries).length;\n }\n}\n\nexport class SingleValueRegistry {\n constructor () {\n this._registries = {};\n }\n add (id, value) {\n this._registries[id] = value;\n }\n get (id) {\n return this._registries[id];\n }\n filterKeys (handler) {\n return Object.keys(this._registries).filter(handler);\n }\n findByValue (value) {\n var keys = Object.keys(this._registries).filter((key) => {\n return this._registries[key] === value;\n });\n\n return keys;\n }\n remove (id) {\n let old = this._registries[id];\n delete this._registries[id];\n return old;\n }\n removeByValue (value) {\n let keys = this.findByValue(value);\n return keys.map((key) => {\n return this.remove(key);\n });\n }\n removeAll() {\n let old = this._registries;\n this._registries = {};\n return old;\n }\n size() {\n return Object.keys(this._registries).length;\n }\n}\n\n","'use strict';\n\nexport function unique(prefix) {\n let count = -1;\n return f => {\n return `${prefix}_${++count}`;\n };\n}\n\nexport function noop() {\n}\n\n\nexport function callbackTimeout(timer, onSuccess, onTimeout) {\n\n let timeout = setTimeout(() => {\n\n onSuccess = noop;\n onTimeout();\n\n }, timer);\n\n return function () {\n clearTimeout(timeout);\n onSuccess.apply(this, arguments);\n };\n}\n\n\nexport function createElementWithID(parent, id, cleanContent = false) {\n var nEl = document.createElement('div');\n nEl.id = id;\n if (cleanContent) {\n parent.innerHTML = '';\n }\n parent.appendChild(nEl);\n return nEl;\n}\n\nexport function isPositiveInt(newVal, oldVal) {\n return !isNaN(parseFloat(newVal)) && isFinite(newVal) && newVal > 0 ? newVal : oldVal;\n}\n\nlet endsWith = (function () {\n if (String.prototype.endsWith) return String.prototype.endsWith;\n return function endsWith (searchString, position) {\n var subjectString = this.toString();\n if (position === undefined || position > subjectString.length) {\n position = subjectString.length;\n }\n position -= searchString.length;\n var lastIndex = subjectString.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n };\n})();\n\nexport function stringEndsWith(string, search) {\n return endsWith.call(string, search);\n}\n\nexport function hideFlashEl(el) {\n // can't use display none or visibility none because will block flash in some browsers\n el.style.position = 'absolute';\n el.style.left = '-1px';\n el.style.top = '-1px';\n el.style.width = '1px';\n el.style.height = '1px';\n}\n","'use strict';\n\nvar METHODS = [\n 'handshakeVersion',\n 'initAd',\n 'startAd',\n 'stopAd',\n 'skipAd', // VPAID 2.0 new method\n 'resizeAd',\n 'pauseAd',\n 'resumeAd',\n 'expandAd',\n 'collapseAd',\n 'subscribe',\n 'unsubscribe'\n];\n\nvar EVENTS = [\n 'AdLoaded',\n 'AdStarted',\n 'AdStopped',\n 'AdSkipped',\n 'AdSkippableStateChange', // VPAID 2.0 new event\n 'AdSizeChange', // VPAID 2.0 new event\n 'AdLinearChange',\n 'AdDurationChange', // VPAID 2.0 new event\n 'AdExpandedChange',\n 'AdRemainingTimeChange', // [Deprecated in 2.0] but will be still fired for backwards compatibility\n 'AdVolumeChange',\n 'AdImpression',\n 'AdVideoStart',\n 'AdVideoFirstQuartile',\n 'AdVideoMidpoint',\n 'AdVideoThirdQuartile',\n 'AdVideoComplete',\n 'AdClickThru',\n 'AdInteraction', // VPAID 2.0 new event\n 'AdUserAcceptInvitation',\n 'AdUserMinimize',\n 'AdUserClose',\n 'AdPaused',\n 'AdPlaying',\n 'AdLog',\n 'AdError'\n];\n\nvar GETTERS = [\n 'getAdLinear',\n 'getAdWidth', // VPAID 2.0 new getter\n 'getAdHeight', // VPAID 2.0 new getter\n 'getAdExpanded',\n 'getAdSkippableState', // VPAID 2.0 new getter\n 'getAdRemainingTime',\n 'getAdDuration', // VPAID 2.0 new getter\n 'getAdVolume',\n 'getAdCompanions', // VPAID 2.0 new getter\n 'getAdIcons' // VPAID 2.0 new getter\n];\n\nvar SETTERS = [\n 'setAdVolume'\n];\n\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n\n/**\n * IVPAIDAdUnit\n *\n * @class\n *\n * @param {object} creative\n * @param {HTMLElement} el\n * @param {HTMLVideoElement} video\n */\nfunction IVPAIDAdUnit(creative, el, video) {}\n\n\n/**\n * handshakeVersion\n *\n * @param {string} VPAIDVersion\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.handshakeVersion = function (VPAIDVersion, callback) {};\n\n/**\n * initAd\n *\n * @param {number} width\n * @param {number} height\n * @param {string} viewMode can be 'normal', 'thumbnail' or 'fullscreen'\n * @param {number} desiredBitrate indicates the desired bitrate in kbps\n * @param {object} [creativeData] used for additional initialization data\n * @param {object} [environmentVars] used for passing implementation-specific of js version\n * @param {NodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.initAd = function(width, height, viewMode, desiredBitrate, creativeData, environmentVars, callback) {};\n\n/**\n * startAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.startAd = function(callback) {};\n\n/**\n * stopAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.stopAd = function(callback) {};\n\n/**\n * skipAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.skipAd = function(callback) {};\n\n/**\n * resizeAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.resizeAd = function(width, height, viewMode, callback) {};\n\n/**\n * pauseAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.pauseAd = function(callback) {};\n\n/**\n * resumeAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.resumeAd = function(callback) {};\n\n/**\n * expandAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.expandAd = function(callback) {};\n\n/**\n * collapseAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.collapseAd = function(callback) {};\n\n/**\n * subscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n * @param {object} context\n */\nIVPAIDAdUnit.prototype.subscribe = function(event, handler, context) {};\n\n/**\n * startAd\n *\n * @param {string} event\n * @param {function} handler\n */\nIVPAIDAdUnit.prototype.unsubscribe = function(event, handler) {};\n\n\n\n/**\n * getAdLinear\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdLinear = function(callback) {};\n\n/**\n * getAdWidth\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdWidth = function(callback) {};\n\n/**\n * getAdHeight\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdHeight = function(callback) {};\n\n/**\n * getAdExpanded\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdExpanded = function(callback) {};\n\n/**\n * getAdSkippableState\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdSkippableState = function(callback) {};\n\n/**\n * getAdRemainingTime\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdRemainingTime = function(callback) {};\n\n/**\n * getAdDuration\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdDuration = function(callback) {};\n\n/**\n * getAdVolume\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdVolume = function(callback) {};\n\n/**\n * getAdCompanions\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdCompanions = function(callback) {};\n\n/**\n * getAdIcons\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdIcons = function(callback) {};\n\n/**\n * setAdVolume\n *\n * @param {number} volume\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.setAdVolume = function(volume, callback) {};\n\naddStaticToInterface(IVPAIDAdUnit, 'METHODS', METHODS);\naddStaticToInterface(IVPAIDAdUnit, 'GETTERS', GETTERS);\naddStaticToInterface(IVPAIDAdUnit, 'SETTERS', SETTERS);\naddStaticToInterface(IVPAIDAdUnit, 'EVENTS', EVENTS);\n\n\nvar VPAID1_METHODS = METHODS.filter(function(method) {\n return ['skipAd'].indexOf(method) === -1;\n});\n\naddStaticToInterface(IVPAIDAdUnit, 'checkVPAIDInterface', function checkVPAIDInterface (creative) {\n var result = VPAID1_METHODS.every(function(key) {\n return typeof creative[key] === 'function';\n });\n return result;\n});\n\nmodule.exports = IVPAIDAdUnit;\n\nfunction addStaticToInterface(Interface, name, value) {\n Object.defineProperty(Interface, name, {\n writable: false,\n configurable: false,\n value: value\n });\n}\n\n","'use strict';\n\nvar IVPAIDAdUnit = require('./IVPAIDAdUnit');\nvar Subscriber = require('./subscriber');\nvar checkVPAIDInterface = IVPAIDAdUnit.checkVPAIDInterface;\nvar utils = require('./utils');\nvar METHODS = IVPAIDAdUnit.METHODS;\nvar ERROR = 'AdError';\nvar AD_CLICK = 'AdClickThru';\nvar FILTERED_EVENTS = IVPAIDAdUnit.EVENTS.filter(function (event) {\n return event != AD_CLICK;\n});\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n\n/**\n * VPAIDAdUnit\n * @class\n *\n * @param VPAIDCreative\n * @param {HTMLElement} [el] this will be used in initAd environmentVars.slot if defined\n * @param {HTMLVideoElement} [video] this will be used in initAd environmentVars.videoSlot if defined\n */\nfunction VPAIDAdUnit(VPAIDCreative, el, video, iframe) {\n this._isValid = checkVPAIDInterface(VPAIDCreative);\n if (this._isValid) {\n this._creative = VPAIDCreative;\n this._el = el;\n this._videoEl = video;\n this._iframe = iframe;\n this._subscribers = new Subscriber();\n $addEventsSubscribers.call(this);\n }\n}\n\nVPAIDAdUnit.prototype = Object.create(IVPAIDAdUnit.prototype);\n\n/**\n * isValidVPAIDAd will return if the VPAIDCreative passed in constructor is valid or not\n *\n * @return {boolean}\n */\nVPAIDAdUnit.prototype.isValidVPAIDAd = function isValidVPAIDAd() {\n return this._isValid;\n};\n\nIVPAIDAdUnit.METHODS.forEach(function(method) {\n //NOTE: this methods arguments order are implemented differently from the spec\n var ignores = [\n 'subscribe',\n 'unsubscribe',\n 'initAd'\n ];\n\n if (ignores.indexOf(method) !== -1) return;\n\n VPAIDAdUnit.prototype[method] = function () {\n var ariaty = IVPAIDAdUnit.prototype[method].length;\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n var args = Array.prototype.slice.call(arguments);\n var callback = (ariaty === args.length) ? args.pop() : undefined;\n\n setTimeout(function () {\n var result, error = null;\n try {\n result = this._creative[method].apply(this._creative, args);\n } catch(e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n };\n});\n\n\n/**\n * initAd concreate implementation\n *\n * @param {number} width\n * @param {number} height\n * @param {string} viewMode can be 'normal', 'thumbnail' or 'fullscreen'\n * @param {number} desiredBitrate indicates the desired bitrate in kbps\n * @param {object} [creativeData] used for additional initialization data\n * @param {object} [environmentVars] used for passing implementation-specific of js version, if el & video was used in constructor slot & videoSlot will be added to the object\n * @param {NodeStyleCallback} callback\n */\nVPAIDAdUnit.prototype.initAd = function initAd(width, height, viewMode, desiredBitrate, creativeData, environmentVars, callback) {\n creativeData = creativeData || {};\n environmentVars = utils.extend({\n slot: this._el,\n videoSlot: this._videoEl\n }, environmentVars || {});\n\n setTimeout(function () {\n var error;\n try {\n this._creative.initAd(width, height, viewMode, desiredBitrate, creativeData, environmentVars);\n } catch (e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error);\n }.bind(this), 0);\n};\n\n/**\n * subscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n * @param {object} context\n */\nVPAIDAdUnit.prototype.subscribe = function subscribe(event, handler, context) {\n this._subscribers.subscribe(handler, event, context);\n};\n\n\n/**\n * unsubscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n */\nVPAIDAdUnit.prototype.unsubscribe = function unsubscribe(event, handler) {\n this._subscribers.unsubscribe(handler, event);\n};\n\n//alias\nVPAIDAdUnit.prototype.on = VPAIDAdUnit.prototype.subscribe;\nVPAIDAdUnit.prototype.off = VPAIDAdUnit.prototype.unsubscribe;\n\nIVPAIDAdUnit.GETTERS.forEach(function(getter) {\n VPAIDAdUnit.prototype[getter] = function (callback) {\n setTimeout(function () {\n\n var result, error = null;\n try {\n result = this._creative[getter]();\n } catch(e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n };\n});\n\n/**\n * setAdVolume\n *\n * @param volume\n * @param {nodeStyleCallback} callback\n */\nVPAIDAdUnit.prototype.setAdVolume = function setAdVolume(volume, callback) {\n setTimeout(function () {\n\n var result, error = null;\n try {\n this._creative.setAdVolume(volume);\n result = this._creative.getAdVolume();\n } catch(e) {\n error = e;\n }\n\n if (!error) {\n error = utils.validate(result === volume, 'failed to apply volume: ' + volume);\n }\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n};\n\nVPAIDAdUnit.prototype._destroy = function destroy() {\n this.stopAd();\n this._subscribers.unsubscribeAll();\n};\n\nfunction $addEventsSubscribers() {\n // some ads implement\n // so they only handle one subscriber\n // to handle this we create our one\n FILTERED_EVENTS.forEach(function (event) {\n this._creative.subscribe($trigger.bind(this, event), event);\n }.bind(this));\n\n // map the click event to be an object instead of depending of the order of the arguments\n // and to be consistent with the flash\n this._creative.subscribe($clickThruHook.bind(this), AD_CLICK);\n\n // because we are adding the element inside the iframe\n // the user is not able to click in the video\n if (this._videoEl) {\n var documentElement = this._iframe.contentDocument.documentElement;\n var videoEl = this._videoEl;\n documentElement.addEventListener('click', function(e) {\n if (e.target === documentElement) {\n videoEl.click();\n }\n });\n }\n}\n\nfunction $clickThruHook(url, id, playerHandles) {\n this._subscribers.triggerSync(AD_CLICK, {url: url, id: id, playerHandles: playerHandles});\n}\n\nfunction $trigger(event) {\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n this._subscribers.trigger(event, Array.prototype.slice(arguments, 1));\n}\n\nfunction callOrTriggerEvent(callback, subscribers, error, result) {\n if (callback) {\n callback(error, result);\n } else if (error) {\n subscribers.trigger(ERROR, error);\n }\n}\n\nmodule.exports = VPAIDAdUnit;\n\n","'use strict';\n\nvar utils = require('./utils');\nvar unique = utils.unique('vpaidIframe');\nvar VPAIDAdUnit = require('./VPAIDAdUnit');\n\nvar defaultTemplate = '' +\n '' +\n '' +\n '
' +\n '' +\n '' +\n '' +\n '';\n\nvar AD_STOPPED = 'AdStopped';\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n/**\n * VPAIDHTML5Client\n * @class\n *\n * @param {HTMLElement} el that will contain the iframe to load adUnit and a el to add to adUnit slot\n * @param {HTMLVideoElement} video default video element to be used by adUnit\n * @param {object} [templateConfig] template: html template to be used instead of the default, extraOptions: to be used when rendering the template\n * @param {object} [vpaidOptions] timeout: when loading adUnit\n */\nfunction VPAIDHTML5Client(el, video, templateConfig, vpaidOptions) {\n templateConfig = templateConfig || {};\n\n this._id = unique();\n this._destroyed = false;\n\n this._frameContainer = utils.createElementInEl(el, 'div');\n this._videoEl = video;\n this._vpaidOptions = vpaidOptions || {timeout: 10000};\n\n this._templateConfig = {\n template: templateConfig.template || defaultTemplate,\n extraOptions: templateConfig.extraOptions || {}\n };\n}\n\n/**\n * destroy\n *\n */\nVPAIDHTML5Client.prototype.destroy = function destroy() {\n if (this._destroyed) {\n return;\n }\n this._destroyed = true;\n $unloadPreviousAdUnit.call(this);\n};\n\n/**\n * isDestroyed\n *\n * @return {boolean}\n */\nVPAIDHTML5Client.prototype.isDestroyed = function isDestroyed() {\n return this._destroyed;\n};\n\n/**\n * loadAdUnit\n *\n * @param {string} adURL url of the js of the adUnit\n * @param {nodeStyleCallback} callback\n */\nVPAIDHTML5Client.prototype.loadAdUnit = function loadAdUnit(adURL, callback) {\n $throwIfDestroyed.call(this);\n $unloadPreviousAdUnit.call(this);\n var that = this;\n\n var frame = utils.createIframeWithContent(\n this._frameContainer,\n this._templateConfig.template,\n utils.extend({\n iframeURL_JS: adURL,\n iframeID: this.getID(),\n origin: getOrigin()\n }, this._templateConfig.extraOptions)\n );\n\n this._frame = frame;\n\n this._onLoad = utils.callbackTimeout(\n this._vpaidOptions.timeout,\n onLoad.bind(this),\n onTimeout.bind(this)\n );\n\n window.addEventListener('message', this._onLoad);\n\n function onLoad (e) {\n /*jshint validthis: false */\n //don't clear timeout\n if (e.origin !== getOrigin()) return;\n var result = JSON.parse(e.data);\n\n //don't clear timeout\n if (result.id !== that.getID()) return;\n\n var adUnit, error, createAd;\n if (!that._frame.contentWindow) {\n\n error = 'the iframe is not anymore in the DOM tree';\n\n } else {\n createAd = that._frame.contentWindow.getVPAIDAd;\n error = utils.validate(typeof createAd === 'function', 'the ad didn\\'t return a function to create an ad');\n }\n\n if (!error) {\n var adEl = that._frame.contentWindow.document.querySelector('.ad-element');\n adUnit = new VPAIDAdUnit(createAd(), adEl, that._videoEl, that._frame);\n adUnit.subscribe(AD_STOPPED, $adDestroyed.bind(that));\n error = utils.validate(adUnit.isValidVPAIDAd(), 'the add is not fully complaint with VPAID specification');\n }\n\n that._adUnit = adUnit;\n $destroyLoadListener.call(that);\n callback(error, error ? null : adUnit);\n\n //clear timeout\n return true;\n }\n\n function onTimeout() {\n callback('timeout', null);\n }\n};\n\n/**\n * unloadAdUnit\n *\n */\nVPAIDHTML5Client.prototype.unloadAdUnit = function unloadAdUnit() {\n $unloadPreviousAdUnit.call(this);\n};\n\n/**\n * getID will return the unique id\n *\n * @return {string}\n */\nVPAIDHTML5Client.prototype.getID = function () {\n return this._id;\n};\n\n\n/**\n * $removeEl\n *\n * @param {string} key\n */\nfunction $removeEl(key) {\n var el = this[key];\n if (el) {\n el.remove();\n delete this[key];\n }\n}\n\nfunction $adDestroyed() {\n $removeAdElements.call(this);\n delete this._adUnit;\n}\n\nfunction $unloadPreviousAdUnit() {\n $removeAdElements.call(this);\n $destroyAdUnit.call(this);\n}\n\nfunction $removeAdElements() {\n $removeEl.call(this, '_frame');\n $destroyLoadListener.call(this);\n}\n\n/**\n * $destroyLoadListener\n *\n */\nfunction $destroyLoadListener() {\n if (this._onLoad) {\n window.removeEventListener('message', this._onLoad);\n utils.clearCallbackTimeout(this._onLoad);\n delete this._onLoad;\n }\n}\n\n\nfunction $destroyAdUnit() {\n if (this._adUnit) {\n this._adUnit.stopAd();\n delete this._adUnit;\n }\n}\n\n/**\n * $throwIfDestroyed\n *\n */\nfunction $throwIfDestroyed() {\n if (this._destroyed) {\n throw new Error ('VPAIDHTML5Client already destroyed!');\n }\n}\n\nfunction getOrigin() {\n if( window.location.origin ) {\n return window.location.origin;\n }\n else {\n return window.location.protocol + \"//\" +\n window.location.hostname +\n (window.location.port ? ':' + window.location.port: '');\n }\n}\n\nmodule.exports = VPAIDHTML5Client;\nwindow.VPAIDHTML5Client = VPAIDHTML5Client;\n\n","'use strict';\n\nfunction Subscriber() {\n this._subscribers = {};\n}\n\nSubscriber.prototype.subscribe = function subscribe(handler, eventName, context) {\n if (!this.isHandlerAttached(handler, eventName)) {\n this.get(eventName).push({handler: handler, context: context, eventName: eventName});\n }\n};\n\nSubscriber.prototype.unsubscribe = function unsubscribe(handler, eventName) {\n this._subscribers[eventName] = this.get(eventName).filter(function (subscriber) {\n return handler !== subscriber.handler;\n });\n};\n\nSubscriber.prototype.unsubscribeAll = function unsubscribeAll() {\n this._subscribers = {};\n};\n\nSubscriber.prototype.trigger = function(eventName, data) {\n var that = this;\n var subscribers = this.get(eventName)\n .concat(this.get('*'));\n\n subscribers.forEach(function (subscriber) {\n setTimeout(function () {\n if (that.isHandlerAttached(subscriber.handler, subscriber.eventName)) {\n subscriber.handler.call(subscriber.context, data);\n }\n }, 0);\n });\n};\n\nSubscriber.prototype.triggerSync = function(eventName, data) {\n var subscribers = this.get(eventName)\n .concat(this.get('*'));\n\n subscribers.forEach(function (subscriber) {\n subscriber.handler.call(subscriber.context, data);\n });\n};\n\nSubscriber.prototype.get = function get(eventName) {\n if (!this._subscribers[eventName]) {\n this._subscribers[eventName] = [];\n }\n return this._subscribers[eventName];\n};\n\nSubscriber.prototype.isHandlerAttached = function isHandlerAttached(handler, eventName) {\n return this.get(eventName).some(function(subscriber) {\n return handler === subscriber.handler;\n })\n};\n\nmodule.exports = Subscriber;\n\n","'use strict';\n\n/**\n * noop a empty function\n */\nfunction noop() {}\n\n/**\n * validate if is not validate will return an Error with the message\n *\n * @param {boolean} isValid\n * @param {string} message\n */\nfunction validate(isValid, message) {\n return isValid ? null : new Error(message);\n}\n\nvar timeouts = {};\n/**\n * clearCallbackTimeout\n *\n * @param {function} func handler to remove\n */\nfunction clearCallbackTimeout(func) {\n var timeout = timeouts[func];\n if (timeout) {\n clearTimeout(timeout);\n delete timeouts[func];\n }\n}\n\n/**\n * callbackTimeout if the onSuccess is not called and returns true in the timelimit then onTimeout will be called\n *\n * @param {number} timer\n * @param {function} onSuccess\n * @param {function} onTimeout\n */\nfunction callbackTimeout(timer, onSuccess, onTimeout) {\n var callback, timeout;\n\n timeout = setTimeout(function () {\n onSuccess = noop;\n delete timeout[callback];\n onTimeout();\n }, timer);\n\n callback = function () {\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n if (onSuccess.apply(this, arguments)) {\n clearCallbackTimeout(callback);\n }\n };\n\n timeouts[callback] = timeout;\n\n return callback;\n}\n\n\n/**\n * createElementInEl\n *\n * @param {HTMLElement} parent\n * @param {string} tagName\n * @param {string} id\n */\nfunction createElementInEl(parent, tagName, id) {\n var nEl = document.createElement(tagName);\n if (id) nEl.id = id;\n parent.appendChild(nEl);\n return nEl;\n}\n\n/**\n * createIframeWithContent\n *\n * @param {HTMLElement} parent\n * @param {string} template simple template using {{var}}\n * @param {object} data\n */\nfunction createIframeWithContent(parent, template, data) {\n var iframe = createIframe(parent, null, data.zIndex);\n if (!setIframeContent(iframe, simpleTemplate(template, data))) return;\n return iframe;\n}\n\n/**\n * createIframe\n *\n * @param {HTMLElement} parent\n * @param {string} url\n */\nfunction createIframe(parent, url, zIndex) {\n var nEl = document.createElement('iframe');\n nEl.src = url || 'about:blank';\n nEl.marginWidth = '0';\n nEl.marginHeight = '0';\n nEl.frameBorder = '0';\n nEl.width = '100%';\n nEl.height = '100%';\n nEl.style.position = 'absolute';\n nEl.style.left = '0';\n nEl.style.top = '0';\n nEl.style.margin = '0px';\n nEl.style.padding = '0px';\n nEl.style.border = 'none';\n\n if(zIndex){\n nEl.style.zIndex = zIndex;\n }\n\n nEl.setAttribute('SCROLLING','NO');\n parent.innerHTML = '';\n parent.appendChild(nEl);\n return nEl;\n}\n\n/**\n * simpleTemplate\n *\n * @param {string} template\n * @param {object} data\n */\nfunction simpleTemplate(template, data) {\n Object.keys(data).forEach(function (key) {\n var value = (typeof value === 'object') ? JSON.stringify(data[key]) : data[key];\n template = template.replace(new RegExp('{{' + key + '}}', 'g'), value);\n });\n return template;\n}\n\n/**\n * setIframeContent\n *\n * @param {HTMLIframeElement} iframeEl\n * @param content\n */\nfunction setIframeContent(iframeEl, content) {\n var iframeDoc = iframeEl.contentWindow && iframeEl.contentWindow.document;\n if (!iframeDoc) return false;\n\n iframeDoc.write(content);\n\n return true;\n}\n\n\n/**\n * extend object with keys from another object\n *\n * @param {object} toExtend\n * @param {object} fromSource\n */\nfunction extend(toExtend, fromSource) {\n Object.keys(fromSource).forEach(function(key) {\n toExtend[key] = fromSource[key];\n });\n return toExtend;\n}\n\n\n/**\n * unique will create a unique string everytime is called, sequentially and prefixed\n *\n * @param {string} prefix\n */\nfunction unique(prefix) {\n var count = -1;\n return function () {\n return prefix + '_' + (++count);\n };\n}\n\nmodule.exports = {\n noop: noop,\n validate: validate,\n clearCallbackTimeout: clearCallbackTimeout,\n callbackTimeout: callbackTimeout,\n createElementInEl: createElementInEl,\n createIframeWithContent: createIframeWithContent,\n createIframe: createIframe,\n simpleTemplate: simpleTemplate,\n setIframeContent: setIframeContent,\n extend: extend,\n unique: unique\n};\n\n","/*! SWFObject v2.3.20130521 \r\n is released under the MIT License \r\n*/\r\n\r\n/* global ActiveXObject: false */\r\n\r\n(function (root, factory) {\r\n if (typeof define === 'function' && define.amd) {\r\n // AMD\r\n define(factory);\r\n } else if (typeof module === 'object' && module.exports) {\r\n // Node, CommonJS-like\r\n module.exports = factory();\r\n } else {\r\n // Browser globals (root is window)\r\n root.swfobject = factory();\r\n }\r\n}(this, function () {\r\n\r\n var UNDEF = \"undefined\",\r\n OBJECT = \"object\",\r\n SHOCKWAVE_FLASH = \"Shockwave Flash\",\r\n SHOCKWAVE_FLASH_AX = \"ShockwaveFlash.ShockwaveFlash\",\r\n FLASH_MIME_TYPE = \"application/x-shockwave-flash\",\r\n EXPRESS_INSTALL_ID = \"SWFObjectExprInst\",\r\n ON_READY_STATE_CHANGE = \"onreadystatechange\",\r\n\r\n win = window,\r\n doc = document,\r\n nav = navigator,\r\n\r\n plugin = false,\r\n domLoadFnArr = [],\r\n regObjArr = [],\r\n objIdArr = [],\r\n listenersArr = [],\r\n storedFbContent,\r\n storedFbContentId,\r\n storedCallbackFn,\r\n storedCallbackObj,\r\n isDomLoaded = false,\r\n isExpressInstallActive = false,\r\n dynamicStylesheet,\r\n dynamicStylesheetMedia,\r\n autoHideShow = true,\r\n encodeURIEnabled = false,\r\n\r\n /* Centralized function for browser feature detection\r\n - User agent string detection is only used when no good alternative is possible\r\n - Is executed directly for optimal performance\r\n */\r\n ua = function () {\r\n var w3cdom = typeof doc.getElementById !== UNDEF && typeof doc.getElementsByTagName !== UNDEF && typeof doc.createElement !== UNDEF,\r\n u = nav.userAgent.toLowerCase(),\r\n p = nav.platform.toLowerCase(),\r\n windows = p ? /win/.test(p) : /win/.test(u),\r\n mac = p ? /mac/.test(p) : /mac/.test(u),\r\n webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\\/(\\d+(\\.\\d+)?).*$/, \"$1\")) : false, // returns either the webkit version or false if not webkit\r\n ie = nav.appName === \"Microsoft Internet Explorer\",\r\n playerVersion = [0, 0, 0],\r\n d = null;\r\n if (typeof nav.plugins !== UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] === OBJECT) {\r\n d = nav.plugins[SHOCKWAVE_FLASH].description;\r\n // nav.mimeTypes[\"application/x-shockwave-flash\"].enabledPlugin indicates whether plug-ins are enabled or disabled in Safari 3+\r\n if (d && (typeof nav.mimeTypes !== UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) {\r\n plugin = true;\r\n ie = false; // cascaded feature detection for Internet Explorer\r\n d = d.replace(/^.*\\s+(\\S+\\s+\\S+$)/, \"$1\");\r\n playerVersion[0] = toInt(d.replace(/^(.*)\\..*$/, \"$1\"));\r\n playerVersion[1] = toInt(d.replace(/^.*\\.(.*)\\s.*$/, \"$1\"));\r\n playerVersion[2] = /[a-zA-Z]/.test(d) ? toInt(d.replace(/^.*[a-zA-Z]+(.*)$/, \"$1\")) : 0;\r\n }\r\n }\r\n else if (typeof win.ActiveXObject !== UNDEF) {\r\n try {\r\n var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);\r\n if (a) { // a will return null when ActiveX is disabled\r\n d = a.GetVariable(\"$version\");\r\n if (d) {\r\n ie = true; // cascaded feature detection for Internet Explorer\r\n d = d.split(\" \")[1].split(\",\");\r\n playerVersion = [toInt(d[0]), toInt(d[1]), toInt(d[2])];\r\n }\r\n }\r\n }\r\n catch (e) {}\r\n }\r\n return {w3: w3cdom, pv: playerVersion, wk: webkit, ie: ie, win: windows, mac: mac};\r\n }(),\r\n\r\n /* Cross-browser onDomLoad\r\n - Will fire an event as soon as the DOM of a web page is loaded\r\n - Internet Explorer workaround based on Diego Perini's solution: http://javascript.nwbox.com/IEContentLoaded/\r\n - Regular onload serves as fallback\r\n */\r\n onDomLoad = function () {\r\n if (!ua.w3) { return; }\r\n if ((typeof doc.readyState !== UNDEF && (doc.readyState === \"complete\" || doc.readyState === \"interactive\")) || (typeof doc.readyState === UNDEF && (doc.getElementsByTagName(\"body\")[0] || doc.body))) { // function is fired after onload, e.g. when script is inserted dynamically\r\n callDomLoadFunctions();\r\n }\r\n if (!isDomLoaded) {\r\n if (typeof doc.addEventListener !== UNDEF) {\r\n doc.addEventListener(\"DOMContentLoaded\", callDomLoadFunctions, false);\r\n }\r\n if (ua.ie) {\r\n doc.attachEvent(ON_READY_STATE_CHANGE, function detach() {\r\n if (doc.readyState === \"complete\") {\r\n doc.detachEvent(ON_READY_STATE_CHANGE, detach);\r\n callDomLoadFunctions();\r\n }\r\n });\r\n if (win == top) { // if not inside an iframe\r\n (function checkDomLoadedIE() {\r\n if (isDomLoaded) { return; }\r\n try {\r\n doc.documentElement.doScroll(\"left\");\r\n }\r\n catch (e) {\r\n setTimeout(checkDomLoadedIE, 0);\r\n return;\r\n }\r\n callDomLoadFunctions();\r\n }());\r\n }\r\n }\r\n if (ua.wk) {\r\n (function checkDomLoadedWK() {\r\n if (isDomLoaded) { return; }\r\n if (!/loaded|complete/.test(doc.readyState)) {\r\n setTimeout(checkDomLoadedWK, 0);\r\n return;\r\n }\r\n callDomLoadFunctions();\r\n }());\r\n }\r\n }\r\n }();\r\n\r\n function callDomLoadFunctions() {\r\n if (isDomLoaded || !document.getElementsByTagName(\"body\")[0]) { return; }\r\n try { // test if we can really add/remove elements to/from the DOM; we don't want to fire it too early\r\n var t, span = createElement(\"span\");\r\n span.style.display = \"none\"; //hide the span in case someone has styled spans via CSS\r\n t = doc.getElementsByTagName(\"body\")[0].appendChild(span);\r\n t.parentNode.removeChild(t);\r\n t = null; //clear the variables\r\n span = null;\r\n }\r\n catch (e) { return; }\r\n isDomLoaded = true;\r\n var dl = domLoadFnArr.length;\r\n for (var i = 0; i < dl; i++) {\r\n domLoadFnArr[i]();\r\n }\r\n }\r\n\r\n function addDomLoadEvent(fn) {\r\n if (isDomLoaded) {\r\n fn();\r\n }\r\n else {\r\n domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+\r\n }\r\n }\r\n\r\n /* Cross-browser onload\r\n - Based on James Edwards' solution: http://brothercake.com/site/resources/scripts/onload/\r\n - Will fire an event as soon as a web page including all of its assets are loaded\r\n */\r\n function addLoadEvent(fn) {\r\n if (typeof win.addEventListener !== UNDEF) {\r\n win.addEventListener(\"load\", fn, false);\r\n }\r\n else if (typeof doc.addEventListener !== UNDEF) {\r\n doc.addEventListener(\"load\", fn, false);\r\n }\r\n else if (typeof win.attachEvent !== UNDEF) {\r\n addListener(win, \"onload\", fn);\r\n }\r\n else if (typeof win.onload === \"function\") {\r\n var fnOld = win.onload;\r\n win.onload = function () {\r\n fnOld();\r\n fn();\r\n };\r\n }\r\n else {\r\n win.onload = fn;\r\n }\r\n }\r\n\r\n /* Detect the Flash Player version for non-Internet Explorer browsers\r\n - Detecting the plug-in version via the object element is more precise than using the plugins collection item's description:\r\n a. Both release and build numbers can be detected\r\n b. Avoid wrong descriptions by corrupt installers provided by Adobe\r\n c. Avoid wrong descriptions by multiple Flash Player entries in the plugin Array, caused by incorrect browser imports\r\n - Disadvantage of this method is that it depends on the availability of the DOM, while the plugins collection is immediately available\r\n */\r\n function testPlayerVersion() {\r\n var b = doc.getElementsByTagName(\"body\")[0];\r\n var o = createElement(OBJECT);\r\n o.setAttribute(\"style\", \"visibility: hidden;\");\r\n o.setAttribute(\"type\", FLASH_MIME_TYPE);\r\n var t = b.appendChild(o);\r\n if (t) {\r\n var counter = 0;\r\n (function checkGetVariable() {\r\n if (typeof t.GetVariable !== UNDEF) {\r\n try {\r\n var d = t.GetVariable(\"$version\");\r\n if (d) {\r\n d = d.split(\" \")[1].split(\",\");\r\n ua.pv = [toInt(d[0]), toInt(d[1]), toInt(d[2])];\r\n }\r\n } catch (e) {\r\n //t.GetVariable(\"$version\") is known to fail in Flash Player 8 on Firefox\r\n //If this error is encountered, assume FP8 or lower. Time to upgrade.\r\n ua.pv = [8, 0, 0];\r\n }\r\n }\r\n else if (counter < 10) {\r\n counter++;\r\n setTimeout(checkGetVariable, 10);\r\n return;\r\n }\r\n b.removeChild(o);\r\n t = null;\r\n matchVersions();\r\n }());\r\n }\r\n else {\r\n matchVersions();\r\n }\r\n }\r\n\r\n /* Perform Flash Player and SWF version matching; static publishing only\r\n */\r\n function matchVersions() {\r\n var rl = regObjArr.length;\r\n if (rl > 0) {\r\n for (var i = 0; i < rl; i++) { // for each registered object element\r\n var id = regObjArr[i].id;\r\n var cb = regObjArr[i].callbackFn;\r\n var cbObj = {success: false, id: id};\r\n if (ua.pv[0] > 0) {\r\n var obj = getElementById(id);\r\n if (obj) {\r\n if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { // Flash Player version >= published SWF version: Houston, we have a match!\r\n setVisibility(id, true);\r\n if (cb) {\r\n cbObj.success = true;\r\n cbObj.ref = getObjectById(id);\r\n cbObj.id = id;\r\n cb(cbObj);\r\n }\r\n }\r\n else if (regObjArr[i].expressInstall && canExpressInstall()) { // show the Adobe Express Install dialog if set by the web page author and if supported\r\n var att = {};\r\n att.data = regObjArr[i].expressInstall;\r\n att.width = obj.getAttribute(\"width\") || \"0\";\r\n att.height = obj.getAttribute(\"height\") || \"0\";\r\n if (obj.getAttribute(\"class\")) { att.styleclass = obj.getAttribute(\"class\"); }\r\n if (obj.getAttribute(\"align\")) { att.align = obj.getAttribute(\"align\"); }\r\n // parse HTML object param element's name-value pairs\r\n var par = {};\r\n var p = obj.getElementsByTagName(\"param\");\r\n var pl = p.length;\r\n for (var j = 0; j < pl; j++) {\r\n if (p[j].getAttribute(\"name\").toLowerCase() !== \"movie\") {\r\n par[p[j].getAttribute(\"name\")] = p[j].getAttribute(\"value\");\r\n }\r\n }\r\n showExpressInstall(att, par, id, cb);\r\n }\r\n else { // Flash Player and SWF version mismatch or an older Webkit engine that ignores the HTML object element's nested param elements: display fallback content instead of SWF\r\n displayFbContent(obj);\r\n if (cb) { cb(cbObj); }\r\n }\r\n }\r\n }\r\n else { // if no Flash Player is installed or the fp version cannot be detected we let the HTML object element do its job (either show a SWF or fallback content)\r\n setVisibility(id, true);\r\n if (cb) {\r\n var o = getObjectById(id); // test whether there is an HTML object element or not\r\n if (o && typeof o.SetVariable !== UNDEF) {\r\n cbObj.success = true;\r\n cbObj.ref = o;\r\n cbObj.id = o.id;\r\n }\r\n cb(cbObj);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /* Main function\r\n - Will preferably execute onDomLoad, otherwise onload (as a fallback)\r\n */\r\n domLoadFnArr[0] = function () {\r\n if (plugin) {\r\n testPlayerVersion();\r\n }\r\n else {\r\n matchVersions();\r\n }\r\n };\r\n\r\n function getObjectById(objectIdStr) {\r\n var r = null,\r\n o = getElementById(objectIdStr);\r\n\r\n if (o && o.nodeName.toUpperCase() === \"OBJECT\") {\r\n //If targeted object is valid Flash file\r\n if (typeof o.SetVariable !== UNDEF) {\r\n r = o;\r\n } else {\r\n //If SetVariable is not working on targeted object but a nested object is\r\n //available, assume classic nested object markup. Return nested object.\r\n\r\n //If SetVariable is not working on targeted object and there is no nested object,\r\n //return the original object anyway. This is probably new simplified markup.\r\n\r\n r = o.getElementsByTagName(OBJECT)[0] || o;\r\n }\r\n }\r\n\r\n return r;\r\n }\r\n\r\n /* Requirements for Adobe Express Install\r\n - only one instance can be active at a time\r\n - fp 6.0.65 or higher\r\n - Win/Mac OS only\r\n - no Webkit engines older than version 312\r\n */\r\n function canExpressInstall() {\r\n return !isExpressInstallActive && hasPlayerVersion(\"6.0.65\") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);\r\n }\r\n\r\n /* Show the Adobe Express Install dialog\r\n - Reference: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75\r\n */\r\n function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {\r\n\r\n var obj = getElementById(replaceElemIdStr);\r\n\r\n //Ensure that replaceElemIdStr is really a string and not an element\r\n replaceElemIdStr = getId(replaceElemIdStr);\r\n\r\n isExpressInstallActive = true;\r\n storedCallbackFn = callbackFn || null;\r\n storedCallbackObj = {success: false, id: replaceElemIdStr};\r\n\r\n if (obj) {\r\n if (obj.nodeName.toUpperCase() === \"OBJECT\") { // static publishing\r\n storedFbContent = abstractFbContent(obj);\r\n storedFbContentId = null;\r\n }\r\n else { // dynamic publishing\r\n storedFbContent = obj;\r\n storedFbContentId = replaceElemIdStr;\r\n }\r\n att.id = EXPRESS_INSTALL_ID;\r\n if (typeof att.width === UNDEF || (!/%$/.test(att.width) && toInt(att.width) < 310)) { att.width = \"310\"; }\r\n if (typeof att.height === UNDEF || (!/%$/.test(att.height) && toInt(att.height) < 137)) { att.height = \"137\"; }\r\n var pt = ua.ie ? \"ActiveX\" : \"PlugIn\",\r\n fv = \"MMredirectURL=\" + encodeURIComponent(win.location.toString().replace(/&/g, \"%26\")) + \"&MMplayerType=\" + pt + \"&MMdoctitle=\" + encodeURIComponent(doc.title.slice(0, 47) + \" - Flash Player Installation\");\r\n if (typeof par.flashvars !== UNDEF) {\r\n par.flashvars += \"&\" + fv;\r\n }\r\n else {\r\n par.flashvars = fv;\r\n }\r\n // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it,\r\n // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work\r\n if (ua.ie && obj.readyState != 4) {\r\n var newObj = createElement(\"div\");\r\n replaceElemIdStr += \"SWFObjectNew\";\r\n newObj.setAttribute(\"id\", replaceElemIdStr);\r\n obj.parentNode.insertBefore(newObj, obj); // insert placeholder div that will be replaced by the object element that loads expressinstall.swf\r\n obj.style.display = \"none\";\r\n removeSWF(obj); //removeSWF accepts elements now\r\n }\r\n createSWF(att, par, replaceElemIdStr);\r\n }\r\n }\r\n\r\n /* Functions to abstract and display fallback content\r\n */\r\n function displayFbContent(obj) {\r\n if (ua.ie && obj.readyState != 4) {\r\n // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it,\r\n // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work\r\n obj.style.display = \"none\";\r\n var el = createElement(\"div\");\r\n obj.parentNode.insertBefore(el, obj); // insert placeholder div that will be replaced by the fallback content\r\n el.parentNode.replaceChild(abstractFbContent(obj), el);\r\n removeSWF(obj); //removeSWF accepts elements now\r\n }\r\n else {\r\n obj.parentNode.replaceChild(abstractFbContent(obj), obj);\r\n }\r\n }\r\n\r\n function abstractFbContent(obj) {\r\n var ac = createElement(\"div\");\r\n if (ua.win && ua.ie) {\r\n ac.innerHTML = obj.innerHTML;\r\n }\r\n else {\r\n var nestedObj = obj.getElementsByTagName(OBJECT)[0];\r\n if (nestedObj) {\r\n var c = nestedObj.childNodes;\r\n if (c) {\r\n var cl = c.length;\r\n for (var i = 0; i < cl; i++) {\r\n if (!(c[i].nodeType == 1 && c[i].nodeName === \"PARAM\") && !(c[i].nodeType == 8)) {\r\n ac.appendChild(c[i].cloneNode(true));\r\n }\r\n }\r\n }\r\n }\r\n }\r\n return ac;\r\n }\r\n\r\n function createIeObject(url, paramStr) {\r\n var div = createElement(\"div\");\r\n div.innerHTML = \"\" + paramStr + \"\";\r\n return div.firstChild;\r\n }\r\n\r\n /* Cross-browser dynamic SWF creation\r\n */\r\n function createSWF(attObj, parObj, id) {\r\n var r, el = getElementById(id);\r\n id = getId(id); // ensure id is truly an ID and not an element\r\n\r\n if (ua.wk && ua.wk < 312) { return r; }\r\n\r\n if (el) {\r\n var o = (ua.ie) ? createElement(\"div\") : createElement(OBJECT),\r\n attr,\r\n attrLower,\r\n param;\r\n\r\n if (typeof attObj.id === UNDEF) { // if no 'id' is defined for the object element, it will inherit the 'id' from the fallback content\r\n attObj.id = id;\r\n }\r\n\r\n //Add params\r\n for (param in parObj) {\r\n //filter out prototype additions from other potential libraries and IE specific param element\r\n if (parObj.hasOwnProperty(param) && param.toLowerCase() !== \"movie\") {\r\n createObjParam(o, param, parObj[param]);\r\n }\r\n }\r\n\r\n //Create IE object, complete with param nodes\r\n if (ua.ie) { o = createIeObject(attObj.data, o.innerHTML); }\r\n\r\n //Add attributes to object\r\n for (attr in attObj) {\r\n if (attObj.hasOwnProperty(attr)) { // filter out prototype additions from other potential libraries\r\n attrLower = attr.toLowerCase();\r\n\r\n // 'class' is an ECMA4 reserved keyword\r\n if (attrLower === \"styleclass\") {\r\n o.setAttribute(\"class\", attObj[attr]);\r\n } else if (attrLower !== \"classid\" && attrLower !== \"data\") {\r\n o.setAttribute(attr, attObj[attr]);\r\n }\r\n }\r\n }\r\n\r\n if (ua.ie) {\r\n objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on unload (dynamic publishing only)\r\n } else {\r\n o.setAttribute(\"type\", FLASH_MIME_TYPE);\r\n o.setAttribute(\"data\", attObj.data);\r\n }\r\n\r\n el.parentNode.replaceChild(o, el);\r\n r = o;\r\n }\r\n\r\n return r;\r\n }\r\n\r\n function createObjParam(el, pName, pValue) {\r\n var p = createElement(\"param\");\r\n p.setAttribute(\"name\", pName);\r\n p.setAttribute(\"value\", pValue);\r\n el.appendChild(p);\r\n }\r\n\r\n /* Cross-browser SWF removal\r\n - Especially needed to safely and completely remove a SWF in Internet Explorer\r\n */\r\n function removeSWF(id) {\r\n var obj = getElementById(id);\r\n if (obj && obj.nodeName.toUpperCase() === \"OBJECT\") {\r\n if (ua.ie) {\r\n obj.style.display = \"none\";\r\n (function removeSWFInIE() {\r\n if (obj.readyState == 4) {\r\n //This step prevents memory leaks in Internet Explorer\r\n for (var i in obj) {\r\n if (typeof obj[i] === \"function\") {\r\n obj[i] = null;\r\n }\r\n }\r\n obj.parentNode.removeChild(obj);\r\n } else {\r\n setTimeout(removeSWFInIE, 10);\r\n }\r\n }());\r\n }\r\n else {\r\n obj.parentNode.removeChild(obj);\r\n }\r\n }\r\n }\r\n\r\n function isElement(id) {\r\n return (id && id.nodeType && id.nodeType === 1);\r\n }\r\n\r\n function getId(thing) {\r\n return (isElement(thing)) ? thing.id : thing;\r\n }\r\n\r\n /* Functions to optimize JavaScript compression\r\n */\r\n function getElementById(id) {\r\n\r\n //Allow users to pass an element OR an element's ID\r\n if (isElement(id)) { return id; }\r\n\r\n var el = null;\r\n try {\r\n el = doc.getElementById(id);\r\n }\r\n catch (e) {}\r\n return el;\r\n }\r\n\r\n function createElement(el) {\r\n return doc.createElement(el);\r\n }\r\n\r\n //To aid compression; replaces 14 instances of pareseInt with radix\r\n function toInt(str) {\r\n return parseInt(str, 10);\r\n }\r\n\r\n /* Updated attachEvent function for Internet Explorer\r\n - Stores attachEvent information in an Array, so on unload the detachEvent functions can be called to avoid memory leaks\r\n */\r\n function addListener(target, eventType, fn) {\r\n target.attachEvent(eventType, fn);\r\n listenersArr[listenersArr.length] = [target, eventType, fn];\r\n }\r\n\r\n /* Flash Player and SWF content version matching\r\n */\r\n function hasPlayerVersion(rv) {\r\n rv += \"\"; //Coerce number to string, if needed.\r\n var pv = ua.pv, v = rv.split(\".\");\r\n v[0] = toInt(v[0]);\r\n v[1] = toInt(v[1]) || 0; // supports short notation, e.g. \"9\" instead of \"9.0.0\"\r\n v[2] = toInt(v[2]) || 0;\r\n return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;\r\n }\r\n\r\n /* Cross-browser dynamic CSS creation\r\n - Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php\r\n */\r\n function createCSS(sel, decl, media, newStyle) {\r\n var h = doc.getElementsByTagName(\"head\")[0];\r\n if (!h) { return; } // to also support badly authored HTML pages that lack a head element\r\n var m = (typeof media === \"string\") ? media : \"screen\";\r\n if (newStyle) {\r\n dynamicStylesheet = null;\r\n dynamicStylesheetMedia = null;\r\n }\r\n if (!dynamicStylesheet || dynamicStylesheetMedia != m) {\r\n // create dynamic stylesheet + get a global reference to it\r\n var s = createElement(\"style\");\r\n s.setAttribute(\"type\", \"text/css\");\r\n s.setAttribute(\"media\", m);\r\n dynamicStylesheet = h.appendChild(s);\r\n if (ua.ie && typeof doc.styleSheets !== UNDEF && doc.styleSheets.length > 0) {\r\n dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];\r\n }\r\n dynamicStylesheetMedia = m;\r\n }\r\n // add style rule\r\n if (dynamicStylesheet) {\r\n if (typeof dynamicStylesheet.addRule !== UNDEF) {\r\n dynamicStylesheet.addRule(sel, decl);\r\n } else if (typeof doc.createTextNode !== UNDEF) {\r\n dynamicStylesheet.appendChild(doc.createTextNode(sel + \" {\" + decl + \"}\"));\r\n }\r\n }\r\n }\r\n\r\n function setVisibility(id, isVisible) {\r\n if (!autoHideShow) { return; }\r\n var v = isVisible ? \"visible\" : \"hidden\",\r\n el = getElementById(id);\r\n if (isDomLoaded && el) {\r\n el.style.visibility = v;\r\n } else if (typeof id === \"string\") {\r\n createCSS(\"#\" + id, \"visibility:\" + v);\r\n }\r\n }\r\n\r\n /* Filter to avoid XSS attacks\r\n */\r\n function urlEncodeIfNecessary(s) {\r\n var regex = /[\\\\\\\"<>\\.;]/;\r\n var hasBadChars = regex.exec(s) !== null;\r\n return hasBadChars && typeof encodeURIComponent !== UNDEF ? encodeURIComponent(s) : s;\r\n }\r\n\r\n /* Release memory to avoid memory leaks caused by closures, fix hanging audio/video threads and force open sockets/NetConnections to disconnect (Internet Explorer only)\r\n */\r\n var cleanup = function () {\r\n if (ua.ie) {\r\n window.attachEvent(\"onunload\", function () {\r\n // remove listeners to avoid memory leaks\r\n var ll = listenersArr.length;\r\n for (var i = 0; i < ll; i++) {\r\n listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);\r\n }\r\n // cleanup dynamically embedded objects to fix audio/video threads and force open sockets and NetConnections to disconnect\r\n var il = objIdArr.length;\r\n for (var j = 0; j < il; j++) {\r\n removeSWF(objIdArr[j]);\r\n }\r\n // cleanup library's main closures to avoid memory leaks\r\n for (var k in ua) {\r\n ua[k] = null;\r\n }\r\n ua = null;\r\n for (var l in swfobject) {\r\n swfobject[l] = null;\r\n }\r\n swfobject = null;\r\n });\r\n }\r\n }();\r\n\r\n return {\r\n /* Public API\r\n - Reference: http://code.google.com/p/swfobject/wiki/documentation\r\n */\r\n registerObject: function (objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {\r\n if (ua.w3 && objectIdStr && swfVersionStr) {\r\n var regObj = {};\r\n regObj.id = objectIdStr;\r\n regObj.swfVersion = swfVersionStr;\r\n regObj.expressInstall = xiSwfUrlStr;\r\n regObj.callbackFn = callbackFn;\r\n regObjArr[regObjArr.length] = regObj;\r\n setVisibility(objectIdStr, false);\r\n }\r\n else if (callbackFn) {\r\n callbackFn({success: false, id: objectIdStr});\r\n }\r\n },\r\n\r\n getObjectById: function (objectIdStr) {\r\n if (ua.w3) {\r\n return getObjectById(objectIdStr);\r\n }\r\n },\r\n\r\n embedSWF: function (swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {\r\n\r\n var id = getId(replaceElemIdStr),\r\n callbackObj = {success: false, id: id};\r\n\r\n if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {\r\n setVisibility(id, false);\r\n addDomLoadEvent(function () {\r\n widthStr += \"\"; // auto-convert to string\r\n heightStr += \"\";\r\n var att = {};\r\n if (attObj && typeof attObj === OBJECT) {\r\n for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs\r\n att[i] = attObj[i];\r\n }\r\n }\r\n att.data = swfUrlStr;\r\n att.width = widthStr;\r\n att.height = heightStr;\r\n var par = {};\r\n if (parObj && typeof parObj === OBJECT) {\r\n for (var j in parObj) { // copy object to avoid the use of references, because web authors often reuse parObj for multiple SWFs\r\n par[j] = parObj[j];\r\n }\r\n }\r\n if (flashvarsObj && typeof flashvarsObj === OBJECT) {\r\n for (var k in flashvarsObj) { // copy object to avoid the use of references, because web authors often reuse flashvarsObj for multiple SWFs\r\n if (flashvarsObj.hasOwnProperty(k)) {\r\n\r\n var key = (encodeURIEnabled) ? encodeURIComponent(k) : k,\r\n value = (encodeURIEnabled) ? encodeURIComponent(flashvarsObj[k]) : flashvarsObj[k];\r\n\r\n if (typeof par.flashvars !== UNDEF) {\r\n par.flashvars += \"&\" + key + \"=\" + value;\r\n }\r\n else {\r\n par.flashvars = key + \"=\" + value;\r\n }\r\n\r\n }\r\n }\r\n }\r\n if (hasPlayerVersion(swfVersionStr)) { // create SWF\r\n var obj = createSWF(att, par, replaceElemIdStr);\r\n if (att.id == id) {\r\n setVisibility(id, true);\r\n }\r\n callbackObj.success = true;\r\n callbackObj.ref = obj;\r\n callbackObj.id = obj.id;\r\n }\r\n else if (xiSwfUrlStr && canExpressInstall()) { // show Adobe Express Install\r\n att.data = xiSwfUrlStr;\r\n showExpressInstall(att, par, replaceElemIdStr, callbackFn);\r\n return;\r\n }\r\n else { // show fallback content\r\n setVisibility(id, true);\r\n }\r\n if (callbackFn) { callbackFn(callbackObj); }\r\n });\r\n }\r\n else if (callbackFn) { callbackFn(callbackObj); }\r\n },\r\n\r\n switchOffAutoHideShow: function () {\r\n autoHideShow = false;\r\n },\r\n\r\n enableUriEncoding: function (bool) {\r\n encodeURIEnabled = (typeof bool === UNDEF) ? true : bool;\r\n },\r\n\r\n ua: ua,\r\n\r\n getFlashPlayerVersion: function () {\r\n return {major: ua.pv[0], minor: ua.pv[1], release: ua.pv[2]};\r\n },\r\n\r\n hasFlashPlayerVersion: hasPlayerVersion,\r\n\r\n createSWF: function (attObj, parObj, replaceElemIdStr) {\r\n if (ua.w3) {\r\n return createSWF(attObj, parObj, replaceElemIdStr);\r\n }\r\n else {\r\n return undefined;\r\n }\r\n },\r\n\r\n showExpressInstall: function (att, par, replaceElemIdStr, callbackFn) {\r\n if (ua.w3 && canExpressInstall()) {\r\n showExpressInstall(att, par, replaceElemIdStr, callbackFn);\r\n }\r\n },\r\n\r\n removeSWF: function (objElemIdStr) {\r\n if (ua.w3) {\r\n removeSWF(objElemIdStr);\r\n }\r\n },\r\n\r\n createCSS: function (selStr, declStr, mediaStr, newStyleBoolean) {\r\n if (ua.w3) {\r\n createCSS(selStr, declStr, mediaStr, newStyleBoolean);\r\n }\r\n },\r\n\r\n addDomLoadEvent: addDomLoadEvent,\r\n\r\n addLoadEvent: addLoadEvent,\r\n\r\n getQueryParamValue: function (param) {\r\n var q = doc.location.search || doc.location.hash;\r\n if (q) {\r\n if (/\\?/.test(q)) { q = q.split(\"?\")[1]; } // strip question mark\r\n if (!param) {\r\n return urlEncodeIfNecessary(q);\r\n }\r\n var pairs = q.split(\"&\");\r\n for (var i = 0; i < pairs.length; i++) {\r\n if (pairs[i].substring(0, pairs[i].indexOf(\"=\")) == param) {\r\n return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf(\"=\") + 1)));\r\n }\r\n }\r\n }\r\n return \"\";\r\n },\r\n\r\n // For internal usage only\r\n expressInstallCallback: function () {\r\n if (isExpressInstallActive) {\r\n var obj = getElementById(EXPRESS_INSTALL_ID);\r\n if (obj && storedFbContent) {\r\n obj.parentNode.replaceChild(storedFbContent, obj);\r\n if (storedFbContentId) {\r\n setVisibility(storedFbContentId, true);\r\n if (ua.ie) { storedFbContent.style.display = \"block\"; }\r\n }\r\n if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }\r\n }\r\n isExpressInstallActive = false;\r\n }\r\n },\r\n\r\n version: \"2.3\"\r\n\r\n };\r\n}));\r\n","'use strict';\n\nvar InLine = require('./InLine');\nvar Wrapper = require('./Wrapper');\n\nfunction Ad(adJTree) {\n if (!(this instanceof Ad)) {\n return new Ad(adJTree);\n }\n this.initialize(adJTree);\n}\n\nAd.prototype.initialize = function(adJTree) {\n this.id = adJTree.attr('id');\n this.sequence = adJTree.attr('sequence');\n\n if(adJTree.inLine) {\n this.inLine = new InLine(adJTree.inLine);\n }\n\n if(adJTree.wrapper){\n this.wrapper = new Wrapper(adJTree.wrapper);\n }\n};\n\nmodule.exports = Ad;","'use strict';\n\nvar TrackingEvent = require('./TrackingEvent');\n\nvar utilities = require('../../utils/utilityFunctions');\n\nvar xml = require('../../utils/xml');\n\n\nfunction Companion(companionJTree) {\n if (!(this instanceof Companion)) {\n return new Companion(companionJTree);\n }\n\n //Required Elements\n this.creativeType = xml.attr(companionJTree.staticResource, 'creativeType');\n this.staticResource = xml.keyValue(companionJTree.staticResource);\n\n // Weird bug when the JXON tree is built it doesn't handle casing properly in this situation...\n var htmlResource = null;\n if (xml.keyValue(companionJTree.HTMLResource)) {\n htmlResource = xml.keyValue(companionJTree.HTMLResource);\n } else if (xml.keyValue(companionJTree.hTMLResource)) {\n htmlResource = xml.keyValue(companionJTree.hTMLResource);\n }\n this.htmlResource = htmlResource;\n\n var iframeResource = null;\n if (xml.keyValue(companionJTree.IFrameResource)) {\n iframeResource = xml.keyValue(companionJTree.IFrameResource);\n } else if (xml.keyValue(companionJTree.iFrameresource)) {\n iframeResource = xml.keyValue(companionJTree.iFrameresource);\n }\n this.iframeResource = iframeResource;\n\n //Optional fields\n this.id = xml.attr(companionJTree, 'id');\n this.width = xml.attr(companionJTree, 'width');\n this.height = xml.attr(companionJTree, 'height');\n this.expandedWidth = xml.attr(companionJTree, 'expandedWidth');\n this.expandedHeight = xml.attr(companionJTree, 'expandedHeight');\n this.scalable = xml.attr(companionJTree, 'scalable');\n this.maintainAspectRatio = xml.attr(companionJTree, 'maintainAspectRatio');\n this.minSuggestedDuration = xml.attr(companionJTree, 'minSuggestedDuration');\n this.apiFramework = xml.attr(companionJTree, 'apiFramework');\n this.companionClickThrough = xml.keyValue(companionJTree.companionClickThrough);\n this.trackingEvents = parseTrackingEvents(companionJTree.trackingEvents && companionJTree.trackingEvents.tracking);\n\n /*** Local functions ***/\n function parseTrackingEvents(trackingEvents) {\n var trackings = [];\n if (utilities.isDefined(trackingEvents)) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingData) {\n trackings.push(new TrackingEvent(trackingData));\n });\n }\n return trackings;\n }\n}\n\nmodule.exports = Companion;","'use strict';\n\nvar Linear = require('./Linear');\nvar Companion = require('./Companion');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction Creative(creativeJTree) {\n if(!(this instanceof Creative)) {\n return new Creative(creativeJTree);\n }\n\n this.id = creativeJTree.attr('id');\n this.sequence = creativeJTree.attr('sequence');\n this.adId = creativeJTree.attr('adId');\n this.apiFramework = creativeJTree.attr('apiFramework');\n\n if(creativeJTree.linear) {\n this.linear = new Linear(creativeJTree.linear);\n }\n\n if (creativeJTree.companionAds) {\n var companions = [];\n var companionAds = creativeJTree.companionAds && creativeJTree.companionAds.companion;\n if (utilities.isDefined(companionAds)) {\n companionAds = utilities.isArray(companionAds) ? companionAds : [companionAds];\n companionAds.forEach(function (companionData) {\n companions.push(new Companion(companionData));\n });\n }\n this.companionAds = companions;\n }\n}\n\n/**\n * Returns true if the browser supports at the creative.\n */\nCreative.prototype.isSupported = function(){\n if(this.linear) {\n return this.linear.isSupported();\n }\n\n return true;\n};\n\nCreative.parseCreatives = function parseCreatives(creativesJTree) {\n var creatives = [];\n var creativesData;\n if (utilities.isDefined(creativesJTree) && utilities.isDefined(creativesJTree.creative)) {\n creativesData = utilities.isArray(creativesJTree.creative) ? creativesJTree.creative : [creativesJTree.creative];\n creativesData.forEach(function (creative) {\n creatives.push(new Creative(creative));\n });\n }\n return creatives;\n};\n\nmodule.exports = Creative;\n","'use strict';\n\nvar vastUtil = require('./vastUtil');\nvar Creative = require('./Creative');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction InLine(inlineJTree) {\n if (!(this instanceof InLine)) {\n return new InLine(inlineJTree);\n }\n\n //Required Fields\n this.adTitle = xml.keyValue(inlineJTree.adTitle);\n this.adSystem = xml.keyValue(inlineJTree.adSystem);\n this.impressions = vastUtil.parseImpressions(inlineJTree.impression);\n this.creatives = Creative.parseCreatives(inlineJTree.creatives);\n\n //Optional Fields\n this.description = xml.keyValue(inlineJTree.description);\n this.advertiser = xml.keyValue(inlineJTree.advertiser);\n this.surveys = parseSurveys(inlineJTree.survey);\n this.error = xml.keyValue(inlineJTree.error);\n this.pricing = xml.keyValue(inlineJTree.pricing);\n this.extensions = inlineJTree.extensions;\n\n /*** Local Functions ***/\n function parseSurveys(inlineSurveys) {\n if (inlineSurveys) {\n return utilities.transformArray(utilities.isArray(inlineSurveys) ? inlineSurveys : [inlineSurveys], function (survey) {\n if(utilities.isNotEmptyString(survey.keyValue)){\n return {\n uri: survey.keyValue,\n type: survey.attr('type')\n };\n }\n\n return undefined;\n });\n }\n return [];\n }\n}\n\n\n/**\n * Returns true if the browser supports all the creatives.\n */\nInLine.prototype.isSupported = function(){\n var i,len;\n\n if(this.creatives.length === 0) {\n return false;\n }\n\n for(i = 0, len = this.creatives.length; i< len; i+=1){\n if(!this.creatives[i].isSupported()){\n return false;\n }\n }\n return true;\n};\n\nmodule.exports = InLine;\n","'use strict';\n\nvar TrackingEvent = require('./TrackingEvent');\nvar MediaFile = require('./MediaFile');\nvar VideoClicks = require('./VideoClicks');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar parsers = require('./parsers');\n\nvar xml = require('../../utils/xml');\n\n\nfunction Linear(linearJTree) {\n if (!(this instanceof Linear)) {\n return new Linear(linearJTree);\n }\n\n //Required Elements\n this.duration = parsers.duration(xml.keyValue(linearJTree.duration));\n this.mediaFiles = parseMediaFiles(linearJTree.mediaFiles && linearJTree.mediaFiles.mediaFile);\n\n //Optional fields\n this.trackingEvents = parseTrackingEvents(linearJTree.trackingEvents && linearJTree.trackingEvents.tracking, this.duration);\n this.skipoffset = parsers.offset(xml.attr(linearJTree, 'skipoffset'), this.duration);\n\n if (linearJTree.videoClicks) {\n this.videoClicks = new VideoClicks(linearJTree.videoClicks);\n }\n\n if(linearJTree.adParameters) {\n this.adParameters = xml.keyValue(linearJTree.adParameters);\n\n if(xml.attr(linearJTree.adParameters, 'xmlEncoded')){\n this.adParameters = xml.decode(this.adParameters);\n }\n }\n\n /*** Local functions ***/\n function parseTrackingEvents(trackingEvents, duration) {\n var trackings = [];\n if (utilities.isDefined(trackingEvents)) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingData) {\n trackings.push(new TrackingEvent(trackingData, duration));\n });\n }\n return trackings;\n }\n\n function parseMediaFiles(mediaFilesJxonTree) {\n var mediaFiles = [];\n if (utilities.isDefined(mediaFilesJxonTree)) {\n mediaFilesJxonTree = utilities.isArray(mediaFilesJxonTree) ? mediaFilesJxonTree : [mediaFilesJxonTree];\n\n mediaFilesJxonTree.forEach(function (mfData) {\n mediaFiles.push(new MediaFile(mfData));\n });\n }\n return mediaFiles;\n }\n}\n\n/**\n * Must return true if at least one of the MediaFiles' type is supported\n */\nLinear.prototype.isSupported = function () {\n var i, len;\n for(i=0, len=this.mediaFiles.length; i 0) {\n getAd(waterfallAds.shift(),[], waterfallHandler);\n } else {\n callback(error, adChain);\n }\n } else {\n callback(null, adChain);\n }\n }\n });\n\n /*** Local functions ***/\n function getAdWaterfall(adTagUrl, callback) {\n var requestVastXML = that._requestVASTXml.bind(that, adTagUrl);\n async.waterfall([\n requestVastXML,\n buildVastWaterfall\n ], callback);\n }\n\n function buildVastWaterfall(xmlStr, callback) {\n var vastTree;\n try {\n vastTree = xml.toJXONTree(xmlStr);\n\n if(utilities.isArray(vastTree.ad)) {\n vastTree.ads = vastTree.ad;\n } else if(vastTree.ad){\n vastTree.ads = [vastTree.ad];\n } else {\n vastTree.ads = [];\n }\n callback(validateVASTTree(vastTree), vastTree);\n\n } catch (e) {\n callback(new VASTError(\"on VASTClient.getVASTAd.buildVastWaterfall, error parsing xml\", 100), null);\n }\n }\n\n function validateVASTTree(vastTree) {\n var vastVersion = xml.attr(vastTree, 'version');\n\n if (!vastTree.ad) {\n return new VASTError('on VASTClient.getVASTAd.validateVASTTree, no Ad in VAST tree', 303);\n }\n\n if (vastVersion && (vastVersion != 3 && vastVersion != 2)) {\n return new VASTError('on VASTClient.getVASTAd.validateVASTTree, not supported VAST version \"' + vastVersion + '\"', 102);\n }\n\n return null;\n }\n\n function getAd(adTagUrl, adChain, callback) {\n if (adChain.length >= that.WRAPPER_LIMIT) {\n return callback(new VASTError(\"on VASTClient.getVASTAd.getAd, players wrapper limit reached (the limit is \" + that.WRAPPER_LIMIT + \")\", 302), adChain);\n }\n\n async.waterfall([\n function (next) {\n if (utilities.isString(adTagUrl)) {\n requestVASTAd(adTagUrl, next);\n } else {\n next(null, adTagUrl);\n }\n },\n buildAd\n ], function (error, ad) {\n if (ad) {\n adChain.push(ad);\n }\n\n if (error) {\n return callback(error, adChain);\n }\n\n if (ad.wrapper) {\n return getAd(ad.wrapper.VASTAdTagURI, adChain, callback);\n }\n\n return callback(null, adChain);\n });\n }\n\n function buildAd(adJxonTree, callback) {\n try {\n var ad = new Ad(adJxonTree);\n callback(validateAd(ad), ad);\n } catch (e) {\n callback(new VASTError('on VASTClient.getVASTAd.buildAd, error parsing xml', 100), null);\n }\n }\n\n function validateAd(ad) {\n var wrapper = ad.wrapper;\n var inLine = ad.inLine;\n var errMsgPrefix = 'on VASTClient.getVASTAd.validateAd, ';\n\n if (inLine && wrapper) {\n return new VASTError(errMsgPrefix +\"InLine and Wrapper both found on the same Ad\", 101);\n }\n\n if (!inLine && !wrapper) {\n return new VASTError(errMsgPrefix + \"nor wrapper nor inline elements found on the Ad\", 101);\n }\n\n if (inLine && !inLine.isSupported()) {\n return new VASTError(errMsgPrefix + \"could not find MediaFile that is supported by this video player\", 403);\n }\n\n if (wrapper && !wrapper.VASTAdTagURI) {\n return new VASTError(errMsgPrefix + \"missing 'VASTAdTagURI' in wrapper\", 101);\n }\n\n return null;\n }\n\n function requestVASTAd(adTagUrl, callback) {\n that._requestVASTXml(adTagUrl, function (error, xmlStr) {\n if (error) {\n return callback(error);\n }\n try {\n var vastTree = xml.toJXONTree(xmlStr);\n callback(validateVASTTree(vastTree), vastTree.ad);\n } catch (e) {\n callback(new VASTError(\"on VASTClient.getVASTAd.requestVASTAd, error parsing xml\", 100));\n }\n });\n }\n};\n\nVASTClient.prototype._requestVASTXml = function requestVASTXml(adTagUrl, callback) {\n try {\n if (utilities.isFunction(adTagUrl)) {\n adTagUrl(requestHandler);\n } else {\n http.get(adTagUrl, requestHandler, {\n withCredentials: true\n });\n }\n } catch (e) {\n callback(e);\n }\n\n /*** Local functions ***/\n function requestHandler(error, response, status) {\n if (error) {\n var errMsg = utilities.isDefined(status) ?\n \"on VASTClient.requestVastXML, HTTP request error with status '\" + status + \"'\" :\n \"on VASTClient.requestVastXML, Error getting the the VAST XML with he passed adTagXML fn\";\n return callback(new VASTError(errMsg, 301), null);\n }\n\n callback(null, response);\n }\n};\n\nVASTClient.prototype._buildVASTResponse = function buildVASTResponse(adsChain) {\n var response = new VASTResponse();\n addAdsToResponse(response, adsChain);\n validateResponse(response);\n\n return response;\n\n //*** Local function ****\n function addAdsToResponse(response, ads) {\n ads.forEach(function (ad) {\n response.addAd(ad);\n });\n }\n\n function validateResponse(response) {\n var progressEvents = response.trackingEvents.progress;\n\n if (!response.hasLinear()) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, Received an Ad type that is not supported\", 200);\n }\n\n if (response.duration === undefined) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, Missing duration field in VAST response\", 101);\n }\n\n if (progressEvents) {\n progressEvents.forEach(function (progressEvent) {\n if (!utilities.isNumber(progressEvent.offset)) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, missing or wrong offset attribute on progress tracking event\", 101);\n }\n });\n }\n }\n};\n\nVASTClient.prototype._trackError = function (error, adChain) {\n if (!utilities.isArray(adChain) || adChain.length === 0) { //There is nothing to track\n return;\n }\n\n var errorURLMacros = [];\n adChain.forEach(addErrorUrlMacros);\n vastUtil.track(errorURLMacros, {ERRORCODE: error.code || 900}); //900 <== Undefined error\n\n /*** Local functions ***/\n function addErrorUrlMacros(ad) {\n if (ad.wrapper && ad.wrapper.error) {\n errorURLMacros.push(ad.wrapper.error);\n }\n\n if (ad.inLine && ad.inLine.error) {\n errorURLMacros.push(ad.inLine.error);\n }\n }\n};\n\nmodule.exports = VASTClient;\n","'use strict';\n\nfunction VASTError(message, code) {\n this.message = 'VAST Error: ' + (message || '');\n if (code) {\n this.code = code;\n }\n}\n\nVASTError.prototype = new Error();\nVASTError.prototype.name = \"VAST Error\";\n\nmodule.exports = VASTError;","'use strict';\n\n/**\n * Inner helper class that deals with the logic of the individual steps needed to setup an ad in the player.\n *\n * @param player {object} instance of the player that will play the ad. It assumes that the videojs-contrib-ads plugin\n * has been initialized when you use its utility functions.\n *\n * @constructor\n */\n\nvar VASTResponse = require('./VASTResponse');\nvar VASTError = require('./VASTError');\nvar VASTTracker = require('./VASTTracker');\nvar vastUtil = require('./vastUtil');\n\nvar async = require('../../utils/async');\nvar dom = require('../../utils/dom');\nvar playerUtils = require('../../utils/playerUtils');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VASTIntegrator(player) {\n if (!(this instanceof VASTIntegrator)) {\n return new VASTIntegrator(player);\n }\n\n this.player = player;\n}\n\nVASTIntegrator.prototype.playAd = function playAd(vastResponse, callback) {\n var that = this;\n callback = callback || utilities.noop;\n\n if (!(vastResponse instanceof VASTResponse)) {\n return callback(new VASTError('On VASTIntegrator, missing required VASTResponse'));\n }\n\n async.waterfall([\n function (next) {\n next(null, vastResponse);\n },\n this._selectAdSource.bind(this),\n this._createVASTTracker.bind(this),\n this._addClickThrough.bind(this),\n this._addSkipButton.bind(this),\n this._setupEvents.bind(this),\n this._playSelectedAd.bind(this)\n ], function (error, response) {\n if (error && response) {\n that._trackError(error, response);\n }\n callback(error, response);\n });\n\n this._adUnit = {\n _src: null,\n type: 'VAST',\n pauseAd: function () {\n that.player.pause(true);\n },\n\n resumeAd: function () {\n that.player.play(true);\n },\n\n isPaused: function () {\n return that.player.paused(true);\n },\n\n getSrc: function () {\n return this._src;\n }\n };\n\n return this._adUnit;\n};\n\nVASTIntegrator.prototype._selectAdSource = function selectAdSource(response, callback) {\n var source;\n\n var playerWidth = dom.getDimension(this.player.el()).width;\n response.mediaFiles.sort(function compareTo(a, b) {\n var deltaA = Math.abs(playerWidth - a.width);\n var deltaB = Math.abs(playerWidth - b.width);\n return deltaA - deltaB;\n });\n\n source = this.player.selectSource(response.mediaFiles).source;\n\n if (source) {\n if (this._adUnit) {\n this._adUnit._src = source;\n }\n return callback(null, source, response);\n }\n\n // code 403 <== Couldn't find MediaFile that is supported by this video player\n callback(new VASTError(\"Could not find Ad mediafile supported by this player\", 403), response);\n};\n\nVASTIntegrator.prototype._createVASTTracker = function createVASTTracker(adMediaFile, response, callback) {\n try {\n callback(null, adMediaFile, new VASTTracker(adMediaFile.src, response), response);\n } catch (e) {\n callback(e, response);\n }\n};\n\nVASTIntegrator.prototype._setupEvents = function setupEvents(adMediaFile, tracker, response, callback) {\n var previouslyMuted;\n var player = this.player;\n player.on('fullscreenchange', trackFullscreenChange);\n player.on('vast.adStart', trackImpressions);\n player.on('pause', trackPause);\n player.on('timeupdate', trackProgress);\n player.on('volumechange', trackVolumeChange);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], unbindEvents);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel', 'vast.adSkip'], function(evt){\n if(evt.type === 'vast.adEnd'){\n tracker.trackComplete();\n }\n });\n\n return callback(null, adMediaFile, response);\n\n /*** Local Functions ***/\n function unbindEvents() {\n player.off('fullscreenchange', trackFullscreenChange);\n player.off('vast.adStart', trackImpressions);\n player.off('pause', trackPause);\n player.off('timeupdate', trackProgress);\n player.off('volumechange', trackVolumeChange);\n }\n\n function trackFullscreenChange() {\n if (player.isFullscreen()) {\n tracker.trackFullscreen();\n } else {\n tracker.trackExitFullscreen();\n }\n }\n\n function trackPause() {\n //NOTE: whenever a video ends the video Element triggers a 'pause' event before the 'ended' event.\n // We should not track this pause event because it makes the VAST tracking confusing again we use a\n // Threshold of 2 seconds to prevent false positives on IOS.\n if (Math.abs(player.duration() - player.currentTime()) < 2) {\n return;\n }\n\n tracker.trackPause();\n playerUtils.once(player, ['play', 'vast.adEnd', 'vast.adsCancel'], function (evt) {\n if(evt.type === 'play'){\n tracker.trackResume();\n }\n });\n }\n\n function trackProgress() {\n var currentTimeInMs = player.currentTime() * 1000;\n tracker.trackProgress(currentTimeInMs);\n }\n\n function trackImpressions() {\n tracker.trackImpressions();\n tracker.trackCreativeView();\n }\n\n function trackVolumeChange() {\n var muted = player.muted();\n if (muted) {\n tracker.trackMute();\n } else if (previouslyMuted) {\n tracker.trackUnmute();\n }\n previouslyMuted = muted;\n }\n};\n\nVASTIntegrator.prototype._addSkipButton = function addSkipButton(source, tracker, response, callback) {\n var skipOffsetInSec;\n var that = this;\n\n if (utilities.isNumber(response.skipoffset)) {\n skipOffsetInSec = response.skipoffset / 1000;\n addSkipButtonToPlayer(this.player, skipOffsetInSec);\n }\n callback(null, source, tracker, response);\n\n /*** Local function ***/\n function addSkipButtonToPlayer(player, skipOffset) {\n var skipButton = createSkipButton(player);\n var updateSkipButton = updateSkipButtonState.bind(that, skipButton, skipOffset, player);\n\n player.el().appendChild(skipButton);\n player.on('timeupdate', updateSkipButton);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeSkipButton);\n\n function removeSkipButton() {\n player.off('timeupdate', updateSkipButton);\n dom.remove(skipButton);\n }\n }\n\n function createSkipButton(player) {\n var skipButton = window.document.createElement(\"div\");\n dom.addClass(skipButton, \"vast-skip-button\");\n\n skipButton.onclick = function (e) {\n if (dom.hasClass(skipButton, 'enabled')) {\n tracker.trackSkip();\n player.trigger('vast.adSkip');\n }\n\n //We prevent event propagation to avoid problems with the clickThrough and so on\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n } else {\n return false;\n }\n };\n\n return skipButton;\n }\n\n function updateSkipButtonState(skipButton, skipOffset, player) {\n var timeLeft = Math.ceil(skipOffset - player.currentTime());\n if (timeLeft > 0) {\n skipButton.innerHTML = \"Skip in \" + utilities.toFixedDigits(timeLeft, 2) + \"...\";\n } else {\n if (!dom.hasClass(skipButton, 'enabled')) {\n dom.addClass(skipButton, 'enabled');\n skipButton.innerHTML = \"Skip ad\";\n }\n }\n }\n};\n\nVASTIntegrator.prototype._addClickThrough = function addClickThrough(mediaFile, tracker, response, callback) {\n var player = this.player;\n var blocker = createClickThroughBlocker(player, tracker, response);\n var updateBlocker = updateBlockerURL.bind(this, blocker, response, player);\n\n player.el().insertBefore(blocker, player.controlBar.el());\n player.on('timeupdate', updateBlocker);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeBlocker);\n\n return callback(null, mediaFile, tracker, response);\n\n /*** Local Functions ***/\n\n function createClickThroughBlocker(player, tracker, response) {\n var blocker = window.document.createElement(\"a\");\n var clickThroughMacro = response.clickThrough;\n\n dom.addClass(blocker, 'vast-blocker');\n blocker.href = generateClickThroughURL(clickThroughMacro, player);\n\n if (utilities.isString(clickThroughMacro)) {\n blocker.target = \"_blank\";\n }\n\n blocker.onclick = function (e) {\n if (player.paused()) {\n player.play();\n\n //We prevent event propagation to avoid problems with the player's normal pause mechanism\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n }\n return false;\n }\n\n player.pause();\n tracker.trackClick();\n };\n\n return blocker;\n }\n\n function updateBlockerURL(blocker, response, player) {\n blocker.href = generateClickThroughURL(response.clickThrough, player);\n }\n\n function generateClickThroughURL(clickThroughMacro, player) {\n var variables = {\n ASSETURI: mediaFile.src,\n CONTENTPLAYHEAD: vastUtil.formatProgress(player.currentTime() * 1000)\n };\n\n return clickThroughMacro ? vastUtil.parseURLMacro(clickThroughMacro, variables) : '#';\n }\n\n function removeBlocker() {\n player.off('timeupdate', updateBlocker);\n dom.remove(blocker);\n }\n};\n\nVASTIntegrator.prototype._playSelectedAd = function playSelectedAd(source, response, callback) {\n var player = this.player;\n\n player.preload(\"auto\"); //without preload=auto the durationchange event is never fired\n player.src(source);\n\n playerUtils.once(player, ['durationchange', 'error', 'vast.adsCancel'], function (evt) {\n if (evt.type === 'durationchange') {\n playAd();\n } else if(evt.type === 'error') {\n callback(new VASTError(\"on VASTIntegrator, Player is unable to play the Ad\", 400), response);\n }\n //NOTE: If the ads get canceled we do nothing/\n });\n\n /**** local functions ******/\n function playAd() {\n\n playerUtils.once(player, ['playing', 'vast.adsCancel'], function (evt) {\n if(evt.type === 'vast.adsCancel'){\n return;\n }\n\n player.trigger('vast.adStart');\n\n player.on('ended', proceed);\n player.on('vast.adsCancel', proceed);\n player.on('vast.adSkip', proceed);\n\n function proceed(evt) {\n\n if(evt.type === 'ended' && (player.duration() - player.currentTime()) > 3 ) {\n // Ignore ended event if the Ad time was not 'near' the end\n // avoids issues where IOS controls could skip the Ad\n return;\n }\n\n player.off('ended', proceed);\n player.off('vast.adsCancel', proceed);\n player.off('vast.adSkip', proceed);\n\n //NOTE: if the ads get cancel we do nothing apart removing the listners\n if(evt.type === 'ended' || evt.type === 'vast.adSkip'){\n callback(null, response);\n }\n }\n });\n\n player.play();\n }\n};\n\nVASTIntegrator.prototype._trackError = function trackError(error, response) {\n vastUtil.track(response.errorURLMacros, {ERRORCODE: error.code || 900});\n};\n\nmodule.exports = VASTIntegrator;","'use strict';\n\nvar Ad = require('./Ad');\nvar VideoClicks = require('./VideoClicks');\nvar Linear = require('./Linear');\nvar InLine = require('./InLine');\nvar Wrapper = require('./Wrapper');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nwindow.InLine__A = InLine;\nfunction VASTResponse() {\n if (!(this instanceof VASTResponse)) {\n return new VASTResponse();\n }\n\n this._linearAdded = false;\n this.ads = [];\n this.errorURLMacros = [];\n this.impressions = [];\n this.clickTrackings = [];\n this.customClicks = [];\n this.trackingEvents = {};\n this.mediaFiles = [];\n this.clickThrough = undefined;\n this.adTitle = '';\n this.duration = undefined;\n this.skipoffset = undefined;\n}\n\nVASTResponse.prototype.addAd = function (ad) {\n var inLine, wrapper;\n if (ad instanceof Ad) {\n inLine = ad.inLine;\n wrapper = ad.wrapper;\n\n this.ads.push(ad);\n\n if (inLine) {\n this._addInLine(inLine);\n }\n\n if (wrapper) {\n this._addWrapper(wrapper);\n }\n }\n};\n\nVASTResponse.prototype._addErrorTrackUrl = function (error) {\n var errorURL = error instanceof xml.JXONTree ? xml.keyValue(error) : error;\n if (errorURL) {\n this.errorURLMacros.push(errorURL);\n }\n};\n\nVASTResponse.prototype._addImpressions = function (impressions) {\n utilities.isArray(impressions) && appendToArray(this.impressions, impressions);\n};\n\nVASTResponse.prototype._addClickThrough = function (clickThrough) {\n if (utilities.isNotEmptyString(clickThrough)) {\n this.clickThrough = clickThrough;\n }\n};\n\nVASTResponse.prototype._addClickTrackings = function (clickTrackings) {\n utilities.isArray(clickTrackings) && appendToArray(this.clickTrackings, clickTrackings);\n};\n\nVASTResponse.prototype._addCustomClicks = function (customClicks) {\n utilities.isArray(customClicks) && appendToArray(this.customClicks, customClicks);\n};\n\nVASTResponse.prototype._addTrackingEvents = function (trackingEvents) {\n var eventsMap = this.trackingEvents;\n\n if (trackingEvents) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingEvent) {\n if (!eventsMap[trackingEvent.name]) {\n eventsMap[trackingEvent.name] = [];\n }\n eventsMap[trackingEvent.name].push(trackingEvent);\n });\n }\n};\n\nVASTResponse.prototype._addTitle = function (title) {\n if (utilities.isNotEmptyString(title)) {\n this.adTitle = title;\n }\n};\n\nVASTResponse.prototype._addDuration = function (duration) {\n if (utilities.isNumber(duration)) {\n this.duration = duration;\n }\n};\n\nVASTResponse.prototype._addVideoClicks = function (videoClicks) {\n if (videoClicks instanceof VideoClicks) {\n this._addClickThrough(videoClicks.clickThrough);\n this._addClickTrackings(videoClicks.clickTrackings);\n this._addCustomClicks(videoClicks.customClicks);\n }\n};\n\nVASTResponse.prototype._addMediaFiles = function (mediaFiles) {\n utilities.isArray(mediaFiles) && appendToArray(this.mediaFiles, mediaFiles);\n};\n\nVASTResponse.prototype._addSkipoffset = function (offset) {\n if (offset) {\n this.skipoffset = offset;\n }\n};\n\nVASTResponse.prototype._addAdParameters = function (adParameters) {\n if (adParameters) {\n this.adParameters = adParameters;\n }\n};\n\nVASTResponse.prototype._addLinear = function (linear) {\n if (linear instanceof Linear) {\n this._addDuration(linear.duration);\n this._addTrackingEvents(linear.trackingEvents);\n this._addVideoClicks(linear.videoClicks);\n this._addMediaFiles(linear.mediaFiles);\n this._addSkipoffset(linear.skipoffset);\n this._addAdParameters(linear.adParameters);\n this._linearAdded = true;\n }\n};\n\nVASTResponse.prototype._addInLine = function (inLine) {\n var that = this;\n\n if (inLine instanceof InLine) {\n this._addTitle(inLine.adTitle);\n this._addErrorTrackUrl(inLine.error);\n this._addImpressions(inLine.impressions);\n\n inLine.creatives.forEach(function (creative) {\n if (creative.linear) {\n that._addLinear(creative.linear);\n }\n });\n }\n};\n\nVASTResponse.prototype._addWrapper = function (wrapper) {\n var that = this;\n\n if (wrapper instanceof Wrapper) {\n this._addErrorTrackUrl(wrapper.error);\n this._addImpressions(wrapper.impressions);\n\n wrapper.creatives.forEach(function (creative) {\n var linear = creative.linear;\n if (linear) {\n that._addVideoClicks(linear.videoClicks);\n that.clickThrough = undefined;//We ensure that no clickThrough has been added\n that._addTrackingEvents(linear.trackingEvents);\n }\n });\n }\n};\n\nVASTResponse.prototype.hasLinear = function(){\n return this._linearAdded;\n};\n\nfunction appendToArray(array, items) {\n items.forEach(function (item) {\n array.push(item);\n });\n}\n\nmodule.exports = VASTResponse;\n\n","'use strict';\n\nvar VASTError = require('./VASTError');\nvar VASTResponse = require('./VASTResponse');\nvar vastUtil = require('./vastUtil');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VASTTracker(assetURI, vastResponse) {\n if (!(this instanceof VASTTracker)) {\n return new VASTTracker(assetURI, vastResponse);\n }\n\n this.sanityCheck(assetURI, vastResponse);\n this.initialize(assetURI, vastResponse);\n\n}\n\nVASTTracker.prototype.initialize = function(assetURI, vastResponse) {\n this.response = vastResponse;\n this.assetURI = assetURI;\n this.progress = 0;\n this.quartiles = {\n firstQuartile: {tracked: false, time: Math.round(25 * vastResponse.duration) / 100},\n midpoint: {tracked: false, time: Math.round(50 * vastResponse.duration) / 100},\n thirdQuartile: {tracked: false, time: Math.round(75 * vastResponse.duration) / 100}\n };\n};\n\nVASTTracker.prototype.sanityCheck = function(assetURI, vastResponse) {\n if (!utilities.isString(assetURI) || utilities.isEmptyString(assetURI)) {\n throw new VASTError('on VASTTracker constructor, missing required the URI of the ad asset being played');\n }\n\n if (!(vastResponse instanceof VASTResponse)) {\n throw new VASTError('on VASTTracker constructor, missing required VAST response');\n }\n};\n\nVASTTracker.prototype.trackURLs = function trackURLs(urls, variables) {\n if (utilities.isArray(urls) && urls.length > 0) {\n variables = utilities.extend({\n ASSETURI: this.assetURI,\n CONTENTPLAYHEAD: vastUtil.formatProgress(this.progress)\n }, variables || {});\n\n vastUtil.track(urls, variables);\n }\n};\n\nVASTTracker.prototype.trackEvent = function trackEvent(eventName, trackOnce) {\n this.trackURLs(getEventUris(this.response.trackingEvents[eventName]));\n if (trackOnce) {\n this.response.trackingEvents[eventName] = undefined;\n }\n\n /*** Local function ***/\n function getEventUris(trackingEvents) {\n var uris;\n\n if (trackingEvents) {\n uris = [];\n trackingEvents.forEach(function (event) {\n uris.push(event.uri);\n });\n }\n return uris;\n }\n};\n\nVASTTracker.prototype.trackProgress = function trackProgress(newProgressInMs) {\n var that = this;\n var events = [];\n var ONCE = true;\n var ALWAYS = false;\n var trackingEvents = this.response.trackingEvents;\n\n if (utilities.isNumber(newProgressInMs)) {\n addTrackEvent('start', ONCE, newProgressInMs > 0);\n addTrackEvent('rewind', ALWAYS, hasRewound(this.progress, newProgressInMs));\n addQuartileEvents(newProgressInMs);\n trackProgressEvents(newProgressInMs);\n trackEvents();\n this.progress = newProgressInMs;\n }\n\n /*** Local function ***/\n function hasRewound(currentProgress, newProgress) {\n var REWIND_THRESHOLD = 3000; //IOS video clock is very unreliable and we need a 3 seconds threshold to ensure that there was a rewind an that it was on purpose.\n return currentProgress > newProgressInMs && Math.abs(newProgress - currentProgress) > REWIND_THRESHOLD;\n }\n\n function addTrackEvent(eventName, trackOnce, canBeAdded) {\n if (trackingEvents[eventName] && canBeAdded) {\n events.push({\n name: eventName,\n trackOnce: !!trackOnce\n });\n }\n }\n\n function addQuartileEvents(progress) {\n var quartiles = that.quartiles;\n var firstQuartile = that.quartiles.firstQuartile;\n var midpoint = that.quartiles.midpoint;\n var thirdQuartile = that.quartiles.thirdQuartile;\n\n if (!firstQuartile.tracked) {\n trackQuartile('firstQuartile', progress);\n } else if (!midpoint.tracked) {\n trackQuartile('midpoint', progress);\n } else if (!thirdQuartile.tracked){\n trackQuartile('thirdQuartile', progress);\n }\n\n /*** Local function ***/\n function trackQuartile(quartileName, progress){\n var quartile = quartiles[quartileName];\n if(canBeTracked(quartile, progress)){\n quartile.tracked = true;\n addTrackEvent(quartileName, ONCE, true);\n }\n }\n }\n\n function canBeTracked(quartile, progress) {\n var quartileTime = quartile.time;\n //We only fire the quartile event if the progress is bigger than the quartile time by 5 seconds at most.\n return progress >= quartileTime && progress <= (quartileTime + 5000);\n }\n\n function trackProgressEvents(progress) {\n if (!utilities.isArray(trackingEvents.progress)) {\n return; //Nothing to track\n }\n\n var pendingProgressEvts = [];\n\n trackingEvents.progress.forEach(function (evt) {\n if (evt.offset <= progress) {\n that.trackURLs([evt.uri]);\n } else {\n pendingProgressEvts.push(evt);\n }\n });\n trackingEvents.progress = pendingProgressEvts;\n }\n\n function trackEvents() {\n events.forEach(function (event) {\n that.trackEvent(event.name, event.trackOnce);\n });\n }\n};\n\n[\n 'rewind',\n 'fullscreen',\n 'exitFullscreen',\n 'pause',\n 'resume',\n 'mute',\n 'unmute',\n 'acceptInvitation',\n 'acceptInvitationLinear',\n 'collapse',\n 'expand'\n].forEach(function (eventName) {\n VASTTracker.prototype['track' + utilities.capitalize(eventName)] = function () {\n this.trackEvent(eventName);\n };\n });\n\n[\n 'start',\n 'skip',\n 'close',\n 'closeLinear'\n].forEach(function (eventName) {\n VASTTracker.prototype['track' + utilities.capitalize(eventName)] = function () {\n this.trackEvent(eventName, true);\n };\n });\n\n[\n 'firstQuartile',\n 'midpoint',\n 'thirdQuartile'\n].forEach(function (quartile) {\n VASTTracker.prototype['track' + utilities.capitalize(quartile)] = function () {\n this.quartiles[quartile].tracked = true;\n this.trackEvent(quartile, true);\n };\n });\n\nVASTTracker.prototype.trackComplete = function () {\n if(this.quartiles.thirdQuartile.tracked){\n this.trackEvent('complete', true);\n }\n};\n\nVASTTracker.prototype.trackErrorWithCode = function trackErrorWithCode(errorcode) {\n if (utilities.isNumber(errorcode)) {\n this.trackURLs(this.response.errorURLMacros, {ERRORCODE: errorcode});\n }\n};\n\nVASTTracker.prototype.trackImpressions = function trackImpressions() {\n this.trackURLs(this.response.impressions);\n};\n\nVASTTracker.prototype.trackCreativeView = function trackCreativeView() {\n this.trackEvent('creativeView');\n};\n\nVASTTracker.prototype.trackClick = function trackClick() {\n this.trackURLs(this.response.clickTrackings);\n};\n\nmodule.exports = VASTTracker;\n","'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction VideoClicks(videoClickJTree) {\n if (!(this instanceof VideoClicks)) {\n return new VideoClicks(videoClickJTree);\n }\n\n this.clickThrough = xml.keyValue(videoClickJTree.clickThrough);\n this.clickTrackings = parseClickTrackings(videoClickJTree.clickTracking);\n this.customClicks = parseClickTrackings(videoClickJTree.customClick);\n\n /*** Local functions ***/\n function parseClickTrackings(trackingData) {\n var clickTrackings = [];\n if (trackingData) {\n trackingData = utilities.isArray(trackingData) ? trackingData : [trackingData];\n trackingData.forEach(function (clickTrackingData) {\n clickTrackings.push(xml.keyValue(clickTrackingData));\n });\n }\n return clickTrackings;\n }\n}\n\nmodule.exports = VideoClicks;","'use strict';\n\nvar vastUtil = require('./vastUtil');\nvar Creative = require('./Creative');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction Wrapper(wrapperJTree) {\n if(!(this instanceof Wrapper)) {\n return new Wrapper(wrapperJTree);\n }\n\n //Required elements\n this.adSystem = xml.keyValue(wrapperJTree.adSystem);\n this.impressions = vastUtil.parseImpressions(wrapperJTree.impression);\n this.VASTAdTagURI = xml.keyValue(wrapperJTree.vASTAdTagURI);\n\n //Optional elements\n this.creatives = Creative.parseCreatives(wrapperJTree.creatives);\n this.error = xml.keyValue(wrapperJTree.error);\n this.extensions = wrapperJTree.extensions;\n\n //Optional attrs\n this.followAdditionalWrappers = utilities.isDefined(xml.attr(wrapperJTree, 'followAdditionalWrappers'))? xml.attr(wrapperJTree, 'followAdditionalWrappers'): true;\n this.allowMultipleAds = xml.attr(wrapperJTree, 'allowMultipleAds');\n this.fallbackOnNoAd = xml.attr(wrapperJTree, 'fallbackOnNoAd');\n}\n\nmodule.exports = Wrapper;\n","'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\n\nvar durationRegex = /(\\d\\d):(\\d\\d):(\\d\\d)(\\.(\\d\\d\\d))?/;\n\nvar parsers = {\n\n duration: function parseDuration(durationStr) {\n\n var match, durationInMs;\n\n if (utilities.isString(durationStr)) {\n match = durationStr.match(durationRegex);\n if (match) {\n durationInMs = parseHoursToMs(match[1]) + parseMinToMs(match[2]) + parseSecToMs(match[3]) + parseInt(match[5] || 0);\n }\n }\n\n return isNaN(durationInMs) ? null : durationInMs;\n\n /*** local functions ***/\n function parseHoursToMs(hourStr) {\n return parseInt(hourStr, 10) * 60 * 60 * 1000;\n }\n\n function parseMinToMs(minStr) {\n return parseInt(minStr, 10) * 60 * 1000;\n }\n\n function parseSecToMs(secStr) {\n return parseInt(secStr, 10) * 1000;\n }\n },\n\n offset: function parseOffset(offset, duration) {\n if(isPercentage(offset)){\n return calculatePercentage(offset, duration);\n }\n return parsers.duration(offset);\n\n /*** Local function ***/\n function isPercentage(offset) {\n var percentageRegex = /^\\d+(\\.\\d+)?%$/g;\n return percentageRegex.test(offset);\n }\n\n function calculatePercentage(percentStr, duration) {\n if(duration) {\n return calcPercent(duration, parseFloat(percentStr.replace('%', '')));\n }\n return null;\n }\n\n function calcPercent(quantity, percent){\n return quantity * percent / 100;\n }\n }\n\n};\n\n\nmodule.exports = parsers;","'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\nvar VPAIDHTML5Tech = require('../vpaid/VPAIDHTML5Tech');\nvar VPAIDFlashTech = require('../vpaid/VPAIDFlashTech');\nvar VPAIDFLASHClient = require('VPAIDFLASHClient/js/VPAIDFLASHClient');\n\nvar vastUtil = {\n\n track: function track(URLMacros, variables) {\n var sources = vastUtil.parseURLMacros(URLMacros, variables);\n var trackImgs = [];\n sources.forEach(function (src) {\n var img = new Image();\n img.src = src;\n trackImgs.push(img);\n });\n return trackImgs;\n },\n\n parseURLMacros: function parseMacros(URLMacros, variables) {\n var parsedURLs = [];\n\n variables = variables || {};\n\n if (!(variables[\"CACHEBUSTING\"])) {\n variables[\"CACHEBUSTING\"] = Math.round(Math.random() * 1.0e+10);\n }\n\n URLMacros.forEach(function (URLMacro) {\n parsedURLs.push(vastUtil._parseURLMacro(URLMacro, variables));\n });\n\n return parsedURLs;\n },\n\n parseURLMacro: function parseMacro(URLMacro, variables) {\n variables = variables || {};\n\n if (!(variables[\"CACHEBUSTING\"])) {\n variables[\"CACHEBUSTING\"] = Math.round(Math.random() * 1.0e+10);\n }\n\n return vastUtil._parseURLMacro(URLMacro, variables);\n },\n\n _parseURLMacro: function parseMacro(URLMacro, variables) {\n variables = variables || {};\n\n utilities.forEach(variables, function (value, key) {\n URLMacro = URLMacro.replace(new RegExp(\"\\\\[\" + key + \"\\\\\\]\", 'gm'), value);\n });\n\n return URLMacro;\n },\n\n parseDuration: function parseDuration(durationStr) {\n var durationRegex = /(\\d\\d):(\\d\\d):(\\d\\d)(\\.(\\d\\d\\d))?/;\n var match, durationInMs;\n\n if (utilities.isString(durationStr)) {\n match = durationStr.match(durationRegex);\n if (match) {\n durationInMs = parseHoursToMs(match[1]) + parseMinToMs(match[2]) + parseSecToMs(match[3]) + parseInt(match[5] || 0);\n }\n }\n\n return isNaN(durationInMs) ? null : durationInMs;\n\n /*** local functions ***/\n function parseHoursToMs(hourStr) {\n return parseInt(hourStr, 10) * 60 * 60 * 1000;\n }\n\n function parseMinToMs(minStr) {\n return parseInt(minStr, 10) * 60 * 1000;\n }\n\n function parseSecToMs(secStr) {\n return parseInt(secStr, 10) * 1000;\n }\n },\n\n parseImpressions: function parseImpressions(impressions) {\n if (impressions) {\n impressions = utilities.isArray(impressions) ? impressions : [impressions];\n return utilities.transformArray(impressions, function (impression) {\n if (utilities.isNotEmptyString(impression.keyValue)) {\n return impression.keyValue;\n }\n return undefined;\n });\n }\n return [];\n },\n\n\n //We assume that the progress is going to arrive in milliseconds\n formatProgress: function formatProgress(progress) {\n var hours, minutes, seconds, milliseconds;\n hours = progress / (60 * 60 * 1000);\n hours = Math.floor(hours);\n minutes = (progress / (60 * 1000)) % 60;\n minutes = Math.floor(minutes);\n seconds = (progress / 1000) % 60;\n seconds = Math.floor(seconds);\n milliseconds = progress % 1000;\n return utilities.toFixedDigits(hours, 2) + ':' + utilities.toFixedDigits(minutes, 2) + ':' + utilities.toFixedDigits(seconds, 2) + '.' + utilities.toFixedDigits(milliseconds, 3);\n },\n\n parseOffset: function parseOffset(offset, duration) {\n if (isPercentage(offset)) {\n return calculatePercentage(offset, duration);\n }\n return vastUtil.parseDuration(offset);\n\n /*** Local function ***/\n function isPercentage(offset) {\n var percentageRegex = /^\\d+(\\.\\d+)?%$/g;\n return percentageRegex.test(offset);\n }\n\n function calculatePercentage(percentStr, duration) {\n if (duration) {\n return calcPercent(duration, parseFloat(percentStr.replace('%', '')));\n }\n return null;\n }\n\n function calcPercent(quantity, percent) {\n return quantity * percent / 100;\n }\n },\n\n\n //List of supported VPAID technologies\n VPAID_techs: [\n VPAIDFlashTech,\n VPAIDHTML5Tech\n ],\n\n isVPAID: function isVPAIDMediaFile(mediaFile) {\n return !!mediaFile && mediaFile.apiFramework === 'VPAID';\n },\n\n findSupportedVPAIDTech: function findSupportedVPAIDTech(mimeType) {\n var i, len, VPAIDTech;\n\n for (i = 0, len = this.VPAID_techs.length; i < len; i += 1) {\n VPAIDTech = this.VPAID_techs[i];\n if (VPAIDTech.supports(mimeType)) {\n return VPAIDTech;\n }\n }\n return null;\n },\n\n isFlashSupported: function isFlashSupported() {\n return VPAIDFLASHClient.isSupported();\n },\n\n /**\n * Necessary step for VPAIDFLAShClient to know if flash is supported and not blocked.\n * IMPORTANT NOTE: This is an async test and needs to be run as soon as possible.\n *\n * @param vpaidFlashLoaderPath the path to the vpaidFlashLoader swf obj.\n */\n runFlashSupportCheck: function runFlashSupportCheck(vpaidFlashLoaderPath) {\n VPAIDFLASHClient.runFlashTest({data: vpaidFlashLoaderPath});\n }\n\n};\n\nmodule.exports = vastUtil;\n","'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VPAIDAdUnitWrapper(vpaidAdUnit, opts) {\n if (!(this instanceof VPAIDAdUnitWrapper)) {\n return new VPAIDAdUnitWrapper(vpaidAdUnit, opts);\n }\n sanityCheck(vpaidAdUnit, opts);\n\n this.options = utilities.extend({}, opts);\n\n this._adUnit = vpaidAdUnit;\n\n /*** Local Functions ***/\n function sanityCheck(adUnit, opts) {\n if (!adUnit || !VPAIDAdUnitWrapper.checkVPAIDInterface(adUnit)) {\n throw new VASTError('on VPAIDAdUnitWrapper, the passed VPAID adUnit does not fully implement the VPAID interface');\n }\n\n if (!utilities.isObject(opts)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper, expected options hash but got '\" + opts + \"'\");\n }\n\n if (!(\"responseTimeout\" in opts) || !utilities.isNumber(opts.responseTimeout) ){\n throw new VASTError(\"on VPAIDAdUnitWrapper, expected responseTimeout in options\");\n }\n }\n}\n\nVPAIDAdUnitWrapper.checkVPAIDInterface = function checkVPAIDInterface(VPAIDAdUnit) {\n //NOTE: skipAd is not part of the method list because it only appears in VPAID 2.0 and we support VPAID 1.0\n var VPAIDInterfaceMethods = [\n 'handshakeVersion', 'initAd', 'startAd', 'stopAd', 'resizeAd', 'pauseAd', 'expandAd', 'collapseAd'\n ];\n\n for (var i = 0, len = VPAIDInterfaceMethods.length; i < len; i++) {\n if (!VPAIDAdUnit || !utilities.isFunction(VPAIDAdUnit[VPAIDInterfaceMethods[i]])) {\n return false;\n }\n }\n\n\n return canSubscribeToEvents(VPAIDAdUnit) && canUnsubscribeFromEvents(VPAIDAdUnit);\n\n /*** Local Functions ***/\n\n function canSubscribeToEvents(adUnit) {\n return utilities.isFunction(adUnit.subscribe) || utilities.isFunction(adUnit.addEventListener) || utilities.isFunction(adUnit.on);\n }\n\n function canUnsubscribeFromEvents(adUnit) {\n return utilities.isFunction(adUnit.unsubscribe) || utilities.isFunction(adUnit.removeEventListener) || utilities.isFunction(adUnit.off);\n\n }\n};\n\nVPAIDAdUnitWrapper.prototype.adUnitAsyncCall = function () {\n var args = utilities.arrayLikeObjToArray(arguments);\n var method = args.shift();\n var cb = args.pop();\n var timeoutId;\n\n sanityCheck(method, cb, this._adUnit);\n args.push(wrapCallback());\n\n this._adUnit[method].apply(this._adUnit, args);\n timeoutId = setTimeout(function () {\n timeoutId = null;\n cb(new VASTError(\"on VPAIDAdUnitWrapper, timeout while waiting for a response on call '\" + method + \"'\"));\n cb = utilities.noop;\n }, this.options.responseTimeout);\n\n /*** Local functions ***/\n function sanityCheck(method, cb, adUnit) {\n if (!utilities.isString(method) || !utilities.isFunction(adUnit[method])) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.adUnitAsyncCall, invalid method name\");\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.adUnitAsyncCall, missing callback\");\n }\n }\n\n function wrapCallback() {\n return function () {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n cb.apply(this, arguments);\n };\n }\n};\n\nVPAIDAdUnitWrapper.prototype.on = function (evtName, handler) {\n var addEventListener = this._adUnit.addEventListener || this._adUnit.subscribe || this._adUnit.on;\n addEventListener.call(this._adUnit, evtName, handler);\n};\n\nVPAIDAdUnitWrapper.prototype.off = function (evtName, handler) {\n var removeEventListener = this._adUnit.removeEventListener || this._adUnit.unsubscribe || this._adUnit.off;\n removeEventListener.call(this._adUnit, evtName, handler);\n};\n\nVPAIDAdUnitWrapper.prototype.waitForEvent = function (evtName, cb, context) {\n var timeoutId;\n sanityCheck(evtName, cb);\n context = context || null;\n\n this.on(evtName, responseListener);\n\n timeoutId = setTimeout(function () {\n cb(new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, timeout while waiting for event '\" + evtName + \"'\"));\n timeoutId = null;\n cb = utilities.noop;\n }, this.options.responseTimeout);\n\n /*** Local functions ***/\n function sanityCheck(evtName, cb) {\n if (!utilities.isString(evtName)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, missing evt name\");\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, missing callback\");\n }\n }\n\n function responseListener() {\n var args = utilities.arrayLikeObjToArray(arguments);\n\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n\n args.unshift(null);\n cb.apply(context, args);\n }\n};\n\n// VPAID METHODS\nVPAIDAdUnitWrapper.prototype.handshakeVersion = function (version, cb) {\n this.adUnitAsyncCall('handshakeVersion', version, cb);\n};\n\n/* jshint maxparams:6 */\nVPAIDAdUnitWrapper.prototype.initAd = function (width, height, viewMode, desiredBitrate, adUnitData, cb) {\n this.waitForEvent('AdLoaded', cb);\n this._adUnit.initAd(width, height, viewMode, desiredBitrate, adUnitData);\n};\n\nVPAIDAdUnitWrapper.prototype.resizeAd = function (width, height, viewMode, cb) {\n // NOTE: AdSizeChange event is only supported on VPAID 2.0 so for the moment we are not going to use it\n // and will assume that everything is fine after the async call\n this.adUnitAsyncCall('resizeAd', width, height, viewMode, cb);\n};\n\nVPAIDAdUnitWrapper.prototype.startAd = function (cb) {\n this.waitForEvent('AdStarted', cb);\n this._adUnit.startAd();\n};\n\nVPAIDAdUnitWrapper.prototype.stopAd = function (cb) {\n this.waitForEvent('AdStopped', cb);\n this._adUnit.stopAd();\n};\n\nVPAIDAdUnitWrapper.prototype.pauseAd = function (cb) {\n this.waitForEvent('AdPaused', cb);\n this._adUnit.pauseAd();\n};\n\nVPAIDAdUnitWrapper.prototype.resumeAd = function (cb) {\n this.waitForEvent('AdPlaying', cb);\n this._adUnit.resumeAd();\n};\n\nVPAIDAdUnitWrapper.prototype.expandAd = function (cb) {\n this.waitForEvent('AdExpandedChange', cb);\n this._adUnit.expandAd();\n};\n\nVPAIDAdUnitWrapper.prototype.collapseAd = function (cb) {\n this.waitForEvent('AdExpandedChange', cb);\n this._adUnit.collapseAd();\n};\n\nVPAIDAdUnitWrapper.prototype.skipAd = function (cb) {\n this.waitForEvent('AdSkipped', cb);\n this._adUnit.skipAd();\n};\n\n//VPAID property getters\n[\n 'adLinear',\n 'adWidth',\n 'adHeight',\n 'adExpanded',\n 'adSkippableState',\n 'adRemainingTime',\n 'adDuration',\n 'adVolume',\n 'adCompanions',\n 'adIcons'\n].forEach(function (property) {\n var getterName = 'get' + utilities.capitalize(property);\n\n VPAIDAdUnitWrapper.prototype[getterName] = function (cb) {\n this.adUnitAsyncCall(getterName, cb);\n };\n});\n\n//VPAID property setters\nVPAIDAdUnitWrapper.prototype.setAdVolume = function(volume, cb){\n this.adUnitAsyncCall('setAdVolume',volume, cb);\n};\n\nmodule.exports = VPAIDAdUnitWrapper;\n","'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar VPAIDFLASHClient = require('VPAIDFLASHClient/js/VPAIDFLASHClient');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar dom = require('../../utils/dom');\n\nfunction VPAIDFlashTech(mediaFile, settings) {\n if (!(this instanceof VPAIDFlashTech)) {\n return new VPAIDFlashTech(mediaFile);\n }\n sanityCheck(mediaFile);\n this.name = 'vpaid-flash';\n this.mediaFile = mediaFile;\n this.containerEl = null;\n this.vpaidFlashClient = null;\n this.settings = settings;\n\n /*** local functions ***/\n function sanityCheck(mediaFile) {\n if (!mediaFile || !utilities.isString(mediaFile.src)) {\n throw new VASTError('on VPAIDFlashTech, invalid MediaFile');\n }\n }\n}\n\nVPAIDFlashTech.VPAIDFLASHClient = VPAIDFLASHClient;\n\nVPAIDFlashTech.supports = function (type) {\n return type === 'application/x-shockwave-flash' && VPAIDFlashTech.VPAIDFLASHClient.isSupported();\n};\n\nVPAIDFlashTech.prototype.loadAdUnit = function loadFlashCreative(containerEl, objectEl, callback) {\n var that = this;\n var flashClientOpts = this.settings && this.settings.vpaidFlashLoaderPath ? {data: this.settings.vpaidFlashLoaderPath} : undefined;\n sanityCheck(containerEl, callback);\n\n this.containerEl = containerEl;\n this.vpaidFlashClient = new VPAIDFlashTech.VPAIDFLASHClient(containerEl, function (error) {\n if (error) {\n return callback(error);\n }\n\n that.vpaidFlashClient.loadAdUnit(that.mediaFile.src, callback);\n }, flashClientOpts);\n\n /*** Local Functions ***/\n function sanityCheck(container, cb) {\n\n if (!dom.isDomElement(container)) {\n throw new VASTError('on VPAIDFlashTech.loadAdUnit, invalid dom container element');\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError('on VPAIDFlashTech.loadAdUnit, missing valid callback');\n }\n }\n};\n\nVPAIDFlashTech.prototype.unloadAdUnit = function () {\n if (this.vpaidFlashClient) {\n try{\n this.vpaidFlashClient.destroy();\n } catch(e){\n if(console && utilities.isFunction(console.log)){\n console.log('VAST ERROR: trying to unload the VPAID adunit');\n }\n }\n this.vpaidFlashClient = null;\n }\n\n if (this.containerEl) {\n dom.remove(this.containerEl);\n this.containerEl = null;\n }\n};\n\nmodule.exports = VPAIDFlashTech;\n","'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar VPAIDHTML5Client = require('VPAIDHTML5Client/js/VPAIDHTML5Client');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar dom = require('../../utils/dom');\n\nfunction VPAIDHTML5Tech(mediaFile) {\n\n if(!(this instanceof VPAIDHTML5Tech)) {\n return new VPAIDHTML5Tech(mediaFile);\n }\n\n sanityCheck(mediaFile);\n\n this.name = 'vpaid-html5';\n this.containerEl = null;\n this.videoEl = null;\n this.vpaidHTMLClient = null;\n\n this.mediaFile = mediaFile;\n\n function sanityCheck(mediaFile) {\n if (!mediaFile || !utilities.isString(mediaFile.src)) {\n throw new VASTError(VPAIDHTML5Tech.INVALID_MEDIA_FILE);\n }\n }\n}\n\nVPAIDHTML5Tech.VPAIDHTML5Client = VPAIDHTML5Client;\n\nVPAIDHTML5Tech.supports = function (type) {\n return !utilities.isOldIE() && type === 'application/javascript';\n};\n\nVPAIDHTML5Tech.prototype.loadAdUnit = function loadAdUnit(containerEl, videoEl, callback) {\n sanityCheck(containerEl, videoEl, callback);\n\n this.containerEl = containerEl;\n this.videoEl = videoEl;\n this.vpaidHTMLClient = new VPAIDHTML5Tech.VPAIDHTML5Client(containerEl, videoEl, {});\n this.vpaidHTMLClient.loadAdUnit(this.mediaFile.src, callback);\n\n function sanityCheck(container, video, cb) {\n if (!dom.isDomElement(container)) {\n throw new VASTError(VPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL);\n }\n\n if (!dom.isDomElement(video) || video.tagName.toLowerCase() !== 'video') {\n throw new VASTError(VPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL);\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(VPAIDHTML5Tech.MISSING_CALLBACK);\n }\n }\n};\n\nVPAIDHTML5Tech.prototype.unloadAdUnit = function unloadAdUnit() {\n if (this.vpaidHTMLClient) {\n try {\n this.vpaidHTMLClient.destroy();\n } catch(e) {\n if (console && utilities.isFunction(console.log)) {\n console.log('VAST ERROR: trying to unload the VPAID adunit');\n }\n }\n\n this.vpaidHTMLClient = null;\n }\n\n if (this.containerEl) {\n dom.remove(this.containerEl);\n this.containerEl = null;\n }\n};\n\nvar PREFIX = 'on VPAIDHTML5Tech';\nVPAIDHTML5Tech.INVALID_MEDIA_FILE = PREFIX + ', invalid MediaFile';\nVPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL = PREFIX + ', invalid container HtmlElement';\nVPAIDHTML5Tech.INVALID_DOM_VIDEO_EL = PREFIX + ', invalid HTMLVideoElement';\nVPAIDHTML5Tech.MISSING_CALLBACK = PREFIX + ', missing valid callback';\n\nmodule.exports = VPAIDHTML5Tech;","'use strict';\n\nvar VASTError = require('../vast/VASTError');\nvar VASTResponse = require('../vast/VASTResponse');\nvar VASTTracker = require('../vast/VASTTracker');\nvar vastUtil = require('../vast/vastUtil');\n\nvar VPAIDAdUnitWrapper = require('./VPAIDAdUnitWrapper');\n\nvar async = require('../../utils/async');\nvar dom = require('../../utils/dom');\nvar playerUtils = require('../../utils/playerUtils');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VPAIDIntegrator(player, settings) {\n if (!(this instanceof VPAIDIntegrator)) {\n return new VPAIDIntegrator(player);\n }\n\n this.VIEW_MODE = {\n NORMAL: 'normal',\n FULLSCREEN: \"fullscreen\",\n THUMBNAIL: \"thumbnail\"\n };\n this.player = player;\n this.containerEl = createVPAIDContainerEl(player);\n this.options = {\n responseTimeout: 5000,\n VPAID_VERSION: '2.0'\n };\n this.settings = settings;\n\n /*** Local functions ***/\n\n function createVPAIDContainerEl() {\n var containerEl = document.createElement('div');\n dom.addClass(containerEl, 'VPAID-container');\n player.el().insertBefore(containerEl, player.controlBar.el());\n return containerEl;\n\n }\n}\n\nVPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) {\n if (!(vastResponse instanceof VASTResponse)) {\n return callback(new VASTError('on VASTIntegrator.playAd, missing required VASTResponse'));\n }\n\n var that = this;\n var player = this.player;\n var tech = this._findSupportedTech(vastResponse, this.settings);\n\n callback = callback || utilities.noop;\n\n this._adUnit = null;\n\n dom.addClass(player.el(), 'vjs-vpaid-ad');\n\n player.on('vast.adsCancel', triggerVpaidAdEnd);\n player.one('vpaid.adEnd', function(){\n player.off('vast.adsCancel', triggerVpaidAdEnd);\n removeAdUnit();\n });\n\n if (tech) {\n async.waterfall([\n function (next) {\n next(null, tech, vastResponse);\n },\n this._loadAdUnit.bind(this),\n this._playAdUnit.bind(this),\n this._finishPlaying.bind(this)\n\n ], adComplete);\n\n this._adUnit = {\n _paused: true,\n type: 'VPAID',\n pauseAd: function() {\n player.trigger('vpaid.pauseAd');\n player.pause(true);//we make sure that the video content gets stopped.\n },\n resumeAd: function() {\n player.trigger('vpaid.resumeAd');\n },\n isPaused: function() {\n return this._paused;\n },\n getSrc: function() {\n return tech.mediaFile;\n }\n };\n\n } else {\n var error = new VASTError('on VPAIDIntegrator.playAd, could not find a supported mediaFile', 403);\n adComplete(error, this._adUnit, vastResponse);\n }\n\n return this._adUnit;\n\n /*** Local functions ***/\n function adComplete(error, adUnit, vastResponse) {\n if (error && vastResponse) {\n that._trackError(vastResponse, error.code);\n }\n player.trigger('vpaid.adEnd');\n callback(error, vastResponse);\n }\n\n function triggerVpaidAdEnd(){\n player.trigger('vpaid.adEnd');\n }\n\n function removeAdUnit() {\n if (tech) {\n tech.unloadAdUnit();\n }\n dom.removeClass(player.el(), 'vjs-vpaid-ad');\n }\n};\n\nVPAIDIntegrator.prototype._findSupportedTech = function (vastResponse, settings) {\n if (!(vastResponse instanceof VASTResponse)) {\n return null;\n }\n\n var vpaidMediaFiles = vastResponse.mediaFiles.filter(vastUtil.isVPAID);\n var i, len, mediaFile, VPAIDTech;\n\n for (i = 0, len = vpaidMediaFiles.length; i < len; i += 1) {\n mediaFile = vpaidMediaFiles[i];\n VPAIDTech = vastUtil.findSupportedVPAIDTech(mediaFile.type);\n if (VPAIDTech) {\n return new VPAIDTech(mediaFile, settings);\n }\n }\n return null;\n};\n\nVPAIDIntegrator.prototype._createVPAIDAdUnitWrapper = function(adUnit, src, responseTimeout) {\n return new VPAIDAdUnitWrapper(adUnit, {src: src, responseTimeout: responseTimeout});\n};\n\nVPAIDIntegrator.prototype._loadAdUnit = function (tech, vastResponse, next) {\n var that = this;\n var player = this.player;\n var vjsTechEl = player.el().querySelector('.vjs-tech');\n var responseTimeout = this.settings.responseTimeout || this.options.responseTimeout;\n tech.loadAdUnit(this.containerEl, vjsTechEl, function (error, adUnit) {\n if (error) {\n return next(error, adUnit, vastResponse);\n }\n\n try {\n var WrappedAdUnit = that._createVPAIDAdUnitWrapper(adUnit, tech.mediaFile.src, responseTimeout);\n var techClass = 'vjs-' + tech.name + '-ad';\n dom.addClass(player.el(), techClass);\n player.one('vpaid.adEnd', function() {\n dom.removeClass(player.el(),techClass);\n });\n next(null, WrappedAdUnit, vastResponse);\n } catch (e) {\n next(e, adUnit, vastResponse);\n }\n });\n};\n\nVPAIDIntegrator.prototype._playAdUnit = function (adUnit, vastResponse, callback) {\n async.waterfall([\n function (next) {\n next(null, adUnit, vastResponse);\n },\n this._handshake.bind(this),\n this._initAd.bind(this),\n this._setupEvents.bind(this),\n this._addSkipButton.bind(this),\n this._linkPlayerControls.bind(this),\n this._startAd.bind(this)\n ], callback);\n};\n\nVPAIDIntegrator.prototype._handshake = function handshake(adUnit, vastResponse, next) {\n adUnit.handshakeVersion(this.options.VPAID_VERSION, function (error, version) {\n if (error) {\n return next(error, adUnit, vastResponse);\n }\n\n if (version && isSupportedVersion(version)) {\n return next(null, adUnit, vastResponse);\n }\n\n return next(new VASTError('on VPAIDIntegrator._handshake, unsupported version \"' + version + '\"'), adUnit, vastResponse);\n });\n\n function isSupportedVersion(version) {\n var majorNum = major(version);\n return majorNum >= 1 && majorNum <= 2;\n }\n\n function major(version) {\n var parts = version.split('.');\n return parseInt(parts[0], 10);\n }\n};\n\nVPAIDIntegrator.prototype._initAd = function (adUnit, vastResponse, next) {\n var tech = this.player.el().querySelector('.vjs-tech');\n var dimension = dom.getDimension(tech);\n adUnit.initAd(dimension.width, dimension.height, this.VIEW_MODE.NORMAL, -1, {AdParameters: vastResponse.adParameters || ''}, function (error) {\n next(error, adUnit, vastResponse);\n });\n};\n\nVPAIDIntegrator.prototype._createVASTTracker = function(adUnitSrc, vastResponse) {\n return new VASTTracker(adUnitSrc, vastResponse);\n};\n\nVPAIDIntegrator.prototype._setupEvents = function (adUnit, vastResponse, next) {\n var adUnitSrc = adUnit.options.src;\n var tracker = this._createVASTTracker(adUnitSrc, vastResponse);\n var player = this.player;\n var that = this;\n\n adUnit.on('AdSkipped', function () {\n player.trigger('vpaid.AdSkipped');\n tracker.trackSkip();\n });\n\n adUnit.on('AdImpression', function () {\n player.trigger('vpaid.AdImpression');\n tracker.trackImpressions();\n });\n\n adUnit.on('AdStarted', function () {\n player.trigger('vpaid.AdStarted');\n tracker.trackCreativeView();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdVideoStart', function () {\n player.trigger('vpaid.AdVideoStart');\n tracker.trackStart();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdPlaying', function () {\n player.trigger('vpaid.AdPlaying');\n tracker.trackResume();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdPaused', function () {\n player.trigger('vpaid.AdPaused');\n tracker.trackPause();\n notifyPauseToPlayer();\n });\n\n function notifyPlayToPlayer(){\n if(that._adUnit && that._adUnit.isPaused()){\n that._adUnit._paused = false;\n }\n player.trigger('play');\n\n }\n\n function notifyPauseToPlayer() {\n if(that._adUnit){\n that._adUnit._paused = true;\n }\n player.trigger('pause');\n }\n\n adUnit.on('AdVideoFirstQuartile', function () {\n player.trigger('vpaid.AdVideoFirstQuartile');\n tracker.trackFirstQuartile();\n });\n\n adUnit.on('AdVideoMidpoint', function () {\n player.trigger('vpaid.AdVideoMidpoint');\n tracker.trackMidpoint();\n });\n\n adUnit.on('AdVideoThirdQuartile', function () {\n player.trigger('vpaid.AdVideoThirdQuartile');\n tracker.trackThirdQuartile();\n });\n\n adUnit.on('AdVideoComplete', function () {\n player.trigger('vpaid.AdVideoComplete');\n tracker.trackComplete();\n });\n\n adUnit.on('AdClickThru', function (data) {\n player.trigger('vpaid.AdClickThru');\n var url = data.url;\n var playerHandles = data.playerHandles;\n var clickThruUrl = utilities.isNotEmptyString(url) ? url : generateClickThroughURL(vastResponse.clickThrough);\n\n tracker.trackClick();\n if (playerHandles && clickThruUrl) {\n window.open(clickThruUrl, '_blank');\n }\n\n function generateClickThroughURL(clickThroughMacro) {\n var variables = {\n ASSETURI: adUnit.options.src,\n CONTENTPLAYHEAD: 0 //In VPAID there is no method to know the current time from the adUnit\n };\n\n return clickThroughMacro ? vastUtil.parseURLMacro(clickThroughMacro, variables) : null;\n }\n });\n\n adUnit.on('AdUserAcceptInvitation', function () {\n player.trigger('vpaid.AdUserAcceptInvitation');\n tracker.trackAcceptInvitation();\n tracker.trackAcceptInvitationLinear();\n });\n\n adUnit.on('AdUserClose', function () {\n player.trigger('vpaid.AdUserClose');\n tracker.trackClose();\n tracker.trackCloseLinear();\n });\n\n adUnit.on('AdUserMinimize', function () {\n player.trigger('vpaid.AdUserMinimize');\n tracker.trackCollapse();\n });\n\n adUnit.on('AdError', function () {\n player.trigger('vpaid.AdError');\n //NOTE: we track errors code 901, as noted in VAST 3.0\n tracker.trackErrorWithCode(901);\n });\n\n adUnit.on('AdVolumeChange', function () {\n player.trigger('vpaid.AdVolumeChange');\n var lastVolume = player.volume();\n adUnit.getAdVolume(function (error, currentVolume) {\n if (currentVolume === 0 && lastVolume > 0) {\n tracker.trackMute();\n }\n\n if (currentVolume > 0 && lastVolume === 0) {\n tracker.trackUnmute();\n }\n\n player.volume(currentVolume);\n });\n });\n\n var updateViewSize = resizeAd.bind(this, player, adUnit, this.VIEW_MODE);\n var updateViewSizeThrottled = utilities.throttle(updateViewSize, 100);\n var autoResize = this.settings.autoResize;\n\n if (autoResize) {\n dom.addEventListener(window, 'resize', updateViewSizeThrottled);\n dom.addEventListener(window, 'orientationchange', updateViewSizeThrottled);\n }\n\n player.on('vast.resize', updateViewSize);\n player.on('vpaid.pauseAd', pauseAdUnit);\n player.on('vpaid.resumeAd', resumeAdUnit);\n\n player.one('vpaid.adEnd', function () {\n player.off('vast.resize', updateViewSize);\n player.off('vpaid.pauseAd', pauseAdUnit);\n player.off('vpaid.resumeAd', resumeAdUnit);\n\n if (autoResize) {\n dom.removeEventListener(window, 'resize', updateViewSizeThrottled);\n dom.removeEventListener(window, 'orientationchange', updateViewSizeThrottled);\n }\n });\n\n next(null, adUnit, vastResponse);\n\n /*** Local Functions ***/\n function pauseAdUnit() {\n adUnit.pauseAd(utilities.noop);\n }\n\n function resumeAdUnit() {\n adUnit.resumeAd(utilities.noop);\n }\n};\n\nVPAIDIntegrator.prototype._addSkipButton = function (adUnit, vastResponse, next) {\n var skipButton;\n var player = this.player;\n\n adUnit.on('AdSkippableStateChange', updateSkipButtonState);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeSkipButton);\n\n next(null, adUnit, vastResponse);\n\n /*** Local function ***/\n function updateSkipButtonState() {\n player.trigger('vpaid.AdSkippableStateChange');\n adUnit.getAdSkippableState(function (error, isSkippable) {\n if (isSkippable) {\n if (!skipButton) {\n addSkipButton(player);\n }\n } else {\n removeSkipButton(player);\n }\n });\n }\n\n function addSkipButton(player) {\n skipButton = createSkipButton(player);\n player.el().appendChild(skipButton);\n }\n\n function removeSkipButton() {\n dom.remove(skipButton);\n skipButton = null;\n }\n\n function createSkipButton() {\n var skipButton = window.document.createElement(\"div\");\n dom.addClass(skipButton, \"vast-skip-button\");\n dom.addClass(skipButton, \"enabled\");\n skipButton.innerHTML = \"Skip ad\";\n\n skipButton.onclick = function (e) {\n adUnit.skipAd(utilities.noop);//We skip the adUnit\n\n //We prevent event propagation to avoid problems with the clickThrough and so on\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n } else {\n return false;\n }\n };\n\n return skipButton;\n }\n};\n\nVPAIDIntegrator.prototype._linkPlayerControls = function (adUnit, vastResponse, next) {\n var that = this;\n linkVolumeControl(this.player, adUnit);\n linkFullScreenControl(this.player, adUnit, this.VIEW_MODE);\n\n next(null, adUnit, vastResponse);\n\n /*** Local functions ***/\n function linkVolumeControl(player, adUnit) {\n player.on('volumechange', updateAdUnitVolume);\n adUnit.on('AdVolumeChange', updatePlayerVolume);\n\n player.one('vpaid.adEnd', function () {\n player.off('volumechange', updateAdUnitVolume);\n });\n\n\n /*** local functions ***/\n function updateAdUnitVolume() {\n var vol = player.muted() ? 0 : player.volume();\n adUnit.setAdVolume(vol, logError);\n }\n\n function updatePlayerVolume() {\n player.trigger('vpaid.AdVolumeChange');\n adUnit.getAdVolume(function (error, vol) {\n if (error) {\n logError(error);\n } else {\n player.volume(vol);\n }\n });\n }\n }\n\n function linkFullScreenControl(player, adUnit, VIEW_MODE) {\n var updateViewSize = resizeAd.bind(that, player, adUnit, VIEW_MODE);\n\n player.on('fullscreenchange', updateViewSize);\n\n player.one('vpaid.adEnd', function () {\n player.off('fullscreenchange', updateViewSize);\n });\n }\n};\n\nVPAIDIntegrator.prototype._startAd = function (adUnit, vastResponse, next) {\n var player = this.player;\n\n adUnit.startAd(function (error) {\n if (!error) {\n player.trigger('vast.adStart');\n }\n next(error, adUnit, vastResponse);\n });\n};\n\nVPAIDIntegrator.prototype._finishPlaying = function (adUnit, vastResponse, next) {\n var player = this.player;\n adUnit.on('AdStopped', function () {\n player.trigger('vpaid.AdStopped');\n finishPlayingAd(null);\n });\n\n adUnit.on('AdError', function (error) {\n var errMsg = error? error.message : 'on VPAIDIntegrator, error while waiting for the adUnit to finish playing';\n finishPlayingAd(new VASTError(errMsg));\n });\n\n /*** local functions ***/\n function finishPlayingAd(error) {\n next(error, adUnit, vastResponse);\n }\n};\n\nVPAIDIntegrator.prototype._trackError = function trackError(response, errorCode) {\n vastUtil.track(response.errorURLMacros, {ERRORCODE: errorCode || 901});\n};\n\nfunction resizeAd(player, adUnit, VIEW_MODE) {\n var tech = player.el().querySelector('.vjs-tech');\n var dimension = dom.getDimension(tech);\n var MODE = player.isFullscreen() ? VIEW_MODE.FULLSCREEN : VIEW_MODE.NORMAL;\n adUnit.resizeAd(dimension.width, dimension.height, MODE, logError);\n}\n\nfunction logError(error) {\n if (error && console && console.log) {\n console.log('ERROR: ' + error.message, error);\n }\n}\n\nmodule.exports = VPAIDIntegrator;","'use strict';\n\nvar dom = require('../../utils/dom');\n\nvar element = document.createElement('div');\nelement.className = 'vjs-ads-label vjs-control vjs-label-hidden';\nelement.innerHTML = 'Advertisement';\n\nvar AdsLabelFactory = function(baseComponent) {\n return {\n /** @constructor */\n init: function init(player, options) {\n options.el = element;\n baseComponent.call(this, player, options);\n\n // We asynchronously reposition the ads label element\n setTimeout(function () {\n var currentTimeComp = player.controlBar &&( player.controlBar.getChild(\"timerControls\") || player.controlBar.getChild(\"currentTimeDisplay\") );\n if(currentTimeComp) {\n player.controlBar.el().insertBefore(element, currentTimeComp.el());\n }\n dom.removeClass(element, 'vjs-label-hidden');\n }, 0);\n },\n\n el: function getElement() {\n return element;\n }\n };\n};\n\nmodule.exports = AdsLabelFactory;","'use strict';\n\nvar baseVideoJsComponent = videojs.getComponent('Component');\n\nvar AdsLabel = require('./ads-label')(baseVideoJsComponent);\n\nvideojs.registerComponent('AdsLabel', videojs.extend(baseVideoJsComponent, AdsLabel));\n","'use strict';\n\n/**\n * The component that shows a black screen until the ads plugin has decided if it can or it can not play the ad.\n *\n * Note: In case you wonder why instead of this black poster we don't just show the spinner loader.\n * IOS devices do not work well with animations and the browser chrashes from time to time That is why we chose to\n * have a secondary black poster.\n *\n * It also makes it much more easier for the users of the plugin since it does not change the default behaviour of the\n * spinner and the player works the same way with and without the plugin.\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvar element = document.createElement('div');\n\nvar BlackPosterFactory = function(baseComponent) {\n return {\n /** @constructor */\n init: function init(player, options) {\n options.el = element;\n element.className = 'vjs-black-poster';\n baseComponent.call(this, player, options);\n\n var posterImg = player.getChild('posterImage');\n\n //We need to do it asynchronously to be sure that the black poster el is on the dom.\n setTimeout(function() {\n if(posterImg && player && player.el()) {\n player.el().insertBefore(element, posterImg.el());\n }\n }, 0);\n },\n el: function getElement() {\n return element;\n }\n };\n};\n\nmodule.exports = BlackPosterFactory;","'use strict';\n\nvar baseVideoJsComponent = videojs.getComponent('Component');\n\nvar BlackPoster = require('./black-poster')(baseVideoJsComponent);\n\nvideojs.registerComponent('BlackPoster', videojs.extend(baseVideoJsComponent, BlackPoster));\n","'use strict';\n\nvar VASTClient = require('../ads/vast/VASTClient');\nvar VASTError = require('../ads/vast/VASTError');\nvar vastUtil = require('../ads/vast/vastUtil');\n\nvar VASTIntegrator = require('../ads/vast/VASTIntegrator');\nvar VPAIDIntegrator = require('../ads/vpaid/VPAIDIntegrator');\n\nvar async = require('../utils/async');\nvar dom = require('../utils/dom');\nvar playerUtils = require('../utils/playerUtils');\nvar utilities = require('../utils/utilityFunctions');\n\nmodule.exports = function VASTPlugin(options) {\n var snapshot;\n var player = this;\n var vast = new VASTClient();\n var adsCanceled = false;\n var defaultOpts = {\n // maximum amount of time in ms to wait to receive `adsready` from the ad\n // implementation after play has been requested. Ad implementations are\n // expected to load any dynamic libraries and make any requests to determine\n // ad policies for a video during this time.\n timeout: 500,\n\n //TODO:finish this IOS FIX\n //Whenever you play an add on IOS, the native player kicks in and we loose control of it. On very heavy pages the 'play' event\n // May occur after the video content has already started. This is wrong if you want to play a preroll ad that needs to happen before the user\n // starts watching the content. To prevent this usec\n iosPrerollCancelTimeout: 2000,\n\n // maximun amount of time for the ad to actually start playing. If this timeout gets\n // triggered the ads will be cancelled\n adCancelTimeout: 3000,\n\n // Boolean flag that configures the player to play a new ad before the user sees the video again\n // the current video\n playAdAlways: false,\n\n // Flag to enable or disable the ads by default.\n adsEnabled: true,\n\n // Boolean flag to enable or disable the resize with window.resize or orientationchange\n autoResize: true,\n\n // Path to the VPAID flash ad's loader\n vpaidFlashLoaderPath: '/VPAIDFlash.swf'\n };\n\n var settings = utilities.extend({}, defaultOpts, options || {});\n\n if(utilities.isUndefined(settings.adTagUrl) && utilities.isDefined(settings.url)){\n settings.adTagUrl = settings.url;\n }\n\n if (utilities.isString(settings.adTagUrl)) {\n settings.adTagUrl = utilities.echoFn(settings.adTagUrl);\n }\n\n if (utilities.isDefined(settings.adTagXML) && !utilities.isFunction(settings.adTagXML)) {\n return trackAdError(new VASTError('on VideoJS VAST plugin, the passed adTagXML option does not contain a function'));\n }\n\n if (!utilities.isDefined(settings.adTagUrl) && !utilities.isFunction(settings.adTagXML)) {\n return trackAdError(new VASTError('on VideoJS VAST plugin, missing adTagUrl on options object'));\n }\n\n vastUtil.runFlashSupportCheck(settings.vpaidFlashLoaderPath);// Necessary step for VPAIDFLASHClient to work.\n\n playerUtils.prepareForAds(player);\n\n if (settings.playAdAlways) {\n // No matter what happens we play a new ad before the user sees the video again.\n player.on('vast.contentEnd', function () {\n setTimeout(function () {\n player.trigger('vast.reset');\n }, 0);\n });\n }\n\n player.on('vast.firstPlay', tryToPlayPrerollAd);\n\n player.on('vast.reset', function () {\n //If we are reseting the plugin, we don't want to restore the content\n snapshot = null;\n cancelAds();\n });\n\n player.vast = {\n isEnabled: function () {\n return settings.adsEnabled;\n },\n\n enable: function () {\n settings.adsEnabled = true;\n },\n\n disable: function () {\n settings.adsEnabled = false;\n }\n };\n\n return player.vast;\n\n /**** Local functions ****/\n function tryToPlayPrerollAd() {\n //We remove the poster to prevent flickering whenever the content starts playing\n playerUtils.removeNativePoster(player);\n\n playerUtils.once(player, ['vast.adsCancel', 'vast.adEnd'], function () {\n removeAdUnit();\n restoreVideoContent();\n });\n\n async.waterfall([\n checkAdsEnabled,\n preparePlayerForAd,\n startAdCancelTimeout,\n playPrerollAd\n ], function (error, response) {\n if (error) {\n trackAdError(error, response);\n } else {\n player.trigger('vast.adEnd');\n }\n });\n\n /*** Local functions ***/\n\n function removeAdUnit() {\n if (player.vast && player.vast.adUnit) {\n player.vast.adUnit = null; //We remove the adUnit\n }\n }\n\n function restoreVideoContent() {\n setupContentEvents();\n if (snapshot) {\n playerUtils.restorePlayerSnapshot(player, snapshot);\n snapshot = null;\n }\n }\n\n function setupContentEvents() {\n playerUtils.once(player, ['playing', 'vast.reset', 'vast.firstPlay'], function (evt) {\n if (evt.type !== 'playing') {\n return;\n }\n\n player.trigger('vast.contentStart');\n\n playerUtils.once(player, ['ended', 'vast.reset', 'vast.firstPlay'], function (evt) {\n if (evt.type === 'ended') {\n player.trigger('vast.contentEnd');\n }\n });\n });\n }\n\n function checkAdsEnabled(next) {\n if (settings.adsEnabled) {\n return next(null);\n }\n next(new VASTError('Ads are not enabled'));\n }\n\n function preparePlayerForAd(next) {\n if (canPlayPrerollAd()) {\n snapshot = playerUtils.getPlayerSnapshot(player);\n player.pause();\n addSpinnerIcon();\n\n if(player.paused()) {\n next(null);\n } else {\n playerUtils.once(player, ['playing'], function() {\n player.pause();\n next(null);\n });\n }\n } else {\n next(new VASTError('video content has been playing before preroll ad'));\n }\n }\n\n function canPlayPrerollAd() {\n return !utilities.isIPhone() || player.currentTime() <= settings.iosPrerollCancelTimeout;\n }\n\n function startAdCancelTimeout(next) {\n var adCancelTimeoutId;\n adsCanceled = false;\n\n adCancelTimeoutId = setTimeout(function () {\n trackAdError(new VASTError('timeout while waiting for the video to start playing', 402));\n }, settings.adCancelTimeout);\n\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], clearAdCancelTimeout);\n\n /*** local functions ***/\n function clearAdCancelTimeout() {\n if (adCancelTimeoutId) {\n clearTimeout(adCancelTimeoutId);\n adCancelTimeoutId = null;\n }\n }\n\n next(null);\n }\n\n function addSpinnerIcon() {\n dom.addClass(player.el(), 'vjs-vast-ad-loading');\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], removeSpinnerIcon);\n }\n\n function removeSpinnerIcon() {\n //IMPORTANT NOTE: We remove the spinnerIcon asynchronously to give time to the browser to start the video.\n // If we remove it synchronously we see a flash of the content video before the ad starts playing.\n setTimeout(function () {\n dom.removeClass(player.el(), 'vjs-vast-ad-loading');\n }, 100);\n }\n\n }\n\n function cancelAds() {\n player.trigger('vast.adsCancel');\n adsCanceled = true;\n }\n\n function playPrerollAd(callback) {\n async.waterfall([\n getVastResponse,\n playAd\n ], callback);\n }\n\n function getVastResponse(callback) {\n vast.getVASTResponse(settings.adTagUrl ? settings.adTagUrl() : settings.adTagXML, callback);\n }\n\n function playAd(vastResponse, callback) {\n //TODO: Find a better way to stop the play. The 'playPrerollWaterfall' ends in an inconsistent situation\n //If the state is not 'preroll?' it means the ads were canceled therefore, we break the waterfall\n if (adsCanceled) {\n return;\n }\n\n var adIntegrator = isVPAID(vastResponse) ? new VPAIDIntegrator(player, settings) : new VASTIntegrator(player);\n var adFinished = false;\n\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], function (evt) {\n if (evt.type === 'vast.adStart') {\n addAdsLabel();\n }\n });\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeAdsLabel);\n\n if (utilities.isIDevice()) {\n preventManualProgress();\n }\n\n player.vast.vastResponse = vastResponse;\n player.vast.adUnit = adIntegrator.playAd(vastResponse, callback);\n\n /*** Local functions ****/\n function addAdsLabel() {\n if (adFinished || player.controlBar.getChild('AdsLabel')) {\n return;\n }\n\n player.controlBar.addChild('AdsLabel');\n }\n\n function removeAdsLabel() {\n player.controlBar.removeChild('AdsLabel');\n adFinished = true;\n }\n\n function preventManualProgress() {\n //IOS video clock is very unreliable and we need a 3 seconds threshold to ensure that the user forwarded/rewound the ad\n var PROGRESS_THRESHOLD = 3;\n var previousTime = 0;\n var skipad_attempts = 0;\n\n player.on('timeupdate', preventAdSeek);\n player.on('ended', preventAdSkip);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel', 'vast.adError'], stopPreventManualProgress);\n\n /*** Local functions ***/\n function preventAdSkip() {\n // Ignore ended event if the Ad time was not 'near' the end\n // and revert time to the previous 'valid' time\n if ((player.duration() - previousTime) > PROGRESS_THRESHOLD) {\n player.pause(true); // this reduce the video jitter if the IOS skip button is pressed\n player.play(true); // we need to trigger the play to put the video element back in a valid state\n player.currentTime(previousTime);\n }\n }\n\n function preventAdSeek() {\n var currentTime = player.currentTime();\n var progressDelta = Math.abs(currentTime - previousTime);\n if (progressDelta > PROGRESS_THRESHOLD) {\n skipad_attempts += 1;\n if (skipad_attempts >= 2) {\n player.pause(true);\n }\n player.currentTime(previousTime);\n } else {\n previousTime = currentTime;\n }\n }\n\n function stopPreventManualProgress() {\n player.off('timeupdate', preventAdSeek);\n player.off('ended', preventAdSkip);\n }\n }\n }\n\n function trackAdError(error, vastResponse) {\n player.trigger({type: 'vast.adError', error: error});\n cancelAds();\n if (console && console.log) {\n console.log('AD ERROR:', error.message, error, vastResponse);\n }\n }\n\n function isVPAID(vastResponse) {\n var i, len;\n var mediaFiles = vastResponse.mediaFiles;\n for (i = 0, len = mediaFiles.length; i < len; i++) {\n if (vastUtil.isVPAID(mediaFiles[i])) {\n return true;\n }\n }\n return false;\n }\n};\n","//Small subset of async\n\nvar utilities = require('./utilityFunctions');\n\nvar async = {};\n\nasync.setImmediate = function (fn) {\n setTimeout(fn, 0);\n};\n\nasync.iterator = function (tasks) {\n var makeCallback = function (index) {\n var fn = function () {\n if (tasks.length) {\n tasks[index].apply(null, arguments);\n }\n return fn.next();\n };\n fn.next = function () {\n return (index < tasks.length - 1) ? makeCallback(index + 1) : null;\n };\n return fn;\n };\n return makeCallback(0);\n};\n\n\nasync.waterfall = function (tasks, callback) {\n callback = callback || function () { };\n if (!utilities.isArray(tasks)) {\n var err = new Error('First argument to waterfall must be an array of functions');\n return callback(err);\n }\n if (!tasks.length) {\n return callback();\n }\n var wrapIterator = function (iterator) {\n return function (err) {\n if (err) {\n callback.apply(null, arguments);\n callback = function () {\n };\n }\n else {\n var args = Array.prototype.slice.call(arguments, 1);\n var next = iterator.next();\n if (next) {\n args.push(wrapIterator(next));\n }\n else {\n args.push(callback);\n }\n async.setImmediate(function () {\n iterator.apply(null, args);\n });\n }\n };\n };\n wrapIterator(async.iterator(tasks))();\n};\n\nasync.when = function (condition, callback) {\n if (!utilities.isFunction(callback)) {\n throw new Error(\"async.when error: missing callback argument\");\n }\n\n var isAllowed = utilities.isFunction(condition) ? condition : function () {\n return !!condition;\n };\n\n return function () {\n var args = utilities.arrayLikeObjToArray(arguments);\n var next = args.pop();\n\n if (isAllowed.apply(null, args)) {\n return callback.apply(this, arguments);\n }\n\n args.unshift(null);\n return next.apply(null, args);\n };\n};\n\nmodule.exports = async;\n\n","'use strict';\n\nvar utilities = require('./utilityFunctions');\n\nvar dom = {};\n\ndom.isVisible = function isVisible(el) {\n var style = window.getComputedStyle(el);\n return style.visibility !== 'hidden';\n};\n\ndom.isHidden = function isHidden(el) {\n var style = window.getComputedStyle(el);\n return style.display === 'none';\n};\n\ndom.isShown = function isShown(el) {\n return !dom.isHidden(el);\n};\n\ndom.hide = function hide(el) {\n el.__prev_style_display_ = el.style.display;\n el.style.display = 'none';\n};\n\ndom.show = function show(el) {\n if (dom.isHidden(el)) {\n el.style.display = el.__prev_style_display_;\n }\n el.__prev_style_display_ = undefined;\n};\n\ndom.hasClass = function hasClass(el, cssClass) {\n var classes, i, len;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.contains(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n cssClass = (cssClass || '');\n\n for (i = 0, len = classes.length; i < len; i += 1) {\n if (classes[i] === cssClass) {\n return true;\n }\n }\n }\n return false;\n};\n\ndom.addClass = function (el, cssClass) {\n var classes;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.add(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n if (utilities.isString(cssClass) && utilities.isNotEmptyString(cssClass.replace(/\\s+/, ''))) {\n classes.push(cssClass);\n el.setAttribute('class', classes.join(' '));\n }\n }\n};\n\ndom.removeClass = function (el, cssClass) {\n var classes;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.remove(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n var newClasses = [];\n var i, len;\n if (utilities.isString(cssClass) && utilities.isNotEmptyString(cssClass.replace(/\\s+/, ''))) {\n\n for (i = 0, len = classes.length; i < len; i += 1) {\n if (cssClass !== classes[i]) {\n newClasses.push(classes[i]);\n }\n }\n el.setAttribute('class', newClasses.join(' '));\n }\n }\n};\n\ndom.addEventListener = function addEventListener(el, type, handler) {\n if(utilities.isArray(el)){\n utilities.forEach(el, function(e) {\n dom.addEventListener(e, type, handler);\n });\n return;\n }\n\n if(utilities.isArray(type)){\n utilities.forEach(type, function(t) {\n dom.addEventListener(el, t, handler);\n });\n return;\n }\n\n if (el.addEventListener) {\n el.addEventListener(type, handler, false);\n } else if (el.attachEvent) {\n // WARNING!!! this is a very naive implementation !\n // the event object that should be passed to the handler\n // would not be there for IE8\n // we should use \"window.event\" and then \"event.srcElement\"\n // instead of \"event.target\"\n el.attachEvent(\"on\" + type, handler);\n }\n};\n\ndom.removeEventListener = function removeEventListener(el, type, handler) {\n if(utilities.isArray(el)){\n utilities.forEach(el, function(e) {\n dom.removeEventListener(e, type, handler);\n });\n return;\n }\n\n if(utilities.isArray(type)){\n utilities.forEach(type, function(t) {\n dom.removeEventListener(el, t, handler);\n });\n return;\n }\n\n if (el.removeEventListener) {\n el.removeEventListener(type, handler, false);\n } else if (el.detachEvent) {\n el.detachEvent(\"on\" + type, handler);\n } else {\n el[\"on\" + type] = null;\n }\n};\n\ndom.dispatchEvent = function dispatchEvent(el, event) {\n if (el.dispatchEvent) {\n el.dispatchEvent(event);\n } else {\n el.fireEvent(\"on\" + event.eventType, event);\n }\n};\n\ndom.isDescendant = function isDescendant(parent, child) {\n var node = child.parentNode;\n while (node !== null) {\n if (node === parent) {\n return true;\n }\n node = node.parentNode;\n }\n return false;\n};\n\ndom.getTextContent = function getTextContent(el){\n return el.textContent || el.text;\n};\n\ndom.prependChild = function prependChild(parent, child) {\n if(child.parentNode){\n child.parentNode.removeChild(child);\n }\n return parent.insertBefore(child, parent.firstChild);\n};\n\ndom.remove = function removeNode(node){\n if(node && node.parentNode){\n node.parentNode.removeChild(node);\n }\n};\n\ndom.isDomElement = function isDomElement(o) {\n return o instanceof Element;\n};\n\ndom.click = function(el, handler) {\n dom.addEventListener(el, 'click', handler);\n};\n\ndom.once = function(el, type, handler) {\n function handlerWrap() {\n handler.apply(null, arguments);\n dom.removeEventListener(el, type, handlerWrap);\n }\n\n dom.addEventListener(el, type, handlerWrap);\n};\n\n//Note: there is no getBoundingClientRect on iPad so we need a fallback\ndom.getDimension = function getDimension(element) {\n var rect;\n\n //On IE9 and below getBoundingClientRect does not work consistently\n if(!utilities.isOldIE() && element.getBoundingClientRect) {\n rect = element.getBoundingClientRect();\n return {\n width: rect.width,\n height: rect.height\n };\n }\n\n return {\n width: element.offsetWidth,\n height: element.offsetHeight\n };\n};\n\nmodule.exports = dom;","'use strict';\n\nvar urlUtils = require('./urlUtils');\nvar utilities = require('./utilityFunctions');\n\nfunction HttpRequestError(message) {\n this.message = 'HttpRequest Error: ' + (message || '');\n}\nHttpRequestError.prototype = new Error();\nHttpRequestError.prototype.name = \"HttpRequest Error\";\n\nfunction HttpRequest(createXhr) {\n if (!utilities.isFunction(createXhr)) {\n throw new HttpRequestError('Missing XMLHttpRequest factory method');\n }\n\n this.createXhr = createXhr;\n}\n\nHttpRequest.prototype.run = function (method, url, callback, options) {\n sanityCheck(url, callback, options);\n var timeout, timeoutId;\n var xhr = this.createXhr();\n options = options || {};\n timeout = utilities.isNumber(options.timeout) ? options.timeout : 0;\n\n xhr.open(method, urlUtils.urlParts(url).href, true);\n\n if (options.headers) {\n setHeaders(xhr, options.headers);\n }\n\n if (options.withCredentials) {\n xhr.withCredentials = true;\n }\n\n xhr.onload = function () {\n var statusText, response, status;\n\n /**\n * The only way to do a secure request on IE8 and IE9 is with the XDomainRequest object. Unfortunately, microsoft is\n * so nice that decided that the status property and the 'getAllResponseHeaders' method where not needed so we have to\n * fake them. If the request gets done with an XDomainRequest instance, we will assume that there are no headers and\n * the status will always be 200. If you don't like it, DO NOT USE ANCIENT BROWSERS!!!\n *\n * For mor info go to: https://msdn.microsoft.com/en-us/library/cc288060(v=vs.85).aspx\n */\n if (!xhr.getAllResponseHeaders) {\n xhr.getAllResponseHeaders = function () {\n return null;\n };\n }\n\n if (!xhr.status) {\n xhr.status = 200;\n }\n\n if (utilities.isDefined(timeoutId)) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n\n statusText = xhr.statusText || '';\n\n // responseText is the old-school way of retrieving response (supported by IE8 & 9)\n // response/responseType properties were introduced in XHR Level2 spec (supported by IE10)\n response = ('response' in xhr) ? xhr.response : xhr.responseText;\n\n // normalize IE9 bug (http://bugs.jquery.com/ticket/1450)\n status = xhr.status === 1223 ? 204 : xhr.status;\n\n callback(\n status,\n response,\n xhr.getAllResponseHeaders(),\n statusText);\n };\n\n xhr.onerror = requestError;\n xhr.onabort = requestError;\n\n xhr.send();\n\n if (timeout > 0) {\n timeoutId = setTimeout(function () {\n xhr && xhr.abort();\n }, timeout);\n }\n\n function sanityCheck(url, callback, options) {\n if (!utilities.isString(url) || utilities.isEmptyString(url)) {\n throw new HttpRequestError(\"Invalid url '\" + url + \"'\");\n }\n\n if (!utilities.isFunction(callback)) {\n throw new HttpRequestError(\"Invalid handler '\" + callback + \"' for the http request\");\n }\n\n if (utilities.isDefined(options) && !utilities.isObject(options)) {\n throw new HttpRequestError(\"Invalid options map '\" + options + \"'\");\n }\n }\n\n function setHeaders(xhr, headers) {\n utilities.forEach(headers, function (value, key) {\n if (utilities.isDefined(value)) {\n xhr.setRequestHeader(key, value);\n }\n });\n }\n\n function requestError() {\n callback(-1, null, null, '');\n }\n};\n\nHttpRequest.prototype.get = function (url, callback, options) {\n this.run('GET', url, processResponse, options);\n\n function processResponse(status, response, headersString, statusText) {\n if (isSuccess(status)) {\n callback(null, response, status, headersString, statusText);\n } else {\n callback(new HttpRequestError(statusText), response, status, headersString, statusText);\n }\n }\n\n function isSuccess(status) {\n return 200 <= status && status < 300;\n }\n};\n\nfunction createXhr() {\n var xhr = new XMLHttpRequest();\n if (!(\"withCredentials\" in xhr)) {\n // XDomainRequest for IE.\n xhr = new XDomainRequest();\n }\n return xhr;\n}\n\nvar http = new HttpRequest(createXhr);\n\nmodule.exports = {\n http: http,\n HttpRequest: HttpRequest,\n HttpRequestError: HttpRequestError,\n createXhr: createXhr\n};\n","'use strict';\n\nvar dom = require('./dom');\nvar utilities = require('./utilityFunctions');\n\nvar playerUtils = {};\n\n/**\n * Returns an object that captures the portions of player state relevant to\n * video playback. The result of this function can be passed to\n * restorePlayerSnapshot with a player to return the player to the state it\n * was in when this function was invoked.\n * @param {object} player The videojs player object\n */\nplayerUtils.getPlayerSnapshot = function getPlayerSnapshot(player) {\n var tech = player.el().querySelector('.vjs-tech');\n\n var snapshot = {\n ended: player.ended(),\n src: player.currentSrc(),\n currentTime: player.currentTime(),\n type: player.currentType(),\n playing: !player.paused(),\n suppressedTracks: getSuppressedTracks(player)\n };\n\n if (tech) {\n snapshot.nativePoster = tech.poster;\n snapshot.style = tech.getAttribute('style');\n }\n return snapshot;\n\n /**** Local Functions ****/\n function getSuppressedTracks(player) {\n var tracks = player.remoteTextTracks ? player.remoteTextTracks() : [];\n\n if (tracks && utilities.isArray(tracks.tracks_)) {\n tracks = tracks.tracks_;\n }\n\n if (!utilities.isArray(tracks)) {\n tracks = [];\n }\n\n var suppressedTracks = [];\n tracks.forEach(function (track) {\n suppressedTracks.push({\n track: track,\n mode: track.mode\n });\n track.mode = 'disabled';\n });\n\n return suppressedTracks;\n }\n};\n\n/**\n * Attempts to modify the specified player so that its state is equivalent to\n * the state of the snapshot.\n * @param {object} snapshot - the player state to apply\n */\nplayerUtils.restorePlayerSnapshot = function restorePlayerSnapshot(player, snapshot) {\n var tech = player.el().querySelector('.vjs-tech');\n var attempts = 20; // the number of remaining attempts to restore the snapshot\n\n if (snapshot.nativePoster) {\n tech.poster = snapshot.nativePoster;\n }\n\n if ('style' in snapshot) {\n // overwrite all css style properties to restore state precisely\n tech.setAttribute('style', snapshot.style || '');\n }\n\n if (hasSrcChanged(player, snapshot)) {\n\n // on ios7, fiddling with textTracks too early will cause safari to crash\n player.one('contentloadedmetadata', restoreTracks);\n\n player.one('canplay', tryToResume);\n ensureCanplayEvtGetsFired();\n\n // if the src changed for ad playback, reset it\n player.src({src: snapshot.src, type: snapshot.type});\n\n // safari requires a call to `load` to pick up a changed source\n player.load();\n\n } else {\n restoreTracks();\n\n if (snapshot.playing) {\n player.play();\n }\n }\n\n /*** Local Functions ***/\n\n /**\n * Sometimes firefox does not trigger the 'canplay' evt.\n * This code ensure that it always gets triggered triggered.\n */\n function ensureCanplayEvtGetsFired() {\n var timeoutId = setTimeout(function() {\n player.trigger('canplay');\n }, 1000);\n\n player.one('canplay', function(){\n clearTimeout(timeoutId);\n });\n }\n\n /**\n * Determine whether the player needs to be restored to its state\n * before ad playback began. With a custom ad display or burned-in\n * ads, the content player state hasn't been modified and so no\n * restoration is required\n */\n function hasSrcChanged(player, snapshot) {\n if (player.src()) {\n return player.src() !== snapshot.src;\n }\n // the player was configured through source element children\n return player.currentSrc() !== snapshot.src;\n }\n\n function restoreTracks() {\n var suppressedTracks = snapshot.suppressedTracks;\n suppressedTracks.forEach(function (trackSnapshot) {\n trackSnapshot.track.mode = trackSnapshot.mode;\n });\n }\n\n /**\n * Determine if the video element has loaded enough of the snapshot source\n * to be ready to apply the rest of the state\n */\n function tryToResume() {\n\n // if some period of the video is seekable, resume playback\n // otherwise delay a bit and then check again unless we're out of attempts\n\n if (!playerUtils.isReadyToResume(player) && attempts--) {\n setTimeout(tryToResume, 50);\n } else {\n try {\n if(player.currentTime() !== snapshot.currentTime) {\n if (snapshot.playing) { // if needed restore playing status after seek completes\n player.one('seeked', function() {\n player.play();\n });\n }\n player.currentTime(snapshot.currentTime);\n\n } else if (snapshot.playing) {\n // if needed and no seek has been performed, restore playing status immediately\n player.play();\n }\n\n } catch (e) {\n videojs.log.warn('Failed to resume the content after an advertisement', e);\n }\n }\n }\n};\n\nplayerUtils.isReadyToResume = function (player) {\n\n if (player.readyState() > 1) {\n // some browsers and media aren't \"seekable\".\n // readyState greater than 1 allows for seeking without exceptions\n return true;\n }\n\n if (player.seekable() === undefined) {\n // if the player doesn't expose the seekable time ranges, try to\n // resume playback immediately\n return true;\n }\n\n if (player.seekable().length > 0) {\n // if some period of the video is seekable, resume playback\n return true;\n }\n\n return false;\n};\n\n/**\n * This function prepares the player to display ads.\n * Adding convenience events like the 'vast.firsPlay' that gets fired when the video is first played\n * and ads the blackPoster to the player to prevent content from being displayed before the preroll ad.\n *\n * @param player\n */\nplayerUtils.prepareForAds = function (player) {\n var blackPoster = player.addChild('blackPoster');\n var _firstPlay = true;\n var volumeSnapshot;\n\n\n monkeyPatchPlayerApi();\n\n player.on('play', tryToTriggerFirstPlay);\n player.on('vast.reset', resetFirstPlay);//Every time we change the sources we reset the first play.\n player.on('vast.firstPlay', restoreContentVolume);\n player.on('error', hideBlackPoster);//If there is an error in the player we remove the blackposter to show the err msg\n player.on('vast.adStart', hideBlackPoster);\n player.on('vast.adsCancel', hideBlackPoster);\n player.on('vast.adError', hideBlackPoster);\n player.on('vast.adStart', addStyles);\n player.on('vast.adEnd', removeStyles);\n player.on('vast.adsCancel', removeStyles);\n\n /*** Local Functions ***/\n\n /**\n What this function does is ugly and horrible and I should think twice before calling myself a good developer. With that said,\n it is the best solution I could find to mute the video until the 'play' event happens (on mobile devices) and the plugin can decide whether\n to play the ad or not.\n\n We also need this monkeypatch to be able to pause and resume an ad using the player's API\n\n If you have a better solution please do tell me.\n */\n function monkeyPatchPlayerApi() {\n\n /**\n * Monkey patch needed to handle firstPlay and resume of playing ad.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are restoring a VAST ad.\n * @returns {player}\n */\n var origPlay = player.play;\n player.play = function (callOrigPlay) {\n var that = this;\n\n if (isFirstPlay()) {\n firstPlay();\n } else {\n resume(callOrigPlay);\n }\n\n return this;\n\n /*** local functions ***/\n function firstPlay() {\n if (!utilities.isIPhone()) {\n volumeSnapshot = saveVolumeSnapshot();\n player.muted(true);\n }\n\n origPlay.apply(that, arguments);\n }\n\n function resume(callOrigPlay) {\n if (isAdPlaying() && !callOrigPlay) {\n player.vast.adUnit.resumeAd();\n } else {\n origPlay.apply(that, arguments);\n }\n }\n };\n\n\n /**\n * Needed monkey patch to handle pause of playing ad.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are pausing a VAST ad.\n * @returns {player}\n */\n var origPause = player.pause;\n player.pause = function (callOrigPause) {\n if (isAdPlaying() && !callOrigPause) {\n player.vast.adUnit.pauseAd();\n } else {\n origPause.apply(this, arguments);\n }\n return this;\n };\n\n\n /**\n * Needed monkey patch to handle paused state of the player when ads are playing.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are pausing a VAST ad.\n * @returns {player}\n */\n var origPaused = player.paused;\n player.paused = function (callOrigPaused) {\n if (isAdPlaying() && !callOrigPaused) {\n return player.vast.adUnit.isPaused();\n }\n return origPaused.apply(this, arguments);\n };\n }\n\n function isAdPlaying() {\n return player.vast && player.vast.adUnit;\n }\n\n function tryToTriggerFirstPlay() {\n if (isFirstPlay()) {\n _firstPlay = false;\n player.trigger('vast.firstPlay');\n }\n }\n\n function resetFirstPlay() {\n _firstPlay = true;\n blackPoster.show();\n restoreContentVolume();\n }\n\n function isFirstPlay() {\n return _firstPlay;\n }\n\n function saveVolumeSnapshot() {\n return {\n muted: player.muted(),\n volume: player.volume()\n };\n }\n\n function restoreContentVolume() {\n if (volumeSnapshot) {\n player.currentTime(0);\n restoreVolumeSnapshot(volumeSnapshot);\n volumeSnapshot = null;\n }\n }\n\n function restoreVolumeSnapshot(snapshot) {\n if (utilities.isObject(snapshot)) {\n player.volume(snapshot.volume);\n player.muted(snapshot.muted);\n }\n }\n\n function hideBlackPoster() {\n if (!dom.hasClass(blackPoster.el(), 'vjs-hidden')) {\n blackPoster.hide();\n }\n }\n\n function addStyles() {\n dom.addClass(player.el(), 'vjs-ad-playing');\n }\n\n function removeStyles() {\n dom.removeClass(player.el(), 'vjs-ad-playing');\n }\n};\n\n/**\n * Remove the poster attribute from the video element tech, if present. When\n * reusing a video element for multiple videos, the poster image will briefly\n * reappear while the new source loads. Removing the attribute ahead of time\n * prevents the poster from showing up between videos.\n * @param {object} player The videojs player object\n */\nplayerUtils.removeNativePoster = function (player) {\n var tech = player.el().querySelector('.vjs-tech');\n if (tech) {\n tech.removeAttribute('poster');\n }\n};\n\n/**\n * Helper function to listen to many events until one of them gets fired, then we\n * execute the handler and unsubscribe all the event listeners;\n *\n * @param player specific player from where to listen for the events\n * @param events array of events\n * @param handler function to execute once one of the events fires\n */\nplayerUtils.once = function once(player, events, handler) {\n function listener() {\n handler.apply(null, arguments);\n\n events.forEach(function (event) {\n player.off(event, listener);\n });\n }\n\n events.forEach(function (event) {\n player.on(event, listener);\n });\n};\n\n\nmodule.exports = playerUtils;","'use strict';\n\nvar utilities = require('./utilityFunctions');\n\n/**\n *\n * IMPORTANT NOTE: This function comes from angularJs and was originally called urlResolve\n * you can take a look at the original code here https://github.com/angular/angular.js/blob/master/src/ng/urlUtils.js\n *\n * Implementation Notes for non-IE browsers\n * ----------------------------------------\n * Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM,\n * results both in the normalizing and parsing of the URL. Normalizing means that a relative\n * URL will be resolved into an absolute URL in the context of the application document.\n * Parsing means that the anchor node's host, hostname, protocol, port, pathname and related\n * properties are all populated to reflect the normalized URL. This approach has wide\n * compatibility - Safari 1+, Mozilla 1+, Opera 7+,e etc. See\n * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n *\n * Implementation Notes for IE\n * ---------------------------\n * IE >= 8 and <= 10 normalizes the URL when assigned to the anchor node similar to the other\n * browsers. However, the parsed components will not be set if the URL assigned did not specify\n * them. (e.g. if you assign a.href = \"foo\", then a.protocol, a.host, etc. will be empty.) We\n * work around that by performing the parsing in a 2nd step by taking a previously normalized\n * URL (e.g. by assigning to a.href) and assigning it a.href again. This correctly populates the\n * properties such as protocol, hostname, port, etc.\n *\n * IE7 does not normalize the URL when assigned to an anchor node. (Apparently, it does, if one\n * uses the inner HTML approach to assign the URL as part of an HTML snippet -\n * http://stackoverflow.com/a/472729) However, setting img[src] does normalize the URL.\n * Unfortunately, setting img[src] to something like \"javascript:foo\" on IE throws an exception.\n * Since the primary usage for normalizing URLs is to sanitize such URLs, we can't use that\n * method and IE < 8 is unsupported.\n *\n * References:\n * http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement\n * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n * http://url.spec.whatwg.org/#urlutils\n * https://github.com/angular/angular.js/pull/2902\n * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/\n *\n * @kind function\n * @param {string} url The URL to be parsed.\n * @description Normalizes and parses a URL.\n * @returns {object} Returns the normalized URL as a dictionary.\n *\n * | member name | Description |\n * |---------------|----------------|\n * | href | A normalized version of the provided URL if it was not an absolute URL |\n * | protocol | The protocol including the trailing colon |\n * | host | The host and port (if the port is non-default) of the normalizedUrl |\n * | search | The search params, minus the question mark |\n * | hash | The hash string, minus the hash symbol\n * | hostname | The hostname\n * | port | The port, without \":\"\n * | pathname | The pathname, beginning with \"/\"\n *\n */\n\nvar urlParsingNode = document.createElement(\"a\");\n/**\n * documentMode is an IE-only property\n * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx\n */\nvar msie = document.documentMode;\n\nfunction urlParts(url) {\n var href = url;\n\n if (msie) {\n // Normalize before parse. Refer Implementation Notes on why this is\n // done in two steps on IE.\n urlParsingNode.setAttribute(\"href\", href);\n href = urlParsingNode.href;\n }\n\n urlParsingNode.setAttribute('href', href);\n\n // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n return {\n href: urlParsingNode.href,\n protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n host: urlParsingNode.host,\n search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n hostname: urlParsingNode.hostname,\n port: utilities.isNotEmptyString(urlParsingNode.port)? urlParsingNode.port: 80,\n pathname: (urlParsingNode.pathname.charAt(0) === '/')\n ? urlParsingNode.pathname\n : '/' + urlParsingNode.pathname\n };\n}\n\n\n/**\n * This function accepts a query string (search part of a url) and returns a dictionary with\n * the different key value pairs\n * @param {string} qs queryString\n */\nfunction queryStringToObj(qs, cond) {\n var pairs, qsObj;\n\n cond = utilities.isFunction(cond)? cond : function() {\n return true;\n };\n\n qs = qs.trim().replace(/^\\?/, '');\n pairs = qs.split('&');\n qsObj = {};\n\n utilities.forEach(pairs, function (pair) {\n var keyValue, key, value;\n if (pair !== '') {\n keyValue = pair.split('=');\n key = keyValue[0];\n value = keyValue[1];\n if(cond(key, value)){\n qsObj[key] = value;\n }\n }\n });\n\n return qsObj;\n}\n\n/**\n * This function accepts an object and serializes it into a query string without the leading '?'\n * @param obj\n * @returns {string}\n */\nfunction objToQueryString(obj) {\n var pairs = [];\n utilities.forEach(obj, function (value, key) {\n pairs.push(key + '=' + value);\n });\n return pairs.join('&');\n}\n\nmodule.exports = {\n urlParts: urlParts,\n queryStringToObj: queryStringToObj,\n objToQueryString: objToQueryString\n};\n","/*jshint unused:false */\n\"use strict\";\n\nvar NODE_TYPE_ELEMENT = 1;\nvar SNAKE_CASE_REGEXP = /[A-Z]/g;\nvar EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/i;\n/*jslint maxlen: 500 */\nvar ISO8086_REGEXP = /^([\\+-]?\\d{4}(?!\\d{2}\\b))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))([T\\s]((([01]\\d|2[0-3])((:?)[0-5]\\d)?|24\\:?00)([\\.,]\\d+(?!:))?)?(\\17[0-5]\\d([\\.,]\\d+)?)?([zZ]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)?$/;\n\n\nfunction noop(){ }\n\nfunction isNull(o) {\n return o === null;\n}\n\nfunction isDefined(o){\n return o !== undefined;\n}\n\nfunction isUndefined(o){\n return o === undefined;\n}\n\nfunction isObject(obj) {\n return typeof obj === 'object';\n}\n\nfunction isFunction(str){\n return typeof str === 'function';\n}\n\nfunction isNumber(num){\n return typeof num === 'number';\n}\n\nfunction isWindow(obj) {\n return utilities.isObject(obj) && obj.window === obj;\n}\n\nfunction isArray(array){\n return Object.prototype.toString.call( array ) === '[object Array]';\n}\n\nfunction isArrayLike(obj) {\n if (obj === null || utilities.isWindow(obj) || utilities.isFunction(obj) || utilities.isUndefined(obj)) {\n return false;\n }\n\n var length = obj.length;\n\n if (obj.nodeType === NODE_TYPE_ELEMENT && length) {\n return true;\n }\n\n return utilities.isString(obj) || utilities.isArray(obj) || length === 0 ||\n typeof length === 'number' && length > 0 && (length - 1) in obj;\n}\n\nfunction isString(str){\n return typeof str === 'string';\n}\n\nfunction isEmptyString(str) {\n return utilities.isString(str) && str.length === 0;\n}\n\nfunction isNotEmptyString(str) {\n return utilities.isString(str) && str.length !== 0;\n}\n\nfunction arrayLikeObjToArray(args) {\n return Array.prototype.slice.call(args);\n}\n\nfunction forEach(obj, iterator, context) {\n var key, length;\n if (obj) {\n if (isFunction(obj)) {\n for (key in obj) {\n // Need to check if hasOwnProperty exists,\n // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function\n if (key !== 'prototype' && key !== 'length' && key !== 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n } else if (isArray(obj)) {\n var isPrimitive = typeof obj !== 'object';\n for (key = 0, length = obj.length; key < length; key++) {\n if (isPrimitive || key in obj) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n } else if (obj.forEach && obj.forEach !== forEach) {\n obj.forEach(iterator, context, obj);\n } else {\n for (key in obj) {\n if (obj.hasOwnProperty(key)) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n }\n }\n return obj;\n}\n\nfunction snake_case(name, separator) {\n separator = separator || '_';\n return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {\n return (pos ? separator : '') + letter.toLowerCase();\n });\n}\n\nfunction isValidEmail(email){\n if(!utilities.isString(email)){\n return false;\n }\n\n return EMAIL_REGEXP.test(email.trim());\n}\n\nfunction extend (obj) {\n var arg, i, k;\n for (i = 1; i < arguments.length; i++) {\n arg = arguments[i];\n for (k in arg) {\n if (arg.hasOwnProperty(k)) {\n if(isObject(obj[k]) && !isNull(obj[k]) && isObject(arg[k])){\n obj[k] = extend({}, obj[k], arg[k]);\n }else {\n obj[k] = arg[k];\n }\n }\n }\n }\n return obj;\n}\n\nfunction capitalize(s){\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nfunction decapitalize(s) {\n return s.charAt(0).toLowerCase() + s.slice(1);\n}\n\n/**\n * This method works the same way array.prototype.map works but if the transformer returns undefine, then\n * it won't be added to the transformed Array.\n */\nfunction transformArray(array, transformer) {\n var transformedArray = [];\n\n array.forEach(function(item, index){\n var transformedItem = transformer(item, index);\n if(utilities.isDefined(transformedItem)) {\n transformedArray.push(transformedItem);\n }\n });\n\n return transformedArray;\n}\n\nfunction toFixedDigits(num, digits) {\n var formattedNum = num + '';\n digits = utilities.isNumber(digits) ? digits : 0;\n num = utilities.isNumber(num) ? num : parseInt(num, 10);\n if(utilities.isNumber(num) && !isNaN(num)){\n formattedNum = num + '';\n while(formattedNum.length < digits) {\n formattedNum = '0' + formattedNum;\n }\n return formattedNum;\n }\n return NaN + '';\n}\n\nfunction throttle(callback, delay) {\n var previousCall = new Date().getTime() - (delay + 1);\n return function() {\n var time = new Date().getTime();\n if ((time - previousCall) >= delay) {\n previousCall = time;\n callback.apply(this, arguments);\n }\n };\n}\n\nfunction debounce (callback, wait) {\n var timeoutId;\n\n return function (){\n if(timeoutId) {\n clearTimeout(timeoutId);\n }\n timeoutId = setTimeout(function(){\n callback.apply(this, arguments);\n timeoutId = undefined;\n }, wait);\n };\n}\n\n// a function designed to blow up the stack in a naive way\n// but it is ok for videoJs children components\nfunction treeSearch(root, getChildren, found){\n var children = getChildren(root);\n for (var i = 0; i < children.length; i++){\n if (found(children[i])) {\n return children[i];\n }\n else {\n var el = treeSearch(children[i], getChildren, found);\n if (el){\n return el;\n }\n }\n }\n}\n\nfunction echoFn(val) {\n return function () {\n return val;\n };\n}\n\n//Note: Supported formats come from http://www.w3.org/TR/NOTE-datetime\n// and the iso8601 regex comes from http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/\nfunction isISO8601(value) {\n if(utilities.isNumber(value)){\n value = value + ''; //we make sure that we are working with strings\n }\n\n if(!utilities.isString(value)){\n return false;\n }\n\n return ISO8086_REGEXP.test(value.trim());\n}\n\n/**\n * Checks if the Browser is IE9 and below\n * @returns {boolean}\n */\nfunction isOldIE() {\n var version = utilities.getInternetExplorerVersion(navigator);\n if (version === -1) {\n return false;\n }\n\n return version < 10;\n}\n\n/**\n * Returns the version of Internet Explorer or a -1 (indicating the use of another browser).\n * Source: https://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx\n * @returns {number} the version of Internet Explorer or a -1 (indicating the use of another browser).\n */\nfunction getInternetExplorerVersion(navigator) {\n var rv = -1;\n\n if (navigator.appName == 'Microsoft Internet Explorer') {\n var ua = navigator.userAgent;\n var re = new RegExp(\"MSIE ([0-9]{1,}[\\.0-9]{0,})\");\n var res = re.exec(ua);\n if (res !== null) {\n rv = parseFloat(res[1]);\n }\n }\n\n return rv;\n}\n\n/*** Mobile Utility functions ***/\nfunction isIDevice() {\n return /iP(hone|ad)/.test(utilities._UA);\n}\n\nfunction isMobile() {\n return /iP(hone|ad|od)|Android|Windows Phone/.test(utilities._UA);\n}\n\nfunction isIPhone() {\n return /iP(hone|od)/.test(utilities._UA);\n}\n\nfunction isAndroid() {\n return /Android/.test(utilities._UA);\n}\n\nvar utilities = {\n _UA: navigator.userAgent,\n noop: noop,\n isNull: isNull,\n isDefined: isDefined,\n isUndefined: isUndefined,\n isObject: isObject,\n isFunction: isFunction,\n isNumber: isNumber,\n isWindow: isWindow,\n isArray: isArray,\n isArrayLike: isArrayLike,\n isString: isString,\n isEmptyString: isEmptyString,\n isNotEmptyString: isNotEmptyString,\n arrayLikeObjToArray: arrayLikeObjToArray,\n forEach: forEach,\n snake_case: snake_case,\n isValidEmail: isValidEmail,\n extend: extend,\n capitalize: capitalize,\n decapitalize: decapitalize,\n transformArray: transformArray,\n toFixedDigits: toFixedDigits,\n throttle: throttle,\n debounce: debounce,\n treeSearch: treeSearch,\n echoFn: echoFn,\n isISO8601: isISO8601,\n isOldIE: isOldIE,\n getInternetExplorerVersion: getInternetExplorerVersion,\n isIDevice: isIDevice,\n isMobile: isMobile,\n isIPhone: isIPhone,\n isAndroid: isAndroid\n};\n\nmodule.exports = utilities;","'use strict';\n\nvar utilities = require('./utilityFunctions');\n\nvar xml = {};\n\nxml.strToXMLDoc = function strToXMLDoc(stringContainingXMLSource){\n //IE 8\n if(typeof window.DOMParser === 'undefined'){\n var xmlDocument = new ActiveXObject('Microsoft.XMLDOM');\n xmlDocument.async = false;\n xmlDocument.loadXML(stringContainingXMLSource);\n return xmlDocument;\n }\n\n return parseString(stringContainingXMLSource);\n\n function parseString(stringContainingXMLSource){\n var parser = new DOMParser();\n var parsedDocument;\n\n //Note: This try catch is to deal with the fact that on IE parser.parseFromString does throw an error but the rest of the browsers don't.\n try {\n parsedDocument = parser.parseFromString(stringContainingXMLSource, \"application/xml\");\n\n if(isParseError(parsedDocument) || utilities.isEmptyString(stringContainingXMLSource)){\n throw new Error();\n }\n }catch(e){\n throw new Error(\"xml.strToXMLDOC: Error parsing the string: '\" + stringContainingXMLSource + \"'\");\n }\n\n return parsedDocument;\n }\n\n function isParseError(parsedDocument) {\n try { // parser and parsererrorNS could be cached on startup for efficiency\n var parser = new DOMParser(),\n erroneousParse = parser.parseFromString('INVALID', 'text/xml'),\n parsererrorNS = erroneousParse.getElementsByTagName(\"parsererror\")[0].namespaceURI;\n\n if (parsererrorNS === 'http://www.w3.org/1999/xhtml') {\n // In PhantomJS the parseerror element doesn't seem to have a special namespace, so we are just guessing here :(\n return parsedDocument.getElementsByTagName(\"parsererror\").length > 0;\n }\n\n return parsedDocument.getElementsByTagNameNS(parsererrorNS, 'parsererror').length > 0;\n } catch (e) {\n //Note on IE parseString throws an error by itself and it will never reach this code. Because it will have failed before\n }\n }\n};\n\nxml.parseText = function parseText (sValue) {\n if (/^\\s*$/.test(sValue)) { return null; }\n if (/^(?:true|false)$/i.test(sValue)) { return sValue.toLowerCase() === \"true\"; }\n if (isFinite(sValue)) { return parseFloat(sValue); }\n if (utilities.isISO8601(sValue)) { return new Date(sValue); }\n return sValue.trim();\n};\n\nxml.JXONTree = function JXONTree (oXMLParent) {\n var parseText = xml.parseText;\n\n //The document object is an especial object that it may miss some functions or attrs depending on the browser.\n //To prevent this problem with create the JXONTree using the root childNode which is a fully fleshed node on all supported\n //browsers.\n if(oXMLParent.documentElement){\n return new xml.JXONTree(oXMLParent.documentElement);\n }\n\n if (oXMLParent.hasChildNodes()) {\n var sCollectedTxt = \"\";\n for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {\n oNode = oXMLParent.childNodes.item(nItem);\n /*jshint bitwise: false*/\n if ((oNode.nodeType - 1 | 1) === 3) { sCollectedTxt += oNode.nodeType === 3 ? oNode.nodeValue.trim() : oNode.nodeValue; }\n else if (oNode.nodeType === 1 && !oNode.prefix) {\n sProp = utilities.decapitalize(oNode.nodeName);\n vContent = new xml.JXONTree(oNode);\n if (this.hasOwnProperty(sProp)) {\n if (this[sProp].constructor !== Array) { this[sProp] = [this[sProp]]; }\n this[sProp].push(vContent);\n } else { this[sProp] = vContent; }\n }\n }\n if (sCollectedTxt) { this.keyValue = parseText(sCollectedTxt); }\n }\n\n //IE8 Stupid fix\n var hasAttr = typeof oXMLParent.hasAttributes === 'undefined'? oXMLParent.attributes.length > 0: oXMLParent.hasAttributes();\n if (hasAttr) {\n var oAttrib;\n for (var nAttrib = 0; nAttrib < oXMLParent.attributes.length; nAttrib++) {\n oAttrib = oXMLParent.attributes.item(nAttrib);\n this[\"@\" + utilities.decapitalize(oAttrib.name)] = parseText(oAttrib.value.trim());\n }\n }\n};\n\nxml.JXONTree.prototype.attr = function(attr) {\n return this['@' + utilities.decapitalize(attr)];\n};\n\nxml.toJXONTree = function toJXONTree(xmlString){\n var xmlDoc = xml.strToXMLDoc(xmlString);\n return new xml.JXONTree(xmlDoc);\n};\n\n/**\n * Helper function to extract the keyvalue of a JXONTree obj\n *\n * @param xmlObj {JXONTree}\n * return the key value or undefined;\n */\nxml.keyValue = function getKeyValue(xmlObj) {\n if(xmlObj){\n return xmlObj.keyValue;\n }\n return undefined;\n};\n\nxml.attr = function getAttrValue(xmlObj, attr) {\n if(xmlObj) {\n return xmlObj['@' + utilities.decapitalize(attr)];\n }\n return undefined;\n};\n\nxml.encode = function encodeXML(str) {\n return str.replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n};\n\nxml.decode = function decodeXML(str) {\n return str.replace(/'/g, \"'\")\n .replace(/"/g, '\"')\n .replace(/>/g, '>')\n .replace(/</g, '<')\n .replace(/&/g, '&');\n};\n\nmodule.exports = xml;","'use strict';\n\nrequire('./plugin/components/ads-label_5');\nrequire('./plugin/components/black-poster_5');\n\nvar videoJsVAST = require('./plugin/videojs.vast.vpaid');\n\nvideojs.plugin('vastClient', videoJsVAST);\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["node_modules/browser-pack/_prelude.js","bower_components/VPAIDFLASHClient/js/IVPAIDAdUnit.js","videojs_5.vast.vpaid.js","bower_components/VPAIDFLASHClient/js/VPAIDAdUnit.js","bower_components/VPAIDFLASHClient/js/VPAIDFLASHClient.js","bower_components/VPAIDFLASHClient/js/jsFlashBridge.js","bower_components/VPAIDFLASHClient/js/jsFlashBridgeRegistry.js","bower_components/VPAIDFLASHClient/js/registry.js","bower_components/VPAIDFLASHClient/js/utils.js","bower_components/VPAIDHTML5Client/js/IVPAIDAdUnit.js","bower_components/VPAIDHTML5Client/js/VPAIDAdUnit.js","bower_components/VPAIDHTML5Client/js/VPAIDHTML5Client.js","bower_components/VPAIDHTML5Client/js/subscriber.js","bower_components/VPAIDHTML5Client/js/utils.js","src/scripts/ads/vast/Ad.js","src/scripts/ads/vast/Companion.js","src/scripts/ads/vast/Creative.js","src/scripts/ads/vast/InLine.js","src/scripts/ads/vast/Linear.js","src/scripts/ads/vast/MediaFile.js","src/scripts/ads/vast/TrackingEvent.js","src/scripts/ads/vast/VASTClient.js","src/scripts/ads/vast/VASTError.js","src/scripts/ads/vast/VASTIntegrator.js","src/scripts/ads/vast/VASTResponse.js","src/scripts/ads/vast/VASTTracker.js","src/scripts/ads/vast/VideoClicks.js","src/scripts/ads/vast/Wrapper.js","src/scripts/ads/vast/parsers.js","src/scripts/ads/vast/vastUtil.js","src/scripts/ads/vpaid/VPAIDAdUnitWrapper.js","src/scripts/ads/vpaid/VPAIDFlashTech.js","src/scripts/ads/vpaid/VPAIDHTML5Tech.js","src/scripts/ads/vpaid/VPAIDIntegrator.js","src/scripts/plugin/components/ads-label.js","src/scripts/plugin/components/ads-label_5.js","src/scripts/plugin/components/black-poster.js","src/scripts/plugin/components/black-poster_5.js","src/scripts/plugin/videojs.vast.vpaid.js","src/scripts/utils/async.js","src/scripts/utils/dom.js","src/scripts/utils/http.js","src/scripts/utils/playerUtils.js","src/scripts/utils/urlUtils.js","src/scripts/utils/utilityFunctions.js","src/scripts/utils/xml.js","src/scripts/videojs_5.vast.vpaid.js"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length",1,"module","_createClass","defineProperties","target","props","descriptor","enumerable","configurable","writable","Object","defineProperty","key","Constructor","protoProps","staticProps","prototype","value","_classCallCheck","instance","TypeError","IVPAIDAdUnit","this","handshakeVersion","playerVPAIDVersion","arguments","undefined","callback","initAd","width","height","viewMode","desiredBitrate","creativeData","AdParameters","environmentVars","flashVars","resizeAd","startAd","stopAd","pauseAd","resumeAd","expandAd","collapseAd","skipAd","getAdLinear","getAdWidth","getAdHeight","getAdExpanded","getAdSkippableState","getAdRemainingTime","getAdDuration","setAdVolume","soundVolume","getAdVolume","getAdCompanions","getAdIcons",2,"_possibleConstructorReturn","self","ReferenceError","_inherits","subClass","superClass","create","constructor","setPrototypeOf","__proto__","ALL_VPAID_METHODS","getOwnPropertyNames","filter","property","indexOf","VPAIDAdUnit","_IVPAIDAdUnit","flash","_this","getPrototypeOf","_destroyed","_flash","_destroy","_this2","forEach","methodName","removeCallbackByMethodName","EVENTS","event","offEvent","isDestroyed","on","eventName","off","callFlashMethod","setSize","getWidth","getHeight","volume","./IVPAIDAdUnit",3,"JSFlashBridge","noop","callbackTimeout","isPositiveInt","createElementWithID","uniqueVPAID","unique","ERROR","FLASH_VERSION","VPAIDFLASHClient","vpaidParentEl","swfConfig","data","params","wmode","salign","align","allowScriptAccess","scale","allowFullScreen","quality","vpaidOptions","debug","timeout","hasExternalDependencies","onError","_vpaidParentEl","_flashID","movie","FlashVars","VPAID_FLASH_HANDLER","isSupported","el","swfobject","createSWF","handler","err","$loadPendedAdUnit","error","setTimeout","destroy","_destroyAdUnit","_loadLater","_adUnitLoad","removeCallback","_adUnit","loadAdUnit","adURL","$throwIfDestroyed","isReady","message","url","unloadAdUnit","getFlashID","getFlashURL","setStaticProperty","hasFlashPlayerVersion","window","propertyName","./VPAIDAdUnit","./jsFlashBridge","./utils",4,"stringEndsWith","SingleValueRegistry","MultipleValuesRegistry","registry","flashURL","flashID","loadHandShake","_el","_flashURL","_width","_height","_handlers","_callbacks","_uniqueMethodIdentifier","_ready","_handShakeHandler","addInstance","add","remove","removeByKey","offAll","removeAll","args","callbackID","concat","$asyncCallback","_trigger","removeByValue","suffix","filterKeys","removeAllCallbacks","get","_callCallback","result","trigger","_handShake","getSize","newWidth","newHeight","setAttribute","setWidth","setHeight","removeInstanceByID","parentElement","removeChild","_this3","typeID","typeName","getInstanceByID","./jsFlashBridgeRegistry","./registry",5,"instances","JSFlashBridgeRegistry","id",6,"_registries","push","keys","findByValue","index","splice","old","map","size","_this4",7,"prefix","count","timer","onSuccess","onTimeout","clearTimeout","apply","parent","nEl","document","createElement","innerHTML","appendChild","newVal","oldVal","isNaN","parseFloat","isFinite","endsWith","String","searchString","position","subjectString","toString","lastIndex","string","search",8,"METHODS","GETTERS","SETTERS","creative","video","VPAIDVersion","subscribe","context","unsubscribe","addStaticToInterface","VPAID1_METHODS","method","checkVPAIDInterface","every","Interface","name",9,"Subscriber","utils","AD_CLICK","FILTERED_EVENTS","VPAIDCreative","iframe","_isValid","_creative","_videoEl","_iframe","_subscribers","$addEventsSubscribers","isValidVPAIDAd","ignores","ariaty","Array","slice","pop","callOrTriggerEvent","bind","extend","slot","videoSlot","getter","validate","unsubscribeAll","$trigger","$clickThruHook","documentElement","contentDocument","videoEl","addEventListener","click","playerHandles","triggerSync","subscribers","./subscriber",10,"defaultTemplate","AD_STOPPED","VPAIDHTML5Client","templateConfig","_id","_frameContainer","createElementInEl","_vpaidOptions","_templateConfig","template","extraOptions","$unloadPreviousAdUnit","frame","createIframeWithContent","iframeURL_JS","iframeID","getID","_frame","_onLoad","onLoad","origin","location","JSON","parse","adUnit","createAd","contentWindow","getVPAIDAd","adEl","querySelector","$adDestroyed","$destroyLoadListener","$removeEl","$removeAdElements","$destroyAdUnit","removeEventListener","clearCallbackTimeout",11,"subscriber","that",12,"isValid","timeouts","func","tagName","createIframe","setIframeContent","simpleTemplate","src","marginWidth","marginHeight","frameBorder","style","left","top","margin","padding","border","stringify","replace","RegExp","iframeEl","content","iframeDoc","write","toExtend","fromSource",13,"InLine","Wrapper","Ad","adJTree","initialize","attr","sequence","inLine","wrapper","./InLine","./Wrapper",14,"TrackingEvent","utilities","xml","Companion","companionJTree","creativeType","staticResource","keyValue","htmlResource","HTMLResource","hTMLResource","iframeResource","IFrameResource","iFrameresource","expandedWidth","expandedHeight","scalable","maintainAspectRatio","minSuggestedDuration","apiFramework","companionClickThrough","trackingEvents","parseTrackingEvents","tracking","trackings","isDefined","isArray","trackingData","../../utils/utilityFunctions","../../utils/xml","./TrackingEvent",15,"Linear","Creative","creativeJTree","adId","linear","companionAds","companions","companion","companionData","./Companion","./Linear",16,"vastUtil","inlineJTree","adTitle","adSystem","impressions","parseImpressions","impression","creatives","parseCreatives","description","advertiser","surveys","parseSurveys","survey","pricing","extensions","inlineSurveys","transformArray","isNotEmptyString","uri","type","./vastUtil",17,"MediaFile","VideoClicks","parsers","linearJTree","duration","mediaFiles","parseMediaFiles","mediaFile","skipoffset","offset","videoClicks","adParameters","decode","mediaFilesJxonTree","mfData","./MediaFile","./VideoClicks","./parsers",18,"attributesList","mediaFileJTree","x","attribute",19,"trackingJTree",20,"VASTError","VASTResponse","async","http","VASTClient","options","defaultOptions","WRAPPER_LIMIT","settings","errorURLMacros","getVASTResponse","adTagUrl","sanityCheck","isFunction","waterfall","_getVASTAd","buildVASTResponse","adsChain","cb","response","_buildVASTResponse","getAdWaterfall","vastTree","waterfallAds","ads","_trackError","getAd","shift","waterfallHandler","adChain","requestVastXML","_requestVASTXml","buildVastWaterfall","xmlStr","toJXONTree","ad","validateVASTTree","vastVersion","next","isString","requestVASTAd","buildAd","VASTAdTagURI","adJxonTree","validateAd","errMsgPrefix","requestVASTXml","requestHandler","withCredentials","status","errMsg","addAdsToResponse","validateResponse","addAd","progressEvents","progress","hasLinear","progressEvent","isNumber","addErrorUrlMacros","track","ERRORCODE","../../utils/async","../../utils/http","./Ad","./VASTError","./VASTResponse",21,22,"VASTTracker","dom","playerUtils","VASTIntegrator","player","playAd","vastResponse","_selectAdSource","_createVASTTracker","_addClickThrough","_addSkipButton","_setupEvents","_playSelectedAd","_src","pause","play","isPaused","paused","getSrc","selectAdSource","source","playerWidth","getDimension","sort","compareTo","b","deltaA","Math","abs","deltaB","selectSource","createVASTTracker","adMediaFile","setupEvents","tracker","previouslyMuted","trackFullscreenChange","trackImpressions","trackPause","trackProgress","trackVolumeChange","once","unbindEvents","evt","trackComplete","isFullscreen","trackFullscreen","trackExitFullscreen","currentTime","trackResume","currentTimeInMs","trackCreativeView","muted","trackMute","trackUnmute","addSkipButton","skipOffsetInSec","addSkipButtonToPlayer","skipOffset","skipButton","createSkipButton","updateSkipButton","updateSkipButtonState","removeSkipButton","addClass","onclick","hasClass","trackSkip","Event","stopPropagation","timeLeft","ceil","toFixedDigits","addClickThrough","blocker","createClickThroughBlocker","updateBlocker","updateBlockerURL","insertBefore","controlBar","removeBlocker","clickThroughMacro","clickThrough","href","generateClickThroughURL","trackClick","variables","ASSETURI","CONTENTPLAYHEAD","formatProgress","parseURLMacro","playSelectedAd","preload","trackError","../../utils/dom","../../utils/playerUtils","./VASTTracker",23,"InLine__A","_linearAdded","clickTrackings","customClicks","_addInLine","_addWrapper","_addErrorTrackUrl","errorURL","JXONTree","_addImpressions","appendToArray","_addClickTrackings","_addCustomClicks","_addTrackingEvents","eventsMap","trackingEvent","_addTitle","title","_addDuration","_addVideoClicks","_addMediaFiles","_addSkipoffset","_addAdParameters","_addLinear","array","items","item",24,"assetURI","quartiles","firstQuartile","tracked","time","round","midpoint","thirdQuartile","isEmptyString","trackURLs","urls","trackEvent","trackOnce","getEventUris","uris","newProgressInMs","events","ONCE","ALWAYS","addTrackEvent","hasRewound","addQuartileEvents","trackProgressEvents","trackEvents","currentProgress","newProgress","REWIND_THRESHOLD","canBeAdded","trackQuartile","quartileName","quartile","canBeTracked","quartileTime","pendingProgressEvts","capitalize","trackErrorWithCode","errorcode",25,"videoClickJTree","parseClickTrackings","clickTracking","customClick","clickTrackingData",26,"wrapperJTree","vASTAdTagURI","followAdditionalWrappers","allowMultipleAds","fallbackOnNoAd",27,"durationRegex","parseDuration","durationStr","match","durationInMs","parseHoursToMs","parseMinToMs","parseSecToMs","parseInt","hourStr","minStr","secStr","parseOffset","isPercentage","calculatePercentage","percentageRegex","test","percentStr","calcPercent","quantity","percent",28,"URLMacros","sources","parseURLMacros","trackImgs","img","Image","parseMacros","parsedURLs","random","URLMacro","_parseURLMacro","parseMacro","creativesJTree","creativesData","hours","minutes","seconds","milliseconds","floor","isVPAID","isVPAIDMediaFile","./Creative",29,"VPAIDAdUnitWrapper","vpaidAdUnit","opts","isObject","responseTimeout","VPAIDInterfaceMethods","len","canSubscribeToEvents","canUnsubscribeFromEvents","adUnitAsyncCall","arrayLikeObjToArray","timeoutId","wrapCallback","evtName","waitForEvent","responseListener","unshift","version","adUnitData","getterName","../vast/VASTError",30,"VPAIDFlashTech","containerEl","vpaidFlashClient","supports","loadFlashCreative","objectEl","flashClientOpts","vpaidFlashLoaderPath","container","isDomElement","console","log","VPAIDFLASHClient/js/VPAIDFLASHClient",31,"VPAIDHTML5Tech","vpaidHTMLClient","INVALID_MEDIA_FILE","isOldIE","INVALID_DOM_CONTAINER_EL","toLowerCase","MISSING_CALLBACK","PREFIX","INVALID_DOM_VIDEO_EL","VPAIDHTML5Client/js/VPAIDHTML5Client",32,"VPAIDIntegrator","VIEW_MODE","NORMAL","FULLSCREEN","THUMBNAIL","createVPAIDContainerEl","VPAID_VERSION","techs","playVPaidAd","tech","_findSupportedTech","triggerVpaidAdEnd","one","removeAdUnit","_loadAdUnit","_playAdUnit","_finishPlaying","_paused","removeClass","vpaidMediaFiles","VPAIDTech","findSupportedTech","mediafile","_createVPAIDAdUnitWrapper","vjsTechEl","WrappedAdUnit","techClass","_handshake","_initAd","_linkPlayerControls","_startAd","handshake","isSupportedVersion","majorNum","major","parts","split","dimension","adUnitSrc","notifyPlayToPlayer","trackStart","notifyPauseToPlayer","trackFirstQuartile","trackMidpoint","trackThirdQuartile","clickThruUrl","open","trackAcceptInvitation","trackAcceptInvitationLinear","trackClose","trackCloseLinear","trackCollapse","lastVolume","currentVolume","updateViewSize","updateViewSizeThrottled","throttle","autoResize","pauseAdUnit","resumeAdUnit","isSkippable","linkVolumeControl","linkFullScreenControl","updateAdUnitVolume","updatePlayerVolume","vol","logError","finishPlayingAd","MODE","../vast/VASTResponse","../vast/VASTTracker","../vast/vastUtil","./VPAIDAdUnitWrapper","./VPAIDFlashTech","./VPAIDHTML5Tech",33,"element","className","AdsLabelFactory","baseComponent","init","currentTimeComp","getChild","getElement",34,"baseVideoJsComponent","videojs","getComponent","AdsLabel","registerComponent","./ads-label",35,"BlackPosterFactory","posterImg",36,"BlackPoster","./black-poster",37,"VASTPlugin","snapshot","vast","adsCanceled","defaultOpts","iosPrerollCancelTimeout","adCancelTimeout","playAdAlways","adsEnabled","isUndefined","echoFn","adTagXML","trackAdError","prepareForAds","tryToPlayPrerollAd","cancelAds","isEnabled","enable","disable","removeNativePoster","restoreVideoContent","checkAdsEnabled","preparePlayerForAd","startAdCancelTimeout","playPrerollAd","setupContentEvents","restorePlayerSnapshot","canPlayPrerollAd","getPlayerSnapshot","addSpinnerIcon","isIPhone","adCancelTimeoutId","clearAdCancelTimeout","removeSpinnerIcon","getVastResponse","adIntegrator","adFinished","addAdsLabel","removeAdsLabel","isIDevice","preventManualProgress","addChild","PROGRESS_THRESHOLD","previousTime","skipad_attempts","adTimeupdateHandler","stopPreventManualProgress","progressDelta","../ads/vast/VASTClient","../ads/vast/VASTError","../ads/vast/VASTIntegrator","../ads/vast/vastUtil","../ads/vpaid/VPAIDIntegrator","../utils/async","../utils/dom","../utils/playerUtils","../utils/utilityFunctions",38,"setImmediate","fn","iterator","tasks","makeCallback","wrapIterator","when","condition","isAllowed","./utilityFunctions",39,"isVisible","getComputedStyle","visibility","isHidden","display","isShown","hide","__prev_style_display_","show","cssClass","classes","classList","contains","getAttribute","join","newClasses","attachEvent","detachEvent","dispatchEvent","fireEvent","eventType","isDescendant","child","node","parentNode","getTextContent","textContent","text","prependChild","firstChild","removeNode","Element","handlerWrap","rect","getBoundingClientRect","offsetWidth","offsetHeight",40,"urlUtils","HttpRequestError","HttpRequest","createXhr","run","xhr","urlParts","headers","setHeaders","onload","statusText","getAllResponseHeaders","responseText","onerror","requestError","onabort","send","abort","setRequestHeader","processResponse","headersString","isSuccess","XMLHttpRequest","XDomainRequest","./urlUtils",41,"ended","currentSrc","currentType","playing","suppressedTracks","getSuppressedTracks","nativePoster","poster","tracks","remoteTextTracks","tracks_","mode","attempts","hasSrcChanged","restoreTracks","tryToResume","ensureCanplayEvtGetsFired","load","trackSnapshot","isReadyToResume","warn","readyState","seekable","blackPoster","_firstPlay","volumeSnapshot","monkeyPatchPlayerApi","tryToTriggerFirstPlay","resetFirstPlay","restoreContentVolume","hideBlackPoster","addStyles","removeStyles","origPlay","callOrigPlay","isFirstPlay","firstPlay","resume","saveVolumeSnapshot","isAdPlaying","origPause","callOrigPause","origPaused","callOrigPaused","restoreVolumeSnapshot","removeAttribute","listener","./dom",42,"urlParsingNode","msie","documentMode","protocol","host","hash","hostname","port","pathname","charAt","queryStringToObj","qs","cond","pairs","qsObj","trim","pair","objToQueryString","obj",43,"NODE_TYPE_ELEMENT","SNAKE_CASE_REGEXP","EMAIL_REGEXP","ISO8086_REGEXP","isNull","str","num","isWindow","isArrayLike","nodeType","hasOwnProperty","isPrimitive","snake_case","separator","letter","pos","isValidEmail","email","arg","k","toUpperCase","decapitalize","transformer","transformedArray","transformedItem","digits","formattedNum","NaN","delay","previousCall","Date","getTime","debounce","wait","treeSearch","root","getChildren","found","children","val","isISO8601","getInternetExplorerVersion","navigator","rv","appName","ua","userAgent","re","res","exec","_UA","isMobile","isAndroid",44,"strToXMLDoc","stringContainingXMLSource","DOMParser","xmlDocument","ActiveXObject","loadXML","parseString","parser","parsedDocument","parseFromString","isParseError","erroneousParse","parsererrorNS","getElementsByTagName","namespaceURI","getElementsByTagNameNS","parseText","sValue","oXMLParent","hasChildNodes","sCollectedTxt","oNode","sProp","vContent","nItem","childNodes","nodeValue","nodeName","hasAttr","hasAttributes","attributes","oAttrib","nAttrib","xmlString","xmlDoc","getKeyValue","xmlObj","getAttrValue","encode","encodeXML","decodeXML",45,"videoJsVAST","plugin","./plugin/components/ads-label_5","./plugin/components/black-poster_5","./plugin/videojs.vast.vpaid"],"mappings":"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","file":"videojs_5.vast.vpaid.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o 0) {\n callback(event);\n }\n }, 0);\n }\n });\n }\n }, {\n key: '_callCallback',\n value: function _callCallback(methodName, callbackID, err, result) {\n\n var callback = this._callbacks.get(callbackID);\n\n //not all methods callback's are mandatory\n //but if there exist an error, fire the error event\n if (!callback) {\n if (err && callbackID === '') {\n this.trigger(ERROR, err);\n }\n return;\n }\n\n $asyncCallback.call(this, callbackID, err, result);\n }\n }, {\n key: '_handShake',\n value: function _handShake(err, data) {\n this._ready = true;\n if (this._handShakeHandler) {\n this._handShakeHandler(err, data);\n delete this._handShakeHandler;\n }\n }\n\n //methods like properties specific to this implementation of VPAID\n\n }, {\n key: 'getSize',\n value: function getSize() {\n return { width: this._width, height: this._height };\n }\n }, {\n key: 'setSize',\n value: function setSize(newWidth, newHeight) {\n this._width = isPositiveInt(newWidth, this._width);\n this._height = isPositiveInt(newHeight, this._height);\n this._el.setAttribute('width', this._width);\n this._el.setAttribute('height', this._height);\n }\n }, {\n key: 'getWidth',\n value: function getWidth() {\n return this._width;\n }\n }, {\n key: 'setWidth',\n value: function setWidth(newWidth) {\n this.setSize(newWidth, this._height);\n }\n }, {\n key: 'getHeight',\n value: function getHeight() {\n return this._height;\n }\n }, {\n key: 'setHeight',\n value: function setHeight(newHeight) {\n this.setSize(this._width, newHeight);\n }\n }, {\n key: 'getFlashID',\n value: function getFlashID() {\n return this._flashID;\n }\n }, {\n key: 'getFlashURL',\n value: function getFlashURL() {\n return this._flashURL;\n }\n }, {\n key: 'isReady',\n value: function isReady() {\n return this._ready;\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.offAll();\n this.removeAllCallbacks();\n registry.removeInstanceByID(this._flashID);\n if (this._el.parentElement) {\n this._el.parentElement.removeChild(this._el);\n }\n }\n }]);\n\n return JSFlashBridge;\n}();\n\nfunction $asyncCallback(callbackID, err, result) {\n var _this3 = this;\n\n setTimeout(function () {\n var callback = _this3._callbacks.get(callbackID);\n if (callback) {\n _this3._callbacks.remove(callbackID);\n callback(err, result);\n }\n }, 0);\n}\n\nObject.defineProperty(JSFlashBridge, 'VPAID_FLASH_HANDLER', {\n writable: false,\n configurable: false,\n value: VPAID_FLASH_HANDLER\n});\n\n/**\n * External interface handler\n *\n * @param {string} flashID identifier of the flash who call this\n * @param {string} typeID what type of message is, can be 'event' or 'callback'\n * @param {string} typeName if the typeID is a event the typeName will be the eventName, if is a callback the typeID is the methodName that is related this callback\n * @param {string} callbackID only applies when the typeID is 'callback', identifier of the callback to call\n * @param {object} error error object\n * @param {object} data\n */\nwindow[VPAID_FLASH_HANDLER] = function (flashID, typeID, typeName, callbackID, error, data) {\n var instance = registry.getInstanceByID(flashID);\n if (!instance) return;\n if (typeName === 'handShake') {\n instance._handShake(error, data);\n } else {\n if (typeID !== 'event') {\n instance._callCallback(typeName, callbackID, error, data);\n } else {\n instance._trigger(typeName, data);\n }\n }\n};\n\n},{\"./jsFlashBridgeRegistry\":5,\"./registry\":6,\"./utils\":7}],5:[function(require,module,exports){\n'use strict';\n\nvar SingleValueRegistry = require('./registry').SingleValueRegistry;\nvar instances = new SingleValueRegistry();\n\nvar JSFlashBridgeRegistry = {};\nObject.defineProperty(JSFlashBridgeRegistry, 'addInstance', {\n writable: false,\n configurable: false,\n value: function value(id, instance) {\n instances.add(id, instance);\n }\n});\n\nObject.defineProperty(JSFlashBridgeRegistry, 'getInstanceByID', {\n writable: false,\n configurable: false,\n value: function value(id) {\n return instances.get(id);\n }\n});\n\nObject.defineProperty(JSFlashBridgeRegistry, 'removeInstanceByID', {\n writable: false,\n configurable: false,\n value: function value(id) {\n return instances.remove(id);\n }\n});\n\nmodule.exports = JSFlashBridgeRegistry;\n\n},{\"./registry\":6}],6:[function(require,module,exports){\n'use strict';\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar MultipleValuesRegistry = exports.MultipleValuesRegistry = function () {\n function MultipleValuesRegistry() {\n _classCallCheck(this, MultipleValuesRegistry);\n\n this._registries = {};\n }\n\n _createClass(MultipleValuesRegistry, [{\n key: 'add',\n value: function add(id, value) {\n if (!this._registries[id]) {\n this._registries[id] = [];\n }\n if (this._registries[id].indexOf(value) === -1) {\n this._registries[id].push(value);\n }\n }\n }, {\n key: 'get',\n value: function get(id) {\n return this._registries[id] || [];\n }\n }, {\n key: 'filterKeys',\n value: function filterKeys(handler) {\n return Object.keys(this._registries).filter(handler);\n }\n }, {\n key: 'findByValue',\n value: function findByValue(value) {\n var _this = this;\n\n var keys = Object.keys(this._registries).filter(function (key) {\n return _this._registries[key].indexOf(value) !== -1;\n });\n\n return keys;\n }\n }, {\n key: 'remove',\n value: function remove(key, value) {\n if (!this._registries[key]) {\n return;\n }\n\n var index = this._registries[key].indexOf(value);\n\n if (index < 0) {\n return;\n }\n return this._registries[key].splice(index, 1);\n }\n }, {\n key: 'removeByKey',\n value: function removeByKey(id) {\n var old = this._registries[id];\n delete this._registries[id];\n return old;\n }\n }, {\n key: 'removeByValue',\n value: function removeByValue(value) {\n var _this2 = this;\n\n var keys = this.findByValue(value);\n return keys.map(function (key) {\n return _this2.remove(key, value);\n });\n }\n }, {\n key: 'removeAll',\n value: function removeAll() {\n var old = this._registries;\n this._registries = {};\n return old;\n }\n }, {\n key: 'size',\n value: function size() {\n return Object.keys(this._registries).length;\n }\n }]);\n\n return MultipleValuesRegistry;\n}();\n\nvar SingleValueRegistry = exports.SingleValueRegistry = function () {\n function SingleValueRegistry() {\n _classCallCheck(this, SingleValueRegistry);\n\n this._registries = {};\n }\n\n _createClass(SingleValueRegistry, [{\n key: 'add',\n value: function add(id, value) {\n this._registries[id] = value;\n }\n }, {\n key: 'get',\n value: function get(id) {\n return this._registries[id];\n }\n }, {\n key: 'filterKeys',\n value: function filterKeys(handler) {\n return Object.keys(this._registries).filter(handler);\n }\n }, {\n key: 'findByValue',\n value: function findByValue(value) {\n var _this3 = this;\n\n var keys = Object.keys(this._registries).filter(function (key) {\n return _this3._registries[key] === value;\n });\n\n return keys;\n }\n }, {\n key: 'remove',\n value: function remove(id) {\n var old = this._registries[id];\n delete this._registries[id];\n return old;\n }\n }, {\n key: 'removeByValue',\n value: function removeByValue(value) {\n var _this4 = this;\n\n var keys = this.findByValue(value);\n return keys.map(function (key) {\n return _this4.remove(key);\n });\n }\n }, {\n key: 'removeAll',\n value: function removeAll() {\n var old = this._registries;\n this._registries = {};\n return old;\n }\n }, {\n key: 'size',\n value: function size() {\n return Object.keys(this._registries).length;\n }\n }]);\n\n return SingleValueRegistry;\n}();\n\n},{}],7:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.unique = unique;\nexports.noop = noop;\nexports.callbackTimeout = callbackTimeout;\nexports.createElementWithID = createElementWithID;\nexports.isPositiveInt = isPositiveInt;\nexports.stringEndsWith = stringEndsWith;\nfunction unique(prefix) {\n var count = -1;\n return function (f) {\n return prefix + '_' + ++count;\n };\n}\n\nfunction noop() {}\n\nfunction callbackTimeout(timer, onSuccess, onTimeout) {\n\n var timeout = setTimeout(function () {\n\n onSuccess = noop;\n onTimeout();\n }, timer);\n\n return function () {\n clearTimeout(timeout);\n onSuccess.apply(this, arguments);\n };\n}\n\nfunction createElementWithID(parent, id) {\n var nEl = document.createElement('div');\n nEl.id = id;\n parent.innerHTML = '';\n parent.appendChild(nEl);\n return nEl;\n}\n\nfunction isPositiveInt(newVal, oldVal) {\n return !isNaN(parseFloat(newVal)) && isFinite(newVal) && newVal > 0 ? newVal : oldVal;\n}\n\nvar endsWith = function () {\n if (String.prototype.endsWith) return String.prototype.endsWith;\n return function endsWith(searchString, position) {\n var subjectString = this.toString();\n if (position === undefined || position > subjectString.length) {\n position = subjectString.length;\n }\n position -= searchString.length;\n var lastIndex = subjectString.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n };\n}();\n\nfunction stringEndsWith(string, search) {\n return endsWith.call(string, search);\n}\n\n},{}],8:[function(require,module,exports){\n'use strict';\n\nvar METHODS = [\n 'handshakeVersion',\n 'initAd',\n 'startAd',\n 'stopAd',\n 'skipAd', // VPAID 2.0 new method\n 'resizeAd',\n 'pauseAd',\n 'resumeAd',\n 'expandAd',\n 'collapseAd',\n 'subscribe',\n 'unsubscribe'\n];\n\nvar EVENTS = [\n 'AdLoaded',\n 'AdStarted',\n 'AdStopped',\n 'AdSkipped',\n 'AdSkippableStateChange', // VPAID 2.0 new event\n 'AdSizeChange', // VPAID 2.0 new event\n 'AdLinearChange',\n 'AdDurationChange', // VPAID 2.0 new event\n 'AdExpandedChange',\n 'AdRemainingTimeChange', // [Deprecated in 2.0] but will be still fired for backwards compatibility\n 'AdVolumeChange',\n 'AdImpression',\n 'AdVideoStart',\n 'AdVideoFirstQuartile',\n 'AdVideoMidpoint',\n 'AdVideoThirdQuartile',\n 'AdVideoComplete',\n 'AdClickThru',\n 'AdInteraction', // VPAID 2.0 new event\n 'AdUserAcceptInvitation',\n 'AdUserMinimize',\n 'AdUserClose',\n 'AdPaused',\n 'AdPlaying',\n 'AdLog',\n 'AdError'\n];\n\nvar GETTERS = [\n 'getAdLinear',\n 'getAdWidth', // VPAID 2.0 new getter\n 'getAdHeight', // VPAID 2.0 new getter\n 'getAdExpanded',\n 'getAdSkippableState', // VPAID 2.0 new getter\n 'getAdRemainingTime',\n 'getAdDuration', // VPAID 2.0 new getter\n 'getAdVolume',\n 'getAdCompanions', // VPAID 2.0 new getter\n 'getAdIcons' // VPAID 2.0 new getter\n];\n\nvar SETTERS = [\n 'setAdVolume'\n];\n\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n\n/**\n * IVPAIDAdUnit\n *\n * @class\n *\n * @param {object} creative\n * @param {HTMLElement} el\n * @param {HTMLVideoElement} video\n */\nfunction IVPAIDAdUnit(creative, el, video) {}\n\n\n/**\n * handshakeVersion\n *\n * @param {string} VPAIDVersion\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.handshakeVersion = function (VPAIDVersion, callback) {};\n\n/**\n * initAd\n *\n * @param {number} width\n * @param {number} height\n * @param {string} viewMode can be 'normal', 'thumbnail' or 'fullscreen'\n * @param {number} desiredBitrate indicates the desired bitrate in kbps\n * @param {object} [creativeData] used for additional initialization data\n * @param {object} [environmentVars] used for passing implementation-specific of js version\n * @param {NodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.initAd = function(width, height, viewMode, desiredBitrate, creativeData, environmentVars, callback) {};\n\n/**\n * startAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.startAd = function(callback) {};\n\n/**\n * stopAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.stopAd = function(callback) {};\n\n/**\n * skipAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.skipAd = function(callback) {};\n\n/**\n * resizeAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.resizeAd = function(width, height, viewMode, callback) {};\n\n/**\n * pauseAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.pauseAd = function(callback) {};\n\n/**\n * resumeAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.resumeAd = function(callback) {};\n\n/**\n * expandAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.expandAd = function(callback) {};\n\n/**\n * collapseAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.collapseAd = function(callback) {};\n\n/**\n * subscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n * @param {object} context\n */\nIVPAIDAdUnit.prototype.subscribe = function(event, handler, context) {};\n\n/**\n * startAd\n *\n * @param {string} event\n * @param {function} handler\n */\nIVPAIDAdUnit.prototype.unsubscribe = function(event, handler) {};\n\n\n\n/**\n * getAdLinear\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdLinear = function(callback) {};\n\n/**\n * getAdWidth\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdWidth = function(callback) {};\n\n/**\n * getAdHeight\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdHeight = function(callback) {};\n\n/**\n * getAdExpanded\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdExpanded = function(callback) {};\n\n/**\n * getAdSkippableState\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdSkippableState = function(callback) {};\n\n/**\n * getAdRemainingTime\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdRemainingTime = function(callback) {};\n\n/**\n * getAdDuration\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdDuration = function(callback) {};\n\n/**\n * getAdVolume\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdVolume = function(callback) {};\n\n/**\n * getAdCompanions\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdCompanions = function(callback) {};\n\n/**\n * getAdIcons\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdIcons = function(callback) {};\n\n/**\n * setAdVolume\n *\n * @param {number} volume\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.setAdVolume = function(volume, callback) {};\n\naddStaticToInterface(IVPAIDAdUnit, 'METHODS', METHODS);\naddStaticToInterface(IVPAIDAdUnit, 'GETTERS', GETTERS);\naddStaticToInterface(IVPAIDAdUnit, 'SETTERS', SETTERS);\naddStaticToInterface(IVPAIDAdUnit, 'EVENTS', EVENTS);\n\n\nvar VPAID1_METHODS = METHODS.filter(function(method) {\n return ['skipAd'].indexOf(method) === -1;\n});\n\naddStaticToInterface(IVPAIDAdUnit, 'checkVPAIDInterface', function checkVPAIDInterface (creative) {\n var result = VPAID1_METHODS.every(function(key) {\n return typeof creative[key] === 'function';\n });\n return result;\n});\n\nmodule.exports = IVPAIDAdUnit;\n\nfunction addStaticToInterface(Interface, name, value) {\n Object.defineProperty(Interface, name, {\n writable: false,\n configurable: false,\n value: value\n });\n}\n\n\n},{}],9:[function(require,module,exports){\n'use strict';\n\nvar IVPAIDAdUnit = require('./IVPAIDAdUnit');\nvar Subscriber = require('./subscriber');\nvar checkVPAIDInterface = IVPAIDAdUnit.checkVPAIDInterface;\nvar utils = require('./utils');\nvar METHODS = IVPAIDAdUnit.METHODS;\nvar ERROR = 'AdError';\nvar AD_CLICK = 'AdClickThru';\nvar FILTERED_EVENTS = IVPAIDAdUnit.EVENTS.filter(function (event) {\n return event != AD_CLICK;\n});\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n\n/**\n * VPAIDAdUnit\n * @class\n *\n * @param VPAIDCreative\n * @param {HTMLElement} [el] this will be used in initAd environmentVars.slot if defined\n * @param {HTMLVideoElement} [video] this will be used in initAd environmentVars.videoSlot if defined\n */\nfunction VPAIDAdUnit(VPAIDCreative, el, video, iframe) {\n this._isValid = checkVPAIDInterface(VPAIDCreative);\n if (this._isValid) {\n this._creative = VPAIDCreative;\n this._el = el;\n this._videoEl = video;\n this._iframe = iframe;\n this._subscribers = new Subscriber();\n $addEventsSubscribers.call(this);\n }\n}\n\nVPAIDAdUnit.prototype = Object.create(IVPAIDAdUnit.prototype);\n\n/**\n * isValidVPAIDAd will return if the VPAIDCreative passed in constructor is valid or not\n *\n * @return {boolean}\n */\nVPAIDAdUnit.prototype.isValidVPAIDAd = function isValidVPAIDAd() {\n return this._isValid;\n};\n\nIVPAIDAdUnit.METHODS.forEach(function(method) {\n //NOTE: this methods arguments order are implemented differently from the spec\n var ignores = [\n 'subscribe',\n 'unsubscribe',\n 'initAd'\n ];\n\n if (ignores.indexOf(method) !== -1) return;\n\n VPAIDAdUnit.prototype[method] = function () {\n var ariaty = IVPAIDAdUnit.prototype[method].length;\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n var args = Array.prototype.slice.call(arguments);\n var callback = (ariaty === args.length) ? args.pop() : undefined;\n\n setTimeout(function () {\n var result, error = null;\n try {\n result = this._creative[method].apply(this._creative, args);\n } catch(e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n };\n});\n\n\n/**\n * initAd concreate implementation\n *\n * @param {number} width\n * @param {number} height\n * @param {string} viewMode can be 'normal', 'thumbnail' or 'fullscreen'\n * @param {number} desiredBitrate indicates the desired bitrate in kbps\n * @param {object} [creativeData] used for additional initialization data\n * @param {object} [environmentVars] used for passing implementation-specific of js version, if el & video was used in constructor slot & videoSlot will be added to the object\n * @param {NodeStyleCallback} callback\n */\nVPAIDAdUnit.prototype.initAd = function initAd(width, height, viewMode, desiredBitrate, creativeData, environmentVars, callback) {\n creativeData = creativeData || {};\n environmentVars = utils.extend({\n slot: this._el,\n videoSlot: this._videoEl\n }, environmentVars || {});\n\n setTimeout(function () {\n var error;\n try {\n this._creative.initAd(width, height, viewMode, desiredBitrate, creativeData, environmentVars);\n } catch (e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error);\n }.bind(this), 0);\n};\n\n/**\n * subscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n * @param {object} context\n */\nVPAIDAdUnit.prototype.subscribe = function subscribe(event, handler, context) {\n this._subscribers.subscribe(handler, event, context);\n};\n\n\n/**\n * unsubscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n */\nVPAIDAdUnit.prototype.unsubscribe = function unsubscribe(event, handler) {\n this._subscribers.unsubscribe(handler, event);\n};\n\n//alias\nVPAIDAdUnit.prototype.on = VPAIDAdUnit.prototype.subscribe;\nVPAIDAdUnit.prototype.off = VPAIDAdUnit.prototype.unsubscribe;\n\nIVPAIDAdUnit.GETTERS.forEach(function(getter) {\n VPAIDAdUnit.prototype[getter] = function (callback) {\n setTimeout(function () {\n\n var result, error = null;\n try {\n result = this._creative[getter]();\n } catch(e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n };\n});\n\n/**\n * setAdVolume\n *\n * @param volume\n * @param {nodeStyleCallback} callback\n */\nVPAIDAdUnit.prototype.setAdVolume = function setAdVolume(volume, callback) {\n setTimeout(function () {\n\n var result, error = null;\n try {\n this._creative.setAdVolume(volume);\n result = this._creative.getAdVolume();\n } catch(e) {\n error = e;\n }\n\n if (!error) {\n error = utils.validate(result === volume, 'failed to apply volume: ' + volume);\n }\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n};\n\nVPAIDAdUnit.prototype._destroy = function destroy() {\n this.stopAd();\n this._subscribers.unsubscribeAll();\n};\n\nfunction $addEventsSubscribers() {\n // some ads implement\n // so they only handle one subscriber\n // to handle this we create our one\n FILTERED_EVENTS.forEach(function (event) {\n this._creative.subscribe($trigger.bind(this, event), event);\n }.bind(this));\n\n // map the click event to be an object instead of depending of the order of the arguments\n // and to be consistent with the flash\n this._creative.subscribe($clickThruHook.bind(this), AD_CLICK);\n\n // because we are adding the element inside the iframe\n // the user is not able to click in the video\n if (this._videoEl) {\n var documentElement = this._iframe.contentDocument.documentElement;\n var videoEl = this._videoEl;\n documentElement.addEventListener('click', function(e) {\n if (e.target === documentElement) {\n videoEl.click();\n }\n });\n }\n}\n\nfunction $clickThruHook(url, id, playerHandles) {\n this._subscribers.triggerSync(AD_CLICK, {url: url, id: id, playerHandles: playerHandles});\n}\n\nfunction $trigger(event) {\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n this._subscribers.trigger(event, Array.prototype.slice(arguments, 1));\n}\n\nfunction callOrTriggerEvent(callback, subscribers, error, result) {\n if (callback) {\n callback(error, result);\n } else if (error) {\n subscribers.trigger(ERROR, error);\n }\n}\n\nmodule.exports = VPAIDAdUnit;\n\n\n},{\"./IVPAIDAdUnit\":8,\"./subscriber\":11,\"./utils\":12}],10:[function(require,module,exports){\n'use strict';\n\nvar utils = require('./utils');\nvar unique = utils.unique('vpaidIframe');\nvar VPAIDAdUnit = require('./VPAIDAdUnit');\n\nvar defaultTemplate = '';\ndefaultTemplate += '
';\n\nvar AD_STOPPED = 'AdStopped';\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n/**\n * VPAIDHTML5Client\n * @class\n *\n * @param {HTMLElement} el that will contain the iframe to load adUnit and a el to add to adUnit slot\n * @param {HTMLVideoElement} video default video element to be used by adUnit\n * @param {object} [templateConfig] template: html template to be used instead of the default, extraOptions: to be used when rendering the template\n * @param {object} [vpaidOptions] timeout: when loading adUnit\n */\nfunction VPAIDHTML5Client(el, video, templateConfig, vpaidOptions) {\n templateConfig = templateConfig || {};\n\n this._id = unique();\n this._destroyed = false;\n\n this._frameContainer = utils.createElementInEl(el, 'div');\n this._videoEl = video;\n this._vpaidOptions = vpaidOptions || {timeout: 10000};\n\n this._templateConfig = {\n template: templateConfig.template || defaultTemplate,\n extraOptions: templateConfig.extraOptions || {}\n };\n\n}\n\n/**\n * destroy\n *\n */\nVPAIDHTML5Client.prototype.destroy = function destroy() {\n if (this._destroyed) {\n return;\n }\n this._destroyed = true;\n $unloadPreviousAdUnit.call(this);\n};\n\n/**\n * isDestroyed\n *\n * @return {boolean}\n */\nVPAIDHTML5Client.prototype.isDestroyed = function isDestroyed() {\n return this._destroyed;\n};\n\n/**\n * loadAdUnit\n *\n * @param {string} adURL url of the js of the adUnit\n * @param {nodeStyleCallback} callback\n */\nVPAIDHTML5Client.prototype.loadAdUnit = function loadAdUnit(adURL, callback) {\n $throwIfDestroyed.call(this);\n $unloadPreviousAdUnit.call(this);\n\n var frame = utils.createIframeWithContent(\n this._frameContainer,\n this._templateConfig.template,\n utils.extend({\n iframeURL_JS: adURL,\n iframeID: this.getID()\n }, this._templateConfig.extraOptions)\n );\n this._frame = frame;\n\n this._onLoad = utils.callbackTimeout(\n this._vpaidOptions.timeout,\n onLoad.bind(this),\n onTimeout.bind(this)\n );\n\n window.addEventListener('message', this._onLoad);\n\n function onLoad (e) {\n /*jshint validthis: false */\n //don't clear timeout\n if (e.origin !== window.location.origin) return;\n var result = JSON.parse(e.data);\n\n //don't clear timeout\n if (result.id !== this.getID()) return;\n\n var adUnit, error, createAd;\n if (!this._frame.contentWindow) {\n\n error = 'the iframe is not anymore in the DOM tree';\n\n } else {\n createAd = this._frame.contentWindow.getVPAIDAd;\n error = utils.validate(typeof createAd === 'function', 'the ad didn\\'t return a function to create an ad');\n }\n\n if (!error) {\n var adEl = this._frame.contentWindow.document.querySelector('.ad-element');\n adUnit = new VPAIDAdUnit(createAd(), adEl, this._videoEl, this._frame);\n adUnit.subscribe(AD_STOPPED, $adDestroyed.bind(this));\n error = utils.validate(adUnit.isValidVPAIDAd(), 'the add is not fully complaint with VPAID specification');\n }\n\n this._adUnit = adUnit;\n $destroyLoadListener.call(this);\n callback(error, error ? null : adUnit);\n\n //clear timeout\n return true;\n }\n\n function onTimeout() {\n callback('timeout', null);\n }\n};\n\n/**\n * unloadAdUnit\n *\n */\nVPAIDHTML5Client.prototype.unloadAdUnit = function unloadAdUnit() {\n $unloadPreviousAdUnit.call(this);\n};\n\n/**\n * getID will return the unique id\n *\n * @return {string}\n */\nVPAIDHTML5Client.prototype.getID = function () {\n return this._id;\n};\n\n\n/**\n * $removeEl\n *\n * @param {string} key\n */\nfunction $removeEl(key) {\n var el = this[key];\n if (el) {\n el.remove();\n delete this[key];\n }\n}\n\nfunction $adDestroyed() {\n $removeAdElements.call(this);\n delete this._adUnit;\n}\n\nfunction $unloadPreviousAdUnit() {\n $removeAdElements.call(this);\n $destroyAdUnit.call(this);\n}\n\nfunction $removeAdElements() {\n $removeEl.call(this, '_frame');\n $destroyLoadListener.call(this);\n}\n\n/**\n * $destroyLoadListener\n *\n */\nfunction $destroyLoadListener() {\n if (this._onLoad) {\n window.removeEventListener('message', this._onLoad);\n utils.clearCallbackTimeout(this._onLoad);\n delete this._onLoad;\n }\n}\n\n\nfunction $destroyAdUnit() {\n if (this._adUnit) {\n this._adUnit.stopAd();\n delete this._adUnit;\n }\n}\n\n/**\n * $throwIfDestroyed\n *\n */\nfunction $throwIfDestroyed() {\n if (this._destroyed) {\n throw new Error ('VPAIDHTML5Client already destroyed!');\n }\n}\n\nmodule.exports = VPAIDHTML5Client;\nwindow.VPAIDHTML5Client = VPAIDHTML5Client;\n\n\n},{\"./VPAIDAdUnit\":9,\"./utils\":12}],11:[function(require,module,exports){\n'use strict';\n\nfunction Subscriber() {\n this._subscribers = {};\n}\n\nSubscriber.prototype.subscribe = function subscribe(handler, eventName, context) {\n this.get(eventName).push({handler: handler, context: context});\n};\n\nSubscriber.prototype.unsubscribe = function unsubscribe(handler, eventName) {\n this._subscribers[eventName] = this.get(eventName).filter(function (subscriber) {\n return handler === subscriber.handler;\n });\n};\n\nSubscriber.prototype.unsubscribeAll = function unsubscribeAll() {\n this._subscribers = {};\n};\n\nSubscriber.prototype.trigger = function(eventName, data) {\n var that = this;\n that.get(eventName).forEach(function (subscriber) {\n setTimeout(function () {\n if (that.get(eventName)) {\n subscriber.handler.call(subscriber.context, data);\n }\n }, 0);\n });\n};\n\nSubscriber.prototype.triggerSync = function(eventName, data) {\n this.get(eventName).forEach(function (subscriber) {\n subscriber.handler.call(subscriber.context, data);\n });\n};\n\nSubscriber.prototype.get = function get(eventName) {\n if (!this._subscribers[eventName]) {\n this._subscribers[eventName] = [];\n }\n return this._subscribers[eventName];\n};\n\nmodule.exports = Subscriber;\n\n\n},{}],12:[function(require,module,exports){\n'use strict';\n\n/**\n * noop a empty function\n */\nfunction noop() {}\n\n/**\n * validate if is not validate will return an Error with the message\n *\n * @param {boolean} isValid\n * @param {string} message\n */\nfunction validate(isValid, message) {\n return isValid ? null : new Error(message);\n}\n\nvar timeouts = {};\n/**\n * clearCallbackTimeout\n *\n * @param {function} func handler to remove\n */\nfunction clearCallbackTimeout(func) {\n var timeout = timeouts[func];\n if (timeout) {\n clearTimeout(timeout);\n delete timeouts[func];\n }\n}\n\n/**\n * callbackTimeout if the onSuccess is not called and returns true in the timelimit then onTimeout will be called\n *\n * @param {number} timer\n * @param {function} onSuccess\n * @param {function} onTimeout\n */\nfunction callbackTimeout(timer, onSuccess, onTimeout) {\n var callback, timeout;\n\n timeout = setTimeout(function () {\n onSuccess = noop;\n delete timeout[callback];\n onTimeout();\n }, timer);\n\n callback = function () {\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n if (onSuccess.apply(this, arguments)) {\n clearCallbackTimeout(callback);\n }\n };\n\n timeouts[callback] = timeout;\n\n return callback;\n}\n\n\n/**\n * createElementInEl\n *\n * @param {HTMLElement} parent\n * @param {string} tagName\n * @param {string} id\n */\nfunction createElementInEl(parent, tagName, id) {\n var nEl = document.createElement(tagName);\n if (id) nEl.id = id;\n parent.appendChild(nEl);\n return nEl;\n}\n\n/**\n * createIframeWithContent\n *\n * @param {HTMLElement} parent\n * @param {string} template simple template using {{var}}\n * @param {object} data\n */\nfunction createIframeWithContent(parent, template, data) {\n var iframe = createIframe(parent);\n if (!setIframeContent(iframe, simpleTemplate(template, data))) return;\n return iframe;\n}\n\n/**\n * createIframe\n *\n * @param {HTMLElement} parent\n * @param {string} url\n */\nfunction createIframe(parent, url) {\n var nEl = document.createElement('iframe');\n nEl.src = url || 'about:blank';\n nEl.marginWidth = '0';\n nEl.marginHeight = '0';\n nEl.frameBorder = '0';\n nEl.width = '100%';\n nEl.height = '100%';\n nEl.style.position = 'absolute';\n nEl.style.left = '0';\n nEl.style.top = '0';\n nEl.style.margin = '0px';\n nEl.style.padding = '0px';\n nEl.style.border = 'none';\n nEl.setAttribute('SCROLLING','NO');\n parent.innerHTML = '';\n parent.appendChild(nEl);\n return nEl;\n}\n\n/**\n * simpleTemplate\n *\n * @param {string} template\n * @param {object} data\n */\nfunction simpleTemplate(template, data) {\n Object.keys(data).forEach(function (key) {\n var value = (typeof value === 'object') ? JSON.stringify(data[key]) : data[key];\n template = template.replace(new RegExp('{{' + key + '}}', 'g'), value);\n });\n return template;\n}\n\n/**\n * setIframeContent\n *\n * @param {HTMLIframeElement} iframeEl\n * @param content\n */\nfunction setIframeContent(iframeEl, content) {\n var iframeDoc = iframeEl.contentWindow && iframeEl.contentWindow.document;\n if (!iframeDoc) return false;\n\n iframeDoc.write(content);\n\n return true;\n}\n\n\n/**\n * extend object with keys from another object\n *\n * @param {object} toExtend\n * @param {object} fromSource\n */\nfunction extend(toExtend, fromSource) {\n Object.keys(fromSource).forEach(function(key) {\n toExtend[key] = fromSource[key];\n });\n return toExtend;\n}\n\n\n/**\n * unique will create a unique string everytime is called, sequentially and prefixed\n *\n * @param {string} prefix\n */\nfunction unique(prefix) {\n var count = -1;\n return function () {\n return prefix + '_' + (++count);\n };\n}\n\nmodule.exports = {\n noop: noop,\n validate: validate,\n clearCallbackTimeout: clearCallbackTimeout,\n callbackTimeout: callbackTimeout,\n createElementInEl: createElementInEl,\n createIframeWithContent: createIframeWithContent,\n createIframe: createIframe,\n simpleTemplate: simpleTemplate,\n setIframeContent: setIframeContent,\n extend: extend,\n unique: unique\n};\n\n\n},{}],13:[function(require,module,exports){\n'use strict';\n\nvar InLine = require('./InLine');\nvar Wrapper = require('./Wrapper');\n\nfunction Ad(adJTree) {\n if (!(this instanceof Ad)) {\n return new Ad(adJTree);\n }\n this.initialize(adJTree);\n}\n\nAd.prototype.initialize = function(adJTree) {\n this.id = adJTree.attr('id');\n this.sequence = adJTree.attr('sequence');\n\n if(adJTree.inLine) {\n this.inLine = new InLine(adJTree.inLine);\n }\n\n if(adJTree.wrapper){\n this.wrapper = new Wrapper(adJTree.wrapper);\n }\n};\n\nmodule.exports = Ad;\n},{\"./InLine\":16,\"./Wrapper\":26}],14:[function(require,module,exports){\n'use strict';\n\nvar TrackingEvent = require('./TrackingEvent');\n\nvar utilities = require('../../utils/utilityFunctions');\n\nvar xml = require('../../utils/xml');\n\n\nfunction Companion(companionJTree) {\n if (!(this instanceof Companion)) {\n return new Companion(companionJTree);\n }\n\n //Required Elements\n this.creativeType = xml.attr(companionJTree.staticResource, 'creativeType');\n this.staticResource = xml.keyValue(companionJTree.staticResource);\n\n // Weird bug when the JXON tree is built it doesn't handle casing properly in this situation...\n var htmlResource = null;\n if (xml.keyValue(companionJTree.HTMLResource)) {\n htmlResource = xml.keyValue(companionJTree.HTMLResource);\n } else if (xml.keyValue(companionJTree.hTMLResource)) {\n htmlResource = xml.keyValue(companionJTree.hTMLResource);\n }\n this.htmlResource = htmlResource;\n\n var iframeResource = null;\n if (xml.keyValue(companionJTree.IFrameResource)) {\n iframeResource = xml.keyValue(companionJTree.IFrameResource);\n } else if (xml.keyValue(companionJTree.iFrameresource)) {\n iframeResource = xml.keyValue(companionJTree.iFrameresource);\n }\n this.iframeResource = iframeResource;\n\n //Optional fields\n this.id = xml.attr(companionJTree, 'id');\n this.width = xml.attr(companionJTree, 'width');\n this.height = xml.attr(companionJTree, 'height');\n this.expandedWidth = xml.attr(companionJTree, 'expandedWidth');\n this.expandedHeight = xml.attr(companionJTree, 'expandedHeight');\n this.scalable = xml.attr(companionJTree, 'scalable');\n this.maintainAspectRatio = xml.attr(companionJTree, 'maintainAspectRatio');\n this.minSuggestedDuration = xml.attr(companionJTree, 'minSuggestedDuration');\n this.apiFramework = xml.attr(companionJTree, 'apiFramework');\n this.companionClickThrough = xml.keyValue(companionJTree.companionClickThrough);\n this.trackingEvents = parseTrackingEvents(companionJTree.trackingEvents && companionJTree.trackingEvents.tracking);\n\n /*** Local functions ***/\n function parseTrackingEvents(trackingEvents) {\n var trackings = [];\n if (utilities.isDefined(trackingEvents)) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingData) {\n trackings.push(new TrackingEvent(trackingData));\n });\n }\n return trackings;\n }\n}\n\nmodule.exports = Companion;\n},{\"../../utils/utilityFunctions\":43,\"../../utils/xml\":44,\"./TrackingEvent\":19}],15:[function(require,module,exports){\n'use strict';\n\nvar Linear = require('./Linear');\nvar Companion = require('./Companion');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction Creative(creativeJTree) {\n if(!(this instanceof Creative)) {\n return new Creative(creativeJTree);\n }\n\n this.id = creativeJTree.attr('id');\n this.sequence = creativeJTree.attr('sequence');\n this.adId = creativeJTree.attr('adId');\n this.apiFramework = creativeJTree.attr('apiFramework');\n\n if(creativeJTree.linear) {\n this.linear = new Linear(creativeJTree.linear);\n }\n\n if (creativeJTree.companionAds) {\n var companions = [];\n var companionAds = creativeJTree.companionAds && creativeJTree.companionAds.companion;\n companionAds = utilities.isArray(companionAds) ? companionAds : [companionAds];\n companionAds.forEach(function (companionData) {\n companions.push(new Companion(companionData));\n });\n\n this.companionAds = companions;\n }\n}\n\nmodule.exports = Creative;\n},{\"../../utils/utilityFunctions\":43,\"./Companion\":14,\"./Linear\":17}],16:[function(require,module,exports){\n'use strict';\n\nvar vastUtil = require('./vastUtil');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction InLine(inlineJTree) {\n if (!(this instanceof InLine)) {\n return new InLine(inlineJTree);\n }\n\n //Required Fields\n this.adTitle = xml.keyValue(inlineJTree.adTitle);\n this.adSystem = xml.keyValue(inlineJTree.adSystem);\n this.impressions = vastUtil.parseImpressions(inlineJTree.impression);\n this.creatives = vastUtil.parseCreatives(inlineJTree.creatives);\n\n //Optional Fields\n this.description = xml.keyValue(inlineJTree.description);\n this.advertiser = xml.keyValue(inlineJTree.advertiser);\n this.surveys = parseSurveys(inlineJTree.survey);\n this.error = xml.keyValue(inlineJTree.error);\n this.pricing = xml.keyValue(inlineJTree.pricing);\n this.extensions = inlineJTree.extensions;\n\n /*** Local Functions ***/\n function parseSurveys(inlineSurveys) {\n if (inlineSurveys) {\n return utilities.transformArray(utilities.isArray(inlineSurveys) ? inlineSurveys : [inlineSurveys], function (survey) {\n if(utilities.isNotEmptyString(survey.keyValue)){\n return {\n uri: survey.keyValue,\n type: survey.attr('type')\n };\n }\n\n return undefined;\n });\n }\n return [];\n }\n}\n\nmodule.exports = InLine;\n},{\"../../utils/utilityFunctions\":43,\"../../utils/xml\":44,\"./vastUtil\":28}],17:[function(require,module,exports){\n'use strict';\n\nvar TrackingEvent = require('./TrackingEvent');\nvar MediaFile = require('./MediaFile');\nvar VideoClicks = require('./VideoClicks');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar parsers = require('./parsers');\n\nvar xml = require('../../utils/xml');\n\n\nfunction Linear(linearJTree) {\n if (!(this instanceof Linear)) {\n return new Linear(linearJTree);\n }\n\n //Required Elements\n this.duration = parsers.duration(xml.keyValue(linearJTree.duration));\n this.mediaFiles = parseMediaFiles(linearJTree.mediaFiles && linearJTree.mediaFiles.mediaFile);\n\n //Optional fields\n this.trackingEvents = parseTrackingEvents(linearJTree.trackingEvents && linearJTree.trackingEvents.tracking, this.duration);\n this.skipoffset = parsers.offset(xml.attr(linearJTree, 'skipoffset'), this.duration);\n\n if (linearJTree.videoClicks) {\n this.videoClicks = new VideoClicks(linearJTree.videoClicks);\n }\n\n if(linearJTree.adParameters) {\n this.adParameters = xml.keyValue(linearJTree.adParameters);\n\n if(xml.attr(linearJTree.adParameters, 'xmlEncoded')){\n this.adParameters = xml.decode(this.adParameters);\n }\n }\n\n /*** Local functions ***/\n function parseTrackingEvents(trackingEvents, duration) {\n var trackings = [];\n if (utilities.isDefined(trackingEvents)) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingData) {\n trackings.push(new TrackingEvent(trackingData, duration));\n });\n }\n return trackings;\n }\n\n function parseMediaFiles(mediaFilesJxonTree) {\n var mediaFiles = [];\n if (utilities.isDefined(mediaFilesJxonTree)) {\n mediaFilesJxonTree = utilities.isArray(mediaFilesJxonTree) ? mediaFilesJxonTree : [mediaFilesJxonTree];\n\n mediaFilesJxonTree.forEach(function (mfData) {\n mediaFiles.push(new MediaFile(mfData));\n });\n }\n return mediaFiles;\n }\n}\n\nmodule.exports = Linear;\n},{\"../../utils/utilityFunctions\":43,\"../../utils/xml\":44,\"./MediaFile\":18,\"./TrackingEvent\":19,\"./VideoClicks\":25,\"./parsers\":27}],18:[function(require,module,exports){\n'use strict';\n\nvar xml = require('../../utils/xml');\n\nvar attributesList = [\n //Required attributes\n 'delivery',\n 'type',\n 'width',\n 'height',\n //Optional attributes\n 'codec',\n 'id',\n 'bitrate',\n 'minBitrate',\n 'maxBitrate',\n 'scalable',\n 'maintainAspectRatio',\n 'apiFramework'\n];\n\nfunction MediaFile(mediaFileJTree) {\n if (!(this instanceof MediaFile)) {\n return new MediaFile(mediaFileJTree);\n }\n\n //Required attributes\n this.src = xml.keyValue(mediaFileJTree);\n\n for(var x=0; x 0) {\n getAd(waterfallAds.shift(),[], waterfallHandler);\n } else {\n callback(error, adChain);\n }\n } else {\n callback(null, adChain);\n }\n }\n });\n\n /*** Local functions ***/\n function getAdWaterfall(adTagUrl, callback) {\n var requestVastXML = that._requestVASTXml.bind(that, adTagUrl);\n async.waterfall([\n requestVastXML,\n buildVastWaterfall\n ], callback);\n }\n\n function buildVastWaterfall(xmlStr, callback) {\n var vastTree;\n try {\n vastTree = xml.toJXONTree(xmlStr);\n\n if(utilities.isArray(vastTree.ad)) {\n vastTree.ads = vastTree.ad;\n } else if(vastTree.ad){\n vastTree.ads = [vastTree.ad];\n } else {\n vastTree.ads = [];\n }\n callback(validateVASTTree(vastTree), vastTree);\n\n } catch (e) {\n callback(new VASTError(\"on VASTClient.getVASTAd.buildVastWaterfall, error parsing xml\", 100), null);\n }\n }\n\n function validateVASTTree(vastTree) {\n var vastVersion = xml.attr(vastTree, 'version');\n\n if (!vastTree.ad) {\n return new VASTError('on VASTClient.getVASTAd.validateVASTTree, no Ad in VAST tree', 303);\n }\n\n if (vastVersion && (vastVersion != 3 && vastVersion != 2)) {\n return new VASTError('on VASTClient.getVASTAd.validateVASTTree, not supported VAST version \"' + vastVersion + '\"', 102);\n }\n\n return null;\n }\n\n function getAd(adTagUrl, adChain, callback) {\n if (adChain.length >= that.WRAPPER_LIMIT) {\n return callback(new VASTError(\"on VASTClient.getVASTAd.getAd, players wrapper limit reached (the limit is \" + that.WRAPPER_LIMIT + \")\", 302), adChain);\n }\n\n async.waterfall([\n function (next) {\n if (utilities.isString(adTagUrl)) {\n requestVASTAd(adTagUrl, next);\n } else {\n next(null, adTagUrl);\n }\n },\n buildAd\n ], function (error, ad) {\n if (ad) {\n adChain.push(ad);\n }\n\n if (error) {\n return callback(error, adChain);\n }\n\n if (ad.wrapper) {\n return getAd(ad.wrapper.VASTAdTagURI, adChain, callback);\n }\n\n return callback(null, adChain);\n });\n }\n\n function buildAd(adJxonTree, callback) {\n try {\n var ad = new Ad(adJxonTree);\n callback(validateAd(ad), ad);\n } catch (e) {\n callback(new VASTError('on VASTClient.getVASTAd.buildAd, error parsing xml', 100), null);\n }\n }\n\n function validateAd(ad) {\n var wrapper = ad.wrapper;\n var inLine = ad.inLine;\n var errMsgPrefix = 'on VASTClient.getVASTAd.validateAd, ';\n\n if (inLine && wrapper) {\n return new VASTError(errMsgPrefix +\"InLine and Wrapper both found on the same Ad\", 101);\n }\n\n if (!inLine && !wrapper) {\n return new VASTError(errMsgPrefix + \"nor wrapper nor inline elements found on the Ad\", 101);\n }\n\n if (inLine && inLine.creatives.length === 0) {\n return new VASTError(errMsgPrefix + \"missing creative in InLine element\", 101);\n }\n\n if (wrapper && !wrapper.VASTAdTagURI) {\n return new VASTError(errMsgPrefix + \"missing 'VASTAdTagURI' in wrapper\", 101);\n }\n }\n\n function requestVASTAd(adTagUrl, callback) {\n that._requestVASTXml(adTagUrl, function (error, xmlStr) {\n if (error) {\n return callback(error);\n }\n try {\n var vastTree = xml.toJXONTree(xmlStr);\n callback(validateVASTTree(vastTree), vastTree.ad);\n } catch (e) {\n callback(new VASTError(\"on VASTClient.getVASTAd.requestVASTAd, error parsing xml\", 100));\n }\n });\n }\n};\n\nVASTClient.prototype._requestVASTXml = function requestVASTXml(adTagUrl, callback) {\n try {\n if (utilities.isFunction(adTagUrl)) {\n adTagUrl(requestHandler);\n } else {\n http.get(adTagUrl, requestHandler, {\n withCredentials: true\n });\n }\n } catch (e) {\n callback(e);\n }\n\n /*** Local functions ***/\n function requestHandler(error, response, status) {\n if (error) {\n var errMsg = utilities.isDefined(status) ?\n \"on VASTClient.requestVastXML, HTTP request error with status '\" + status + \"'\" :\n \"on VASTClient.requestVastXML, Error getting the the VAST XML with he passed adTagXML fn\";\n return callback(new VASTError(errMsg, 301), null);\n }\n\n callback(null, response);\n }\n};\n\nVASTClient.prototype._buildVASTResponse = function buildVASTResponse(adsChain) {\n var response = new VASTResponse();\n addAdsToResponse(response, adsChain);\n validateResponse(response);\n\n return response;\n\n //*** Local function ****\n function addAdsToResponse(response, ads) {\n ads.forEach(function (ad) {\n response.addAd(ad);\n });\n }\n\n function validateResponse(response) {\n var progressEvents = response.trackingEvents.progress;\n\n if (!response.hasLinear()) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, Received an Ad type that is not supported\", 200);\n }\n\n if (response.duration === undefined) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, Missing duration field in VAST response\", 101);\n }\n\n if (progressEvents) {\n progressEvents.forEach(function (progressEvent) {\n if (!utilities.isNumber(progressEvent.offset)) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, missing or wrong offset attribute on progress tracking event\", 101);\n }\n });\n }\n }\n};\n\nVASTClient.prototype._trackError = function (error, adChain) {\n if (!utilities.isArray(adChain) || adChain.length === 0) { //There is nothing to track\n return;\n }\n\n var errorURLMacros = [];\n adChain.forEach(addErrorUrlMacros);\n vastUtil.track(errorURLMacros, {ERRORCODE: error.code || 900}); //900 <== Undefined error\n\n /*** Local functions ***/\n function addErrorUrlMacros(ad) {\n if (ad.wrapper && ad.wrapper.error) {\n errorURLMacros.push(ad.wrapper.error);\n }\n\n if (ad.inLine && ad.inLine.error) {\n errorURLMacros.push(ad.inLine.error);\n }\n }\n};\n\nmodule.exports = VASTClient;\n\n},{\"../../utils/async\":38,\"../../utils/http\":40,\"../../utils/utilityFunctions\":43,\"../../utils/xml\":44,\"./Ad\":13,\"./VASTError\":21,\"./VASTResponse\":23,\"./vastUtil\":28}],21:[function(require,module,exports){\n'use strict';\n\nfunction VASTError(message, code) {\n this.message = 'VAST Error: ' + (message || '');\n if (code) {\n this.code = code;\n }\n}\n\nVASTError.prototype = new Error();\nVASTError.prototype.name = \"VAST Error\";\n\nmodule.exports = VASTError;\n},{}],22:[function(require,module,exports){\n'use strict';\n\n/**\n * Inner helper class that deals with the logic of the individual steps needed to setup an ad in the player.\n *\n * @param player {object} instance of the player that will play the ad. It assumes that the videojs-contrib-ads plugin\n * has been initialized when you use its utility functions.\n *\n * @constructor\n */\n\nvar VASTResponse = require('./VASTResponse');\nvar VASTError = require('./VASTError');\nvar VASTTracker = require('./VASTTracker');\nvar vastUtil = require('./vastUtil');\n\nvar async = require('../../utils/async');\nvar dom = require('../../utils/dom');\nvar playerUtils = require('../../utils/playerUtils');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VASTIntegrator(player) {\n if (!(this instanceof VASTIntegrator)) {\n return new VASTIntegrator(player);\n }\n\n this.player = player;\n}\n\nVASTIntegrator.prototype.playAd = function playAd(vastResponse, callback) {\n var that = this;\n callback = callback || utilities.noop;\n\n if (!(vastResponse instanceof VASTResponse)) {\n return callback(new VASTError('On VASTIntegrator, missing required VASTResponse'));\n }\n\n async.waterfall([\n function (next) {\n next(null, vastResponse);\n },\n this._selectAdSource.bind(this),\n this._createVASTTracker.bind(this),\n this._addClickThrough.bind(this),\n this._addSkipButton.bind(this),\n this._setupEvents.bind(this),\n this._playSelectedAd.bind(this)\n ], function (error, response) {\n if (error && response) {\n that._trackError(error, response);\n }\n callback(error, response);\n });\n\n this._adUnit = {\n _src: null,\n type: 'VAST',\n pauseAd: function () {\n that.player.pause(true);\n },\n\n resumeAd: function () {\n that.player.play(true);\n },\n\n isPaused: function () {\n return that.player.paused(true);\n },\n\n getSrc: function () {\n return this._src;\n }\n };\n\n return this._adUnit;\n};\n\nVASTIntegrator.prototype._selectAdSource = function selectAdSource(response, callback) {\n var source;\n\n var playerWidth = dom.getDimension(this.player.el()).width;\n response.mediaFiles.sort(function compareTo(a, b) {\n var deltaA = Math.abs(playerWidth - a.width);\n var deltaB = Math.abs(playerWidth - b.width);\n return deltaA - deltaB;\n });\n\n source = this.player.selectSource(response.mediaFiles).source;\n\n if (source) {\n if (this._adUnit) {\n this._adUnit._src = source;\n }\n return callback(null, source, response);\n }\n\n // code 403 <== Couldn't find MediaFile that is supported by this video player\n callback(new VASTError(\"Could not find Ad mediafile supported by this player\", 403), response);\n};\n\nVASTIntegrator.prototype._createVASTTracker = function createVASTTracker(adMediaFile, response, callback) {\n try {\n callback(null, adMediaFile, new VASTTracker(adMediaFile.src, response), response);\n } catch (e) {\n callback(e, response);\n }\n};\n\nVASTIntegrator.prototype._setupEvents = function setupEvents(adMediaFile, tracker, response, callback) {\n var previouslyMuted;\n var player = this.player;\n player.on('fullscreenchange', trackFullscreenChange);\n player.on('vast.adStart', trackImpressions);\n player.on('pause', trackPause);\n player.on('timeupdate', trackProgress);\n player.on('volumechange', trackVolumeChange);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], unbindEvents);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel', 'vast.adSkip'], function(evt){\n if(evt.type === 'vast.adEnd'){\n tracker.trackComplete();\n }\n });\n\n return callback(null, adMediaFile, response);\n\n /*** Local Functions ***/\n function unbindEvents() {\n player.off('fullscreenchange', trackFullscreenChange);\n player.off('vast.adStart', trackImpressions);\n player.off('pause', trackPause);\n player.off('timeupdate', trackProgress);\n player.off('volumechange', trackVolumeChange);\n }\n\n function trackFullscreenChange() {\n if (player.isFullscreen()) {\n tracker.trackFullscreen();\n } else {\n tracker.trackExitFullscreen();\n }\n }\n\n function trackPause() {\n //NOTE: whenever a video ends the video Element triggers a 'pause' event before the 'ended' event.\n // We should not track this pause event because it makes the VAST tracking confusing again we use a\n // Threshold of 2 seconds to prevent false positives on IOS.\n if (Math.abs(player.duration() - player.currentTime()) < 2) {\n return;\n }\n\n tracker.trackPause();\n playerUtils.once(player, ['play', 'vast.adEnd', 'vast.adsCancel'], function (evt) {\n if(evt.type === 'play'){\n tracker.trackResume();\n }\n });\n }\n\n function trackProgress() {\n var currentTimeInMs = player.currentTime() * 1000;\n tracker.trackProgress(currentTimeInMs);\n }\n\n function trackImpressions() {\n tracker.trackImpressions();\n tracker.trackCreativeView();\n }\n\n function trackVolumeChange() {\n var muted = player.muted();\n if (muted) {\n tracker.trackMute();\n } else if (previouslyMuted) {\n tracker.trackUnmute();\n }\n previouslyMuted = muted;\n }\n};\n\nVASTIntegrator.prototype._addSkipButton = function addSkipButton(source, tracker, response, callback) {\n var skipOffsetInSec;\n var that = this;\n\n if (utilities.isNumber(response.skipoffset)) {\n skipOffsetInSec = response.skipoffset / 1000;\n addSkipButtonToPlayer(this.player, skipOffsetInSec);\n }\n callback(null, source, tracker, response);\n\n /*** Local function ***/\n function addSkipButtonToPlayer(player, skipOffset) {\n var skipButton = createSkipButton(player);\n var updateSkipButton = updateSkipButtonState.bind(that, skipButton, skipOffset, player);\n\n player.el().appendChild(skipButton);\n player.on('timeupdate', updateSkipButton);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeSkipButton);\n\n function removeSkipButton() {\n player.off('timeupdate', updateSkipButton);\n dom.remove(skipButton);\n }\n }\n\n function createSkipButton(player) {\n var skipButton = window.document.createElement(\"div\");\n dom.addClass(skipButton, \"vast-skip-button\");\n\n skipButton.onclick = function (e) {\n if (dom.hasClass(skipButton, 'enabled')) {\n tracker.trackSkip();\n player.trigger('vast.adSkip');\n }\n\n //We prevent event propagation to avoid problems with the clickThrough and so on\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n } else {\n return false;\n }\n };\n\n return skipButton;\n }\n\n function updateSkipButtonState(skipButton, skipOffset, player) {\n var timeLeft = Math.ceil(skipOffset - player.currentTime());\n if (timeLeft > 0) {\n skipButton.innerHTML = \"Skip in \" + utilities.toFixedDigits(timeLeft, 2) + \"...\";\n } else {\n if (!dom.hasClass(skipButton, 'enabled')) {\n dom.addClass(skipButton, 'enabled');\n skipButton.innerHTML = \"Skip ad\";\n }\n }\n }\n};\n\nVASTIntegrator.prototype._addClickThrough = function addClickThrough(mediaFile, tracker, response, callback) {\n var player = this.player;\n var blocker = createClickThroughBlocker(player, tracker, response);\n var updateBlocker = updateBlockerURL.bind(this, blocker, response, player);\n\n player.el().insertBefore(blocker, player.controlBar.el());\n player.on('timeupdate', updateBlocker);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeBlocker);\n\n return callback(null, mediaFile, tracker, response);\n\n /*** Local Functions ***/\n\n function createClickThroughBlocker(player, tracker, response) {\n var blocker = window.document.createElement(\"a\");\n var clickThroughMacro = response.clickThrough;\n\n dom.addClass(blocker, 'vast-blocker');\n blocker.href = generateClickThroughURL(clickThroughMacro, player);\n\n if (utilities.isString(clickThroughMacro)) {\n blocker.target = \"_blank\";\n }\n\n blocker.onclick = function (e) {\n if (player.paused()) {\n player.play();\n\n //We prevent event propagation to avoid problems with the player's normal pause mechanism\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n }\n return false;\n }\n\n player.pause();\n tracker.trackClick();\n };\n\n return blocker;\n }\n\n function updateBlockerURL(blocker, response, player) {\n blocker.href = generateClickThroughURL(response.clickThrough, player);\n }\n\n function generateClickThroughURL(clickThroughMacro, player) {\n var variables = {\n ASSETURI: mediaFile.src,\n CONTENTPLAYHEAD: vastUtil.formatProgress(player.currentTime() * 1000)\n };\n\n return clickThroughMacro ? vastUtil.parseURLMacro(clickThroughMacro, variables) : '#';\n }\n\n function removeBlocker() {\n player.off('timeupdate', updateBlocker);\n dom.remove(blocker);\n }\n};\n\nVASTIntegrator.prototype._playSelectedAd = function playSelectedAd(source, response, callback) {\n var player = this.player;\n\n player.preload(\"auto\"); //without preload=auto the durationchange event is never fired\n player.src(source);\n\n playerUtils.once(player, ['durationchange', 'error', 'vast.adsCancel'], function (evt) {\n if (evt.type === 'durationchange') {\n playAd();\n } else if(evt.type === 'error') {\n callback(new VASTError(\"on VASTIntegrator, Player is unable to play the Ad\", 400), response);\n }\n //NOTE: If the ads get canceled we do nothing/\n });\n\n /**** local functions ******/\n function playAd() {\n playerUtils.once(player, ['playing', 'vast.adsCancel'], function (evt) {\n if(evt.type === 'vast.adsCancel'){\n return;\n }\n\n player.trigger('vast.adStart');\n\n playerUtils.once(player, ['ended', 'vast.adsCancel', 'vast.adSkip'], function (evt) {\n if(evt.type === 'ended' || evt.type === 'vast.adSkip'){\n callback(null, response);\n }\n //NOTE: if the ads get cancel we do nothing\n });\n });\n player.play();\n }\n};\n\nVASTIntegrator.prototype._trackError = function trackError(error, response) {\n vastUtil.track(response.errorURLMacros, {ERRORCODE: error.code || 900});\n};\n\nmodule.exports = VASTIntegrator;\n},{\"../../utils/async\":38,\"../../utils/dom\":39,\"../../utils/playerUtils\":41,\"../../utils/utilityFunctions\":43,\"./VASTError\":21,\"./VASTResponse\":23,\"./VASTTracker\":24,\"./vastUtil\":28}],23:[function(require,module,exports){\n'use strict';\n\nvar Ad = require('./Ad');\nvar VideoClicks = require('./VideoClicks');\nvar Linear = require('./Linear');\nvar InLine = require('./InLine');\nvar Wrapper = require('./Wrapper');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nwindow.InLine__A = InLine;\nfunction VASTResponse() {\n if (!(this instanceof VASTResponse)) {\n return new VASTResponse();\n }\n\n this._linearAdded = false;\n this.ads = [];\n this.errorURLMacros = [];\n this.impressions = [];\n this.clickTrackings = [];\n this.customClicks = [];\n this.trackingEvents = {};\n this.mediaFiles = [];\n this.clickThrough = undefined;\n this.adTitle = '';\n this.duration = undefined;\n this.skipoffset = undefined;\n}\n\nVASTResponse.prototype.addAd = function (ad) {\n var inLine, wrapper;\n if (ad instanceof Ad) {\n inLine = ad.inLine;\n wrapper = ad.wrapper;\n\n this.ads.push(ad);\n\n if (inLine) {\n this._addInLine(inLine);\n }\n\n if (wrapper) {\n this._addWrapper(wrapper);\n }\n }\n};\n\nVASTResponse.prototype._addErrorTrackUrl = function (error) {\n var errorURL = error instanceof xml.JXONTree ? xml.keyValue(error) : error;\n if (errorURL) {\n this.errorURLMacros.push(errorURL);\n }\n};\n\nVASTResponse.prototype._addImpressions = function (impressions) {\n utilities.isArray(impressions) && appendToArray(this.impressions, impressions);\n};\n\nVASTResponse.prototype._addClickThrough = function (clickThrough) {\n if (utilities.isNotEmptyString(clickThrough)) {\n this.clickThrough = clickThrough;\n }\n};\n\nVASTResponse.prototype._addClickTrackings = function (clickTrackings) {\n utilities.isArray(clickTrackings) && appendToArray(this.clickTrackings, clickTrackings);\n};\n\nVASTResponse.prototype._addCustomClicks = function (customClicks) {\n utilities.isArray(customClicks) && appendToArray(this.customClicks, customClicks);\n};\n\nVASTResponse.prototype._addTrackingEvents = function (trackingEvents) {\n var eventsMap = this.trackingEvents;\n\n if (trackingEvents) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingEvent) {\n if (!eventsMap[trackingEvent.name]) {\n eventsMap[trackingEvent.name] = [];\n }\n eventsMap[trackingEvent.name].push(trackingEvent);\n });\n }\n};\n\nVASTResponse.prototype._addTitle = function (title) {\n if (utilities.isNotEmptyString(title)) {\n this.adTitle = title;\n }\n};\n\nVASTResponse.prototype._addDuration = function (duration) {\n if (utilities.isNumber(duration)) {\n this.duration = duration;\n }\n};\n\nVASTResponse.prototype._addVideoClicks = function (videoClicks) {\n if (videoClicks instanceof VideoClicks) {\n this._addClickThrough(videoClicks.clickThrough);\n this._addClickTrackings(videoClicks.clickTrackings);\n this._addCustomClicks(videoClicks.customClicks);\n }\n};\n\nVASTResponse.prototype._addMediaFiles = function (mediaFiles) {\n utilities.isArray(mediaFiles) && appendToArray(this.mediaFiles, mediaFiles);\n};\n\nVASTResponse.prototype._addSkipoffset = function (offset) {\n if (offset) {\n this.skipoffset = offset;\n }\n};\n\nVASTResponse.prototype._addAdParameters = function (adParameters) {\n if (adParameters) {\n this.adParameters = adParameters;\n }\n};\n\nVASTResponse.prototype._addLinear = function (linear) {\n if (linear instanceof Linear) {\n this._addDuration(linear.duration);\n this._addTrackingEvents(linear.trackingEvents);\n this._addVideoClicks(linear.videoClicks);\n this._addMediaFiles(linear.mediaFiles);\n this._addSkipoffset(linear.skipoffset);\n this._addAdParameters(linear.adParameters);\n this._linearAdded = true;\n }\n};\n\nVASTResponse.prototype._addInLine = function (inLine) {\n var that = this;\n\n if (inLine instanceof InLine) {\n this._addTitle(inLine.adTitle);\n this._addErrorTrackUrl(inLine.error);\n this._addImpressions(inLine.impressions);\n\n inLine.creatives.forEach(function (creative) {\n if (creative.linear) {\n that._addLinear(creative.linear);\n }\n });\n }\n};\n\nVASTResponse.prototype._addWrapper = function (wrapper) {\n var that = this;\n\n if (wrapper instanceof Wrapper) {\n this._addErrorTrackUrl(wrapper.error);\n this._addImpressions(wrapper.impressions);\n\n wrapper.creatives.forEach(function (creative) {\n var linear = creative.linear;\n if (linear) {\n that._addVideoClicks(linear.videoClicks);\n that.clickThrough = undefined;//We ensure that no clickThrough has been added\n that._addTrackingEvents(linear.trackingEvents);\n }\n });\n }\n};\n\nVASTResponse.prototype.hasLinear = function(){\n return this._linearAdded;\n};\n\nfunction appendToArray(array, items) {\n items.forEach(function (item) {\n array.push(item);\n });\n}\n\nmodule.exports = VASTResponse;\n\n\n},{\"../../utils/utilityFunctions\":43,\"../../utils/xml\":44,\"./Ad\":13,\"./InLine\":16,\"./Linear\":17,\"./VideoClicks\":25,\"./Wrapper\":26}],24:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('./VASTError');\nvar VASTResponse = require('./VASTResponse');\nvar vastUtil = require('./vastUtil');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VASTTracker(assetURI, vastResponse) {\n if (!(this instanceof VASTTracker)) {\n return new VASTTracker(assetURI, vastResponse);\n }\n\n this.sanityCheck(assetURI, vastResponse);\n this.initialize(assetURI, vastResponse);\n\n}\n\nVASTTracker.prototype.initialize = function(assetURI, vastResponse) {\n this.response = vastResponse;\n this.assetURI = assetURI;\n this.progress = 0;\n this.quartiles = {\n firstQuartile: {tracked: false, time: Math.round(25 * vastResponse.duration) / 100},\n midpoint: {tracked: false, time: Math.round(50 * vastResponse.duration) / 100},\n thirdQuartile: {tracked: false, time: Math.round(75 * vastResponse.duration) / 100}\n };\n};\n\nVASTTracker.prototype.sanityCheck = function(assetURI, vastResponse) {\n if (!utilities.isString(assetURI) || utilities.isEmptyString(assetURI)) {\n throw new VASTError('on VASTTracker constructor, missing required the URI of the ad asset being played');\n }\n\n if (!(vastResponse instanceof VASTResponse)) {\n throw new VASTError('on VASTTracker constructor, missing required VAST response');\n }\n};\n\nVASTTracker.prototype.trackURLs = function trackURLs(urls, variables) {\n if (utilities.isArray(urls) && urls.length > 0) {\n variables = utilities.extend({\n ASSETURI: this.assetURI,\n CONTENTPLAYHEAD: vastUtil.formatProgress(this.progress)\n }, variables || {});\n\n vastUtil.track(urls, variables);\n }\n};\n\nVASTTracker.prototype.trackEvent = function trackEvent(eventName, trackOnce) {\n this.trackURLs(getEventUris(this.response.trackingEvents[eventName]));\n if (trackOnce) {\n this.response.trackingEvents[eventName] = undefined;\n }\n\n /*** Local function ***/\n function getEventUris(trackingEvents) {\n var uris;\n\n if (trackingEvents) {\n uris = [];\n trackingEvents.forEach(function (event) {\n uris.push(event.uri);\n });\n }\n return uris;\n }\n};\n\nVASTTracker.prototype.trackProgress = function trackProgress(newProgressInMs) {\n var that = this;\n var events = [];\n var ONCE = true;\n var ALWAYS = false;\n var trackingEvents = this.response.trackingEvents;\n\n if (utilities.isNumber(newProgressInMs)) {\n addTrackEvent('start', ONCE, newProgressInMs > 0);\n addTrackEvent('rewind', ALWAYS, hasRewound(this.progress, newProgressInMs));\n addQuartileEvents(newProgressInMs);\n trackProgressEvents(newProgressInMs);\n trackEvents();\n this.progress = newProgressInMs;\n }\n\n /*** Local function ***/\n function hasRewound(currentProgress, newProgress) {\n var REWIND_THRESHOLD = 3000; //IOS video clock is very unreliable and we need a 3 seconds threshold to ensure that there was a rewind an that it was on purpose.\n return currentProgress > newProgressInMs && Math.abs(newProgress - currentProgress) > REWIND_THRESHOLD;\n }\n\n function addTrackEvent(eventName, trackOnce, canBeAdded) {\n if (trackingEvents[eventName] && canBeAdded) {\n events.push({\n name: eventName,\n trackOnce: !!trackOnce\n });\n }\n }\n\n function addQuartileEvents(progress) {\n var quartiles = that.quartiles;\n var firstQuartile = that.quartiles.firstQuartile;\n var midpoint = that.quartiles.midpoint;\n var thirdQuartile = that.quartiles.thirdQuartile;\n\n if (!firstQuartile.tracked) {\n trackQuartile('firstQuartile', progress);\n } else if (!midpoint.tracked) {\n trackQuartile('midpoint', progress);\n } else if (!thirdQuartile.tracked){\n trackQuartile('thirdQuartile', progress);\n }\n\n /*** Local function ***/\n function trackQuartile(quartileName, progress){\n var quartile = quartiles[quartileName];\n if(canBeTracked(quartile, progress)){\n quartile.tracked = true;\n addTrackEvent(quartileName, ONCE, true);\n }\n }\n }\n\n function canBeTracked(quartile, progress) {\n var quartileTime = quartile.time;\n //We only fire the quartile event if the progress is bigger than the quartile time by 5 seconds at most.\n return progress >= quartileTime && progress <= (quartileTime + 5000);\n }\n\n function trackProgressEvents(progress) {\n if (!utilities.isArray(trackingEvents.progress)) {\n return; //Nothing to track\n }\n\n var pendingProgressEvts = [];\n\n trackingEvents.progress.forEach(function (evt) {\n if (evt.offset <= progress) {\n that.trackURLs([evt.uri]);\n } else {\n pendingProgressEvts.push(evt);\n }\n });\n trackingEvents.progress = pendingProgressEvts;\n }\n\n function trackEvents() {\n events.forEach(function (event) {\n that.trackEvent(event.name, event.trackOnce);\n });\n }\n};\n\n[\n 'rewind',\n 'fullscreen',\n 'exitFullscreen',\n 'pause',\n 'resume',\n 'mute',\n 'unmute',\n 'acceptInvitation',\n 'acceptInvitationLinear',\n 'collapse',\n 'expand'\n].forEach(function (eventName) {\n VASTTracker.prototype['track' + utilities.capitalize(eventName)] = function () {\n this.trackEvent(eventName);\n };\n });\n\n[\n 'start',\n 'skip',\n 'close',\n 'closeLinear'\n].forEach(function (eventName) {\n VASTTracker.prototype['track' + utilities.capitalize(eventName)] = function () {\n this.trackEvent(eventName, true);\n };\n });\n\n[\n 'firstQuartile',\n 'midpoint',\n 'thirdQuartile'\n].forEach(function (quartile) {\n VASTTracker.prototype['track' + utilities.capitalize(quartile)] = function () {\n this.quartiles[quartile].tracked = true;\n this.trackEvent(quartile, true);\n };\n });\n\nVASTTracker.prototype.trackComplete = function () {\n if(this.quartiles.thirdQuartile.tracked){\n this.trackEvent('complete', true);\n }\n};\n\nVASTTracker.prototype.trackErrorWithCode = function trackErrorWithCode(errorcode) {\n if (utilities.isNumber(errorcode)) {\n this.trackURLs(this.response.errorURLMacros, {ERRORCODE: errorcode});\n }\n};\n\nVASTTracker.prototype.trackImpressions = function trackImpressions() {\n this.trackURLs(this.response.impressions);\n};\n\nVASTTracker.prototype.trackCreativeView = function trackCreativeView() {\n this.trackEvent('creativeView');\n};\n\nVASTTracker.prototype.trackClick = function trackClick() {\n this.trackURLs(this.response.clickTrackings);\n};\n\nmodule.exports = VASTTracker;\n\n},{\"../../utils/utilityFunctions\":43,\"./VASTError\":21,\"./VASTResponse\":23,\"./vastUtil\":28}],25:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction VideoClicks(videoClickJTree) {\n if (!(this instanceof VideoClicks)) {\n return new VideoClicks(videoClickJTree);\n }\n\n this.clickThrough = xml.keyValue(videoClickJTree.clickThrough);\n this.clickTrackings = parseClickTrackings(videoClickJTree.clickTracking);\n this.customClicks = parseClickTrackings(videoClickJTree.customClick);\n\n /*** Local functions ***/\n function parseClickTrackings(trackingData) {\n var clickTrackings = [];\n if (trackingData) {\n trackingData = utilities.isArray(trackingData) ? trackingData : [trackingData];\n trackingData.forEach(function (clickTrackingData) {\n clickTrackings.push(xml.keyValue(clickTrackingData));\n });\n }\n return clickTrackings;\n }\n}\n\nmodule.exports = VideoClicks;\n},{\"../../utils/utilityFunctions\":43,\"../../utils/xml\":44}],26:[function(require,module,exports){\n'use strict';\n\nvar vastUtil = require('./vastUtil');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction Wrapper(wrapperJTree) {\n if(!(this instanceof Wrapper)) {\n return new Wrapper(wrapperJTree);\n }\n\n //Required elements\n this.adSystem = xml.keyValue(wrapperJTree.adSystem);\n this.impressions = vastUtil.parseImpressions(wrapperJTree.impression);\n this.VASTAdTagURI = xml.keyValue(wrapperJTree.vASTAdTagURI);\n\n //Optional elements\n this.creatives = vastUtil.parseCreatives(wrapperJTree.creatives);\n this.error = xml.keyValue(wrapperJTree.error);\n this.extensions = wrapperJTree.extensions;\n\n //Optional attrs\n this.followAdditionalWrappers = utilities.isDefined(xml.attr(wrapperJTree, 'followAdditionalWrappers'))? xml.attr(wrapperJTree, 'followAdditionalWrappers'): true;\n this.allowMultipleAds = xml.attr(wrapperJTree, 'allowMultipleAds');\n this.fallbackOnNoAd = xml.attr(wrapperJTree, 'fallbackOnNoAd');\n}\n\nmodule.exports = Wrapper;\n},{\"../../utils/utilityFunctions\":43,\"../../utils/xml\":44,\"./vastUtil\":28}],27:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\n\nvar durationRegex = /(\\d\\d):(\\d\\d):(\\d\\d)(\\.(\\d\\d\\d))?/;\n\nvar parsers = {\n\n duration: function parseDuration(durationStr) {\n\n var match, durationInMs;\n\n if (utilities.isString(durationStr)) {\n match = durationStr.match(durationRegex);\n if (match) {\n durationInMs = parseHoursToMs(match[1]) + parseMinToMs(match[2]) + parseSecToMs(match[3]) + parseInt(match[5] || 0);\n }\n }\n\n return isNaN(durationInMs) ? null : durationInMs;\n\n /*** local functions ***/\n function parseHoursToMs(hourStr) {\n return parseInt(hourStr, 10) * 60 * 60 * 1000;\n }\n\n function parseMinToMs(minStr) {\n return parseInt(minStr, 10) * 60 * 1000;\n }\n\n function parseSecToMs(secStr) {\n return parseInt(secStr, 10) * 1000;\n }\n },\n\n offset: function parseOffset(offset, duration) {\n if(isPercentage(offset)){\n return calculatePercentage(offset, duration);\n }\n return parsers.duration(offset);\n\n /*** Local function ***/\n function isPercentage(offset) {\n var percentageRegex = /^\\d+(\\.\\d+)?%$/g;\n return percentageRegex.test(offset);\n }\n\n function calculatePercentage(percentStr, duration) {\n if(duration) {\n return calcPercent(duration, parseFloat(percentStr.replace('%', '')));\n }\n return null;\n }\n\n function calcPercent(quantity, percent){\n return quantity * percent / 100;\n }\n }\n\n};\n\n\nmodule.exports = parsers;\n},{\"../../utils/utilityFunctions\":43}],28:[function(require,module,exports){\n'use strict';\n\nvar Creative = require('./Creative');\nvar utilities = require('../../utils/utilityFunctions');\n\nvar vastUtil = {\n\n track: function track(URLMacros, variables) {\n var sources = vastUtil.parseURLMacros(URLMacros, variables);\n var trackImgs = [];\n sources.forEach(function (src) {\n var img = new Image();\n img.src = src;\n trackImgs.push(img);\n });\n return trackImgs;\n },\n\n parseURLMacros: function parseMacros(URLMacros, variables) {\n var parsedURLs = [];\n\n variables = variables || {};\n\n if (!(variables[\"CACHEBUSTING\"])) {\n variables[\"CACHEBUSTING\"] = Math.round(Math.random() * 1.0e+10);\n }\n\n URLMacros.forEach(function (URLMacro) {\n parsedURLs.push(vastUtil._parseURLMacro(URLMacro, variables));\n });\n\n return parsedURLs;\n },\n\n parseURLMacro: function parseMacro(URLMacro, variables) {\n variables = variables || {};\n\n if (!(variables[\"CACHEBUSTING\"])) {\n variables[\"CACHEBUSTING\"] = Math.round(Math.random() * 1.0e+10);\n }\n\n return vastUtil._parseURLMacro(URLMacro, variables);\n },\n\n _parseURLMacro: function parseMacro(URLMacro, variables) {\n variables = variables || {};\n\n utilities.forEach(variables, function (value, key) {\n URLMacro = URLMacro.replace(new RegExp(\"\\\\[\" + key + \"\\\\\\]\", 'gm'), value);\n });\n\n return URLMacro;\n },\n\n parseDuration: function parseDuration(durationStr) {\n var durationRegex = /(\\d\\d):(\\d\\d):(\\d\\d)(\\.(\\d\\d\\d))?/;\n var match, durationInMs;\n\n if (utilities.isString(durationStr)) {\n match = durationStr.match(durationRegex);\n if (match) {\n durationInMs = parseHoursToMs(match[1]) + parseMinToMs(match[2]) + parseSecToMs(match[3]) + parseInt(match[5] || 0);\n }\n }\n\n return isNaN(durationInMs) ? null : durationInMs;\n\n /*** local functions ***/\n function parseHoursToMs(hourStr) {\n return parseInt(hourStr, 10) * 60 * 60 * 1000;\n }\n\n function parseMinToMs(minStr) {\n return parseInt(minStr, 10) * 60 * 1000;\n }\n\n function parseSecToMs(secStr) {\n return parseInt(secStr, 10) * 1000;\n }\n },\n\n parseImpressions: function parseImpressions(impressions) {\n if (impressions) {\n impressions = utilities.isArray(impressions) ? impressions : [impressions];\n return utilities.transformArray(impressions, function (impression) {\n if (utilities.isNotEmptyString(impression.keyValue)) {\n return impression.keyValue;\n }\n return undefined;\n });\n }\n return [];\n },\n\n parseCreatives: function parseCreatives(creativesJTree) {\n var creatives = [];\n var creativesData;\n if (utilities.isDefined(creativesJTree) && utilities.isDefined(creativesJTree.creative)) {\n creativesData = utilities.isArray(creativesJTree.creative) ? creativesJTree.creative : [creativesJTree.creative];\n creativesData.forEach(function (creative) {\n creatives.push(new Creative(creative));\n });\n }\n return creatives;\n },\n\n //We assume that the progress is going to arrive in milliseconds\n formatProgress: function formatProgress(progress) {\n var hours, minutes, seconds, milliseconds;\n hours = progress / (60 * 60 * 1000);\n hours = Math.floor(hours);\n minutes = (progress / (60 * 1000)) % 60;\n minutes = Math.floor(minutes);\n seconds = (progress / 1000) % 60;\n seconds = Math.floor(seconds);\n milliseconds = progress % 1000;\n return utilities.toFixedDigits(hours, 2) + ':' + utilities.toFixedDigits(minutes, 2) + ':' + utilities.toFixedDigits(seconds, 2) + '.' + utilities.toFixedDigits(milliseconds, 3);\n },\n\n parseOffset: function parseOffset(offset, duration) {\n if(isPercentage(offset)){\n return calculatePercentage(offset, duration);\n }\n return vastUtil.parseDuration(offset);\n\n /*** Local function ***/\n function isPercentage(offset) {\n var percentageRegex = /^\\d+(\\.\\d+)?%$/g;\n return percentageRegex.test(offset);\n }\n\n function calculatePercentage(percentStr, duration) {\n if(duration) {\n return calcPercent(duration, parseFloat(percentStr.replace('%', '')));\n }\n return null;\n }\n\n function calcPercent(quantity, percent){\n return quantity * percent / 100;\n }\n },\n\n isVPAID: function isVPAIDMediaFile(mediaFile) {\n return !!mediaFile && mediaFile.apiFramework === 'VPAID';\n }\n};\n\n\nmodule.exports = vastUtil;\n},{\"../../utils/utilityFunctions\":43,\"./Creative\":15}],29:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VPAIDAdUnitWrapper(vpaidAdUnit, opts) {\n if (!(this instanceof VPAIDAdUnitWrapper)) {\n return new VPAIDAdUnitWrapper(vpaidAdUnit, opts);\n }\n sanityCheck(vpaidAdUnit, opts);\n\n this.options = utilities.extend({}, opts);\n\n this._adUnit = vpaidAdUnit;\n\n /*** Local Functions ***/\n function sanityCheck(adUnit, opts) {\n if (!adUnit || !VPAIDAdUnitWrapper.checkVPAIDInterface(adUnit)) {\n throw new VASTError('on VPAIDAdUnitWrapper, the passed VPAID adUnit does not fully implement the VPAID interface');\n }\n\n if (!utilities.isObject(opts)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper, expected options hash but got '\" + opts + \"'\");\n }\n\n if (!(\"responseTimeout\" in opts) || !utilities.isNumber(opts.responseTimeout) ){\n throw new VASTError(\"on VPAIDAdUnitWrapper, expected responseTimeout in options\");\n }\n }\n}\n\nVPAIDAdUnitWrapper.checkVPAIDInterface = function checkVPAIDInterface(VPAIDAdUnit) {\n //NOTE: skipAd is not part of the method list because it only appears in VPAID 2.0 and we support VPAID 1.0\n var VPAIDInterfaceMethods = [\n 'handshakeVersion', 'initAd', 'startAd', 'stopAd', 'resizeAd', 'pauseAd', 'expandAd', 'collapseAd'\n ];\n\n for (var i = 0, len = VPAIDInterfaceMethods.length; i < len; i++) {\n if (!VPAIDAdUnit || !utilities.isFunction(VPAIDAdUnit[VPAIDInterfaceMethods[i]])) {\n return false;\n }\n }\n\n\n return canSubscribeToEvents(VPAIDAdUnit) && canUnsubscribeFromEvents(VPAIDAdUnit);\n\n /*** Local Functions ***/\n\n function canSubscribeToEvents(adUnit) {\n return utilities.isFunction(adUnit.subscribe) || utilities.isFunction(adUnit.addEventListener) || utilities.isFunction(adUnit.on);\n }\n\n function canUnsubscribeFromEvents(adUnit) {\n return utilities.isFunction(adUnit.unsubscribe) || utilities.isFunction(adUnit.removeEventListener) || utilities.isFunction(adUnit.off);\n\n }\n};\n\nVPAIDAdUnitWrapper.prototype.adUnitAsyncCall = function () {\n var args = utilities.arrayLikeObjToArray(arguments);\n var method = args.shift();\n var cb = args.pop();\n var timeoutId;\n\n sanityCheck(method, cb, this._adUnit);\n args.push(wrapCallback());\n\n this._adUnit[method].apply(this._adUnit, args);\n timeoutId = setTimeout(function () {\n timeoutId = null;\n cb(new VASTError(\"on VPAIDAdUnitWrapper, timeout while waiting for a response on call '\" + method + \"'\"));\n cb = utilities.noop;\n }, this.options.responseTimeout);\n\n /*** Local functions ***/\n function sanityCheck(method, cb, adUnit) {\n if (!utilities.isString(method) || !utilities.isFunction(adUnit[method])) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.adUnitAsyncCall, invalid method name\");\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.adUnitAsyncCall, missing callback\");\n }\n }\n\n function wrapCallback() {\n return function () {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n cb.apply(this, arguments);\n };\n }\n};\n\nVPAIDAdUnitWrapper.prototype.on = function (evtName, handler) {\n var addEventListener = this._adUnit.addEventListener || this._adUnit.subscribe || this._adUnit.on;\n addEventListener.call(this._adUnit, evtName, handler);\n};\n\nVPAIDAdUnitWrapper.prototype.off = function (evtName, handler) {\n var removeEventListener = this._adUnit.removeEventListener || this._adUnit.unsubscribe || this._adUnit.off;\n removeEventListener.call(this._adUnit, evtName, handler);\n};\n\nVPAIDAdUnitWrapper.prototype.waitForEvent = function (evtName, cb, context) {\n var timeoutId;\n sanityCheck(evtName, cb);\n context = context || null;\n\n this.on(evtName, responseListener);\n\n timeoutId = setTimeout(function () {\n cb(new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, timeout while waiting for event '\" + evtName + \"'\"));\n timeoutId = null;\n cb = utilities.noop;\n }, this.options.responseTimeout);\n\n /*** Local functions ***/\n function sanityCheck(evtName, cb) {\n if (!utilities.isString(evtName)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, missing evt name\");\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, missing callback\");\n }\n }\n\n function responseListener() {\n var args = utilities.arrayLikeObjToArray(arguments);\n\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n\n args.unshift(null);\n cb.apply(context, args);\n }\n};\n\n// VPAID METHODS\nVPAIDAdUnitWrapper.prototype.handshakeVersion = function (version, cb) {\n this.adUnitAsyncCall('handshakeVersion', version, cb);\n};\n\n/* jshint maxparams:6 */\nVPAIDAdUnitWrapper.prototype.initAd = function (width, height, viewMode, desiredBitrate, adUnitData, cb) {\n this.waitForEvent('AdLoaded', cb);\n this._adUnit.initAd(width, height, viewMode, desiredBitrate, adUnitData);\n};\n\nVPAIDAdUnitWrapper.prototype.resizeAd = function (width, height, viewMode, cb) {\n // NOTE: AdSizeChange event is only supported on VPAID 2.0 so for the moment we are not going to use it\n // and will assume that everything is fine after the async call\n this.adUnitAsyncCall('resizeAd', width, height, viewMode, cb);\n};\n\nVPAIDAdUnitWrapper.prototype.startAd = function (cb) {\n this.waitForEvent('AdStarted', cb);\n this._adUnit.startAd();\n};\n\nVPAIDAdUnitWrapper.prototype.stopAd = function (cb) {\n this.waitForEvent('AdStopped', cb);\n this._adUnit.stopAd();\n};\n\nVPAIDAdUnitWrapper.prototype.pauseAd = function (cb) {\n this.waitForEvent('AdPaused', cb);\n this._adUnit.pauseAd();\n};\n\nVPAIDAdUnitWrapper.prototype.resumeAd = function (cb) {\n this.waitForEvent('AdPlaying', cb);\n this._adUnit.resumeAd();\n};\n\nVPAIDAdUnitWrapper.prototype.expandAd = function (cb) {\n this.waitForEvent('AdExpandedChange', cb);\n this._adUnit.expandAd();\n};\n\nVPAIDAdUnitWrapper.prototype.collapseAd = function (cb) {\n this.waitForEvent('AdExpandedChange', cb);\n this._adUnit.collapseAd();\n};\n\nVPAIDAdUnitWrapper.prototype.skipAd = function (cb) {\n this.waitForEvent('AdSkipped', cb);\n this._adUnit.skipAd();\n};\n\n//VPAID property getters\n[\n 'adLinear',\n 'adWidth',\n 'adHeight',\n 'adExpanded',\n 'adSkippableState',\n 'adRemainingTime',\n 'adDuration',\n 'adVolume',\n 'adCompanions',\n 'adIcons'\n].forEach(function (property) {\n var getterName = 'get' + utilities.capitalize(property);\n\n VPAIDAdUnitWrapper.prototype[getterName] = function (cb) {\n this.adUnitAsyncCall(getterName, cb);\n };\n});\n\n//VPAID property setters\nVPAIDAdUnitWrapper.prototype.setAdVolume = function(volume, cb){\n this.adUnitAsyncCall('setAdVolume',volume, cb);\n};\n\nmodule.exports = VPAIDAdUnitWrapper;\n\n},{\"../../utils/utilityFunctions\":43,\"../vast/VASTError\":21}],30:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar VPAIDFLASHClient = require('VPAIDFLASHClient/js/VPAIDFLASHClient');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar dom = require('../../utils/dom');\n\nfunction VPAIDFlashTech(mediaFile, settings) {\n if (!(this instanceof VPAIDFlashTech)) {\n return new VPAIDFlashTech(mediaFile);\n }\n sanityCheck(mediaFile);\n this.name = 'vpaid-flash';\n this.mediaFile = mediaFile;\n this.containerEl = null;\n this.vpaidFlashClient = null;\n this.settings = settings;\n\n /*** local functions ***/\n function sanityCheck(mediaFile) {\n if (!mediaFile || !utilities.isString(mediaFile.src)) {\n throw new VASTError('on VPAIDFlashTech, invalid MediaFile');\n }\n }\n}\n\nVPAIDFlashTech.VPAIDFLASHClient = VPAIDFLASHClient;\n\nVPAIDFlashTech.supports = function (type) {\n return type === 'application/x-shockwave-flash' && VPAIDFlashTech.VPAIDFLASHClient.isSupported();\n};\n\nVPAIDFlashTech.prototype.loadAdUnit = function loadFlashCreative(containerEl, objectEl, callback) {\n var that = this;\n var flashClientOpts = this.settings && this.settings.vpaidFlashLoaderPath ? {data: this.settings.vpaidFlashLoaderPath} : undefined;\n sanityCheck(containerEl, callback);\n\n this.containerEl = containerEl;\n this.vpaidFlashClient = new VPAIDFlashTech.VPAIDFLASHClient(containerEl, function (error) {\n if (error) {\n return callback(error);\n }\n\n that.vpaidFlashClient.loadAdUnit(that.mediaFile.src, callback);\n }, flashClientOpts);\n\n /*** Local Functions ***/\n function sanityCheck(container, cb) {\n\n if (!dom.isDomElement(container)) {\n throw new VASTError('on VPAIDFlashTech.loadAdUnit, invalid dom container element');\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError('on VPAIDFlashTech.loadAdUnit, missing valid callback');\n }\n }\n};\n\nVPAIDFlashTech.prototype.unloadAdUnit = function () {\n if (this.vpaidFlashClient) {\n try{\n this.vpaidFlashClient.destroy();\n } catch(e){\n if(console && utilities.isFunction(console.log)){\n console.log('VAST ERROR: trying to unload the VPAID adunit');\n }\n }\n this.vpaidFlashClient = null;\n }\n\n if (this.containerEl) {\n dom.remove(this.containerEl);\n this.containerEl = null;\n }\n};\n\nmodule.exports = VPAIDFlashTech;\n},{\"../../utils/dom\":39,\"../../utils/utilityFunctions\":43,\"../vast/VASTError\":21,\"VPAIDFLASHClient/js/VPAIDFLASHClient\":3}],31:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar VPAIDHTML5Client = require('VPAIDHTML5Client/js/VPAIDHTML5Client');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar dom = require('../../utils/dom');\n\nfunction VPAIDHTML5Tech(mediaFile) {\n\n if(!(this instanceof VPAIDHTML5Tech)) {\n return new VPAIDHTML5Tech(mediaFile);\n }\n\n sanityCheck(mediaFile);\n\n this.name = 'vpaid-html5';\n this.containerEl = null;\n this.videoEl = null;\n this.vpaidHTMLClient = null;\n\n this.mediaFile = mediaFile;\n\n function sanityCheck(mediaFile) {\n if (!mediaFile || !utilities.isString(mediaFile.src)) {\n throw new VASTError(VPAIDHTML5Tech.INVALID_MEDIA_FILE);\n }\n }\n}\n\nVPAIDHTML5Tech.VPAIDHTML5Client = VPAIDHTML5Client;\n\nVPAIDHTML5Tech.supports = function (type) {\n return !utilities.isOldIE() && type === 'application/javascript';\n};\n\nVPAIDHTML5Tech.prototype.loadAdUnit = function loadAdUnit(containerEl, videoEl, callback) {\n sanityCheck(containerEl, videoEl, callback);\n\n this.containerEl = containerEl;\n this.videoEl = videoEl;\n this.vpaidHTMLClient = new VPAIDHTML5Tech.VPAIDHTML5Client(containerEl, videoEl, {});\n this.vpaidHTMLClient.loadAdUnit(this.mediaFile.src, callback);\n\n function sanityCheck(container, video, cb) {\n if (!dom.isDomElement(container)) {\n throw new VASTError(VPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL);\n }\n\n if (!dom.isDomElement(video) || video.tagName.toLowerCase() !== 'video') {\n throw new VASTError(VPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL);\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(VPAIDHTML5Tech.MISSING_CALLBACK);\n }\n }\n};\n\nVPAIDHTML5Tech.prototype.unloadAdUnit = function unloadAdUnit() {\n if (this.vpaidHTMLClient) {\n try {\n this.vpaidHTMLClient.destroy();\n } catch(e) {\n if (console && utilities.isFunction(console.log)) {\n console.log('VAST ERROR: trying to unload the VPAID adunit');\n }\n }\n\n this.vpaidHTMLClient = null;\n }\n\n if (this.containerEl) {\n dom.remove(this.containerEl);\n this.containerEl = null;\n }\n};\n\nvar PREFIX = 'on VPAIDHTML5Tech';\nVPAIDHTML5Tech.INVALID_MEDIA_FILE = PREFIX + ', invalid MediaFile';\nVPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL = PREFIX + ', invalid container HtmlElement';\nVPAIDHTML5Tech.INVALID_DOM_VIDEO_EL = PREFIX + ', invalid HTMLVideoElement';\nVPAIDHTML5Tech.MISSING_CALLBACK = PREFIX + ', missing valid callback';\n\nmodule.exports = VPAIDHTML5Tech;\n},{\"../../utils/dom\":39,\"../../utils/utilityFunctions\":43,\"../vast/VASTError\":21,\"VPAIDHTML5Client/js/VPAIDHTML5Client\":10}],32:[function(require,module,exports){\n'use strict';\n\nvar VASTError = require('../vast/VASTError');\nvar VASTResponse = require('../vast/VASTResponse');\nvar VASTTracker = require('../vast/VASTTracker');\nvar vastUtil = require('../vast/vastUtil');\n\nvar VPAIDAdUnitWrapper = require('./VPAIDAdUnitWrapper');\nvar VPAIDHTML5Tech = require('./VPAIDHTML5Tech');\nvar VPAIDFlashTech = require('./VPAIDFlashTech');\n\nvar async = require('../../utils/async');\nvar dom = require('../../utils/dom');\nvar playerUtils = require('../../utils/playerUtils');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VPAIDIntegrator(player, settings) {\n if (!(this instanceof VPAIDIntegrator)) {\n return new VPAIDIntegrator(player);\n }\n\n this.VIEW_MODE = {\n NORMAL: 'normal',\n FULLSCREEN: \"fullscreen\",\n THUMBNAIL: \"thumbnail\"\n };\n this.player = player;\n this.containerEl = createVPAIDContainerEl(player);\n this.options = {\n responseTimeout: 5000,\n VPAID_VERSION: '2.0'\n };\n this.settings = settings;\n\n /*** Local functions ***/\n\n function createVPAIDContainerEl() {\n var containerEl = document.createElement('div');\n dom.addClass(containerEl, 'VPAID-container');\n player.el().insertBefore(containerEl, player.controlBar.el());\n return containerEl;\n\n }\n}\n\n//List of supported VPAID technologies\nVPAIDIntegrator.techs = [\n VPAIDFlashTech,\n VPAIDHTML5Tech\n];\n\nVPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) {\n var that = this;\n var tech;\n var player = this.player;\n\n callback = callback || utilities.noop;\n if (!(vastResponse instanceof VASTResponse)) {\n return callback(new VASTError('on VASTIntegrator.playAd, missing required VASTResponse'));\n }\n\n tech = this._findSupportedTech(vastResponse, this.settings);\n dom.addClass(player.el(), 'vjs-vpaid-ad');\n\n player.on('vast.adsCancel', triggerVpaidAdEnd);\n player.one('vpaid.adEnd', function(){\n player.off('vast.adsCancel', triggerVpaidAdEnd);\n removeAdUnit();\n });\n\n if (tech) {\n async.waterfall([\n function (next) {\n next(null, tech, vastResponse);\n },\n this._loadAdUnit.bind(this),\n this._playAdUnit.bind(this),\n this._finishPlaying.bind(this)\n\n ], function (error, adUnit, vastResponse) {\n if (error) {\n that._trackError(vastResponse);\n }\n player.trigger('vpaid.adEnd');\n callback(error, vastResponse);\n });\n\n this._adUnit = {\n _paused: true,\n type: 'VPAID',\n pauseAd: function() {\n player.trigger('vpaid.pauseAd');\n player.pause(true);//we make sure that the video content gets stopped.\n },\n resumeAd: function() {\n player.trigger('vpaid.resumeAd');\n },\n isPaused: function() {\n return this._paused;\n },\n getSrc: function() {\n return tech.mediaFile;\n }\n };\n\n return this._adUnit;\n }\n\n callback(new VASTError('on VPAIDIntegrator.playAd, could not find a supported mediaFile'));\n\n return null;\n /*** Local functions ***/\n function triggerVpaidAdEnd(){\n player.trigger('vpaid.adEnd');\n }\n\n function removeAdUnit() {\n if (tech) {\n tech.unloadAdUnit();\n }\n dom.removeClass(player.el(), 'vjs-vpaid-ad');\n }\n};\n\nVPAIDIntegrator.prototype._findSupportedTech = function (vastResponse, settings) {\n if (!(vastResponse instanceof VASTResponse)) {\n return null;\n }\n\n var vpaidMediaFiles = vastResponse.mediaFiles.filter(vastUtil.isVPAID);\n var i, len, mediaFile, VPAIDTech;\n\n for (i = 0, len = vpaidMediaFiles.length; i < len; i += 1) {\n mediaFile = vpaidMediaFiles[i];\n VPAIDTech = findSupportedTech(mediaFile);\n if (VPAIDTech) {\n return new VPAIDTech(mediaFile, settings);\n }\n }\n return null;\n\n /*** Local functions ***/\n function findSupportedTech(mediafile) {\n var type = mediafile.type;\n var i, len, VPAIDTech;\n for (i = 0, len = VPAIDIntegrator.techs.length; i < len; i += 1) {\n VPAIDTech = VPAIDIntegrator.techs[i];\n if (VPAIDTech.supports(type)) {\n return VPAIDTech;\n }\n }\n return null;\n }\n};\n\nVPAIDIntegrator.prototype._createVPAIDAdUnitWrapper = function(adUnit, src, responseTimeout) {\n return new VPAIDAdUnitWrapper(adUnit, {src: src, responseTimeout: responseTimeout});\n};\n\nVPAIDIntegrator.prototype._loadAdUnit = function (tech, vastResponse, next) {\n var that = this;\n var player = this.player;\n var vjsTechEl = player.el().querySelector('.vjs-tech');\n var responseTimeout = this.settings.responseTimeout || this.options.responseTimeout;\n tech.loadAdUnit(this.containerEl, vjsTechEl, function (error, adUnit) {\n if (error) {\n return next(error, adUnit, vastResponse);\n }\n\n try {\n var WrappedAdUnit = that._createVPAIDAdUnitWrapper(adUnit, tech.mediaFile.src, responseTimeout);\n var techClass = 'vjs-' + tech.name + '-ad';\n dom.addClass(player.el(), techClass);\n player.one('vpaid.adEnd', function() {\n dom.removeClass(player.el(),techClass);\n });\n next(null, WrappedAdUnit, vastResponse);\n } catch (e) {\n next(e, adUnit, vastResponse);\n }\n });\n};\n\nVPAIDIntegrator.prototype._playAdUnit = function (adUnit, vastResponse, callback) {\n async.waterfall([\n function (next) {\n next(null, adUnit, vastResponse);\n },\n this._handshake.bind(this),\n this._initAd.bind(this),\n this._setupEvents.bind(this),\n this._addSkipButton.bind(this),\n this._linkPlayerControls.bind(this),\n this._startAd.bind(this)\n ], callback);\n};\n\nVPAIDIntegrator.prototype._handshake = function handshake(adUnit, vastResponse, next) {\n adUnit.handshakeVersion(this.options.VPAID_VERSION, function (error, version) {\n if (error) {\n return next(error, adUnit, vastResponse);\n }\n\n if (version && isSupportedVersion(version)) {\n return next(null, adUnit, vastResponse);\n }\n\n return next(new VASTError('on VPAIDIntegrator._handshake, unsupported version \"' + version + '\"'), adUnit, vastResponse);\n });\n\n function isSupportedVersion(version) {\n var majorNum = major(version);\n return majorNum >= 1 && majorNum <= 2;\n }\n\n function major(version) {\n var parts = version.split('.');\n return parseInt(parts[0], 10);\n }\n};\n\nVPAIDIntegrator.prototype._initAd = function (adUnit, vastResponse, next) {\n var tech = this.player.el().querySelector('.vjs-tech');\n var dimension = dom.getDimension(tech);\n adUnit.initAd(dimension.width, dimension.height, this.VIEW_MODE.NORMAL, -1, {AdParameters: vastResponse.adParameters || ''}, function (error) {\n next(error, adUnit, vastResponse);\n });\n};\n\nVPAIDIntegrator.prototype._createVASTTracker = function(adUnitSrc, vastResponse) {\n return new VASTTracker(adUnitSrc, vastResponse);\n};\n\nVPAIDIntegrator.prototype._setupEvents = function (adUnit, vastResponse, next) {\n var adUnitSrc = adUnit.options.src;\n var tracker = this._createVASTTracker(adUnitSrc, vastResponse);\n var player = this.player;\n var that = this;\n\n adUnit.on('AdSkipped', function () {\n player.trigger('vpaid.AdSkipped');\n tracker.trackSkip();\n });\n\n adUnit.on('AdImpression', function () {\n player.trigger('vpaid.AdImpression');\n tracker.trackImpressions();\n });\n\n adUnit.on('AdStarted', function () {\n player.trigger('vpaid.AdStarted');\n tracker.trackCreativeView();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdVideoStart', function () {\n player.trigger('vpaid.AdVideoStart');\n tracker.trackStart();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdPlaying', function () {\n player.trigger('vpaid.AdPlaying');\n tracker.trackResume();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdPaused', function () {\n player.trigger('vpaid.AdPaused');\n tracker.trackPause();\n notifyPauseToPlayer();\n });\n\n function notifyPlayToPlayer(){\n if(that._adUnit && that._adUnit.isPaused()){\n that._adUnit._paused = false;\n }\n player.trigger('play');\n\n }\n\n function notifyPauseToPlayer() {\n if(that._adUnit){\n that._adUnit._paused = true;\n }\n player.trigger('pause');\n }\n\n adUnit.on('AdVideoFirstQuartile', function () {\n player.trigger('vpaid.AdVideoFirstQuartile');\n tracker.trackFirstQuartile();\n });\n\n adUnit.on('AdVideoMidpoint', function () {\n player.trigger('vpaid.AdVideoMidpoint');\n tracker.trackMidpoint();\n });\n\n adUnit.on('AdVideoThirdQuartile', function () {\n player.trigger('vpaid.AdVideoThirdQuartile');\n tracker.trackThirdQuartile();\n });\n\n adUnit.on('AdVideoComplete', function () {\n player.trigger('vpaid.AdVideoComplete');\n tracker.trackComplete();\n });\n\n adUnit.on('AdClickThru', function (data) {\n player.trigger('vpaid.AdClickThru');\n var url = data.url;\n var playerHandles = data.playerHandles;\n var clickThruUrl = utilities.isNotEmptyString(url) ? url : generateClickThroughURL(vastResponse.clickThrough);\n\n tracker.trackClick();\n if (playerHandles && clickThruUrl) {\n window.open(clickThruUrl, '_blank');\n }\n\n function generateClickThroughURL(clickThroughMacro) {\n var variables = {\n ASSETURI: adUnit.options.src,\n CONTENTPLAYHEAD: 0 //In VPAID there is no method to know the current time from the adUnit\n };\n\n return clickThroughMacro ? vastUtil.parseURLMacro(clickThroughMacro, variables) : null;\n }\n });\n\n adUnit.on('AdUserAcceptInvitation', function () {\n player.trigger('vpaid.AdUserAcceptInvitation');\n tracker.trackAcceptInvitation();\n tracker.trackAcceptInvitationLinear();\n });\n\n adUnit.on('AdUserClose', function () {\n player.trigger('vpaid.AdUserClose');\n tracker.trackClose();\n tracker.trackCloseLinear();\n });\n\n adUnit.on('AdUserMinimize', function () {\n player.trigger('vpaid.AdUserMinimize');\n tracker.trackCollapse();\n });\n\n adUnit.on('AdError', function () {\n player.trigger('vpaid.AdError');\n //NOTE: we track errors code 901, as noted in VAST 3.0\n tracker.trackErrorWithCode(901);\n });\n\n adUnit.on('AdVolumeChange', function () {\n player.trigger('vpaid.AdVolumeChange');\n var lastVolume = player.volume();\n adUnit.getAdVolume(function (error, currentVolume) {\n if (currentVolume === 0 && lastVolume > 0) {\n tracker.trackMute();\n }\n\n if (currentVolume > 0 && lastVolume === 0) {\n tracker.trackUnmute();\n }\n\n player.volume(currentVolume);\n });\n });\n\n var updateViewSize = resizeAd.bind(this, player, adUnit, this.VIEW_MODE);\n var updateViewSizeThrottled = utilities.throttle(updateViewSize, 100);\n var autoResize = this.settings.autoResize;\n\n if (autoResize) {\n dom.addEventListener(window, 'resize', updateViewSizeThrottled);\n dom.addEventListener(window, 'orientationchange', updateViewSizeThrottled);\n }\n\n player.on('vast.resize', updateViewSize);\n player.on('vpaid.pauseAd', pauseAdUnit);\n player.on('vpaid.resumeAd', resumeAdUnit);\n\n player.one('vpaid.adEnd', function () {\n player.off('vast.resize', updateViewSize);\n player.off('vpaid.pauseAd', pauseAdUnit);\n player.off('vpaid.resumeAd', resumeAdUnit);\n\n if (autoResize) {\n dom.removeEventListener(window, 'resize', updateViewSizeThrottled);\n dom.removeEventListener(window, 'orientationchange', updateViewSizeThrottled);\n }\n });\n\n next(null, adUnit, vastResponse);\n\n /*** Local Functions ***/\n function pauseAdUnit() {\n adUnit.pauseAd(utilities.noop);\n }\n\n function resumeAdUnit() {\n adUnit.resumeAd(utilities.noop);\n }\n};\n\nVPAIDIntegrator.prototype._addSkipButton = function (adUnit, vastResponse, next) {\n var skipButton;\n var player = this.player;\n\n adUnit.on('AdSkippableStateChange', updateSkipButtonState);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeSkipButton);\n\n next(null, adUnit, vastResponse);\n\n /*** Local function ***/\n function updateSkipButtonState() {\n player.trigger('vpaid.AdSkippableStateChange');\n adUnit.getAdSkippableState(function (error, isSkippable) {\n if (isSkippable) {\n if (!skipButton) {\n addSkipButton(player);\n }\n } else {\n removeSkipButton(player);\n }\n });\n }\n\n function addSkipButton(player) {\n skipButton = createSkipButton(player);\n player.el().appendChild(skipButton);\n }\n\n function removeSkipButton() {\n dom.remove(skipButton);\n skipButton = null;\n }\n\n function createSkipButton() {\n var skipButton = window.document.createElement(\"div\");\n dom.addClass(skipButton, \"vast-skip-button\");\n dom.addClass(skipButton, \"enabled\");\n skipButton.innerHTML = \"Skip ad\";\n\n skipButton.onclick = function (e) {\n adUnit.skipAd(utilities.noop);//We skip the adUnit\n\n //We prevent event propagation to avoid problems with the clickThrough and so on\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n } else {\n return false;\n }\n };\n\n return skipButton;\n }\n};\n\nVPAIDIntegrator.prototype._linkPlayerControls = function (adUnit, vastResponse, next) {\n var that = this;\n linkVolumeControl(this.player, adUnit);\n linkFullScreenControl(this.player, adUnit, this.VIEW_MODE);\n\n next(null, adUnit, vastResponse);\n\n /*** Local functions ***/\n function linkVolumeControl(player, adUnit) {\n player.on('volumechange', updateAdUnitVolume);\n adUnit.on('AdVolumeChange', updatePlayerVolume);\n\n player.one('vpaid.adEnd', function () {\n player.off('volumechange', updateAdUnitVolume);\n });\n\n\n /*** local functions ***/\n function updateAdUnitVolume() {\n var vol = player.muted() ? 0 : player.volume();\n adUnit.setAdVolume(vol, logError);\n }\n\n function updatePlayerVolume() {\n player.trigger('vpaid.AdVolumeChange');\n adUnit.getAdVolume(function (error, vol) {\n if (error) {\n logError(error);\n } else {\n player.volume(vol);\n }\n });\n }\n }\n\n function linkFullScreenControl(player, adUnit, VIEW_MODE) {\n var updateViewSize = resizeAd.bind(that, player, adUnit, VIEW_MODE);\n\n player.on('fullscreenchange', updateViewSize);\n\n player.one('vpaid.adEnd', function () {\n player.off('fullscreenchange', updateViewSize);\n });\n }\n};\n\nVPAIDIntegrator.prototype._startAd = function (adUnit, vastResponse, next) {\n var player = this.player;\n\n adUnit.startAd(function (error) {\n if (!error) {\n player.trigger('vast.adStart');\n }\n next(error, adUnit, vastResponse);\n });\n};\n\nVPAIDIntegrator.prototype._finishPlaying = function (adUnit, vastResponse, next) {\n var player = this.player;\n adUnit.on('AdStopped', function () {\n player.trigger('vpaid.AdStopped');\n finishPlayingAd(null);\n });\n\n adUnit.on('AdError', function (error) {\n var errMsg = error? error.message : 'on VPAIDIntegrator, error while waiting for the adUnit to finish playing';\n finishPlayingAd(new VASTError(errMsg));\n });\n\n /*** local functions ***/\n function finishPlayingAd(error) {\n next(error, adUnit, vastResponse);\n }\n};\n\nVPAIDIntegrator.prototype._trackError = function trackError(response) {\n vastUtil.track(response.errorURLMacros, {ERRORCODE: 901});\n};\n\nfunction resizeAd(player, adUnit, VIEW_MODE) {\n var tech = player.el().querySelector('.vjs-tech');\n var dimension = dom.getDimension(tech);\n var MODE = player.isFullscreen() ? VIEW_MODE.FULLSCREEN : VIEW_MODE.NORMAL;\n adUnit.resizeAd(dimension.width, dimension.height, MODE, logError);\n}\n\nfunction logError(error) {\n if (error && console && console.log) {\n console.log('ERROR: ' + error.message, error);\n }\n}\n\nmodule.exports = VPAIDIntegrator;\n},{\"../../utils/async\":38,\"../../utils/dom\":39,\"../../utils/playerUtils\":41,\"../../utils/utilityFunctions\":43,\"../vast/VASTError\":21,\"../vast/VASTResponse\":23,\"../vast/VASTTracker\":24,\"../vast/vastUtil\":28,\"./VPAIDAdUnitWrapper\":29,\"./VPAIDFlashTech\":30,\"./VPAIDHTML5Tech\":31}],33:[function(require,module,exports){\n'use strict';\n\nvar dom = require('../../utils/dom');\n\nvar element = document.createElement('div');\nelement.className = 'vjs-ads-label vjs-control vjs-label-hidden';\nelement.innerHTML = 'Advertisement';\n\nvar AdsLabelFactory = function(baseComponent) {\n return {\n /** @constructor */\n init: function init(player, options) {\n options.el = element;\n baseComponent.call(this, player, options);\n\n // We asynchronously reposition the ads label element\n setTimeout(function () {\n var currentTimeComp = player.controlBar &&( player.controlBar.getChild(\"timerControls\") || player.controlBar.getChild(\"currentTimeDisplay\") );\n if(currentTimeComp) {\n player.controlBar.el().insertBefore(element, currentTimeComp.el());\n }\n dom.removeClass(element, 'vjs-label-hidden');\n }, 0);\n },\n\n el: function getElement() {\n return element;\n }\n };\n};\n\nmodule.exports = AdsLabelFactory;\n},{\"../../utils/dom\":39}],34:[function(require,module,exports){\n'use strict';\n\nvar baseVideoJsComponent = videojs.getComponent('Component');\n\nvar AdsLabel = require('./ads-label')(baseVideoJsComponent);\n\nvideojs.registerComponent('AdsLabel', videojs.extend(baseVideoJsComponent, AdsLabel));\n\n},{\"./ads-label\":33}],35:[function(require,module,exports){\n'use strict';\n\n/**\n * The component that shows a black screen until the ads plugin has decided if it can or it can not play the ad.\n *\n * Note: In case you wonder why instead of this black poster we don't just show the spinner loader.\n * IOS devices do not work well with animations and the browser chrashes from time to time That is why we chose to\n * have a secondary black poster.\n *\n * It also makes it much more easier for the users of the plugin since it does not change the default behaviour of the\n * spinner and the player works the same way with and without the plugin.\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvar element = document.createElement('div');\n\nvar BlackPosterFactory = function(baseComponent) {\n return {\n /** @constructor */\n init: function init(player, options) {\n options.el = element;\n element.className = 'vjs-black-poster';\n baseComponent.call(this, player, options);\n\n var posterImg = player.getChild('posterImage');\n\n //We need to do it asynchronously to be sure that the black poster el is on the dom.\n setTimeout(function() {\n if(posterImg && player && player.el()) {\n player.el().insertBefore(element, posterImg.el());\n }\n }, 0);\n },\n el: function getElement() {\n return element;\n }\n };\n};\n\nmodule.exports = BlackPosterFactory;\n},{}],36:[function(require,module,exports){\n'use strict';\n\nvar baseVideoJsComponent = videojs.getComponent('Component');\n\nvar BlackPoster = require('./black-poster')(baseVideoJsComponent);\n\nvideojs.registerComponent('BlackPoster', videojs.extend(baseVideoJsComponent, BlackPoster));\n\n},{\"./black-poster\":35}],37:[function(require,module,exports){\n'use strict';\n\nvar VASTClient = require('../ads/vast/VASTClient');\nvar VASTError = require('../ads/vast/VASTError');\nvar vastUtil = require('../ads/vast/vastUtil');\n\nvar VASTIntegrator = require('../ads/vast/VASTIntegrator');\nvar VPAIDIntegrator = require('../ads/vpaid/VPAIDIntegrator');\n\nvar async = require('../utils/async');\nvar dom = require('../utils/dom');\nvar playerUtils = require('../utils/playerUtils');\nvar utilities = require('../utils/utilityFunctions');\n\nmodule.exports = function VASTPlugin(options) {\n var snapshot;\n var player = this;\n var vast = new VASTClient();\n var adsCanceled = false;\n var defaultOpts = {\n // maximum amount of time in ms to wait to receive `adsready` from the ad\n // implementation after play has been requested. Ad implementations are\n // expected to load any dynamic libraries and make any requests to determine\n // ad policies for a video during this time.\n timeout: 500,\n\n //TODO:finish this IOS FIX\n //Whenever you play an add on IOS, the native player kicks in and we loose control of it. On very heavy pages the 'play' event\n // May occur after the video content has already started. This is wrong if you want to play a preroll ad that needs to happen before the user\n // starts watching the content. To prevent this usec\n iosPrerollCancelTimeout: 2000,\n\n // maximun amount of time for the ad to actually start playing. If this timeout gets\n // triggered the ads will be cancelled\n adCancelTimeout: 3000,\n\n // Boolean flag that configures the player to play a new ad before the user sees the video again\n // the current video\n playAdAlways: false,\n\n // Flag to enable or disable the ads by default.\n adsEnabled: true,\n\n // Boolean flag to enable or disable the resize with window.resize or orientationchange\n autoResize: true,\n\n // Path to the VPAID flash ad's loader\n vpaidFlashLoaderPath: '/VPAIDFlash.swf'\n };\n\n var settings = utilities.extend({}, defaultOpts, options || {});\n\n if(utilities.isUndefined(settings.adTagUrl) && utilities.isDefined(settings.url)){\n settings.adTagUrl = settings.url;\n }\n\n if (utilities.isString(settings.adTagUrl)) {\n settings.adTagUrl = utilities.echoFn(settings.adTagUrl);\n }\n\n if (utilities.isDefined(settings.adTagXML) && !utilities.isFunction(settings.adTagXML)) {\n return trackAdError(new VASTError('on VideoJS VAST plugin, the passed adTagXML option does not contain a function'));\n }\n\n if (!utilities.isDefined(settings.adTagUrl) && !utilities.isFunction(settings.adTagXML)) {\n return trackAdError(new VASTError('on VideoJS VAST plugin, missing adTagUrl on options object'));\n }\n\n playerUtils.prepareForAds(player);\n\n if (settings.playAdAlways) {\n // No matter what happens we play a new ad before the user sees the video again.\n player.on('vast.contentEnd', function () {\n setTimeout(function () {\n player.trigger('vast.reset');\n }, 0);\n });\n }\n\n player.on('vast.firstPlay', tryToPlayPrerollAd);\n\n player.on('vast.reset', function () {\n //If we are reseting the plugin, we don't want to restore the content\n snapshot = null;\n cancelAds();\n });\n\n player.vast = {\n isEnabled: function () {\n return settings.adsEnabled;\n },\n\n enable: function () {\n settings.adsEnabled = true;\n },\n\n disable: function () {\n settings.adsEnabled = false;\n }\n };\n\n return player.vast;\n\n /**** Local functions ****/\n function tryToPlayPrerollAd() {\n //We remove the poster to prevent flickering whenever the content starts playing\n playerUtils.removeNativePoster(player);\n\n playerUtils.once(player, ['vast.adsCancel', 'vast.adEnd'], function () {\n removeAdUnit();\n restoreVideoContent();\n });\n\n async.waterfall([\n checkAdsEnabled,\n preparePlayerForAd,\n startAdCancelTimeout,\n playPrerollAd\n ], function (error, response) {\n if (error) {\n trackAdError(error, response);\n } else {\n player.trigger('vast.adEnd');\n }\n });\n\n /*** Local functions ***/\n\n function removeAdUnit() {\n if (player.vast && player.vast.adUnit) {\n player.vast.adUnit = null; //We remove the adUnit\n }\n }\n\n function restoreVideoContent() {\n setupContentEvents();\n if (snapshot) {\n playerUtils.restorePlayerSnapshot(player, snapshot);\n snapshot = null;\n }\n }\n\n function setupContentEvents() {\n playerUtils.once(player, ['playing', 'vast.reset', 'vast.firstPlay'], function (evt) {\n if (evt.type !== 'playing') {\n return;\n }\n\n player.trigger('vast.contentStart');\n\n playerUtils.once(player, ['ended', 'vast.reset', 'vast.firstPlay'], function (evt) {\n if (evt.type === 'ended') {\n player.trigger('vast.contentEnd');\n }\n });\n });\n }\n\n function checkAdsEnabled(next) {\n if (settings.adsEnabled) {\n return next(null);\n }\n next(new VASTError('Ads are not enabled'));\n }\n\n function preparePlayerForAd(next) {\n if (canPlayPrerollAd()) {\n snapshot = playerUtils.getPlayerSnapshot(player);\n player.pause();\n addSpinnerIcon();\n\n if(player.paused()) {\n next(null);\n } else {\n playerUtils.once(player, ['playing'], function() {\n player.pause();\n next(null);\n });\n }\n } else {\n next(new VASTError('video content has been playing before preroll ad'));\n }\n }\n\n function canPlayPrerollAd() {\n return !utilities.isIPhone() || player.currentTime() <= settings.iosPrerollCancelTimeout;\n }\n\n function startAdCancelTimeout(next) {\n var adCancelTimeoutId;\n adsCanceled = false;\n\n adCancelTimeoutId = setTimeout(function () {\n trackAdError(new VASTError('timeout while waiting for the video to start playing', 402));\n }, settings.adCancelTimeout);\n\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], clearAdCancelTimeout);\n\n /*** local functions ***/\n function clearAdCancelTimeout() {\n if (adCancelTimeoutId) {\n clearTimeout(adCancelTimeoutId);\n adCancelTimeoutId = null;\n }\n }\n\n next(null);\n }\n\n function addSpinnerIcon() {\n dom.addClass(player.el(), 'vjs-vast-ad-loading');\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], removeSpinnerIcon);\n }\n\n function removeSpinnerIcon() {\n //IMPORTANT NOTE: We remove the spinnerIcon asynchronously to give time to the browser to start the video.\n // If we remove it synchronously we see a flash of the content video before the ad starts playing.\n setTimeout(function () {\n dom.removeClass(player.el(), 'vjs-vast-ad-loading');\n }, 100);\n }\n\n }\n\n function cancelAds() {\n player.trigger('vast.adsCancel');\n adsCanceled = true;\n }\n\n function playPrerollAd(callback) {\n async.waterfall([\n getVastResponse,\n playAd\n ], callback);\n }\n\n function getVastResponse(callback) {\n vast.getVASTResponse(settings.adTagUrl ? settings.adTagUrl() : settings.adTagXML, callback);\n }\n\n function playAd(vastResponse, callback) {\n //TODO: Find a better way to stop the play. The 'playPrerollWaterfall' ends in an inconsistent situation\n //If the state is not 'preroll?' it means the ads were canceled therefore, we break the waterfall\n if (adsCanceled) {\n return;\n }\n\n var adIntegrator = isVPAID(vastResponse) ? new VPAIDIntegrator(player, settings) : new VASTIntegrator(player);\n var adFinished = false;\n\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], function (evt) {\n if (evt.type === 'vast.adStart') {\n addAdsLabel();\n }\n });\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeAdsLabel);\n\n if (utilities.isIDevice()) {\n preventManualProgress();\n }\n\n player.vast.vastResponse = vastResponse;\n player.vast.adUnit = adIntegrator.playAd(vastResponse, callback);\n\n /*** Local functions ****/\n function addAdsLabel() {\n if (adFinished || player.controlBar.getChild('AdsLabel')) {\n return;\n }\n\n player.controlBar.addChild('AdsLabel');\n }\n\n function removeAdsLabel() {\n player.controlBar.removeChild('AdsLabel');\n adFinished = true;\n }\n\n function preventManualProgress() {\n //IOS video clock is very unreliable and we need a 3 seconds threshold to ensure that the user forwarded/rewound the ad\n var PROGRESS_THRESHOLD = 3;\n var previousTime = 0;\n var skipad_attempts = 0;\n\n player.on('timeupdate', adTimeupdateHandler);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel', 'vast.adError'], stopPreventManualProgress);\n\n /*** Local functions ***/\n function adTimeupdateHandler() {\n var currentTime = player.currentTime();\n var progressDelta = Math.abs(currentTime - previousTime);\n\n if (progressDelta > PROGRESS_THRESHOLD) {\n skipad_attempts += 1;\n if (skipad_attempts >= 2) {\n player.pause();\n }\n player.currentTime(previousTime);\n } else {\n previousTime = currentTime;\n }\n }\n\n function stopPreventManualProgress() {\n player.off('timeupdate', adTimeupdateHandler);\n }\n }\n }\n\n function trackAdError(error, vastResponse) {\n player.trigger({type: 'vast.adError', error: error});\n cancelAds();\n if (console && console.log) {\n console.log('AD ERROR:', error.message, error, vastResponse);\n }\n }\n\n function isVPAID(vastResponse) {\n var i, len;\n var mediaFiles = vastResponse.mediaFiles;\n for (i = 0, len = mediaFiles.length; i < len; i++) {\n if (vastUtil.isVPAID(mediaFiles[i])) {\n return true;\n }\n }\n return false;\n }\n};\n},{\"../ads/vast/VASTClient\":20,\"../ads/vast/VASTError\":21,\"../ads/vast/VASTIntegrator\":22,\"../ads/vast/vastUtil\":28,\"../ads/vpaid/VPAIDIntegrator\":32,\"../utils/async\":38,\"../utils/dom\":39,\"../utils/playerUtils\":41,\"../utils/utilityFunctions\":43}],38:[function(require,module,exports){\n//Small subset of async\n\nvar utilities = require('./utilityFunctions');\n\nvar async = {};\n\nasync.setImmediate = function (fn) {\n setTimeout(fn, 0);\n};\n\nasync.iterator = function (tasks) {\n var makeCallback = function (index) {\n var fn = function () {\n if (tasks.length) {\n tasks[index].apply(null, arguments);\n }\n return fn.next();\n };\n fn.next = function () {\n return (index < tasks.length - 1) ? makeCallback(index + 1) : null;\n };\n return fn;\n };\n return makeCallback(0);\n};\n\n\nasync.waterfall = function (tasks, callback) {\n callback = callback || function () { };\n if (!utilities.isArray(tasks)) {\n var err = new Error('First argument to waterfall must be an array of functions');\n return callback(err);\n }\n if (!tasks.length) {\n return callback();\n }\n var wrapIterator = function (iterator) {\n return function (err) {\n if (err) {\n callback.apply(null, arguments);\n callback = function () {\n };\n }\n else {\n var args = Array.prototype.slice.call(arguments, 1);\n var next = iterator.next();\n if (next) {\n args.push(wrapIterator(next));\n }\n else {\n args.push(callback);\n }\n async.setImmediate(function () {\n iterator.apply(null, args);\n });\n }\n };\n };\n wrapIterator(async.iterator(tasks))();\n};\n\nasync.when = function (condition, callback) {\n if (!utilities.isFunction(callback)) {\n throw new Error(\"async.when error: missing callback argument\");\n }\n\n var isAllowed = utilities.isFunction(condition) ? condition : function () {\n return !!condition;\n };\n\n return function () {\n var args = utilities.arrayLikeObjToArray(arguments);\n var next = args.pop();\n\n if (isAllowed.apply(null, args)) {\n return callback.apply(this, arguments);\n }\n\n args.unshift(null);\n return next.apply(null, args);\n };\n};\n\nmodule.exports = async;\n\n\n},{\"./utilityFunctions\":43}],39:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('./utilityFunctions');\n\nvar dom = {};\n\ndom.isVisible = function isVisible(el) {\n var style = window.getComputedStyle(el);\n return style.visibility !== 'hidden';\n};\n\ndom.isHidden = function isHidden(el) {\n var style = window.getComputedStyle(el);\n return style.display === 'none';\n};\n\ndom.isShown = function isShown(el) {\n return !dom.isHidden(el);\n};\n\ndom.hide = function hide(el) {\n el.__prev_style_display_ = el.style.display;\n el.style.display = 'none';\n};\n\ndom.show = function show(el) {\n if (dom.isHidden(el)) {\n el.style.display = el.__prev_style_display_;\n }\n el.__prev_style_display_ = undefined;\n};\n\ndom.hasClass = function hasClass(el, cssClass) {\n var classes, i, len;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.contains(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n cssClass = (cssClass || '');\n\n for (i = 0, len = classes.length; i < len; i += 1) {\n if (classes[i] === cssClass) {\n return true;\n }\n }\n }\n return false;\n};\n\ndom.addClass = function (el, cssClass) {\n var classes;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.add(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n if (utilities.isString(cssClass) && utilities.isNotEmptyString(cssClass.replace(/\\s+/, ''))) {\n classes.push(cssClass);\n el.setAttribute('class', classes.join(' '));\n }\n }\n};\n\ndom.removeClass = function (el, cssClass) {\n var classes;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.remove(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n var newClasses = [];\n var i, len;\n if (utilities.isString(cssClass) && utilities.isNotEmptyString(cssClass.replace(/\\s+/, ''))) {\n\n for (i = 0, len = classes.length; i < len; i += 1) {\n if (cssClass !== classes[i]) {\n newClasses.push(classes[i]);\n }\n }\n el.setAttribute('class', newClasses.join(' '));\n }\n }\n};\n\ndom.addEventListener = function addEventListener(el, type, handler) {\n if(utilities.isArray(el)){\n utilities.forEach(el, function(e) {\n dom.addEventListener(e, type, handler);\n });\n return;\n }\n\n if(utilities.isArray(type)){\n utilities.forEach(type, function(t) {\n dom.addEventListener(el, t, handler);\n });\n return;\n }\n\n if (el.addEventListener) {\n el.addEventListener(type, handler, false);\n } else if (el.attachEvent) {\n // WARNING!!! this is a very naive implementation !\n // the event object that should be passed to the handler\n // would not be there for IE8\n // we should use \"window.event\" and then \"event.srcElement\"\n // instead of \"event.target\"\n el.attachEvent(\"on\" + type, handler);\n }\n};\n\ndom.removeEventListener = function removeEventListener(el, type, handler) {\n if(utilities.isArray(el)){\n utilities.forEach(el, function(e) {\n dom.removeEventListener(e, type, handler);\n });\n return;\n }\n\n if(utilities.isArray(type)){\n utilities.forEach(type, function(t) {\n dom.removeEventListener(el, t, handler);\n });\n return;\n }\n\n if (el.removeEventListener) {\n el.removeEventListener(type, handler, false);\n } else if (el.detachEvent) {\n el.detachEvent(\"on\" + type, handler);\n } else {\n el[\"on\" + type] = null;\n }\n};\n\ndom.dispatchEvent = function dispatchEvent(el, event) {\n if (el.dispatchEvent) {\n el.dispatchEvent(event);\n } else {\n el.fireEvent(\"on\" + event.eventType, event);\n }\n};\n\ndom.isDescendant = function isDescendant(parent, child) {\n var node = child.parentNode;\n while (node !== null) {\n if (node === parent) {\n return true;\n }\n node = node.parentNode;\n }\n return false;\n};\n\ndom.getTextContent = function getTextContent(el){\n return el.textContent || el.text;\n};\n\ndom.prependChild = function prependChild(parent, child) {\n if(child.parentNode){\n child.parentNode.removeChild(child);\n }\n return parent.insertBefore(child, parent.firstChild);\n};\n\ndom.remove = function removeNode(node){\n if(node && node.parentNode){\n node.parentNode.removeChild(node);\n }\n};\n\ndom.isDomElement = function isDomElement(o) {\n return o instanceof Element;\n};\n\ndom.click = function(el, handler) {\n dom.addEventListener(el, 'click', handler);\n};\n\ndom.once = function(el, type, handler) {\n function handlerWrap() {\n handler.apply(null, arguments);\n dom.removeEventListener(el, type, handlerWrap);\n }\n\n dom.addEventListener(el, type, handlerWrap);\n};\n\n//Note: there is no getBoundingClientRect on iPad so we need a fallback\ndom.getDimension = function getDimension(element) {\n var rect;\n\n //On IE9 and below getBoundingClientRect does not work consistently\n if(!utilities.isOldIE() && element.getBoundingClientRect) {\n rect = element.getBoundingClientRect();\n return {\n width: rect.width,\n height: rect.height\n };\n }\n\n return {\n width: element.offsetWidth,\n height: element.offsetHeight\n };\n};\n\nmodule.exports = dom;\n},{\"./utilityFunctions\":43}],40:[function(require,module,exports){\n'use strict';\n\nvar urlUtils = require('./urlUtils');\nvar utilities = require('./utilityFunctions');\n\nfunction HttpRequestError(message) {\n this.message = 'HttpRequest Error: ' + (message || '');\n}\nHttpRequestError.prototype = new Error();\nHttpRequestError.prototype.name = \"HttpRequest Error\";\n\nfunction HttpRequest(createXhr) {\n if (!utilities.isFunction(createXhr)) {\n throw new HttpRequestError('Missing XMLHttpRequest factory method');\n }\n\n this.createXhr = createXhr;\n}\n\nHttpRequest.prototype.run = function (method, url, callback, options) {\n sanityCheck(url, callback, options);\n var timeout, timeoutId;\n var xhr = this.createXhr();\n options = options || {};\n timeout = utilities.isNumber(options.timeout) ? options.timeout : 0;\n\n xhr.open(method, urlUtils.urlParts(url).href, true);\n\n if (options.headers) {\n setHeaders(xhr, options.headers);\n }\n\n if (options.withCredentials) {\n xhr.withCredentials = true;\n }\n\n xhr.onload = function () {\n var statusText, response, status;\n\n /**\n * The only way to do a secure request on IE8 and IE9 is with the XDomainRequest object. Unfortunately, microsoft is\n * so nice that decided that the status property and the 'getAllResponseHeaders' method where not needed so we have to\n * fake them. If the request gets done with an XDomainRequest instance, we will assume that there are no headers and\n * the status will always be 200. If you don't like it, DO NOT USE ANCIENT BROWSERS!!!\n *\n * For mor info go to: https://msdn.microsoft.com/en-us/library/cc288060(v=vs.85).aspx\n */\n if (!xhr.getAllResponseHeaders) {\n xhr.getAllResponseHeaders = function () {\n return null;\n };\n }\n\n if (!xhr.status) {\n xhr.status = 200;\n }\n\n if (utilities.isDefined(timeoutId)) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n\n statusText = xhr.statusText || '';\n\n // responseText is the old-school way of retrieving response (supported by IE8 & 9)\n // response/responseType properties were introduced in XHR Level2 spec (supported by IE10)\n response = ('response' in xhr) ? xhr.response : xhr.responseText;\n\n // normalize IE9 bug (http://bugs.jquery.com/ticket/1450)\n status = xhr.status === 1223 ? 204 : xhr.status;\n\n callback(\n status,\n response,\n xhr.getAllResponseHeaders(),\n statusText);\n };\n\n xhr.onerror = requestError;\n xhr.onabort = requestError;\n\n xhr.send();\n\n if (timeout > 0) {\n timeoutId = setTimeout(function () {\n xhr && xhr.abort();\n }, timeout);\n }\n\n function sanityCheck(url, callback, options) {\n if (!utilities.isString(url) || utilities.isEmptyString(url)) {\n throw new HttpRequestError(\"Invalid url '\" + url + \"'\");\n }\n\n if (!utilities.isFunction(callback)) {\n throw new HttpRequestError(\"Invalid handler '\" + callback + \"' for the http request\");\n }\n\n if (utilities.isDefined(options) && !utilities.isObject(options)) {\n throw new HttpRequestError(\"Invalid options map '\" + options + \"'\");\n }\n }\n\n function setHeaders(xhr, headers) {\n utilities.forEach(headers, function (value, key) {\n if (utilities.isDefined(value)) {\n xhr.setRequestHeader(key, value);\n }\n });\n }\n\n function requestError() {\n callback(-1, null, null, '');\n }\n};\n\nHttpRequest.prototype.get = function (url, callback, options) {\n this.run('GET', url, processResponse, options);\n\n function processResponse(status, response, headersString, statusText) {\n if (isSuccess(status)) {\n callback(null, response, status, headersString, statusText);\n } else {\n callback(new HttpRequestError(statusText), response, status, headersString, statusText);\n }\n }\n\n function isSuccess(status) {\n return 200 <= status && status < 300;\n }\n};\n\nfunction createXhr() {\n var xhr = new XMLHttpRequest();\n if (!(\"withCredentials\" in xhr)) {\n // XDomainRequest for IE.\n xhr = new XDomainRequest();\n }\n return xhr;\n}\n\nvar http = new HttpRequest(createXhr);\n\nmodule.exports = {\n http: http,\n HttpRequest: HttpRequest,\n HttpRequestError: HttpRequestError,\n createXhr: createXhr\n};\n\n},{\"./urlUtils\":42,\"./utilityFunctions\":43}],41:[function(require,module,exports){\n'use strict';\n\nvar dom = require('./dom');\nvar utilities = require('./utilityFunctions');\n\nvar playerUtils = {};\n\n/**\n * Returns an object that captures the portions of player state relevant to\n * video playback. The result of this function can be passed to\n * restorePlayerSnapshot with a player to return the player to the state it\n * was in when this function was invoked.\n * @param {object} player The videojs player object\n */\nplayerUtils.getPlayerSnapshot = function getPlayerSnapshot(player) {\n var tech = player.el().querySelector('.vjs-tech');\n\n var snapshot = {\n ended: player.ended(),\n src: player.currentSrc(),\n currentTime: player.currentTime(),\n type: player.currentType(),\n playing: !player.paused(),\n suppressedTracks: getSuppressedTracks(player)\n };\n\n if (tech) {\n snapshot.nativePoster = tech.poster;\n snapshot.style = tech.getAttribute('style');\n }\n return snapshot;\n\n /**** Local Functions ****/\n function getSuppressedTracks(player) {\n var tracks = player.remoteTextTracks ? player.remoteTextTracks() : [];\n\n if (tracks && utilities.isArray(tracks.tracks_)) {\n tracks = tracks.tracks_;\n }\n\n if (!utilities.isArray(tracks)) {\n tracks = [];\n }\n\n var suppressedTracks = [];\n tracks.forEach(function (track) {\n suppressedTracks.push({\n track: track,\n mode: track.mode\n });\n track.mode = 'disabled';\n });\n\n return suppressedTracks;\n }\n};\n\n/**\n * Attempts to modify the specified player so that its state is equivalent to\n * the state of the snapshot.\n * @param {object} snapshot - the player state to apply\n */\nplayerUtils.restorePlayerSnapshot = function restorePlayerSnapshot(player, snapshot) {\n var tech = player.el().querySelector('.vjs-tech');\n var attempts = 20; // the number of remaining attempts to restore the snapshot\n\n if (snapshot.nativePoster) {\n tech.poster = snapshot.nativePoster;\n }\n\n if ('style' in snapshot) {\n // overwrite all css style properties to restore state precisely\n tech.setAttribute('style', snapshot.style || '');\n }\n\n if (hasSrcChanged(player, snapshot)) {\n\n // on ios7, fiddling with textTracks too early will cause safari to crash\n player.one('contentloadedmetadata', restoreTracks);\n\n player.one('canplay', tryToResume);\n ensureCanplayEvtGetsFired();\n\n // if the src changed for ad playback, reset it\n player.src({src: snapshot.src, type: snapshot.type});\n\n // safari requires a call to `load` to pick up a changed source\n player.load();\n\n } else {\n restoreTracks();\n\n if (snapshot.playing) {\n player.play();\n }\n }\n\n /*** Local Functions ***/\n\n /**\n * Sometimes firefox does not trigger the 'canplay' evt.\n * This code ensure that it always gets triggered triggered.\n */\n function ensureCanplayEvtGetsFired() {\n var timeoutId = setTimeout(function() {\n player.trigger('canplay');\n }, 1000);\n\n player.one('canplay', function(){\n clearTimeout(timeoutId);\n });\n }\n\n /**\n * Determine whether the player needs to be restored to its state\n * before ad playback began. With a custom ad display or burned-in\n * ads, the content player state hasn't been modified and so no\n * restoration is required\n */\n function hasSrcChanged(player, snapshot) {\n if (player.src()) {\n return player.src() !== snapshot.src;\n }\n // the player was configured through source element children\n return player.currentSrc() !== snapshot.src;\n }\n\n function restoreTracks() {\n var suppressedTracks = snapshot.suppressedTracks;\n suppressedTracks.forEach(function (trackSnapshot) {\n trackSnapshot.track.mode = trackSnapshot.mode;\n });\n }\n\n /**\n * Determine if the video element has loaded enough of the snapshot source\n * to be ready to apply the rest of the state\n */\n function tryToResume() {\n\n // if some period of the video is seekable, resume playback\n // otherwise delay a bit and then check again unless we're out of attempts\n\n if (!playerUtils.isReadyToResume(player) && attempts--) {\n setTimeout(tryToResume, 50);\n } else {\n try {\n if(player.currentTime() !== snapshot.currentTime) {\n if (snapshot.playing) { // if needed restore playing status after seek completes\n player.one('seeked', function() {\n player.play();\n });\n }\n player.currentTime(snapshot.currentTime);\n\n } else if (snapshot.playing) {\n // if needed and no seek has been performed, restore playing status immediately\n player.play();\n }\n\n } catch (e) {\n videojs.log.warn('Failed to resume the content after an advertisement', e);\n }\n }\n }\n};\n\nplayerUtils.isReadyToResume = function (player) {\n\n if (player.readyState() > 1) {\n // some browsers and media aren't \"seekable\".\n // readyState greater than 1 allows for seeking without exceptions\n return true;\n }\n\n if (player.seekable() === undefined) {\n // if the player doesn't expose the seekable time ranges, try to\n // resume playback immediately\n return true;\n }\n\n if (player.seekable().length > 0) {\n // if some period of the video is seekable, resume playback\n return true;\n }\n\n return false;\n};\n\n/**\n * This function prepares the player to display ads.\n * Adding convenience events like the 'vast.firsPlay' that gets fired when the video is first played\n * and ads the blackPoster to the player to prevent content from being displayed before the preroll ad.\n *\n * @param player\n */\nplayerUtils.prepareForAds = function (player) {\n var blackPoster = player.addChild('blackPoster');\n var _firstPlay = true;\n var volumeSnapshot;\n\n\n monkeyPatchPlayerApi();\n\n player.on('play', tryToTriggerFirstPlay);\n player.on('vast.reset', resetFirstPlay);//Every time we change the sources we reset the first play.\n player.on('vast.firstPlay', restoreContentVolume);\n player.on('error', hideBlackPoster);//If there is an error in the player we remove the blackposter to show the err msg\n player.on('vast.adStart', hideBlackPoster);\n player.on('vast.adsCancel', hideBlackPoster);\n player.on('vast.adError', hideBlackPoster);\n player.on('vast.adStart', addStyles);\n player.on('vast.adEnd', removeStyles);\n player.on('vast.adsCancel', removeStyles);\n\n /*** Local Functions ***/\n\n /**\n What this function does is ugly and horrible and I should think twice before calling myself a good developer. With that said,\n it is the best solution I could find to mute the video until the 'play' event happens (on mobile devices) and the plugin can decide whether\n to play the ad or not.\n\n We also need this monkeypatch to be able to pause and resume an ad using the player's API\n\n If you have a better solution please do tell me.\n */\n function monkeyPatchPlayerApi() {\n\n /**\n * Monkey patch needed to handle firstPlay and resume of playing ad.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are restoring a VAST ad.\n * @returns {player}\n */\n var origPlay = player.play;\n player.play = function (callOrigPlay) {\n var that = this;\n\n if (isFirstPlay()) {\n firstPlay();\n } else {\n resume(callOrigPlay);\n }\n\n return this;\n\n /*** local functions ***/\n function firstPlay() {\n if (!utilities.isIPhone()) {\n volumeSnapshot = saveVolumeSnapshot();\n player.muted(true);\n }\n\n origPlay.apply(that, arguments);\n }\n\n function resume(callOrigPlay) {\n if (isAdPlaying() && !callOrigPlay) {\n player.vast.adUnit.resumeAd();\n } else {\n origPlay.apply(that, arguments);\n }\n }\n };\n\n\n /**\n * Needed monkey patch to handle pause of playing ad.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are pausing a VAST ad.\n * @returns {player}\n */\n var origPause = player.pause;\n player.pause = function (callOrigPause) {\n if (isAdPlaying() && !callOrigPause) {\n player.vast.adUnit.pauseAd();\n } else {\n origPause.apply(this, arguments);\n }\n return this;\n };\n\n\n /**\n * Needed monkey patch to handle paused state of the player when ads are playing.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are pausing a VAST ad.\n * @returns {player}\n */\n var origPaused = player.paused;\n player.paused = function (callOrigPaused) {\n if (isAdPlaying() && !callOrigPaused) {\n return player.vast.adUnit.isPaused();\n }\n return origPaused.apply(this, arguments);\n };\n }\n\n function isAdPlaying() {\n return player.vast && player.vast.adUnit;\n }\n\n function tryToTriggerFirstPlay() {\n if (isFirstPlay()) {\n _firstPlay = false;\n player.trigger('vast.firstPlay');\n }\n }\n\n function resetFirstPlay() {\n _firstPlay = true;\n blackPoster.show();\n restoreContentVolume();\n }\n\n function isFirstPlay() {\n return _firstPlay;\n }\n\n function saveVolumeSnapshot() {\n return {\n muted: player.muted(),\n volume: player.volume()\n };\n }\n\n function restoreContentVolume() {\n if (volumeSnapshot) {\n player.currentTime(0);\n restoreVolumeSnapshot(volumeSnapshot);\n volumeSnapshot = null;\n }\n }\n\n function restoreVolumeSnapshot(snapshot) {\n if (utilities.isObject(snapshot)) {\n player.volume(snapshot.volume);\n player.muted(snapshot.muted);\n }\n }\n\n function hideBlackPoster() {\n if (!dom.hasClass(blackPoster.el(), 'vjs-hidden')) {\n blackPoster.hide();\n }\n }\n\n function addStyles() {\n dom.addClass(player.el(), 'vjs-ad-playing');\n }\n\n function removeStyles() {\n dom.removeClass(player.el(), 'vjs-ad-playing');\n }\n};\n\n/**\n * Remove the poster attribute from the video element tech, if present. When\n * reusing a video element for multiple videos, the poster image will briefly\n * reappear while the new source loads. Removing the attribute ahead of time\n * prevents the poster from showing up between videos.\n * @param {object} player The videojs player object\n */\nplayerUtils.removeNativePoster = function (player) {\n var tech = player.el().querySelector('.vjs-tech');\n if (tech) {\n tech.removeAttribute('poster');\n }\n};\n\n/**\n * Helper function to listen to many events until one of them gets fired, then we\n * execute the handler and unsubscribe all the event listeners;\n *\n * @param player specific player from where to listen for the events\n * @param events array of events\n * @param handler function to execute once one of the events fires\n */\nplayerUtils.once = function once(player, events, handler) {\n function listener() {\n handler.apply(null, arguments);\n\n events.forEach(function (event) {\n player.off(event, listener);\n });\n }\n\n events.forEach(function (event) {\n player.on(event, listener);\n });\n};\n\n\nmodule.exports = playerUtils;\n},{\"./dom\":39,\"./utilityFunctions\":43}],42:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('./utilityFunctions');\n\n/**\n *\n * IMPORTANT NOTE: This function comes from angularJs and was originally called urlResolve\n * you can take a look at the original code here https://github.com/angular/angular.js/blob/master/src/ng/urlUtils.js\n *\n * Implementation Notes for non-IE browsers\n * ----------------------------------------\n * Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM,\n * results both in the normalizing and parsing of the URL. Normalizing means that a relative\n * URL will be resolved into an absolute URL in the context of the application document.\n * Parsing means that the anchor node's host, hostname, protocol, port, pathname and related\n * properties are all populated to reflect the normalized URL. This approach has wide\n * compatibility - Safari 1+, Mozilla 1+, Opera 7+,e etc. See\n * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n *\n * Implementation Notes for IE\n * ---------------------------\n * IE >= 8 and <= 10 normalizes the URL when assigned to the anchor node similar to the other\n * browsers. However, the parsed components will not be set if the URL assigned did not specify\n * them. (e.g. if you assign a.href = \"foo\", then a.protocol, a.host, etc. will be empty.) We\n * work around that by performing the parsing in a 2nd step by taking a previously normalized\n * URL (e.g. by assigning to a.href) and assigning it a.href again. This correctly populates the\n * properties such as protocol, hostname, port, etc.\n *\n * IE7 does not normalize the URL when assigned to an anchor node. (Apparently, it does, if one\n * uses the inner HTML approach to assign the URL as part of an HTML snippet -\n * http://stackoverflow.com/a/472729) However, setting img[src] does normalize the URL.\n * Unfortunately, setting img[src] to something like \"javascript:foo\" on IE throws an exception.\n * Since the primary usage for normalizing URLs is to sanitize such URLs, we can't use that\n * method and IE < 8 is unsupported.\n *\n * References:\n * http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement\n * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n * http://url.spec.whatwg.org/#urlutils\n * https://github.com/angular/angular.js/pull/2902\n * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/\n *\n * @kind function\n * @param {string} url The URL to be parsed.\n * @description Normalizes and parses a URL.\n * @returns {object} Returns the normalized URL as a dictionary.\n *\n * | member name | Description |\n * |---------------|----------------|\n * | href | A normalized version of the provided URL if it was not an absolute URL |\n * | protocol | The protocol including the trailing colon |\n * | host | The host and port (if the port is non-default) of the normalizedUrl |\n * | search | The search params, minus the question mark |\n * | hash | The hash string, minus the hash symbol\n * | hostname | The hostname\n * | port | The port, without \":\"\n * | pathname | The pathname, beginning with \"/\"\n *\n */\n\nvar urlParsingNode = document.createElement(\"a\");\n/**\n * documentMode is an IE-only property\n * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx\n */\nvar msie = document.documentMode;\n\nfunction urlParts(url) {\n var href = url;\n\n if (msie) {\n // Normalize before parse. Refer Implementation Notes on why this is\n // done in two steps on IE.\n urlParsingNode.setAttribute(\"href\", href);\n href = urlParsingNode.href;\n }\n\n urlParsingNode.setAttribute('href', href);\n\n // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n return {\n href: urlParsingNode.href,\n protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n host: urlParsingNode.host,\n search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n hostname: urlParsingNode.hostname,\n port: utilities.isNotEmptyString(urlParsingNode.port)? urlParsingNode.port: 80,\n pathname: (urlParsingNode.pathname.charAt(0) === '/')\n ? urlParsingNode.pathname\n : '/' + urlParsingNode.pathname\n };\n}\n\n\n/**\n * This function accepts a query string (search part of a url) and returns a dictionary with\n * the different key value pairs\n * @param {string} qs queryString\n */\nfunction queryStringToObj(qs, cond) {\n var pairs, qsObj;\n\n cond = utilities.isFunction(cond)? cond : function() {\n return true;\n };\n\n qs = qs.trim().replace(/^\\?/, '');\n pairs = qs.split('&');\n qsObj = {};\n\n utilities.forEach(pairs, function (pair) {\n var keyValue, key, value;\n if (pair !== '') {\n keyValue = pair.split('=');\n key = keyValue[0];\n value = keyValue[1];\n if(cond(key, value)){\n qsObj[key] = value;\n }\n }\n });\n\n return qsObj;\n}\n\n/**\n * This function accepts an object and serializes it into a query string without the leading '?'\n * @param obj\n * @returns {string}\n */\nfunction objToQueryString(obj) {\n var pairs = [];\n utilities.forEach(obj, function (value, key) {\n pairs.push(key + '=' + value);\n });\n return pairs.join('&');\n}\n\nmodule.exports = {\n urlParts: urlParts,\n queryStringToObj: queryStringToObj,\n objToQueryString: objToQueryString\n};\n\n},{\"./utilityFunctions\":43}],43:[function(require,module,exports){\n/*jshint unused:false */\n\"use strict\";\n\nvar NODE_TYPE_ELEMENT = 1;\nvar SNAKE_CASE_REGEXP = /[A-Z]/g;\nvar EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/i;\n/*jslint maxlen: 500 */\nvar ISO8086_REGEXP = /^([\\+-]?\\d{4}(?!\\d{2}\\b))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))([T\\s]((([01]\\d|2[0-3])((:?)[0-5]\\d)?|24\\:?00)([\\.,]\\d+(?!:))?)?(\\17[0-5]\\d([\\.,]\\d+)?)?([zZ]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)?$/;\n\n\nfunction noop(){ }\n\nfunction isNull(o) {\n return o === null;\n}\n\nfunction isDefined(o){\n return o !== undefined;\n}\n\nfunction isUndefined(o){\n return o === undefined;\n}\n\nfunction isObject(obj) {\n return typeof obj === 'object';\n}\n\nfunction isFunction(str){\n return typeof str === 'function';\n}\n\nfunction isNumber(num){\n return typeof num === 'number';\n}\n\nfunction isWindow(obj) {\n return utilities.isObject(obj) && obj.window === obj;\n}\n\nfunction isArray(array){\n return Object.prototype.toString.call( array ) === '[object Array]';\n}\n\nfunction isArrayLike(obj) {\n if (obj === null || utilities.isWindow(obj) || utilities.isFunction(obj) || utilities.isUndefined(obj)) {\n return false;\n }\n\n var length = obj.length;\n\n if (obj.nodeType === NODE_TYPE_ELEMENT && length) {\n return true;\n }\n\n return utilities.isString(obj) || utilities.isArray(obj) || length === 0 ||\n typeof length === 'number' && length > 0 && (length - 1) in obj;\n}\n\nfunction isString(str){\n return typeof str === 'string';\n}\n\nfunction isEmptyString(str) {\n return utilities.isString(str) && str.length === 0;\n}\n\nfunction isNotEmptyString(str) {\n return utilities.isString(str) && str.length !== 0;\n}\n\nfunction arrayLikeObjToArray(args) {\n return Array.prototype.slice.call(args);\n}\n\nfunction forEach(obj, iterator, context) {\n var key, length;\n if (obj) {\n if (isFunction(obj)) {\n for (key in obj) {\n // Need to check if hasOwnProperty exists,\n // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function\n if (key !== 'prototype' && key !== 'length' && key !== 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n } else if (isArray(obj)) {\n var isPrimitive = typeof obj !== 'object';\n for (key = 0, length = obj.length; key < length; key++) {\n if (isPrimitive || key in obj) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n } else if (obj.forEach && obj.forEach !== forEach) {\n obj.forEach(iterator, context, obj);\n } else {\n for (key in obj) {\n if (obj.hasOwnProperty(key)) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n }\n }\n return obj;\n}\n\nfunction snake_case(name, separator) {\n separator = separator || '_';\n return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {\n return (pos ? separator : '') + letter.toLowerCase();\n });\n}\n\nfunction isValidEmail(email){\n if(!utilities.isString(email)){\n return false;\n }\n\n return EMAIL_REGEXP.test(email.trim());\n}\n\nfunction extend (obj) {\n var arg, i, k;\n for (i = 1; i < arguments.length; i++) {\n arg = arguments[i];\n for (k in arg) {\n if (arg.hasOwnProperty(k)) {\n if(isObject(obj[k]) && !isNull(obj[k]) && isObject(arg[k])){\n obj[k] = extend({}, obj[k], arg[k]);\n }else {\n obj[k] = arg[k];\n }\n }\n }\n }\n return obj;\n}\n\nfunction capitalize(s){\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nfunction decapitalize(s) {\n return s.charAt(0).toLowerCase() + s.slice(1);\n}\n\n/**\n * This method works the same way array.prototype.map works but if the transformer returns undefine, then\n * it won't be added to the transformed Array.\n */\nfunction transformArray(array, transformer) {\n var transformedArray = [];\n\n array.forEach(function(item, index){\n var transformedItem = transformer(item, index);\n if(utilities.isDefined(transformedItem)) {\n transformedArray.push(transformedItem);\n }\n });\n\n return transformedArray;\n}\n\nfunction toFixedDigits(num, digits) {\n var formattedNum = num + '';\n digits = utilities.isNumber(digits) ? digits : 0;\n num = utilities.isNumber(num) ? num : parseInt(num, 10);\n if(utilities.isNumber(num) && !isNaN(num)){\n formattedNum = num + '';\n while(formattedNum.length < digits) {\n formattedNum = '0' + formattedNum;\n }\n return formattedNum;\n }\n return NaN + '';\n}\n\nfunction throttle(callback, delay) {\n var previousCall = new Date().getTime() - (delay + 1);\n return function() {\n var time = new Date().getTime();\n if ((time - previousCall) >= delay) {\n previousCall = time;\n callback.apply(this, arguments);\n }\n };\n}\n\nfunction debounce (callback, wait) {\n var timeoutId;\n\n return function (){\n if(timeoutId) {\n clearTimeout(timeoutId);\n }\n timeoutId = setTimeout(function(){\n callback.apply(this, arguments);\n timeoutId = undefined;\n }, wait);\n };\n}\n\n// a function designed to blow up the stack in a naive way\n// but it is ok for videoJs children components\nfunction treeSearch(root, getChildren, found){\n var children = getChildren(root);\n for (var i = 0; i < children.length; i++){\n if (found(children[i])) {\n return children[i];\n }\n else {\n var el = treeSearch(children[i], getChildren, found);\n if (el){\n return el;\n }\n }\n }\n}\n\nfunction echoFn(val) {\n return function () {\n return val;\n };\n}\n\n//Note: Supported formats come from http://www.w3.org/TR/NOTE-datetime\n// and the iso8601 regex comes from http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/\nfunction isISO8601(value) {\n if(utilities.isNumber(value)){\n value = value + ''; //we make sure that we are working with strings\n }\n\n if(!utilities.isString(value)){\n return false;\n }\n\n return ISO8086_REGEXP.test(value.trim());\n}\n\n/**\n * Checks if the Browser is IE9 and below\n * @returns {boolean}\n */\nfunction isOldIE() {\n var version = utilities.getInternetExplorerVersion(navigator);\n if (version === -1) {\n return false;\n }\n\n return version < 10;\n}\n\n/**\n * Returns the version of Internet Explorer or a -1 (indicating the use of another browser).\n * Source: https://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx\n * @returns {number} the version of Internet Explorer or a -1 (indicating the use of another browser).\n */\nfunction getInternetExplorerVersion(navigator) {\n var rv = -1;\n\n if (navigator.appName == 'Microsoft Internet Explorer') {\n var ua = navigator.userAgent;\n var re = new RegExp(\"MSIE ([0-9]{1,}[\\.0-9]{0,})\");\n var res = re.exec(ua);\n if (res !== null) {\n rv = parseFloat(res[1]);\n }\n }\n\n return rv;\n}\n\n/*** Mobile Utility functions ***/\nfunction isIDevice() {\n return /iP(hone|ad)/.test(utilities._UA);\n}\n\nfunction isMobile() {\n return /iP(hone|ad|od)|Android|Windows Phone/.test(utilities._UA);\n}\n\nfunction isIPhone() {\n return /iP(hone|od)/.test(utilities._UA);\n}\n\nfunction isAndroid() {\n return /Android/.test(utilities._UA);\n}\n\nvar utilities = {\n _UA: navigator.userAgent,\n noop: noop,\n isNull: isNull,\n isDefined: isDefined,\n isUndefined: isUndefined,\n isObject: isObject,\n isFunction: isFunction,\n isNumber: isNumber,\n isWindow: isWindow,\n isArray: isArray,\n isArrayLike: isArrayLike,\n isString: isString,\n isEmptyString: isEmptyString,\n isNotEmptyString: isNotEmptyString,\n arrayLikeObjToArray: arrayLikeObjToArray,\n forEach: forEach,\n snake_case: snake_case,\n isValidEmail: isValidEmail,\n extend: extend,\n capitalize: capitalize,\n decapitalize: decapitalize,\n transformArray: transformArray,\n toFixedDigits: toFixedDigits,\n throttle: throttle,\n debounce: debounce,\n treeSearch: treeSearch,\n echoFn: echoFn,\n isISO8601: isISO8601,\n isOldIE: isOldIE,\n getInternetExplorerVersion: getInternetExplorerVersion,\n isIDevice: isIDevice,\n isMobile: isMobile,\n isIPhone: isIPhone,\n isAndroid: isAndroid\n};\n\nmodule.exports = utilities;\n},{}],44:[function(require,module,exports){\n'use strict';\n\nvar utilities = require('./utilityFunctions');\n\nvar xml = {};\n\nxml.strToXMLDoc = function strToXMLDoc(stringContainingXMLSource){\n //IE 8\n if(typeof window.DOMParser === 'undefined'){\n var xmlDocument = new ActiveXObject('Microsoft.XMLDOM');\n xmlDocument.async = false;\n xmlDocument.loadXML(stringContainingXMLSource);\n return xmlDocument;\n }\n\n return parseString(stringContainingXMLSource);\n\n function parseString(stringContainingXMLSource){\n var parser = new DOMParser();\n var parsedDocument;\n\n //Note: This try catch is to deal with the fact that on IE parser.parseFromString does throw an error but the rest of the browsers don't.\n try {\n parsedDocument = parser.parseFromString(stringContainingXMLSource, \"application/xml\");\n\n if(isParseError(parsedDocument) || utilities.isEmptyString(stringContainingXMLSource)){\n throw new Error();\n }\n }catch(e){\n throw new Error(\"xml.strToXMLDOC: Error parsing the string: '\" + stringContainingXMLSource + \"'\");\n }\n\n return parsedDocument;\n }\n\n function isParseError(parsedDocument) {\n try { // parser and parsererrorNS could be cached on startup for efficiency\n var parser = new DOMParser(),\n erroneousParse = parser.parseFromString('INVALID', 'text/xml'),\n parsererrorNS = erroneousParse.getElementsByTagName(\"parsererror\")[0].namespaceURI;\n\n if (parsererrorNS === 'http://www.w3.org/1999/xhtml') {\n // In PhantomJS the parseerror element doesn't seem to have a special namespace, so we are just guessing here :(\n return parsedDocument.getElementsByTagName(\"parsererror\").length > 0;\n }\n\n return parsedDocument.getElementsByTagNameNS(parsererrorNS, 'parsererror').length > 0;\n } catch (e) {\n //Note on IE parseString throws an error by itself and it will never reach this code. Because it will have failed before\n }\n }\n};\n\nxml.parseText = function parseText (sValue) {\n if (/^\\s*$/.test(sValue)) { return null; }\n if (/^(?:true|false)$/i.test(sValue)) { return sValue.toLowerCase() === \"true\"; }\n if (isFinite(sValue)) { return parseFloat(sValue); }\n if (utilities.isISO8601(sValue)) { return new Date(sValue); }\n return sValue.trim();\n};\n\nxml.JXONTree = function JXONTree (oXMLParent) {\n var parseText = xml.parseText;\n\n //The document object is an especial object that it may miss some functions or attrs depending on the browser.\n //To prevent this problem with create the JXONTree using the root childNode which is a fully fleshed node on all supported\n //browsers.\n if(oXMLParent.documentElement){\n return new xml.JXONTree(oXMLParent.documentElement);\n }\n\n if (oXMLParent.hasChildNodes()) {\n var sCollectedTxt = \"\";\n for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {\n oNode = oXMLParent.childNodes.item(nItem);\n /*jshint bitwise: false*/\n if ((oNode.nodeType - 1 | 1) === 3) { sCollectedTxt += oNode.nodeType === 3 ? oNode.nodeValue.trim() : oNode.nodeValue; }\n else if (oNode.nodeType === 1 && !oNode.prefix) {\n sProp = utilities.decapitalize(oNode.nodeName);\n vContent = new xml.JXONTree(oNode);\n if (this.hasOwnProperty(sProp)) {\n if (this[sProp].constructor !== Array) { this[sProp] = [this[sProp]]; }\n this[sProp].push(vContent);\n } else { this[sProp] = vContent; }\n }\n }\n if (sCollectedTxt) { this.keyValue = parseText(sCollectedTxt); }\n }\n\n //IE8 Stupid fix\n var hasAttr = typeof oXMLParent.hasAttributes === 'undefined'? oXMLParent.attributes.length > 0: oXMLParent.hasAttributes();\n if (hasAttr) {\n var oAttrib;\n for (var nAttrib = 0; nAttrib < oXMLParent.attributes.length; nAttrib++) {\n oAttrib = oXMLParent.attributes.item(nAttrib);\n this[\"@\" + utilities.decapitalize(oAttrib.name)] = parseText(oAttrib.value.trim());\n }\n }\n};\n\nxml.JXONTree.prototype.attr = function(attr) {\n return this['@' + utilities.decapitalize(attr)];\n};\n\nxml.toJXONTree = function toJXONTree(xmlString){\n var xmlDoc = xml.strToXMLDoc(xmlString);\n return new xml.JXONTree(xmlDoc);\n};\n\n/**\n * Helper function to extract the keyvalue of a JXONTree obj\n *\n * @param xmlObj {JXONTree}\n * return the key value or undefined;\n */\nxml.keyValue = function getKeyValue(xmlObj) {\n if(xmlObj){\n return xmlObj.keyValue;\n }\n return undefined;\n};\n\nxml.attr = function getAttrValue(xmlObj, attr) {\n if(xmlObj) {\n return xmlObj['@' + utilities.decapitalize(attr)];\n }\n return undefined;\n};\n\nxml.encode = function encodeXML(str) {\n return str.replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n};\n\nxml.decode = function decodeXML(str) {\n return str.replace(/'/g, \"'\")\n .replace(/"/g, '\"')\n .replace(/>/g, '>')\n .replace(/</g, '<')\n .replace(/&/g, '&');\n};\n\nmodule.exports = xml;\n},{\"./utilityFunctions\":43}],45:[function(require,module,exports){\n'use strict';\n\nrequire('./plugin/components/ads-label_5');\nrequire('./plugin/components/black-poster_5');\n\nvar videoJsVAST = require('./plugin/videojs.vast.vpaid');\n\nvideojs.plugin('vastClient', videoJsVAST);\n\n},{\"./plugin/components/ads-label_5\":34,\"./plugin/components/black-poster_5\":36,\"./plugin/videojs.vast.vpaid\":37}]},{},[45])\n\n","'use strict';\n\nlet IVPAIDAdUnit = require('./IVPAIDAdUnit').IVPAIDAdUnit;\nlet ALL_VPAID_METHODS = Object.getOwnPropertyNames(IVPAIDAdUnit.prototype).filter(function (property) {\n return ['constructor'].indexOf(property) === -1;\n});\n\nexport class VPAIDAdUnit extends IVPAIDAdUnit {\n constructor (flash) {\n super();\n this._destroyed = false;\n this._flash = flash;\n }\n\n _destroy() {\n this._destroyed = true;\n ALL_VPAID_METHODS.forEach((methodName) => {\n this._flash.removeCallbackByMethodName(methodName);\n });\n IVPAIDAdUnit.EVENTS.forEach((event) => {\n this._flash.offEvent(event);\n });\n\n this._flash = null;\n }\n\n isDestroyed () {\n return this._destroyed;\n }\n\n on(eventName, callback) {\n this._flash.on(eventName, callback);\n }\n\n off(eventName, callback) {\n this._flash.off(eventName, callback);\n }\n\n //VPAID interface\n handshakeVersion(playerVPAIDVersion = '2.0', callback = undefined) {\n this._flash.callFlashMethod('handshakeVersion', [playerVPAIDVersion], callback);\n }\n initAd (width, height, viewMode, desiredBitrate, creativeData = {AdParameters: ''}, environmentVars = {flashVars: ''}, callback = undefined) {\n //resize element that has the flash object\n this._flash.setSize(width, height);\n creativeData = creativeData || {AdParameters: ''};\n environmentVars = environmentVars || {flashVars: ''};\n\n this._flash.callFlashMethod('initAd', [this._flash.getWidth(), this._flash.getHeight(), viewMode, desiredBitrate, creativeData.AdParameters || '', environmentVars.flashVars || ''], callback);\n }\n resizeAd(width, height, viewMode, callback = undefined) {\n //resize element that has the flash object\n this._flash.setSize(width, height);\n\n //resize ad inside the flash\n this._flash.callFlashMethod('resizeAd', [this._flash.getWidth(), this._flash.getHeight(), viewMode], callback);\n }\n startAd(callback = undefined) {\n this._flash.callFlashMethod('startAd', [], callback);\n }\n stopAd(callback = undefined) {\n this._flash.callFlashMethod('stopAd', [], callback);\n }\n pauseAd(callback = undefined) {\n this._flash.callFlashMethod('pauseAd', [], callback);\n }\n resumeAd(callback = undefined) {\n this._flash.callFlashMethod('resumeAd', [], callback);\n }\n expandAd(callback = undefined) {\n this._flash.callFlashMethod('expandAd', [], callback);\n }\n collapseAd(callback = undefined) {\n this._flash.callFlashMethod('collapseAd', [], callback);\n }\n skipAd(callback = undefined) {\n this._flash.callFlashMethod('skipAd', [], callback);\n }\n\n //properties that will be treat as async methods\n getAdLinear(callback) {\n this._flash.callFlashMethod('getAdLinear', [], callback);\n }\n getAdWidth(callback) {\n this._flash.callFlashMethod('getAdWidth', [], callback);\n }\n getAdHeight(callback) {\n this._flash.callFlashMethod('getAdHeight', [], callback);\n }\n getAdExpanded(callback) {\n this._flash.callFlashMethod('getAdExpanded', [], callback);\n }\n getAdSkippableState(callback) {\n this._flash.callFlashMethod('getAdSkippableState', [], callback);\n }\n getAdRemainingTime(callback) {\n this._flash.callFlashMethod('getAdRemainingTime', [], callback);\n }\n getAdDuration(callback) {\n this._flash.callFlashMethod('getAdDuration', [], callback);\n }\n setAdVolume(volume, callback = undefined) {\n this._flash.callFlashMethod('setAdVolume', [volume], callback);\n }\n getAdVolume(callback) {\n this._flash.callFlashMethod('getAdVolume', [], callback);\n }\n getAdCompanions(callback) {\n this._flash.callFlashMethod('getAdCompanions', [], callback);\n }\n getAdIcons(callback) {\n this._flash.callFlashMethod('getAdIcons', [], callback);\n }\n}\n\n","'use strict';\n\nlet JSFlashBridge = require('./jsFlashBridge').JSFlashBridge;\nlet VPAIDAdUnit = require('./VPAIDAdUnit').VPAIDAdUnit;\n\nlet noop = require('./utils').noop;\nlet callbackTimeout = require('./utils').callbackTimeout;\nlet isPositiveInt = require('./utils').isPositiveInt;\nlet createElementWithID = require('./utils').createElementWithID;\nlet uniqueVPAID = require('./utils').unique('vpaid');\n\nconst ERROR = 'error';\nconst FLASH_VERSION = '10.1.0';\n\nclass VPAIDFLASHClient {\n constructor (vpaidParentEl, callback, swfConfig = {data: 'VPAIDFlash.swf', width: 800, height: 400}, params = { wmode: 'transparent', salign: 'tl', align: 'left', allowScriptAccess: 'always', scale: 'noScale', allowFullScreen: 'true', quality: 'high'}, vpaidOptions = { debug: false, timeout: 10000 }) {\n\n if (!VPAIDFLASHClient.hasExternalDependencies()) {\n return onError('no swfobject in global scope. check: https://github.com/swfobject/swfobject or https://code.google.com/p/swfobject/');\n }\n\n this._vpaidParentEl = vpaidParentEl;\n this._flashID = uniqueVPAID();\n this._destroyed = false;\n callback = callback || noop;\n\n swfConfig.width = isPositiveInt(swfConfig.width, 800);\n swfConfig.height = isPositiveInt(swfConfig.height, 400);\n\n createElementWithID(vpaidParentEl, this._flashID);\n\n params.movie = swfConfig.data;\n params.FlashVars = `flashid=${this._flashID}&handler=${JSFlashBridge.VPAID_FLASH_HANDLER}&debug=${vpaidOptions.debug}&salign=${params.salign}`;\n\n if (!VPAIDFLASHClient.isSupported()) {\n return onError('user don\\'t support flash or doesn\\'t have the minimum required version of flash ' + FLASH_VERSION);\n }\n\n this.el = swfobject.createSWF(swfConfig, params, this._flashID);\n\n if (!this.el) {\n return onError( 'swfobject failed to create object in element' );\n }\n\n var handler = callbackTimeout(vpaidOptions.timeout,\n (err, data) => {\n $loadPendedAdUnit.call(this);\n callback(err, data);\n }, () => {\n callback( 'vpaid flash load timeout ' + vpaidOptions.timeout );\n }\n );\n\n this._flash = new JSFlashBridge(this.el, swfConfig.data, this._flashID, swfConfig.width, swfConfig.height, handler);\n\n function onError(error) {\n setTimeout(() => {\n callback(new Error(error));\n }, 0);\n return this;\n }\n\n }\n\n destroy () {\n this._destroyAdUnit();\n\n if (this._flash) {\n this._flash.destroy();\n this._flash = null;\n }\n this.el = null;\n this._destroyed = true;\n }\n\n isDestroyed () {\n return this._destroyed;\n }\n\n _destroyAdUnit() {\n delete this._loadLater;\n\n if (this._adUnitLoad) {\n this._adUnitLoad = null;\n this._flash.removeCallback(this._adUnitLoad);\n }\n\n if (this._adUnit) {\n this._adUnit._destroy();\n this._adUnit = null;\n }\n }\n\n loadAdUnit(adURL, callback) {\n $throwIfDestroyed.call(this);\n\n if (this._adUnit) {\n this._destroyAdUnit();\n }\n\n if (this._flash.isReady()) {\n this._adUnitLoad = (err, message) => {\n if (!err) {\n this._adUnit = new VPAIDAdUnit(this._flash);\n }\n this._adUnitLoad = null;\n callback(err, this._adUnit);\n };\n\n this._flash.callFlashMethod('loadAdUnit', [adURL], this._adUnitLoad);\n }else {\n this._loadLater = {url: adURL, callback};\n }\n }\n\n unloadAdUnit(callback = undefined) {\n $throwIfDestroyed.call(this);\n\n this._destroyAdUnit();\n this._flash.callFlashMethod('unloadAdUnit', [], callback);\n }\n getFlashID() {\n $throwIfDestroyed.call(this);\n return this._flash.getFlashID();\n }\n getFlashURL() {\n $throwIfDestroyed.call(this);\n return this._flash.getFlashURL();\n }\n}\n\nsetStaticProperty('isSupported', () => {\n return VPAIDFLASHClient.hasExternalDependencies() && swfobject.hasFlashPlayerVersion(FLASH_VERSION);\n});\n\nsetStaticProperty('hasExternalDependencies', () => {\n return !!window.swfobject;\n});\n\nfunction $throwIfDestroyed() {\n if(this._destroyed) {\n throw new error('VPAIDFlashToJS is destroyed!');\n }\n}\n\nfunction $loadPendedAdUnit() {\n if (this._loadLater) {\n this.loadAdUnit(this._loadLater.url, this._loadLater.callback);\n delete this._loadLater;\n }\n}\n\nfunction setStaticProperty(propertyName, value) {\n Object.defineProperty(VPAIDFLASHClient, propertyName, {\n writable: false,\n configurable: false,\n value: value\n });\n}\n\nwindow.VPAIDFLASHClient = VPAIDFLASHClient;\nmodule.exports = VPAIDFLASHClient;\n\n","'use strict';\n\nlet unique = require('./utils').unique;\nlet isPositiveInt = require('./utils').isPositiveInt;\nlet stringEndsWith = require('./utils').stringEndsWith;\nlet SingleValueRegistry = require('./registry').SingleValueRegistry;\nlet MultipleValuesRegistry = require('./registry').MultipleValuesRegistry;\nconst registry = require('./jsFlashBridgeRegistry');\nconst VPAID_FLASH_HANDLER = 'vpaid_video_flash_handler';\nconst ERROR = 'AdError';\n\nexport class JSFlashBridge {\n constructor (el, flashURL, flashID, width, height, loadHandShake) {\n this._el = el;\n this._flashID = flashID;\n this._flashURL = flashURL;\n this._width = width;\n this._height = height;\n this._handlers = new MultipleValuesRegistry();\n this._callbacks = new SingleValueRegistry();\n this._uniqueMethodIdentifier = unique(this._flashID);\n this._ready = false;\n this._handShakeHandler = loadHandShake;\n\n registry.addInstance(this._flashID, this);\n }\n\n on(eventName, callback) {\n this._handlers.add(eventName, callback);\n }\n\n off(eventName, callback) {\n return this._handlers.remove(eventName, callback);\n }\n\n offEvent(eventName) {\n return this._handlers.removeByKey(eventName);\n }\n\n offAll() {\n return this._handlers.removeAll();\n }\n\n callFlashMethod(methodName, args = [], callback = undefined) {\n var callbackID = '';\n // if no callback, some methods the return is void so they don't need callback\n if (callback) {\n callbackID = `${this._uniqueMethodIdentifier()}_${methodName}`;\n this._callbacks.add(callbackID, callback);\n }\n\n\n try {\n //methods are created by ExternalInterface.addCallback in as3 code, if for some reason it failed\n //this code will throw an error\n this._el[methodName]([callbackID].concat(args));\n\n } catch (e) {\n if (callback) {\n $asyncCallback.call(this, callbackID, e);\n } else {\n\n //if there isn't any callback to return error use error event handler\n this._trigger(ERROR, e);\n }\n }\n }\n\n removeCallback(callback) {\n return this._callbacks.removeByValue(callback);\n }\n\n removeCallbackByMethodName(suffix) {\n this._callbacks.filterKeys((key) => {\n return stringEndsWith(key, suffix);\n }).forEach((key) => {\n this._callbacks.remove(key);\n });\n }\n\n removeAllCallbacks() {\n return this._callbacks.removeAll();\n }\n\n _trigger(eventName, event) {\n this._handlers.get(eventName).forEach((callback) => {\n //clickThru has to be sync, if not will be block by the popupblocker\n if (eventName === 'AdClickThru') {\n callback(event);\n } else {\n setTimeout(() => {\n if (this._handlers.get(eventName).length > 0) {\n callback(event);\n }\n }, 0);\n }\n });\n }\n\n _callCallback(methodName, callbackID, err, result) {\n\n let callback = this._callbacks.get(callbackID);\n\n //not all methods callback's are mandatory\n //but if there exist an error, fire the error event\n if (!callback) {\n if (err && callbackID === '') {\n this.trigger(ERROR, err);\n }\n return;\n }\n\n $asyncCallback.call(this, callbackID, err, result);\n\n }\n\n _handShake(err, data) {\n this._ready = true;\n if (this._handShakeHandler) {\n this._handShakeHandler(err, data);\n delete this._handShakeHandler;\n }\n }\n\n //methods like properties specific to this implementation of VPAID\n getSize() {\n return {width: this._width, height: this._height};\n }\n setSize(newWidth, newHeight) {\n this._width = isPositiveInt(newWidth, this._width);\n this._height = isPositiveInt(newHeight, this._height);\n this._el.setAttribute('width', this._width);\n this._el.setAttribute('height', this._height);\n }\n getWidth() {\n return this._width;\n }\n setWidth(newWidth) {\n this.setSize(newWidth, this._height);\n }\n getHeight() {\n return this._height;\n }\n setHeight(newHeight) {\n this.setSize(this._width, newHeight);\n }\n getFlashID() {\n return this._flashID;\n }\n getFlashURL() {\n return this._flashURL;\n }\n isReady() {\n return this._ready;\n }\n destroy() {\n this.offAll();\n this.removeAllCallbacks();\n registry.removeInstanceByID(this._flashID);\n if (this._el.parentElement) {\n this._el.parentElement.removeChild(this._el);\n }\n }\n}\n\nfunction $asyncCallback(callbackID, err, result) {\n setTimeout(() => {\n let callback = this._callbacks.get(callbackID);\n if (callback) {\n this._callbacks.remove(callbackID);\n callback(err, result);\n }\n }, 0);\n}\n\nObject.defineProperty(JSFlashBridge, 'VPAID_FLASH_HANDLER', {\n writable: false,\n configurable: false,\n value: VPAID_FLASH_HANDLER\n});\n\n/**\n * External interface handler\n *\n * @param {string} flashID identifier of the flash who call this\n * @param {string} typeID what type of message is, can be 'event' or 'callback'\n * @param {string} typeName if the typeID is a event the typeName will be the eventName, if is a callback the typeID is the methodName that is related this callback\n * @param {string} callbackID only applies when the typeID is 'callback', identifier of the callback to call\n * @param {object} error error object\n * @param {object} data\n */\nwindow[VPAID_FLASH_HANDLER] = (flashID, typeID, typeName, callbackID, error, data) => {\n let instance = registry.getInstanceByID(flashID);\n if (!instance) return;\n if (typeName === 'handShake') {\n instance._handShake(error, data);\n } else {\n if (typeID !== 'event') {\n instance._callCallback(typeName, callbackID, error, data);\n } else {\n instance._trigger(typeName, data);\n }\n }\n};\n\n","'use strict';\n\nlet SingleValueRegistry = require('./registry').SingleValueRegistry;\nlet instances = new SingleValueRegistry();\n\nconst JSFlashBridgeRegistry = {};\nObject.defineProperty(JSFlashBridgeRegistry, 'addInstance', {\n writable: false,\n configurable: false,\n value: function (id, instance) {\n instances.add(id, instance);\n }\n});\n\nObject.defineProperty(JSFlashBridgeRegistry, 'getInstanceByID', {\n writable: false,\n configurable: false,\n value: function (id) {\n return instances.get(id);\n }\n});\n\nObject.defineProperty(JSFlashBridgeRegistry, 'removeInstanceByID', {\n writable: false,\n configurable: false,\n value: function (id) {\n return instances.remove(id);\n }\n});\n\nmodule.exports = JSFlashBridgeRegistry;\n\n","'use strict';\n\nexport class MultipleValuesRegistry {\n constructor () {\n this._registries = {};\n }\n add (id, value) {\n if (!this._registries[id]) {\n this._registries[id] = [];\n }\n if (this._registries[id].indexOf(value) === -1) {\n this._registries[id].push(value);\n }\n }\n get (id) {\n return this._registries[id] || [];\n }\n filterKeys (handler) {\n return Object.keys(this._registries).filter(handler);\n }\n findByValue (value) {\n var keys = Object.keys(this._registries).filter((key) => {\n return this._registries[key].indexOf(value) !== -1;\n });\n\n return keys;\n }\n remove(key, value) {\n if (!this._registries[key]) { return; }\n\n var index = this._registries[key].indexOf(value);\n\n if (index < 0) { return; }\n return this._registries[key].splice(index, 1);\n }\n removeByKey (id) {\n let old = this._registries[id];\n delete this._registries[id];\n return old;\n }\n removeByValue (value) {\n let keys = this.findByValue(value);\n return keys.map((key) => {\n return this.remove(key, value);\n });\n }\n removeAll() {\n let old = this._registries;\n this._registries = {};\n return old;\n }\n size() {\n return Object.keys(this._registries).length;\n }\n}\n\nexport class SingleValueRegistry {\n constructor () {\n this._registries = {};\n }\n add (id, value) {\n this._registries[id] = value;\n }\n get (id) {\n return this._registries[id];\n }\n filterKeys (handler) {\n return Object.keys(this._registries).filter(handler);\n }\n findByValue (value) {\n var keys = Object.keys(this._registries).filter((key) => {\n return this._registries[key] === value;\n });\n\n return keys;\n }\n remove (id) {\n let old = this._registries[id];\n delete this._registries[id];\n return old;\n }\n removeByValue (value) {\n let keys = this.findByValue(value);\n return keys.map((key) => {\n return this.remove(key);\n });\n }\n removeAll() {\n let old = this._registries;\n this._registries = {};\n return old;\n }\n size() {\n return Object.keys(this._registries).length;\n }\n}\n\n","'use strict';\n\nexport function unique(prefix) {\n let count = -1;\n return f => {\n return `${prefix}_${++count}`;\n };\n}\n\nexport function noop() {\n}\n\n\nexport function callbackTimeout(timer, onSuccess, onTimeout) {\n\n let timeout = setTimeout(() => {\n\n onSuccess = noop;\n onTimeout();\n\n }, timer);\n\n return function () {\n clearTimeout(timeout);\n onSuccess.apply(this, arguments);\n };\n}\n\n\nexport function createElementWithID(parent, id) {\n var nEl = document.createElement('div');\n nEl.id = id;\n parent.innerHTML = '';\n parent.appendChild(nEl);\n return nEl;\n}\n\nexport function isPositiveInt(newVal, oldVal) {\n return !isNaN(parseFloat(newVal)) && isFinite(newVal) && newVal > 0 ? newVal : oldVal;\n}\n\nlet endsWith = (function () {\n if (String.prototype.endsWith) return String.prototype.endsWith;\n return function endsWith (searchString, position) {\n var subjectString = this.toString();\n if (position === undefined || position > subjectString.length) {\n position = subjectString.length;\n }\n position -= searchString.length;\n var lastIndex = subjectString.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n }\n})();\n\nexport function stringEndsWith(string, search) {\n return endsWith.call(string, search);\n}\n\n\n","'use strict';\n\nvar METHODS = [\n 'handshakeVersion',\n 'initAd',\n 'startAd',\n 'stopAd',\n 'skipAd', // VPAID 2.0 new method\n 'resizeAd',\n 'pauseAd',\n 'resumeAd',\n 'expandAd',\n 'collapseAd',\n 'subscribe',\n 'unsubscribe'\n];\n\nvar EVENTS = [\n 'AdLoaded',\n 'AdStarted',\n 'AdStopped',\n 'AdSkipped',\n 'AdSkippableStateChange', // VPAID 2.0 new event\n 'AdSizeChange', // VPAID 2.0 new event\n 'AdLinearChange',\n 'AdDurationChange', // VPAID 2.0 new event\n 'AdExpandedChange',\n 'AdRemainingTimeChange', // [Deprecated in 2.0] but will be still fired for backwards compatibility\n 'AdVolumeChange',\n 'AdImpression',\n 'AdVideoStart',\n 'AdVideoFirstQuartile',\n 'AdVideoMidpoint',\n 'AdVideoThirdQuartile',\n 'AdVideoComplete',\n 'AdClickThru',\n 'AdInteraction', // VPAID 2.0 new event\n 'AdUserAcceptInvitation',\n 'AdUserMinimize',\n 'AdUserClose',\n 'AdPaused',\n 'AdPlaying',\n 'AdLog',\n 'AdError'\n];\n\nvar GETTERS = [\n 'getAdLinear',\n 'getAdWidth', // VPAID 2.0 new getter\n 'getAdHeight', // VPAID 2.0 new getter\n 'getAdExpanded',\n 'getAdSkippableState', // VPAID 2.0 new getter\n 'getAdRemainingTime',\n 'getAdDuration', // VPAID 2.0 new getter\n 'getAdVolume',\n 'getAdCompanions', // VPAID 2.0 new getter\n 'getAdIcons' // VPAID 2.0 new getter\n];\n\nvar SETTERS = [\n 'setAdVolume'\n];\n\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n\n/**\n * IVPAIDAdUnit\n *\n * @class\n *\n * @param {object} creative\n * @param {HTMLElement} el\n * @param {HTMLVideoElement} video\n */\nfunction IVPAIDAdUnit(creative, el, video) {}\n\n\n/**\n * handshakeVersion\n *\n * @param {string} VPAIDVersion\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.handshakeVersion = function (VPAIDVersion, callback) {};\n\n/**\n * initAd\n *\n * @param {number} width\n * @param {number} height\n * @param {string} viewMode can be 'normal', 'thumbnail' or 'fullscreen'\n * @param {number} desiredBitrate indicates the desired bitrate in kbps\n * @param {object} [creativeData] used for additional initialization data\n * @param {object} [environmentVars] used for passing implementation-specific of js version\n * @param {NodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.initAd = function(width, height, viewMode, desiredBitrate, creativeData, environmentVars, callback) {};\n\n/**\n * startAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.startAd = function(callback) {};\n\n/**\n * stopAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.stopAd = function(callback) {};\n\n/**\n * skipAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.skipAd = function(callback) {};\n\n/**\n * resizeAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.resizeAd = function(width, height, viewMode, callback) {};\n\n/**\n * pauseAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.pauseAd = function(callback) {};\n\n/**\n * resumeAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.resumeAd = function(callback) {};\n\n/**\n * expandAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.expandAd = function(callback) {};\n\n/**\n * collapseAd\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.collapseAd = function(callback) {};\n\n/**\n * subscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n * @param {object} context\n */\nIVPAIDAdUnit.prototype.subscribe = function(event, handler, context) {};\n\n/**\n * startAd\n *\n * @param {string} event\n * @param {function} handler\n */\nIVPAIDAdUnit.prototype.unsubscribe = function(event, handler) {};\n\n\n\n/**\n * getAdLinear\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdLinear = function(callback) {};\n\n/**\n * getAdWidth\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdWidth = function(callback) {};\n\n/**\n * getAdHeight\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdHeight = function(callback) {};\n\n/**\n * getAdExpanded\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdExpanded = function(callback) {};\n\n/**\n * getAdSkippableState\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdSkippableState = function(callback) {};\n\n/**\n * getAdRemainingTime\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdRemainingTime = function(callback) {};\n\n/**\n * getAdDuration\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdDuration = function(callback) {};\n\n/**\n * getAdVolume\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdVolume = function(callback) {};\n\n/**\n * getAdCompanions\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdCompanions = function(callback) {};\n\n/**\n * getAdIcons\n *\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.getAdIcons = function(callback) {};\n\n/**\n * setAdVolume\n *\n * @param {number} volume\n * @param {nodeStyleCallback} callback\n */\nIVPAIDAdUnit.prototype.setAdVolume = function(volume, callback) {};\n\naddStaticToInterface(IVPAIDAdUnit, 'METHODS', METHODS);\naddStaticToInterface(IVPAIDAdUnit, 'GETTERS', GETTERS);\naddStaticToInterface(IVPAIDAdUnit, 'SETTERS', SETTERS);\naddStaticToInterface(IVPAIDAdUnit, 'EVENTS', EVENTS);\n\n\nvar VPAID1_METHODS = METHODS.filter(function(method) {\n return ['skipAd'].indexOf(method) === -1;\n});\n\naddStaticToInterface(IVPAIDAdUnit, 'checkVPAIDInterface', function checkVPAIDInterface (creative) {\n var result = VPAID1_METHODS.every(function(key) {\n return typeof creative[key] === 'function';\n });\n return result;\n});\n\nmodule.exports = IVPAIDAdUnit;\n\nfunction addStaticToInterface(Interface, name, value) {\n Object.defineProperty(Interface, name, {\n writable: false,\n configurable: false,\n value: value\n });\n}\n\n","'use strict';\n\nvar IVPAIDAdUnit = require('./IVPAIDAdUnit');\nvar Subscriber = require('./subscriber');\nvar checkVPAIDInterface = IVPAIDAdUnit.checkVPAIDInterface;\nvar utils = require('./utils');\nvar METHODS = IVPAIDAdUnit.METHODS;\nvar ERROR = 'AdError';\nvar AD_CLICK = 'AdClickThru';\nvar FILTERED_EVENTS = IVPAIDAdUnit.EVENTS.filter(function (event) {\n return event != AD_CLICK;\n});\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n\n/**\n * VPAIDAdUnit\n * @class\n *\n * @param VPAIDCreative\n * @param {HTMLElement} [el] this will be used in initAd environmentVars.slot if defined\n * @param {HTMLVideoElement} [video] this will be used in initAd environmentVars.videoSlot if defined\n */\nfunction VPAIDAdUnit(VPAIDCreative, el, video, iframe) {\n this._isValid = checkVPAIDInterface(VPAIDCreative);\n if (this._isValid) {\n this._creative = VPAIDCreative;\n this._el = el;\n this._videoEl = video;\n this._iframe = iframe;\n this._subscribers = new Subscriber();\n $addEventsSubscribers.call(this);\n }\n}\n\nVPAIDAdUnit.prototype = Object.create(IVPAIDAdUnit.prototype);\n\n/**\n * isValidVPAIDAd will return if the VPAIDCreative passed in constructor is valid or not\n *\n * @return {boolean}\n */\nVPAIDAdUnit.prototype.isValidVPAIDAd = function isValidVPAIDAd() {\n return this._isValid;\n};\n\nIVPAIDAdUnit.METHODS.forEach(function(method) {\n //NOTE: this methods arguments order are implemented differently from the spec\n var ignores = [\n 'subscribe',\n 'unsubscribe',\n 'initAd'\n ];\n\n if (ignores.indexOf(method) !== -1) return;\n\n VPAIDAdUnit.prototype[method] = function () {\n var ariaty = IVPAIDAdUnit.prototype[method].length;\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n var args = Array.prototype.slice.call(arguments);\n var callback = (ariaty === args.length) ? args.pop() : undefined;\n\n setTimeout(function () {\n var result, error = null;\n try {\n result = this._creative[method].apply(this._creative, args);\n } catch(e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n };\n});\n\n\n/**\n * initAd concreate implementation\n *\n * @param {number} width\n * @param {number} height\n * @param {string} viewMode can be 'normal', 'thumbnail' or 'fullscreen'\n * @param {number} desiredBitrate indicates the desired bitrate in kbps\n * @param {object} [creativeData] used for additional initialization data\n * @param {object} [environmentVars] used for passing implementation-specific of js version, if el & video was used in constructor slot & videoSlot will be added to the object\n * @param {NodeStyleCallback} callback\n */\nVPAIDAdUnit.prototype.initAd = function initAd(width, height, viewMode, desiredBitrate, creativeData, environmentVars, callback) {\n creativeData = creativeData || {};\n environmentVars = utils.extend({\n slot: this._el,\n videoSlot: this._videoEl\n }, environmentVars || {});\n\n setTimeout(function () {\n var error;\n try {\n this._creative.initAd(width, height, viewMode, desiredBitrate, creativeData, environmentVars);\n } catch (e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error);\n }.bind(this), 0);\n};\n\n/**\n * subscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n * @param {object} context\n */\nVPAIDAdUnit.prototype.subscribe = function subscribe(event, handler, context) {\n this._subscribers.subscribe(handler, event, context);\n};\n\n\n/**\n * unsubscribe\n *\n * @param {string} event\n * @param {nodeStyleCallback} handler\n */\nVPAIDAdUnit.prototype.unsubscribe = function unsubscribe(event, handler) {\n this._subscribers.unsubscribe(handler, event);\n};\n\n//alias\nVPAIDAdUnit.prototype.on = VPAIDAdUnit.prototype.subscribe;\nVPAIDAdUnit.prototype.off = VPAIDAdUnit.prototype.unsubscribe;\n\nIVPAIDAdUnit.GETTERS.forEach(function(getter) {\n VPAIDAdUnit.prototype[getter] = function (callback) {\n setTimeout(function () {\n\n var result, error = null;\n try {\n result = this._creative[getter]();\n } catch(e) {\n error = e;\n }\n\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n };\n});\n\n/**\n * setAdVolume\n *\n * @param volume\n * @param {nodeStyleCallback} callback\n */\nVPAIDAdUnit.prototype.setAdVolume = function setAdVolume(volume, callback) {\n setTimeout(function () {\n\n var result, error = null;\n try {\n this._creative.setAdVolume(volume);\n result = this._creative.getAdVolume();\n } catch(e) {\n error = e;\n }\n\n if (!error) {\n error = utils.validate(result === volume, 'failed to apply volume: ' + volume);\n }\n callOrTriggerEvent(callback, this._subscribers, error, result);\n }.bind(this), 0);\n};\n\nVPAIDAdUnit.prototype._destroy = function destroy() {\n this.stopAd();\n this._subscribers.unsubscribeAll();\n};\n\nfunction $addEventsSubscribers() {\n // some ads implement\n // so they only handle one subscriber\n // to handle this we create our one\n FILTERED_EVENTS.forEach(function (event) {\n this._creative.subscribe($trigger.bind(this, event), event);\n }.bind(this));\n\n // map the click event to be an object instead of depending of the order of the arguments\n // and to be consistent with the flash\n this._creative.subscribe($clickThruHook.bind(this), AD_CLICK);\n\n // because we are adding the element inside the iframe\n // the user is not able to click in the video\n if (this._videoEl) {\n var documentElement = this._iframe.contentDocument.documentElement;\n var videoEl = this._videoEl;\n documentElement.addEventListener('click', function(e) {\n if (e.target === documentElement) {\n videoEl.click();\n }\n });\n }\n}\n\nfunction $clickThruHook(url, id, playerHandles) {\n this._subscribers.triggerSync(AD_CLICK, {url: url, id: id, playerHandles: playerHandles});\n}\n\nfunction $trigger(event) {\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n this._subscribers.trigger(event, Array.prototype.slice(arguments, 1));\n}\n\nfunction callOrTriggerEvent(callback, subscribers, error, result) {\n if (callback) {\n callback(error, result);\n } else if (error) {\n subscribers.trigger(ERROR, error);\n }\n}\n\nmodule.exports = VPAIDAdUnit;\n\n","'use strict';\n\nvar utils = require('./utils');\nvar unique = utils.unique('vpaidIframe');\nvar VPAIDAdUnit = require('./VPAIDAdUnit');\n\nvar defaultTemplate = '';\ndefaultTemplate += '
';\n\nvar AD_STOPPED = 'AdStopped';\n\n/**\n * This callback is displayed as global member. The callback use nodejs error-first callback style\n * @callback NodeStyleCallback\n * @param {string|null}\n * @param {undefined|object}\n */\n\n/**\n * VPAIDHTML5Client\n * @class\n *\n * @param {HTMLElement} el that will contain the iframe to load adUnit and a el to add to adUnit slot\n * @param {HTMLVideoElement} video default video element to be used by adUnit\n * @param {object} [templateConfig] template: html template to be used instead of the default, extraOptions: to be used when rendering the template\n * @param {object} [vpaidOptions] timeout: when loading adUnit\n */\nfunction VPAIDHTML5Client(el, video, templateConfig, vpaidOptions) {\n templateConfig = templateConfig || {};\n\n this._id = unique();\n this._destroyed = false;\n\n this._frameContainer = utils.createElementInEl(el, 'div');\n this._videoEl = video;\n this._vpaidOptions = vpaidOptions || {timeout: 10000};\n\n this._templateConfig = {\n template: templateConfig.template || defaultTemplate,\n extraOptions: templateConfig.extraOptions || {}\n };\n\n}\n\n/**\n * destroy\n *\n */\nVPAIDHTML5Client.prototype.destroy = function destroy() {\n if (this._destroyed) {\n return;\n }\n this._destroyed = true;\n $unloadPreviousAdUnit.call(this);\n};\n\n/**\n * isDestroyed\n *\n * @return {boolean}\n */\nVPAIDHTML5Client.prototype.isDestroyed = function isDestroyed() {\n return this._destroyed;\n};\n\n/**\n * loadAdUnit\n *\n * @param {string} adURL url of the js of the adUnit\n * @param {nodeStyleCallback} callback\n */\nVPAIDHTML5Client.prototype.loadAdUnit = function loadAdUnit(adURL, callback) {\n $throwIfDestroyed.call(this);\n $unloadPreviousAdUnit.call(this);\n\n var frame = utils.createIframeWithContent(\n this._frameContainer,\n this._templateConfig.template,\n utils.extend({\n iframeURL_JS: adURL,\n iframeID: this.getID()\n }, this._templateConfig.extraOptions)\n );\n this._frame = frame;\n\n this._onLoad = utils.callbackTimeout(\n this._vpaidOptions.timeout,\n onLoad.bind(this),\n onTimeout.bind(this)\n );\n\n window.addEventListener('message', this._onLoad);\n\n function onLoad (e) {\n /*jshint validthis: false */\n //don't clear timeout\n if (e.origin !== window.location.origin) return;\n var result = JSON.parse(e.data);\n\n //don't clear timeout\n if (result.id !== this.getID()) return;\n\n var adUnit, error, createAd;\n if (!this._frame.contentWindow) {\n\n error = 'the iframe is not anymore in the DOM tree';\n\n } else {\n createAd = this._frame.contentWindow.getVPAIDAd;\n error = utils.validate(typeof createAd === 'function', 'the ad didn\\'t return a function to create an ad');\n }\n\n if (!error) {\n var adEl = this._frame.contentWindow.document.querySelector('.ad-element');\n adUnit = new VPAIDAdUnit(createAd(), adEl, this._videoEl, this._frame);\n adUnit.subscribe(AD_STOPPED, $adDestroyed.bind(this));\n error = utils.validate(adUnit.isValidVPAIDAd(), 'the add is not fully complaint with VPAID specification');\n }\n\n this._adUnit = adUnit;\n $destroyLoadListener.call(this);\n callback(error, error ? null : adUnit);\n\n //clear timeout\n return true;\n }\n\n function onTimeout() {\n callback('timeout', null);\n }\n};\n\n/**\n * unloadAdUnit\n *\n */\nVPAIDHTML5Client.prototype.unloadAdUnit = function unloadAdUnit() {\n $unloadPreviousAdUnit.call(this);\n};\n\n/**\n * getID will return the unique id\n *\n * @return {string}\n */\nVPAIDHTML5Client.prototype.getID = function () {\n return this._id;\n};\n\n\n/**\n * $removeEl\n *\n * @param {string} key\n */\nfunction $removeEl(key) {\n var el = this[key];\n if (el) {\n el.remove();\n delete this[key];\n }\n}\n\nfunction $adDestroyed() {\n $removeAdElements.call(this);\n delete this._adUnit;\n}\n\nfunction $unloadPreviousAdUnit() {\n $removeAdElements.call(this);\n $destroyAdUnit.call(this);\n}\n\nfunction $removeAdElements() {\n $removeEl.call(this, '_frame');\n $destroyLoadListener.call(this);\n}\n\n/**\n * $destroyLoadListener\n *\n */\nfunction $destroyLoadListener() {\n if (this._onLoad) {\n window.removeEventListener('message', this._onLoad);\n utils.clearCallbackTimeout(this._onLoad);\n delete this._onLoad;\n }\n}\n\n\nfunction $destroyAdUnit() {\n if (this._adUnit) {\n this._adUnit.stopAd();\n delete this._adUnit;\n }\n}\n\n/**\n * $throwIfDestroyed\n *\n */\nfunction $throwIfDestroyed() {\n if (this._destroyed) {\n throw new Error ('VPAIDHTML5Client already destroyed!');\n }\n}\n\nmodule.exports = VPAIDHTML5Client;\nwindow.VPAIDHTML5Client = VPAIDHTML5Client;\n\n","'use strict';\n\nfunction Subscriber() {\n this._subscribers = {};\n}\n\nSubscriber.prototype.subscribe = function subscribe(handler, eventName, context) {\n this.get(eventName).push({handler: handler, context: context});\n};\n\nSubscriber.prototype.unsubscribe = function unsubscribe(handler, eventName) {\n this._subscribers[eventName] = this.get(eventName).filter(function (subscriber) {\n return handler === subscriber.handler;\n });\n};\n\nSubscriber.prototype.unsubscribeAll = function unsubscribeAll() {\n this._subscribers = {};\n};\n\nSubscriber.prototype.trigger = function(eventName, data) {\n var that = this;\n that.get(eventName).forEach(function (subscriber) {\n setTimeout(function () {\n if (that.get(eventName)) {\n subscriber.handler.call(subscriber.context, data);\n }\n }, 0);\n });\n};\n\nSubscriber.prototype.triggerSync = function(eventName, data) {\n this.get(eventName).forEach(function (subscriber) {\n subscriber.handler.call(subscriber.context, data);\n });\n};\n\nSubscriber.prototype.get = function get(eventName) {\n if (!this._subscribers[eventName]) {\n this._subscribers[eventName] = [];\n }\n return this._subscribers[eventName];\n};\n\nmodule.exports = Subscriber;\n\n","'use strict';\n\n/**\n * noop a empty function\n */\nfunction noop() {}\n\n/**\n * validate if is not validate will return an Error with the message\n *\n * @param {boolean} isValid\n * @param {string} message\n */\nfunction validate(isValid, message) {\n return isValid ? null : new Error(message);\n}\n\nvar timeouts = {};\n/**\n * clearCallbackTimeout\n *\n * @param {function} func handler to remove\n */\nfunction clearCallbackTimeout(func) {\n var timeout = timeouts[func];\n if (timeout) {\n clearTimeout(timeout);\n delete timeouts[func];\n }\n}\n\n/**\n * callbackTimeout if the onSuccess is not called and returns true in the timelimit then onTimeout will be called\n *\n * @param {number} timer\n * @param {function} onSuccess\n * @param {function} onTimeout\n */\nfunction callbackTimeout(timer, onSuccess, onTimeout) {\n var callback, timeout;\n\n timeout = setTimeout(function () {\n onSuccess = noop;\n delete timeout[callback];\n onTimeout();\n }, timer);\n\n callback = function () {\n // TODO avoid leaking arguments\n // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments\n if (onSuccess.apply(this, arguments)) {\n clearCallbackTimeout(callback);\n }\n };\n\n timeouts[callback] = timeout;\n\n return callback;\n}\n\n\n/**\n * createElementInEl\n *\n * @param {HTMLElement} parent\n * @param {string} tagName\n * @param {string} id\n */\nfunction createElementInEl(parent, tagName, id) {\n var nEl = document.createElement(tagName);\n if (id) nEl.id = id;\n parent.appendChild(nEl);\n return nEl;\n}\n\n/**\n * createIframeWithContent\n *\n * @param {HTMLElement} parent\n * @param {string} template simple template using {{var}}\n * @param {object} data\n */\nfunction createIframeWithContent(parent, template, data) {\n var iframe = createIframe(parent);\n if (!setIframeContent(iframe, simpleTemplate(template, data))) return;\n return iframe;\n}\n\n/**\n * createIframe\n *\n * @param {HTMLElement} parent\n * @param {string} url\n */\nfunction createIframe(parent, url) {\n var nEl = document.createElement('iframe');\n nEl.src = url || 'about:blank';\n nEl.marginWidth = '0';\n nEl.marginHeight = '0';\n nEl.frameBorder = '0';\n nEl.width = '100%';\n nEl.height = '100%';\n nEl.style.position = 'absolute';\n nEl.style.left = '0';\n nEl.style.top = '0';\n nEl.style.margin = '0px';\n nEl.style.padding = '0px';\n nEl.style.border = 'none';\n nEl.setAttribute('SCROLLING','NO');\n parent.innerHTML = '';\n parent.appendChild(nEl);\n return nEl;\n}\n\n/**\n * simpleTemplate\n *\n * @param {string} template\n * @param {object} data\n */\nfunction simpleTemplate(template, data) {\n Object.keys(data).forEach(function (key) {\n var value = (typeof value === 'object') ? JSON.stringify(data[key]) : data[key];\n template = template.replace(new RegExp('{{' + key + '}}', 'g'), value);\n });\n return template;\n}\n\n/**\n * setIframeContent\n *\n * @param {HTMLIframeElement} iframeEl\n * @param content\n */\nfunction setIframeContent(iframeEl, content) {\n var iframeDoc = iframeEl.contentWindow && iframeEl.contentWindow.document;\n if (!iframeDoc) return false;\n\n iframeDoc.write(content);\n\n return true;\n}\n\n\n/**\n * extend object with keys from another object\n *\n * @param {object} toExtend\n * @param {object} fromSource\n */\nfunction extend(toExtend, fromSource) {\n Object.keys(fromSource).forEach(function(key) {\n toExtend[key] = fromSource[key];\n });\n return toExtend;\n}\n\n\n/**\n * unique will create a unique string everytime is called, sequentially and prefixed\n *\n * @param {string} prefix\n */\nfunction unique(prefix) {\n var count = -1;\n return function () {\n return prefix + '_' + (++count);\n };\n}\n\nmodule.exports = {\n noop: noop,\n validate: validate,\n clearCallbackTimeout: clearCallbackTimeout,\n callbackTimeout: callbackTimeout,\n createElementInEl: createElementInEl,\n createIframeWithContent: createIframeWithContent,\n createIframe: createIframe,\n simpleTemplate: simpleTemplate,\n setIframeContent: setIframeContent,\n extend: extend,\n unique: unique\n};\n\n","'use strict';\n\nvar InLine = require('./InLine');\nvar Wrapper = require('./Wrapper');\n\nfunction Ad(adJTree) {\n if (!(this instanceof Ad)) {\n return new Ad(adJTree);\n }\n this.initialize(adJTree);\n}\n\nAd.prototype.initialize = function(adJTree) {\n this.id = adJTree.attr('id');\n this.sequence = adJTree.attr('sequence');\n\n if(adJTree.inLine) {\n this.inLine = new InLine(adJTree.inLine);\n }\n\n if(adJTree.wrapper){\n this.wrapper = new Wrapper(adJTree.wrapper);\n }\n};\n\nmodule.exports = Ad;","'use strict';\n\nvar TrackingEvent = require('./TrackingEvent');\n\nvar utilities = require('../../utils/utilityFunctions');\n\nvar xml = require('../../utils/xml');\n\n\nfunction Companion(companionJTree) {\n if (!(this instanceof Companion)) {\n return new Companion(companionJTree);\n }\n\n //Required Elements\n this.creativeType = xml.attr(companionJTree.staticResource, 'creativeType');\n this.staticResource = xml.keyValue(companionJTree.staticResource);\n\n // Weird bug when the JXON tree is built it doesn't handle casing properly in this situation...\n var htmlResource = null;\n if (xml.keyValue(companionJTree.HTMLResource)) {\n htmlResource = xml.keyValue(companionJTree.HTMLResource);\n } else if (xml.keyValue(companionJTree.hTMLResource)) {\n htmlResource = xml.keyValue(companionJTree.hTMLResource);\n }\n this.htmlResource = htmlResource;\n\n var iframeResource = null;\n if (xml.keyValue(companionJTree.IFrameResource)) {\n iframeResource = xml.keyValue(companionJTree.IFrameResource);\n } else if (xml.keyValue(companionJTree.iFrameresource)) {\n iframeResource = xml.keyValue(companionJTree.iFrameresource);\n }\n this.iframeResource = iframeResource;\n\n //Optional fields\n this.id = xml.attr(companionJTree, 'id');\n this.width = xml.attr(companionJTree, 'width');\n this.height = xml.attr(companionJTree, 'height');\n this.expandedWidth = xml.attr(companionJTree, 'expandedWidth');\n this.expandedHeight = xml.attr(companionJTree, 'expandedHeight');\n this.scalable = xml.attr(companionJTree, 'scalable');\n this.maintainAspectRatio = xml.attr(companionJTree, 'maintainAspectRatio');\n this.minSuggestedDuration = xml.attr(companionJTree, 'minSuggestedDuration');\n this.apiFramework = xml.attr(companionJTree, 'apiFramework');\n this.companionClickThrough = xml.keyValue(companionJTree.companionClickThrough);\n this.trackingEvents = parseTrackingEvents(companionJTree.trackingEvents && companionJTree.trackingEvents.tracking);\n\n /*** Local functions ***/\n function parseTrackingEvents(trackingEvents) {\n var trackings = [];\n if (utilities.isDefined(trackingEvents)) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingData) {\n trackings.push(new TrackingEvent(trackingData));\n });\n }\n return trackings;\n }\n}\n\nmodule.exports = Companion;","'use strict';\n\nvar Linear = require('./Linear');\nvar Companion = require('./Companion');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction Creative(creativeJTree) {\n if(!(this instanceof Creative)) {\n return new Creative(creativeJTree);\n }\n\n this.id = creativeJTree.attr('id');\n this.sequence = creativeJTree.attr('sequence');\n this.adId = creativeJTree.attr('adId');\n this.apiFramework = creativeJTree.attr('apiFramework');\n\n if(creativeJTree.linear) {\n this.linear = new Linear(creativeJTree.linear);\n }\n\n if (creativeJTree.companionAds) {\n var companions = [];\n var companionAds = creativeJTree.companionAds && creativeJTree.companionAds.companion;\n companionAds = utilities.isArray(companionAds) ? companionAds : [companionAds];\n companionAds.forEach(function (companionData) {\n companions.push(new Companion(companionData));\n });\n\n this.companionAds = companions;\n }\n}\n\nmodule.exports = Creative;","'use strict';\n\nvar vastUtil = require('./vastUtil');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction InLine(inlineJTree) {\n if (!(this instanceof InLine)) {\n return new InLine(inlineJTree);\n }\n\n //Required Fields\n this.adTitle = xml.keyValue(inlineJTree.adTitle);\n this.adSystem = xml.keyValue(inlineJTree.adSystem);\n this.impressions = vastUtil.parseImpressions(inlineJTree.impression);\n this.creatives = vastUtil.parseCreatives(inlineJTree.creatives);\n\n //Optional Fields\n this.description = xml.keyValue(inlineJTree.description);\n this.advertiser = xml.keyValue(inlineJTree.advertiser);\n this.surveys = parseSurveys(inlineJTree.survey);\n this.error = xml.keyValue(inlineJTree.error);\n this.pricing = xml.keyValue(inlineJTree.pricing);\n this.extensions = inlineJTree.extensions;\n\n /*** Local Functions ***/\n function parseSurveys(inlineSurveys) {\n if (inlineSurveys) {\n return utilities.transformArray(utilities.isArray(inlineSurveys) ? inlineSurveys : [inlineSurveys], function (survey) {\n if(utilities.isNotEmptyString(survey.keyValue)){\n return {\n uri: survey.keyValue,\n type: survey.attr('type')\n };\n }\n\n return undefined;\n });\n }\n return [];\n }\n}\n\nmodule.exports = InLine;","'use strict';\n\nvar TrackingEvent = require('./TrackingEvent');\nvar MediaFile = require('./MediaFile');\nvar VideoClicks = require('./VideoClicks');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar parsers = require('./parsers');\n\nvar xml = require('../../utils/xml');\n\n\nfunction Linear(linearJTree) {\n if (!(this instanceof Linear)) {\n return new Linear(linearJTree);\n }\n\n //Required Elements\n this.duration = parsers.duration(xml.keyValue(linearJTree.duration));\n this.mediaFiles = parseMediaFiles(linearJTree.mediaFiles && linearJTree.mediaFiles.mediaFile);\n\n //Optional fields\n this.trackingEvents = parseTrackingEvents(linearJTree.trackingEvents && linearJTree.trackingEvents.tracking, this.duration);\n this.skipoffset = parsers.offset(xml.attr(linearJTree, 'skipoffset'), this.duration);\n\n if (linearJTree.videoClicks) {\n this.videoClicks = new VideoClicks(linearJTree.videoClicks);\n }\n\n if(linearJTree.adParameters) {\n this.adParameters = xml.keyValue(linearJTree.adParameters);\n\n if(xml.attr(linearJTree.adParameters, 'xmlEncoded')){\n this.adParameters = xml.decode(this.adParameters);\n }\n }\n\n /*** Local functions ***/\n function parseTrackingEvents(trackingEvents, duration) {\n var trackings = [];\n if (utilities.isDefined(trackingEvents)) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingData) {\n trackings.push(new TrackingEvent(trackingData, duration));\n });\n }\n return trackings;\n }\n\n function parseMediaFiles(mediaFilesJxonTree) {\n var mediaFiles = [];\n if (utilities.isDefined(mediaFilesJxonTree)) {\n mediaFilesJxonTree = utilities.isArray(mediaFilesJxonTree) ? mediaFilesJxonTree : [mediaFilesJxonTree];\n\n mediaFilesJxonTree.forEach(function (mfData) {\n mediaFiles.push(new MediaFile(mfData));\n });\n }\n return mediaFiles;\n }\n}\n\nmodule.exports = Linear;","'use strict';\n\nvar xml = require('../../utils/xml');\n\nvar attributesList = [\n //Required attributes\n 'delivery',\n 'type',\n 'width',\n 'height',\n //Optional attributes\n 'codec',\n 'id',\n 'bitrate',\n 'minBitrate',\n 'maxBitrate',\n 'scalable',\n 'maintainAspectRatio',\n 'apiFramework'\n];\n\nfunction MediaFile(mediaFileJTree) {\n if (!(this instanceof MediaFile)) {\n return new MediaFile(mediaFileJTree);\n }\n\n //Required attributes\n this.src = xml.keyValue(mediaFileJTree);\n\n for(var x=0; x 0) {\n getAd(waterfallAds.shift(),[], waterfallHandler);\n } else {\n callback(error, adChain);\n }\n } else {\n callback(null, adChain);\n }\n }\n });\n\n /*** Local functions ***/\n function getAdWaterfall(adTagUrl, callback) {\n var requestVastXML = that._requestVASTXml.bind(that, adTagUrl);\n async.waterfall([\n requestVastXML,\n buildVastWaterfall\n ], callback);\n }\n\n function buildVastWaterfall(xmlStr, callback) {\n var vastTree;\n try {\n vastTree = xml.toJXONTree(xmlStr);\n\n if(utilities.isArray(vastTree.ad)) {\n vastTree.ads = vastTree.ad;\n } else if(vastTree.ad){\n vastTree.ads = [vastTree.ad];\n } else {\n vastTree.ads = [];\n }\n callback(validateVASTTree(vastTree), vastTree);\n\n } catch (e) {\n callback(new VASTError(\"on VASTClient.getVASTAd.buildVastWaterfall, error parsing xml\", 100), null);\n }\n }\n\n function validateVASTTree(vastTree) {\n var vastVersion = xml.attr(vastTree, 'version');\n\n if (!vastTree.ad) {\n return new VASTError('on VASTClient.getVASTAd.validateVASTTree, no Ad in VAST tree', 303);\n }\n\n if (vastVersion && (vastVersion != 3 && vastVersion != 2)) {\n return new VASTError('on VASTClient.getVASTAd.validateVASTTree, not supported VAST version \"' + vastVersion + '\"', 102);\n }\n\n return null;\n }\n\n function getAd(adTagUrl, adChain, callback) {\n if (adChain.length >= that.WRAPPER_LIMIT) {\n return callback(new VASTError(\"on VASTClient.getVASTAd.getAd, players wrapper limit reached (the limit is \" + that.WRAPPER_LIMIT + \")\", 302), adChain);\n }\n\n async.waterfall([\n function (next) {\n if (utilities.isString(adTagUrl)) {\n requestVASTAd(adTagUrl, next);\n } else {\n next(null, adTagUrl);\n }\n },\n buildAd\n ], function (error, ad) {\n if (ad) {\n adChain.push(ad);\n }\n\n if (error) {\n return callback(error, adChain);\n }\n\n if (ad.wrapper) {\n return getAd(ad.wrapper.VASTAdTagURI, adChain, callback);\n }\n\n return callback(null, adChain);\n });\n }\n\n function buildAd(adJxonTree, callback) {\n try {\n var ad = new Ad(adJxonTree);\n callback(validateAd(ad), ad);\n } catch (e) {\n callback(new VASTError('on VASTClient.getVASTAd.buildAd, error parsing xml', 100), null);\n }\n }\n\n function validateAd(ad) {\n var wrapper = ad.wrapper;\n var inLine = ad.inLine;\n var errMsgPrefix = 'on VASTClient.getVASTAd.validateAd, ';\n\n if (inLine && wrapper) {\n return new VASTError(errMsgPrefix +\"InLine and Wrapper both found on the same Ad\", 101);\n }\n\n if (!inLine && !wrapper) {\n return new VASTError(errMsgPrefix + \"nor wrapper nor inline elements found on the Ad\", 101);\n }\n\n if (inLine && inLine.creatives.length === 0) {\n return new VASTError(errMsgPrefix + \"missing creative in InLine element\", 101);\n }\n\n if (wrapper && !wrapper.VASTAdTagURI) {\n return new VASTError(errMsgPrefix + \"missing 'VASTAdTagURI' in wrapper\", 101);\n }\n }\n\n function requestVASTAd(adTagUrl, callback) {\n that._requestVASTXml(adTagUrl, function (error, xmlStr) {\n if (error) {\n return callback(error);\n }\n try {\n var vastTree = xml.toJXONTree(xmlStr);\n callback(validateVASTTree(vastTree), vastTree.ad);\n } catch (e) {\n callback(new VASTError(\"on VASTClient.getVASTAd.requestVASTAd, error parsing xml\", 100));\n }\n });\n }\n};\n\nVASTClient.prototype._requestVASTXml = function requestVASTXml(adTagUrl, callback) {\n try {\n if (utilities.isFunction(adTagUrl)) {\n adTagUrl(requestHandler);\n } else {\n http.get(adTagUrl, requestHandler, {\n withCredentials: true\n });\n }\n } catch (e) {\n callback(e);\n }\n\n /*** Local functions ***/\n function requestHandler(error, response, status) {\n if (error) {\n var errMsg = utilities.isDefined(status) ?\n \"on VASTClient.requestVastXML, HTTP request error with status '\" + status + \"'\" :\n \"on VASTClient.requestVastXML, Error getting the the VAST XML with he passed adTagXML fn\";\n return callback(new VASTError(errMsg, 301), null);\n }\n\n callback(null, response);\n }\n};\n\nVASTClient.prototype._buildVASTResponse = function buildVASTResponse(adsChain) {\n var response = new VASTResponse();\n addAdsToResponse(response, adsChain);\n validateResponse(response);\n\n return response;\n\n //*** Local function ****\n function addAdsToResponse(response, ads) {\n ads.forEach(function (ad) {\n response.addAd(ad);\n });\n }\n\n function validateResponse(response) {\n var progressEvents = response.trackingEvents.progress;\n\n if (!response.hasLinear()) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, Received an Ad type that is not supported\", 200);\n }\n\n if (response.duration === undefined) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, Missing duration field in VAST response\", 101);\n }\n\n if (progressEvents) {\n progressEvents.forEach(function (progressEvent) {\n if (!utilities.isNumber(progressEvent.offset)) {\n throw new VASTError(\"on VASTClient._buildVASTResponse, missing or wrong offset attribute on progress tracking event\", 101);\n }\n });\n }\n }\n};\n\nVASTClient.prototype._trackError = function (error, adChain) {\n if (!utilities.isArray(adChain) || adChain.length === 0) { //There is nothing to track\n return;\n }\n\n var errorURLMacros = [];\n adChain.forEach(addErrorUrlMacros);\n vastUtil.track(errorURLMacros, {ERRORCODE: error.code || 900}); //900 <== Undefined error\n\n /*** Local functions ***/\n function addErrorUrlMacros(ad) {\n if (ad.wrapper && ad.wrapper.error) {\n errorURLMacros.push(ad.wrapper.error);\n }\n\n if (ad.inLine && ad.inLine.error) {\n errorURLMacros.push(ad.inLine.error);\n }\n }\n};\n\nmodule.exports = VASTClient;\n","'use strict';\n\nfunction VASTError(message, code) {\n this.message = 'VAST Error: ' + (message || '');\n if (code) {\n this.code = code;\n }\n}\n\nVASTError.prototype = new Error();\nVASTError.prototype.name = \"VAST Error\";\n\nmodule.exports = VASTError;","'use strict';\n\n/**\n * Inner helper class that deals with the logic of the individual steps needed to setup an ad in the player.\n *\n * @param player {object} instance of the player that will play the ad. It assumes that the videojs-contrib-ads plugin\n * has been initialized when you use its utility functions.\n *\n * @constructor\n */\n\nvar VASTResponse = require('./VASTResponse');\nvar VASTError = require('./VASTError');\nvar VASTTracker = require('./VASTTracker');\nvar vastUtil = require('./vastUtil');\n\nvar async = require('../../utils/async');\nvar dom = require('../../utils/dom');\nvar playerUtils = require('../../utils/playerUtils');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VASTIntegrator(player) {\n if (!(this instanceof VASTIntegrator)) {\n return new VASTIntegrator(player);\n }\n\n this.player = player;\n}\n\nVASTIntegrator.prototype.playAd = function playAd(vastResponse, callback) {\n var that = this;\n callback = callback || utilities.noop;\n\n if (!(vastResponse instanceof VASTResponse)) {\n return callback(new VASTError('On VASTIntegrator, missing required VASTResponse'));\n }\n\n async.waterfall([\n function (next) {\n next(null, vastResponse);\n },\n this._selectAdSource.bind(this),\n this._createVASTTracker.bind(this),\n this._addClickThrough.bind(this),\n this._addSkipButton.bind(this),\n this._setupEvents.bind(this),\n this._playSelectedAd.bind(this)\n ], function (error, response) {\n if (error && response) {\n that._trackError(error, response);\n }\n callback(error, response);\n });\n\n this._adUnit = {\n _src: null,\n type: 'VAST',\n pauseAd: function () {\n that.player.pause(true);\n },\n\n resumeAd: function () {\n that.player.play(true);\n },\n\n isPaused: function () {\n return that.player.paused(true);\n },\n\n getSrc: function () {\n return this._src;\n }\n };\n\n return this._adUnit;\n};\n\nVASTIntegrator.prototype._selectAdSource = function selectAdSource(response, callback) {\n var source;\n\n var playerWidth = dom.getDimension(this.player.el()).width;\n response.mediaFiles.sort(function compareTo(a, b) {\n var deltaA = Math.abs(playerWidth - a.width);\n var deltaB = Math.abs(playerWidth - b.width);\n return deltaA - deltaB;\n });\n\n source = this.player.selectSource(response.mediaFiles).source;\n\n if (source) {\n if (this._adUnit) {\n this._adUnit._src = source;\n }\n return callback(null, source, response);\n }\n\n // code 403 <== Couldn't find MediaFile that is supported by this video player\n callback(new VASTError(\"Could not find Ad mediafile supported by this player\", 403), response);\n};\n\nVASTIntegrator.prototype._createVASTTracker = function createVASTTracker(adMediaFile, response, callback) {\n try {\n callback(null, adMediaFile, new VASTTracker(adMediaFile.src, response), response);\n } catch (e) {\n callback(e, response);\n }\n};\n\nVASTIntegrator.prototype._setupEvents = function setupEvents(adMediaFile, tracker, response, callback) {\n var previouslyMuted;\n var player = this.player;\n player.on('fullscreenchange', trackFullscreenChange);\n player.on('vast.adStart', trackImpressions);\n player.on('pause', trackPause);\n player.on('timeupdate', trackProgress);\n player.on('volumechange', trackVolumeChange);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], unbindEvents);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel', 'vast.adSkip'], function(evt){\n if(evt.type === 'vast.adEnd'){\n tracker.trackComplete();\n }\n });\n\n return callback(null, adMediaFile, response);\n\n /*** Local Functions ***/\n function unbindEvents() {\n player.off('fullscreenchange', trackFullscreenChange);\n player.off('vast.adStart', trackImpressions);\n player.off('pause', trackPause);\n player.off('timeupdate', trackProgress);\n player.off('volumechange', trackVolumeChange);\n }\n\n function trackFullscreenChange() {\n if (player.isFullscreen()) {\n tracker.trackFullscreen();\n } else {\n tracker.trackExitFullscreen();\n }\n }\n\n function trackPause() {\n //NOTE: whenever a video ends the video Element triggers a 'pause' event before the 'ended' event.\n // We should not track this pause event because it makes the VAST tracking confusing again we use a\n // Threshold of 2 seconds to prevent false positives on IOS.\n if (Math.abs(player.duration() - player.currentTime()) < 2) {\n return;\n }\n\n tracker.trackPause();\n playerUtils.once(player, ['play', 'vast.adEnd', 'vast.adsCancel'], function (evt) {\n if(evt.type === 'play'){\n tracker.trackResume();\n }\n });\n }\n\n function trackProgress() {\n var currentTimeInMs = player.currentTime() * 1000;\n tracker.trackProgress(currentTimeInMs);\n }\n\n function trackImpressions() {\n tracker.trackImpressions();\n tracker.trackCreativeView();\n }\n\n function trackVolumeChange() {\n var muted = player.muted();\n if (muted) {\n tracker.trackMute();\n } else if (previouslyMuted) {\n tracker.trackUnmute();\n }\n previouslyMuted = muted;\n }\n};\n\nVASTIntegrator.prototype._addSkipButton = function addSkipButton(source, tracker, response, callback) {\n var skipOffsetInSec;\n var that = this;\n\n if (utilities.isNumber(response.skipoffset)) {\n skipOffsetInSec = response.skipoffset / 1000;\n addSkipButtonToPlayer(this.player, skipOffsetInSec);\n }\n callback(null, source, tracker, response);\n\n /*** Local function ***/\n function addSkipButtonToPlayer(player, skipOffset) {\n var skipButton = createSkipButton(player);\n var updateSkipButton = updateSkipButtonState.bind(that, skipButton, skipOffset, player);\n\n player.el().appendChild(skipButton);\n player.on('timeupdate', updateSkipButton);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeSkipButton);\n\n function removeSkipButton() {\n player.off('timeupdate', updateSkipButton);\n dom.remove(skipButton);\n }\n }\n\n function createSkipButton(player) {\n var skipButton = window.document.createElement(\"div\");\n dom.addClass(skipButton, \"vast-skip-button\");\n\n skipButton.onclick = function (e) {\n if (dom.hasClass(skipButton, 'enabled')) {\n tracker.trackSkip();\n player.trigger('vast.adSkip');\n }\n\n //We prevent event propagation to avoid problems with the clickThrough and so on\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n } else {\n return false;\n }\n };\n\n return skipButton;\n }\n\n function updateSkipButtonState(skipButton, skipOffset, player) {\n var timeLeft = Math.ceil(skipOffset - player.currentTime());\n if (timeLeft > 0) {\n skipButton.innerHTML = \"Skip in \" + utilities.toFixedDigits(timeLeft, 2) + \"...\";\n } else {\n if (!dom.hasClass(skipButton, 'enabled')) {\n dom.addClass(skipButton, 'enabled');\n skipButton.innerHTML = \"Skip ad\";\n }\n }\n }\n};\n\nVASTIntegrator.prototype._addClickThrough = function addClickThrough(mediaFile, tracker, response, callback) {\n var player = this.player;\n var blocker = createClickThroughBlocker(player, tracker, response);\n var updateBlocker = updateBlockerURL.bind(this, blocker, response, player);\n\n player.el().insertBefore(blocker, player.controlBar.el());\n player.on('timeupdate', updateBlocker);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeBlocker);\n\n return callback(null, mediaFile, tracker, response);\n\n /*** Local Functions ***/\n\n function createClickThroughBlocker(player, tracker, response) {\n var blocker = window.document.createElement(\"a\");\n var clickThroughMacro = response.clickThrough;\n\n dom.addClass(blocker, 'vast-blocker');\n blocker.href = generateClickThroughURL(clickThroughMacro, player);\n\n if (utilities.isString(clickThroughMacro)) {\n blocker.target = \"_blank\";\n }\n\n blocker.onclick = function (e) {\n if (player.paused()) {\n player.play();\n\n //We prevent event propagation to avoid problems with the player's normal pause mechanism\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n }\n return false;\n }\n\n player.pause();\n tracker.trackClick();\n };\n\n return blocker;\n }\n\n function updateBlockerURL(blocker, response, player) {\n blocker.href = generateClickThroughURL(response.clickThrough, player);\n }\n\n function generateClickThroughURL(clickThroughMacro, player) {\n var variables = {\n ASSETURI: mediaFile.src,\n CONTENTPLAYHEAD: vastUtil.formatProgress(player.currentTime() * 1000)\n };\n\n return clickThroughMacro ? vastUtil.parseURLMacro(clickThroughMacro, variables) : '#';\n }\n\n function removeBlocker() {\n player.off('timeupdate', updateBlocker);\n dom.remove(blocker);\n }\n};\n\nVASTIntegrator.prototype._playSelectedAd = function playSelectedAd(source, response, callback) {\n var player = this.player;\n\n player.preload(\"auto\"); //without preload=auto the durationchange event is never fired\n player.src(source);\n\n playerUtils.once(player, ['durationchange', 'error', 'vast.adsCancel'], function (evt) {\n if (evt.type === 'durationchange') {\n playAd();\n } else if(evt.type === 'error') {\n callback(new VASTError(\"on VASTIntegrator, Player is unable to play the Ad\", 400), response);\n }\n //NOTE: If the ads get canceled we do nothing/\n });\n\n /**** local functions ******/\n function playAd() {\n playerUtils.once(player, ['playing', 'vast.adsCancel'], function (evt) {\n if(evt.type === 'vast.adsCancel'){\n return;\n }\n\n player.trigger('vast.adStart');\n\n playerUtils.once(player, ['ended', 'vast.adsCancel', 'vast.adSkip'], function (evt) {\n if(evt.type === 'ended' || evt.type === 'vast.adSkip'){\n callback(null, response);\n }\n //NOTE: if the ads get cancel we do nothing\n });\n });\n player.play();\n }\n};\n\nVASTIntegrator.prototype._trackError = function trackError(error, response) {\n vastUtil.track(response.errorURLMacros, {ERRORCODE: error.code || 900});\n};\n\nmodule.exports = VASTIntegrator;","'use strict';\n\nvar Ad = require('./Ad');\nvar VideoClicks = require('./VideoClicks');\nvar Linear = require('./Linear');\nvar InLine = require('./InLine');\nvar Wrapper = require('./Wrapper');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nwindow.InLine__A = InLine;\nfunction VASTResponse() {\n if (!(this instanceof VASTResponse)) {\n return new VASTResponse();\n }\n\n this._linearAdded = false;\n this.ads = [];\n this.errorURLMacros = [];\n this.impressions = [];\n this.clickTrackings = [];\n this.customClicks = [];\n this.trackingEvents = {};\n this.mediaFiles = [];\n this.clickThrough = undefined;\n this.adTitle = '';\n this.duration = undefined;\n this.skipoffset = undefined;\n}\n\nVASTResponse.prototype.addAd = function (ad) {\n var inLine, wrapper;\n if (ad instanceof Ad) {\n inLine = ad.inLine;\n wrapper = ad.wrapper;\n\n this.ads.push(ad);\n\n if (inLine) {\n this._addInLine(inLine);\n }\n\n if (wrapper) {\n this._addWrapper(wrapper);\n }\n }\n};\n\nVASTResponse.prototype._addErrorTrackUrl = function (error) {\n var errorURL = error instanceof xml.JXONTree ? xml.keyValue(error) : error;\n if (errorURL) {\n this.errorURLMacros.push(errorURL);\n }\n};\n\nVASTResponse.prototype._addImpressions = function (impressions) {\n utilities.isArray(impressions) && appendToArray(this.impressions, impressions);\n};\n\nVASTResponse.prototype._addClickThrough = function (clickThrough) {\n if (utilities.isNotEmptyString(clickThrough)) {\n this.clickThrough = clickThrough;\n }\n};\n\nVASTResponse.prototype._addClickTrackings = function (clickTrackings) {\n utilities.isArray(clickTrackings) && appendToArray(this.clickTrackings, clickTrackings);\n};\n\nVASTResponse.prototype._addCustomClicks = function (customClicks) {\n utilities.isArray(customClicks) && appendToArray(this.customClicks, customClicks);\n};\n\nVASTResponse.prototype._addTrackingEvents = function (trackingEvents) {\n var eventsMap = this.trackingEvents;\n\n if (trackingEvents) {\n trackingEvents = utilities.isArray(trackingEvents) ? trackingEvents : [trackingEvents];\n trackingEvents.forEach(function (trackingEvent) {\n if (!eventsMap[trackingEvent.name]) {\n eventsMap[trackingEvent.name] = [];\n }\n eventsMap[trackingEvent.name].push(trackingEvent);\n });\n }\n};\n\nVASTResponse.prototype._addTitle = function (title) {\n if (utilities.isNotEmptyString(title)) {\n this.adTitle = title;\n }\n};\n\nVASTResponse.prototype._addDuration = function (duration) {\n if (utilities.isNumber(duration)) {\n this.duration = duration;\n }\n};\n\nVASTResponse.prototype._addVideoClicks = function (videoClicks) {\n if (videoClicks instanceof VideoClicks) {\n this._addClickThrough(videoClicks.clickThrough);\n this._addClickTrackings(videoClicks.clickTrackings);\n this._addCustomClicks(videoClicks.customClicks);\n }\n};\n\nVASTResponse.prototype._addMediaFiles = function (mediaFiles) {\n utilities.isArray(mediaFiles) && appendToArray(this.mediaFiles, mediaFiles);\n};\n\nVASTResponse.prototype._addSkipoffset = function (offset) {\n if (offset) {\n this.skipoffset = offset;\n }\n};\n\nVASTResponse.prototype._addAdParameters = function (adParameters) {\n if (adParameters) {\n this.adParameters = adParameters;\n }\n};\n\nVASTResponse.prototype._addLinear = function (linear) {\n if (linear instanceof Linear) {\n this._addDuration(linear.duration);\n this._addTrackingEvents(linear.trackingEvents);\n this._addVideoClicks(linear.videoClicks);\n this._addMediaFiles(linear.mediaFiles);\n this._addSkipoffset(linear.skipoffset);\n this._addAdParameters(linear.adParameters);\n this._linearAdded = true;\n }\n};\n\nVASTResponse.prototype._addInLine = function (inLine) {\n var that = this;\n\n if (inLine instanceof InLine) {\n this._addTitle(inLine.adTitle);\n this._addErrorTrackUrl(inLine.error);\n this._addImpressions(inLine.impressions);\n\n inLine.creatives.forEach(function (creative) {\n if (creative.linear) {\n that._addLinear(creative.linear);\n }\n });\n }\n};\n\nVASTResponse.prototype._addWrapper = function (wrapper) {\n var that = this;\n\n if (wrapper instanceof Wrapper) {\n this._addErrorTrackUrl(wrapper.error);\n this._addImpressions(wrapper.impressions);\n\n wrapper.creatives.forEach(function (creative) {\n var linear = creative.linear;\n if (linear) {\n that._addVideoClicks(linear.videoClicks);\n that.clickThrough = undefined;//We ensure that no clickThrough has been added\n that._addTrackingEvents(linear.trackingEvents);\n }\n });\n }\n};\n\nVASTResponse.prototype.hasLinear = function(){\n return this._linearAdded;\n};\n\nfunction appendToArray(array, items) {\n items.forEach(function (item) {\n array.push(item);\n });\n}\n\nmodule.exports = VASTResponse;\n\n","'use strict';\n\nvar VASTError = require('./VASTError');\nvar VASTResponse = require('./VASTResponse');\nvar vastUtil = require('./vastUtil');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VASTTracker(assetURI, vastResponse) {\n if (!(this instanceof VASTTracker)) {\n return new VASTTracker(assetURI, vastResponse);\n }\n\n this.sanityCheck(assetURI, vastResponse);\n this.initialize(assetURI, vastResponse);\n\n}\n\nVASTTracker.prototype.initialize = function(assetURI, vastResponse) {\n this.response = vastResponse;\n this.assetURI = assetURI;\n this.progress = 0;\n this.quartiles = {\n firstQuartile: {tracked: false, time: Math.round(25 * vastResponse.duration) / 100},\n midpoint: {tracked: false, time: Math.round(50 * vastResponse.duration) / 100},\n thirdQuartile: {tracked: false, time: Math.round(75 * vastResponse.duration) / 100}\n };\n};\n\nVASTTracker.prototype.sanityCheck = function(assetURI, vastResponse) {\n if (!utilities.isString(assetURI) || utilities.isEmptyString(assetURI)) {\n throw new VASTError('on VASTTracker constructor, missing required the URI of the ad asset being played');\n }\n\n if (!(vastResponse instanceof VASTResponse)) {\n throw new VASTError('on VASTTracker constructor, missing required VAST response');\n }\n};\n\nVASTTracker.prototype.trackURLs = function trackURLs(urls, variables) {\n if (utilities.isArray(urls) && urls.length > 0) {\n variables = utilities.extend({\n ASSETURI: this.assetURI,\n CONTENTPLAYHEAD: vastUtil.formatProgress(this.progress)\n }, variables || {});\n\n vastUtil.track(urls, variables);\n }\n};\n\nVASTTracker.prototype.trackEvent = function trackEvent(eventName, trackOnce) {\n this.trackURLs(getEventUris(this.response.trackingEvents[eventName]));\n if (trackOnce) {\n this.response.trackingEvents[eventName] = undefined;\n }\n\n /*** Local function ***/\n function getEventUris(trackingEvents) {\n var uris;\n\n if (trackingEvents) {\n uris = [];\n trackingEvents.forEach(function (event) {\n uris.push(event.uri);\n });\n }\n return uris;\n }\n};\n\nVASTTracker.prototype.trackProgress = function trackProgress(newProgressInMs) {\n var that = this;\n var events = [];\n var ONCE = true;\n var ALWAYS = false;\n var trackingEvents = this.response.trackingEvents;\n\n if (utilities.isNumber(newProgressInMs)) {\n addTrackEvent('start', ONCE, newProgressInMs > 0);\n addTrackEvent('rewind', ALWAYS, hasRewound(this.progress, newProgressInMs));\n addQuartileEvents(newProgressInMs);\n trackProgressEvents(newProgressInMs);\n trackEvents();\n this.progress = newProgressInMs;\n }\n\n /*** Local function ***/\n function hasRewound(currentProgress, newProgress) {\n var REWIND_THRESHOLD = 3000; //IOS video clock is very unreliable and we need a 3 seconds threshold to ensure that there was a rewind an that it was on purpose.\n return currentProgress > newProgressInMs && Math.abs(newProgress - currentProgress) > REWIND_THRESHOLD;\n }\n\n function addTrackEvent(eventName, trackOnce, canBeAdded) {\n if (trackingEvents[eventName] && canBeAdded) {\n events.push({\n name: eventName,\n trackOnce: !!trackOnce\n });\n }\n }\n\n function addQuartileEvents(progress) {\n var quartiles = that.quartiles;\n var firstQuartile = that.quartiles.firstQuartile;\n var midpoint = that.quartiles.midpoint;\n var thirdQuartile = that.quartiles.thirdQuartile;\n\n if (!firstQuartile.tracked) {\n trackQuartile('firstQuartile', progress);\n } else if (!midpoint.tracked) {\n trackQuartile('midpoint', progress);\n } else if (!thirdQuartile.tracked){\n trackQuartile('thirdQuartile', progress);\n }\n\n /*** Local function ***/\n function trackQuartile(quartileName, progress){\n var quartile = quartiles[quartileName];\n if(canBeTracked(quartile, progress)){\n quartile.tracked = true;\n addTrackEvent(quartileName, ONCE, true);\n }\n }\n }\n\n function canBeTracked(quartile, progress) {\n var quartileTime = quartile.time;\n //We only fire the quartile event if the progress is bigger than the quartile time by 5 seconds at most.\n return progress >= quartileTime && progress <= (quartileTime + 5000);\n }\n\n function trackProgressEvents(progress) {\n if (!utilities.isArray(trackingEvents.progress)) {\n return; //Nothing to track\n }\n\n var pendingProgressEvts = [];\n\n trackingEvents.progress.forEach(function (evt) {\n if (evt.offset <= progress) {\n that.trackURLs([evt.uri]);\n } else {\n pendingProgressEvts.push(evt);\n }\n });\n trackingEvents.progress = pendingProgressEvts;\n }\n\n function trackEvents() {\n events.forEach(function (event) {\n that.trackEvent(event.name, event.trackOnce);\n });\n }\n};\n\n[\n 'rewind',\n 'fullscreen',\n 'exitFullscreen',\n 'pause',\n 'resume',\n 'mute',\n 'unmute',\n 'acceptInvitation',\n 'acceptInvitationLinear',\n 'collapse',\n 'expand'\n].forEach(function (eventName) {\n VASTTracker.prototype['track' + utilities.capitalize(eventName)] = function () {\n this.trackEvent(eventName);\n };\n });\n\n[\n 'start',\n 'skip',\n 'close',\n 'closeLinear'\n].forEach(function (eventName) {\n VASTTracker.prototype['track' + utilities.capitalize(eventName)] = function () {\n this.trackEvent(eventName, true);\n };\n });\n\n[\n 'firstQuartile',\n 'midpoint',\n 'thirdQuartile'\n].forEach(function (quartile) {\n VASTTracker.prototype['track' + utilities.capitalize(quartile)] = function () {\n this.quartiles[quartile].tracked = true;\n this.trackEvent(quartile, true);\n };\n });\n\nVASTTracker.prototype.trackComplete = function () {\n if(this.quartiles.thirdQuartile.tracked){\n this.trackEvent('complete', true);\n }\n};\n\nVASTTracker.prototype.trackErrorWithCode = function trackErrorWithCode(errorcode) {\n if (utilities.isNumber(errorcode)) {\n this.trackURLs(this.response.errorURLMacros, {ERRORCODE: errorcode});\n }\n};\n\nVASTTracker.prototype.trackImpressions = function trackImpressions() {\n this.trackURLs(this.response.impressions);\n};\n\nVASTTracker.prototype.trackCreativeView = function trackCreativeView() {\n this.trackEvent('creativeView');\n};\n\nVASTTracker.prototype.trackClick = function trackClick() {\n this.trackURLs(this.response.clickTrackings);\n};\n\nmodule.exports = VASTTracker;\n","'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction VideoClicks(videoClickJTree) {\n if (!(this instanceof VideoClicks)) {\n return new VideoClicks(videoClickJTree);\n }\n\n this.clickThrough = xml.keyValue(videoClickJTree.clickThrough);\n this.clickTrackings = parseClickTrackings(videoClickJTree.clickTracking);\n this.customClicks = parseClickTrackings(videoClickJTree.customClick);\n\n /*** Local functions ***/\n function parseClickTrackings(trackingData) {\n var clickTrackings = [];\n if (trackingData) {\n trackingData = utilities.isArray(trackingData) ? trackingData : [trackingData];\n trackingData.forEach(function (clickTrackingData) {\n clickTrackings.push(xml.keyValue(clickTrackingData));\n });\n }\n return clickTrackings;\n }\n}\n\nmodule.exports = VideoClicks;","'use strict';\n\nvar vastUtil = require('./vastUtil');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar xml = require('../../utils/xml');\n\nfunction Wrapper(wrapperJTree) {\n if(!(this instanceof Wrapper)) {\n return new Wrapper(wrapperJTree);\n }\n\n //Required elements\n this.adSystem = xml.keyValue(wrapperJTree.adSystem);\n this.impressions = vastUtil.parseImpressions(wrapperJTree.impression);\n this.VASTAdTagURI = xml.keyValue(wrapperJTree.vASTAdTagURI);\n\n //Optional elements\n this.creatives = vastUtil.parseCreatives(wrapperJTree.creatives);\n this.error = xml.keyValue(wrapperJTree.error);\n this.extensions = wrapperJTree.extensions;\n\n //Optional attrs\n this.followAdditionalWrappers = utilities.isDefined(xml.attr(wrapperJTree, 'followAdditionalWrappers'))? xml.attr(wrapperJTree, 'followAdditionalWrappers'): true;\n this.allowMultipleAds = xml.attr(wrapperJTree, 'allowMultipleAds');\n this.fallbackOnNoAd = xml.attr(wrapperJTree, 'fallbackOnNoAd');\n}\n\nmodule.exports = Wrapper;","'use strict';\n\nvar utilities = require('../../utils/utilityFunctions');\n\nvar durationRegex = /(\\d\\d):(\\d\\d):(\\d\\d)(\\.(\\d\\d\\d))?/;\n\nvar parsers = {\n\n duration: function parseDuration(durationStr) {\n\n var match, durationInMs;\n\n if (utilities.isString(durationStr)) {\n match = durationStr.match(durationRegex);\n if (match) {\n durationInMs = parseHoursToMs(match[1]) + parseMinToMs(match[2]) + parseSecToMs(match[3]) + parseInt(match[5] || 0);\n }\n }\n\n return isNaN(durationInMs) ? null : durationInMs;\n\n /*** local functions ***/\n function parseHoursToMs(hourStr) {\n return parseInt(hourStr, 10) * 60 * 60 * 1000;\n }\n\n function parseMinToMs(minStr) {\n return parseInt(minStr, 10) * 60 * 1000;\n }\n\n function parseSecToMs(secStr) {\n return parseInt(secStr, 10) * 1000;\n }\n },\n\n offset: function parseOffset(offset, duration) {\n if(isPercentage(offset)){\n return calculatePercentage(offset, duration);\n }\n return parsers.duration(offset);\n\n /*** Local function ***/\n function isPercentage(offset) {\n var percentageRegex = /^\\d+(\\.\\d+)?%$/g;\n return percentageRegex.test(offset);\n }\n\n function calculatePercentage(percentStr, duration) {\n if(duration) {\n return calcPercent(duration, parseFloat(percentStr.replace('%', '')));\n }\n return null;\n }\n\n function calcPercent(quantity, percent){\n return quantity * percent / 100;\n }\n }\n\n};\n\n\nmodule.exports = parsers;","'use strict';\n\nvar Creative = require('./Creative');\nvar utilities = require('../../utils/utilityFunctions');\n\nvar vastUtil = {\n\n track: function track(URLMacros, variables) {\n var sources = vastUtil.parseURLMacros(URLMacros, variables);\n var trackImgs = [];\n sources.forEach(function (src) {\n var img = new Image();\n img.src = src;\n trackImgs.push(img);\n });\n return trackImgs;\n },\n\n parseURLMacros: function parseMacros(URLMacros, variables) {\n var parsedURLs = [];\n\n variables = variables || {};\n\n if (!(variables[\"CACHEBUSTING\"])) {\n variables[\"CACHEBUSTING\"] = Math.round(Math.random() * 1.0e+10);\n }\n\n URLMacros.forEach(function (URLMacro) {\n parsedURLs.push(vastUtil._parseURLMacro(URLMacro, variables));\n });\n\n return parsedURLs;\n },\n\n parseURLMacro: function parseMacro(URLMacro, variables) {\n variables = variables || {};\n\n if (!(variables[\"CACHEBUSTING\"])) {\n variables[\"CACHEBUSTING\"] = Math.round(Math.random() * 1.0e+10);\n }\n\n return vastUtil._parseURLMacro(URLMacro, variables);\n },\n\n _parseURLMacro: function parseMacro(URLMacro, variables) {\n variables = variables || {};\n\n utilities.forEach(variables, function (value, key) {\n URLMacro = URLMacro.replace(new RegExp(\"\\\\[\" + key + \"\\\\\\]\", 'gm'), value);\n });\n\n return URLMacro;\n },\n\n parseDuration: function parseDuration(durationStr) {\n var durationRegex = /(\\d\\d):(\\d\\d):(\\d\\d)(\\.(\\d\\d\\d))?/;\n var match, durationInMs;\n\n if (utilities.isString(durationStr)) {\n match = durationStr.match(durationRegex);\n if (match) {\n durationInMs = parseHoursToMs(match[1]) + parseMinToMs(match[2]) + parseSecToMs(match[3]) + parseInt(match[5] || 0);\n }\n }\n\n return isNaN(durationInMs) ? null : durationInMs;\n\n /*** local functions ***/\n function parseHoursToMs(hourStr) {\n return parseInt(hourStr, 10) * 60 * 60 * 1000;\n }\n\n function parseMinToMs(minStr) {\n return parseInt(minStr, 10) * 60 * 1000;\n }\n\n function parseSecToMs(secStr) {\n return parseInt(secStr, 10) * 1000;\n }\n },\n\n parseImpressions: function parseImpressions(impressions) {\n if (impressions) {\n impressions = utilities.isArray(impressions) ? impressions : [impressions];\n return utilities.transformArray(impressions, function (impression) {\n if (utilities.isNotEmptyString(impression.keyValue)) {\n return impression.keyValue;\n }\n return undefined;\n });\n }\n return [];\n },\n\n parseCreatives: function parseCreatives(creativesJTree) {\n var creatives = [];\n var creativesData;\n if (utilities.isDefined(creativesJTree) && utilities.isDefined(creativesJTree.creative)) {\n creativesData = utilities.isArray(creativesJTree.creative) ? creativesJTree.creative : [creativesJTree.creative];\n creativesData.forEach(function (creative) {\n creatives.push(new Creative(creative));\n });\n }\n return creatives;\n },\n\n //We assume that the progress is going to arrive in milliseconds\n formatProgress: function formatProgress(progress) {\n var hours, minutes, seconds, milliseconds;\n hours = progress / (60 * 60 * 1000);\n hours = Math.floor(hours);\n minutes = (progress / (60 * 1000)) % 60;\n minutes = Math.floor(minutes);\n seconds = (progress / 1000) % 60;\n seconds = Math.floor(seconds);\n milliseconds = progress % 1000;\n return utilities.toFixedDigits(hours, 2) + ':' + utilities.toFixedDigits(minutes, 2) + ':' + utilities.toFixedDigits(seconds, 2) + '.' + utilities.toFixedDigits(milliseconds, 3);\n },\n\n parseOffset: function parseOffset(offset, duration) {\n if(isPercentage(offset)){\n return calculatePercentage(offset, duration);\n }\n return vastUtil.parseDuration(offset);\n\n /*** Local function ***/\n function isPercentage(offset) {\n var percentageRegex = /^\\d+(\\.\\d+)?%$/g;\n return percentageRegex.test(offset);\n }\n\n function calculatePercentage(percentStr, duration) {\n if(duration) {\n return calcPercent(duration, parseFloat(percentStr.replace('%', '')));\n }\n return null;\n }\n\n function calcPercent(quantity, percent){\n return quantity * percent / 100;\n }\n },\n\n isVPAID: function isVPAIDMediaFile(mediaFile) {\n return !!mediaFile && mediaFile.apiFramework === 'VPAID';\n }\n};\n\n\nmodule.exports = vastUtil;","'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VPAIDAdUnitWrapper(vpaidAdUnit, opts) {\n if (!(this instanceof VPAIDAdUnitWrapper)) {\n return new VPAIDAdUnitWrapper(vpaidAdUnit, opts);\n }\n sanityCheck(vpaidAdUnit, opts);\n\n this.options = utilities.extend({}, opts);\n\n this._adUnit = vpaidAdUnit;\n\n /*** Local Functions ***/\n function sanityCheck(adUnit, opts) {\n if (!adUnit || !VPAIDAdUnitWrapper.checkVPAIDInterface(adUnit)) {\n throw new VASTError('on VPAIDAdUnitWrapper, the passed VPAID adUnit does not fully implement the VPAID interface');\n }\n\n if (!utilities.isObject(opts)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper, expected options hash but got '\" + opts + \"'\");\n }\n\n if (!(\"responseTimeout\" in opts) || !utilities.isNumber(opts.responseTimeout) ){\n throw new VASTError(\"on VPAIDAdUnitWrapper, expected responseTimeout in options\");\n }\n }\n}\n\nVPAIDAdUnitWrapper.checkVPAIDInterface = function checkVPAIDInterface(VPAIDAdUnit) {\n //NOTE: skipAd is not part of the method list because it only appears in VPAID 2.0 and we support VPAID 1.0\n var VPAIDInterfaceMethods = [\n 'handshakeVersion', 'initAd', 'startAd', 'stopAd', 'resizeAd', 'pauseAd', 'expandAd', 'collapseAd'\n ];\n\n for (var i = 0, len = VPAIDInterfaceMethods.length; i < len; i++) {\n if (!VPAIDAdUnit || !utilities.isFunction(VPAIDAdUnit[VPAIDInterfaceMethods[i]])) {\n return false;\n }\n }\n\n\n return canSubscribeToEvents(VPAIDAdUnit) && canUnsubscribeFromEvents(VPAIDAdUnit);\n\n /*** Local Functions ***/\n\n function canSubscribeToEvents(adUnit) {\n return utilities.isFunction(adUnit.subscribe) || utilities.isFunction(adUnit.addEventListener) || utilities.isFunction(adUnit.on);\n }\n\n function canUnsubscribeFromEvents(adUnit) {\n return utilities.isFunction(adUnit.unsubscribe) || utilities.isFunction(adUnit.removeEventListener) || utilities.isFunction(adUnit.off);\n\n }\n};\n\nVPAIDAdUnitWrapper.prototype.adUnitAsyncCall = function () {\n var args = utilities.arrayLikeObjToArray(arguments);\n var method = args.shift();\n var cb = args.pop();\n var timeoutId;\n\n sanityCheck(method, cb, this._adUnit);\n args.push(wrapCallback());\n\n this._adUnit[method].apply(this._adUnit, args);\n timeoutId = setTimeout(function () {\n timeoutId = null;\n cb(new VASTError(\"on VPAIDAdUnitWrapper, timeout while waiting for a response on call '\" + method + \"'\"));\n cb = utilities.noop;\n }, this.options.responseTimeout);\n\n /*** Local functions ***/\n function sanityCheck(method, cb, adUnit) {\n if (!utilities.isString(method) || !utilities.isFunction(adUnit[method])) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.adUnitAsyncCall, invalid method name\");\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.adUnitAsyncCall, missing callback\");\n }\n }\n\n function wrapCallback() {\n return function () {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n cb.apply(this, arguments);\n };\n }\n};\n\nVPAIDAdUnitWrapper.prototype.on = function (evtName, handler) {\n var addEventListener = this._adUnit.addEventListener || this._adUnit.subscribe || this._adUnit.on;\n addEventListener.call(this._adUnit, evtName, handler);\n};\n\nVPAIDAdUnitWrapper.prototype.off = function (evtName, handler) {\n var removeEventListener = this._adUnit.removeEventListener || this._adUnit.unsubscribe || this._adUnit.off;\n removeEventListener.call(this._adUnit, evtName, handler);\n};\n\nVPAIDAdUnitWrapper.prototype.waitForEvent = function (evtName, cb, context) {\n var timeoutId;\n sanityCheck(evtName, cb);\n context = context || null;\n\n this.on(evtName, responseListener);\n\n timeoutId = setTimeout(function () {\n cb(new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, timeout while waiting for event '\" + evtName + \"'\"));\n timeoutId = null;\n cb = utilities.noop;\n }, this.options.responseTimeout);\n\n /*** Local functions ***/\n function sanityCheck(evtName, cb) {\n if (!utilities.isString(evtName)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, missing evt name\");\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(\"on VPAIDAdUnitWrapper.waitForEvent, missing callback\");\n }\n }\n\n function responseListener() {\n var args = utilities.arrayLikeObjToArray(arguments);\n\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n\n args.unshift(null);\n cb.apply(context, args);\n }\n};\n\n// VPAID METHODS\nVPAIDAdUnitWrapper.prototype.handshakeVersion = function (version, cb) {\n this.adUnitAsyncCall('handshakeVersion', version, cb);\n};\n\n/* jshint maxparams:6 */\nVPAIDAdUnitWrapper.prototype.initAd = function (width, height, viewMode, desiredBitrate, adUnitData, cb) {\n this.waitForEvent('AdLoaded', cb);\n this._adUnit.initAd(width, height, viewMode, desiredBitrate, adUnitData);\n};\n\nVPAIDAdUnitWrapper.prototype.resizeAd = function (width, height, viewMode, cb) {\n // NOTE: AdSizeChange event is only supported on VPAID 2.0 so for the moment we are not going to use it\n // and will assume that everything is fine after the async call\n this.adUnitAsyncCall('resizeAd', width, height, viewMode, cb);\n};\n\nVPAIDAdUnitWrapper.prototype.startAd = function (cb) {\n this.waitForEvent('AdStarted', cb);\n this._adUnit.startAd();\n};\n\nVPAIDAdUnitWrapper.prototype.stopAd = function (cb) {\n this.waitForEvent('AdStopped', cb);\n this._adUnit.stopAd();\n};\n\nVPAIDAdUnitWrapper.prototype.pauseAd = function (cb) {\n this.waitForEvent('AdPaused', cb);\n this._adUnit.pauseAd();\n};\n\nVPAIDAdUnitWrapper.prototype.resumeAd = function (cb) {\n this.waitForEvent('AdPlaying', cb);\n this._adUnit.resumeAd();\n};\n\nVPAIDAdUnitWrapper.prototype.expandAd = function (cb) {\n this.waitForEvent('AdExpandedChange', cb);\n this._adUnit.expandAd();\n};\n\nVPAIDAdUnitWrapper.prototype.collapseAd = function (cb) {\n this.waitForEvent('AdExpandedChange', cb);\n this._adUnit.collapseAd();\n};\n\nVPAIDAdUnitWrapper.prototype.skipAd = function (cb) {\n this.waitForEvent('AdSkipped', cb);\n this._adUnit.skipAd();\n};\n\n//VPAID property getters\n[\n 'adLinear',\n 'adWidth',\n 'adHeight',\n 'adExpanded',\n 'adSkippableState',\n 'adRemainingTime',\n 'adDuration',\n 'adVolume',\n 'adCompanions',\n 'adIcons'\n].forEach(function (property) {\n var getterName = 'get' + utilities.capitalize(property);\n\n VPAIDAdUnitWrapper.prototype[getterName] = function (cb) {\n this.adUnitAsyncCall(getterName, cb);\n };\n});\n\n//VPAID property setters\nVPAIDAdUnitWrapper.prototype.setAdVolume = function(volume, cb){\n this.adUnitAsyncCall('setAdVolume',volume, cb);\n};\n\nmodule.exports = VPAIDAdUnitWrapper;\n","'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar VPAIDFLASHClient = require('VPAIDFLASHClient/js/VPAIDFLASHClient');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar dom = require('../../utils/dom');\n\nfunction VPAIDFlashTech(mediaFile, settings) {\n if (!(this instanceof VPAIDFlashTech)) {\n return new VPAIDFlashTech(mediaFile);\n }\n sanityCheck(mediaFile);\n this.name = 'vpaid-flash';\n this.mediaFile = mediaFile;\n this.containerEl = null;\n this.vpaidFlashClient = null;\n this.settings = settings;\n\n /*** local functions ***/\n function sanityCheck(mediaFile) {\n if (!mediaFile || !utilities.isString(mediaFile.src)) {\n throw new VASTError('on VPAIDFlashTech, invalid MediaFile');\n }\n }\n}\n\nVPAIDFlashTech.VPAIDFLASHClient = VPAIDFLASHClient;\n\nVPAIDFlashTech.supports = function (type) {\n return type === 'application/x-shockwave-flash' && VPAIDFlashTech.VPAIDFLASHClient.isSupported();\n};\n\nVPAIDFlashTech.prototype.loadAdUnit = function loadFlashCreative(containerEl, objectEl, callback) {\n var that = this;\n var flashClientOpts = this.settings && this.settings.vpaidFlashLoaderPath ? {data: this.settings.vpaidFlashLoaderPath} : undefined;\n sanityCheck(containerEl, callback);\n\n this.containerEl = containerEl;\n this.vpaidFlashClient = new VPAIDFlashTech.VPAIDFLASHClient(containerEl, function (error) {\n if (error) {\n return callback(error);\n }\n\n that.vpaidFlashClient.loadAdUnit(that.mediaFile.src, callback);\n }, flashClientOpts);\n\n /*** Local Functions ***/\n function sanityCheck(container, cb) {\n\n if (!dom.isDomElement(container)) {\n throw new VASTError('on VPAIDFlashTech.loadAdUnit, invalid dom container element');\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError('on VPAIDFlashTech.loadAdUnit, missing valid callback');\n }\n }\n};\n\nVPAIDFlashTech.prototype.unloadAdUnit = function () {\n if (this.vpaidFlashClient) {\n try{\n this.vpaidFlashClient.destroy();\n } catch(e){\n if(console && utilities.isFunction(console.log)){\n console.log('VAST ERROR: trying to unload the VPAID adunit');\n }\n }\n this.vpaidFlashClient = null;\n }\n\n if (this.containerEl) {\n dom.remove(this.containerEl);\n this.containerEl = null;\n }\n};\n\nmodule.exports = VPAIDFlashTech;","'use strict';\n\nvar VASTError = require('../vast/VASTError');\n\nvar VPAIDHTML5Client = require('VPAIDHTML5Client/js/VPAIDHTML5Client');\n\nvar utilities = require('../../utils/utilityFunctions');\nvar dom = require('../../utils/dom');\n\nfunction VPAIDHTML5Tech(mediaFile) {\n\n if(!(this instanceof VPAIDHTML5Tech)) {\n return new VPAIDHTML5Tech(mediaFile);\n }\n\n sanityCheck(mediaFile);\n\n this.name = 'vpaid-html5';\n this.containerEl = null;\n this.videoEl = null;\n this.vpaidHTMLClient = null;\n\n this.mediaFile = mediaFile;\n\n function sanityCheck(mediaFile) {\n if (!mediaFile || !utilities.isString(mediaFile.src)) {\n throw new VASTError(VPAIDHTML5Tech.INVALID_MEDIA_FILE);\n }\n }\n}\n\nVPAIDHTML5Tech.VPAIDHTML5Client = VPAIDHTML5Client;\n\nVPAIDHTML5Tech.supports = function (type) {\n return !utilities.isOldIE() && type === 'application/javascript';\n};\n\nVPAIDHTML5Tech.prototype.loadAdUnit = function loadAdUnit(containerEl, videoEl, callback) {\n sanityCheck(containerEl, videoEl, callback);\n\n this.containerEl = containerEl;\n this.videoEl = videoEl;\n this.vpaidHTMLClient = new VPAIDHTML5Tech.VPAIDHTML5Client(containerEl, videoEl, {});\n this.vpaidHTMLClient.loadAdUnit(this.mediaFile.src, callback);\n\n function sanityCheck(container, video, cb) {\n if (!dom.isDomElement(container)) {\n throw new VASTError(VPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL);\n }\n\n if (!dom.isDomElement(video) || video.tagName.toLowerCase() !== 'video') {\n throw new VASTError(VPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL);\n }\n\n if (!utilities.isFunction(cb)) {\n throw new VASTError(VPAIDHTML5Tech.MISSING_CALLBACK);\n }\n }\n};\n\nVPAIDHTML5Tech.prototype.unloadAdUnit = function unloadAdUnit() {\n if (this.vpaidHTMLClient) {\n try {\n this.vpaidHTMLClient.destroy();\n } catch(e) {\n if (console && utilities.isFunction(console.log)) {\n console.log('VAST ERROR: trying to unload the VPAID adunit');\n }\n }\n\n this.vpaidHTMLClient = null;\n }\n\n if (this.containerEl) {\n dom.remove(this.containerEl);\n this.containerEl = null;\n }\n};\n\nvar PREFIX = 'on VPAIDHTML5Tech';\nVPAIDHTML5Tech.INVALID_MEDIA_FILE = PREFIX + ', invalid MediaFile';\nVPAIDHTML5Tech.INVALID_DOM_CONTAINER_EL = PREFIX + ', invalid container HtmlElement';\nVPAIDHTML5Tech.INVALID_DOM_VIDEO_EL = PREFIX + ', invalid HTMLVideoElement';\nVPAIDHTML5Tech.MISSING_CALLBACK = PREFIX + ', missing valid callback';\n\nmodule.exports = VPAIDHTML5Tech;","'use strict';\n\nvar VASTError = require('../vast/VASTError');\nvar VASTResponse = require('../vast/VASTResponse');\nvar VASTTracker = require('../vast/VASTTracker');\nvar vastUtil = require('../vast/vastUtil');\n\nvar VPAIDAdUnitWrapper = require('./VPAIDAdUnitWrapper');\nvar VPAIDHTML5Tech = require('./VPAIDHTML5Tech');\nvar VPAIDFlashTech = require('./VPAIDFlashTech');\n\nvar async = require('../../utils/async');\nvar dom = require('../../utils/dom');\nvar playerUtils = require('../../utils/playerUtils');\nvar utilities = require('../../utils/utilityFunctions');\n\nfunction VPAIDIntegrator(player, settings) {\n if (!(this instanceof VPAIDIntegrator)) {\n return new VPAIDIntegrator(player);\n }\n\n this.VIEW_MODE = {\n NORMAL: 'normal',\n FULLSCREEN: \"fullscreen\",\n THUMBNAIL: \"thumbnail\"\n };\n this.player = player;\n this.containerEl = createVPAIDContainerEl(player);\n this.options = {\n responseTimeout: 5000,\n VPAID_VERSION: '2.0'\n };\n this.settings = settings;\n\n /*** Local functions ***/\n\n function createVPAIDContainerEl() {\n var containerEl = document.createElement('div');\n dom.addClass(containerEl, 'VPAID-container');\n player.el().insertBefore(containerEl, player.controlBar.el());\n return containerEl;\n\n }\n}\n\n//List of supported VPAID technologies\nVPAIDIntegrator.techs = [\n VPAIDFlashTech,\n VPAIDHTML5Tech\n];\n\nVPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) {\n var that = this;\n var tech;\n var player = this.player;\n\n callback = callback || utilities.noop;\n if (!(vastResponse instanceof VASTResponse)) {\n return callback(new VASTError('on VASTIntegrator.playAd, missing required VASTResponse'));\n }\n\n tech = this._findSupportedTech(vastResponse, this.settings);\n dom.addClass(player.el(), 'vjs-vpaid-ad');\n\n player.on('vast.adsCancel', triggerVpaidAdEnd);\n player.one('vpaid.adEnd', function(){\n player.off('vast.adsCancel', triggerVpaidAdEnd);\n removeAdUnit();\n });\n\n if (tech) {\n async.waterfall([\n function (next) {\n next(null, tech, vastResponse);\n },\n this._loadAdUnit.bind(this),\n this._playAdUnit.bind(this),\n this._finishPlaying.bind(this)\n\n ], function (error, adUnit, vastResponse) {\n if (error) {\n that._trackError(vastResponse);\n }\n player.trigger('vpaid.adEnd');\n callback(error, vastResponse);\n });\n\n this._adUnit = {\n _paused: true,\n type: 'VPAID',\n pauseAd: function() {\n player.trigger('vpaid.pauseAd');\n player.pause(true);//we make sure that the video content gets stopped.\n },\n resumeAd: function() {\n player.trigger('vpaid.resumeAd');\n },\n isPaused: function() {\n return this._paused;\n },\n getSrc: function() {\n return tech.mediaFile;\n }\n };\n\n return this._adUnit;\n }\n\n callback(new VASTError('on VPAIDIntegrator.playAd, could not find a supported mediaFile'));\n\n return null;\n /*** Local functions ***/\n function triggerVpaidAdEnd(){\n player.trigger('vpaid.adEnd');\n }\n\n function removeAdUnit() {\n if (tech) {\n tech.unloadAdUnit();\n }\n dom.removeClass(player.el(), 'vjs-vpaid-ad');\n }\n};\n\nVPAIDIntegrator.prototype._findSupportedTech = function (vastResponse, settings) {\n if (!(vastResponse instanceof VASTResponse)) {\n return null;\n }\n\n var vpaidMediaFiles = vastResponse.mediaFiles.filter(vastUtil.isVPAID);\n var i, len, mediaFile, VPAIDTech;\n\n for (i = 0, len = vpaidMediaFiles.length; i < len; i += 1) {\n mediaFile = vpaidMediaFiles[i];\n VPAIDTech = findSupportedTech(mediaFile);\n if (VPAIDTech) {\n return new VPAIDTech(mediaFile, settings);\n }\n }\n return null;\n\n /*** Local functions ***/\n function findSupportedTech(mediafile) {\n var type = mediafile.type;\n var i, len, VPAIDTech;\n for (i = 0, len = VPAIDIntegrator.techs.length; i < len; i += 1) {\n VPAIDTech = VPAIDIntegrator.techs[i];\n if (VPAIDTech.supports(type)) {\n return VPAIDTech;\n }\n }\n return null;\n }\n};\n\nVPAIDIntegrator.prototype._createVPAIDAdUnitWrapper = function(adUnit, src, responseTimeout) {\n return new VPAIDAdUnitWrapper(adUnit, {src: src, responseTimeout: responseTimeout});\n};\n\nVPAIDIntegrator.prototype._loadAdUnit = function (tech, vastResponse, next) {\n var that = this;\n var player = this.player;\n var vjsTechEl = player.el().querySelector('.vjs-tech');\n var responseTimeout = this.settings.responseTimeout || this.options.responseTimeout;\n tech.loadAdUnit(this.containerEl, vjsTechEl, function (error, adUnit) {\n if (error) {\n return next(error, adUnit, vastResponse);\n }\n\n try {\n var WrappedAdUnit = that._createVPAIDAdUnitWrapper(adUnit, tech.mediaFile.src, responseTimeout);\n var techClass = 'vjs-' + tech.name + '-ad';\n dom.addClass(player.el(), techClass);\n player.one('vpaid.adEnd', function() {\n dom.removeClass(player.el(),techClass);\n });\n next(null, WrappedAdUnit, vastResponse);\n } catch (e) {\n next(e, adUnit, vastResponse);\n }\n });\n};\n\nVPAIDIntegrator.prototype._playAdUnit = function (adUnit, vastResponse, callback) {\n async.waterfall([\n function (next) {\n next(null, adUnit, vastResponse);\n },\n this._handshake.bind(this),\n this._initAd.bind(this),\n this._setupEvents.bind(this),\n this._addSkipButton.bind(this),\n this._linkPlayerControls.bind(this),\n this._startAd.bind(this)\n ], callback);\n};\n\nVPAIDIntegrator.prototype._handshake = function handshake(adUnit, vastResponse, next) {\n adUnit.handshakeVersion(this.options.VPAID_VERSION, function (error, version) {\n if (error) {\n return next(error, adUnit, vastResponse);\n }\n\n if (version && isSupportedVersion(version)) {\n return next(null, adUnit, vastResponse);\n }\n\n return next(new VASTError('on VPAIDIntegrator._handshake, unsupported version \"' + version + '\"'), adUnit, vastResponse);\n });\n\n function isSupportedVersion(version) {\n var majorNum = major(version);\n return majorNum >= 1 && majorNum <= 2;\n }\n\n function major(version) {\n var parts = version.split('.');\n return parseInt(parts[0], 10);\n }\n};\n\nVPAIDIntegrator.prototype._initAd = function (adUnit, vastResponse, next) {\n var tech = this.player.el().querySelector('.vjs-tech');\n var dimension = dom.getDimension(tech);\n adUnit.initAd(dimension.width, dimension.height, this.VIEW_MODE.NORMAL, -1, {AdParameters: vastResponse.adParameters || ''}, function (error) {\n next(error, adUnit, vastResponse);\n });\n};\n\nVPAIDIntegrator.prototype._createVASTTracker = function(adUnitSrc, vastResponse) {\n return new VASTTracker(adUnitSrc, vastResponse);\n};\n\nVPAIDIntegrator.prototype._setupEvents = function (adUnit, vastResponse, next) {\n var adUnitSrc = adUnit.options.src;\n var tracker = this._createVASTTracker(adUnitSrc, vastResponse);\n var player = this.player;\n var that = this;\n\n adUnit.on('AdSkipped', function () {\n player.trigger('vpaid.AdSkipped');\n tracker.trackSkip();\n });\n\n adUnit.on('AdImpression', function () {\n player.trigger('vpaid.AdImpression');\n tracker.trackImpressions();\n });\n\n adUnit.on('AdStarted', function () {\n player.trigger('vpaid.AdStarted');\n tracker.trackCreativeView();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdVideoStart', function () {\n player.trigger('vpaid.AdVideoStart');\n tracker.trackStart();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdPlaying', function () {\n player.trigger('vpaid.AdPlaying');\n tracker.trackResume();\n notifyPlayToPlayer();\n });\n\n adUnit.on('AdPaused', function () {\n player.trigger('vpaid.AdPaused');\n tracker.trackPause();\n notifyPauseToPlayer();\n });\n\n function notifyPlayToPlayer(){\n if(that._adUnit && that._adUnit.isPaused()){\n that._adUnit._paused = false;\n }\n player.trigger('play');\n\n }\n\n function notifyPauseToPlayer() {\n if(that._adUnit){\n that._adUnit._paused = true;\n }\n player.trigger('pause');\n }\n\n adUnit.on('AdVideoFirstQuartile', function () {\n player.trigger('vpaid.AdVideoFirstQuartile');\n tracker.trackFirstQuartile();\n });\n\n adUnit.on('AdVideoMidpoint', function () {\n player.trigger('vpaid.AdVideoMidpoint');\n tracker.trackMidpoint();\n });\n\n adUnit.on('AdVideoThirdQuartile', function () {\n player.trigger('vpaid.AdVideoThirdQuartile');\n tracker.trackThirdQuartile();\n });\n\n adUnit.on('AdVideoComplete', function () {\n player.trigger('vpaid.AdVideoComplete');\n tracker.trackComplete();\n });\n\n adUnit.on('AdClickThru', function (data) {\n player.trigger('vpaid.AdClickThru');\n var url = data.url;\n var playerHandles = data.playerHandles;\n var clickThruUrl = utilities.isNotEmptyString(url) ? url : generateClickThroughURL(vastResponse.clickThrough);\n\n tracker.trackClick();\n if (playerHandles && clickThruUrl) {\n window.open(clickThruUrl, '_blank');\n }\n\n function generateClickThroughURL(clickThroughMacro) {\n var variables = {\n ASSETURI: adUnit.options.src,\n CONTENTPLAYHEAD: 0 //In VPAID there is no method to know the current time from the adUnit\n };\n\n return clickThroughMacro ? vastUtil.parseURLMacro(clickThroughMacro, variables) : null;\n }\n });\n\n adUnit.on('AdUserAcceptInvitation', function () {\n player.trigger('vpaid.AdUserAcceptInvitation');\n tracker.trackAcceptInvitation();\n tracker.trackAcceptInvitationLinear();\n });\n\n adUnit.on('AdUserClose', function () {\n player.trigger('vpaid.AdUserClose');\n tracker.trackClose();\n tracker.trackCloseLinear();\n });\n\n adUnit.on('AdUserMinimize', function () {\n player.trigger('vpaid.AdUserMinimize');\n tracker.trackCollapse();\n });\n\n adUnit.on('AdError', function () {\n player.trigger('vpaid.AdError');\n //NOTE: we track errors code 901, as noted in VAST 3.0\n tracker.trackErrorWithCode(901);\n });\n\n adUnit.on('AdVolumeChange', function () {\n player.trigger('vpaid.AdVolumeChange');\n var lastVolume = player.volume();\n adUnit.getAdVolume(function (error, currentVolume) {\n if (currentVolume === 0 && lastVolume > 0) {\n tracker.trackMute();\n }\n\n if (currentVolume > 0 && lastVolume === 0) {\n tracker.trackUnmute();\n }\n\n player.volume(currentVolume);\n });\n });\n\n var updateViewSize = resizeAd.bind(this, player, adUnit, this.VIEW_MODE);\n var updateViewSizeThrottled = utilities.throttle(updateViewSize, 100);\n var autoResize = this.settings.autoResize;\n\n if (autoResize) {\n dom.addEventListener(window, 'resize', updateViewSizeThrottled);\n dom.addEventListener(window, 'orientationchange', updateViewSizeThrottled);\n }\n\n player.on('vast.resize', updateViewSize);\n player.on('vpaid.pauseAd', pauseAdUnit);\n player.on('vpaid.resumeAd', resumeAdUnit);\n\n player.one('vpaid.adEnd', function () {\n player.off('vast.resize', updateViewSize);\n player.off('vpaid.pauseAd', pauseAdUnit);\n player.off('vpaid.resumeAd', resumeAdUnit);\n\n if (autoResize) {\n dom.removeEventListener(window, 'resize', updateViewSizeThrottled);\n dom.removeEventListener(window, 'orientationchange', updateViewSizeThrottled);\n }\n });\n\n next(null, adUnit, vastResponse);\n\n /*** Local Functions ***/\n function pauseAdUnit() {\n adUnit.pauseAd(utilities.noop);\n }\n\n function resumeAdUnit() {\n adUnit.resumeAd(utilities.noop);\n }\n};\n\nVPAIDIntegrator.prototype._addSkipButton = function (adUnit, vastResponse, next) {\n var skipButton;\n var player = this.player;\n\n adUnit.on('AdSkippableStateChange', updateSkipButtonState);\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeSkipButton);\n\n next(null, adUnit, vastResponse);\n\n /*** Local function ***/\n function updateSkipButtonState() {\n player.trigger('vpaid.AdSkippableStateChange');\n adUnit.getAdSkippableState(function (error, isSkippable) {\n if (isSkippable) {\n if (!skipButton) {\n addSkipButton(player);\n }\n } else {\n removeSkipButton(player);\n }\n });\n }\n\n function addSkipButton(player) {\n skipButton = createSkipButton(player);\n player.el().appendChild(skipButton);\n }\n\n function removeSkipButton() {\n dom.remove(skipButton);\n skipButton = null;\n }\n\n function createSkipButton() {\n var skipButton = window.document.createElement(\"div\");\n dom.addClass(skipButton, \"vast-skip-button\");\n dom.addClass(skipButton, \"enabled\");\n skipButton.innerHTML = \"Skip ad\";\n\n skipButton.onclick = function (e) {\n adUnit.skipAd(utilities.noop);//We skip the adUnit\n\n //We prevent event propagation to avoid problems with the clickThrough and so on\n if (window.Event.prototype.stopPropagation !== undefined) {\n e.stopPropagation();\n } else {\n return false;\n }\n };\n\n return skipButton;\n }\n};\n\nVPAIDIntegrator.prototype._linkPlayerControls = function (adUnit, vastResponse, next) {\n var that = this;\n linkVolumeControl(this.player, adUnit);\n linkFullScreenControl(this.player, adUnit, this.VIEW_MODE);\n\n next(null, adUnit, vastResponse);\n\n /*** Local functions ***/\n function linkVolumeControl(player, adUnit) {\n player.on('volumechange', updateAdUnitVolume);\n adUnit.on('AdVolumeChange', updatePlayerVolume);\n\n player.one('vpaid.adEnd', function () {\n player.off('volumechange', updateAdUnitVolume);\n });\n\n\n /*** local functions ***/\n function updateAdUnitVolume() {\n var vol = player.muted() ? 0 : player.volume();\n adUnit.setAdVolume(vol, logError);\n }\n\n function updatePlayerVolume() {\n player.trigger('vpaid.AdVolumeChange');\n adUnit.getAdVolume(function (error, vol) {\n if (error) {\n logError(error);\n } else {\n player.volume(vol);\n }\n });\n }\n }\n\n function linkFullScreenControl(player, adUnit, VIEW_MODE) {\n var updateViewSize = resizeAd.bind(that, player, adUnit, VIEW_MODE);\n\n player.on('fullscreenchange', updateViewSize);\n\n player.one('vpaid.adEnd', function () {\n player.off('fullscreenchange', updateViewSize);\n });\n }\n};\n\nVPAIDIntegrator.prototype._startAd = function (adUnit, vastResponse, next) {\n var player = this.player;\n\n adUnit.startAd(function (error) {\n if (!error) {\n player.trigger('vast.adStart');\n }\n next(error, adUnit, vastResponse);\n });\n};\n\nVPAIDIntegrator.prototype._finishPlaying = function (adUnit, vastResponse, next) {\n var player = this.player;\n adUnit.on('AdStopped', function () {\n player.trigger('vpaid.AdStopped');\n finishPlayingAd(null);\n });\n\n adUnit.on('AdError', function (error) {\n var errMsg = error? error.message : 'on VPAIDIntegrator, error while waiting for the adUnit to finish playing';\n finishPlayingAd(new VASTError(errMsg));\n });\n\n /*** local functions ***/\n function finishPlayingAd(error) {\n next(error, adUnit, vastResponse);\n }\n};\n\nVPAIDIntegrator.prototype._trackError = function trackError(response) {\n vastUtil.track(response.errorURLMacros, {ERRORCODE: 901});\n};\n\nfunction resizeAd(player, adUnit, VIEW_MODE) {\n var tech = player.el().querySelector('.vjs-tech');\n var dimension = dom.getDimension(tech);\n var MODE = player.isFullscreen() ? VIEW_MODE.FULLSCREEN : VIEW_MODE.NORMAL;\n adUnit.resizeAd(dimension.width, dimension.height, MODE, logError);\n}\n\nfunction logError(error) {\n if (error && console && console.log) {\n console.log('ERROR: ' + error.message, error);\n }\n}\n\nmodule.exports = VPAIDIntegrator;","'use strict';\n\nvar dom = require('../../utils/dom');\n\nvar element = document.createElement('div');\nelement.className = 'vjs-ads-label vjs-control vjs-label-hidden';\nelement.innerHTML = 'Advertisement';\n\nvar AdsLabelFactory = function(baseComponent) {\n return {\n /** @constructor */\n init: function init(player, options) {\n options.el = element;\n baseComponent.call(this, player, options);\n\n // We asynchronously reposition the ads label element\n setTimeout(function () {\n var currentTimeComp = player.controlBar &&( player.controlBar.getChild(\"timerControls\") || player.controlBar.getChild(\"currentTimeDisplay\") );\n if(currentTimeComp) {\n player.controlBar.el().insertBefore(element, currentTimeComp.el());\n }\n dom.removeClass(element, 'vjs-label-hidden');\n }, 0);\n },\n\n el: function getElement() {\n return element;\n }\n };\n};\n\nmodule.exports = AdsLabelFactory;","'use strict';\n\nvar baseVideoJsComponent = videojs.getComponent('Component');\n\nvar AdsLabel = require('./ads-label')(baseVideoJsComponent);\n\nvideojs.registerComponent('AdsLabel', videojs.extend(baseVideoJsComponent, AdsLabel));\n","'use strict';\n\n/**\n * The component that shows a black screen until the ads plugin has decided if it can or it can not play the ad.\n *\n * Note: In case you wonder why instead of this black poster we don't just show the spinner loader.\n * IOS devices do not work well with animations and the browser chrashes from time to time That is why we chose to\n * have a secondary black poster.\n *\n * It also makes it much more easier for the users of the plugin since it does not change the default behaviour of the\n * spinner and the player works the same way with and without the plugin.\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvar element = document.createElement('div');\n\nvar BlackPosterFactory = function(baseComponent) {\n return {\n /** @constructor */\n init: function init(player, options) {\n options.el = element;\n element.className = 'vjs-black-poster';\n baseComponent.call(this, player, options);\n\n var posterImg = player.getChild('posterImage');\n\n //We need to do it asynchronously to be sure that the black poster el is on the dom.\n setTimeout(function() {\n if(posterImg && player && player.el()) {\n player.el().insertBefore(element, posterImg.el());\n }\n }, 0);\n },\n el: function getElement() {\n return element;\n }\n };\n};\n\nmodule.exports = BlackPosterFactory;","'use strict';\n\nvar baseVideoJsComponent = videojs.getComponent('Component');\n\nvar BlackPoster = require('./black-poster')(baseVideoJsComponent);\n\nvideojs.registerComponent('BlackPoster', videojs.extend(baseVideoJsComponent, BlackPoster));\n","'use strict';\n\nvar VASTClient = require('../ads/vast/VASTClient');\nvar VASTError = require('../ads/vast/VASTError');\nvar vastUtil = require('../ads/vast/vastUtil');\n\nvar VASTIntegrator = require('../ads/vast/VASTIntegrator');\nvar VPAIDIntegrator = require('../ads/vpaid/VPAIDIntegrator');\n\nvar async = require('../utils/async');\nvar dom = require('../utils/dom');\nvar playerUtils = require('../utils/playerUtils');\nvar utilities = require('../utils/utilityFunctions');\n\nmodule.exports = function VASTPlugin(options) {\n var snapshot;\n var player = this;\n var vast = new VASTClient();\n var adsCanceled = false;\n var defaultOpts = {\n // maximum amount of time in ms to wait to receive `adsready` from the ad\n // implementation after play has been requested. Ad implementations are\n // expected to load any dynamic libraries and make any requests to determine\n // ad policies for a video during this time.\n timeout: 500,\n\n //TODO:finish this IOS FIX\n //Whenever you play an add on IOS, the native player kicks in and we loose control of it. On very heavy pages the 'play' event\n // May occur after the video content has already started. This is wrong if you want to play a preroll ad that needs to happen before the user\n // starts watching the content. To prevent this usec\n iosPrerollCancelTimeout: 2000,\n\n // maximun amount of time for the ad to actually start playing. If this timeout gets\n // triggered the ads will be cancelled\n adCancelTimeout: 3000,\n\n // Boolean flag that configures the player to play a new ad before the user sees the video again\n // the current video\n playAdAlways: false,\n\n // Flag to enable or disable the ads by default.\n adsEnabled: true,\n\n // Boolean flag to enable or disable the resize with window.resize or orientationchange\n autoResize: true,\n\n // Path to the VPAID flash ad's loader\n vpaidFlashLoaderPath: '/VPAIDFlash.swf'\n };\n\n var settings = utilities.extend({}, defaultOpts, options || {});\n\n if(utilities.isUndefined(settings.adTagUrl) && utilities.isDefined(settings.url)){\n settings.adTagUrl = settings.url;\n }\n\n if (utilities.isString(settings.adTagUrl)) {\n settings.adTagUrl = utilities.echoFn(settings.adTagUrl);\n }\n\n if (utilities.isDefined(settings.adTagXML) && !utilities.isFunction(settings.adTagXML)) {\n return trackAdError(new VASTError('on VideoJS VAST plugin, the passed adTagXML option does not contain a function'));\n }\n\n if (!utilities.isDefined(settings.adTagUrl) && !utilities.isFunction(settings.adTagXML)) {\n return trackAdError(new VASTError('on VideoJS VAST plugin, missing adTagUrl on options object'));\n }\n\n playerUtils.prepareForAds(player);\n\n if (settings.playAdAlways) {\n // No matter what happens we play a new ad before the user sees the video again.\n player.on('vast.contentEnd', function () {\n setTimeout(function () {\n player.trigger('vast.reset');\n }, 0);\n });\n }\n\n player.on('vast.firstPlay', tryToPlayPrerollAd);\n\n player.on('vast.reset', function () {\n //If we are reseting the plugin, we don't want to restore the content\n snapshot = null;\n cancelAds();\n });\n\n player.vast = {\n isEnabled: function () {\n return settings.adsEnabled;\n },\n\n enable: function () {\n settings.adsEnabled = true;\n },\n\n disable: function () {\n settings.adsEnabled = false;\n }\n };\n\n return player.vast;\n\n /**** Local functions ****/\n function tryToPlayPrerollAd() {\n //We remove the poster to prevent flickering whenever the content starts playing\n playerUtils.removeNativePoster(player);\n\n playerUtils.once(player, ['vast.adsCancel', 'vast.adEnd'], function () {\n removeAdUnit();\n restoreVideoContent();\n });\n\n async.waterfall([\n checkAdsEnabled,\n preparePlayerForAd,\n startAdCancelTimeout,\n playPrerollAd\n ], function (error, response) {\n if (error) {\n trackAdError(error, response);\n } else {\n player.trigger('vast.adEnd');\n }\n });\n\n /*** Local functions ***/\n\n function removeAdUnit() {\n if (player.vast && player.vast.adUnit) {\n player.vast.adUnit = null; //We remove the adUnit\n }\n }\n\n function restoreVideoContent() {\n setupContentEvents();\n if (snapshot) {\n playerUtils.restorePlayerSnapshot(player, snapshot);\n snapshot = null;\n }\n }\n\n function setupContentEvents() {\n playerUtils.once(player, ['playing', 'vast.reset', 'vast.firstPlay'], function (evt) {\n if (evt.type !== 'playing') {\n return;\n }\n\n player.trigger('vast.contentStart');\n\n playerUtils.once(player, ['ended', 'vast.reset', 'vast.firstPlay'], function (evt) {\n if (evt.type === 'ended') {\n player.trigger('vast.contentEnd');\n }\n });\n });\n }\n\n function checkAdsEnabled(next) {\n if (settings.adsEnabled) {\n return next(null);\n }\n next(new VASTError('Ads are not enabled'));\n }\n\n function preparePlayerForAd(next) {\n if (canPlayPrerollAd()) {\n snapshot = playerUtils.getPlayerSnapshot(player);\n player.pause();\n addSpinnerIcon();\n\n if(player.paused()) {\n next(null);\n } else {\n playerUtils.once(player, ['playing'], function() {\n player.pause();\n next(null);\n });\n }\n } else {\n next(new VASTError('video content has been playing before preroll ad'));\n }\n }\n\n function canPlayPrerollAd() {\n return !utilities.isIPhone() || player.currentTime() <= settings.iosPrerollCancelTimeout;\n }\n\n function startAdCancelTimeout(next) {\n var adCancelTimeoutId;\n adsCanceled = false;\n\n adCancelTimeoutId = setTimeout(function () {\n trackAdError(new VASTError('timeout while waiting for the video to start playing', 402));\n }, settings.adCancelTimeout);\n\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], clearAdCancelTimeout);\n\n /*** local functions ***/\n function clearAdCancelTimeout() {\n if (adCancelTimeoutId) {\n clearTimeout(adCancelTimeoutId);\n adCancelTimeoutId = null;\n }\n }\n\n next(null);\n }\n\n function addSpinnerIcon() {\n dom.addClass(player.el(), 'vjs-vast-ad-loading');\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], removeSpinnerIcon);\n }\n\n function removeSpinnerIcon() {\n //IMPORTANT NOTE: We remove the spinnerIcon asynchronously to give time to the browser to start the video.\n // If we remove it synchronously we see a flash of the content video before the ad starts playing.\n setTimeout(function () {\n dom.removeClass(player.el(), 'vjs-vast-ad-loading');\n }, 100);\n }\n\n }\n\n function cancelAds() {\n player.trigger('vast.adsCancel');\n adsCanceled = true;\n }\n\n function playPrerollAd(callback) {\n async.waterfall([\n getVastResponse,\n playAd\n ], callback);\n }\n\n function getVastResponse(callback) {\n vast.getVASTResponse(settings.adTagUrl ? settings.adTagUrl() : settings.adTagXML, callback);\n }\n\n function playAd(vastResponse, callback) {\n //TODO: Find a better way to stop the play. The 'playPrerollWaterfall' ends in an inconsistent situation\n //If the state is not 'preroll?' it means the ads were canceled therefore, we break the waterfall\n if (adsCanceled) {\n return;\n }\n\n var adIntegrator = isVPAID(vastResponse) ? new VPAIDIntegrator(player, settings) : new VASTIntegrator(player);\n var adFinished = false;\n\n playerUtils.once(player, ['vast.adStart', 'vast.adsCancel'], function (evt) {\n if (evt.type === 'vast.adStart') {\n addAdsLabel();\n }\n });\n\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel'], removeAdsLabel);\n\n if (utilities.isIDevice()) {\n preventManualProgress();\n }\n\n player.vast.vastResponse = vastResponse;\n player.vast.adUnit = adIntegrator.playAd(vastResponse, callback);\n\n /*** Local functions ****/\n function addAdsLabel() {\n if (adFinished || player.controlBar.getChild('AdsLabel')) {\n return;\n }\n\n player.controlBar.addChild('AdsLabel');\n }\n\n function removeAdsLabel() {\n player.controlBar.removeChild('AdsLabel');\n adFinished = true;\n }\n\n function preventManualProgress() {\n //IOS video clock is very unreliable and we need a 3 seconds threshold to ensure that the user forwarded/rewound the ad\n var PROGRESS_THRESHOLD = 3;\n var previousTime = 0;\n var skipad_attempts = 0;\n\n player.on('timeupdate', adTimeupdateHandler);\n playerUtils.once(player, ['vast.adEnd', 'vast.adsCancel', 'vast.adError'], stopPreventManualProgress);\n\n /*** Local functions ***/\n function adTimeupdateHandler() {\n var currentTime = player.currentTime();\n var progressDelta = Math.abs(currentTime - previousTime);\n\n if (progressDelta > PROGRESS_THRESHOLD) {\n skipad_attempts += 1;\n if (skipad_attempts >= 2) {\n player.pause();\n }\n player.currentTime(previousTime);\n } else {\n previousTime = currentTime;\n }\n }\n\n function stopPreventManualProgress() {\n player.off('timeupdate', adTimeupdateHandler);\n }\n }\n }\n\n function trackAdError(error, vastResponse) {\n player.trigger({type: 'vast.adError', error: error});\n cancelAds();\n if (console && console.log) {\n console.log('AD ERROR:', error.message, error, vastResponse);\n }\n }\n\n function isVPAID(vastResponse) {\n var i, len;\n var mediaFiles = vastResponse.mediaFiles;\n for (i = 0, len = mediaFiles.length; i < len; i++) {\n if (vastUtil.isVPAID(mediaFiles[i])) {\n return true;\n }\n }\n return false;\n }\n};","//Small subset of async\n\nvar utilities = require('./utilityFunctions');\n\nvar async = {};\n\nasync.setImmediate = function (fn) {\n setTimeout(fn, 0);\n};\n\nasync.iterator = function (tasks) {\n var makeCallback = function (index) {\n var fn = function () {\n if (tasks.length) {\n tasks[index].apply(null, arguments);\n }\n return fn.next();\n };\n fn.next = function () {\n return (index < tasks.length - 1) ? makeCallback(index + 1) : null;\n };\n return fn;\n };\n return makeCallback(0);\n};\n\n\nasync.waterfall = function (tasks, callback) {\n callback = callback || function () { };\n if (!utilities.isArray(tasks)) {\n var err = new Error('First argument to waterfall must be an array of functions');\n return callback(err);\n }\n if (!tasks.length) {\n return callback();\n }\n var wrapIterator = function (iterator) {\n return function (err) {\n if (err) {\n callback.apply(null, arguments);\n callback = function () {\n };\n }\n else {\n var args = Array.prototype.slice.call(arguments, 1);\n var next = iterator.next();\n if (next) {\n args.push(wrapIterator(next));\n }\n else {\n args.push(callback);\n }\n async.setImmediate(function () {\n iterator.apply(null, args);\n });\n }\n };\n };\n wrapIterator(async.iterator(tasks))();\n};\n\nasync.when = function (condition, callback) {\n if (!utilities.isFunction(callback)) {\n throw new Error(\"async.when error: missing callback argument\");\n }\n\n var isAllowed = utilities.isFunction(condition) ? condition : function () {\n return !!condition;\n };\n\n return function () {\n var args = utilities.arrayLikeObjToArray(arguments);\n var next = args.pop();\n\n if (isAllowed.apply(null, args)) {\n return callback.apply(this, arguments);\n }\n\n args.unshift(null);\n return next.apply(null, args);\n };\n};\n\nmodule.exports = async;\n\n","'use strict';\n\nvar utilities = require('./utilityFunctions');\n\nvar dom = {};\n\ndom.isVisible = function isVisible(el) {\n var style = window.getComputedStyle(el);\n return style.visibility !== 'hidden';\n};\n\ndom.isHidden = function isHidden(el) {\n var style = window.getComputedStyle(el);\n return style.display === 'none';\n};\n\ndom.isShown = function isShown(el) {\n return !dom.isHidden(el);\n};\n\ndom.hide = function hide(el) {\n el.__prev_style_display_ = el.style.display;\n el.style.display = 'none';\n};\n\ndom.show = function show(el) {\n if (dom.isHidden(el)) {\n el.style.display = el.__prev_style_display_;\n }\n el.__prev_style_display_ = undefined;\n};\n\ndom.hasClass = function hasClass(el, cssClass) {\n var classes, i, len;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.contains(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n cssClass = (cssClass || '');\n\n for (i = 0, len = classes.length; i < len; i += 1) {\n if (classes[i] === cssClass) {\n return true;\n }\n }\n }\n return false;\n};\n\ndom.addClass = function (el, cssClass) {\n var classes;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.add(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n if (utilities.isString(cssClass) && utilities.isNotEmptyString(cssClass.replace(/\\s+/, ''))) {\n classes.push(cssClass);\n el.setAttribute('class', classes.join(' '));\n }\n }\n};\n\ndom.removeClass = function (el, cssClass) {\n var classes;\n\n if (utilities.isNotEmptyString(cssClass)) {\n if (el.classList) {\n return el.classList.remove(cssClass);\n }\n\n classes = utilities.isString(el.getAttribute('class')) ? el.getAttribute('class').split(/\\s+/) : [];\n var newClasses = [];\n var i, len;\n if (utilities.isString(cssClass) && utilities.isNotEmptyString(cssClass.replace(/\\s+/, ''))) {\n\n for (i = 0, len = classes.length; i < len; i += 1) {\n if (cssClass !== classes[i]) {\n newClasses.push(classes[i]);\n }\n }\n el.setAttribute('class', newClasses.join(' '));\n }\n }\n};\n\ndom.addEventListener = function addEventListener(el, type, handler) {\n if(utilities.isArray(el)){\n utilities.forEach(el, function(e) {\n dom.addEventListener(e, type, handler);\n });\n return;\n }\n\n if(utilities.isArray(type)){\n utilities.forEach(type, function(t) {\n dom.addEventListener(el, t, handler);\n });\n return;\n }\n\n if (el.addEventListener) {\n el.addEventListener(type, handler, false);\n } else if (el.attachEvent) {\n // WARNING!!! this is a very naive implementation !\n // the event object that should be passed to the handler\n // would not be there for IE8\n // we should use \"window.event\" and then \"event.srcElement\"\n // instead of \"event.target\"\n el.attachEvent(\"on\" + type, handler);\n }\n};\n\ndom.removeEventListener = function removeEventListener(el, type, handler) {\n if(utilities.isArray(el)){\n utilities.forEach(el, function(e) {\n dom.removeEventListener(e, type, handler);\n });\n return;\n }\n\n if(utilities.isArray(type)){\n utilities.forEach(type, function(t) {\n dom.removeEventListener(el, t, handler);\n });\n return;\n }\n\n if (el.removeEventListener) {\n el.removeEventListener(type, handler, false);\n } else if (el.detachEvent) {\n el.detachEvent(\"on\" + type, handler);\n } else {\n el[\"on\" + type] = null;\n }\n};\n\ndom.dispatchEvent = function dispatchEvent(el, event) {\n if (el.dispatchEvent) {\n el.dispatchEvent(event);\n } else {\n el.fireEvent(\"on\" + event.eventType, event);\n }\n};\n\ndom.isDescendant = function isDescendant(parent, child) {\n var node = child.parentNode;\n while (node !== null) {\n if (node === parent) {\n return true;\n }\n node = node.parentNode;\n }\n return false;\n};\n\ndom.getTextContent = function getTextContent(el){\n return el.textContent || el.text;\n};\n\ndom.prependChild = function prependChild(parent, child) {\n if(child.parentNode){\n child.parentNode.removeChild(child);\n }\n return parent.insertBefore(child, parent.firstChild);\n};\n\ndom.remove = function removeNode(node){\n if(node && node.parentNode){\n node.parentNode.removeChild(node);\n }\n};\n\ndom.isDomElement = function isDomElement(o) {\n return o instanceof Element;\n};\n\ndom.click = function(el, handler) {\n dom.addEventListener(el, 'click', handler);\n};\n\ndom.once = function(el, type, handler) {\n function handlerWrap() {\n handler.apply(null, arguments);\n dom.removeEventListener(el, type, handlerWrap);\n }\n\n dom.addEventListener(el, type, handlerWrap);\n};\n\n//Note: there is no getBoundingClientRect on iPad so we need a fallback\ndom.getDimension = function getDimension(element) {\n var rect;\n\n //On IE9 and below getBoundingClientRect does not work consistently\n if(!utilities.isOldIE() && element.getBoundingClientRect) {\n rect = element.getBoundingClientRect();\n return {\n width: rect.width,\n height: rect.height\n };\n }\n\n return {\n width: element.offsetWidth,\n height: element.offsetHeight\n };\n};\n\nmodule.exports = dom;","'use strict';\n\nvar urlUtils = require('./urlUtils');\nvar utilities = require('./utilityFunctions');\n\nfunction HttpRequestError(message) {\n this.message = 'HttpRequest Error: ' + (message || '');\n}\nHttpRequestError.prototype = new Error();\nHttpRequestError.prototype.name = \"HttpRequest Error\";\n\nfunction HttpRequest(createXhr) {\n if (!utilities.isFunction(createXhr)) {\n throw new HttpRequestError('Missing XMLHttpRequest factory method');\n }\n\n this.createXhr = createXhr;\n}\n\nHttpRequest.prototype.run = function (method, url, callback, options) {\n sanityCheck(url, callback, options);\n var timeout, timeoutId;\n var xhr = this.createXhr();\n options = options || {};\n timeout = utilities.isNumber(options.timeout) ? options.timeout : 0;\n\n xhr.open(method, urlUtils.urlParts(url).href, true);\n\n if (options.headers) {\n setHeaders(xhr, options.headers);\n }\n\n if (options.withCredentials) {\n xhr.withCredentials = true;\n }\n\n xhr.onload = function () {\n var statusText, response, status;\n\n /**\n * The only way to do a secure request on IE8 and IE9 is with the XDomainRequest object. Unfortunately, microsoft is\n * so nice that decided that the status property and the 'getAllResponseHeaders' method where not needed so we have to\n * fake them. If the request gets done with an XDomainRequest instance, we will assume that there are no headers and\n * the status will always be 200. If you don't like it, DO NOT USE ANCIENT BROWSERS!!!\n *\n * For mor info go to: https://msdn.microsoft.com/en-us/library/cc288060(v=vs.85).aspx\n */\n if (!xhr.getAllResponseHeaders) {\n xhr.getAllResponseHeaders = function () {\n return null;\n };\n }\n\n if (!xhr.status) {\n xhr.status = 200;\n }\n\n if (utilities.isDefined(timeoutId)) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n\n statusText = xhr.statusText || '';\n\n // responseText is the old-school way of retrieving response (supported by IE8 & 9)\n // response/responseType properties were introduced in XHR Level2 spec (supported by IE10)\n response = ('response' in xhr) ? xhr.response : xhr.responseText;\n\n // normalize IE9 bug (http://bugs.jquery.com/ticket/1450)\n status = xhr.status === 1223 ? 204 : xhr.status;\n\n callback(\n status,\n response,\n xhr.getAllResponseHeaders(),\n statusText);\n };\n\n xhr.onerror = requestError;\n xhr.onabort = requestError;\n\n xhr.send();\n\n if (timeout > 0) {\n timeoutId = setTimeout(function () {\n xhr && xhr.abort();\n }, timeout);\n }\n\n function sanityCheck(url, callback, options) {\n if (!utilities.isString(url) || utilities.isEmptyString(url)) {\n throw new HttpRequestError(\"Invalid url '\" + url + \"'\");\n }\n\n if (!utilities.isFunction(callback)) {\n throw new HttpRequestError(\"Invalid handler '\" + callback + \"' for the http request\");\n }\n\n if (utilities.isDefined(options) && !utilities.isObject(options)) {\n throw new HttpRequestError(\"Invalid options map '\" + options + \"'\");\n }\n }\n\n function setHeaders(xhr, headers) {\n utilities.forEach(headers, function (value, key) {\n if (utilities.isDefined(value)) {\n xhr.setRequestHeader(key, value);\n }\n });\n }\n\n function requestError() {\n callback(-1, null, null, '');\n }\n};\n\nHttpRequest.prototype.get = function (url, callback, options) {\n this.run('GET', url, processResponse, options);\n\n function processResponse(status, response, headersString, statusText) {\n if (isSuccess(status)) {\n callback(null, response, status, headersString, statusText);\n } else {\n callback(new HttpRequestError(statusText), response, status, headersString, statusText);\n }\n }\n\n function isSuccess(status) {\n return 200 <= status && status < 300;\n }\n};\n\nfunction createXhr() {\n var xhr = new XMLHttpRequest();\n if (!(\"withCredentials\" in xhr)) {\n // XDomainRequest for IE.\n xhr = new XDomainRequest();\n }\n return xhr;\n}\n\nvar http = new HttpRequest(createXhr);\n\nmodule.exports = {\n http: http,\n HttpRequest: HttpRequest,\n HttpRequestError: HttpRequestError,\n createXhr: createXhr\n};\n","'use strict';\n\nvar dom = require('./dom');\nvar utilities = require('./utilityFunctions');\n\nvar playerUtils = {};\n\n/**\n * Returns an object that captures the portions of player state relevant to\n * video playback. The result of this function can be passed to\n * restorePlayerSnapshot with a player to return the player to the state it\n * was in when this function was invoked.\n * @param {object} player The videojs player object\n */\nplayerUtils.getPlayerSnapshot = function getPlayerSnapshot(player) {\n var tech = player.el().querySelector('.vjs-tech');\n\n var snapshot = {\n ended: player.ended(),\n src: player.currentSrc(),\n currentTime: player.currentTime(),\n type: player.currentType(),\n playing: !player.paused(),\n suppressedTracks: getSuppressedTracks(player)\n };\n\n if (tech) {\n snapshot.nativePoster = tech.poster;\n snapshot.style = tech.getAttribute('style');\n }\n return snapshot;\n\n /**** Local Functions ****/\n function getSuppressedTracks(player) {\n var tracks = player.remoteTextTracks ? player.remoteTextTracks() : [];\n\n if (tracks && utilities.isArray(tracks.tracks_)) {\n tracks = tracks.tracks_;\n }\n\n if (!utilities.isArray(tracks)) {\n tracks = [];\n }\n\n var suppressedTracks = [];\n tracks.forEach(function (track) {\n suppressedTracks.push({\n track: track,\n mode: track.mode\n });\n track.mode = 'disabled';\n });\n\n return suppressedTracks;\n }\n};\n\n/**\n * Attempts to modify the specified player so that its state is equivalent to\n * the state of the snapshot.\n * @param {object} snapshot - the player state to apply\n */\nplayerUtils.restorePlayerSnapshot = function restorePlayerSnapshot(player, snapshot) {\n var tech = player.el().querySelector('.vjs-tech');\n var attempts = 20; // the number of remaining attempts to restore the snapshot\n\n if (snapshot.nativePoster) {\n tech.poster = snapshot.nativePoster;\n }\n\n if ('style' in snapshot) {\n // overwrite all css style properties to restore state precisely\n tech.setAttribute('style', snapshot.style || '');\n }\n\n if (hasSrcChanged(player, snapshot)) {\n\n // on ios7, fiddling with textTracks too early will cause safari to crash\n player.one('contentloadedmetadata', restoreTracks);\n\n player.one('canplay', tryToResume);\n ensureCanplayEvtGetsFired();\n\n // if the src changed for ad playback, reset it\n player.src({src: snapshot.src, type: snapshot.type});\n\n // safari requires a call to `load` to pick up a changed source\n player.load();\n\n } else {\n restoreTracks();\n\n if (snapshot.playing) {\n player.play();\n }\n }\n\n /*** Local Functions ***/\n\n /**\n * Sometimes firefox does not trigger the 'canplay' evt.\n * This code ensure that it always gets triggered triggered.\n */\n function ensureCanplayEvtGetsFired() {\n var timeoutId = setTimeout(function() {\n player.trigger('canplay');\n }, 1000);\n\n player.one('canplay', function(){\n clearTimeout(timeoutId);\n });\n }\n\n /**\n * Determine whether the player needs to be restored to its state\n * before ad playback began. With a custom ad display or burned-in\n * ads, the content player state hasn't been modified and so no\n * restoration is required\n */\n function hasSrcChanged(player, snapshot) {\n if (player.src()) {\n return player.src() !== snapshot.src;\n }\n // the player was configured through source element children\n return player.currentSrc() !== snapshot.src;\n }\n\n function restoreTracks() {\n var suppressedTracks = snapshot.suppressedTracks;\n suppressedTracks.forEach(function (trackSnapshot) {\n trackSnapshot.track.mode = trackSnapshot.mode;\n });\n }\n\n /**\n * Determine if the video element has loaded enough of the snapshot source\n * to be ready to apply the rest of the state\n */\n function tryToResume() {\n\n // if some period of the video is seekable, resume playback\n // otherwise delay a bit and then check again unless we're out of attempts\n\n if (!playerUtils.isReadyToResume(player) && attempts--) {\n setTimeout(tryToResume, 50);\n } else {\n try {\n if(player.currentTime() !== snapshot.currentTime) {\n if (snapshot.playing) { // if needed restore playing status after seek completes\n player.one('seeked', function() {\n player.play();\n });\n }\n player.currentTime(snapshot.currentTime);\n\n } else if (snapshot.playing) {\n // if needed and no seek has been performed, restore playing status immediately\n player.play();\n }\n\n } catch (e) {\n videojs.log.warn('Failed to resume the content after an advertisement', e);\n }\n }\n }\n};\n\nplayerUtils.isReadyToResume = function (player) {\n\n if (player.readyState() > 1) {\n // some browsers and media aren't \"seekable\".\n // readyState greater than 1 allows for seeking without exceptions\n return true;\n }\n\n if (player.seekable() === undefined) {\n // if the player doesn't expose the seekable time ranges, try to\n // resume playback immediately\n return true;\n }\n\n if (player.seekable().length > 0) {\n // if some period of the video is seekable, resume playback\n return true;\n }\n\n return false;\n};\n\n/**\n * This function prepares the player to display ads.\n * Adding convenience events like the 'vast.firsPlay' that gets fired when the video is first played\n * and ads the blackPoster to the player to prevent content from being displayed before the preroll ad.\n *\n * @param player\n */\nplayerUtils.prepareForAds = function (player) {\n var blackPoster = player.addChild('blackPoster');\n var _firstPlay = true;\n var volumeSnapshot;\n\n\n monkeyPatchPlayerApi();\n\n player.on('play', tryToTriggerFirstPlay);\n player.on('vast.reset', resetFirstPlay);//Every time we change the sources we reset the first play.\n player.on('vast.firstPlay', restoreContentVolume);\n player.on('error', hideBlackPoster);//If there is an error in the player we remove the blackposter to show the err msg\n player.on('vast.adStart', hideBlackPoster);\n player.on('vast.adsCancel', hideBlackPoster);\n player.on('vast.adError', hideBlackPoster);\n player.on('vast.adStart', addStyles);\n player.on('vast.adEnd', removeStyles);\n player.on('vast.adsCancel', removeStyles);\n\n /*** Local Functions ***/\n\n /**\n What this function does is ugly and horrible and I should think twice before calling myself a good developer. With that said,\n it is the best solution I could find to mute the video until the 'play' event happens (on mobile devices) and the plugin can decide whether\n to play the ad or not.\n\n We also need this monkeypatch to be able to pause and resume an ad using the player's API\n\n If you have a better solution please do tell me.\n */\n function monkeyPatchPlayerApi() {\n\n /**\n * Monkey patch needed to handle firstPlay and resume of playing ad.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are restoring a VAST ad.\n * @returns {player}\n */\n var origPlay = player.play;\n player.play = function (callOrigPlay) {\n var that = this;\n\n if (isFirstPlay()) {\n firstPlay();\n } else {\n resume(callOrigPlay);\n }\n\n return this;\n\n /*** local functions ***/\n function firstPlay() {\n if (!utilities.isIPhone()) {\n volumeSnapshot = saveVolumeSnapshot();\n player.muted(true);\n }\n\n origPlay.apply(that, arguments);\n }\n\n function resume(callOrigPlay) {\n if (isAdPlaying() && !callOrigPlay) {\n player.vast.adUnit.resumeAd();\n } else {\n origPlay.apply(that, arguments);\n }\n }\n };\n\n\n /**\n * Needed monkey patch to handle pause of playing ad.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are pausing a VAST ad.\n * @returns {player}\n */\n var origPause = player.pause;\n player.pause = function (callOrigPause) {\n if (isAdPlaying() && !callOrigPause) {\n player.vast.adUnit.pauseAd();\n } else {\n origPause.apply(this, arguments);\n }\n return this;\n };\n\n\n /**\n * Needed monkey patch to handle paused state of the player when ads are playing.\n *\n * @param callOrigPlay necessary flag to prevent infinite loop when you are pausing a VAST ad.\n * @returns {player}\n */\n var origPaused = player.paused;\n player.paused = function (callOrigPaused) {\n if (isAdPlaying() && !callOrigPaused) {\n return player.vast.adUnit.isPaused();\n }\n return origPaused.apply(this, arguments);\n };\n }\n\n function isAdPlaying() {\n return player.vast && player.vast.adUnit;\n }\n\n function tryToTriggerFirstPlay() {\n if (isFirstPlay()) {\n _firstPlay = false;\n player.trigger('vast.firstPlay');\n }\n }\n\n function resetFirstPlay() {\n _firstPlay = true;\n blackPoster.show();\n restoreContentVolume();\n }\n\n function isFirstPlay() {\n return _firstPlay;\n }\n\n function saveVolumeSnapshot() {\n return {\n muted: player.muted(),\n volume: player.volume()\n };\n }\n\n function restoreContentVolume() {\n if (volumeSnapshot) {\n player.currentTime(0);\n restoreVolumeSnapshot(volumeSnapshot);\n volumeSnapshot = null;\n }\n }\n\n function restoreVolumeSnapshot(snapshot) {\n if (utilities.isObject(snapshot)) {\n player.volume(snapshot.volume);\n player.muted(snapshot.muted);\n }\n }\n\n function hideBlackPoster() {\n if (!dom.hasClass(blackPoster.el(), 'vjs-hidden')) {\n blackPoster.hide();\n }\n }\n\n function addStyles() {\n dom.addClass(player.el(), 'vjs-ad-playing');\n }\n\n function removeStyles() {\n dom.removeClass(player.el(), 'vjs-ad-playing');\n }\n};\n\n/**\n * Remove the poster attribute from the video element tech, if present. When\n * reusing a video element for multiple videos, the poster image will briefly\n * reappear while the new source loads. Removing the attribute ahead of time\n * prevents the poster from showing up between videos.\n * @param {object} player The videojs player object\n */\nplayerUtils.removeNativePoster = function (player) {\n var tech = player.el().querySelector('.vjs-tech');\n if (tech) {\n tech.removeAttribute('poster');\n }\n};\n\n/**\n * Helper function to listen to many events until one of them gets fired, then we\n * execute the handler and unsubscribe all the event listeners;\n *\n * @param player specific player from where to listen for the events\n * @param events array of events\n * @param handler function to execute once one of the events fires\n */\nplayerUtils.once = function once(player, events, handler) {\n function listener() {\n handler.apply(null, arguments);\n\n events.forEach(function (event) {\n player.off(event, listener);\n });\n }\n\n events.forEach(function (event) {\n player.on(event, listener);\n });\n};\n\n\nmodule.exports = playerUtils;","'use strict';\n\nvar utilities = require('./utilityFunctions');\n\n/**\n *\n * IMPORTANT NOTE: This function comes from angularJs and was originally called urlResolve\n * you can take a look at the original code here https://github.com/angular/angular.js/blob/master/src/ng/urlUtils.js\n *\n * Implementation Notes for non-IE browsers\n * ----------------------------------------\n * Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM,\n * results both in the normalizing and parsing of the URL. Normalizing means that a relative\n * URL will be resolved into an absolute URL in the context of the application document.\n * Parsing means that the anchor node's host, hostname, protocol, port, pathname and related\n * properties are all populated to reflect the normalized URL. This approach has wide\n * compatibility - Safari 1+, Mozilla 1+, Opera 7+,e etc. See\n * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n *\n * Implementation Notes for IE\n * ---------------------------\n * IE >= 8 and <= 10 normalizes the URL when assigned to the anchor node similar to the other\n * browsers. However, the parsed components will not be set if the URL assigned did not specify\n * them. (e.g. if you assign a.href = \"foo\", then a.protocol, a.host, etc. will be empty.) We\n * work around that by performing the parsing in a 2nd step by taking a previously normalized\n * URL (e.g. by assigning to a.href) and assigning it a.href again. This correctly populates the\n * properties such as protocol, hostname, port, etc.\n *\n * IE7 does not normalize the URL when assigned to an anchor node. (Apparently, it does, if one\n * uses the inner HTML approach to assign the URL as part of an HTML snippet -\n * http://stackoverflow.com/a/472729) However, setting img[src] does normalize the URL.\n * Unfortunately, setting img[src] to something like \"javascript:foo\" on IE throws an exception.\n * Since the primary usage for normalizing URLs is to sanitize such URLs, we can't use that\n * method and IE < 8 is unsupported.\n *\n * References:\n * http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement\n * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n * http://url.spec.whatwg.org/#urlutils\n * https://github.com/angular/angular.js/pull/2902\n * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/\n *\n * @kind function\n * @param {string} url The URL to be parsed.\n * @description Normalizes and parses a URL.\n * @returns {object} Returns the normalized URL as a dictionary.\n *\n * | member name | Description |\n * |---------------|----------------|\n * | href | A normalized version of the provided URL if it was not an absolute URL |\n * | protocol | The protocol including the trailing colon |\n * | host | The host and port (if the port is non-default) of the normalizedUrl |\n * | search | The search params, minus the question mark |\n * | hash | The hash string, minus the hash symbol\n * | hostname | The hostname\n * | port | The port, without \":\"\n * | pathname | The pathname, beginning with \"/\"\n *\n */\n\nvar urlParsingNode = document.createElement(\"a\");\n/**\n * documentMode is an IE-only property\n * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx\n */\nvar msie = document.documentMode;\n\nfunction urlParts(url) {\n var href = url;\n\n if (msie) {\n // Normalize before parse. Refer Implementation Notes on why this is\n // done in two steps on IE.\n urlParsingNode.setAttribute(\"href\", href);\n href = urlParsingNode.href;\n }\n\n urlParsingNode.setAttribute('href', href);\n\n // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n return {\n href: urlParsingNode.href,\n protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n host: urlParsingNode.host,\n search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n hostname: urlParsingNode.hostname,\n port: utilities.isNotEmptyString(urlParsingNode.port)? urlParsingNode.port: 80,\n pathname: (urlParsingNode.pathname.charAt(0) === '/')\n ? urlParsingNode.pathname\n : '/' + urlParsingNode.pathname\n };\n}\n\n\n/**\n * This function accepts a query string (search part of a url) and returns a dictionary with\n * the different key value pairs\n * @param {string} qs queryString\n */\nfunction queryStringToObj(qs, cond) {\n var pairs, qsObj;\n\n cond = utilities.isFunction(cond)? cond : function() {\n return true;\n };\n\n qs = qs.trim().replace(/^\\?/, '');\n pairs = qs.split('&');\n qsObj = {};\n\n utilities.forEach(pairs, function (pair) {\n var keyValue, key, value;\n if (pair !== '') {\n keyValue = pair.split('=');\n key = keyValue[0];\n value = keyValue[1];\n if(cond(key, value)){\n qsObj[key] = value;\n }\n }\n });\n\n return qsObj;\n}\n\n/**\n * This function accepts an object and serializes it into a query string without the leading '?'\n * @param obj\n * @returns {string}\n */\nfunction objToQueryString(obj) {\n var pairs = [];\n utilities.forEach(obj, function (value, key) {\n pairs.push(key + '=' + value);\n });\n return pairs.join('&');\n}\n\nmodule.exports = {\n urlParts: urlParts,\n queryStringToObj: queryStringToObj,\n objToQueryString: objToQueryString\n};\n","/*jshint unused:false */\n\"use strict\";\n\nvar NODE_TYPE_ELEMENT = 1;\nvar SNAKE_CASE_REGEXP = /[A-Z]/g;\nvar EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/i;\n/*jslint maxlen: 500 */\nvar ISO8086_REGEXP = /^([\\+-]?\\d{4}(?!\\d{2}\\b))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))([T\\s]((([01]\\d|2[0-3])((:?)[0-5]\\d)?|24\\:?00)([\\.,]\\d+(?!:))?)?(\\17[0-5]\\d([\\.,]\\d+)?)?([zZ]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)?$/;\n\n\nfunction noop(){ }\n\nfunction isNull(o) {\n return o === null;\n}\n\nfunction isDefined(o){\n return o !== undefined;\n}\n\nfunction isUndefined(o){\n return o === undefined;\n}\n\nfunction isObject(obj) {\n return typeof obj === 'object';\n}\n\nfunction isFunction(str){\n return typeof str === 'function';\n}\n\nfunction isNumber(num){\n return typeof num === 'number';\n}\n\nfunction isWindow(obj) {\n return utilities.isObject(obj) && obj.window === obj;\n}\n\nfunction isArray(array){\n return Object.prototype.toString.call( array ) === '[object Array]';\n}\n\nfunction isArrayLike(obj) {\n if (obj === null || utilities.isWindow(obj) || utilities.isFunction(obj) || utilities.isUndefined(obj)) {\n return false;\n }\n\n var length = obj.length;\n\n if (obj.nodeType === NODE_TYPE_ELEMENT && length) {\n return true;\n }\n\n return utilities.isString(obj) || utilities.isArray(obj) || length === 0 ||\n typeof length === 'number' && length > 0 && (length - 1) in obj;\n}\n\nfunction isString(str){\n return typeof str === 'string';\n}\n\nfunction isEmptyString(str) {\n return utilities.isString(str) && str.length === 0;\n}\n\nfunction isNotEmptyString(str) {\n return utilities.isString(str) && str.length !== 0;\n}\n\nfunction arrayLikeObjToArray(args) {\n return Array.prototype.slice.call(args);\n}\n\nfunction forEach(obj, iterator, context) {\n var key, length;\n if (obj) {\n if (isFunction(obj)) {\n for (key in obj) {\n // Need to check if hasOwnProperty exists,\n // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function\n if (key !== 'prototype' && key !== 'length' && key !== 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n } else if (isArray(obj)) {\n var isPrimitive = typeof obj !== 'object';\n for (key = 0, length = obj.length; key < length; key++) {\n if (isPrimitive || key in obj) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n } else if (obj.forEach && obj.forEach !== forEach) {\n obj.forEach(iterator, context, obj);\n } else {\n for (key in obj) {\n if (obj.hasOwnProperty(key)) {\n iterator.call(context, obj[key], key, obj);\n }\n }\n }\n }\n return obj;\n}\n\nfunction snake_case(name, separator) {\n separator = separator || '_';\n return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {\n return (pos ? separator : '') + letter.toLowerCase();\n });\n}\n\nfunction isValidEmail(email){\n if(!utilities.isString(email)){\n return false;\n }\n\n return EMAIL_REGEXP.test(email.trim());\n}\n\nfunction extend (obj) {\n var arg, i, k;\n for (i = 1; i < arguments.length; i++) {\n arg = arguments[i];\n for (k in arg) {\n if (arg.hasOwnProperty(k)) {\n if(isObject(obj[k]) && !isNull(obj[k]) && isObject(arg[k])){\n obj[k] = extend({}, obj[k], arg[k]);\n }else {\n obj[k] = arg[k];\n }\n }\n }\n }\n return obj;\n}\n\nfunction capitalize(s){\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nfunction decapitalize(s) {\n return s.charAt(0).toLowerCase() + s.slice(1);\n}\n\n/**\n * This method works the same way array.prototype.map works but if the transformer returns undefine, then\n * it won't be added to the transformed Array.\n */\nfunction transformArray(array, transformer) {\n var transformedArray = [];\n\n array.forEach(function(item, index){\n var transformedItem = transformer(item, index);\n if(utilities.isDefined(transformedItem)) {\n transformedArray.push(transformedItem);\n }\n });\n\n return transformedArray;\n}\n\nfunction toFixedDigits(num, digits) {\n var formattedNum = num + '';\n digits = utilities.isNumber(digits) ? digits : 0;\n num = utilities.isNumber(num) ? num : parseInt(num, 10);\n if(utilities.isNumber(num) && !isNaN(num)){\n formattedNum = num + '';\n while(formattedNum.length < digits) {\n formattedNum = '0' + formattedNum;\n }\n return formattedNum;\n }\n return NaN + '';\n}\n\nfunction throttle(callback, delay) {\n var previousCall = new Date().getTime() - (delay + 1);\n return function() {\n var time = new Date().getTime();\n if ((time - previousCall) >= delay) {\n previousCall = time;\n callback.apply(this, arguments);\n }\n };\n}\n\nfunction debounce (callback, wait) {\n var timeoutId;\n\n return function (){\n if(timeoutId) {\n clearTimeout(timeoutId);\n }\n timeoutId = setTimeout(function(){\n callback.apply(this, arguments);\n timeoutId = undefined;\n }, wait);\n };\n}\n\n// a function designed to blow up the stack in a naive way\n// but it is ok for videoJs children components\nfunction treeSearch(root, getChildren, found){\n var children = getChildren(root);\n for (var i = 0; i < children.length; i++){\n if (found(children[i])) {\n return children[i];\n }\n else {\n var el = treeSearch(children[i], getChildren, found);\n if (el){\n return el;\n }\n }\n }\n}\n\nfunction echoFn(val) {\n return function () {\n return val;\n };\n}\n\n//Note: Supported formats come from http://www.w3.org/TR/NOTE-datetime\n// and the iso8601 regex comes from http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/\nfunction isISO8601(value) {\n if(utilities.isNumber(value)){\n value = value + ''; //we make sure that we are working with strings\n }\n\n if(!utilities.isString(value)){\n return false;\n }\n\n return ISO8086_REGEXP.test(value.trim());\n}\n\n/**\n * Checks if the Browser is IE9 and below\n * @returns {boolean}\n */\nfunction isOldIE() {\n var version = utilities.getInternetExplorerVersion(navigator);\n if (version === -1) {\n return false;\n }\n\n return version < 10;\n}\n\n/**\n * Returns the version of Internet Explorer or a -1 (indicating the use of another browser).\n * Source: https://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx\n * @returns {number} the version of Internet Explorer or a -1 (indicating the use of another browser).\n */\nfunction getInternetExplorerVersion(navigator) {\n var rv = -1;\n\n if (navigator.appName == 'Microsoft Internet Explorer') {\n var ua = navigator.userAgent;\n var re = new RegExp(\"MSIE ([0-9]{1,}[\\.0-9]{0,})\");\n var res = re.exec(ua);\n if (res !== null) {\n rv = parseFloat(res[1]);\n }\n }\n\n return rv;\n}\n\n/*** Mobile Utility functions ***/\nfunction isIDevice() {\n return /iP(hone|ad)/.test(utilities._UA);\n}\n\nfunction isMobile() {\n return /iP(hone|ad|od)|Android|Windows Phone/.test(utilities._UA);\n}\n\nfunction isIPhone() {\n return /iP(hone|od)/.test(utilities._UA);\n}\n\nfunction isAndroid() {\n return /Android/.test(utilities._UA);\n}\n\nvar utilities = {\n _UA: navigator.userAgent,\n noop: noop,\n isNull: isNull,\n isDefined: isDefined,\n isUndefined: isUndefined,\n isObject: isObject,\n isFunction: isFunction,\n isNumber: isNumber,\n isWindow: isWindow,\n isArray: isArray,\n isArrayLike: isArrayLike,\n isString: isString,\n isEmptyString: isEmptyString,\n isNotEmptyString: isNotEmptyString,\n arrayLikeObjToArray: arrayLikeObjToArray,\n forEach: forEach,\n snake_case: snake_case,\n isValidEmail: isValidEmail,\n extend: extend,\n capitalize: capitalize,\n decapitalize: decapitalize,\n transformArray: transformArray,\n toFixedDigits: toFixedDigits,\n throttle: throttle,\n debounce: debounce,\n treeSearch: treeSearch,\n echoFn: echoFn,\n isISO8601: isISO8601,\n isOldIE: isOldIE,\n getInternetExplorerVersion: getInternetExplorerVersion,\n isIDevice: isIDevice,\n isMobile: isMobile,\n isIPhone: isIPhone,\n isAndroid: isAndroid\n};\n\nmodule.exports = utilities;","'use strict';\n\nvar utilities = require('./utilityFunctions');\n\nvar xml = {};\n\nxml.strToXMLDoc = function strToXMLDoc(stringContainingXMLSource){\n //IE 8\n if(typeof window.DOMParser === 'undefined'){\n var xmlDocument = new ActiveXObject('Microsoft.XMLDOM');\n xmlDocument.async = false;\n xmlDocument.loadXML(stringContainingXMLSource);\n return xmlDocument;\n }\n\n return parseString(stringContainingXMLSource);\n\n function parseString(stringContainingXMLSource){\n var parser = new DOMParser();\n var parsedDocument;\n\n //Note: This try catch is to deal with the fact that on IE parser.parseFromString does throw an error but the rest of the browsers don't.\n try {\n parsedDocument = parser.parseFromString(stringContainingXMLSource, \"application/xml\");\n\n if(isParseError(parsedDocument) || utilities.isEmptyString(stringContainingXMLSource)){\n throw new Error();\n }\n }catch(e){\n throw new Error(\"xml.strToXMLDOC: Error parsing the string: '\" + stringContainingXMLSource + \"'\");\n }\n\n return parsedDocument;\n }\n\n function isParseError(parsedDocument) {\n try { // parser and parsererrorNS could be cached on startup for efficiency\n var parser = new DOMParser(),\n erroneousParse = parser.parseFromString('INVALID', 'text/xml'),\n parsererrorNS = erroneousParse.getElementsByTagName(\"parsererror\")[0].namespaceURI;\n\n if (parsererrorNS === 'http://www.w3.org/1999/xhtml') {\n // In PhantomJS the parseerror element doesn't seem to have a special namespace, so we are just guessing here :(\n return parsedDocument.getElementsByTagName(\"parsererror\").length > 0;\n }\n\n return parsedDocument.getElementsByTagNameNS(parsererrorNS, 'parsererror').length > 0;\n } catch (e) {\n //Note on IE parseString throws an error by itself and it will never reach this code. Because it will have failed before\n }\n }\n};\n\nxml.parseText = function parseText (sValue) {\n if (/^\\s*$/.test(sValue)) { return null; }\n if (/^(?:true|false)$/i.test(sValue)) { return sValue.toLowerCase() === \"true\"; }\n if (isFinite(sValue)) { return parseFloat(sValue); }\n if (utilities.isISO8601(sValue)) { return new Date(sValue); }\n return sValue.trim();\n};\n\nxml.JXONTree = function JXONTree (oXMLParent) {\n var parseText = xml.parseText;\n\n //The document object is an especial object that it may miss some functions or attrs depending on the browser.\n //To prevent this problem with create the JXONTree using the root childNode which is a fully fleshed node on all supported\n //browsers.\n if(oXMLParent.documentElement){\n return new xml.JXONTree(oXMLParent.documentElement);\n }\n\n if (oXMLParent.hasChildNodes()) {\n var sCollectedTxt = \"\";\n for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {\n oNode = oXMLParent.childNodes.item(nItem);\n /*jshint bitwise: false*/\n if ((oNode.nodeType - 1 | 1) === 3) { sCollectedTxt += oNode.nodeType === 3 ? oNode.nodeValue.trim() : oNode.nodeValue; }\n else if (oNode.nodeType === 1 && !oNode.prefix) {\n sProp = utilities.decapitalize(oNode.nodeName);\n vContent = new xml.JXONTree(oNode);\n if (this.hasOwnProperty(sProp)) {\n if (this[sProp].constructor !== Array) { this[sProp] = [this[sProp]]; }\n this[sProp].push(vContent);\n } else { this[sProp] = vContent; }\n }\n }\n if (sCollectedTxt) { this.keyValue = parseText(sCollectedTxt); }\n }\n\n //IE8 Stupid fix\n var hasAttr = typeof oXMLParent.hasAttributes === 'undefined'? oXMLParent.attributes.length > 0: oXMLParent.hasAttributes();\n if (hasAttr) {\n var oAttrib;\n for (var nAttrib = 0; nAttrib < oXMLParent.attributes.length; nAttrib++) {\n oAttrib = oXMLParent.attributes.item(nAttrib);\n this[\"@\" + utilities.decapitalize(oAttrib.name)] = parseText(oAttrib.value.trim());\n }\n }\n};\n\nxml.JXONTree.prototype.attr = function(attr) {\n return this['@' + utilities.decapitalize(attr)];\n};\n\nxml.toJXONTree = function toJXONTree(xmlString){\n var xmlDoc = xml.strToXMLDoc(xmlString);\n return new xml.JXONTree(xmlDoc);\n};\n\n/**\n * Helper function to extract the keyvalue of a JXONTree obj\n *\n * @param xmlObj {JXONTree}\n * return the key value or undefined;\n */\nxml.keyValue = function getKeyValue(xmlObj) {\n if(xmlObj){\n return xmlObj.keyValue;\n }\n return undefined;\n};\n\nxml.attr = function getAttrValue(xmlObj, attr) {\n if(xmlObj) {\n return xmlObj['@' + utilities.decapitalize(attr)];\n }\n return undefined;\n};\n\nxml.encode = function encodeXML(str) {\n return str.replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n};\n\nxml.decode = function decodeXML(str) {\n return str.replace(/'/g, \"'\")\n .replace(/"/g, '\"')\n .replace(/>/g, '>')\n .replace(/</g, '<')\n .replace(/&/g, '&');\n};\n\nmodule.exports = xml;","'use strict';\n\nrequire('./plugin/components/ads-label_5');\nrequire('./plugin/components/black-poster_5');\n\nvar videoJsVAST = require('./plugin/videojs.vast.vpaid');\n\nvideojs.plugin('vastClient', videoJsVAST);\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/src/scripts/ads/vast/Companion.js b/src/scripts/ads/vast/Companion.js index d62c0981..39836b16 100644 --- a/src/scripts/ads/vast/Companion.js +++ b/src/scripts/ads/vast/Companion.js @@ -6,16 +6,24 @@ var utilities = require('../../utils/utilityFunctions'); var xml = require('../../utils/xml'); +var logger = require ('../../utils/consoleLogger'); + function Companion(companionJTree) { if (!(this instanceof Companion)) { return new Companion(companionJTree); } + logger.info (" found companion ad"); + logger.debug (" companionJTree:", companionJTree); + //Required Elements this.creativeType = xml.attr(companionJTree.staticResource, 'creativeType'); this.staticResource = xml.keyValue(companionJTree.staticResource); + logger.info (" creativeType: " + this.creativeType); + logger.info (" staticResource: " + this.staticResource); + // Weird bug when the JXON tree is built it doesn't handle casing properly in this situation... var htmlResource = null; if (xml.keyValue(companionJTree.HTMLResource)) { @@ -23,6 +31,12 @@ function Companion(companionJTree) { } else if (xml.keyValue(companionJTree.hTMLResource)) { htmlResource = xml.keyValue(companionJTree.hTMLResource); } + + if (htmlResource !== null) + { + logger.info (" found html resource", htmlResource); + } + this.htmlResource = htmlResource; var iframeResource = null; @@ -31,6 +45,12 @@ function Companion(companionJTree) { } else if (xml.keyValue(companionJTree.iFrameresource)) { iframeResource = xml.keyValue(companionJTree.iFrameresource); } + + if (iframeResource !== null) + { + logger.info (" found iframe resource", iframeResource); + } + this.iframeResource = iframeResource; //Optional fields @@ -46,6 +66,9 @@ function Companion(companionJTree) { this.companionClickThrough = xml.keyValue(companionJTree.companionClickThrough); this.trackingEvents = parseTrackingEvents(companionJTree.trackingEvents && companionJTree.trackingEvents.tracking); + logger.info (" companionClickThrough: " + this.companionClickThrough); + + /*** Local functions ***/ function parseTrackingEvents(trackingEvents) { var trackings = []; diff --git a/src/scripts/ads/vast/VASTClient.js b/src/scripts/ads/vast/VASTClient.js index dff110fc..cd134937 100644 --- a/src/scripts/ads/vast/VASTClient.js +++ b/src/scripts/ads/vast/VASTClient.js @@ -10,6 +10,8 @@ var http = require('../../utils/http').http; var utilities = require('../../utils/utilityFunctions'); var xml = require('../../utils/xml'); +var logger = require ('../../utils/consoleLogger'); + function VASTClient(options) { if (!(this instanceof VASTClient)) { return new VASTClient(options); @@ -101,6 +103,7 @@ VASTClient.prototype._getVASTAd = function (adTagUrl, callback) { var vastTree; try { vastTree = xml.toJXONTree(xmlStr); + logger.debug ("built JXONTree from VAST response:", vastTree); if(utilities.isArray(vastTree.ad)) { vastTree.ads = vastTree.ad; @@ -214,6 +217,7 @@ VASTClient.prototype._requestVASTXml = function requestVASTXml(adTagUrl, callbac if (utilities.isFunction(adTagUrl)) { adTagUrl(requestHandler); } else { + logger.info ("requesting adTagUrl: " + adTagUrl); http.get(adTagUrl, requestHandler, { withCredentials: true }); diff --git a/src/scripts/ads/vast/VASTIntegrator.js b/src/scripts/ads/vast/VASTIntegrator.js index 81c091f2..a7b5e310 100644 --- a/src/scripts/ads/vast/VASTIntegrator.js +++ b/src/scripts/ads/vast/VASTIntegrator.js @@ -19,6 +19,8 @@ var dom = require('../../utils/dom'); var playerUtils = require('../../utils/playerUtils'); var utilities = require('../../utils/utilityFunctions'); +var logger = require ('../../utils/consoleLogger'); + function VASTIntegrator(player) { if (!(this instanceof VASTIntegrator)) { return new VASTIntegrator(player); @@ -88,6 +90,7 @@ VASTIntegrator.prototype._selectAdSource = function selectAdSource(response, cal source = this.player.selectSource(response.mediaFiles).source; if (source) { + logger.info ("selected source: ", source); if (this._adUnit) { this._adUnit._src = source; } @@ -305,8 +308,11 @@ VASTIntegrator.prototype._playSelectedAd = function playSelectedAd(source, respo player.preload("auto"); //without preload=auto the durationchange event is never fired player.src(source); + logger.debug (" waiting for durationchange to play the ad..."); + playerUtils.once(player, ['durationchange', 'error', 'vast.adsCancel'], function (evt) { if (evt.type === 'durationchange') { + logger.debug (" got durationchange; calling playAd()"); playAd(); } else if(evt.type === 'error') { callback(new VASTError("on VASTIntegrator, Player is unable to play the Ad", 400), response); @@ -322,6 +328,8 @@ VASTIntegrator.prototype._playSelectedAd = function playSelectedAd(source, respo return; } + logger.debug (" got playing event; triggering vast.adStart..."); + player.trigger('vast.adStart'); player.on('ended', proceed); @@ -347,6 +355,8 @@ VASTIntegrator.prototype._playSelectedAd = function playSelectedAd(source, respo } }); + logger.debug (" calling player.play()..."); + player.play(); } }; diff --git a/src/scripts/ads/vpaid/VPAIDFlashTech.js b/src/scripts/ads/vpaid/VPAIDFlashTech.js index b3c8b476..d7b03eee 100644 --- a/src/scripts/ads/vpaid/VPAIDFlashTech.js +++ b/src/scripts/ads/vpaid/VPAIDFlashTech.js @@ -7,6 +7,8 @@ var VPAIDFLASHClient = require('VPAIDFLASHClient/js/VPAIDFLASHClient'); var utilities = require('../../utils/utilityFunctions'); var dom = require('../../utils/dom'); +var logger = require ('../../utils/consoleLogger'); + function VPAIDFlashTech(mediaFile, settings) { if (!(this instanceof VPAIDFlashTech)) { return new VPAIDFlashTech(mediaFile); @@ -38,11 +40,15 @@ VPAIDFlashTech.prototype.loadAdUnit = function loadFlashCreative(containerEl, ob sanityCheck(containerEl, callback); this.containerEl = containerEl; + + logger.debug (" loading VPAIDFLASHClient with opts:", flashClientOpts); + this.vpaidFlashClient = new VPAIDFlashTech.VPAIDFLASHClient(containerEl, function (error) { if (error) { return callback(error); } + logger.info (" calling VPAIDFLASHClient.loadAdUnit(); that.mediaFile:", that.mediaFile); that.vpaidFlashClient.loadAdUnit(that.mediaFile.src, callback); }, flashClientOpts); @@ -64,9 +70,7 @@ VPAIDFlashTech.prototype.unloadAdUnit = function () { try{ this.vpaidFlashClient.destroy(); } catch(e){ - if(console && utilities.isFunction(console.log)){ - console.log('VAST ERROR: trying to unload the VPAID adunit'); - } + logger.error ('VAST ERROR: trying to unload the VPAID adunit'); } this.vpaidFlashClient = null; } diff --git a/src/scripts/ads/vpaid/VPAIDHTML5Tech.js b/src/scripts/ads/vpaid/VPAIDHTML5Tech.js index 53351d64..5aaeec82 100644 --- a/src/scripts/ads/vpaid/VPAIDHTML5Tech.js +++ b/src/scripts/ads/vpaid/VPAIDHTML5Tech.js @@ -7,6 +7,8 @@ var VPAIDHTML5Client = require('VPAIDHTML5Client/js/VPAIDHTML5Client'); var utilities = require('../../utils/utilityFunctions'); var dom = require('../../utils/dom'); +var logger = require ('../../utils/consoleLogger'); + function VPAIDHTML5Tech(mediaFile) { if(!(this instanceof VPAIDHTML5Tech)) { @@ -63,9 +65,7 @@ VPAIDHTML5Tech.prototype.unloadAdUnit = function unloadAdUnit() { try { this.vpaidHTMLClient.destroy(); } catch(e) { - if (console && utilities.isFunction(console.log)) { - console.log('VAST ERROR: trying to unload the VPAID adunit'); - } + logger.error ('VAST ERROR: trying to unload the VPAID adunit'); } this.vpaidHTMLClient = null; diff --git a/src/scripts/ads/vpaid/VPAIDIntegrator.js b/src/scripts/ads/vpaid/VPAIDIntegrator.js index 166afded..5bf75196 100644 --- a/src/scripts/ads/vpaid/VPAIDIntegrator.js +++ b/src/scripts/ads/vpaid/VPAIDIntegrator.js @@ -12,6 +12,8 @@ var dom = require('../../utils/dom'); var playerUtils = require('../../utils/playerUtils'); var utilities = require('../../utils/utilityFunctions'); +var logger = require ('../../utils/consoleLogger'); + function VPAIDIntegrator(player, settings) { if (!(this instanceof VPAIDIntegrator)) { return new VPAIDIntegrator(player); @@ -48,6 +50,7 @@ VPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) var that = this; var player = this.player; + logger.debug (" looking for supported tech..."); var tech = this._findSupportedTech(vastResponse, this.settings); callback = callback || utilities.noop; @@ -63,6 +66,8 @@ VPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) }); if (tech) { + logger.info (" found tech: ", tech); + async.waterfall([ function (next) { next(null, tech, vastResponse); @@ -92,6 +97,7 @@ VPAIDIntegrator.prototype.playAd = function playVPaidAd(vastResponse, callback) }; } else { + logger.debug (" could not find suitable tech"); var error = new VASTError('on VPAIDIntegrator.playAd, could not find a supported mediaFile', 403); adComplete(error, this._adUnit, vastResponse); } @@ -528,8 +534,8 @@ function resizeAd(player, adUnit, VIEW_MODE) { } function logError(error) { - if (error && console && console.log) { - console.log('ERROR: ' + error.message, error); + if (error) { + logger.error ('ERROR: ' + error.message, error); } } diff --git a/src/scripts/plugin/videojs.vast.vpaid.js b/src/scripts/plugin/videojs.vast.vpaid.js index 6cf19e0a..97851948 100644 --- a/src/scripts/plugin/videojs.vast.vpaid.js +++ b/src/scripts/plugin/videojs.vast.vpaid.js @@ -12,6 +12,8 @@ var dom = require('../utils/dom'); var playerUtils = require('../utils/playerUtils'); var utilities = require('../utils/utilityFunctions'); +var logger = require ('../utils/consoleLogger'); + module.exports = function VASTPlugin(options) { var snapshot; var player = this; @@ -45,7 +47,15 @@ module.exports = function VASTPlugin(options) { autoResize: true, // Path to the VPAID flash ad's loader - vpaidFlashLoaderPath: '/VPAIDFlash.swf' + vpaidFlashLoaderPath: '/VPAIDFlash.swf', + + // verbosity of console logging: + // 0 - error + // 1 - error, warn + // 2 - error, warn, info + // 3 - error, warn, info, log + // 4 - error, warn, info, log, debug + verbosity: 0 }; var settings = utilities.extend({}, defaultOpts, options || {}); @@ -66,6 +76,8 @@ module.exports = function VASTPlugin(options) { return trackAdError(new VASTError('on VideoJS VAST plugin, missing adTagUrl on options object')); } + logger.setVerbosity (settings.verbosity); + vastUtil.runFlashSupportCheck(settings.vpaidFlashLoaderPath);// Necessary step for VPAIDFLASHClient to work. playerUtils.prepareForAds(player); @@ -263,6 +275,7 @@ module.exports = function VASTPlugin(options) { } player.vast.vastResponse = vastResponse; + logger.debug ("calling adIntegrator.playAd() with vastResponse:", vastResponse); player.vast.adUnit = adIntegrator.playAd(vastResponse, callback); /*** Local functions ****/ @@ -325,9 +338,7 @@ module.exports = function VASTPlugin(options) { function trackAdError(error, vastResponse) { player.trigger({type: 'vast.adError', error: error}); cancelAds(); - if (console && console.log) { - console.log('AD ERROR:', error.message, error, vastResponse); - } + logger.error ('AD ERROR:', error.message, error, vastResponse); } function isVPAID(vastResponse) { diff --git a/src/scripts/utils/consoleLogger.js b/src/scripts/utils/consoleLogger.js new file mode 100644 index 00000000..cb6c4034 --- /dev/null +++ b/src/scripts/utils/consoleLogger.js @@ -0,0 +1,94 @@ +/*jshint unused:false */ +"use strict"; + +var _verbosity = 0; +var _prefix = "[videojs-vast-vpaid] "; + +function setVerbosity (v) +{ + _verbosity = v; +} + +function handleMsg (method, args) +{ + if ((args.length) > 0 && (typeof args[0] === 'string')) + { + args[0] = _prefix + args[0]; + } + + if (method.apply) + { + method.apply (console, Array.prototype.slice.call(args)); + } + else + { + method (Array.prototype.slice.call(args)); + } +} + +function debug () +{ + if (_verbosity < 4) + { + return; + } + + handleMsg (console.debug, arguments); +} + +function log () +{ + if (_verbosity < 3) + { + return; + } + + handleMsg (console.log, arguments); +} + +function info () +{ + if (_verbosity < 2) + { + return; + } + + handleMsg (console.info, arguments); +} + + +function warn () +{ + if (_verbosity < 1) + { + return; + } + + handleMsg (console.warn, arguments); +} + +function error () +{ + handleMsg (console.error, arguments); +} + +var consoleLogger = { + setVerbosity: setVerbosity, + debug: debug, + log: log, + info: info, + warn: warn, + error: error +}; + +if ((typeof (console) === 'undefined') || !console.log) +{ + // no console available; make functions no-op + consoleLogger.debug = function () {}; + consoleLogger.log = function () {}; + consoleLogger.info = function () {}; + consoleLogger.warn = function () {}; + consoleLogger.error = function () {}; +} + +module.exports = consoleLogger; \ No newline at end of file