/* * ATTENTION: An "eval-source-map" devtool has been used. * This devtool is neither made for production nor for readable output files. * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools. * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) * or disable the default devtool with "devtool: false". * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else { var a = factory(); for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; } })(self, function() { return /******/ (function() { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ "./libs/flatpickr/flatpickr.js": /*!*************************************!*\ !*** ./libs/flatpickr/flatpickr.js ***! \*************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { "use strict"; eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"flatpickr\": function() { return /* reexport module object */ flatpickr_dist_flatpickr__WEBPACK_IMPORTED_MODULE_0__; }\n/* harmony export */ });\n/* harmony import */ var flatpickr_dist_flatpickr__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! flatpickr/dist/flatpickr */ \"./node_modules/flatpickr/dist/flatpickr.js\");\n/* harmony import */ var flatpickr_dist_flatpickr__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(flatpickr_dist_flatpickr__WEBPACK_IMPORTED_MODULE_0__);\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9saWJzL2ZsYXRwaWNrci9mbGF0cGlja3IuanMuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQXNEIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vVnVleHkvLi9saWJzL2ZsYXRwaWNrci9mbGF0cGlja3IuanM/ZTJiMCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmbGF0cGlja3IgZnJvbSAnZmxhdHBpY2tyL2Rpc3QvZmxhdHBpY2tyJztcclxuXHJcbmV4cG9ydCB7IGZsYXRwaWNrciB9O1xyXG4iXSwibmFtZXMiOlsiZmxhdHBpY2tyIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./libs/flatpickr/flatpickr.js\n"); /***/ }), /***/ "./node_modules/flatpickr/dist/flatpickr.js": /*!**************************************************!*\ !*** ./node_modules/flatpickr/dist/flatpickr.js ***! \**************************************************/ /***/ (function(module) { eval("/* flatpickr v4.6.13, @license MIT */\n(function (global, factory) {\n true ? module.exports = factory() :\n 0;\n}(this, (function () { 'use strict';\n\n /*! *****************************************************************************\r\n Copyright (c) Microsoft Corporation.\r\n\r\n Permission to use, copy, modify, and/or distribute this software for any\r\n purpose with or without fee is hereby granted.\r\n\r\n THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\n REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\n AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\n INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\n LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\n OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\n PERFORMANCE OF THIS SOFTWARE.\r\n ***************************************************************************** */\r\n\r\n var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n };\r\n return __assign.apply(this, arguments);\r\n };\r\n\r\n function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n }\n\n var HOOKS = [\n \"onChange\",\n \"onClose\",\n \"onDayCreate\",\n \"onDestroy\",\n \"onKeyDown\",\n \"onMonthChange\",\n \"onOpen\",\n \"onParseConfig\",\n \"onReady\",\n \"onValueUpdate\",\n \"onYearChange\",\n \"onPreCalendarPosition\",\n ];\n var defaults = {\n _disable: [],\n allowInput: false,\n allowInvalidPreload: false,\n altFormat: \"F j, Y\",\n altInput: false,\n altInputClass: \"form-control input\",\n animate: typeof window === \"object\" &&\n window.navigator.userAgent.indexOf(\"MSIE\") === -1,\n ariaDateFormat: \"F j, Y\",\n autoFillDefaultTime: true,\n clickOpens: true,\n closeOnSelect: true,\n conjunction: \", \",\n dateFormat: \"Y-m-d\",\n defaultHour: 12,\n defaultMinute: 0,\n defaultSeconds: 0,\n disable: [],\n disableMobile: false,\n enableSeconds: false,\n enableTime: false,\n errorHandler: function (err) {\n return typeof console !== \"undefined\" && console.warn(err);\n },\n getWeek: function (givenDate) {\n var date = new Date(givenDate.getTime());\n date.setHours(0, 0, 0, 0);\n // Thursday in current week decides the year.\n date.setDate(date.getDate() + 3 - ((date.getDay() + 6) % 7));\n // January 4 is always in week 1.\n var week1 = new Date(date.getFullYear(), 0, 4);\n // Adjust to Thursday in week 1 and count number of weeks from date to week1.\n return (1 +\n Math.round(((date.getTime() - week1.getTime()) / 86400000 -\n 3 +\n ((week1.getDay() + 6) % 7)) /\n 7));\n },\n hourIncrement: 1,\n ignoredFocusElements: [],\n inline: false,\n locale: \"default\",\n minuteIncrement: 5,\n mode: \"single\",\n monthSelectorType: \"dropdown\",\n nextArrow: \"\",\n noCalendar: false,\n now: new Date(),\n onChange: [],\n onClose: [],\n onDayCreate: [],\n onDestroy: [],\n onKeyDown: [],\n onMonthChange: [],\n onOpen: [],\n onParseConfig: [],\n onReady: [],\n onValueUpdate: [],\n onYearChange: [],\n onPreCalendarPosition: [],\n plugins: [],\n position: \"auto\",\n positionElement: undefined,\n prevArrow: \"\",\n shorthandCurrentMonth: false,\n showMonths: 1,\n static: false,\n time_24hr: false,\n weekNumbers: false,\n wrap: false,\n };\n\n var english = {\n weekdays: {\n shorthand: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n longhand: [\n \"Sunday\",\n \"Monday\",\n \"Tuesday\",\n \"Wednesday\",\n \"Thursday\",\n \"Friday\",\n \"Saturday\",\n ],\n },\n months: {\n shorthand: [\n \"Jan\",\n \"Feb\",\n \"Mar\",\n \"Apr\",\n \"May\",\n \"Jun\",\n \"Jul\",\n \"Aug\",\n \"Sep\",\n \"Oct\",\n \"Nov\",\n \"Dec\",\n ],\n longhand: [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n ],\n },\n daysInMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],\n firstDayOfWeek: 0,\n ordinal: function (nth) {\n var s = nth % 100;\n if (s > 3 && s < 21)\n return \"th\";\n switch (s % 10) {\n case 1:\n return \"st\";\n case 2:\n return \"nd\";\n case 3:\n return \"rd\";\n default:\n return \"th\";\n }\n },\n rangeSeparator: \" to \",\n weekAbbreviation: \"Wk\",\n scrollTitle: \"Scroll to increment\",\n toggleTitle: \"Click to toggle\",\n amPM: [\"AM\", \"PM\"],\n yearAriaLabel: \"Year\",\n monthAriaLabel: \"Month\",\n hourAriaLabel: \"Hour\",\n minuteAriaLabel: \"Minute\",\n time_24hr: false,\n };\n\n var pad = function (number, length) {\n if (length === void 0) { length = 2; }\n return (\"000\" + number).slice(length * -1);\n };\n var int = function (bool) { return (bool === true ? 1 : 0); };\n /* istanbul ignore next */\n function debounce(fn, wait) {\n var t;\n return function () {\n var _this = this;\n var args = arguments;\n clearTimeout(t);\n t = setTimeout(function () { return fn.apply(_this, args); }, wait);\n };\n }\n var arrayify = function (obj) {\n return obj instanceof Array ? obj : [obj];\n };\n\n function toggleClass(elem, className, bool) {\n if (bool === true)\n return elem.classList.add(className);\n elem.classList.remove(className);\n }\n function createElement(tag, className, content) {\n var e = window.document.createElement(tag);\n className = className || \"\";\n content = content || \"\";\n e.className = className;\n if (content !== undefined)\n e.textContent = content;\n return e;\n }\n function clearNode(node) {\n while (node.firstChild)\n node.removeChild(node.firstChild);\n }\n function findParent(node, condition) {\n if (condition(node))\n return node;\n else if (node.parentNode)\n return findParent(node.parentNode, condition);\n return undefined; // nothing found\n }\n function createNumberInput(inputClassName, opts) {\n var wrapper = createElement(\"div\", \"numInputWrapper\"), numInput = createElement(\"input\", \"numInput \" + inputClassName), arrowUp = createElement(\"span\", \"arrowUp\"), arrowDown = createElement(\"span\", \"arrowDown\");\n if (navigator.userAgent.indexOf(\"MSIE 9.0\") === -1) {\n numInput.type = \"number\";\n }\n else {\n numInput.type = \"text\";\n numInput.pattern = \"\\\\d*\";\n }\n if (opts !== undefined)\n for (var key in opts)\n numInput.setAttribute(key, opts[key]);\n wrapper.appendChild(numInput);\n wrapper.appendChild(arrowUp);\n wrapper.appendChild(arrowDown);\n return wrapper;\n }\n function getEventTarget(event) {\n try {\n if (typeof event.composedPath === \"function\") {\n var path = event.composedPath();\n return path[0];\n }\n return event.target;\n }\n catch (error) {\n return event.target;\n }\n }\n\n var doNothing = function () { return undefined; };\n var monthToStr = function (monthNumber, shorthand, locale) { return locale.months[shorthand ? \"shorthand\" : \"longhand\"][monthNumber]; };\n var revFormat = {\n D: doNothing,\n F: function (dateObj, monthName, locale) {\n dateObj.setMonth(locale.months.longhand.indexOf(monthName));\n },\n G: function (dateObj, hour) {\n dateObj.setHours((dateObj.getHours() >= 12 ? 12 : 0) + parseFloat(hour));\n },\n H: function (dateObj, hour) {\n dateObj.setHours(parseFloat(hour));\n },\n J: function (dateObj, day) {\n dateObj.setDate(parseFloat(day));\n },\n K: function (dateObj, amPM, locale) {\n dateObj.setHours((dateObj.getHours() % 12) +\n 12 * int(new RegExp(locale.amPM[1], \"i\").test(amPM)));\n },\n M: function (dateObj, shortMonth, locale) {\n dateObj.setMonth(locale.months.shorthand.indexOf(shortMonth));\n },\n S: function (dateObj, seconds) {\n dateObj.setSeconds(parseFloat(seconds));\n },\n U: function (_, unixSeconds) { return new Date(parseFloat(unixSeconds) * 1000); },\n W: function (dateObj, weekNum, locale) {\n var weekNumber = parseInt(weekNum);\n var date = new Date(dateObj.getFullYear(), 0, 2 + (weekNumber - 1) * 7, 0, 0, 0, 0);\n date.setDate(date.getDate() - date.getDay() + locale.firstDayOfWeek);\n return date;\n },\n Y: function (dateObj, year) {\n dateObj.setFullYear(parseFloat(year));\n },\n Z: function (_, ISODate) { return new Date(ISODate); },\n d: function (dateObj, day) {\n dateObj.setDate(parseFloat(day));\n },\n h: function (dateObj, hour) {\n dateObj.setHours((dateObj.getHours() >= 12 ? 12 : 0) + parseFloat(hour));\n },\n i: function (dateObj, minutes) {\n dateObj.setMinutes(parseFloat(minutes));\n },\n j: function (dateObj, day) {\n dateObj.setDate(parseFloat(day));\n },\n l: doNothing,\n m: function (dateObj, month) {\n dateObj.setMonth(parseFloat(month) - 1);\n },\n n: function (dateObj, month) {\n dateObj.setMonth(parseFloat(month) - 1);\n },\n s: function (dateObj, seconds) {\n dateObj.setSeconds(parseFloat(seconds));\n },\n u: function (_, unixMillSeconds) {\n return new Date(parseFloat(unixMillSeconds));\n },\n w: doNothing,\n y: function (dateObj, year) {\n dateObj.setFullYear(2000 + parseFloat(year));\n },\n };\n var tokenRegex = {\n D: \"\",\n F: \"\",\n G: \"(\\\\d\\\\d|\\\\d)\",\n H: \"(\\\\d\\\\d|\\\\d)\",\n J: \"(\\\\d\\\\d|\\\\d)\\\\w+\",\n K: \"\",\n M: \"\",\n S: \"(\\\\d\\\\d|\\\\d)\",\n U: \"(.+)\",\n W: \"(\\\\d\\\\d|\\\\d)\",\n Y: \"(\\\\d{4})\",\n Z: \"(.+)\",\n d: \"(\\\\d\\\\d|\\\\d)\",\n h: \"(\\\\d\\\\d|\\\\d)\",\n i: \"(\\\\d\\\\d|\\\\d)\",\n j: \"(\\\\d\\\\d|\\\\d)\",\n l: \"\",\n m: \"(\\\\d\\\\d|\\\\d)\",\n n: \"(\\\\d\\\\d|\\\\d)\",\n s: \"(\\\\d\\\\d|\\\\d)\",\n u: \"(.+)\",\n w: \"(\\\\d\\\\d|\\\\d)\",\n y: \"(\\\\d{2})\",\n };\n var formats = {\n // get the date in UTC\n Z: function (date) { return date.toISOString(); },\n // weekday name, short, e.g. Thu\n D: function (date, locale, options) {\n return locale.weekdays.shorthand[formats.w(date, locale, options)];\n },\n // full month name e.g. January\n F: function (date, locale, options) {\n return monthToStr(formats.n(date, locale, options) - 1, false, locale);\n },\n // padded hour 1-12\n G: function (date, locale, options) {\n return pad(formats.h(date, locale, options));\n },\n // hours with leading zero e.g. 03\n H: function (date) { return pad(date.getHours()); },\n // day (1-30) with ordinal suffix e.g. 1st, 2nd\n J: function (date, locale) {\n return locale.ordinal !== undefined\n ? date.getDate() + locale.ordinal(date.getDate())\n : date.getDate();\n },\n // AM/PM\n K: function (date, locale) { return locale.amPM[int(date.getHours() > 11)]; },\n // shorthand month e.g. Jan, Sep, Oct, etc\n M: function (date, locale) {\n return monthToStr(date.getMonth(), true, locale);\n },\n // seconds 00-59\n S: function (date) { return pad(date.getSeconds()); },\n // unix timestamp\n U: function (date) { return date.getTime() / 1000; },\n W: function (date, _, options) {\n return options.getWeek(date);\n },\n // full year e.g. 2016, padded (0001-9999)\n Y: function (date) { return pad(date.getFullYear(), 4); },\n // day in month, padded (01-30)\n d: function (date) { return pad(date.getDate()); },\n // hour from 1-12 (am/pm)\n h: function (date) { return (date.getHours() % 12 ? date.getHours() % 12 : 12); },\n // minutes, padded with leading zero e.g. 09\n i: function (date) { return pad(date.getMinutes()); },\n // day in month (1-30)\n j: function (date) { return date.getDate(); },\n // weekday name, full, e.g. Thursday\n l: function (date, locale) {\n return locale.weekdays.longhand[date.getDay()];\n },\n // padded month number (01-12)\n m: function (date) { return pad(date.getMonth() + 1); },\n // the month number (1-12)\n n: function (date) { return date.getMonth() + 1; },\n // seconds 0-59\n s: function (date) { return date.getSeconds(); },\n // Unix Milliseconds\n u: function (date) { return date.getTime(); },\n // number of the day of the week\n w: function (date) { return date.getDay(); },\n // last two digits of year e.g. 16 for 2016\n y: function (date) { return String(date.getFullYear()).substring(2); },\n };\n\n var createDateFormatter = function (_a) {\n var _b = _a.config, config = _b === void 0 ? defaults : _b, _c = _a.l10n, l10n = _c === void 0 ? english : _c, _d = _a.isMobile, isMobile = _d === void 0 ? false : _d;\n return function (dateObj, frmt, overrideLocale) {\n var locale = overrideLocale || l10n;\n if (config.formatDate !== undefined && !isMobile) {\n return config.formatDate(dateObj, frmt, locale);\n }\n return frmt\n .split(\"\")\n .map(function (c, i, arr) {\n return formats[c] && arr[i - 1] !== \"\\\\\"\n ? formats[c](dateObj, locale, config)\n : c !== \"\\\\\"\n ? c\n : \"\";\n })\n .join(\"\");\n };\n };\n var createDateParser = function (_a) {\n var _b = _a.config, config = _b === void 0 ? defaults : _b, _c = _a.l10n, l10n = _c === void 0 ? english : _c;\n return function (date, givenFormat, timeless, customLocale) {\n if (date !== 0 && !date)\n return undefined;\n var locale = customLocale || l10n;\n var parsedDate;\n var dateOrig = date;\n if (date instanceof Date)\n parsedDate = new Date(date.getTime());\n else if (typeof date !== \"string\" &&\n date.toFixed !== undefined // timestamp\n )\n // create a copy\n parsedDate = new Date(date);\n else if (typeof date === \"string\") {\n // date string\n var format = givenFormat || (config || defaults).dateFormat;\n var datestr = String(date).trim();\n if (datestr === \"today\") {\n parsedDate = new Date();\n timeless = true;\n }\n else if (config && config.parseDate) {\n parsedDate = config.parseDate(date, format);\n }\n else if (/Z$/.test(datestr) ||\n /GMT$/.test(datestr) // datestrings w/ timezone\n ) {\n parsedDate = new Date(date);\n }\n else {\n var matched = void 0, ops = [];\n for (var i = 0, matchIndex = 0, regexStr = \"\"; i < format.length; i++) {\n var token_1 = format[i];\n var isBackSlash = token_1 === \"\\\\\";\n var escaped = format[i - 1] === \"\\\\\" || isBackSlash;\n if (tokenRegex[token_1] && !escaped) {\n regexStr += tokenRegex[token_1];\n var match = new RegExp(regexStr).exec(date);\n if (match && (matched = true)) {\n ops[token_1 !== \"Y\" ? \"push\" : \"unshift\"]({\n fn: revFormat[token_1],\n val: match[++matchIndex],\n });\n }\n }\n else if (!isBackSlash)\n regexStr += \".\"; // don't really care\n }\n parsedDate =\n !config || !config.noCalendar\n ? new Date(new Date().getFullYear(), 0, 1, 0, 0, 0, 0)\n : new Date(new Date().setHours(0, 0, 0, 0));\n ops.forEach(function (_a) {\n var fn = _a.fn, val = _a.val;\n return (parsedDate = fn(parsedDate, val, locale) || parsedDate);\n });\n parsedDate = matched ? parsedDate : undefined;\n }\n }\n /* istanbul ignore next */\n if (!(parsedDate instanceof Date && !isNaN(parsedDate.getTime()))) {\n config.errorHandler(new Error(\"Invalid date provided: \" + dateOrig));\n return undefined;\n }\n if (timeless === true)\n parsedDate.setHours(0, 0, 0, 0);\n return parsedDate;\n };\n };\n /**\n * Compute the difference in dates, measured in ms\n */\n function compareDates(date1, date2, timeless) {\n if (timeless === void 0) { timeless = true; }\n if (timeless !== false) {\n return (new Date(date1.getTime()).setHours(0, 0, 0, 0) -\n new Date(date2.getTime()).setHours(0, 0, 0, 0));\n }\n return date1.getTime() - date2.getTime();\n }\n var isBetween = function (ts, ts1, ts2) {\n return ts > Math.min(ts1, ts2) && ts < Math.max(ts1, ts2);\n };\n var calculateSecondsSinceMidnight = function (hours, minutes, seconds) {\n return hours * 3600 + minutes * 60 + seconds;\n };\n var parseSeconds = function (secondsSinceMidnight) {\n var hours = Math.floor(secondsSinceMidnight / 3600), minutes = (secondsSinceMidnight - hours * 3600) / 60;\n return [hours, minutes, secondsSinceMidnight - hours * 3600 - minutes * 60];\n };\n var duration = {\n DAY: 86400000,\n };\n function getDefaultHours(config) {\n var hours = config.defaultHour;\n var minutes = config.defaultMinute;\n var seconds = config.defaultSeconds;\n if (config.minDate !== undefined) {\n var minHour = config.minDate.getHours();\n var minMinutes = config.minDate.getMinutes();\n var minSeconds = config.minDate.getSeconds();\n if (hours < minHour) {\n hours = minHour;\n }\n if (hours === minHour && minutes < minMinutes) {\n minutes = minMinutes;\n }\n if (hours === minHour && minutes === minMinutes && seconds < minSeconds)\n seconds = config.minDate.getSeconds();\n }\n if (config.maxDate !== undefined) {\n var maxHr = config.maxDate.getHours();\n var maxMinutes = config.maxDate.getMinutes();\n hours = Math.min(hours, maxHr);\n if (hours === maxHr)\n minutes = Math.min(maxMinutes, minutes);\n if (hours === maxHr && minutes === maxMinutes)\n seconds = config.maxDate.getSeconds();\n }\n return { hours: hours, minutes: minutes, seconds: seconds };\n }\n\n if (typeof Object.assign !== \"function\") {\n Object.assign = function (target) {\n var args = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n args[_i - 1] = arguments[_i];\n }\n if (!target) {\n throw TypeError(\"Cannot convert undefined or null to object\");\n }\n var _loop_1 = function (source) {\n if (source) {\n Object.keys(source).forEach(function (key) { return (target[key] = source[key]); });\n }\n };\n for (var _a = 0, args_1 = args; _a < args_1.length; _a++) {\n var source = args_1[_a];\n _loop_1(source);\n }\n return target;\n };\n }\n\n var DEBOUNCED_CHANGE_MS = 300;\n function FlatpickrInstance(element, instanceConfig) {\n var self = {\n config: __assign(__assign({}, defaults), flatpickr.defaultConfig),\n l10n: english,\n };\n self.parseDate = createDateParser({ config: self.config, l10n: self.l10n });\n self._handlers = [];\n self.pluginElements = [];\n self.loadedPlugins = [];\n self._bind = bind;\n self._setHoursFromDate = setHoursFromDate;\n self._positionCalendar = positionCalendar;\n self.changeMonth = changeMonth;\n self.changeYear = changeYear;\n self.clear = clear;\n self.close = close;\n self.onMouseOver = onMouseOver;\n self._createElement = createElement;\n self.createDay = createDay;\n self.destroy = destroy;\n self.isEnabled = isEnabled;\n self.jumpToDate = jumpToDate;\n self.updateValue = updateValue;\n self.open = open;\n self.redraw = redraw;\n self.set = set;\n self.setDate = setDate;\n self.toggle = toggle;\n function setupHelperFunctions() {\n self.utils = {\n getDaysInMonth: function (month, yr) {\n if (month === void 0) { month = self.currentMonth; }\n if (yr === void 0) { yr = self.currentYear; }\n if (month === 1 && ((yr % 4 === 0 && yr % 100 !== 0) || yr % 400 === 0))\n return 29;\n return self.l10n.daysInMonth[month];\n },\n };\n }\n function init() {\n self.element = self.input = element;\n self.isOpen = false;\n parseConfig();\n setupLocale();\n setupInputs();\n setupDates();\n setupHelperFunctions();\n if (!self.isMobile)\n build();\n bindEvents();\n if (self.selectedDates.length || self.config.noCalendar) {\n if (self.config.enableTime) {\n setHoursFromDate(self.config.noCalendar ? self.latestSelectedDateObj : undefined);\n }\n updateValue(false);\n }\n setCalendarWidth();\n var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n /* TODO: investigate this further\n \n Currently, there is weird positioning behavior in safari causing pages\n to scroll up. https://github.com/chmln/flatpickr/issues/563\n \n However, most browsers are not Safari and positioning is expensive when used\n in scale. https://github.com/chmln/flatpickr/issues/1096\n */\n if (!self.isMobile && isSafari) {\n positionCalendar();\n }\n triggerEvent(\"onReady\");\n }\n function getClosestActiveElement() {\n var _a;\n return (((_a = self.calendarContainer) === null || _a === void 0 ? void 0 : _a.getRootNode())\n .activeElement || document.activeElement);\n }\n function bindToInstance(fn) {\n return fn.bind(self);\n }\n function setCalendarWidth() {\n var config = self.config;\n if (config.weekNumbers === false && config.showMonths === 1) {\n return;\n }\n else if (config.noCalendar !== true) {\n window.requestAnimationFrame(function () {\n if (self.calendarContainer !== undefined) {\n self.calendarContainer.style.visibility = \"hidden\";\n self.calendarContainer.style.display = \"block\";\n }\n if (self.daysContainer !== undefined) {\n var daysWidth = (self.days.offsetWidth + 1) * config.showMonths;\n self.daysContainer.style.width = daysWidth + \"px\";\n self.calendarContainer.style.width =\n daysWidth +\n (self.weekWrapper !== undefined\n ? self.weekWrapper.offsetWidth\n : 0) +\n \"px\";\n self.calendarContainer.style.removeProperty(\"visibility\");\n self.calendarContainer.style.removeProperty(\"display\");\n }\n });\n }\n }\n /**\n * The handler for all events targeting the time inputs\n */\n function updateTime(e) {\n if (self.selectedDates.length === 0) {\n var defaultDate = self.config.minDate === undefined ||\n compareDates(new Date(), self.config.minDate) >= 0\n ? new Date()\n : new Date(self.config.minDate.getTime());\n var defaults = getDefaultHours(self.config);\n defaultDate.setHours(defaults.hours, defaults.minutes, defaults.seconds, defaultDate.getMilliseconds());\n self.selectedDates = [defaultDate];\n self.latestSelectedDateObj = defaultDate;\n }\n if (e !== undefined && e.type !== \"blur\") {\n timeWrapper(e);\n }\n var prevValue = self._input.value;\n setHoursFromInputs();\n updateValue();\n if (self._input.value !== prevValue) {\n self._debouncedChange();\n }\n }\n function ampm2military(hour, amPM) {\n return (hour % 12) + 12 * int(amPM === self.l10n.amPM[1]);\n }\n function military2ampm(hour) {\n switch (hour % 24) {\n case 0:\n case 12:\n return 12;\n default:\n return hour % 12;\n }\n }\n /**\n * Syncs the selected date object time with user's time input\n */\n function setHoursFromInputs() {\n if (self.hourElement === undefined || self.minuteElement === undefined)\n return;\n var hours = (parseInt(self.hourElement.value.slice(-2), 10) || 0) % 24, minutes = (parseInt(self.minuteElement.value, 10) || 0) % 60, seconds = self.secondElement !== undefined\n ? (parseInt(self.secondElement.value, 10) || 0) % 60\n : 0;\n if (self.amPM !== undefined) {\n hours = ampm2military(hours, self.amPM.textContent);\n }\n var limitMinHours = self.config.minTime !== undefined ||\n (self.config.minDate &&\n self.minDateHasTime &&\n self.latestSelectedDateObj &&\n compareDates(self.latestSelectedDateObj, self.config.minDate, true) ===\n 0);\n var limitMaxHours = self.config.maxTime !== undefined ||\n (self.config.maxDate &&\n self.maxDateHasTime &&\n self.latestSelectedDateObj &&\n compareDates(self.latestSelectedDateObj, self.config.maxDate, true) ===\n 0);\n if (self.config.maxTime !== undefined &&\n self.config.minTime !== undefined &&\n self.config.minTime > self.config.maxTime) {\n var minBound = calculateSecondsSinceMidnight(self.config.minTime.getHours(), self.config.minTime.getMinutes(), self.config.minTime.getSeconds());\n var maxBound = calculateSecondsSinceMidnight(self.config.maxTime.getHours(), self.config.maxTime.getMinutes(), self.config.maxTime.getSeconds());\n var currentTime = calculateSecondsSinceMidnight(hours, minutes, seconds);\n if (currentTime > maxBound && currentTime < minBound) {\n var result = parseSeconds(minBound);\n hours = result[0];\n minutes = result[1];\n seconds = result[2];\n }\n }\n else {\n if (limitMaxHours) {\n var maxTime = self.config.maxTime !== undefined\n ? self.config.maxTime\n : self.config.maxDate;\n hours = Math.min(hours, maxTime.getHours());\n if (hours === maxTime.getHours())\n minutes = Math.min(minutes, maxTime.getMinutes());\n if (minutes === maxTime.getMinutes())\n seconds = Math.min(seconds, maxTime.getSeconds());\n }\n if (limitMinHours) {\n var minTime = self.config.minTime !== undefined\n ? self.config.minTime\n : self.config.minDate;\n hours = Math.max(hours, minTime.getHours());\n if (hours === minTime.getHours() && minutes < minTime.getMinutes())\n minutes = minTime.getMinutes();\n if (minutes === minTime.getMinutes())\n seconds = Math.max(seconds, minTime.getSeconds());\n }\n }\n setHours(hours, minutes, seconds);\n }\n /**\n * Syncs time input values with a date\n */\n function setHoursFromDate(dateObj) {\n var date = dateObj || self.latestSelectedDateObj;\n if (date && date instanceof Date) {\n setHours(date.getHours(), date.getMinutes(), date.getSeconds());\n }\n }\n /**\n * Sets the hours, minutes, and optionally seconds\n * of the latest selected date object and the\n * corresponding time inputs\n * @param {Number} hours the hour. whether its military\n * or am-pm gets inferred from config\n * @param {Number} minutes the minutes\n * @param {Number} seconds the seconds (optional)\n */\n function setHours(hours, minutes, seconds) {\n if (self.latestSelectedDateObj !== undefined) {\n self.latestSelectedDateObj.setHours(hours % 24, minutes, seconds || 0, 0);\n }\n if (!self.hourElement || !self.minuteElement || self.isMobile)\n return;\n self.hourElement.value = pad(!self.config.time_24hr\n ? ((12 + hours) % 12) + 12 * int(hours % 12 === 0)\n : hours);\n self.minuteElement.value = pad(minutes);\n if (self.amPM !== undefined)\n self.amPM.textContent = self.l10n.amPM[int(hours >= 12)];\n if (self.secondElement !== undefined)\n self.secondElement.value = pad(seconds);\n }\n /**\n * Handles the year input and incrementing events\n * @param {Event} event the keyup or increment event\n */\n function onYearInput(event) {\n var eventTarget = getEventTarget(event);\n var year = parseInt(eventTarget.value) + (event.delta || 0);\n if (year / 1000 > 1 ||\n (event.key === \"Enter\" && !/[^\\d]/.test(year.toString()))) {\n changeYear(year);\n }\n }\n /**\n * Essentially addEventListener + tracking\n * @param {Element} element the element to addEventListener to\n * @param {String} event the event name\n * @param {Function} handler the event handler\n */\n function bind(element, event, handler, options) {\n if (event instanceof Array)\n return event.forEach(function (ev) { return bind(element, ev, handler, options); });\n if (element instanceof Array)\n return element.forEach(function (el) { return bind(el, event, handler, options); });\n element.addEventListener(event, handler, options);\n self._handlers.push({\n remove: function () { return element.removeEventListener(event, handler, options); },\n });\n }\n function triggerChange() {\n triggerEvent(\"onChange\");\n }\n /**\n * Adds all the necessary event listeners\n */\n function bindEvents() {\n if (self.config.wrap) {\n [\"open\", \"close\", \"toggle\", \"clear\"].forEach(function (evt) {\n Array.prototype.forEach.call(self.element.querySelectorAll(\"[data-\" + evt + \"]\"), function (el) {\n return bind(el, \"click\", self[evt]);\n });\n });\n }\n if (self.isMobile) {\n setupMobile();\n return;\n }\n var debouncedResize = debounce(onResize, 50);\n self._debouncedChange = debounce(triggerChange, DEBOUNCED_CHANGE_MS);\n if (self.daysContainer && !/iPhone|iPad|iPod/i.test(navigator.userAgent))\n bind(self.daysContainer, \"mouseover\", function (e) {\n if (self.config.mode === \"range\")\n onMouseOver(getEventTarget(e));\n });\n bind(self._input, \"keydown\", onKeyDown);\n if (self.calendarContainer !== undefined) {\n bind(self.calendarContainer, \"keydown\", onKeyDown);\n }\n if (!self.config.inline && !self.config.static)\n bind(window, \"resize\", debouncedResize);\n if (window.ontouchstart !== undefined)\n bind(window.document, \"touchstart\", documentClick);\n else\n bind(window.document, \"mousedown\", documentClick);\n bind(window.document, \"focus\", documentClick, { capture: true });\n if (self.config.clickOpens === true) {\n bind(self._input, \"focus\", self.open);\n bind(self._input, \"click\", self.open);\n }\n if (self.daysContainer !== undefined) {\n bind(self.monthNav, \"click\", onMonthNavClick);\n bind(self.monthNav, [\"keyup\", \"increment\"], onYearInput);\n bind(self.daysContainer, \"click\", selectDate);\n }\n if (self.timeContainer !== undefined &&\n self.minuteElement !== undefined &&\n self.hourElement !== undefined) {\n var selText = function (e) {\n return getEventTarget(e).select();\n };\n bind(self.timeContainer, [\"increment\"], updateTime);\n bind(self.timeContainer, \"blur\", updateTime, { capture: true });\n bind(self.timeContainer, \"click\", timeIncrement);\n bind([self.hourElement, self.minuteElement], [\"focus\", \"click\"], selText);\n if (self.secondElement !== undefined)\n bind(self.secondElement, \"focus\", function () { return self.secondElement && self.secondElement.select(); });\n if (self.amPM !== undefined) {\n bind(self.amPM, \"click\", function (e) {\n updateTime(e);\n });\n }\n }\n if (self.config.allowInput) {\n bind(self._input, \"blur\", onBlur);\n }\n }\n /**\n * Set the calendar view to a particular date.\n * @param {Date} jumpDate the date to set the view to\n * @param {boolean} triggerChange if change events should be triggered\n */\n function jumpToDate(jumpDate, triggerChange) {\n var jumpTo = jumpDate !== undefined\n ? self.parseDate(jumpDate)\n : self.latestSelectedDateObj ||\n (self.config.minDate && self.config.minDate > self.now\n ? self.config.minDate\n : self.config.maxDate && self.config.maxDate < self.now\n ? self.config.maxDate\n : self.now);\n var oldYear = self.currentYear;\n var oldMonth = self.currentMonth;\n try {\n if (jumpTo !== undefined) {\n self.currentYear = jumpTo.getFullYear();\n self.currentMonth = jumpTo.getMonth();\n }\n }\n catch (e) {\n /* istanbul ignore next */\n e.message = \"Invalid date supplied: \" + jumpTo;\n self.config.errorHandler(e);\n }\n if (triggerChange && self.currentYear !== oldYear) {\n triggerEvent(\"onYearChange\");\n buildMonthSwitch();\n }\n if (triggerChange &&\n (self.currentYear !== oldYear || self.currentMonth !== oldMonth)) {\n triggerEvent(\"onMonthChange\");\n }\n self.redraw();\n }\n /**\n * The up/down arrow handler for time inputs\n * @param {Event} e the click event\n */\n function timeIncrement(e) {\n var eventTarget = getEventTarget(e);\n if (~eventTarget.className.indexOf(\"arrow\"))\n incrementNumInput(e, eventTarget.classList.contains(\"arrowUp\") ? 1 : -1);\n }\n /**\n * Increments/decrements the value of input associ-\n * ated with the up/down arrow by dispatching an\n * \"increment\" event on the input.\n *\n * @param {Event} e the click event\n * @param {Number} delta the diff (usually 1 or -1)\n * @param {Element} inputElem the input element\n */\n function incrementNumInput(e, delta, inputElem) {\n var target = e && getEventTarget(e);\n var input = inputElem ||\n (target && target.parentNode && target.parentNode.firstChild);\n var event = createEvent(\"increment\");\n event.delta = delta;\n input && input.dispatchEvent(event);\n }\n function build() {\n var fragment = window.document.createDocumentFragment();\n self.calendarContainer = createElement(\"div\", \"flatpickr-calendar\");\n self.calendarContainer.tabIndex = -1;\n if (!self.config.noCalendar) {\n fragment.appendChild(buildMonthNav());\n self.innerContainer = createElement(\"div\", \"flatpickr-innerContainer\");\n if (self.config.weekNumbers) {\n var _a = buildWeeks(), weekWrapper = _a.weekWrapper, weekNumbers = _a.weekNumbers;\n self.innerContainer.appendChild(weekWrapper);\n self.weekNumbers = weekNumbers;\n self.weekWrapper = weekWrapper;\n }\n self.rContainer = createElement(\"div\", \"flatpickr-rContainer\");\n self.rContainer.appendChild(buildWeekdays());\n if (!self.daysContainer) {\n self.daysContainer = createElement(\"div\", \"flatpickr-days\");\n self.daysContainer.tabIndex = -1;\n }\n buildDays();\n self.rContainer.appendChild(self.daysContainer);\n self.innerContainer.appendChild(self.rContainer);\n fragment.appendChild(self.innerContainer);\n }\n if (self.config.enableTime) {\n fragment.appendChild(buildTime());\n }\n toggleClass(self.calendarContainer, \"rangeMode\", self.config.mode === \"range\");\n toggleClass(self.calendarContainer, \"animate\", self.config.animate === true);\n toggleClass(self.calendarContainer, \"multiMonth\", self.config.showMonths > 1);\n self.calendarContainer.appendChild(fragment);\n var customAppend = self.config.appendTo !== undefined &&\n self.config.appendTo.nodeType !== undefined;\n if (self.config.inline || self.config.static) {\n self.calendarContainer.classList.add(self.config.inline ? \"inline\" : \"static\");\n if (self.config.inline) {\n if (!customAppend && self.element.parentNode)\n self.element.parentNode.insertBefore(self.calendarContainer, self._input.nextSibling);\n else if (self.config.appendTo !== undefined)\n self.config.appendTo.appendChild(self.calendarContainer);\n }\n if (self.config.static) {\n var wrapper = createElement(\"div\", \"flatpickr-wrapper\");\n if (self.element.parentNode)\n self.element.parentNode.insertBefore(wrapper, self.element);\n wrapper.appendChild(self.element);\n if (self.altInput)\n wrapper.appendChild(self.altInput);\n wrapper.appendChild(self.calendarContainer);\n }\n }\n if (!self.config.static && !self.config.inline)\n (self.config.appendTo !== undefined\n ? self.config.appendTo\n : window.document.body).appendChild(self.calendarContainer);\n }\n function createDay(className, date, _dayNumber, i) {\n var dateIsEnabled = isEnabled(date, true), dayElement = createElement(\"span\", className, date.getDate().toString());\n dayElement.dateObj = date;\n dayElement.$i = i;\n dayElement.setAttribute(\"aria-label\", self.formatDate(date, self.config.ariaDateFormat));\n if (className.indexOf(\"hidden\") === -1 &&\n compareDates(date, self.now) === 0) {\n self.todayDateElem = dayElement;\n dayElement.classList.add(\"today\");\n dayElement.setAttribute(\"aria-current\", \"date\");\n }\n if (dateIsEnabled) {\n dayElement.tabIndex = -1;\n if (isDateSelected(date)) {\n dayElement.classList.add(\"selected\");\n self.selectedDateElem = dayElement;\n if (self.config.mode === \"range\") {\n toggleClass(dayElement, \"startRange\", self.selectedDates[0] &&\n compareDates(date, self.selectedDates[0], true) === 0);\n toggleClass(dayElement, \"endRange\", self.selectedDates[1] &&\n compareDates(date, self.selectedDates[1], true) === 0);\n if (className === \"nextMonthDay\")\n dayElement.classList.add(\"inRange\");\n }\n }\n }\n else {\n dayElement.classList.add(\"flatpickr-disabled\");\n }\n if (self.config.mode === \"range\") {\n if (isDateInRange(date) && !isDateSelected(date))\n dayElement.classList.add(\"inRange\");\n }\n if (self.weekNumbers &&\n self.config.showMonths === 1 &&\n className !== \"prevMonthDay\" &&\n i % 7 === 6) {\n self.weekNumbers.insertAdjacentHTML(\"beforeend\", \"\" + self.config.getWeek(date) + \"\");\n }\n triggerEvent(\"onDayCreate\", dayElement);\n return dayElement;\n }\n function focusOnDayElem(targetNode) {\n targetNode.focus();\n if (self.config.mode === \"range\")\n onMouseOver(targetNode);\n }\n function getFirstAvailableDay(delta) {\n var startMonth = delta > 0 ? 0 : self.config.showMonths - 1;\n var endMonth = delta > 0 ? self.config.showMonths : -1;\n for (var m = startMonth; m != endMonth; m += delta) {\n var month = self.daysContainer.children[m];\n var startIndex = delta > 0 ? 0 : month.children.length - 1;\n var endIndex = delta > 0 ? month.children.length : -1;\n for (var i = startIndex; i != endIndex; i += delta) {\n var c = month.children[i];\n if (c.className.indexOf(\"hidden\") === -1 && isEnabled(c.dateObj))\n return c;\n }\n }\n return undefined;\n }\n function getNextAvailableDay(current, delta) {\n var givenMonth = current.className.indexOf(\"Month\") === -1\n ? current.dateObj.getMonth()\n : self.currentMonth;\n var endMonth = delta > 0 ? self.config.showMonths : -1;\n var loopDelta = delta > 0 ? 1 : -1;\n for (var m = givenMonth - self.currentMonth; m != endMonth; m += loopDelta) {\n var month = self.daysContainer.children[m];\n var startIndex = givenMonth - self.currentMonth === m\n ? current.$i + delta\n : delta < 0\n ? month.children.length - 1\n : 0;\n var numMonthDays = month.children.length;\n for (var i = startIndex; i >= 0 && i < numMonthDays && i != (delta > 0 ? numMonthDays : -1); i += loopDelta) {\n var c = month.children[i];\n if (c.className.indexOf(\"hidden\") === -1 &&\n isEnabled(c.dateObj) &&\n Math.abs(current.$i - i) >= Math.abs(delta))\n return focusOnDayElem(c);\n }\n }\n self.changeMonth(loopDelta);\n focusOnDay(getFirstAvailableDay(loopDelta), 0);\n return undefined;\n }\n function focusOnDay(current, offset) {\n var activeElement = getClosestActiveElement();\n var dayFocused = isInView(activeElement || document.body);\n var startElem = current !== undefined\n ? current\n : dayFocused\n ? activeElement\n : self.selectedDateElem !== undefined && isInView(self.selectedDateElem)\n ? self.selectedDateElem\n : self.todayDateElem !== undefined && isInView(self.todayDateElem)\n ? self.todayDateElem\n : getFirstAvailableDay(offset > 0 ? 1 : -1);\n if (startElem === undefined) {\n self._input.focus();\n }\n else if (!dayFocused) {\n focusOnDayElem(startElem);\n }\n else {\n getNextAvailableDay(startElem, offset);\n }\n }\n function buildMonthDays(year, month) {\n var firstOfMonth = (new Date(year, month, 1).getDay() - self.l10n.firstDayOfWeek + 7) % 7;\n var prevMonthDays = self.utils.getDaysInMonth((month - 1 + 12) % 12, year);\n var daysInMonth = self.utils.getDaysInMonth(month, year), days = window.document.createDocumentFragment(), isMultiMonth = self.config.showMonths > 1, prevMonthDayClass = isMultiMonth ? \"prevMonthDay hidden\" : \"prevMonthDay\", nextMonthDayClass = isMultiMonth ? \"nextMonthDay hidden\" : \"nextMonthDay\";\n var dayNumber = prevMonthDays + 1 - firstOfMonth, dayIndex = 0;\n // prepend days from the ending of previous month\n for (; dayNumber <= prevMonthDays; dayNumber++, dayIndex++) {\n days.appendChild(createDay(\"flatpickr-day \" + prevMonthDayClass, new Date(year, month - 1, dayNumber), dayNumber, dayIndex));\n }\n // Start at 1 since there is no 0th day\n for (dayNumber = 1; dayNumber <= daysInMonth; dayNumber++, dayIndex++) {\n days.appendChild(createDay(\"flatpickr-day\", new Date(year, month, dayNumber), dayNumber, dayIndex));\n }\n // append days from the next month\n for (var dayNum = daysInMonth + 1; dayNum <= 42 - firstOfMonth &&\n (self.config.showMonths === 1 || dayIndex % 7 !== 0); dayNum++, dayIndex++) {\n days.appendChild(createDay(\"flatpickr-day \" + nextMonthDayClass, new Date(year, month + 1, dayNum % daysInMonth), dayNum, dayIndex));\n }\n //updateNavigationCurrentMonth();\n var dayContainer = createElement(\"div\", \"dayContainer\");\n dayContainer.appendChild(days);\n return dayContainer;\n }\n function buildDays() {\n if (self.daysContainer === undefined) {\n return;\n }\n clearNode(self.daysContainer);\n // TODO: week numbers for each month\n if (self.weekNumbers)\n clearNode(self.weekNumbers);\n var frag = document.createDocumentFragment();\n for (var i = 0; i < self.config.showMonths; i++) {\n var d = new Date(self.currentYear, self.currentMonth, 1);\n d.setMonth(self.currentMonth + i);\n frag.appendChild(buildMonthDays(d.getFullYear(), d.getMonth()));\n }\n self.daysContainer.appendChild(frag);\n self.days = self.daysContainer.firstChild;\n if (self.config.mode === \"range\" && self.selectedDates.length === 1) {\n onMouseOver();\n }\n }\n function buildMonthSwitch() {\n if (self.config.showMonths > 1 ||\n self.config.monthSelectorType !== \"dropdown\")\n return;\n var shouldBuildMonth = function (month) {\n if (self.config.minDate !== undefined &&\n self.currentYear === self.config.minDate.getFullYear() &&\n month < self.config.minDate.getMonth()) {\n return false;\n }\n return !(self.config.maxDate !== undefined &&\n self.currentYear === self.config.maxDate.getFullYear() &&\n month > self.config.maxDate.getMonth());\n };\n self.monthsDropdownContainer.tabIndex = -1;\n self.monthsDropdownContainer.innerHTML = \"\";\n for (var i = 0; i < 12; i++) {\n if (!shouldBuildMonth(i))\n continue;\n var month = createElement(\"option\", \"flatpickr-monthDropdown-month\");\n month.value = new Date(self.currentYear, i).getMonth().toString();\n month.textContent = monthToStr(i, self.config.shorthandCurrentMonth, self.l10n);\n month.tabIndex = -1;\n if (self.currentMonth === i) {\n month.selected = true;\n }\n self.monthsDropdownContainer.appendChild(month);\n }\n }\n function buildMonth() {\n var container = createElement(\"div\", \"flatpickr-month\");\n var monthNavFragment = window.document.createDocumentFragment();\n var monthElement;\n if (self.config.showMonths > 1 ||\n self.config.monthSelectorType === \"static\") {\n monthElement = createElement(\"span\", \"cur-month\");\n }\n else {\n self.monthsDropdownContainer = createElement(\"select\", \"flatpickr-monthDropdown-months\");\n self.monthsDropdownContainer.setAttribute(\"aria-label\", self.l10n.monthAriaLabel);\n bind(self.monthsDropdownContainer, \"change\", function (e) {\n var target = getEventTarget(e);\n var selectedMonth = parseInt(target.value, 10);\n self.changeMonth(selectedMonth - self.currentMonth);\n triggerEvent(\"onMonthChange\");\n });\n buildMonthSwitch();\n monthElement = self.monthsDropdownContainer;\n }\n var yearInput = createNumberInput(\"cur-year\", { tabindex: \"-1\" });\n var yearElement = yearInput.getElementsByTagName(\"input\")[0];\n yearElement.setAttribute(\"aria-label\", self.l10n.yearAriaLabel);\n if (self.config.minDate) {\n yearElement.setAttribute(\"min\", self.config.minDate.getFullYear().toString());\n }\n if (self.config.maxDate) {\n yearElement.setAttribute(\"max\", self.config.maxDate.getFullYear().toString());\n yearElement.disabled =\n !!self.config.minDate &&\n self.config.minDate.getFullYear() === self.config.maxDate.getFullYear();\n }\n var currentMonth = createElement(\"div\", \"flatpickr-current-month\");\n currentMonth.appendChild(monthElement);\n currentMonth.appendChild(yearInput);\n monthNavFragment.appendChild(currentMonth);\n container.appendChild(monthNavFragment);\n return {\n container: container,\n yearElement: yearElement,\n monthElement: monthElement,\n };\n }\n function buildMonths() {\n clearNode(self.monthNav);\n self.monthNav.appendChild(self.prevMonthNav);\n if (self.config.showMonths) {\n self.yearElements = [];\n self.monthElements = [];\n }\n for (var m = self.config.showMonths; m--;) {\n var month = buildMonth();\n self.yearElements.push(month.yearElement);\n self.monthElements.push(month.monthElement);\n self.monthNav.appendChild(month.container);\n }\n self.monthNav.appendChild(self.nextMonthNav);\n }\n function buildMonthNav() {\n self.monthNav = createElement(\"div\", \"flatpickr-months\");\n self.yearElements = [];\n self.monthElements = [];\n self.prevMonthNav = createElement(\"span\", \"flatpickr-prev-month\");\n self.prevMonthNav.innerHTML = self.config.prevArrow;\n self.nextMonthNav = createElement(\"span\", \"flatpickr-next-month\");\n self.nextMonthNav.innerHTML = self.config.nextArrow;\n buildMonths();\n Object.defineProperty(self, \"_hidePrevMonthArrow\", {\n get: function () { return self.__hidePrevMonthArrow; },\n set: function (bool) {\n if (self.__hidePrevMonthArrow !== bool) {\n toggleClass(self.prevMonthNav, \"flatpickr-disabled\", bool);\n self.__hidePrevMonthArrow = bool;\n }\n },\n });\n Object.defineProperty(self, \"_hideNextMonthArrow\", {\n get: function () { return self.__hideNextMonthArrow; },\n set: function (bool) {\n if (self.__hideNextMonthArrow !== bool) {\n toggleClass(self.nextMonthNav, \"flatpickr-disabled\", bool);\n self.__hideNextMonthArrow = bool;\n }\n },\n });\n self.currentYearElement = self.yearElements[0];\n updateNavigationCurrentMonth();\n return self.monthNav;\n }\n function buildTime() {\n self.calendarContainer.classList.add(\"hasTime\");\n if (self.config.noCalendar)\n self.calendarContainer.classList.add(\"noCalendar\");\n var defaults = getDefaultHours(self.config);\n self.timeContainer = createElement(\"div\", \"flatpickr-time\");\n self.timeContainer.tabIndex = -1;\n var separator = createElement(\"span\", \"flatpickr-time-separator\", \":\");\n var hourInput = createNumberInput(\"flatpickr-hour\", {\n \"aria-label\": self.l10n.hourAriaLabel,\n });\n self.hourElement = hourInput.getElementsByTagName(\"input\")[0];\n var minuteInput = createNumberInput(\"flatpickr-minute\", {\n \"aria-label\": self.l10n.minuteAriaLabel,\n });\n self.minuteElement = minuteInput.getElementsByTagName(\"input\")[0];\n self.hourElement.tabIndex = self.minuteElement.tabIndex = -1;\n self.hourElement.value = pad(self.latestSelectedDateObj\n ? self.latestSelectedDateObj.getHours()\n : self.config.time_24hr\n ? defaults.hours\n : military2ampm(defaults.hours));\n self.minuteElement.value = pad(self.latestSelectedDateObj\n ? self.latestSelectedDateObj.getMinutes()\n : defaults.minutes);\n self.hourElement.setAttribute(\"step\", self.config.hourIncrement.toString());\n self.minuteElement.setAttribute(\"step\", self.config.minuteIncrement.toString());\n self.hourElement.setAttribute(\"min\", self.config.time_24hr ? \"0\" : \"1\");\n self.hourElement.setAttribute(\"max\", self.config.time_24hr ? \"23\" : \"12\");\n self.hourElement.setAttribute(\"maxlength\", \"2\");\n self.minuteElement.setAttribute(\"min\", \"0\");\n self.minuteElement.setAttribute(\"max\", \"59\");\n self.minuteElement.setAttribute(\"maxlength\", \"2\");\n self.timeContainer.appendChild(hourInput);\n self.timeContainer.appendChild(separator);\n self.timeContainer.appendChild(minuteInput);\n if (self.config.time_24hr)\n self.timeContainer.classList.add(\"time24hr\");\n if (self.config.enableSeconds) {\n self.timeContainer.classList.add(\"hasSeconds\");\n var secondInput = createNumberInput(\"flatpickr-second\");\n self.secondElement = secondInput.getElementsByTagName(\"input\")[0];\n self.secondElement.value = pad(self.latestSelectedDateObj\n ? self.latestSelectedDateObj.getSeconds()\n : defaults.seconds);\n self.secondElement.setAttribute(\"step\", self.minuteElement.getAttribute(\"step\"));\n self.secondElement.setAttribute(\"min\", \"0\");\n self.secondElement.setAttribute(\"max\", \"59\");\n self.secondElement.setAttribute(\"maxlength\", \"2\");\n self.timeContainer.appendChild(createElement(\"span\", \"flatpickr-time-separator\", \":\"));\n self.timeContainer.appendChild(secondInput);\n }\n if (!self.config.time_24hr) {\n // add self.amPM if appropriate\n self.amPM = createElement(\"span\", \"flatpickr-am-pm\", self.l10n.amPM[int((self.latestSelectedDateObj\n ? self.hourElement.value\n : self.config.defaultHour) > 11)]);\n self.amPM.title = self.l10n.toggleTitle;\n self.amPM.tabIndex = -1;\n self.timeContainer.appendChild(self.amPM);\n }\n return self.timeContainer;\n }\n function buildWeekdays() {\n if (!self.weekdayContainer)\n self.weekdayContainer = createElement(\"div\", \"flatpickr-weekdays\");\n else\n clearNode(self.weekdayContainer);\n for (var i = self.config.showMonths; i--;) {\n var container = createElement(\"div\", \"flatpickr-weekdaycontainer\");\n self.weekdayContainer.appendChild(container);\n }\n updateWeekdays();\n return self.weekdayContainer;\n }\n function updateWeekdays() {\n if (!self.weekdayContainer) {\n return;\n }\n var firstDayOfWeek = self.l10n.firstDayOfWeek;\n var weekdays = __spreadArrays(self.l10n.weekdays.shorthand);\n if (firstDayOfWeek > 0 && firstDayOfWeek < weekdays.length) {\n weekdays = __spreadArrays(weekdays.splice(firstDayOfWeek, weekdays.length), weekdays.splice(0, firstDayOfWeek));\n }\n for (var i = self.config.showMonths; i--;) {\n self.weekdayContainer.children[i].innerHTML = \"\\n \\n \" + weekdays.join(\"\") + \"\\n \\n \";\n }\n }\n /* istanbul ignore next */\n function buildWeeks() {\n self.calendarContainer.classList.add(\"hasWeeks\");\n var weekWrapper = createElement(\"div\", \"flatpickr-weekwrapper\");\n weekWrapper.appendChild(createElement(\"span\", \"flatpickr-weekday\", self.l10n.weekAbbreviation));\n var weekNumbers = createElement(\"div\", \"flatpickr-weeks\");\n weekWrapper.appendChild(weekNumbers);\n return {\n weekWrapper: weekWrapper,\n weekNumbers: weekNumbers,\n };\n }\n function changeMonth(value, isOffset) {\n if (isOffset === void 0) { isOffset = true; }\n var delta = isOffset ? value : value - self.currentMonth;\n if ((delta < 0 && self._hidePrevMonthArrow === true) ||\n (delta > 0 && self._hideNextMonthArrow === true))\n return;\n self.currentMonth += delta;\n if (self.currentMonth < 0 || self.currentMonth > 11) {\n self.currentYear += self.currentMonth > 11 ? 1 : -1;\n self.currentMonth = (self.currentMonth + 12) % 12;\n triggerEvent(\"onYearChange\");\n buildMonthSwitch();\n }\n buildDays();\n triggerEvent(\"onMonthChange\");\n updateNavigationCurrentMonth();\n }\n function clear(triggerChangeEvent, toInitial) {\n if (triggerChangeEvent === void 0) { triggerChangeEvent = true; }\n if (toInitial === void 0) { toInitial = true; }\n self.input.value = \"\";\n if (self.altInput !== undefined)\n self.altInput.value = \"\";\n if (self.mobileInput !== undefined)\n self.mobileInput.value = \"\";\n self.selectedDates = [];\n self.latestSelectedDateObj = undefined;\n if (toInitial === true) {\n self.currentYear = self._initialDate.getFullYear();\n self.currentMonth = self._initialDate.getMonth();\n }\n if (self.config.enableTime === true) {\n var _a = getDefaultHours(self.config), hours = _a.hours, minutes = _a.minutes, seconds = _a.seconds;\n setHours(hours, minutes, seconds);\n }\n self.redraw();\n if (triggerChangeEvent)\n // triggerChangeEvent is true (default) or an Event\n triggerEvent(\"onChange\");\n }\n function close() {\n self.isOpen = false;\n if (!self.isMobile) {\n if (self.calendarContainer !== undefined) {\n self.calendarContainer.classList.remove(\"open\");\n }\n if (self._input !== undefined) {\n self._input.classList.remove(\"active\");\n }\n }\n triggerEvent(\"onClose\");\n }\n function destroy() {\n if (self.config !== undefined)\n triggerEvent(\"onDestroy\");\n for (var i = self._handlers.length; i--;) {\n self._handlers[i].remove();\n }\n self._handlers = [];\n if (self.mobileInput) {\n if (self.mobileInput.parentNode)\n self.mobileInput.parentNode.removeChild(self.mobileInput);\n self.mobileInput = undefined;\n }\n else if (self.calendarContainer && self.calendarContainer.parentNode) {\n if (self.config.static && self.calendarContainer.parentNode) {\n var wrapper = self.calendarContainer.parentNode;\n wrapper.lastChild && wrapper.removeChild(wrapper.lastChild);\n if (wrapper.parentNode) {\n while (wrapper.firstChild)\n wrapper.parentNode.insertBefore(wrapper.firstChild, wrapper);\n wrapper.parentNode.removeChild(wrapper);\n }\n }\n else\n self.calendarContainer.parentNode.removeChild(self.calendarContainer);\n }\n if (self.altInput) {\n self.input.type = \"text\";\n if (self.altInput.parentNode)\n self.altInput.parentNode.removeChild(self.altInput);\n delete self.altInput;\n }\n if (self.input) {\n self.input.type = self.input._type;\n self.input.classList.remove(\"flatpickr-input\");\n self.input.removeAttribute(\"readonly\");\n }\n [\n \"_showTimeInput\",\n \"latestSelectedDateObj\",\n \"_hideNextMonthArrow\",\n \"_hidePrevMonthArrow\",\n \"__hideNextMonthArrow\",\n \"__hidePrevMonthArrow\",\n \"isMobile\",\n \"isOpen\",\n \"selectedDateElem\",\n \"minDateHasTime\",\n \"maxDateHasTime\",\n \"days\",\n \"daysContainer\",\n \"_input\",\n \"_positionElement\",\n \"innerContainer\",\n \"rContainer\",\n \"monthNav\",\n \"todayDateElem\",\n \"calendarContainer\",\n \"weekdayContainer\",\n \"prevMonthNav\",\n \"nextMonthNav\",\n \"monthsDropdownContainer\",\n \"currentMonthElement\",\n \"currentYearElement\",\n \"navigationCurrentMonth\",\n \"selectedDateElem\",\n \"config\",\n ].forEach(function (k) {\n try {\n delete self[k];\n }\n catch (_) { }\n });\n }\n function isCalendarElem(elem) {\n return self.calendarContainer.contains(elem);\n }\n function documentClick(e) {\n if (self.isOpen && !self.config.inline) {\n var eventTarget_1 = getEventTarget(e);\n var isCalendarElement = isCalendarElem(eventTarget_1);\n var isInput = eventTarget_1 === self.input ||\n eventTarget_1 === self.altInput ||\n self.element.contains(eventTarget_1) ||\n // web components\n // e.path is not present in all browsers. circumventing typechecks\n (e.path &&\n e.path.indexOf &&\n (~e.path.indexOf(self.input) ||\n ~e.path.indexOf(self.altInput)));\n var lostFocus = !isInput &&\n !isCalendarElement &&\n !isCalendarElem(e.relatedTarget);\n var isIgnored = !self.config.ignoredFocusElements.some(function (elem) {\n return elem.contains(eventTarget_1);\n });\n if (lostFocus && isIgnored) {\n if (self.config.allowInput) {\n self.setDate(self._input.value, false, self.config.altInput\n ? self.config.altFormat\n : self.config.dateFormat);\n }\n if (self.timeContainer !== undefined &&\n self.minuteElement !== undefined &&\n self.hourElement !== undefined &&\n self.input.value !== \"\" &&\n self.input.value !== undefined) {\n updateTime();\n }\n self.close();\n if (self.config &&\n self.config.mode === \"range\" &&\n self.selectedDates.length === 1)\n self.clear(false);\n }\n }\n }\n function changeYear(newYear) {\n if (!newYear ||\n (self.config.minDate && newYear < self.config.minDate.getFullYear()) ||\n (self.config.maxDate && newYear > self.config.maxDate.getFullYear()))\n return;\n var newYearNum = newYear, isNewYear = self.currentYear !== newYearNum;\n self.currentYear = newYearNum || self.currentYear;\n if (self.config.maxDate &&\n self.currentYear === self.config.maxDate.getFullYear()) {\n self.currentMonth = Math.min(self.config.maxDate.getMonth(), self.currentMonth);\n }\n else if (self.config.minDate &&\n self.currentYear === self.config.minDate.getFullYear()) {\n self.currentMonth = Math.max(self.config.minDate.getMonth(), self.currentMonth);\n }\n if (isNewYear) {\n self.redraw();\n triggerEvent(\"onYearChange\");\n buildMonthSwitch();\n }\n }\n function isEnabled(date, timeless) {\n var _a;\n if (timeless === void 0) { timeless = true; }\n var dateToCheck = self.parseDate(date, undefined, timeless); // timeless\n if ((self.config.minDate &&\n dateToCheck &&\n compareDates(dateToCheck, self.config.minDate, timeless !== undefined ? timeless : !self.minDateHasTime) < 0) ||\n (self.config.maxDate &&\n dateToCheck &&\n compareDates(dateToCheck, self.config.maxDate, timeless !== undefined ? timeless : !self.maxDateHasTime) > 0))\n return false;\n if (!self.config.enable && self.config.disable.length === 0)\n return true;\n if (dateToCheck === undefined)\n return false;\n var bool = !!self.config.enable, array = (_a = self.config.enable) !== null && _a !== void 0 ? _a : self.config.disable;\n for (var i = 0, d = void 0; i < array.length; i++) {\n d = array[i];\n if (typeof d === \"function\" &&\n d(dateToCheck) // disabled by function\n )\n return bool;\n else if (d instanceof Date &&\n dateToCheck !== undefined &&\n d.getTime() === dateToCheck.getTime())\n // disabled by date\n return bool;\n else if (typeof d === \"string\") {\n // disabled by date string\n var parsed = self.parseDate(d, undefined, true);\n return parsed && parsed.getTime() === dateToCheck.getTime()\n ? bool\n : !bool;\n }\n else if (\n // disabled by range\n typeof d === \"object\" &&\n dateToCheck !== undefined &&\n d.from &&\n d.to &&\n dateToCheck.getTime() >= d.from.getTime() &&\n dateToCheck.getTime() <= d.to.getTime())\n return bool;\n }\n return !bool;\n }\n function isInView(elem) {\n if (self.daysContainer !== undefined)\n return (elem.className.indexOf(\"hidden\") === -1 &&\n elem.className.indexOf(\"flatpickr-disabled\") === -1 &&\n self.daysContainer.contains(elem));\n return false;\n }\n function onBlur(e) {\n var isInput = e.target === self._input;\n var valueChanged = self._input.value.trimEnd() !== getDateStr();\n if (isInput &&\n valueChanged &&\n !(e.relatedTarget && isCalendarElem(e.relatedTarget))) {\n self.setDate(self._input.value, true, e.target === self.altInput\n ? self.config.altFormat\n : self.config.dateFormat);\n }\n }\n function onKeyDown(e) {\n // e.key e.keyCode\n // \"Backspace\" 8\n // \"Tab\" 9\n // \"Enter\" 13\n // \"Escape\" (IE \"Esc\") 27\n // \"ArrowLeft\" (IE \"Left\") 37\n // \"ArrowUp\" (IE \"Up\") 38\n // \"ArrowRight\" (IE \"Right\") 39\n // \"ArrowDown\" (IE \"Down\") 40\n // \"Delete\" (IE \"Del\") 46\n var eventTarget = getEventTarget(e);\n var isInput = self.config.wrap\n ? element.contains(eventTarget)\n : eventTarget === self._input;\n var allowInput = self.config.allowInput;\n var allowKeydown = self.isOpen && (!allowInput || !isInput);\n var allowInlineKeydown = self.config.inline && isInput && !allowInput;\n if (e.keyCode === 13 && isInput) {\n if (allowInput) {\n self.setDate(self._input.value, true, eventTarget === self.altInput\n ? self.config.altFormat\n : self.config.dateFormat);\n self.close();\n return eventTarget.blur();\n }\n else {\n self.open();\n }\n }\n else if (isCalendarElem(eventTarget) ||\n allowKeydown ||\n allowInlineKeydown) {\n var isTimeObj = !!self.timeContainer &&\n self.timeContainer.contains(eventTarget);\n switch (e.keyCode) {\n case 13:\n if (isTimeObj) {\n e.preventDefault();\n updateTime();\n focusAndClose();\n }\n else\n selectDate(e);\n break;\n case 27: // escape\n e.preventDefault();\n focusAndClose();\n break;\n case 8:\n case 46:\n if (isInput && !self.config.allowInput) {\n e.preventDefault();\n self.clear();\n }\n break;\n case 37:\n case 39:\n if (!isTimeObj && !isInput) {\n e.preventDefault();\n var activeElement = getClosestActiveElement();\n if (self.daysContainer !== undefined &&\n (allowInput === false ||\n (activeElement && isInView(activeElement)))) {\n var delta_1 = e.keyCode === 39 ? 1 : -1;\n if (!e.ctrlKey)\n focusOnDay(undefined, delta_1);\n else {\n e.stopPropagation();\n changeMonth(delta_1);\n focusOnDay(getFirstAvailableDay(1), 0);\n }\n }\n }\n else if (self.hourElement)\n self.hourElement.focus();\n break;\n case 38:\n case 40:\n e.preventDefault();\n var delta = e.keyCode === 40 ? 1 : -1;\n if ((self.daysContainer &&\n eventTarget.$i !== undefined) ||\n eventTarget === self.input ||\n eventTarget === self.altInput) {\n if (e.ctrlKey) {\n e.stopPropagation();\n changeYear(self.currentYear - delta);\n focusOnDay(getFirstAvailableDay(1), 0);\n }\n else if (!isTimeObj)\n focusOnDay(undefined, delta * 7);\n }\n else if (eventTarget === self.currentYearElement) {\n changeYear(self.currentYear - delta);\n }\n else if (self.config.enableTime) {\n if (!isTimeObj && self.hourElement)\n self.hourElement.focus();\n updateTime(e);\n self._debouncedChange();\n }\n break;\n case 9:\n if (isTimeObj) {\n var elems = [\n self.hourElement,\n self.minuteElement,\n self.secondElement,\n self.amPM,\n ]\n .concat(self.pluginElements)\n .filter(function (x) { return x; });\n var i = elems.indexOf(eventTarget);\n if (i !== -1) {\n var target = elems[i + (e.shiftKey ? -1 : 1)];\n e.preventDefault();\n (target || self._input).focus();\n }\n }\n else if (!self.config.noCalendar &&\n self.daysContainer &&\n self.daysContainer.contains(eventTarget) &&\n e.shiftKey) {\n e.preventDefault();\n self._input.focus();\n }\n break;\n }\n }\n if (self.amPM !== undefined && eventTarget === self.amPM) {\n switch (e.key) {\n case self.l10n.amPM[0].charAt(0):\n case self.l10n.amPM[0].charAt(0).toLowerCase():\n self.amPM.textContent = self.l10n.amPM[0];\n setHoursFromInputs();\n updateValue();\n break;\n case self.l10n.amPM[1].charAt(0):\n case self.l10n.amPM[1].charAt(0).toLowerCase():\n self.amPM.textContent = self.l10n.amPM[1];\n setHoursFromInputs();\n updateValue();\n break;\n }\n }\n if (isInput || isCalendarElem(eventTarget)) {\n triggerEvent(\"onKeyDown\", e);\n }\n }\n function onMouseOver(elem, cellClass) {\n if (cellClass === void 0) { cellClass = \"flatpickr-day\"; }\n if (self.selectedDates.length !== 1 ||\n (elem &&\n (!elem.classList.contains(cellClass) ||\n elem.classList.contains(\"flatpickr-disabled\"))))\n return;\n var hoverDate = elem\n ? elem.dateObj.getTime()\n : self.days.firstElementChild.dateObj.getTime(), initialDate = self.parseDate(self.selectedDates[0], undefined, true).getTime(), rangeStartDate = Math.min(hoverDate, self.selectedDates[0].getTime()), rangeEndDate = Math.max(hoverDate, self.selectedDates[0].getTime());\n var containsDisabled = false;\n var minRange = 0, maxRange = 0;\n for (var t = rangeStartDate; t < rangeEndDate; t += duration.DAY) {\n if (!isEnabled(new Date(t), true)) {\n containsDisabled =\n containsDisabled || (t > rangeStartDate && t < rangeEndDate);\n if (t < initialDate && (!minRange || t > minRange))\n minRange = t;\n else if (t > initialDate && (!maxRange || t < maxRange))\n maxRange = t;\n }\n }\n var hoverableCells = Array.from(self.rContainer.querySelectorAll(\"*:nth-child(-n+\" + self.config.showMonths + \") > .\" + cellClass));\n hoverableCells.forEach(function (dayElem) {\n var date = dayElem.dateObj;\n var timestamp = date.getTime();\n var outOfRange = (minRange > 0 && timestamp < minRange) ||\n (maxRange > 0 && timestamp > maxRange);\n if (outOfRange) {\n dayElem.classList.add(\"notAllowed\");\n [\"inRange\", \"startRange\", \"endRange\"].forEach(function (c) {\n dayElem.classList.remove(c);\n });\n return;\n }\n else if (containsDisabled && !outOfRange)\n return;\n [\"startRange\", \"inRange\", \"endRange\", \"notAllowed\"].forEach(function (c) {\n dayElem.classList.remove(c);\n });\n if (elem !== undefined) {\n elem.classList.add(hoverDate <= self.selectedDates[0].getTime()\n ? \"startRange\"\n : \"endRange\");\n if (initialDate < hoverDate && timestamp === initialDate)\n dayElem.classList.add(\"startRange\");\n else if (initialDate > hoverDate && timestamp === initialDate)\n dayElem.classList.add(\"endRange\");\n if (timestamp >= minRange &&\n (maxRange === 0 || timestamp <= maxRange) &&\n isBetween(timestamp, initialDate, hoverDate))\n dayElem.classList.add(\"inRange\");\n }\n });\n }\n function onResize() {\n if (self.isOpen && !self.config.static && !self.config.inline)\n positionCalendar();\n }\n function open(e, positionElement) {\n if (positionElement === void 0) { positionElement = self._positionElement; }\n if (self.isMobile === true) {\n if (e) {\n e.preventDefault();\n var eventTarget = getEventTarget(e);\n if (eventTarget) {\n eventTarget.blur();\n }\n }\n if (self.mobileInput !== undefined) {\n self.mobileInput.focus();\n self.mobileInput.click();\n }\n triggerEvent(\"onOpen\");\n return;\n }\n else if (self._input.disabled || self.config.inline) {\n return;\n }\n var wasOpen = self.isOpen;\n self.isOpen = true;\n if (!wasOpen) {\n self.calendarContainer.classList.add(\"open\");\n self._input.classList.add(\"active\");\n triggerEvent(\"onOpen\");\n positionCalendar(positionElement);\n }\n if (self.config.enableTime === true && self.config.noCalendar === true) {\n if (self.config.allowInput === false &&\n (e === undefined ||\n !self.timeContainer.contains(e.relatedTarget))) {\n setTimeout(function () { return self.hourElement.select(); }, 50);\n }\n }\n }\n function minMaxDateSetter(type) {\n return function (date) {\n var dateObj = (self.config[\"_\" + type + \"Date\"] = self.parseDate(date, self.config.dateFormat));\n var inverseDateObj = self.config[\"_\" + (type === \"min\" ? \"max\" : \"min\") + \"Date\"];\n if (dateObj !== undefined) {\n self[type === \"min\" ? \"minDateHasTime\" : \"maxDateHasTime\"] =\n dateObj.getHours() > 0 ||\n dateObj.getMinutes() > 0 ||\n dateObj.getSeconds() > 0;\n }\n if (self.selectedDates) {\n self.selectedDates = self.selectedDates.filter(function (d) { return isEnabled(d); });\n if (!self.selectedDates.length && type === \"min\")\n setHoursFromDate(dateObj);\n updateValue();\n }\n if (self.daysContainer) {\n redraw();\n if (dateObj !== undefined)\n self.currentYearElement[type] = dateObj.getFullYear().toString();\n else\n self.currentYearElement.removeAttribute(type);\n self.currentYearElement.disabled =\n !!inverseDateObj &&\n dateObj !== undefined &&\n inverseDateObj.getFullYear() === dateObj.getFullYear();\n }\n };\n }\n function parseConfig() {\n var boolOpts = [\n \"wrap\",\n \"weekNumbers\",\n \"allowInput\",\n \"allowInvalidPreload\",\n \"clickOpens\",\n \"time_24hr\",\n \"enableTime\",\n \"noCalendar\",\n \"altInput\",\n \"shorthandCurrentMonth\",\n \"inline\",\n \"static\",\n \"enableSeconds\",\n \"disableMobile\",\n ];\n var userConfig = __assign(__assign({}, JSON.parse(JSON.stringify(element.dataset || {}))), instanceConfig);\n var formats = {};\n self.config.parseDate = userConfig.parseDate;\n self.config.formatDate = userConfig.formatDate;\n Object.defineProperty(self.config, \"enable\", {\n get: function () { return self.config._enable; },\n set: function (dates) {\n self.config._enable = parseDateRules(dates);\n },\n });\n Object.defineProperty(self.config, \"disable\", {\n get: function () { return self.config._disable; },\n set: function (dates) {\n self.config._disable = parseDateRules(dates);\n },\n });\n var timeMode = userConfig.mode === \"time\";\n if (!userConfig.dateFormat && (userConfig.enableTime || timeMode)) {\n var defaultDateFormat = flatpickr.defaultConfig.dateFormat || defaults.dateFormat;\n formats.dateFormat =\n userConfig.noCalendar || timeMode\n ? \"H:i\" + (userConfig.enableSeconds ? \":S\" : \"\")\n : defaultDateFormat + \" H:i\" + (userConfig.enableSeconds ? \":S\" : \"\");\n }\n if (userConfig.altInput &&\n (userConfig.enableTime || timeMode) &&\n !userConfig.altFormat) {\n var defaultAltFormat = flatpickr.defaultConfig.altFormat || defaults.altFormat;\n formats.altFormat =\n userConfig.noCalendar || timeMode\n ? \"h:i\" + (userConfig.enableSeconds ? \":S K\" : \" K\")\n : defaultAltFormat + (\" h:i\" + (userConfig.enableSeconds ? \":S\" : \"\") + \" K\");\n }\n Object.defineProperty(self.config, \"minDate\", {\n get: function () { return self.config._minDate; },\n set: minMaxDateSetter(\"min\"),\n });\n Object.defineProperty(self.config, \"maxDate\", {\n get: function () { return self.config._maxDate; },\n set: minMaxDateSetter(\"max\"),\n });\n var minMaxTimeSetter = function (type) { return function (val) {\n self.config[type === \"min\" ? \"_minTime\" : \"_maxTime\"] = self.parseDate(val, \"H:i:S\");\n }; };\n Object.defineProperty(self.config, \"minTime\", {\n get: function () { return self.config._minTime; },\n set: minMaxTimeSetter(\"min\"),\n });\n Object.defineProperty(self.config, \"maxTime\", {\n get: function () { return self.config._maxTime; },\n set: minMaxTimeSetter(\"max\"),\n });\n if (userConfig.mode === \"time\") {\n self.config.noCalendar = true;\n self.config.enableTime = true;\n }\n Object.assign(self.config, formats, userConfig);\n for (var i = 0; i < boolOpts.length; i++)\n // https://github.com/microsoft/TypeScript/issues/31663\n self.config[boolOpts[i]] =\n self.config[boolOpts[i]] === true ||\n self.config[boolOpts[i]] === \"true\";\n HOOKS.filter(function (hook) { return self.config[hook] !== undefined; }).forEach(function (hook) {\n self.config[hook] = arrayify(self.config[hook] || []).map(bindToInstance);\n });\n self.isMobile =\n !self.config.disableMobile &&\n !self.config.inline &&\n self.config.mode === \"single\" &&\n !self.config.disable.length &&\n !self.config.enable &&\n !self.config.weekNumbers &&\n /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);\n for (var i = 0; i < self.config.plugins.length; i++) {\n var pluginConf = self.config.plugins[i](self) || {};\n for (var key in pluginConf) {\n if (HOOKS.indexOf(key) > -1) {\n self.config[key] = arrayify(pluginConf[key])\n .map(bindToInstance)\n .concat(self.config[key]);\n }\n else if (typeof userConfig[key] === \"undefined\")\n self.config[key] = pluginConf[key];\n }\n }\n if (!userConfig.altInputClass) {\n self.config.altInputClass =\n getInputElem().className + \" \" + self.config.altInputClass;\n }\n triggerEvent(\"onParseConfig\");\n }\n function getInputElem() {\n return self.config.wrap\n ? element.querySelector(\"[data-input]\")\n : element;\n }\n function setupLocale() {\n if (typeof self.config.locale !== \"object\" &&\n typeof flatpickr.l10ns[self.config.locale] === \"undefined\")\n self.config.errorHandler(new Error(\"flatpickr: invalid locale \" + self.config.locale));\n self.l10n = __assign(__assign({}, flatpickr.l10ns.default), (typeof self.config.locale === \"object\"\n ? self.config.locale\n : self.config.locale !== \"default\"\n ? flatpickr.l10ns[self.config.locale]\n : undefined));\n tokenRegex.D = \"(\" + self.l10n.weekdays.shorthand.join(\"|\") + \")\";\n tokenRegex.l = \"(\" + self.l10n.weekdays.longhand.join(\"|\") + \")\";\n tokenRegex.M = \"(\" + self.l10n.months.shorthand.join(\"|\") + \")\";\n tokenRegex.F = \"(\" + self.l10n.months.longhand.join(\"|\") + \")\";\n tokenRegex.K = \"(\" + self.l10n.amPM[0] + \"|\" + self.l10n.amPM[1] + \"|\" + self.l10n.amPM[0].toLowerCase() + \"|\" + self.l10n.amPM[1].toLowerCase() + \")\";\n var userConfig = __assign(__assign({}, instanceConfig), JSON.parse(JSON.stringify(element.dataset || {})));\n if (userConfig.time_24hr === undefined &&\n flatpickr.defaultConfig.time_24hr === undefined) {\n self.config.time_24hr = self.l10n.time_24hr;\n }\n self.formatDate = createDateFormatter(self);\n self.parseDate = createDateParser({ config: self.config, l10n: self.l10n });\n }\n function positionCalendar(customPositionElement) {\n if (typeof self.config.position === \"function\") {\n return void self.config.position(self, customPositionElement);\n }\n if (self.calendarContainer === undefined)\n return;\n triggerEvent(\"onPreCalendarPosition\");\n var positionElement = customPositionElement || self._positionElement;\n var calendarHeight = Array.prototype.reduce.call(self.calendarContainer.children, (function (acc, child) { return acc + child.offsetHeight; }), 0), calendarWidth = self.calendarContainer.offsetWidth, configPos = self.config.position.split(\" \"), configPosVertical = configPos[0], configPosHorizontal = configPos.length > 1 ? configPos[1] : null, inputBounds = positionElement.getBoundingClientRect(), distanceFromBottom = window.innerHeight - inputBounds.bottom, showOnTop = configPosVertical === \"above\" ||\n (configPosVertical !== \"below\" &&\n distanceFromBottom < calendarHeight &&\n inputBounds.top > calendarHeight);\n var top = window.pageYOffset +\n inputBounds.top +\n (!showOnTop ? positionElement.offsetHeight + 2 : -calendarHeight - 2);\n toggleClass(self.calendarContainer, \"arrowTop\", !showOnTop);\n toggleClass(self.calendarContainer, \"arrowBottom\", showOnTop);\n if (self.config.inline)\n return;\n var left = window.pageXOffset + inputBounds.left;\n var isCenter = false;\n var isRight = false;\n if (configPosHorizontal === \"center\") {\n left -= (calendarWidth - inputBounds.width) / 2;\n isCenter = true;\n }\n else if (configPosHorizontal === \"right\") {\n left -= calendarWidth - inputBounds.width;\n isRight = true;\n }\n toggleClass(self.calendarContainer, \"arrowLeft\", !isCenter && !isRight);\n toggleClass(self.calendarContainer, \"arrowCenter\", isCenter);\n toggleClass(self.calendarContainer, \"arrowRight\", isRight);\n var right = window.document.body.offsetWidth -\n (window.pageXOffset + inputBounds.right);\n var rightMost = left + calendarWidth > window.document.body.offsetWidth;\n var centerMost = right + calendarWidth > window.document.body.offsetWidth;\n toggleClass(self.calendarContainer, \"rightMost\", rightMost);\n if (self.config.static)\n return;\n self.calendarContainer.style.top = top + \"px\";\n if (!rightMost) {\n self.calendarContainer.style.left = left + \"px\";\n self.calendarContainer.style.right = \"auto\";\n }\n else if (!centerMost) {\n self.calendarContainer.style.left = \"auto\";\n self.calendarContainer.style.right = right + \"px\";\n }\n else {\n var doc = getDocumentStyleSheet();\n // some testing environments don't have css support\n if (doc === undefined)\n return;\n var bodyWidth = window.document.body.offsetWidth;\n var centerLeft = Math.max(0, bodyWidth / 2 - calendarWidth / 2);\n var centerBefore = \".flatpickr-calendar.centerMost:before\";\n var centerAfter = \".flatpickr-calendar.centerMost:after\";\n var centerIndex = doc.cssRules.length;\n var centerStyle = \"{left:\" + inputBounds.left + \"px;right:auto;}\";\n toggleClass(self.calendarContainer, \"rightMost\", false);\n toggleClass(self.calendarContainer, \"centerMost\", true);\n doc.insertRule(centerBefore + \",\" + centerAfter + centerStyle, centerIndex);\n self.calendarContainer.style.left = centerLeft + \"px\";\n self.calendarContainer.style.right = \"auto\";\n }\n }\n function getDocumentStyleSheet() {\n var editableSheet = null;\n for (var i = 0; i < document.styleSheets.length; i++) {\n var sheet = document.styleSheets[i];\n if (!sheet.cssRules)\n continue;\n try {\n sheet.cssRules;\n }\n catch (err) {\n continue;\n }\n editableSheet = sheet;\n break;\n }\n return editableSheet != null ? editableSheet : createStyleSheet();\n }\n function createStyleSheet() {\n var style = document.createElement(\"style\");\n document.head.appendChild(style);\n return style.sheet;\n }\n function redraw() {\n if (self.config.noCalendar || self.isMobile)\n return;\n buildMonthSwitch();\n updateNavigationCurrentMonth();\n buildDays();\n }\n function focusAndClose() {\n self._input.focus();\n if (window.navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.msMaxTouchPoints !== undefined) {\n // hack - bugs in the way IE handles focus keeps the calendar open\n setTimeout(self.close, 0);\n }\n else {\n self.close();\n }\n }\n function selectDate(e) {\n e.preventDefault();\n e.stopPropagation();\n var isSelectable = function (day) {\n return day.classList &&\n day.classList.contains(\"flatpickr-day\") &&\n !day.classList.contains(\"flatpickr-disabled\") &&\n !day.classList.contains(\"notAllowed\");\n };\n var t = findParent(getEventTarget(e), isSelectable);\n if (t === undefined)\n return;\n var target = t;\n var selectedDate = (self.latestSelectedDateObj = new Date(target.dateObj.getTime()));\n var shouldChangeMonth = (selectedDate.getMonth() < self.currentMonth ||\n selectedDate.getMonth() >\n self.currentMonth + self.config.showMonths - 1) &&\n self.config.mode !== \"range\";\n self.selectedDateElem = target;\n if (self.config.mode === \"single\")\n self.selectedDates = [selectedDate];\n else if (self.config.mode === \"multiple\") {\n var selectedIndex = isDateSelected(selectedDate);\n if (selectedIndex)\n self.selectedDates.splice(parseInt(selectedIndex), 1);\n else\n self.selectedDates.push(selectedDate);\n }\n else if (self.config.mode === \"range\") {\n if (self.selectedDates.length === 2) {\n self.clear(false, false);\n }\n self.latestSelectedDateObj = selectedDate;\n self.selectedDates.push(selectedDate);\n // unless selecting same date twice, sort ascendingly\n if (compareDates(selectedDate, self.selectedDates[0], true) !== 0)\n self.selectedDates.sort(function (a, b) { return a.getTime() - b.getTime(); });\n }\n setHoursFromInputs();\n if (shouldChangeMonth) {\n var isNewYear = self.currentYear !== selectedDate.getFullYear();\n self.currentYear = selectedDate.getFullYear();\n self.currentMonth = selectedDate.getMonth();\n if (isNewYear) {\n triggerEvent(\"onYearChange\");\n buildMonthSwitch();\n }\n triggerEvent(\"onMonthChange\");\n }\n updateNavigationCurrentMonth();\n buildDays();\n updateValue();\n // maintain focus\n if (!shouldChangeMonth &&\n self.config.mode !== \"range\" &&\n self.config.showMonths === 1)\n focusOnDayElem(target);\n else if (self.selectedDateElem !== undefined &&\n self.hourElement === undefined) {\n self.selectedDateElem && self.selectedDateElem.focus();\n }\n if (self.hourElement !== undefined)\n self.hourElement !== undefined && self.hourElement.focus();\n if (self.config.closeOnSelect) {\n var single = self.config.mode === \"single\" && !self.config.enableTime;\n var range = self.config.mode === \"range\" &&\n self.selectedDates.length === 2 &&\n !self.config.enableTime;\n if (single || range) {\n focusAndClose();\n }\n }\n triggerChange();\n }\n var CALLBACKS = {\n locale: [setupLocale, updateWeekdays],\n showMonths: [buildMonths, setCalendarWidth, buildWeekdays],\n minDate: [jumpToDate],\n maxDate: [jumpToDate],\n positionElement: [updatePositionElement],\n clickOpens: [\n function () {\n if (self.config.clickOpens === true) {\n bind(self._input, \"focus\", self.open);\n bind(self._input, \"click\", self.open);\n }\n else {\n self._input.removeEventListener(\"focus\", self.open);\n self._input.removeEventListener(\"click\", self.open);\n }\n },\n ],\n };\n function set(option, value) {\n if (option !== null && typeof option === \"object\") {\n Object.assign(self.config, option);\n for (var key in option) {\n if (CALLBACKS[key] !== undefined)\n CALLBACKS[key].forEach(function (x) { return x(); });\n }\n }\n else {\n self.config[option] = value;\n if (CALLBACKS[option] !== undefined)\n CALLBACKS[option].forEach(function (x) { return x(); });\n else if (HOOKS.indexOf(option) > -1)\n self.config[option] = arrayify(value);\n }\n self.redraw();\n updateValue(true);\n }\n function setSelectedDate(inputDate, format) {\n var dates = [];\n if (inputDate instanceof Array)\n dates = inputDate.map(function (d) { return self.parseDate(d, format); });\n else if (inputDate instanceof Date || typeof inputDate === \"number\")\n dates = [self.parseDate(inputDate, format)];\n else if (typeof inputDate === \"string\") {\n switch (self.config.mode) {\n case \"single\":\n case \"time\":\n dates = [self.parseDate(inputDate, format)];\n break;\n case \"multiple\":\n dates = inputDate\n .split(self.config.conjunction)\n .map(function (date) { return self.parseDate(date, format); });\n break;\n case \"range\":\n dates = inputDate\n .split(self.l10n.rangeSeparator)\n .map(function (date) { return self.parseDate(date, format); });\n break;\n }\n }\n else\n self.config.errorHandler(new Error(\"Invalid date supplied: \" + JSON.stringify(inputDate)));\n self.selectedDates = (self.config.allowInvalidPreload\n ? dates\n : dates.filter(function (d) { return d instanceof Date && isEnabled(d, false); }));\n if (self.config.mode === \"range\")\n self.selectedDates.sort(function (a, b) { return a.getTime() - b.getTime(); });\n }\n function setDate(date, triggerChange, format) {\n if (triggerChange === void 0) { triggerChange = false; }\n if (format === void 0) { format = self.config.dateFormat; }\n if ((date !== 0 && !date) || (date instanceof Array && date.length === 0))\n return self.clear(triggerChange);\n setSelectedDate(date, format);\n self.latestSelectedDateObj =\n self.selectedDates[self.selectedDates.length - 1];\n self.redraw();\n jumpToDate(undefined, triggerChange);\n setHoursFromDate();\n if (self.selectedDates.length === 0) {\n self.clear(false);\n }\n updateValue(triggerChange);\n if (triggerChange)\n triggerEvent(\"onChange\");\n }\n function parseDateRules(arr) {\n return arr\n .slice()\n .map(function (rule) {\n if (typeof rule === \"string\" ||\n typeof rule === \"number\" ||\n rule instanceof Date) {\n return self.parseDate(rule, undefined, true);\n }\n else if (rule &&\n typeof rule === \"object\" &&\n rule.from &&\n rule.to)\n return {\n from: self.parseDate(rule.from, undefined),\n to: self.parseDate(rule.to, undefined),\n };\n return rule;\n })\n .filter(function (x) { return x; }); // remove falsy values\n }\n function setupDates() {\n self.selectedDates = [];\n self.now = self.parseDate(self.config.now) || new Date();\n // Workaround IE11 setting placeholder as the input's value\n var preloadedDate = self.config.defaultDate ||\n ((self.input.nodeName === \"INPUT\" ||\n self.input.nodeName === \"TEXTAREA\") &&\n self.input.placeholder &&\n self.input.value === self.input.placeholder\n ? null\n : self.input.value);\n if (preloadedDate)\n setSelectedDate(preloadedDate, self.config.dateFormat);\n self._initialDate =\n self.selectedDates.length > 0\n ? self.selectedDates[0]\n : self.config.minDate &&\n self.config.minDate.getTime() > self.now.getTime()\n ? self.config.minDate\n : self.config.maxDate &&\n self.config.maxDate.getTime() < self.now.getTime()\n ? self.config.maxDate\n : self.now;\n self.currentYear = self._initialDate.getFullYear();\n self.currentMonth = self._initialDate.getMonth();\n if (self.selectedDates.length > 0)\n self.latestSelectedDateObj = self.selectedDates[0];\n if (self.config.minTime !== undefined)\n self.config.minTime = self.parseDate(self.config.minTime, \"H:i\");\n if (self.config.maxTime !== undefined)\n self.config.maxTime = self.parseDate(self.config.maxTime, \"H:i\");\n self.minDateHasTime =\n !!self.config.minDate &&\n (self.config.minDate.getHours() > 0 ||\n self.config.minDate.getMinutes() > 0 ||\n self.config.minDate.getSeconds() > 0);\n self.maxDateHasTime =\n !!self.config.maxDate &&\n (self.config.maxDate.getHours() > 0 ||\n self.config.maxDate.getMinutes() > 0 ||\n self.config.maxDate.getSeconds() > 0);\n }\n function setupInputs() {\n self.input = getInputElem();\n /* istanbul ignore next */\n if (!self.input) {\n self.config.errorHandler(new Error(\"Invalid input element specified\"));\n return;\n }\n // hack: store previous type to restore it after destroy()\n self.input._type = self.input.type;\n self.input.type = \"text\";\n self.input.classList.add(\"flatpickr-input\");\n self._input = self.input;\n if (self.config.altInput) {\n // replicate self.element\n self.altInput = createElement(self.input.nodeName, self.config.altInputClass);\n self._input = self.altInput;\n self.altInput.placeholder = self.input.placeholder;\n self.altInput.disabled = self.input.disabled;\n self.altInput.required = self.input.required;\n self.altInput.tabIndex = self.input.tabIndex;\n self.altInput.type = \"text\";\n self.input.setAttribute(\"type\", \"hidden\");\n if (!self.config.static && self.input.parentNode)\n self.input.parentNode.insertBefore(self.altInput, self.input.nextSibling);\n }\n if (!self.config.allowInput)\n self._input.setAttribute(\"readonly\", \"readonly\");\n updatePositionElement();\n }\n function updatePositionElement() {\n self._positionElement = self.config.positionElement || self._input;\n }\n function setupMobile() {\n var inputType = self.config.enableTime\n ? self.config.noCalendar\n ? \"time\"\n : \"datetime-local\"\n : \"date\";\n self.mobileInput = createElement(\"input\", self.input.className + \" flatpickr-mobile\");\n self.mobileInput.tabIndex = 1;\n self.mobileInput.type = inputType;\n self.mobileInput.disabled = self.input.disabled;\n self.mobileInput.required = self.input.required;\n self.mobileInput.placeholder = self.input.placeholder;\n self.mobileFormatStr =\n inputType === \"datetime-local\"\n ? \"Y-m-d\\\\TH:i:S\"\n : inputType === \"date\"\n ? \"Y-m-d\"\n : \"H:i:S\";\n if (self.selectedDates.length > 0) {\n self.mobileInput.defaultValue = self.mobileInput.value = self.formatDate(self.selectedDates[0], self.mobileFormatStr);\n }\n if (self.config.minDate)\n self.mobileInput.min = self.formatDate(self.config.minDate, \"Y-m-d\");\n if (self.config.maxDate)\n self.mobileInput.max = self.formatDate(self.config.maxDate, \"Y-m-d\");\n if (self.input.getAttribute(\"step\"))\n self.mobileInput.step = String(self.input.getAttribute(\"step\"));\n self.input.type = \"hidden\";\n if (self.altInput !== undefined)\n self.altInput.type = \"hidden\";\n try {\n if (self.input.parentNode)\n self.input.parentNode.insertBefore(self.mobileInput, self.input.nextSibling);\n }\n catch (_a) { }\n bind(self.mobileInput, \"change\", function (e) {\n self.setDate(getEventTarget(e).value, false, self.mobileFormatStr);\n triggerEvent(\"onChange\");\n triggerEvent(\"onClose\");\n });\n }\n function toggle(e) {\n if (self.isOpen === true)\n return self.close();\n self.open(e);\n }\n function triggerEvent(event, data) {\n // If the instance has been destroyed already, all hooks have been removed\n if (self.config === undefined)\n return;\n var hooks = self.config[event];\n if (hooks !== undefined && hooks.length > 0) {\n for (var i = 0; hooks[i] && i < hooks.length; i++)\n hooks[i](self.selectedDates, self.input.value, self, data);\n }\n if (event === \"onChange\") {\n self.input.dispatchEvent(createEvent(\"change\"));\n // many front-end frameworks bind to the input event\n self.input.dispatchEvent(createEvent(\"input\"));\n }\n }\n function createEvent(name) {\n var e = document.createEvent(\"Event\");\n e.initEvent(name, true, true);\n return e;\n }\n function isDateSelected(date) {\n for (var i = 0; i < self.selectedDates.length; i++) {\n var selectedDate = self.selectedDates[i];\n if (selectedDate instanceof Date &&\n compareDates(selectedDate, date) === 0)\n return \"\" + i;\n }\n return false;\n }\n function isDateInRange(date) {\n if (self.config.mode !== \"range\" || self.selectedDates.length < 2)\n return false;\n return (compareDates(date, self.selectedDates[0]) >= 0 &&\n compareDates(date, self.selectedDates[1]) <= 0);\n }\n function updateNavigationCurrentMonth() {\n if (self.config.noCalendar || self.isMobile || !self.monthNav)\n return;\n self.yearElements.forEach(function (yearElement, i) {\n var d = new Date(self.currentYear, self.currentMonth, 1);\n d.setMonth(self.currentMonth + i);\n if (self.config.showMonths > 1 ||\n self.config.monthSelectorType === \"static\") {\n self.monthElements[i].textContent =\n monthToStr(d.getMonth(), self.config.shorthandCurrentMonth, self.l10n) + \" \";\n }\n else {\n self.monthsDropdownContainer.value = d.getMonth().toString();\n }\n yearElement.value = d.getFullYear().toString();\n });\n self._hidePrevMonthArrow =\n self.config.minDate !== undefined &&\n (self.currentYear === self.config.minDate.getFullYear()\n ? self.currentMonth <= self.config.minDate.getMonth()\n : self.currentYear < self.config.minDate.getFullYear());\n self._hideNextMonthArrow =\n self.config.maxDate !== undefined &&\n (self.currentYear === self.config.maxDate.getFullYear()\n ? self.currentMonth + 1 > self.config.maxDate.getMonth()\n : self.currentYear > self.config.maxDate.getFullYear());\n }\n function getDateStr(specificFormat) {\n var format = specificFormat ||\n (self.config.altInput ? self.config.altFormat : self.config.dateFormat);\n return self.selectedDates\n .map(function (dObj) { return self.formatDate(dObj, format); })\n .filter(function (d, i, arr) {\n return self.config.mode !== \"range\" ||\n self.config.enableTime ||\n arr.indexOf(d) === i;\n })\n .join(self.config.mode !== \"range\"\n ? self.config.conjunction\n : self.l10n.rangeSeparator);\n }\n /**\n * Updates the values of inputs associated with the calendar\n */\n function updateValue(triggerChange) {\n if (triggerChange === void 0) { triggerChange = true; }\n if (self.mobileInput !== undefined && self.mobileFormatStr) {\n self.mobileInput.value =\n self.latestSelectedDateObj !== undefined\n ? self.formatDate(self.latestSelectedDateObj, self.mobileFormatStr)\n : \"\";\n }\n self.input.value = getDateStr(self.config.dateFormat);\n if (self.altInput !== undefined) {\n self.altInput.value = getDateStr(self.config.altFormat);\n }\n if (triggerChange !== false)\n triggerEvent(\"onValueUpdate\");\n }\n function onMonthNavClick(e) {\n var eventTarget = getEventTarget(e);\n var isPrevMonth = self.prevMonthNav.contains(eventTarget);\n var isNextMonth = self.nextMonthNav.contains(eventTarget);\n if (isPrevMonth || isNextMonth) {\n changeMonth(isPrevMonth ? -1 : 1);\n }\n else if (self.yearElements.indexOf(eventTarget) >= 0) {\n eventTarget.select();\n }\n else if (eventTarget.classList.contains(\"arrowUp\")) {\n self.changeYear(self.currentYear + 1);\n }\n else if (eventTarget.classList.contains(\"arrowDown\")) {\n self.changeYear(self.currentYear - 1);\n }\n }\n function timeWrapper(e) {\n e.preventDefault();\n var isKeyDown = e.type === \"keydown\", eventTarget = getEventTarget(e), input = eventTarget;\n if (self.amPM !== undefined && eventTarget === self.amPM) {\n self.amPM.textContent =\n self.l10n.amPM[int(self.amPM.textContent === self.l10n.amPM[0])];\n }\n var min = parseFloat(input.getAttribute(\"min\")), max = parseFloat(input.getAttribute(\"max\")), step = parseFloat(input.getAttribute(\"step\")), curValue = parseInt(input.value, 10), delta = e.delta ||\n (isKeyDown ? (e.which === 38 ? 1 : -1) : 0);\n var newValue = curValue + step * delta;\n if (typeof input.value !== \"undefined\" && input.value.length === 2) {\n var isHourElem = input === self.hourElement, isMinuteElem = input === self.minuteElement;\n if (newValue < min) {\n newValue =\n max +\n newValue +\n int(!isHourElem) +\n (int(isHourElem) && int(!self.amPM));\n if (isMinuteElem)\n incrementNumInput(undefined, -1, self.hourElement);\n }\n else if (newValue > max) {\n newValue =\n input === self.hourElement ? newValue - max - int(!self.amPM) : min;\n if (isMinuteElem)\n incrementNumInput(undefined, 1, self.hourElement);\n }\n if (self.amPM &&\n isHourElem &&\n (step === 1\n ? newValue + curValue === 23\n : Math.abs(newValue - curValue) > step)) {\n self.amPM.textContent =\n self.l10n.amPM[int(self.amPM.textContent === self.l10n.amPM[0])];\n }\n input.value = pad(newValue);\n }\n }\n init();\n return self;\n }\n /* istanbul ignore next */\n function _flatpickr(nodeList, config) {\n // static list\n var nodes = Array.prototype.slice\n .call(nodeList)\n .filter(function (x) { return x instanceof HTMLElement; });\n var instances = [];\n for (var i = 0; i < nodes.length; i++) {\n var node = nodes[i];\n try {\n if (node.getAttribute(\"data-fp-omit\") !== null)\n continue;\n if (node._flatpickr !== undefined) {\n node._flatpickr.destroy();\n node._flatpickr = undefined;\n }\n node._flatpickr = FlatpickrInstance(node, config || {});\n instances.push(node._flatpickr);\n }\n catch (e) {\n console.error(e);\n }\n }\n return instances.length === 1 ? instances[0] : instances;\n }\n /* istanbul ignore next */\n if (typeof HTMLElement !== \"undefined\" &&\n typeof HTMLCollection !== \"undefined\" &&\n typeof NodeList !== \"undefined\") {\n // browser env\n HTMLCollection.prototype.flatpickr = NodeList.prototype.flatpickr = function (config) {\n return _flatpickr(this, config);\n };\n HTMLElement.prototype.flatpickr = function (config) {\n return _flatpickr([this], config);\n };\n }\n /* istanbul ignore next */\n var flatpickr = function (selector, config) {\n if (typeof selector === \"string\") {\n return _flatpickr(window.document.querySelectorAll(selector), config);\n }\n else if (selector instanceof Node) {\n return _flatpickr([selector], config);\n }\n else {\n return _flatpickr(selector, config);\n }\n };\n /* istanbul ignore next */\n flatpickr.defaultConfig = {};\n flatpickr.l10ns = {\n en: __assign({}, english),\n default: __assign({}, english),\n };\n flatpickr.localize = function (l10n) {\n flatpickr.l10ns.default = __assign(__assign({}, flatpickr.l10ns.default), l10n);\n };\n flatpickr.setDefaults = function (config) {\n flatpickr.defaultConfig = __assign(__assign({}, flatpickr.defaultConfig), config);\n };\n flatpickr.parseDate = createDateParser({});\n flatpickr.formatDate = createDateFormatter({});\n flatpickr.compareDates = compareDates;\n /* istanbul ignore next */\n if (typeof jQuery !== \"undefined\" && typeof jQuery.fn !== \"undefined\") {\n jQuery.fn.flatpickr = function (config) {\n return _flatpickr(this, config);\n };\n }\n Date.prototype.fp_incr = function (days) {\n return new Date(this.getFullYear(), this.getMonth(), this.getDate() + (typeof days === \"string\" ? parseInt(days, 10) : days));\n };\n if (typeof window !== \"undefined\") {\n window.flatpickr = flatpickr;\n }\n\n return flatpickr;\n\n})));\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvZmxhdHBpY2tyL2Rpc3QvZmxhdHBpY2tyLmpzLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQSxJQUFJLEtBQTREO0FBQ2hFLElBQUksQ0FDd0c7QUFDNUcsQ0FBQyxzQkFBc0I7O0FBRXZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxREFBcUQsT0FBTztBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzREFBc0QsUUFBUTtBQUM5RCw2Q0FBNkMsUUFBUTtBQUNyRCw2REFBNkQsUUFBUTtBQUNyRTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlEQUFpRCxJQUFJO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlEQUFpRCxJQUFJO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQWlEO0FBQ2pELHdDQUF3QztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELElBQUk7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1QztBQUN2Qyx5RUFBeUU7QUFDekU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDLGtCQUFrQjtBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1REFBdUQsV0FBVztBQUNsRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUNBQXlDLGtCQUFrQjtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4REFBOEQsbUNBQW1DO0FBQ2pHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4REFBOEQsYUFBYTtBQUMzRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkRBQTZELGFBQWE7QUFDMUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscURBQXFELG1DQUFtQztBQUN4RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbURBQW1ELHNDQUFzQztBQUN6RjtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1EQUFtRCxzQ0FBc0M7QUFDekY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4Q0FBOEMsa0RBQWtEO0FBQ2hHO0FBQ0EsMERBQTBELG1DQUFtQztBQUM3RjtBQUNBO0FBQ0EsNENBQTRDO0FBQzVDLHFDQUFxQztBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsdUNBQXVDLFdBQVcsR0FBRztBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDhCQUE4QjtBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLCtCQUErQjtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUMsdUNBQXVDO0FBQzlFO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0Q0FBNEM7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsa0NBQWtDO0FBQ3JFO0FBQ0Esd0JBQXdCLGtCQUFrQjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0VBQXNFO0FBQ3RFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkIsNEJBQTRCO0FBQzVCO0FBQ0E7QUFDQSxzREFBc0Q7QUFDdEQ7QUFDQTtBQUNBLHNEQUFzRDtBQUN0RDtBQUNBLDZDQUE2QztBQUM3QyxpREFBaUQ7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovL1Z1ZXh5Ly4vbm9kZV9tb2R1bGVzL2ZsYXRwaWNrci9kaXN0L2ZsYXRwaWNrci5qcz9jZjA2Il0sInNvdXJjZXNDb250ZW50IjpbIi8qIGZsYXRwaWNrciB2NC42LjEzLCBAbGljZW5zZSBNSVQgKi9cbihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG4gICAgdHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCkgOlxuICAgIHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShmYWN0b3J5KSA6XG4gICAgKGdsb2JhbCA9IHR5cGVvZiBnbG9iYWxUaGlzICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbFRoaXMgOiBnbG9iYWwgfHwgc2VsZiwgZ2xvYmFsLmZsYXRwaWNrciA9IGZhY3RvcnkoKSk7XG59KHRoaXMsIChmdW5jdGlvbiAoKSB7ICd1c2Ugc3RyaWN0JztcblxuICAgIC8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG4gICAgQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uXHJcblxyXG4gICAgUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbiAgICBwdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG4gICAgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxyXG4gICAgUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbiAgICBBTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbiAgICBJTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cclxuICAgIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbiAgICBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcbiAgICBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxyXG4gICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuXHJcbiAgICB2YXIgX19hc3NpZ24gPSBmdW5jdGlvbigpIHtcclxuICAgICAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiB0O1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgcmV0dXJuIF9fYXNzaWduLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbiAgICB9O1xyXG5cclxuICAgIGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXlzKCkge1xyXG4gICAgICAgIGZvciAodmFyIHMgPSAwLCBpID0gMCwgaWwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgaWw7IGkrKykgcyArPSBhcmd1bWVudHNbaV0ubGVuZ3RoO1xyXG4gICAgICAgIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcclxuICAgICAgICAgICAgZm9yICh2YXIgYSA9IGFyZ3VtZW50c1tpXSwgaiA9IDAsIGpsID0gYS5sZW5ndGg7IGogPCBqbDsgaisrLCBrKyspXHJcbiAgICAgICAgICAgICAgICByW2tdID0gYVtqXTtcclxuICAgICAgICByZXR1cm4gcjtcclxuICAgIH1cblxuICAgIHZhciBIT09LUyA9IFtcbiAgICAgICAgXCJvbkNoYW5nZVwiLFxuICAgICAgICBcIm9uQ2xvc2VcIixcbiAgICAgICAgXCJvbkRheUNyZWF0ZVwiLFxuICAgICAgICBcIm9uRGVzdHJveVwiLFxuICAgICAgICBcIm9uS2V5RG93blwiLFxuICAgICAgICBcIm9uTW9udGhDaGFuZ2VcIixcbiAgICAgICAgXCJvbk9wZW5cIixcbiAgICAgICAgXCJvblBhcnNlQ29uZmlnXCIsXG4gICAgICAgIFwib25SZWFkeVwiLFxuICAgICAgICBcIm9uVmFsdWVVcGRhdGVcIixcbiAgICAgICAgXCJvblllYXJDaGFuZ2VcIixcbiAgICAgICAgXCJvblByZUNhbGVuZGFyUG9zaXRpb25cIixcbiAgICBdO1xuICAgIHZhciBkZWZhdWx0cyA9IHtcbiAgICAgICAgX2Rpc2FibGU6IFtdLFxuICAgICAgICBhbGxvd0lucHV0OiBmYWxzZSxcbiAgICAgICAgYWxsb3dJbnZhbGlkUHJlbG9hZDogZmFsc2UsXG4gICAgICAgIGFsdEZvcm1hdDogXCJGIGosIFlcIixcbiAgICAgICAgYWx0SW5wdXQ6IGZhbHNlLFxuICAgICAgICBhbHRJbnB1dENsYXNzOiBcImZvcm0tY29udHJvbCBpbnB1dFwiLFxuICAgICAgICBhbmltYXRlOiB0eXBlb2Ygd2luZG93ID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgICAgICB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKFwiTVNJRVwiKSA9PT0gLTEsXG4gICAgICAgIGFyaWFEYXRlRm9ybWF0OiBcIkYgaiwgWVwiLFxuICAgICAgICBhdXRvRmlsbERlZmF1bHRUaW1lOiB0cnVlLFxuICAgICAgICBjbGlja09wZW5zOiB0cnVlLFxuICAgICAgICBjbG9zZU9uU2VsZWN0OiB0cnVlLFxuICAgICAgICBjb25qdW5jdGlvbjogXCIsIFwiLFxuICAgICAgICBkYXRlRm9ybWF0OiBcIlktbS1kXCIsXG4gICAgICAgIGRlZmF1bHRIb3VyOiAxMixcbiAgICAgICAgZGVmYXVsdE1pbnV0ZTogMCxcbiAgICAgICAgZGVmYXVsdFNlY29uZHM6IDAsXG4gICAgICAgIGRpc2FibGU6IFtdLFxuICAgICAgICBkaXNhYmxlTW9iaWxlOiBmYWxzZSxcbiAgICAgICAgZW5hYmxlU2Vjb25kczogZmFsc2UsXG4gICAgICAgIGVuYWJsZVRpbWU6IGZhbHNlLFxuICAgICAgICBlcnJvckhhbmRsZXI6IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgY29uc29sZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBjb25zb2xlLndhcm4oZXJyKTtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0V2VlazogZnVuY3Rpb24gKGdpdmVuRGF0ZSkge1xuICAgICAgICAgICAgdmFyIGRhdGUgPSBuZXcgRGF0ZShnaXZlbkRhdGUuZ2V0VGltZSgpKTtcbiAgICAgICAgICAgIGRhdGUuc2V0SG91cnMoMCwgMCwgMCwgMCk7XG4gICAgICAgICAgICAvLyBUaHVyc2RheSBpbiBjdXJyZW50IHdlZWsgZGVjaWRlcyB0aGUgeWVhci5cbiAgICAgICAgICAgIGRhdGUuc2V0RGF0ZShkYXRlLmdldERhdGUoKSArIDMgLSAoKGRhdGUuZ2V0RGF5KCkgKyA2KSAlIDcpKTtcbiAgICAgICAgICAgIC8vIEphbnVhcnkgNCBpcyBhbHdheXMgaW4gd2VlayAxLlxuICAgICAgICAgICAgdmFyIHdlZWsxID0gbmV3IERhdGUoZGF0ZS5nZXRGdWxsWWVhcigpLCAwLCA0KTtcbiAgICAgICAgICAgIC8vIEFkanVzdCB0byBUaHVyc2RheSBpbiB3ZWVrIDEgYW5kIGNvdW50IG51bWJlciBvZiB3ZWVrcyBmcm9tIGRhdGUgdG8gd2VlazEuXG4gICAgICAgICAgICByZXR1cm4gKDEgK1xuICAgICAgICAgICAgICAgIE1hdGgucm91bmQoKChkYXRlLmdldFRpbWUoKSAtIHdlZWsxLmdldFRpbWUoKSkgLyA4NjQwMDAwMCAtXG4gICAgICAgICAgICAgICAgICAgIDMgK1xuICAgICAgICAgICAgICAgICAgICAoKHdlZWsxLmdldERheSgpICsgNikgJSA3KSkgL1xuICAgICAgICAgICAgICAgICAgICA3KSk7XG4gICAgICAgIH0sXG4gICAgICAgIGhvdXJJbmNyZW1lbnQ6IDEsXG4gICAgICAgIGlnbm9yZWRGb2N1c0VsZW1lbnRzOiBbXSxcbiAgICAgICAgaW5saW5lOiBmYWxzZSxcbiAgICAgICAgbG9jYWxlOiBcImRlZmF1bHRcIixcbiAgICAgICAgbWludXRlSW5jcmVtZW50OiA1LFxuICAgICAgICBtb2RlOiBcInNpbmdsZVwiLFxuICAgICAgICBtb250aFNlbGVjdG9yVHlwZTogXCJkcm9wZG93blwiLFxuICAgICAgICBuZXh0QXJyb3c6IFwiPHN2ZyB2ZXJzaW9uPScxLjEnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycgeG1sbnM6eGxpbms9J2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnIHZpZXdCb3g9JzAgMCAxNyAxNyc+PGc+PC9nPjxwYXRoIGQ9J00xMy4yMDcgOC40NzJsLTcuODU0IDcuODU0LTAuNzA3LTAuNzA3IDcuMTQ2LTcuMTQ2LTcuMTQ2LTcuMTQ4IDAuNzA3LTAuNzA3IDcuODU0IDcuODU0eicgLz48L3N2Zz5cIixcbiAgICAgICAgbm9DYWxlbmRhcjogZmFsc2UsXG4gICAgICAgIG5vdzogbmV3IERhdGUoKSxcbiAgICAgICAgb25DaGFuZ2U6IFtdLFxuICAgICAgICBvbkNsb3NlOiBbXSxcbiAgICAgICAgb25EYXlDcmVhdGU6IFtdLFxuICAgICAgICBvbkRlc3Ryb3k6IFtdLFxuICAgICAgICBvbktleURvd246IFtdLFxuICAgICAgICBvbk1vbnRoQ2hhbmdlOiBbXSxcbiAgICAgICAgb25PcGVuOiBbXSxcbiAgICAgICAgb25QYXJzZUNvbmZpZzogW10sXG4gICAgICAgIG9uUmVhZHk6IFtdLFxuICAgICAgICBvblZhbHVlVXBkYXRlOiBbXSxcbiAgICAgICAgb25ZZWFyQ2hhbmdlOiBbXSxcbiAgICAgICAgb25QcmVDYWxlbmRhclBvc2l0aW9uOiBbXSxcbiAgICAgICAgcGx1Z2luczogW10sXG4gICAgICAgIHBvc2l0aW9uOiBcImF1dG9cIixcbiAgICAgICAgcG9zaXRpb25FbGVtZW50OiB1bmRlZmluZWQsXG4gICAgICAgIHByZXZBcnJvdzogXCI8c3ZnIHZlcnNpb249JzEuMScgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyB4bWxuczp4bGluaz0naHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluaycgdmlld0JveD0nMCAwIDE3IDE3Jz48Zz48L2c+PHBhdGggZD0nTTUuMjA3IDguNDcxbDcuMTQ2IDcuMTQ3LTAuNzA3IDAuNzA3LTcuODUzLTcuODU0IDcuODU0LTcuODUzIDAuNzA3IDAuNzA3LTcuMTQ3IDcuMTQ2eicgLz48L3N2Zz5cIixcbiAgICAgICAgc2hvcnRoYW5kQ3VycmVudE1vbnRoOiBmYWxzZSxcbiAgICAgICAgc2hvd01vbnRoczogMSxcbiAgICAgICAgc3RhdGljOiBmYWxzZSxcbiAgICAgICAgdGltZV8yNGhyOiBmYWxzZSxcbiAgICAgICAgd2Vla051bWJlcnM6IGZhbHNlLFxuICAgICAgICB3cmFwOiBmYWxzZSxcbiAgICB9O1xuXG4gICAgdmFyIGVuZ2xpc2ggPSB7XG4gICAgICAgIHdlZWtkYXlzOiB7XG4gICAgICAgICAgICBzaG9ydGhhbmQ6IFtcIlN1blwiLCBcIk1vblwiLCBcIlR1ZVwiLCBcIldlZFwiLCBcIlRodVwiLCBcIkZyaVwiLCBcIlNhdFwiXSxcbiAgICAgICAgICAgIGxvbmdoYW5kOiBbXG4gICAgICAgICAgICAgICAgXCJTdW5kYXlcIixcbiAgICAgICAgICAgICAgICBcIk1vbmRheVwiLFxuICAgICAgICAgICAgICAgIFwiVHVlc2RheVwiLFxuICAgICAgICAgICAgICAgIFwiV2VkbmVzZGF5XCIsXG4gICAgICAgICAgICAgICAgXCJUaHVyc2RheVwiLFxuICAgICAgICAgICAgICAgIFwiRnJpZGF5XCIsXG4gICAgICAgICAgICAgICAgXCJTYXR1cmRheVwiLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbW9udGhzOiB7XG4gICAgICAgICAgICBzaG9ydGhhbmQ6IFtcbiAgICAgICAgICAgICAgICBcIkphblwiLFxuICAgICAgICAgICAgICAgIFwiRmViXCIsXG4gICAgICAgICAgICAgICAgXCJNYXJcIixcbiAgICAgICAgICAgICAgICBcIkFwclwiLFxuICAgICAgICAgICAgICAgIFwiTWF5XCIsXG4gICAgICAgICAgICAgICAgXCJKdW5cIixcbiAgICAgICAgICAgICAgICBcIkp1bFwiLFxuICAgICAgICAgICAgICAgIFwiQXVnXCIsXG4gICAgICAgICAgICAgICAgXCJTZXBcIixcbiAgICAgICAgICAgICAgICBcIk9jdFwiLFxuICAgICAgICAgICAgICAgIFwiTm92XCIsXG4gICAgICAgICAgICAgICAgXCJEZWNcIixcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBsb25naGFuZDogW1xuICAgICAgICAgICAgICAgIFwiSmFudWFyeVwiLFxuICAgICAgICAgICAgICAgIFwiRmVicnVhcnlcIixcbiAgICAgICAgICAgICAgICBcIk1hcmNoXCIsXG4gICAgICAgICAgICAgICAgXCJBcHJpbFwiLFxuICAgICAgICAgICAgICAgIFwiTWF5XCIsXG4gICAgICAgICAgICAgICAgXCJKdW5lXCIsXG4gICAgICAgICAgICAgICAgXCJKdWx5XCIsXG4gICAgICAgICAgICAgICAgXCJBdWd1c3RcIixcbiAgICAgICAgICAgICAgICBcIlNlcHRlbWJlclwiLFxuICAgICAgICAgICAgICAgIFwiT2N0b2JlclwiLFxuICAgICAgICAgICAgICAgIFwiTm92ZW1iZXJcIixcbiAgICAgICAgICAgICAgICBcIkRlY2VtYmVyXCIsXG4gICAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBkYXlzSW5Nb250aDogWzMxLCAyOCwgMzEsIDMwLCAzMSwgMzAsIDMxLCAzMSwgMzAsIDMxLCAzMCwgMzFdLFxuICAgICAgICBmaXJzdERheU9mV2VlazogMCxcbiAgICAgICAgb3JkaW5hbDogZnVuY3Rpb24gKG50aCkge1xuICAgICAgICAgICAgdmFyIHMgPSBudGggJSAxMDA7XG4gICAgICAgICAgICBpZiAocyA+IDMgJiYgcyA8IDIxKVxuICAgICAgICAgICAgICAgIHJldHVybiBcInRoXCI7XG4gICAgICAgICAgICBzd2l0Y2ggKHMgJSAxMCkge1xuICAgICAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwic3RcIjtcbiAgICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm5kXCI7XG4gICAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJyZFwiO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInRoXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHJhbmdlU2VwYXJhdG9yOiBcIiB0byBcIixcbiAgICAgICAgd2Vla0FiYnJldmlhdGlvbjogXCJXa1wiLFxuICAgICAgICBzY3JvbGxUaXRsZTogXCJTY3JvbGwgdG8gaW5jcmVtZW50XCIsXG4gICAgICAgIHRvZ2dsZVRpdGxlOiBcIkNsaWNrIHRvIHRvZ2dsZVwiLFxuICAgICAgICBhbVBNOiBbXCJBTVwiLCBcIlBNXCJdLFxuICAgICAgICB5ZWFyQXJpYUxhYmVsOiBcIlllYXJcIixcbiAgICAgICAgbW9udGhBcmlhTGFiZWw6IFwiTW9udGhcIixcbiAgICAgICAgaG91ckFyaWFMYWJlbDogXCJIb3VyXCIsXG4gICAgICAgIG1pbnV0ZUFyaWFMYWJlbDogXCJNaW51dGVcIixcbiAgICAgICAgdGltZV8yNGhyOiBmYWxzZSxcbiAgICB9O1xuXG4gICAgdmFyIHBhZCA9IGZ1bmN0aW9uIChudW1iZXIsIGxlbmd0aCkge1xuICAgICAgICBpZiAobGVuZ3RoID09PSB2b2lkIDApIHsgbGVuZ3RoID0gMjsgfVxuICAgICAgICByZXR1cm4gKFwiMDAwXCIgKyBudW1iZXIpLnNsaWNlKGxlbmd0aCAqIC0xKTtcbiAgICB9O1xuICAgIHZhciBpbnQgPSBmdW5jdGlvbiAoYm9vbCkgeyByZXR1cm4gKGJvb2wgPT09IHRydWUgPyAxIDogMCk7IH07XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBmdW5jdGlvbiBkZWJvdW5jZShmbiwgd2FpdCkge1xuICAgICAgICB2YXIgdDtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0KTtcbiAgICAgICAgICAgIHQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsgcmV0dXJuIGZuLmFwcGx5KF90aGlzLCBhcmdzKTsgfSwgd2FpdCk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIHZhciBhcnJheWlmeSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgcmV0dXJuIG9iaiBpbnN0YW5jZW9mIEFycmF5ID8gb2JqIDogW29ial07XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIHRvZ2dsZUNsYXNzKGVsZW0sIGNsYXNzTmFtZSwgYm9vbCkge1xuICAgICAgICBpZiAoYm9vbCA9PT0gdHJ1ZSlcbiAgICAgICAgICAgIHJldHVybiBlbGVtLmNsYXNzTGlzdC5hZGQoY2xhc3NOYW1lKTtcbiAgICAgICAgZWxlbS5jbGFzc0xpc3QucmVtb3ZlKGNsYXNzTmFtZSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnQodGFnLCBjbGFzc05hbWUsIGNvbnRlbnQpIHtcbiAgICAgICAgdmFyIGUgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWcpO1xuICAgICAgICBjbGFzc05hbWUgPSBjbGFzc05hbWUgfHwgXCJcIjtcbiAgICAgICAgY29udGVudCA9IGNvbnRlbnQgfHwgXCJcIjtcbiAgICAgICAgZS5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gICAgICAgIGlmIChjb250ZW50ICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgICBlLnRleHRDb250ZW50ID0gY29udGVudDtcbiAgICAgICAgcmV0dXJuIGU7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGNsZWFyTm9kZShub2RlKSB7XG4gICAgICAgIHdoaWxlIChub2RlLmZpcnN0Q2hpbGQpXG4gICAgICAgICAgICBub2RlLnJlbW92ZUNoaWxkKG5vZGUuZmlyc3RDaGlsZCk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGZpbmRQYXJlbnQobm9kZSwgY29uZGl0aW9uKSB7XG4gICAgICAgIGlmIChjb25kaXRpb24obm9kZSkpXG4gICAgICAgICAgICByZXR1cm4gbm9kZTtcbiAgICAgICAgZWxzZSBpZiAobm9kZS5wYXJlbnROb2RlKVxuICAgICAgICAgICAgcmV0dXJuIGZpbmRQYXJlbnQobm9kZS5wYXJlbnROb2RlLCBjb25kaXRpb24pO1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkOyAvLyBub3RoaW5nIGZvdW5kXG4gICAgfVxuICAgIGZ1bmN0aW9uIGNyZWF0ZU51bWJlcklucHV0KGlucHV0Q2xhc3NOYW1lLCBvcHRzKSB7XG4gICAgICAgIHZhciB3cmFwcGVyID0gY3JlYXRlRWxlbWVudChcImRpdlwiLCBcIm51bUlucHV0V3JhcHBlclwiKSwgbnVtSW5wdXQgPSBjcmVhdGVFbGVtZW50KFwiaW5wdXRcIiwgXCJudW1JbnB1dCBcIiArIGlucHV0Q2xhc3NOYW1lKSwgYXJyb3dVcCA9IGNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIsIFwiYXJyb3dVcFwiKSwgYXJyb3dEb3duID0gY3JlYXRlRWxlbWVudChcInNwYW5cIiwgXCJhcnJvd0Rvd25cIik7XG4gICAgICAgIGlmIChuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoXCJNU0lFIDkuMFwiKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIG51bUlucHV0LnR5cGUgPSBcIm51bWJlclwiO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbnVtSW5wdXQudHlwZSA9IFwidGV4dFwiO1xuICAgICAgICAgICAgbnVtSW5wdXQucGF0dGVybiA9IFwiXFxcXGQqXCI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdHMgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICAgIGZvciAodmFyIGtleSBpbiBvcHRzKVxuICAgICAgICAgICAgICAgIG51bUlucHV0LnNldEF0dHJpYnV0ZShrZXksIG9wdHNba2V5XSk7XG4gICAgICAgIHdyYXBwZXIuYXBwZW5kQ2hpbGQobnVtSW5wdXQpO1xuICAgICAgICB3cmFwcGVyLmFwcGVuZENoaWxkKGFycm93VXApO1xuICAgICAgICB3cmFwcGVyLmFwcGVuZENoaWxkKGFycm93RG93bik7XG4gICAgICAgIHJldHVybiB3cmFwcGVyO1xuICAgIH1cbiAgICBmdW5jdGlvbiBnZXRFdmVudFRhcmdldChldmVudCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBldmVudC5jb21wb3NlZFBhdGggPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgIHZhciBwYXRoID0gZXZlbnQuY29tcG9zZWRQYXRoKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhdGhbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZXZlbnQudGFyZ2V0O1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgcmV0dXJuIGV2ZW50LnRhcmdldDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkb05vdGhpbmcgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB1bmRlZmluZWQ7IH07XG4gICAgdmFyIG1vbnRoVG9TdHIgPSBmdW5jdGlvbiAobW9udGhOdW1iZXIsIHNob3J0aGFuZCwgbG9jYWxlKSB7IHJldHVybiBsb2NhbGUubW9udGhzW3Nob3J0aGFuZCA/IFwic2hvcnRoYW5kXCIgOiBcImxvbmdoYW5kXCJdW21vbnRoTnVtYmVyXTsgfTtcbiAgICB2YXIgcmV2Rm9ybWF0ID0ge1xuICAgICAgICBEOiBkb05vdGhpbmcsXG4gICAgICAgIEY6IGZ1bmN0aW9uIChkYXRlT2JqLCBtb250aE5hbWUsIGxvY2FsZSkge1xuICAgICAgICAgICAgZGF0ZU9iai5zZXRNb250aChsb2NhbGUubW9udGhzLmxvbmdoYW5kLmluZGV4T2YobW9udGhOYW1lKSk7XG4gICAgICAgIH0sXG4gICAgICAgIEc6IGZ1bmN0aW9uIChkYXRlT2JqLCBob3VyKSB7XG4gICAgICAgICAgICBkYXRlT2JqLnNldEhvdXJzKChkYXRlT2JqLmdldEhvdXJzKCkgPj0gMTIgPyAxMiA6IDApICsgcGFyc2VGbG9hdChob3VyKSk7XG4gICAgICAgIH0sXG4gICAgICAgIEg6IGZ1bmN0aW9uIChkYXRlT2JqLCBob3VyKSB7XG4gICAgICAgICAgICBkYXRlT2JqLnNldEhvdXJzKHBhcnNlRmxvYXQoaG91cikpO1xuICAgICAgICB9LFxuICAgICAgICBKOiBmdW5jdGlvbiAoZGF0ZU9iaiwgZGF5KSB7XG4gICAgICAgICAgICBkYXRlT2JqLnNldERhdGUocGFyc2VGbG9hdChkYXkpKTtcbiAgICAgICAgfSxcbiAgICAgICAgSzogZnVuY3Rpb24gKGRhdGVPYmosIGFtUE0sIGxvY2FsZSkge1xuICAgICAgICAgICAgZGF0ZU9iai5zZXRIb3VycygoZGF0ZU9iai5nZXRIb3VycygpICUgMTIpICtcbiAgICAgICAgICAgICAgICAxMiAqIGludChuZXcgUmVnRXhwKGxvY2FsZS5hbVBNWzFdLCBcImlcIikudGVzdChhbVBNKSkpO1xuICAgICAgICB9LFxuICAgICAgICBNOiBmdW5jdGlvbiAoZGF0ZU9iaiwgc2hvcnRNb250aCwgbG9jYWxlKSB7XG4gICAgICAgICAgICBkYXRlT2JqLnNldE1vbnRoKGxvY2FsZS5tb250aHMuc2hvcnRoYW5kLmluZGV4T2Yoc2hvcnRNb250aCkpO1xuICAgICAgICB9LFxuICAgICAgICBTOiBmdW5jdGlvbiAoZGF0ZU9iaiwgc2Vjb25kcykge1xuICAgICAgICAgICAgZGF0ZU9iai5zZXRTZWNvbmRzKHBhcnNlRmxvYXQoc2Vjb25kcykpO1xuICAgICAgICB9LFxuICAgICAgICBVOiBmdW5jdGlvbiAoXywgdW5peFNlY29uZHMpIHsgcmV0dXJuIG5ldyBEYXRlKHBhcnNlRmxvYXQodW5peFNlY29uZHMpICogMTAwMCk7IH0sXG4gICAgICAgIFc6IGZ1bmN0aW9uIChkYXRlT2JqLCB3ZWVrTnVtLCBsb2NhbGUpIHtcbiAgICAgICAgICAgIHZhciB3ZWVrTnVtYmVyID0gcGFyc2VJbnQod2Vla051bSk7XG4gICAgICAgICAgICB2YXIgZGF0ZSA9IG5ldyBEYXRlKGRhdGVPYmouZ2V0RnVsbFllYXIoKSwgMCwgMiArICh3ZWVrTnVtYmVyIC0gMSkgKiA3LCAwLCAwLCAwLCAwKTtcbiAgICAgICAgICAgIGRhdGUuc2V0RGF0ZShkYXRlLmdldERhdGUoKSAtIGRhdGUuZ2V0RGF5KCkgKyBsb2NhbGUuZmlyc3REYXlPZldlZWspO1xuICAgICAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgICAgIH0sXG4gICAgICAgIFk6IGZ1bmN0aW9uIChkYXRlT2JqLCB5ZWFyKSB7XG4gICAgICAgICAgICBkYXRlT2JqLnNldEZ1bGxZZWFyKHBhcnNlRmxvYXQoeWVhcikpO1xuICAgICAgICB9LFxuICAgICAgICBaOiBmdW5jdGlvbiAoXywgSVNPRGF0ZSkgeyByZXR1cm4gbmV3IERhdGUoSVNPRGF0ZSk7IH0sXG4gICAgICAgIGQ6IGZ1bmN0aW9uIChkYXRlT2JqLCBkYXkpIHtcbiAgICAgICAgICAgIGRhdGVPYmouc2V0RGF0ZShwYXJzZUZsb2F0KGRheSkpO1xuICAgICAgICB9LFxuICAgICAgICBoOiBmdW5jdGlvbiAoZGF0ZU9iaiwgaG91cikge1xuICAgICAgICAgICAgZGF0ZU9iai5zZXRIb3VycygoZGF0ZU9iai5nZXRIb3VycygpID49IDEyID8gMTIgOiAwKSArIHBhcnNlRmxvYXQoaG91cikpO1xuICAgICAgICB9LFxuICAgICAgICBpOiBmdW5jdGlvbiAoZGF0ZU9iaiwgbWludXRlcykge1xuICAgICAgICAgICAgZGF0ZU9iai5zZXRNaW51dGVzKHBhcnNlRmxvYXQobWludXRlcykpO1xuICAgICAgICB9LFxuICAgICAgICBqOiBmdW5jdGlvbiAoZGF0ZU9iaiwgZGF5KSB7XG4gICAgICAgICAgICBkYXRlT2JqLnNldERhdGUocGFyc2VGbG9hdChkYXkpKTtcbiAgICAgICAgfSxcbiAgICAgICAgbDogZG9Ob3RoaW5nLFxuICAgICAgICBtOiBmdW5jdGlvbiAoZGF0ZU9iaiwgbW9udGgpIHtcbiAgICAgICAgICAgIGRhdGVPYmouc2V0TW9udGgocGFyc2VGbG9hdChtb250aCkgLSAxKTtcbiAgICAgICAgfSxcbiAgICAgICAgbjogZnVuY3Rpb24gKGRhdGVPYmosIG1vbnRoKSB7XG4gICAgICAgICAgICBkYXRlT2JqLnNldE1vbnRoKHBhcnNlRmxvYXQobW9udGgpIC0gMSk7XG4gICAgICAgIH0sXG4gICAgICAgIHM6IGZ1bmN0aW9uIChkYXRlT2JqLCBzZWNvbmRzKSB7XG4gICAgICAgICAgICBkYXRlT2JqLnNldFNlY29uZHMocGFyc2VGbG9hdChzZWNvbmRzKSk7XG4gICAgICAgIH0sXG4gICAgICAgIHU6IGZ1bmN0aW9uIChfLCB1bml4TWlsbFNlY29uZHMpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgRGF0ZShwYXJzZUZsb2F0KHVuaXhNaWxsU2Vjb25kcykpO1xuICAgICAgICB9LFxuICAgICAgICB3OiBkb05vdGhpbmcsXG4gICAgICAgIHk6IGZ1bmN0aW9uIChkYXRlT2JqLCB5ZWFyKSB7XG4gICAgICAgICAgICBkYXRlT2JqLnNldEZ1bGxZZWFyKDIwMDAgKyBwYXJzZUZsb2F0KHllYXIpKTtcbiAgICAgICAgfSxcbiAgICB9O1xuICAgIHZhciB0b2tlblJlZ2V4ID0ge1xuICAgICAgICBEOiBcIlwiLFxuICAgICAgICBGOiBcIlwiLFxuICAgICAgICBHOiBcIihcXFxcZFxcXFxkfFxcXFxkKVwiLFxuICAgICAgICBIOiBcIihcXFxcZFxcXFxkfFxcXFxkKVwiLFxuICAgICAgICBKOiBcIihcXFxcZFxcXFxkfFxcXFxkKVxcXFx3K1wiLFxuICAgICAgICBLOiBcIlwiLFxuICAgICAgICBNOiBcIlwiLFxuICAgICAgICBTOiBcIihcXFxcZFxcXFxkfFxcXFxkKVwiLFxuICAgICAgICBVOiBcIiguKylcIixcbiAgICAgICAgVzogXCIoXFxcXGRcXFxcZHxcXFxcZClcIixcbiAgICAgICAgWTogXCIoXFxcXGR7NH0pXCIsXG4gICAgICAgIFo6IFwiKC4rKVwiLFxuICAgICAgICBkOiBcIihcXFxcZFxcXFxkfFxcXFxkKVwiLFxuICAgICAgICBoOiBcIihcXFxcZFxcXFxkfFxcXFxkKVwiLFxuICAgICAgICBpOiBcIihcXFxcZFxcXFxkfFxcXFxkKVwiLFxuICAgICAgICBqOiBcIihcXFxcZFxcXFxkfFxcXFxkKVwiLFxuICAgICAgICBsOiBcIlwiLFxuICAgICAgICBtOiBcIihcXFxcZFxcXFxkfFxcXFxkKVwiLFxuICAgICAgICBuOiBcIihcXFxcZFxcXFxkfFxcXFxkKVwiLFxuICAgICAgICBzOiBcIihcXFxcZFxcXFxkfFxcXFxkKVwiLFxuICAgICAgICB1OiBcIiguKylcIixcbiAgICAgICAgdzogXCIoXFxcXGRcXFxcZHxcXFxcZClcIixcbiAgICAgICAgeTogXCIoXFxcXGR7Mn0pXCIsXG4gICAgfTtcbiAgICB2YXIgZm9ybWF0cyA9IHtcbiAgICAgICAgLy8gZ2V0IHRoZSBkYXRlIGluIFVUQ1xuICAgICAgICBaOiBmdW5jdGlvbiAoZGF0ZSkgeyByZXR1cm4gZGF0ZS50b0lTT1N0cmluZygpOyB9LFxuICAgICAgICAvLyB3ZWVrZGF5IG5hbWUsIHNob3J0LCBlLmcuIFRodVxuICAgICAgICBEOiBmdW5jdGlvbiAoZGF0ZSwgbG9jYWxlLCBvcHRpb25zKSB7XG4gICAgICAgICAgICByZXR1cm4gbG9jYWxlLndlZWtkYXlzLnNob3J0aGFuZFtmb3JtYXRzLncoZGF0ZSwgbG9jYWxlLCBvcHRpb25zKV07XG4gICAgICAgIH0sXG4gICAgICAgIC8vIGZ1bGwgbW9udGggbmFtZSBlLmcuIEphbnVhcnlcbiAgICAgICAgRjogZnVuY3Rpb24gKGRhdGUsIGxvY2FsZSwgb3B0aW9ucykge1xuICAgICAgICAgICAgcmV0dXJuIG1vbnRoVG9TdHIoZm9ybWF0cy5uKGRhdGUsIGxvY2FsZSwgb3B0aW9ucykgLSAxLCBmYWxzZSwgbG9jYWxlKTtcbiAgICAgICAgfSxcbiAgICAgICAgLy8gcGFkZGVkIGhvdXIgMS0xMlxuICAgICAgICBHOiBmdW5jdGlvbiAoZGF0ZSwgbG9jYWxlLCBvcHRpb25zKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFkKGZvcm1hdHMuaChkYXRlLCBsb2NhbGUsIG9wdGlvbnMpKTtcbiAgICAgICAgfSxcbiAgICAgICAgLy8gaG91cnMgd2l0aCBsZWFkaW5nIHplcm8gZS5nLiAwM1xuICAgICAgICBIOiBmdW5jdGlvbiAoZGF0ZSkgeyByZXR1cm4gcGFkKGRhdGUuZ2V0SG91cnMoKSk7IH0sXG4gICAgICAgIC8vIGRheSAoMS0zMCkgd2l0aCBvcmRpbmFsIHN1ZmZpeCBlLmcuIDFzdCwgMm5kXG4gICAgICAgIEo6IGZ1bmN0aW9uIChkYXRlLCBsb2NhbGUpIHtcbiAgICAgICAgICAgIHJldHVybiBsb2NhbGUub3JkaW5hbCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgPyBkYXRlLmdldERhdGUoKSArIGxvY2FsZS5vcmRpbmFsKGRhdGUuZ2V0RGF0ZSgpKVxuICAgICAgICAgICAgICAgIDogZGF0ZS5nZXREYXRlKCk7XG4gICAgICAgIH0sXG4gICAgICAgIC8vIEFNL1BNXG4gICAgICAgIEs6IGZ1bmN0aW9uIChkYXRlLCBsb2NhbGUpIHsgcmV0dXJuIGxvY2FsZS5hbVBNW2ludChkYXRlLmdldEhvdXJzKCkgPiAxMSldOyB9LFxuICAgICAgICAvLyBzaG9ydGhhbmQgbW9udGggZS5nLiBKYW4sIFNlcCwgT2N0LCBldGNcbiAgICAgICAgTTogZnVuY3Rpb24gKGRhdGUsIGxvY2FsZSkge1xuICAgICAgICAgICAgcmV0dXJuIG1vbnRoVG9TdHIoZGF0ZS5nZXRNb250aCgpLCB0cnVlLCBsb2NhbGUpO1xuICAgICAgICB9LFxuICAgICAgICAvLyBzZWNvbmRzIDAwLTU5XG4gICAgICAgIFM6IGZ1bmN0aW9uIChkYXRlKSB7IHJldHVybiBwYWQoZGF0ZS5nZXRTZWNvbmRzKCkpOyB9LFxuICAgICAgICAvLyB1bml4IHRpbWVzdGFtcFxuICAgICAgICBVOiBmdW5jdGlvbiAoZGF0ZSkgeyByZXR1cm4gZGF0ZS5nZXRUaW1lKCkgLyAxMDAwOyB9LFxuICAgICAgICBXOiBmdW5jdGlvbiAoZGF0ZSwgXywgb3B0aW9ucykge1xuICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnMuZ2V0V2VlayhkYXRlKTtcbiAgICAgICAgfSxcbiAgICAgICAgLy8gZnVsbCB5ZWFyIGUuZy4gMjAxNiwgcGFkZGVkICgwMDAxLTk5OTkpXG4gICAgICAgIFk6IGZ1bmN0aW9uIChkYXRlKSB7IHJldHVybiBwYWQoZGF0ZS5nZXRGdWxsWWVhcigpLCA0KTsgfSxcbiAgICAgICAgLy8gZGF5IGluIG1vbnRoLCBwYWRkZWQgKDAxLTMwKVxuICAgICAgICBkOiBmdW5jdGlvbiAoZGF0ZSkgeyByZXR1cm4gcGFkKGRhdGUuZ2V0RGF0ZSgpKTsgfSxcbiAgICAgICAgLy8gaG91ciBmcm9tIDEtMTIgKGFtL3BtKVxuICAgICAgICBoOiBmdW5jdGlvbiAoZGF0ZSkgeyByZXR1cm4gKGRhdGUuZ2V0SG91cnMoKSAlIDEyID8gZGF0ZS5nZXRIb3VycygpICUgMTIgOiAxMik7IH0sXG4gICAgICAgIC8vIG1pbnV0ZXMsIHBhZGRlZCB3aXRoIGxlYWRpbmcgemVybyBlLmcuIDA5XG4gICAgICAgIGk6IGZ1bmN0aW9uIChkYXRlKSB7IHJldHVybiBwYWQoZGF0ZS5nZXRNaW51dGVzKCkpOyB9LFxuICAgICAgICAvLyBkYXkgaW4gbW9udGggKDEtMzApXG4gICAgICAgIGo6IGZ1bmN0aW9uIChkYXRlKSB7IHJldHVybiBkYXRlLmdldERhdGUoKTsgfSxcbiAgICAgICAgLy8gd2Vla2RheSBuYW1lLCBmdWxsLCBlLmcuIFRodXJzZGF5XG4gICAgICAgIGw6IGZ1bmN0aW9uIChkYXRlLCBsb2NhbGUpIHtcbiAgICAgICAgICAgIHJldHVybiBsb2NhbGUud2Vla2RheXMubG9uZ2hhbmRbZGF0ZS5nZXREYXkoKV07XG4gICAgICAgIH0sXG4gICAgICAgIC8vIHBhZGRlZCBtb250aCBudW1iZXIgKDAxLTEyKVxuICAgICAgICBtOiBmdW5jdGlvbiAoZGF0ZSkgeyByZXR1cm4gcGFkKGRhdGUuZ2V0TW9udGgoKSArIDEpOyB9LFxuICAgICAgICAvLyB0aGUgbW9udGggbnVtYmVyICgxLTEyKVxuICAgICAgICBuOiBmdW5jdGlvbiAoZGF0ZSkgeyByZXR1cm4gZGF0ZS5nZXRNb250aCgpICsgMTsgfSxcbiAgICAgICAgLy8gc2Vjb25kcyAwLTU5XG4gICAgICAgIHM6IGZ1bmN0aW9uIChkYXRlKSB7IHJldHVybiBkYXRlLmdldFNlY29uZHMoKTsgfSxcbiAgICAgICAgLy8gVW5peCBNaWxsaXNlY29uZHNcbiAgICAgICAgdTogZnVuY3Rpb24gKGRhdGUpIHsgcmV0dXJuIGRhdGUuZ2V0VGltZSgpOyB9LFxuICAgICAgICAvLyBudW1iZXIgb2YgdGhlIGRheSBvZiB0aGUgd2Vla1xuICAgICAgICB3OiBmdW5jdGlvbiAoZGF0ZSkgeyByZXR1cm4gZGF0ZS5nZXREYXkoKTsgfSxcbiAgICAgICAgLy8gbGFzdCB0d28gZGlnaXRzIG9mIHllYXIgZS5nLiAxNiBmb3IgMjAxNlxuICAgICAgICB5OiBmdW5jdGlvbiAoZGF0ZSkgeyByZXR1cm4gU3RyaW5nKGRhdGUuZ2V0RnVsbFllYXIoKSkuc3Vic3RyaW5nKDIpOyB9LFxuICAgIH07XG5cbiAgICB2YXIgY3JlYXRlRGF0ZUZvcm1hdHRlciA9IGZ1bmN0aW9uIChfYSkge1xuICAgICAgICB2YXIgX2IgPSBfYS5jb25maWcsIGNvbmZpZyA9IF9iID09PSB2b2lkIDAgPyBkZWZhdWx0cyA6IF9iLCBfYyA9IF9hLmwxMG4sIGwxMG4gPSBfYyA9PT0gdm9pZCAwID8gZW5nbGlzaCA6IF9jLCBfZCA9IF9hLmlzTW9iaWxlLCBpc01vYmlsZSA9IF9kID09PSB2b2lkIDAgPyBmYWxzZSA6IF9kO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGRhdGVPYmosIGZybXQsIG92ZXJyaWRlTG9jYWxlKSB7XG4gICAgICAgICAgICB2YXIgbG9jYWxlID0gb3ZlcnJpZGVMb2NhbGUgfHwgbDEwbjtcbiAgICAgICAgICAgIGlmIChjb25maWcuZm9ybWF0RGF0ZSAhPT0gdW5kZWZpbmVkICYmICFpc01vYmlsZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjb25maWcuZm9ybWF0RGF0ZShkYXRlT2JqLCBmcm10LCBsb2NhbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZybXRcbiAgICAgICAgICAgICAgICAuc3BsaXQoXCJcIilcbiAgICAgICAgICAgICAgICAubWFwKGZ1bmN0aW9uIChjLCBpLCBhcnIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZm9ybWF0c1tjXSAmJiBhcnJbaSAtIDFdICE9PSBcIlxcXFxcIlxuICAgICAgICAgICAgICAgICAgICA/IGZvcm1hdHNbY10oZGF0ZU9iaiwgbG9jYWxlLCBjb25maWcpXG4gICAgICAgICAgICAgICAgICAgIDogYyAhPT0gXCJcXFxcXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID8gY1xuICAgICAgICAgICAgICAgICAgICAgICAgOiBcIlwiO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuam9pbihcIlwiKTtcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHZhciBjcmVhdGVEYXRlUGFyc2VyID0gZnVuY3Rpb24gKF9hKSB7XG4gICAgICAgIHZhciBfYiA9IF9hLmNvbmZpZywgY29uZmlnID0gX2IgPT09IHZvaWQgMCA/IGRlZmF1bHRzIDogX2IsIF9jID0gX2EubDEwbiwgbDEwbiA9IF9jID09PSB2b2lkIDAgPyBlbmdsaXNoIDogX2M7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoZGF0ZSwgZ2l2ZW5Gb3JtYXQsIHRpbWVsZXNzLCBjdXN0b21Mb2NhbGUpIHtcbiAgICAgICAgICAgIGlmIChkYXRlICE9PSAwICYmICFkYXRlKVxuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB2YXIgbG9jYWxlID0gY3VzdG9tTG9jYWxlIHx8IGwxMG47XG4gICAgICAgICAgICB2YXIgcGFyc2VkRGF0ZTtcbiAgICAgICAgICAgIHZhciBkYXRlT3JpZyA9IGRhdGU7XG4gICAgICAgICAgICBpZiAoZGF0ZSBpbnN0YW5jZW9mIERhdGUpXG4gICAgICAgICAgICAgICAgcGFyc2VkRGF0ZSA9IG5ldyBEYXRlKGRhdGUuZ2V0VGltZSgpKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBkYXRlICE9PSBcInN0cmluZ1wiICYmXG4gICAgICAgICAgICAgICAgZGF0ZS50b0ZpeGVkICE9PSB1bmRlZmluZWQgLy8gdGltZXN0YW1wXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgLy8gY3JlYXRlIGEgY29weVxuICAgICAgICAgICAgICAgIHBhcnNlZERhdGUgPSBuZXcgRGF0ZShkYXRlKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBkYXRlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgLy8gZGF0ZSBzdHJpbmdcbiAgICAgICAgICAgICAgICB2YXIgZm9ybWF0ID0gZ2l2ZW5Gb3JtYXQgfHwgKGNvbmZpZyB8fCBkZWZhdWx0cykuZGF0ZUZvcm1hdDtcbiAgICAgICAgICAgICAgICB2YXIgZGF0ZXN0ciA9IFN0cmluZyhkYXRlKS50cmltKCk7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGVzdHIgPT09IFwidG9kYXlcIikge1xuICAgICAgICAgICAgICAgICAgICBwYXJzZWREYXRlID0gbmV3IERhdGUoKTtcbiAgICAgICAgICAgICAgICAgICAgdGltZWxlc3MgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChjb25maWcgJiYgY29uZmlnLnBhcnNlRGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICBwYXJzZWREYXRlID0gY29uZmlnLnBhcnNlRGF0ZShkYXRlLCBmb3JtYXQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmICgvWiQvLnRlc3QoZGF0ZXN0cikgfHxcbiAgICAgICAgICAgICAgICAgICAgL0dNVCQvLnRlc3QoZGF0ZXN0cikgLy8gZGF0ZXN0cmluZ3Mgdy8gdGltZXpvbmVcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VkRGF0ZSA9IG5ldyBEYXRlKGRhdGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1hdGNoZWQgPSB2b2lkIDAsIG9wcyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbWF0Y2hJbmRleCA9IDAsIHJlZ2V4U3RyID0gXCJcIjsgaSA8IGZvcm1hdC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRva2VuXzEgPSBmb3JtYXRbaV07XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNCYWNrU2xhc2ggPSB0b2tlbl8xID09PSBcIlxcXFxcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlc2NhcGVkID0gZm9ybWF0W2kgLSAxXSA9PT0gXCJcXFxcXCIgfHwgaXNCYWNrU2xhc2g7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW5SZWdleFt0b2tlbl8xXSAmJiAhZXNjYXBlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2V4U3RyICs9IHRva2VuUmVnZXhbdG9rZW5fMV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1hdGNoID0gbmV3IFJlZ0V4cChyZWdleFN0cikuZXhlYyhkYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWF0Y2ggJiYgKG1hdGNoZWQgPSB0cnVlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHNbdG9rZW5fMSAhPT0gXCJZXCIgPyBcInB1c2hcIiA6IFwidW5zaGlmdFwiXSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbjogcmV2Rm9ybWF0W3Rva2VuXzFdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsOiBtYXRjaFsrK21hdGNoSW5kZXhdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghaXNCYWNrU2xhc2gpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnZXhTdHIgKz0gXCIuXCI7IC8vIGRvbid0IHJlYWxseSBjYXJlXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcGFyc2VkRGF0ZSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAhY29uZmlnIHx8ICFjb25maWcubm9DYWxlbmRhclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gbmV3IERhdGUobmV3IERhdGUoKS5nZXRGdWxsWWVhcigpLCAwLCAxLCAwLCAwLCAwLCAwKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbmV3IERhdGUobmV3IERhdGUoKS5zZXRIb3VycygwLCAwLCAwLCAwKSk7XG4gICAgICAgICAgICAgICAgICAgIG9wcy5mb3JFYWNoKGZ1bmN0aW9uIChfYSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZuID0gX2EuZm4sIHZhbCA9IF9hLnZhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAocGFyc2VkRGF0ZSA9IGZuKHBhcnNlZERhdGUsIHZhbCwgbG9jYWxlKSB8fCBwYXJzZWREYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHBhcnNlZERhdGUgPSBtYXRjaGVkID8gcGFyc2VkRGF0ZSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICAgICAgaWYgKCEocGFyc2VkRGF0ZSBpbnN0YW5jZW9mIERhdGUgJiYgIWlzTmFOKHBhcnNlZERhdGUuZ2V0VGltZSgpKSkpIHtcbiAgICAgICAgICAgICAgICBjb25maWcuZXJyb3JIYW5kbGVyKG5ldyBFcnJvcihcIkludmFsaWQgZGF0ZSBwcm92aWRlZDogXCIgKyBkYXRlT3JpZykpO1xuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGltZWxlc3MgPT09IHRydWUpXG4gICAgICAgICAgICAgICAgcGFyc2VkRGF0ZS5zZXRIb3VycygwLCAwLCAwLCAwKTtcbiAgICAgICAgICAgIHJldHVybiBwYXJzZWREYXRlO1xuICAgICAgICB9O1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQ29tcHV0ZSB0aGUgZGlmZmVyZW5jZSBpbiBkYXRlcywgbWVhc3VyZWQgaW4gbXNcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb21wYXJlRGF0ZXMoZGF0ZTEsIGRhdGUyLCB0aW1lbGVzcykge1xuICAgICAgICBpZiAodGltZWxlc3MgPT09IHZvaWQgMCkgeyB0aW1lbGVzcyA9IHRydWU7IH1cbiAgICAgICAgaWYgKHRpbWVsZXNzICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgcmV0dXJuIChuZXcgRGF0ZShkYXRlMS5nZXRUaW1lKCkpLnNldEhvdXJzKDAsIDAsIDAsIDApIC1cbiAgICAgICAgICAgICAgICBuZXcgRGF0ZShkYXRlMi5nZXRUaW1lKCkpLnNldEhvdXJzKDAsIDAsIDAsIDApKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGF0ZTEuZ2V0VGltZSgpIC0gZGF0ZTIuZ2V0VGltZSgpO1xuICAgIH1cbiAgICB2YXIgaXNCZXR3ZWVuID0gZnVuY3Rpb24gKHRzLCB0czEsIHRzMikge1xuICAgICAgICByZXR1cm4gdHMgPiBNYXRoLm1pbih0czEsIHRzMikgJiYgdHMgPCBNYXRoLm1heCh0czEsIHRzMik7XG4gICAgfTtcbiAgICB2YXIgY2FsY3VsYXRlU2Vjb25kc1NpbmNlTWlkbmlnaHQgPSBmdW5jdGlvbiAoaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMpIHtcbiAgICAgICAgcmV0dXJuIGhvdXJzICogMzYwMCArIG1pbnV0ZXMgKiA2MCArIHNlY29uZHM7XG4gICAgfTtcbiAgICB2YXIgcGFyc2VTZWNvbmRzID0gZnVuY3Rpb24gKHNlY29uZHNTaW5jZU1pZG5pZ2h0KSB7XG4gICAgICAgIHZhciBob3VycyA9IE1hdGguZmxvb3Ioc2Vjb25kc1NpbmNlTWlkbmlnaHQgLyAzNjAwKSwgbWludXRlcyA9IChzZWNvbmRzU2luY2VNaWRuaWdodCAtIGhvdXJzICogMzYwMCkgLyA2MDtcbiAgICAgICAgcmV0dXJuIFtob3VycywgbWludXRlcywgc2Vjb25kc1NpbmNlTWlkbmlnaHQgLSBob3VycyAqIDM2MDAgLSBtaW51dGVzICogNjBdO1xuICAgIH07XG4gICAgdmFyIGR1cmF0aW9uID0ge1xuICAgICAgICBEQVk6IDg2NDAwMDAwLFxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0RGVmYXVsdEhvdXJzKGNvbmZpZykge1xuICAgICAgICB2YXIgaG91cnMgPSBjb25maWcuZGVmYXVsdEhvdXI7XG4gICAgICAgIHZhciBtaW51dGVzID0gY29uZmlnLmRlZmF1bHRNaW51dGU7XG4gICAgICAgIHZhciBzZWNvbmRzID0gY29uZmlnLmRlZmF1bHRTZWNvbmRzO1xuICAgICAgICBpZiAoY29uZmlnLm1pbkRhdGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdmFyIG1pbkhvdXIgPSBjb25maWcubWluRGF0ZS5nZXRIb3VycygpO1xuICAgICAgICAgICAgdmFyIG1pbk1pbnV0ZXMgPSBjb25maWcubWluRGF0ZS5nZXRNaW51dGVzKCk7XG4gICAgICAgICAgICB2YXIgbWluU2Vjb25kcyA9IGNvbmZpZy5taW5EYXRlLmdldFNlY29uZHMoKTtcbiAgICAgICAgICAgIGlmIChob3VycyA8IG1pbkhvdXIpIHtcbiAgICAgICAgICAgICAgICBob3VycyA9IG1pbkhvdXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaG91cnMgPT09IG1pbkhvdXIgJiYgbWludXRlcyA8IG1pbk1pbnV0ZXMpIHtcbiAgICAgICAgICAgICAgICBtaW51dGVzID0gbWluTWludXRlcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChob3VycyA9PT0gbWluSG91ciAmJiBtaW51dGVzID09PSBtaW5NaW51dGVzICYmIHNlY29uZHMgPCBtaW5TZWNvbmRzKVxuICAgICAgICAgICAgICAgIHNlY29uZHMgPSBjb25maWcubWluRGF0ZS5nZXRTZWNvbmRzKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbmZpZy5tYXhEYXRlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHZhciBtYXhIciA9IGNvbmZpZy5tYXhEYXRlLmdldEhvdXJzKCk7XG4gICAgICAgICAgICB2YXIgbWF4TWludXRlcyA9IGNvbmZpZy5tYXhEYXRlLmdldE1pbnV0ZXMoKTtcbiAgICAgICAgICAgIGhvdXJzID0gTWF0aC5taW4oaG91cnMsIG1heEhyKTtcbiAgICAgICAgICAgIGlmIChob3VycyA9PT0gbWF4SHIpXG4gICAgICAgICAgICAgICAgbWludXRlcyA9IE1hdGgubWluKG1heE1pbnV0ZXMsIG1pbnV0ZXMpO1xuICAgICAgICAgICAgaWYgKGhvdXJzID09PSBtYXhIciAmJiBtaW51dGVzID09PSBtYXhNaW51dGVzKVxuICAgICAgICAgICAgICAgIHNlY29uZHMgPSBjb25maWcubWF4RGF0ZS5nZXRTZWNvbmRzKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgaG91cnM6IGhvdXJzLCBtaW51dGVzOiBtaW51dGVzLCBzZWNvbmRzOiBzZWNvbmRzIH07XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBPYmplY3QuYXNzaWduICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgT2JqZWN0LmFzc2lnbiA9IGZ1bmN0aW9uICh0YXJnZXQpIHtcbiAgICAgICAgICAgIHZhciBhcmdzID0gW107XG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDE7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgICAgIGFyZ3NbX2kgLSAxXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRhcmdldCkge1xuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIkNhbm5vdCBjb252ZXJ0IHVuZGVmaW5lZCBvciBudWxsIHRvIG9iamVjdFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBfbG9vcF8xID0gZnVuY3Rpb24gKHNvdXJjZSkge1xuICAgICAgICAgICAgICAgIGlmIChzb3VyY2UpIHtcbiAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmtleXMoc291cmNlKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuICh0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldKTsgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGZvciAodmFyIF9hID0gMCwgYXJnc18xID0gYXJnczsgX2EgPCBhcmdzXzEubGVuZ3RoOyBfYSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIHNvdXJjZSA9IGFyZ3NfMVtfYV07XG4gICAgICAgICAgICAgICAgX2xvb3BfMShzb3VyY2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgREVCT1VOQ0VEX0NIQU5HRV9NUyA9IDMwMDtcbiAgICBmdW5jdGlvbiBGbGF0cGlja3JJbnN0YW5jZShlbGVtZW50LCBpbnN0YW5jZUNvbmZpZykge1xuICAgICAgICB2YXIgc2VsZiA9IHtcbiAgICAgICAgICAgIGNvbmZpZzogX19hc3NpZ24oX19hc3NpZ24oe30sIGRlZmF1bHRzKSwgZmxhdHBpY2tyLmRlZmF1bHRDb25maWcpLFxuICAgICAgICAgICAgbDEwbjogZW5nbGlzaCxcbiAgICAgICAgfTtcbiAgICAgICAgc2VsZi5wYXJzZURhdGUgPSBjcmVhdGVEYXRlUGFyc2VyKHsgY29uZmlnOiBzZWxmLmNvbmZpZywgbDEwbjogc2VsZi5sMTBuIH0pO1xuICAgICAgICBzZWxmLl9oYW5kbGVycyA9IFtdO1xuICAgICAgICBzZWxmLnBsdWdpbkVsZW1lbnRzID0gW107XG4gICAgICAgIHNlbGYubG9hZGVkUGx1Z2lucyA9IFtdO1xuICAgICAgICBzZWxmLl9iaW5kID0gYmluZDtcbiAgICAgICAgc2VsZi5fc2V0SG91cnNGcm9tRGF0ZSA9IHNldEhvdXJzRnJvbURhdGU7XG4gICAgICAgIHNlbGYuX3Bvc2l0aW9uQ2FsZW5kYXIgPSBwb3NpdGlvbkNhbGVuZGFyO1xuICAgICAgICBzZWxmLmNoYW5nZU1vbnRoID0gY2hhbmdlTW9udGg7XG4gICAgICAgIHNlbGYuY2hhbmdlWWVhciA9IGNoYW5nZVllYXI7XG4gICAgICAgIHNlbGYuY2xlYXIgPSBjbGVhcjtcbiAgICAgICAgc2VsZi5jbG9zZSA9IGNsb3NlO1xuICAgICAgICBzZWxmLm9uTW91c2VPdmVyID0gb25Nb3VzZU92ZXI7XG4gICAgICAgIHNlbGYuX2NyZWF0ZUVsZW1lbnQgPSBjcmVhdGVFbGVtZW50O1xuICAgICAgICBzZWxmLmNyZWF0ZURheSA9IGNyZWF0ZURheTtcbiAgICAgICAgc2VsZi5kZXN0cm95ID0gZGVzdHJveTtcbiAgICAgICAgc2VsZi5pc0VuYWJsZWQgPSBpc0VuYWJsZWQ7XG4gICAgICAgIHNlbGYuanVtcFRvRGF0ZSA9IGp1bXBUb0RhdGU7XG4gICAgICAgIHNlbGYudXBkYXRlVmFsdWUgPSB1cGRhdGVWYWx1ZTtcbiAgICAgICAgc2VsZi5vcGVuID0gb3BlbjtcbiAgICAgICAgc2VsZi5yZWRyYXcgPSByZWRyYXc7XG4gICAgICAgIHNlbGYuc2V0ID0gc2V0O1xuICAgICAgICBzZWxmLnNldERhdGUgPSBzZXREYXRlO1xuICAgICAgICBzZWxmLnRvZ2dsZSA9IHRvZ2dsZTtcbiAgICAgICAgZnVuY3Rpb24gc2V0dXBIZWxwZXJGdW5jdGlvbnMoKSB7XG4gICAgICAgICAgICBzZWxmLnV0aWxzID0ge1xuICAgICAgICAgICAgICAgIGdldERheXNJbk1vbnRoOiBmdW5jdGlvbiAobW9udGgsIHlyKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChtb250aCA9PT0gdm9pZCAwKSB7IG1vbnRoID0gc2VsZi5jdXJyZW50TW9udGg7IH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHlyID09PSB2b2lkIDApIHsgeXIgPSBzZWxmLmN1cnJlbnRZZWFyOyB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChtb250aCA9PT0gMSAmJiAoKHlyICUgNCA9PT0gMCAmJiB5ciAlIDEwMCAhPT0gMCkgfHwgeXIgJSA0MDAgPT09IDApKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDI5O1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5sMTBuLmRheXNJbk1vbnRoW21vbnRoXTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBpbml0KCkge1xuICAgICAgICAgICAgc2VsZi5lbGVtZW50ID0gc2VsZi5pbnB1dCA9IGVsZW1lbnQ7XG4gICAgICAgICAgICBzZWxmLmlzT3BlbiA9IGZhbHNlO1xuICAgICAgICAgICAgcGFyc2VDb25maWcoKTtcbiAgICAgICAgICAgIHNldHVwTG9jYWxlKCk7XG4gICAgICAgICAgICBzZXR1cElucHV0cygpO1xuICAgICAgICAgICAgc2V0dXBEYXRlcygpO1xuICAgICAgICAgICAgc2V0dXBIZWxwZXJGdW5jdGlvbnMoKTtcbiAgICAgICAgICAgIGlmICghc2VsZi5pc01vYmlsZSlcbiAgICAgICAgICAgICAgICBidWlsZCgpO1xuICAgICAgICAgICAgYmluZEV2ZW50cygpO1xuICAgICAgICAgICAgaWYgKHNlbGYuc2VsZWN0ZWREYXRlcy5sZW5ndGggfHwgc2VsZi5jb25maWcubm9DYWxlbmRhcikge1xuICAgICAgICAgICAgICAgIGlmIChzZWxmLmNvbmZpZy5lbmFibGVUaW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIHNldEhvdXJzRnJvbURhdGUoc2VsZi5jb25maWcubm9DYWxlbmRhciA/IHNlbGYubGF0ZXN0U2VsZWN0ZWREYXRlT2JqIDogdW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdXBkYXRlVmFsdWUoZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2V0Q2FsZW5kYXJXaWR0aCgpO1xuICAgICAgICAgICAgdmFyIGlzU2FmYXJpID0gL14oKD8hY2hyb21lfGFuZHJvaWQpLikqc2FmYXJpL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgICAgICAgICAgIC8qIFRPRE86IGludmVzdGlnYXRlIHRoaXMgZnVydGhlclxuICAgICAgICBcbiAgICAgICAgICAgICAgQ3VycmVudGx5LCB0aGVyZSBpcyB3ZWlyZCBwb3NpdGlvbmluZyBiZWhhdmlvciBpbiBzYWZhcmkgY2F1c2luZyBwYWdlc1xuICAgICAgICAgICAgICB0byBzY3JvbGwgdXAuIGh0dHBzOi8vZ2l0aHViLmNvbS9jaG1sbi9mbGF0cGlja3IvaXNzdWVzLzU2M1xuICAgICAgICBcbiAgICAgICAgICAgICAgSG93ZXZlciwgbW9zdCBicm93c2VycyBhcmUgbm90IFNhZmFyaSBhbmQgcG9zaXRpb25pbmcgaXMgZXhwZW5zaXZlIHdoZW4gdXNlZFxuICAgICAgICAgICAgICBpbiBzY2FsZS4gaHR0cHM6Ly9naXRodWIuY29tL2NobWxuL2ZsYXRwaWNrci9pc3N1ZXMvMTA5NlxuICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmICghc2VsZi5pc01vYmlsZSAmJiBpc1NhZmFyaSkge1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uQ2FsZW5kYXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRyaWdnZXJFdmVudChcIm9uUmVhZHlcIik7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gZ2V0Q2xvc2VzdEFjdGl2ZUVsZW1lbnQoKSB7XG4gICAgICAgICAgICB2YXIgX2E7XG4gICAgICAgICAgICByZXR1cm4gKCgoX2EgPSBzZWxmLmNhbGVuZGFyQ29udGFpbmVyKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuZ2V0Um9vdE5vZGUoKSlcbiAgICAgICAgICAgICAgICAuYWN0aXZlRWxlbWVudCB8fCBkb2N1bWVudC5hY3RpdmVFbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBiaW5kVG9JbnN0YW5jZShmbikge1xuICAgICAgICAgICAgcmV0dXJuIGZuLmJpbmQoc2VsZik7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gc2V0Q2FsZW5kYXJXaWR0aCgpIHtcbiAgICAgICAgICAgIHZhciBjb25maWcgPSBzZWxmLmNvbmZpZztcbiAgICAgICAgICAgIGlmIChjb25maWcud2Vla051bWJlcnMgPT09IGZhbHNlICYmIGNvbmZpZy5zaG93TW9udGhzID09PSAxKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY29uZmlnLm5vQ2FsZW5kYXIgIT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYuY2FsZW5kYXJDb250YWluZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5jYWxlbmRhckNvbnRhaW5lci5zdHlsZS52aXNpYmlsaXR5ID0gXCJoaWRkZW5cIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY2FsZW5kYXJDb250YWluZXIuc3R5bGUuZGlzcGxheSA9IFwiYmxvY2tcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5kYXlzQ29udGFpbmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkYXlzV2lkdGggPSAoc2VsZi5kYXlzLm9mZnNldFdpZHRoICsgMSkgKiBjb25maWcuc2hvd01vbnRocztcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZGF5c0NvbnRhaW5lci5zdHlsZS53aWR0aCA9IGRheXNXaWR0aCArIFwicHhcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY2FsZW5kYXJDb250YWluZXIuc3R5bGUud2lkdGggPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRheXNXaWR0aCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZWxmLndlZWtXcmFwcGVyICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gc2VsZi53ZWVrV3JhcHBlci5vZmZzZXRXaWR0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAwKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwicHhcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY2FsZW5kYXJDb250YWluZXIuc3R5bGUucmVtb3ZlUHJvcGVydHkoXCJ2aXNpYmlsaXR5XCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5jYWxlbmRhckNvbnRhaW5lci5zdHlsZS5yZW1vdmVQcm9wZXJ0eShcImRpc3BsYXlcIik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGhhbmRsZXIgZm9yIGFsbCBldmVudHMgdGFyZ2V0aW5nIHRoZSB0aW1lIGlucHV0c1xuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gdXBkYXRlVGltZShlKSB7XG4gICAgICAgICAgICBpZiAoc2VsZi5zZWxlY3RlZERhdGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHZhciBkZWZhdWx0RGF0ZSA9IHNlbGYuY29uZmlnLm1pbkRhdGUgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgICAgICAgICAgICAgICBjb21wYXJlRGF0ZXMobmV3IERhdGUoKSwgc2VsZi5jb25maWcubWluRGF0ZSkgPj0gMFxuICAgICAgICAgICAgICAgICAgICA/IG5ldyBEYXRlKClcbiAgICAgICAgICAgICAgICAgICAgOiBuZXcgRGF0ZShzZWxmLmNvbmZpZy5taW5EYXRlLmdldFRpbWUoKSk7XG4gICAgICAgICAgICAgICAgdmFyIGRlZmF1bHRzID0gZ2V0RGVmYXVsdEhvdXJzKHNlbGYuY29uZmlnKTtcbiAgICAgICAgICAgICAgICBkZWZhdWx0RGF0ZS5zZXRIb3VycyhkZWZhdWx0cy5ob3VycywgZGVmYXVsdHMubWludXRlcywgZGVmYXVsdHMuc2Vjb25kcywgZGVmYXVsdERhdGUuZ2V0TWlsbGlzZWNvbmRzKCkpO1xuICAgICAgICAgICAgICAgIHNlbGYuc2VsZWN0ZWREYXRlcyA9IFtkZWZhdWx0RGF0ZV07XG4gICAgICAgICAgICAgICAgc2VsZi5sYXRlc3RTZWxlY3RlZERhdGVPYmogPSBkZWZhdWx0RGF0ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChlICE9PSB1bmRlZmluZWQgJiYgZS50eXBlICE9PSBcImJsdXJcIikge1xuICAgICAgICAgICAgICAgIHRpbWVXcmFwcGVyKGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHByZXZWYWx1ZSA9IHNlbGYuX2lucHV0LnZhbHVlO1xuICAgICAgICAgICAgc2V0SG91cnNGcm9tSW5wdXRzKCk7XG4gICAgICAgICAgICB1cGRhdGVWYWx1ZSgpO1xuICAgICAgICAgICAgaWYgKHNlbGYuX2lucHV0LnZhbHVlICE9PSBwcmV2VmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzZWxmLl9kZWJvdW5jZWRDaGFuZ2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBhbXBtMm1pbGl0YXJ5KGhvdXIsIGFtUE0pIHtcbiAgICAgICAgICAgIHJldHVybiAoaG91ciAlIDEyKSArIDEyICogaW50KGFtUE0gPT09IHNlbGYubDEwbi5hbVBNWzFdKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBtaWxpdGFyeTJhbXBtKGhvdXIpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoaG91ciAlIDI0KSB7XG4gICAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIGNhc2UgMTI6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAxMjtcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaG91ciAlIDEyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTeW5jcyB0aGUgc2VsZWN0ZWQgZGF0ZSBvYmplY3QgdGltZSB3aXRoIHVzZXIncyB0aW1lIGlucHV0XG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBzZXRIb3Vyc0Zyb21JbnB1dHMoKSB7XG4gICAgICAgICAgICBpZiAoc2VsZi5ob3VyRWxlbWVudCA9PT0gdW5kZWZpbmVkIHx8IHNlbGYubWludXRlRWxlbWVudCA9PT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIHZhciBob3VycyA9IChwYXJzZUludChzZWxmLmhvdXJFbGVtZW50LnZhbHVlLnNsaWNlKC0yKSwgMTApIHx8IDApICUgMjQsIG1pbnV0ZXMgPSAocGFyc2VJbnQoc2VsZi5taW51dGVFbGVtZW50LnZhbHVlLCAxMCkgfHwgMCkgJSA2MCwgc2Vjb25kcyA9IHNlbGYuc2Vjb25kRWxlbWVudCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgPyAocGFyc2VJbnQoc2VsZi5zZWNvbmRFbGVtZW50LnZhbHVlLCAxMCkgfHwgMCkgJSA2MFxuICAgICAgICAgICAgICAgIDogMDtcbiAgICAgICAgICAgIGlmIChzZWxmLmFtUE0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGhvdXJzID0gYW1wbTJtaWxpdGFyeShob3Vycywgc2VsZi5hbVBNLnRleHRDb250ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBsaW1pdE1pbkhvdXJzID0gc2VsZi5jb25maWcubWluVGltZSAhPT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgICAgICAgKHNlbGYuY29uZmlnLm1pbkRhdGUgJiZcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5taW5EYXRlSGFzVGltZSAmJlxuICAgICAgICAgICAgICAgICAgICBzZWxmLmxhdGVzdFNlbGVjdGVkRGF0ZU9iaiAmJlxuICAgICAgICAgICAgICAgICAgICBjb21wYXJlRGF0ZXMoc2VsZi5sYXRlc3RTZWxlY3RlZERhdGVPYmosIHNlbGYuY29uZmlnLm1pbkRhdGUsIHRydWUpID09PVxuICAgICAgICAgICAgICAgICAgICAgICAgMCk7XG4gICAgICAgICAgICB2YXIgbGltaXRNYXhIb3VycyA9IHNlbGYuY29uZmlnLm1heFRpbWUgIT09IHVuZGVmaW5lZCB8fFxuICAgICAgICAgICAgICAgIChzZWxmLmNvbmZpZy5tYXhEYXRlICYmXG4gICAgICAgICAgICAgICAgICAgIHNlbGYubWF4RGF0ZUhhc1RpbWUgJiZcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5sYXRlc3RTZWxlY3RlZERhdGVPYmogJiZcbiAgICAgICAgICAgICAgICAgICAgY29tcGFyZURhdGVzKHNlbGYubGF0ZXN0U2VsZWN0ZWREYXRlT2JqLCBzZWxmLmNvbmZpZy5tYXhEYXRlLCB0cnVlKSA9PT1cbiAgICAgICAgICAgICAgICAgICAgICAgIDApO1xuICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLm1heFRpbWUgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgICAgIHNlbGYuY29uZmlnLm1pblRpbWUgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgICAgIHNlbGYuY29uZmlnLm1pblRpbWUgPiBzZWxmLmNvbmZpZy5tYXhUaW1lKSB7XG4gICAgICAgICAgICAgICAgdmFyIG1pbkJvdW5kID0gY2FsY3VsYXRlU2Vjb25kc1NpbmNlTWlkbmlnaHQoc2VsZi5jb25maWcubWluVGltZS5nZXRIb3VycygpLCBzZWxmLmNvbmZpZy5taW5UaW1lLmdldE1pbnV0ZXMoKSwgc2VsZi5jb25maWcubWluVGltZS5nZXRTZWNvbmRzKCkpO1xuICAgICAgICAgICAgICAgIHZhciBtYXhCb3VuZCA9IGNhbGN1bGF0ZVNlY29uZHNTaW5jZU1pZG5pZ2h0KHNlbGYuY29uZmlnLm1heFRpbWUuZ2V0SG91cnMoKSwgc2VsZi5jb25maWcubWF4VGltZS5nZXRNaW51dGVzKCksIHNlbGYuY29uZmlnLm1heFRpbWUuZ2V0U2Vjb25kcygpKTtcbiAgICAgICAgICAgICAgICB2YXIgY3VycmVudFRpbWUgPSBjYWxjdWxhdGVTZWNvbmRzU2luY2VNaWRuaWdodChob3VycywgbWludXRlcywgc2Vjb25kcyk7XG4gICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRUaW1lID4gbWF4Qm91bmQgJiYgY3VycmVudFRpbWUgPCBtaW5Cb3VuZCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gcGFyc2VTZWNvbmRzKG1pbkJvdW5kKTtcbiAgICAgICAgICAgICAgICAgICAgaG91cnMgPSByZXN1bHRbMF07XG4gICAgICAgICAgICAgICAgICAgIG1pbnV0ZXMgPSByZXN1bHRbMV07XG4gICAgICAgICAgICAgICAgICAgIHNlY29uZHMgPSByZXN1bHRbMl07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKGxpbWl0TWF4SG91cnMpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1heFRpbWUgPSBzZWxmLmNvbmZpZy5tYXhUaW1lICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgID8gc2VsZi5jb25maWcubWF4VGltZVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBzZWxmLmNvbmZpZy5tYXhEYXRlO1xuICAgICAgICAgICAgICAgICAgICBob3VycyA9IE1hdGgubWluKGhvdXJzLCBtYXhUaW1lLmdldEhvdXJzKCkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaG91cnMgPT09IG1heFRpbWUuZ2V0SG91cnMoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbnV0ZXMgPSBNYXRoLm1pbihtaW51dGVzLCBtYXhUaW1lLmdldE1pbnV0ZXMoKSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChtaW51dGVzID09PSBtYXhUaW1lLmdldE1pbnV0ZXMoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlY29uZHMgPSBNYXRoLm1pbihzZWNvbmRzLCBtYXhUaW1lLmdldFNlY29uZHMoKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChsaW1pdE1pbkhvdXJzKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBtaW5UaW1lID0gc2VsZi5jb25maWcubWluVGltZSAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICA/IHNlbGYuY29uZmlnLm1pblRpbWVcbiAgICAgICAgICAgICAgICAgICAgICAgIDogc2VsZi5jb25maWcubWluRGF0ZTtcbiAgICAgICAgICAgICAgICAgICAgaG91cnMgPSBNYXRoLm1heChob3VycywgbWluVGltZS5nZXRIb3VycygpKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGhvdXJzID09PSBtaW5UaW1lLmdldEhvdXJzKCkgJiYgbWludXRlcyA8IG1pblRpbWUuZ2V0TWludXRlcygpKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWludXRlcyA9IG1pblRpbWUuZ2V0TWludXRlcygpO1xuICAgICAgICAgICAgICAgICAgICBpZiAobWludXRlcyA9PT0gbWluVGltZS5nZXRNaW51dGVzKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWNvbmRzID0gTWF0aC5tYXgoc2Vjb25kcywgbWluVGltZS5nZXRTZWNvbmRzKCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNldEhvdXJzKGhvdXJzLCBtaW51dGVzLCBzZWNvbmRzKTtcbiAgICAgICAgfVxuICAgICAgICAvKipcbiAgICAgICAgICogU3luY3MgdGltZSBpbnB1dCB2YWx1ZXMgd2l0aCBhIGRhdGVcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIHNldEhvdXJzRnJvbURhdGUoZGF0ZU9iaikge1xuICAgICAgICAgICAgdmFyIGRhdGUgPSBkYXRlT2JqIHx8IHNlbGYubGF0ZXN0U2VsZWN0ZWREYXRlT2JqO1xuICAgICAgICAgICAgaWYgKGRhdGUgJiYgZGF0ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgICAgICAgICBzZXRIb3VycyhkYXRlLmdldEhvdXJzKCksIGRhdGUuZ2V0TWludXRlcygpLCBkYXRlLmdldFNlY29uZHMoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNldHMgdGhlIGhvdXJzLCBtaW51dGVzLCBhbmQgb3B0aW9uYWxseSBzZWNvbmRzXG4gICAgICAgICAqIG9mIHRoZSBsYXRlc3Qgc2VsZWN0ZWQgZGF0ZSBvYmplY3QgYW5kIHRoZVxuICAgICAgICAgKiBjb3JyZXNwb25kaW5nIHRpbWUgaW5wdXRzXG4gICAgICAgICAqIEBwYXJhbSB7TnVtYmVyfSBob3VycyB0aGUgaG91ci4gd2hldGhlciBpdHMgbWlsaXRhcnlcbiAgICAgICAgICogICAgICAgICAgICAgICAgIG9yIGFtLXBtIGdldHMgaW5mZXJyZWQgZnJvbSBjb25maWdcbiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ9IG1pbnV0ZXMgdGhlIG1pbnV0ZXNcbiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlY29uZHMgdGhlIHNlY29uZHMgKG9wdGlvbmFsKVxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gc2V0SG91cnMoaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMpIHtcbiAgICAgICAgICAgIGlmIChzZWxmLmxhdGVzdFNlbGVjdGVkRGF0ZU9iaiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5sYXRlc3RTZWxlY3RlZERhdGVPYmouc2V0SG91cnMoaG91cnMgJSAyNCwgbWludXRlcywgc2Vjb25kcyB8fCAwLCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghc2VsZi5ob3VyRWxlbWVudCB8fCAhc2VsZi5taW51dGVFbGVtZW50IHx8IHNlbGYuaXNNb2JpbGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgc2VsZi5ob3VyRWxlbWVudC52YWx1ZSA9IHBhZCghc2VsZi5jb25maWcudGltZV8yNGhyXG4gICAgICAgICAgICAgICAgPyAoKDEyICsgaG91cnMpICUgMTIpICsgMTIgKiBpbnQoaG91cnMgJSAxMiA9PT0gMClcbiAgICAgICAgICAgICAgICA6IGhvdXJzKTtcbiAgICAgICAgICAgIHNlbGYubWludXRlRWxlbWVudC52YWx1ZSA9IHBhZChtaW51dGVzKTtcbiAgICAgICAgICAgIGlmIChzZWxmLmFtUE0gIT09IHVuZGVmaW5lZClcbiAgICAgICAgICAgICAgICBzZWxmLmFtUE0udGV4dENvbnRlbnQgPSBzZWxmLmwxMG4uYW1QTVtpbnQoaG91cnMgPj0gMTIpXTtcbiAgICAgICAgICAgIGlmIChzZWxmLnNlY29uZEVsZW1lbnQgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICAgICAgICBzZWxmLnNlY29uZEVsZW1lbnQudmFsdWUgPSBwYWQoc2Vjb25kcyk7XG4gICAgICAgIH1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEhhbmRsZXMgdGhlIHllYXIgaW5wdXQgYW5kIGluY3JlbWVudGluZyBldmVudHNcbiAgICAgICAgICogQHBhcmFtIHtFdmVudH0gZXZlbnQgdGhlIGtleXVwIG9yIGluY3JlbWVudCBldmVudFxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gb25ZZWFySW5wdXQoZXZlbnQpIHtcbiAgICAgICAgICAgIHZhciBldmVudFRhcmdldCA9IGdldEV2ZW50VGFyZ2V0KGV2ZW50KTtcbiAgICAgICAgICAgIHZhciB5ZWFyID0gcGFyc2VJbnQoZXZlbnRUYXJnZXQudmFsdWUpICsgKGV2ZW50LmRlbHRhIHx8IDApO1xuICAgICAgICAgICAgaWYgKHllYXIgLyAxMDAwID4gMSB8fFxuICAgICAgICAgICAgICAgIChldmVudC5rZXkgPT09IFwiRW50ZXJcIiAmJiAhL1teXFxkXS8udGVzdCh5ZWFyLnRvU3RyaW5nKCkpKSkge1xuICAgICAgICAgICAgICAgIGNoYW5nZVllYXIoeWVhcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVzc2VudGlhbGx5IGFkZEV2ZW50TGlzdGVuZXIgKyB0cmFja2luZ1xuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgdGhlIGVsZW1lbnQgdG8gYWRkRXZlbnRMaXN0ZW5lciB0b1xuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnQgdGhlIGV2ZW50IG5hbWVcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlciB0aGUgZXZlbnQgaGFuZGxlclxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gYmluZChlbGVtZW50LCBldmVudCwgaGFuZGxlciwgb3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKGV2ZW50IGluc3RhbmNlb2YgQXJyYXkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50LmZvckVhY2goZnVuY3Rpb24gKGV2KSB7IHJldHVybiBiaW5kKGVsZW1lbnQsIGV2LCBoYW5kbGVyLCBvcHRpb25zKTsgfSk7XG4gICAgICAgICAgICBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEFycmF5KVxuICAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50LmZvckVhY2goZnVuY3Rpb24gKGVsKSB7IHJldHVybiBiaW5kKGVsLCBldmVudCwgaGFuZGxlciwgb3B0aW9ucyk7IH0pO1xuICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCBoYW5kbGVyLCBvcHRpb25zKTtcbiAgICAgICAgICAgIHNlbGYuX2hhbmRsZXJzLnB1c2goe1xuICAgICAgICAgICAgICAgIHJlbW92ZTogZnVuY3Rpb24gKCkgeyByZXR1cm4gZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50LCBoYW5kbGVyLCBvcHRpb25zKTsgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHRyaWdnZXJDaGFuZ2UoKSB7XG4gICAgICAgICAgICB0cmlnZ2VyRXZlbnQoXCJvbkNoYW5nZVwiKTtcbiAgICAgICAgfVxuICAgICAgICAvKipcbiAgICAgICAgICogQWRkcyBhbGwgdGhlIG5lY2Vzc2FyeSBldmVudCBsaXN0ZW5lcnNcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGJpbmRFdmVudHMoKSB7XG4gICAgICAgICAgICBpZiAoc2VsZi5jb25maWcud3JhcCkge1xuICAgICAgICAgICAgICAgIFtcIm9wZW5cIiwgXCJjbG9zZVwiLCBcInRvZ2dsZVwiLCBcImNsZWFyXCJdLmZvckVhY2goZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICAgICAgICAgICAgICBBcnJheS5wcm90b3R5cGUuZm9yRWFjaC5jYWxsKHNlbGYuZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiW2RhdGEtXCIgKyBldnQgKyBcIl1cIiksIGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJpbmQoZWwsIFwiY2xpY2tcIiwgc2VsZltldnRdKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc2VsZi5pc01vYmlsZSkge1xuICAgICAgICAgICAgICAgIHNldHVwTW9iaWxlKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGRlYm91bmNlZFJlc2l6ZSA9IGRlYm91bmNlKG9uUmVzaXplLCA1MCk7XG4gICAgICAgICAgICBzZWxmLl9kZWJvdW5jZWRDaGFuZ2UgPSBkZWJvdW5jZSh0cmlnZ2VyQ2hhbmdlLCBERUJPVU5DRURfQ0hBTkdFX01TKTtcbiAgICAgICAgICAgIGlmIChzZWxmLmRheXNDb250YWluZXIgJiYgIS9pUGhvbmV8aVBhZHxpUG9kL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSlcbiAgICAgICAgICAgICAgICBiaW5kKHNlbGYuZGF5c0NvbnRhaW5lciwgXCJtb3VzZW92ZXJcIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLm1vZGUgPT09IFwicmFuZ2VcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uTW91c2VPdmVyKGdldEV2ZW50VGFyZ2V0KGUpKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGJpbmQoc2VsZi5faW5wdXQsIFwia2V5ZG93blwiLCBvbktleURvd24pO1xuICAgICAgICAgICAgaWYgKHNlbGYuY2FsZW5kYXJDb250YWluZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGJpbmQoc2VsZi5jYWxlbmRhckNvbnRhaW5lciwgXCJrZXlkb3duXCIsIG9uS2V5RG93bik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXNlbGYuY29uZmlnLmlubGluZSAmJiAhc2VsZi5jb25maWcuc3RhdGljKVxuICAgICAgICAgICAgICAgIGJpbmQod2luZG93LCBcInJlc2l6ZVwiLCBkZWJvdW5jZWRSZXNpemUpO1xuICAgICAgICAgICAgaWYgKHdpbmRvdy5vbnRvdWNoc3RhcnQgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICAgICAgICBiaW5kKHdpbmRvdy5kb2N1bWVudCwgXCJ0b3VjaHN0YXJ0XCIsIGRvY3VtZW50Q2xpY2spO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGJpbmQod2luZG93LmRvY3VtZW50LCBcIm1vdXNlZG93blwiLCBkb2N1bWVudENsaWNrKTtcbiAgICAgICAgICAgIGJpbmQod2luZG93LmRvY3VtZW50LCBcImZvY3VzXCIsIGRvY3VtZW50Q2xpY2ssIHsgY2FwdHVyZTogdHJ1ZSB9KTtcbiAgICAgICAgICAgIGlmIChzZWxmLmNvbmZpZy5jbGlja09wZW5zID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgYmluZChzZWxmLl9pbnB1dCwgXCJmb2N1c1wiLCBzZWxmLm9wZW4pO1xuICAgICAgICAgICAgICAgIGJpbmQoc2VsZi5faW5wdXQsIFwiY2xpY2tcIiwgc2VsZi5vcGVuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzZWxmLmRheXNDb250YWluZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGJpbmQoc2VsZi5tb250aE5hdiwgXCJjbGlja1wiLCBvbk1vbnRoTmF2Q2xpY2spO1xuICAgICAgICAgICAgICAgIGJpbmQoc2VsZi5tb250aE5hdiwgW1wia2V5dXBcIiwgXCJpbmNyZW1lbnRcIl0sIG9uWWVhcklucHV0KTtcbiAgICAgICAgICAgICAgICBiaW5kKHNlbGYuZGF5c0NvbnRhaW5lciwgXCJjbGlja1wiLCBzZWxlY3REYXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzZWxmLnRpbWVDb250YWluZXIgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgICAgIHNlbGYubWludXRlRWxlbWVudCAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgICAgICAgc2VsZi5ob3VyRWxlbWVudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdmFyIHNlbFRleHQgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0RXZlbnRUYXJnZXQoZSkuc2VsZWN0KCk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBiaW5kKHNlbGYudGltZUNvbnRhaW5lciwgW1wiaW5jcmVtZW50XCJdLCB1cGRhdGVUaW1lKTtcbiAgICAgICAgICAgICAgICBiaW5kKHNlbGYudGltZUNvbnRhaW5lciwgXCJibHVyXCIsIHVwZGF0ZVRpbWUsIHsgY2FwdHVyZTogdHJ1ZSB9KTtcbiAgICAgICAgICAgICAgICBiaW5kKHNlbGYudGltZUNvbnRhaW5lciwgXCJjbGlja1wiLCB0aW1lSW5jcmVtZW50KTtcbiAgICAgICAgICAgICAgICBiaW5kKFtzZWxmLmhvdXJFbGVtZW50LCBzZWxmLm1pbnV0ZUVsZW1lbnRdLCBbXCJmb2N1c1wiLCBcImNsaWNrXCJdLCBzZWxUZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5zZWNvbmRFbGVtZW50ICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgICAgICAgICAgIGJpbmQoc2VsZi5zZWNvbmRFbGVtZW50LCBcImZvY3VzXCIsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNlbGYuc2Vjb25kRWxlbWVudCAmJiBzZWxmLnNlY29uZEVsZW1lbnQuc2VsZWN0KCk7IH0pO1xuICAgICAgICAgICAgICAgIGlmIChzZWxmLmFtUE0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBiaW5kKHNlbGYuYW1QTSwgXCJjbGlja1wiLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlVGltZShlKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLmFsbG93SW5wdXQpIHtcbiAgICAgICAgICAgICAgICBiaW5kKHNlbGYuX2lucHV0LCBcImJsdXJcIiwgb25CbHVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvKipcbiAgICAgICAgICogU2V0IHRoZSBjYWxlbmRhciB2aWV3IHRvIGEgcGFydGljdWxhciBkYXRlLlxuICAgICAgICAgKiBAcGFyYW0ge0RhdGV9IGp1bXBEYXRlIHRoZSBkYXRlIHRvIHNldCB0aGUgdmlldyB0b1xuICAgICAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHRyaWdnZXJDaGFuZ2UgaWYgY2hhbmdlIGV2ZW50cyBzaG91bGQgYmUgdHJpZ2dlcmVkXG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBqdW1wVG9EYXRlKGp1bXBEYXRlLCB0cmlnZ2VyQ2hhbmdlKSB7XG4gICAgICAgICAgICB2YXIganVtcFRvID0ganVtcERhdGUgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgID8gc2VsZi5wYXJzZURhdGUoanVtcERhdGUpXG4gICAgICAgICAgICAgICAgOiBzZWxmLmxhdGVzdFNlbGVjdGVkRGF0ZU9iaiB8fFxuICAgICAgICAgICAgICAgICAgICAoc2VsZi5jb25maWcubWluRGF0ZSAmJiBzZWxmLmNvbmZpZy5taW5EYXRlID4gc2VsZi5ub3dcbiAgICAgICAgICAgICAgICAgICAgICAgID8gc2VsZi5jb25maWcubWluRGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBzZWxmLmNvbmZpZy5tYXhEYXRlICYmIHNlbGYuY29uZmlnLm1heERhdGUgPCBzZWxmLm5vd1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gc2VsZi5jb25maWcubWF4RGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogc2VsZi5ub3cpO1xuICAgICAgICAgICAgdmFyIG9sZFllYXIgPSBzZWxmLmN1cnJlbnRZZWFyO1xuICAgICAgICAgICAgdmFyIG9sZE1vbnRoID0gc2VsZi5jdXJyZW50TW9udGg7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmIChqdW1wVG8gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLmN1cnJlbnRZZWFyID0ganVtcFRvLmdldEZ1bGxZZWFyKCk7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuY3VycmVudE1vbnRoID0ganVtcFRvLmdldE1vbnRoKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICAgICAgICAgIGUubWVzc2FnZSA9IFwiSW52YWxpZCBkYXRlIHN1cHBsaWVkOiBcIiArIGp1bXBUbztcbiAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZy5lcnJvckhhbmRsZXIoZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHJpZ2dlckNoYW5nZSAmJiBzZWxmLmN1cnJlbnRZZWFyICE9PSBvbGRZZWFyKSB7XG4gICAgICAgICAgICAgICAgdHJpZ2dlckV2ZW50KFwib25ZZWFyQ2hhbmdlXCIpO1xuICAgICAgICAgICAgICAgIGJ1aWxkTW9udGhTd2l0Y2goKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0cmlnZ2VyQ2hhbmdlICYmXG4gICAgICAgICAgICAgICAgKHNlbGYuY3VycmVudFllYXIgIT09IG9sZFllYXIgfHwgc2VsZi5jdXJyZW50TW9udGggIT09IG9sZE1vbnRoKSkge1xuICAgICAgICAgICAgICAgIHRyaWdnZXJFdmVudChcIm9uTW9udGhDaGFuZ2VcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZWxmLnJlZHJhdygpO1xuICAgICAgICB9XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdXAvZG93biBhcnJvdyBoYW5kbGVyIGZvciB0aW1lIGlucHV0c1xuICAgICAgICAgKiBAcGFyYW0ge0V2ZW50fSBlIHRoZSBjbGljayBldmVudFxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gdGltZUluY3JlbWVudChlKSB7XG4gICAgICAgICAgICB2YXIgZXZlbnRUYXJnZXQgPSBnZXRFdmVudFRhcmdldChlKTtcbiAgICAgICAgICAgIGlmICh+ZXZlbnRUYXJnZXQuY2xhc3NOYW1lLmluZGV4T2YoXCJhcnJvd1wiKSlcbiAgICAgICAgICAgICAgICBpbmNyZW1lbnROdW1JbnB1dChlLCBldmVudFRhcmdldC5jbGFzc0xpc3QuY29udGFpbnMoXCJhcnJvd1VwXCIpID8gMSA6IC0xKTtcbiAgICAgICAgfVxuICAgICAgICAvKipcbiAgICAgICAgICogSW5jcmVtZW50cy9kZWNyZW1lbnRzIHRoZSB2YWx1ZSBvZiBpbnB1dCBhc3NvY2ktXG4gICAgICAgICAqIGF0ZWQgd2l0aCB0aGUgdXAvZG93biBhcnJvdyBieSBkaXNwYXRjaGluZyBhblxuICAgICAgICAgKiBcImluY3JlbWVudFwiIGV2ZW50IG9uIHRoZSBpbnB1dC5cbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHtFdmVudH0gZSB0aGUgY2xpY2sgZXZlbnRcbiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ9IGRlbHRhIHRoZSBkaWZmICh1c3VhbGx5IDEgb3IgLTEpXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gaW5wdXRFbGVtIHRoZSBpbnB1dCBlbGVtZW50XG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBpbmNyZW1lbnROdW1JbnB1dChlLCBkZWx0YSwgaW5wdXRFbGVtKSB7XG4gICAgICAgICAgICB2YXIgdGFyZ2V0ID0gZSAmJiBnZXRFdmVudFRhcmdldChlKTtcbiAgICAgICAgICAgIHZhciBpbnB1dCA9IGlucHV0RWxlbSB8fFxuICAgICAgICAgICAgICAgICh0YXJnZXQgJiYgdGFyZ2V0LnBhcmVudE5vZGUgJiYgdGFyZ2V0LnBhcmVudE5vZGUuZmlyc3RDaGlsZCk7XG4gICAgICAgICAgICB2YXIgZXZlbnQgPSBjcmVhdGVFdmVudChcImluY3JlbWVudFwiKTtcbiAgICAgICAgICAgIGV2ZW50LmRlbHRhID0gZGVsdGE7XG4gICAgICAgICAgICBpbnB1dCAmJiBpbnB1dC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBidWlsZCgpIHtcbiAgICAgICAgICAgIHZhciBmcmFnbWVudCA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG4gICAgICAgICAgICBzZWxmLmNhbGVuZGFyQ29udGFpbmVyID0gY3JlYXRlRWxlbWVudChcImRpdlwiLCBcImZsYXRwaWNrci1jYWxlbmRhclwiKTtcbiAgICAgICAgICAgIHNlbGYuY2FsZW5kYXJDb250YWluZXIudGFiSW5kZXggPSAtMTtcbiAgICAgICAgICAgIGlmICghc2VsZi5jb25maWcubm9DYWxlbmRhcikge1xuICAgICAgICAgICAgICAgIGZyYWdtZW50LmFwcGVuZENoaWxkKGJ1aWxkTW9udGhOYXYoKSk7XG4gICAgICAgICAgICAgICAgc2VsZi5pbm5lckNvbnRhaW5lciA9IGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgXCJmbGF0cGlja3ItaW5uZXJDb250YWluZXJcIik7XG4gICAgICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLndlZWtOdW1iZXJzKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBfYSA9IGJ1aWxkV2Vla3MoKSwgd2Vla1dyYXBwZXIgPSBfYS53ZWVrV3JhcHBlciwgd2Vla051bWJlcnMgPSBfYS53ZWVrTnVtYmVycztcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5pbm5lckNvbnRhaW5lci5hcHBlbmRDaGlsZCh3ZWVrV3JhcHBlcik7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYud2Vla051bWJlcnMgPSB3ZWVrTnVtYmVycztcbiAgICAgICAgICAgICAgICAgICAgc2VsZi53ZWVrV3JhcHBlciA9IHdlZWtXcmFwcGVyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzZWxmLnJDb250YWluZXIgPSBjcmVhdGVFbGVtZW50KFwiZGl2XCIsIFwiZmxhdHBpY2tyLXJDb250YWluZXJcIik7XG4gICAgICAgICAgICAgICAgc2VsZi5yQ29udGFpbmVyLmFwcGVuZENoaWxkKGJ1aWxkV2Vla2RheXMoKSk7XG4gICAgICAgICAgICAgICAgaWYgKCFzZWxmLmRheXNDb250YWluZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5kYXlzQ29udGFpbmVyID0gY3JlYXRlRWxlbWVudChcImRpdlwiLCBcImZsYXRwaWNrci1kYXlzXCIpO1xuICAgICAgICAgICAgICAgICAgICBzZWxmLmRheXNDb250YWluZXIudGFiSW5kZXggPSAtMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnVpbGREYXlzKCk7XG4gICAgICAgICAgICAgICAgc2VsZi5yQ29udGFpbmVyLmFwcGVuZENoaWxkKHNlbGYuZGF5c0NvbnRhaW5lcik7XG4gICAgICAgICAgICAgICAgc2VsZi5pbm5lckNvbnRhaW5lci5hcHBlbmRDaGlsZChzZWxmLnJDb250YWluZXIpO1xuICAgICAgICAgICAgICAgIGZyYWdtZW50LmFwcGVuZENoaWxkKHNlbGYuaW5uZXJDb250YWluZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLmVuYWJsZVRpbWUpIHtcbiAgICAgICAgICAgICAgICBmcmFnbWVudC5hcHBlbmRDaGlsZChidWlsZFRpbWUoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0b2dnbGVDbGFzcyhzZWxmLmNhbGVuZGFyQ29udGFpbmVyLCBcInJhbmdlTW9kZVwiLCBzZWxmLmNvbmZpZy5tb2RlID09PSBcInJhbmdlXCIpO1xuICAgICAgICAgICAgdG9nZ2xlQ2xhc3Moc2VsZi5jYWxlbmRhckNvbnRhaW5lciwgXCJhbmltYXRlXCIsIHNlbGYuY29uZmlnLmFuaW1hdGUgPT09IHRydWUpO1xuICAgICAgICAgICAgdG9nZ2xlQ2xhc3Moc2VsZi5jYWxlbmRhckNvbnRhaW5lciwgXCJtdWx0aU1vbnRoXCIsIHNlbGYuY29uZmlnLnNob3dNb250aHMgPiAxKTtcbiAgICAgICAgICAgIHNlbGYuY2FsZW5kYXJDb250YWluZXIuYXBwZW5kQ2hpbGQoZnJhZ21lbnQpO1xuICAgICAgICAgICAgdmFyIGN1c3RvbUFwcGVuZCA9IHNlbGYuY29uZmlnLmFwcGVuZFRvICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZy5hcHBlbmRUby5ub2RlVHlwZSAhPT0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLmlubGluZSB8fCBzZWxmLmNvbmZpZy5zdGF0aWMpIHtcbiAgICAgICAgICAgICAgICBzZWxmLmNhbGVuZGFyQ29udGFpbmVyLmNsYXNzTGlzdC5hZGQoc2VsZi5jb25maWcuaW5saW5lID8gXCJpbmxpbmVcIiA6IFwic3RhdGljXCIpO1xuICAgICAgICAgICAgICAgIGlmIChzZWxmLmNvbmZpZy5pbmxpbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjdXN0b21BcHBlbmQgJiYgc2VsZi5lbGVtZW50LnBhcmVudE5vZGUpXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmVsZW1lbnQucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoc2VsZi5jYWxlbmRhckNvbnRhaW5lciwgc2VsZi5faW5wdXQubmV4dFNpYmxpbmcpO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChzZWxmLmNvbmZpZy5hcHBlbmRUbyAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5jb25maWcuYXBwZW5kVG8uYXBwZW5kQ2hpbGQoc2VsZi5jYWxlbmRhckNvbnRhaW5lcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzZWxmLmNvbmZpZy5zdGF0aWMpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdyYXBwZXIgPSBjcmVhdGVFbGVtZW50KFwiZGl2XCIsIFwiZmxhdHBpY2tyLXdyYXBwZXJcIik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLmVsZW1lbnQucGFyZW50Tm9kZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZWxlbWVudC5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh3cmFwcGVyLCBzZWxmLmVsZW1lbnQpO1xuICAgICAgICAgICAgICAgICAgICB3cmFwcGVyLmFwcGVuZENoaWxkKHNlbGYuZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLmFsdElucHV0KVxuICAgICAgICAgICAgICAgICAgICAgICAgd3JhcHBlci5hcHBlbmRDaGlsZChzZWxmLmFsdElucHV0KTtcbiAgICAgICAgICAgICAgICAgICAgd3JhcHBlci5hcHBlbmRDaGlsZChzZWxmLmNhbGVuZGFyQ29udGFpbmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXNlbGYuY29uZmlnLnN0YXRpYyAmJiAhc2VsZi5jb25maWcuaW5saW5lKVxuICAgICAgICAgICAgICAgIChzZWxmLmNvbmZpZy5hcHBlbmRUbyAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gc2VsZi5jb25maWcuYXBwZW5kVG9cbiAgICAgICAgICAgICAgICAgICAgOiB3aW5kb3cuZG9jdW1lbnQuYm9keSkuYXBwZW5kQ2hpbGQoc2VsZi5jYWxlbmRhckNvbnRhaW5lcik7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gY3JlYXRlRGF5KGNsYXNzTmFtZSwgZGF0ZSwgX2RheU51bWJlciwgaSkge1xuICAgICAgICAgICAgdmFyIGRhdGVJc0VuYWJsZWQgPSBpc0VuYWJsZWQoZGF0ZSwgdHJ1ZSksIGRheUVsZW1lbnQgPSBjcmVhdGVFbGVtZW50KFwic3BhblwiLCBjbGFzc05hbWUsIGRhdGUuZ2V0RGF0ZSgpLnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgZGF5RWxlbWVudC5kYXRlT2JqID0gZGF0ZTtcbiAgICAgICAgICAgIGRheUVsZW1lbnQuJGkgPSBpO1xuICAgICAgICAgICAgZGF5RWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJhcmlhLWxhYmVsXCIsIHNlbGYuZm9ybWF0RGF0ZShkYXRlLCBzZWxmLmNvbmZpZy5hcmlhRGF0ZUZvcm1hdCkpO1xuICAgICAgICAgICAgaWYgKGNsYXNzTmFtZS5pbmRleE9mKFwiaGlkZGVuXCIpID09PSAtMSAmJlxuICAgICAgICAgICAgICAgIGNvbXBhcmVEYXRlcyhkYXRlLCBzZWxmLm5vdykgPT09IDApIHtcbiAgICAgICAgICAgICAgICBzZWxmLnRvZGF5RGF0ZUVsZW0gPSBkYXlFbGVtZW50O1xuICAgICAgICAgICAgICAgIGRheUVsZW1lbnQuY2xhc3NMaXN0LmFkZChcInRvZGF5XCIpO1xuICAgICAgICAgICAgICAgIGRheUVsZW1lbnQuc2V0QXR0cmlidXRlKFwiYXJpYS1jdXJyZW50XCIsIFwiZGF0ZVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkYXRlSXNFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgZGF5RWxlbWVudC50YWJJbmRleCA9IC0xO1xuICAgICAgICAgICAgICAgIGlmIChpc0RhdGVTZWxlY3RlZChkYXRlKSkge1xuICAgICAgICAgICAgICAgICAgICBkYXlFbGVtZW50LmNsYXNzTGlzdC5hZGQoXCJzZWxlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZWxlY3RlZERhdGVFbGVtID0gZGF5RWxlbWVudDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLm1vZGUgPT09IFwicmFuZ2VcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG9nZ2xlQ2xhc3MoZGF5RWxlbWVudCwgXCJzdGFydFJhbmdlXCIsIHNlbGYuc2VsZWN0ZWREYXRlc1swXSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBhcmVEYXRlcyhkYXRlLCBzZWxmLnNlbGVjdGVkRGF0ZXNbMF0sIHRydWUpID09PSAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvZ2dsZUNsYXNzKGRheUVsZW1lbnQsIFwiZW5kUmFuZ2VcIiwgc2VsZi5zZWxlY3RlZERhdGVzWzFdICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcGFyZURhdGVzKGRhdGUsIHNlbGYuc2VsZWN0ZWREYXRlc1sxXSwgdHJ1ZSkgPT09IDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PT0gXCJuZXh0TW9udGhEYXlcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXlFbGVtZW50LmNsYXNzTGlzdC5hZGQoXCJpblJhbmdlXCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZGF5RWxlbWVudC5jbGFzc0xpc3QuYWRkKFwiZmxhdHBpY2tyLWRpc2FibGVkXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLm1vZGUgPT09IFwicmFuZ2VcIikge1xuICAgICAgICAgICAgICAgIGlmIChpc0RhdGVJblJhbmdlKGRhdGUpICYmICFpc0RhdGVTZWxlY3RlZChkYXRlKSlcbiAgICAgICAgICAgICAgICAgICAgZGF5RWxlbWVudC5jbGFzc0xpc3QuYWRkKFwiaW5SYW5nZVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzZWxmLndlZWtOdW1iZXJzICYmXG4gICAgICAgICAgICAgICAgc2VsZi5jb25maWcuc2hvd01vbnRocyA9PT0gMSAmJlxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZSAhPT0gXCJwcmV2TW9udGhEYXlcIiAmJlxuICAgICAgICAgICAgICAgIGkgJSA3ID09PSA2KSB7XG4gICAgICAgICAgICAgICAgc2VsZi53ZWVrTnVtYmVycy5pbnNlcnRBZGphY2VudEhUTUwoXCJiZWZvcmVlbmRcIiwgXCI8c3BhbiBjbGFzcz0nZmxhdHBpY2tyLWRheSc+XCIgKyBzZWxmLmNvbmZpZy5nZXRXZWVrKGRhdGUpICsgXCI8L3NwYW4+XCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdHJpZ2dlckV2ZW50KFwib25EYXlDcmVhdGVcIiwgZGF5RWxlbWVudCk7XG4gICAgICAgICAgICByZXR1cm4gZGF5RWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBmb2N1c09uRGF5RWxlbSh0YXJnZXROb2RlKSB7XG4gICAgICAgICAgICB0YXJnZXROb2RlLmZvY3VzKCk7XG4gICAgICAgICAgICBpZiAoc2VsZi5jb25maWcubW9kZSA9PT0gXCJyYW5nZVwiKVxuICAgICAgICAgICAgICAgIG9uTW91c2VPdmVyKHRhcmdldE5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGdldEZpcnN0QXZhaWxhYmxlRGF5KGRlbHRhKSB7XG4gICAgICAgICAgICB2YXIgc3RhcnRNb250aCA9IGRlbHRhID4gMCA/IDAgOiBzZWxmLmNvbmZpZy5zaG93TW9udGhzIC0gMTtcbiAgICAgICAgICAgIHZhciBlbmRNb250aCA9IGRlbHRhID4gMCA/IHNlbGYuY29uZmlnLnNob3dNb250aHMgOiAtMTtcbiAgICAgICAgICAgIGZvciAodmFyIG0gPSBzdGFydE1vbnRoOyBtICE9IGVuZE1vbnRoOyBtICs9IGRlbHRhKSB7XG4gICAgICAgICAgICAgICAgdmFyIG1vbnRoID0gc2VsZi5kYXlzQ29udGFpbmVyLmNoaWxkcmVuW21dO1xuICAgICAgICAgICAgICAgIHZhciBzdGFydEluZGV4ID0gZGVsdGEgPiAwID8gMCA6IG1vbnRoLmNoaWxkcmVuLmxlbmd0aCAtIDE7XG4gICAgICAgICAgICAgICAgdmFyIGVuZEluZGV4ID0gZGVsdGEgPiAwID8gbW9udGguY2hpbGRyZW4ubGVuZ3RoIDogLTE7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IHN0YXJ0SW5kZXg7IGkgIT0gZW5kSW5kZXg7IGkgKz0gZGVsdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGMgPSBtb250aC5jaGlsZHJlbltpXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGMuY2xhc3NOYW1lLmluZGV4T2YoXCJoaWRkZW5cIikgPT09IC0xICYmIGlzRW5hYmxlZChjLmRhdGVPYmopKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBnZXROZXh0QXZhaWxhYmxlRGF5KGN1cnJlbnQsIGRlbHRhKSB7XG4gICAgICAgICAgICB2YXIgZ2l2ZW5Nb250aCA9IGN1cnJlbnQuY2xhc3NOYW1lLmluZGV4T2YoXCJNb250aFwiKSA9PT0gLTFcbiAgICAgICAgICAgICAgICA/IGN1cnJlbnQuZGF0ZU9iai5nZXRNb250aCgpXG4gICAgICAgICAgICAgICAgOiBzZWxmLmN1cnJlbnRNb250aDtcbiAgICAgICAgICAgIHZhciBlbmRNb250aCA9IGRlbHRhID4gMCA/IHNlbGYuY29uZmlnLnNob3dNb250aHMgOiAtMTtcbiAgICAgICAgICAgIHZhciBsb29wRGVsdGEgPSBkZWx0YSA+IDAgPyAxIDogLTE7XG4gICAgICAgICAgICBmb3IgKHZhciBtID0gZ2l2ZW5Nb250aCAtIHNlbGYuY3VycmVudE1vbnRoOyBtICE9IGVuZE1vbnRoOyBtICs9IGxvb3BEZWx0YSkge1xuICAgICAgICAgICAgICAgIHZhciBtb250aCA9IHNlbGYuZGF5c0NvbnRhaW5lci5jaGlsZHJlblttXTtcbiAgICAgICAgICAgICAgICB2YXIgc3RhcnRJbmRleCA9IGdpdmVuTW9udGggLSBzZWxmLmN1cnJlbnRNb250aCA9PT0gbVxuICAgICAgICAgICAgICAgICAgICA/IGN1cnJlbnQuJGkgKyBkZWx0YVxuICAgICAgICAgICAgICAgICAgICA6IGRlbHRhIDwgMFxuICAgICAgICAgICAgICAgICAgICAgICAgPyBtb250aC5jaGlsZHJlbi5sZW5ndGggLSAxXG4gICAgICAgICAgICAgICAgICAgICAgICA6IDA7XG4gICAgICAgICAgICAgICAgdmFyIG51bU1vbnRoRGF5cyA9IG1vbnRoLmNoaWxkcmVuLmxlbmd0aDtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gc3RhcnRJbmRleDsgaSA+PSAwICYmIGkgPCBudW1Nb250aERheXMgJiYgaSAhPSAoZGVsdGEgPiAwID8gbnVtTW9udGhEYXlzIDogLTEpOyBpICs9IGxvb3BEZWx0YSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgYyA9IG1vbnRoLmNoaWxkcmVuW2ldO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYy5jbGFzc05hbWUuaW5kZXhPZihcImhpZGRlblwiKSA9PT0gLTEgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzRW5hYmxlZChjLmRhdGVPYmopICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBNYXRoLmFicyhjdXJyZW50LiRpIC0gaSkgPj0gTWF0aC5hYnMoZGVsdGEpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZvY3VzT25EYXlFbGVtKGMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNlbGYuY2hhbmdlTW9udGgobG9vcERlbHRhKTtcbiAgICAgICAgICAgIGZvY3VzT25EYXkoZ2V0Rmlyc3RBdmFpbGFibGVEYXkobG9vcERlbHRhKSwgMCk7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGZvY3VzT25EYXkoY3VycmVudCwgb2Zmc2V0KSB7XG4gICAgICAgICAgICB2YXIgYWN0aXZlRWxlbWVudCA9IGdldENsb3Nlc3RBY3RpdmVFbGVtZW50KCk7XG4gICAgICAgICAgICB2YXIgZGF5Rm9jdXNlZCA9IGlzSW5WaWV3KGFjdGl2ZUVsZW1lbnQgfHwgZG9jdW1lbnQuYm9keSk7XG4gICAgICAgICAgICB2YXIgc3RhcnRFbGVtID0gY3VycmVudCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgPyBjdXJyZW50XG4gICAgICAgICAgICAgICAgOiBkYXlGb2N1c2VkXG4gICAgICAgICAgICAgICAgICAgID8gYWN0aXZlRWxlbWVudFxuICAgICAgICAgICAgICAgICAgICA6IHNlbGYuc2VsZWN0ZWREYXRlRWxlbSAhPT0gdW5kZWZpbmVkICYmIGlzSW5WaWV3KHNlbGYuc2VsZWN0ZWREYXRlRWxlbSlcbiAgICAgICAgICAgICAgICAgICAgICAgID8gc2VsZi5zZWxlY3RlZERhdGVFbGVtXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHNlbGYudG9kYXlEYXRlRWxlbSAhPT0gdW5kZWZpbmVkICYmIGlzSW5WaWV3KHNlbGYudG9kYXlEYXRlRWxlbSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHNlbGYudG9kYXlEYXRlRWxlbVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZ2V0Rmlyc3RBdmFpbGFibGVEYXkob2Zmc2V0ID4gMCA/IDEgOiAtMSk7XG4gICAgICAgICAgICBpZiAoc3RhcnRFbGVtID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBzZWxmLl9pbnB1dC5mb2N1cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIWRheUZvY3VzZWQpIHtcbiAgICAgICAgICAgICAgICBmb2N1c09uRGF5RWxlbShzdGFydEVsZW0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZ2V0TmV4dEF2YWlsYWJsZURheShzdGFydEVsZW0sIG9mZnNldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gYnVpbGRNb250aERheXMoeWVhciwgbW9udGgpIHtcbiAgICAgICAgICAgIHZhciBmaXJzdE9mTW9udGggPSAobmV3IERhdGUoeWVhciwgbW9udGgsIDEpLmdldERheSgpIC0gc2VsZi5sMTBuLmZpcnN0RGF5T2ZXZWVrICsgNykgJSA3O1xuICAgICAgICAgICAgdmFyIHByZXZNb250aERheXMgPSBzZWxmLnV0aWxzLmdldERheXNJbk1vbnRoKChtb250aCAtIDEgKyAxMikgJSAxMiwgeWVhcik7XG4gICAgICAgICAgICB2YXIgZGF5c0luTW9udGggPSBzZWxmLnV0aWxzLmdldERheXNJbk1vbnRoKG1vbnRoLCB5ZWFyKSwgZGF5cyA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksIGlzTXVsdGlNb250aCA9IHNlbGYuY29uZmlnLnNob3dNb250aHMgPiAxLCBwcmV2TW9udGhEYXlDbGFzcyA9IGlzTXVsdGlNb250aCA/IFwicHJldk1vbnRoRGF5IGhpZGRlblwiIDogXCJwcmV2TW9udGhEYXlcIiwgbmV4dE1vbnRoRGF5Q2xhc3MgPSBpc011bHRpTW9udGggPyBcIm5leHRNb250aERheSBoaWRkZW5cIiA6IFwibmV4dE1vbnRoRGF5XCI7XG4gICAgICAgICAgICB2YXIgZGF5TnVtYmVyID0gcHJldk1vbnRoRGF5cyArIDEgLSBmaXJzdE9mTW9udGgsIGRheUluZGV4ID0gMDtcbiAgICAgICAgICAgIC8vIHByZXBlbmQgZGF5cyBmcm9tIHRoZSBlbmRpbmcgb2YgcHJldmlvdXMgbW9udGhcbiAgICAgICAgICAgIGZvciAoOyBkYXlOdW1iZXIgPD0gcHJldk1vbnRoRGF5czsgZGF5TnVtYmVyKyssIGRheUluZGV4KyspIHtcbiAgICAgICAgICAgICAgICBkYXlzLmFwcGVuZENoaWxkKGNyZWF0ZURheShcImZsYXRwaWNrci1kYXkgXCIgKyBwcmV2TW9udGhEYXlDbGFzcywgbmV3IERhdGUoeWVhciwgbW9udGggLSAxLCBkYXlOdW1iZXIpLCBkYXlOdW1iZXIsIGRheUluZGV4KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBTdGFydCBhdCAxIHNpbmNlIHRoZXJlIGlzIG5vIDB0aCBkYXlcbiAgICAgICAgICAgIGZvciAoZGF5TnVtYmVyID0gMTsgZGF5TnVtYmVyIDw9IGRheXNJbk1vbnRoOyBkYXlOdW1iZXIrKywgZGF5SW5kZXgrKykge1xuICAgICAgICAgICAgICAgIGRheXMuYXBwZW5kQ2hpbGQoY3JlYXRlRGF5KFwiZmxhdHBpY2tyLWRheVwiLCBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgZGF5TnVtYmVyKSwgZGF5TnVtYmVyLCBkYXlJbmRleCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gYXBwZW5kIGRheXMgZnJvbSB0aGUgbmV4dCBtb250aFxuICAgICAgICAgICAgZm9yICh2YXIgZGF5TnVtID0gZGF5c0luTW9udGggKyAxOyBkYXlOdW0gPD0gNDIgLSBmaXJzdE9mTW9udGggJiZcbiAgICAgICAgICAgICAgICAoc2VsZi5jb25maWcuc2hvd01vbnRocyA9PT0gMSB8fCBkYXlJbmRleCAlIDcgIT09IDApOyBkYXlOdW0rKywgZGF5SW5kZXgrKykge1xuICAgICAgICAgICAgICAgIGRheXMuYXBwZW5kQ2hpbGQoY3JlYXRlRGF5KFwiZmxhdHBpY2tyLWRheSBcIiArIG5leHRNb250aERheUNsYXNzLCBuZXcgRGF0ZSh5ZWFyLCBtb250aCArIDEsIGRheU51bSAlIGRheXNJbk1vbnRoKSwgZGF5TnVtLCBkYXlJbmRleCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy91cGRhdGVOYXZpZ2F0aW9uQ3VycmVudE1vbnRoKCk7XG4gICAgICAgICAgICB2YXIgZGF5Q29udGFpbmVyID0gY3JlYXRlRWxlbWVudChcImRpdlwiLCBcImRheUNvbnRhaW5lclwiKTtcbiAgICAgICAgICAgIGRheUNvbnRhaW5lci5hcHBlbmRDaGlsZChkYXlzKTtcbiAgICAgICAgICAgIHJldHVybiBkYXlDb250YWluZXI7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gYnVpbGREYXlzKCkge1xuICAgICAgICAgICAgaWYgKHNlbGYuZGF5c0NvbnRhaW5lciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2xlYXJOb2RlKHNlbGYuZGF5c0NvbnRhaW5lcik7XG4gICAgICAgICAgICAvLyBUT0RPOiB3ZWVrIG51bWJlcnMgZm9yIGVhY2ggbW9udGhcbiAgICAgICAgICAgIGlmIChzZWxmLndlZWtOdW1iZXJzKVxuICAgICAgICAgICAgICAgIGNsZWFyTm9kZShzZWxmLndlZWtOdW1iZXJzKTtcbiAgICAgICAgICAgIHZhciBmcmFnID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZWxmLmNvbmZpZy5zaG93TW9udGhzOyBpKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgZCA9IG5ldyBEYXRlKHNlbGYuY3VycmVudFllYXIsIHNlbGYuY3VycmVudE1vbnRoLCAxKTtcbiAgICAgICAgICAgICAgICBkLnNldE1vbnRoKHNlbGYuY3VycmVudE1vbnRoICsgaSk7XG4gICAgICAgICAgICAgICAgZnJhZy5hcHBlbmRDaGlsZChidWlsZE1vbnRoRGF5cyhkLmdldEZ1bGxZZWFyKCksIGQuZ2V0TW9udGgoKSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2VsZi5kYXlzQ29udGFpbmVyLmFwcGVuZENoaWxkKGZyYWcpO1xuICAgICAgICAgICAgc2VsZi5kYXlzID0gc2VsZi5kYXlzQ29udGFpbmVyLmZpcnN0Q2hpbGQ7XG4gICAgICAgICAgICBpZiAoc2VsZi5jb25maWcubW9kZSA9PT0gXCJyYW5nZVwiICYmIHNlbGYuc2VsZWN0ZWREYXRlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICBvbk1vdXNlT3ZlcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGJ1aWxkTW9udGhTd2l0Y2goKSB7XG4gICAgICAgICAgICBpZiAoc2VsZi5jb25maWcuc2hvd01vbnRocyA+IDEgfHxcbiAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZy5tb250aFNlbGVjdG9yVHlwZSAhPT0gXCJkcm9wZG93blwiKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIHZhciBzaG91bGRCdWlsZE1vbnRoID0gZnVuY3Rpb24gKG1vbnRoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLm1pbkRhdGUgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgICAgICAgICBzZWxmLmN1cnJlbnRZZWFyID09PSBzZWxmLmNvbmZpZy5taW5EYXRlLmdldEZ1bGxZZWFyKCkgJiZcbiAgICAgICAgICAgICAgICAgICAgbW9udGggPCBzZWxmLmNvbmZpZy5taW5EYXRlLmdldE1vbnRoKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gIShzZWxmLmNvbmZpZy5tYXhEYXRlICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5jdXJyZW50WWVhciA9PT0gc2VsZi5jb25maWcubWF4RGF0ZS5nZXRGdWxsWWVhcigpICYmXG4gICAgICAgICAgICAgICAgICAgIG1vbnRoID4gc2VsZi5jb25maWcubWF4RGF0ZS5nZXRNb250aCgpKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBzZWxmLm1vbnRoc0Ryb3Bkb3duQ29udGFpbmVyLnRhYkluZGV4ID0gLTE7XG4gICAgICAgICAgICBzZWxmLm1vbnRoc0Ryb3Bkb3duQ29udGFpbmVyLmlubmVySFRNTCA9IFwiXCI7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDEyOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoIXNob3VsZEJ1aWxkTW9udGgoaSkpXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIHZhciBtb250aCA9IGNyZWF0ZUVsZW1lbnQoXCJvcHRpb25cIiwgXCJmbGF0cGlja3ItbW9udGhEcm9wZG93bi1tb250aFwiKTtcbiAgICAgICAgICAgICAgICBtb250aC52YWx1ZSA9IG5ldyBEYXRlKHNlbGYuY3VycmVudFllYXIsIGkpLmdldE1vbnRoKCkudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICBtb250aC50ZXh0Q29udGVudCA9IG1vbnRoVG9TdHIoaSwgc2VsZi5jb25maWcuc2hvcnRoYW5kQ3VycmVudE1vbnRoLCBzZWxmLmwxMG4pO1xuICAgICAgICAgICAgICAgIG1vbnRoLnRhYkluZGV4ID0gLTE7XG4gICAgICAgICAgICAgICAgaWYgKHNlbGYuY3VycmVudE1vbnRoID09PSBpKSB7XG4gICAgICAgICAgICAgICAgICAgIG1vbnRoLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc2VsZi5tb250aHNEcm9wZG93bkNvbnRhaW5lci5hcHBlbmRDaGlsZChtb250aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gYnVpbGRNb250aCgpIHtcbiAgICAgICAgICAgIHZhciBjb250YWluZXIgPSBjcmVhdGVFbGVtZW50KFwiZGl2XCIsIFwiZmxhdHBpY2tyLW1vbnRoXCIpO1xuICAgICAgICAgICAgdmFyIG1vbnRoTmF2RnJhZ21lbnQgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICAgICAgICAgICAgdmFyIG1vbnRoRWxlbWVudDtcbiAgICAgICAgICAgIGlmIChzZWxmLmNvbmZpZy5zaG93TW9udGhzID4gMSB8fFxuICAgICAgICAgICAgICAgIHNlbGYuY29uZmlnLm1vbnRoU2VsZWN0b3JUeXBlID09PSBcInN0YXRpY1wiKSB7XG4gICAgICAgICAgICAgICAgbW9udGhFbGVtZW50ID0gY3JlYXRlRWxlbWVudChcInNwYW5cIiwgXCJjdXItbW9udGhcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZWxmLm1vbnRoc0Ryb3Bkb3duQ29udGFpbmVyID0gY3JlYXRlRWxlbWVudChcInNlbGVjdFwiLCBcImZsYXRwaWNrci1tb250aERyb3Bkb3duLW1vbnRoc1wiKTtcbiAgICAgICAgICAgICAgICBzZWxmLm1vbnRoc0Ryb3Bkb3duQ29udGFpbmVyLnNldEF0dHJpYnV0ZShcImFyaWEtbGFiZWxcIiwgc2VsZi5sMTBuLm1vbnRoQXJpYUxhYmVsKTtcbiAgICAgICAgICAgICAgICBiaW5kKHNlbGYubW9udGhzRHJvcGRvd25Db250YWluZXIsIFwiY2hhbmdlXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSBnZXRFdmVudFRhcmdldChlKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkTW9udGggPSBwYXJzZUludCh0YXJnZXQudmFsdWUsIDEwKTtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5jaGFuZ2VNb250aChzZWxlY3RlZE1vbnRoIC0gc2VsZi5jdXJyZW50TW9udGgpO1xuICAgICAgICAgICAgICAgICAgICB0cmlnZ2VyRXZlbnQoXCJvbk1vbnRoQ2hhbmdlXCIpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGJ1aWxkTW9udGhTd2l0Y2goKTtcbiAgICAgICAgICAgICAgICBtb250aEVsZW1lbnQgPSBzZWxmLm1vbnRoc0Ryb3Bkb3duQ29udGFpbmVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHllYXJJbnB1dCA9IGNyZWF0ZU51bWJlcklucHV0KFwiY3VyLXllYXJcIiwgeyB0YWJpbmRleDogXCItMVwiIH0pO1xuICAgICAgICAgICAgdmFyIHllYXJFbGVtZW50ID0geWVhcklucHV0LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiaW5wdXRcIilbMF07XG4gICAgICAgICAgICB5ZWFyRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJhcmlhLWxhYmVsXCIsIHNlbGYubDEwbi55ZWFyQXJpYUxhYmVsKTtcbiAgICAgICAgICAgIGlmIChzZWxmLmNvbmZpZy5taW5EYXRlKSB7XG4gICAgICAgICAgICAgICAgeWVhckVsZW1lbnQuc2V0QXR0cmlidXRlKFwibWluXCIsIHNlbGYuY29uZmlnLm1pbkRhdGUuZ2V0RnVsbFllYXIoKS50b1N0cmluZygpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzZWxmLmNvbmZpZy5tYXhEYXRlKSB7XG4gICAgICAgICAgICAgICAgeWVhckVsZW1lbnQuc2V0QXR0cmlidXRlKFwibWF4XCIsIHNlbGYuY29uZmlnLm1heERhdGUuZ2V0RnVsbFllYXIoKS50b1N0cmluZygpKTtcbiAgICAgICAgICAgICAgICB5ZWFyRWxlbWVudC5kaXNhYmxlZCA9XG4gICAgICAgICAgICAgICAgICAgICEhc2VsZi5jb25maWcubWluRGF0ZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5jb25maWcubWluRGF0ZS5nZXRGdWxsWWVhcigpID09PSBzZWxmLmNvbmZpZy5tYXhEYXRlLmdldEZ1bGxZZWFyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgY3VycmVudE1vbnRoID0gY3JlYXRlRWxlbWVudChcImRpdlwiLCBcImZsYXRwaWNrci1jdXJyZW50LW1vbnRoXCIpO1xuICAgICAgICAgICAgY3VycmVudE1vbnRoLmFwcGVuZENoaWxkKG1vbnRoRWxlbWVudCk7XG4gICAgICAgICAgICBjdXJyZW50TW9udGguYXBwZW5kQ2hpbGQoeWVhcklucHV0KTtcbiAgICAgICAgICAgIG1vbnRoTmF2RnJhZ21lbnQuYXBwZW5kQ2hpbGQoY3VycmVudE1vbnRoKTtcbiAgICAgICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChtb250aE5hdkZyYWdtZW50KTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgY29udGFpbmVyOiBjb250YWluZXIsXG4gICAgICAgICAgICAgICAgeWVhckVsZW1lbnQ6IHllYXJFbGVtZW50LFxuICAgICAgICAgICAgICAgIG1vbnRoRWxlbWVudDogbW9udGhFbGVtZW50LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBidWlsZE1vbnRocygpIHtcbiAgICAgICAgICAgIGNsZWFyTm9kZShzZWxmLm1vbnRoTmF2KTtcbiAgICAgICAgICAgIHNlbGYubW9udGhOYXYuYXBwZW5kQ2hpbGQoc2VsZi5wcmV2TW9udGhOYXYpO1xuICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLnNob3dNb250aHMpIHtcbiAgICAgICAgICAgICAgICBzZWxmLnllYXJFbGVtZW50cyA9IFtdO1xuICAgICAgICAgICAgICAgIHNlbGYubW9udGhFbGVtZW50cyA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yICh2YXIgbSA9IHNlbGYuY29uZmlnLnNob3dNb250aHM7IG0tLTspIHtcbiAgICAgICAgICAgICAgICB2YXIgbW9udGggPSBidWlsZE1vbnRoKCk7XG4gICAgICAgICAgICAgICAgc2VsZi55ZWFyRWxlbWVudHMucHVzaChtb250aC55ZWFyRWxlbWVudCk7XG4gICAgICAgICAgICAgICAgc2VsZi5tb250aEVsZW1lbnRzLnB1c2gobW9udGgubW9udGhFbGVtZW50KTtcbiAgICAgICAgICAgICAgICBzZWxmLm1vbnRoTmF2LmFwcGVuZENoaWxkKG1vbnRoLmNvbnRhaW5lcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZWxmLm1vbnRoTmF2LmFwcGVuZENoaWxkKHNlbGYubmV4dE1vbnRoTmF2KTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBidWlsZE1vbnRoTmF2KCkge1xuICAgICAgICAgICAgc2VsZi5tb250aE5hdiA9IGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgXCJmbGF0cGlja3ItbW9udGhzXCIpO1xuICAgICAgICAgICAgc2VsZi55ZWFyRWxlbWVudHMgPSBbXTtcbiAgICAgICAgICAgIHNlbGYubW9udGhFbGVtZW50cyA9IFtdO1xuICAgICAgICAgICAgc2VsZi5wcmV2TW9udGhOYXYgPSBjcmVhdGVFbGVtZW50KFwic3BhblwiLCBcImZsYXRwaWNrci1wcmV2LW1vbnRoXCIpO1xuICAgICAgICAgICAgc2VsZi5wcmV2TW9udGhOYXYuaW5uZXJIVE1MID0gc2VsZi5jb25maWcucHJldkFycm93O1xuICAgICAgICAgICAgc2VsZi5uZXh0TW9udGhOYXYgPSBjcmVhdGVFbGVtZW50KFwic3BhblwiLCBcImZsYXRwaWNrci1uZXh0LW1vbnRoXCIpO1xuICAgICAgICAgICAgc2VsZi5uZXh0TW9udGhOYXYuaW5uZXJIVE1MID0gc2VsZi5jb25maWcubmV4dEFycm93O1xuICAgICAgICAgICAgYnVpbGRNb250aHMoKTtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzZWxmLCBcIl9oaWRlUHJldk1vbnRoQXJyb3dcIiwge1xuICAgICAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gc2VsZi5fX2hpZGVQcmV2TW9udGhBcnJvdzsgfSxcbiAgICAgICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uIChib29sKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLl9faGlkZVByZXZNb250aEFycm93ICE9PSBib29sKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b2dnbGVDbGFzcyhzZWxmLnByZXZNb250aE5hdiwgXCJmbGF0cGlja3ItZGlzYWJsZWRcIiwgYm9vbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9faGlkZVByZXZNb250aEFycm93ID0gYm9vbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzZWxmLCBcIl9oaWRlTmV4dE1vbnRoQXJyb3dcIiwge1xuICAgICAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gc2VsZi5fX2hpZGVOZXh0TW9udGhBcnJvdzsgfSxcbiAgICAgICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uIChib29sKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLl9faGlkZU5leHRNb250aEFycm93ICE9PSBib29sKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b2dnbGVDbGFzcyhzZWxmLm5leHRNb250aE5hdiwgXCJmbGF0cGlja3ItZGlzYWJsZWRcIiwgYm9vbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9faGlkZU5leHRNb250aEFycm93ID0gYm9vbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHNlbGYuY3VycmVudFllYXJFbGVtZW50ID0gc2VsZi55ZWFyRWxlbWVudHNbMF07XG4gICAgICAgICAgICB1cGRhdGVOYXZpZ2F0aW9uQ3VycmVudE1vbnRoKCk7XG4gICAgICAgICAgICByZXR1cm4gc2VsZi5tb250aE5hdjtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBidWlsZFRpbWUoKSB7XG4gICAgICAgICAgICBzZWxmLmNhbGVuZGFyQ29udGFpbmVyLmNsYXNzTGlzdC5hZGQoXCJoYXNUaW1lXCIpO1xuICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLm5vQ2FsZW5kYXIpXG4gICAgICAgICAgICAgICAgc2VsZi5jYWxlbmRhckNvbnRhaW5lci5jbGFzc0xpc3QuYWRkKFwibm9DYWxlbmRhclwiKTtcbiAgICAgICAgICAgIHZhciBkZWZhdWx0cyA9IGdldERlZmF1bHRIb3VycyhzZWxmLmNvbmZpZyk7XG4gICAgICAgICAgICBzZWxmLnRpbWVDb250YWluZXIgPSBjcmVhdGVFbGVtZW50KFwiZGl2XCIsIFwiZmxhdHBpY2tyLXRpbWVcIik7XG4gICAgICAgICAgICBzZWxmLnRpbWVDb250YWluZXIudGFiSW5kZXggPSAtMTtcbiAgICAgICAgICAgIHZhciBzZXBhcmF0b3IgPSBjcmVhdGVFbGVtZW50KFwic3BhblwiLCBcImZsYXRwaWNrci10aW1lLXNlcGFyYXRvclwiLCBcIjpcIik7XG4gICAgICAgICAgICB2YXIgaG91cklucHV0ID0gY3JlYXRlTnVtYmVySW5wdXQoXCJmbGF0cGlja3ItaG91clwiLCB7XG4gICAgICAgICAgICAgICAgXCJhcmlhLWxhYmVsXCI6IHNlbGYubDEwbi5ob3VyQXJpYUxhYmVsLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBzZWxmLmhvdXJFbGVtZW50ID0gaG91cklucHV0LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiaW5wdXRcIilbMF07XG4gICAgICAgICAgICB2YXIgbWludXRlSW5wdXQgPSBjcmVhdGVOdW1iZXJJbnB1dChcImZsYXRwaWNrci1taW51dGVcIiwge1xuICAgICAgICAgICAgICAgIFwiYXJpYS1sYWJlbFwiOiBzZWxmLmwxMG4ubWludXRlQXJpYUxhYmVsLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBzZWxmLm1pbnV0ZUVsZW1lbnQgPSBtaW51dGVJbnB1dC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImlucHV0XCIpWzBdO1xuICAgICAgICAgICAgc2VsZi5ob3VyRWxlbWVudC50YWJJbmRleCA9IHNlbGYubWludXRlRWxlbWVudC50YWJJbmRleCA9IC0xO1xuICAgICAgICAgICAgc2VsZi5ob3VyRWxlbWVudC52YWx1ZSA9IHBhZChzZWxmLmxhdGVzdFNlbGVjdGVkRGF0ZU9ialxuICAgICAgICAgICAgICAgID8gc2VsZi5sYXRlc3RTZWxlY3RlZERhdGVPYmouZ2V0SG91cnMoKVxuICAgICAgICAgICAgICAgIDogc2VsZi5jb25maWcudGltZV8yNGhyXG4gICAgICAgICAgICAgICAgICAgID8gZGVmYXVsdHMuaG91cnNcbiAgICAgICAgICAgICAgICAgICAgOiBtaWxpdGFyeTJhbXBtKGRlZmF1bHRzLmhvdXJzKSk7XG4gICAgICAgICAgICBzZWxmLm1pbnV0ZUVsZW1lbnQudmFsdWUgPSBwYWQoc2VsZi5sYXRlc3RTZWxlY3RlZERhdGVPYmpcbiAgICAgICAgICAgICAgICA/IHNlbGYubGF0ZXN0U2VsZWN0ZWREYXRlT2JqLmdldE1pbnV0ZXMoKVxuICAgICAgICAgICAgICAgIDogZGVmYXVsdHMubWludXRlcyk7XG4gICAgICAgICAgICBzZWxmLmhvdXJFbGVtZW50LnNldEF0dHJpYnV0ZShcInN0ZXBcIiwgc2VsZi5jb25maWcuaG91ckluY3JlbWVudC50b1N0cmluZygpKTtcbiAgICAgICAgICAgIHNlbGYubWludXRlRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJzdGVwXCIsIHNlbGYuY29uZmlnLm1pbnV0ZUluY3JlbWVudC50b1N0cmluZygpKTtcbiAgICAgICAgICAgIHNlbGYuaG91ckVsZW1lbnQuc2V0QXR0cmlidXRlKFwibWluXCIsIHNlbGYuY29uZmlnLnRpbWVfMjRociA/IFwiMFwiIDogXCIxXCIpO1xuICAgICAgICAgICAgc2VsZi5ob3VyRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJtYXhcIiwgc2VsZi5jb25maWcudGltZV8yNGhyID8gXCIyM1wiIDogXCIxMlwiKTtcbiAgICAgICAgICAgIHNlbGYuaG91ckVsZW1lbnQuc2V0QXR0cmlidXRlKFwibWF4bGVuZ3RoXCIsIFwiMlwiKTtcbiAgICAgICAgICAgIHNlbGYubWludXRlRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJtaW5cIiwgXCIwXCIpO1xuICAgICAgICAgICAgc2VsZi5taW51dGVFbGVtZW50LnNldEF0dHJpYnV0ZShcIm1heFwiLCBcIjU5XCIpO1xuICAgICAgICAgICAgc2VsZi5taW51dGVFbGVtZW50LnNldEF0dHJpYnV0ZShcIm1heGxlbmd0aFwiLCBcIjJcIik7XG4gICAgICAgICAgICBzZWxmLnRpbWVDb250YWluZXIuYXBwZW5kQ2hpbGQoaG91cklucHV0KTtcbiAgICAgICAgICAgIHNlbGYudGltZUNvbnRhaW5lci5hcHBlbmRDaGlsZChzZXBhcmF0b3IpO1xuICAgICAgICAgICAgc2VsZi50aW1lQ29udGFpbmVyLmFwcGVuZENoaWxkKG1pbnV0ZUlucHV0KTtcbiAgICAgICAgICAgIGlmIChzZWxmLmNvbmZpZy50aW1lXzI0aHIpXG4gICAgICAgICAgICAgICAgc2VsZi50aW1lQ29udGFpbmVyLmNsYXNzTGlzdC5hZGQoXCJ0aW1lMjRoclwiKTtcbiAgICAgICAgICAgIGlmIChzZWxmLmNvbmZpZy5lbmFibGVTZWNvbmRzKSB7XG4gICAgICAgICAgICAgICAgc2VsZi50aW1lQ29udGFpbmVyLmNsYXNzTGlzdC5hZGQoXCJoYXNTZWNvbmRzXCIpO1xuICAgICAgICAgICAgICAgIHZhciBzZWNvbmRJbnB1dCA9IGNyZWF0ZU51bWJlcklucHV0KFwiZmxhdHBpY2tyLXNlY29uZFwiKTtcbiAgICAgICAgICAgICAgICBzZWxmLnNlY29uZEVsZW1lbnQgPSBzZWNvbmRJbnB1dC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImlucHV0XCIpWzBdO1xuICAgICAgICAgICAgICAgIHNlbGYuc2Vjb25kRWxlbWVudC52YWx1ZSA9IHBhZChzZWxmLmxhdGVzdFNlbGVjdGVkRGF0ZU9ialxuICAgICAgICAgICAgICAgICAgICA/IHNlbGYubGF0ZXN0U2VsZWN0ZWREYXRlT2JqLmdldFNlY29uZHMoKVxuICAgICAgICAgICAgICAgICAgICA6IGRlZmF1bHRzLnNlY29uZHMpO1xuICAgICAgICAgICAgICAgIHNlbGYuc2Vjb25kRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJzdGVwXCIsIHNlbGYubWludXRlRWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJzdGVwXCIpKTtcbiAgICAgICAgICAgICAgICBzZWxmLnNlY29uZEVsZW1lbnQuc2V0QXR0cmlidXRlKFwibWluXCIsIFwiMFwiKTtcbiAgICAgICAgICAgICAgICBzZWxmLnNlY29uZEVsZW1lbnQuc2V0QXR0cmlidXRlKFwibWF4XCIsIFwiNTlcIik7XG4gICAgICAgICAgICAgICAgc2VsZi5zZWNvbmRFbGVtZW50LnNldEF0dHJpYnV0ZShcIm1heGxlbmd0aFwiLCBcIjJcIik7XG4gICAgICAgICAgICAgICAgc2VsZi50aW1lQ29udGFpbmVyLmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIsIFwiZmxhdHBpY2tyLXRpbWUtc2VwYXJhdG9yXCIsIFwiOlwiKSk7XG4gICAgICAgICAgICAgICAgc2VsZi50aW1lQ29udGFpbmVyLmFwcGVuZENoaWxkKHNlY29uZElucHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghc2VsZi5jb25maWcudGltZV8yNGhyKSB7XG4gICAgICAgICAgICAgICAgLy8gYWRkIHNlbGYuYW1QTSBpZiBhcHByb3ByaWF0ZVxuICAgICAgICAgICAgICAgIHNlbGYuYW1QTSA9IGNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIsIFwiZmxhdHBpY2tyLWFtLXBtXCIsIHNlbGYubDEwbi5hbVBNW2ludCgoc2VsZi5sYXRlc3RTZWxlY3RlZERhdGVPYmpcbiAgICAgICAgICAgICAgICAgICAgPyBzZWxmLmhvdXJFbGVtZW50LnZhbHVlXG4gICAgICAgICAgICAgICAgICAgIDogc2VsZi5jb25maWcuZGVmYXVsdEhvdXIpID4gMTEpXSk7XG4gICAgICAgICAgICAgICAgc2VsZi5hbVBNLnRpdGxlID0gc2VsZi5sMTBuLnRvZ2dsZVRpdGxlO1xuICAgICAgICAgICAgICAgIHNlbGYuYW1QTS50YWJJbmRleCA9IC0xO1xuICAgICAgICAgICAgICAgIHNlbGYudGltZUNvbnRhaW5lci5hcHBlbmRDaGlsZChzZWxmLmFtUE0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHNlbGYudGltZUNvbnRhaW5lcjtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBidWlsZFdlZWtkYXlzKCkge1xuICAgICAgICAgICAgaWYgKCFzZWxmLndlZWtkYXlDb250YWluZXIpXG4gICAgICAgICAgICAgICAgc2VsZi53ZWVrZGF5Q29udGFpbmVyID0gY3JlYXRlRWxlbWVudChcImRpdlwiLCBcImZsYXRwaWNrci13ZWVrZGF5c1wiKTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBjbGVhck5vZGUoc2VsZi53ZWVrZGF5Q29udGFpbmVyKTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSBzZWxmLmNvbmZpZy5zaG93TW9udGhzOyBpLS07KSB7XG4gICAgICAgICAgICAgICAgdmFyIGNvbnRhaW5lciA9IGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgXCJmbGF0cGlja3Itd2Vla2RheWNvbnRhaW5lclwiKTtcbiAgICAgICAgICAgICAgICBzZWxmLndlZWtkYXlDb250YWluZXIuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHVwZGF0ZVdlZWtkYXlzKCk7XG4gICAgICAgICAgICByZXR1cm4gc2VsZi53ZWVrZGF5Q29udGFpbmVyO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHVwZGF0ZVdlZWtkYXlzKCkge1xuICAgICAgICAgICAgaWYgKCFzZWxmLndlZWtkYXlDb250YWluZXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZmlyc3REYXlPZldlZWsgPSBzZWxmLmwxMG4uZmlyc3REYXlPZldlZWs7XG4gICAgICAgICAgICB2YXIgd2Vla2RheXMgPSBfX3NwcmVhZEFycmF5cyhzZWxmLmwxMG4ud2Vla2RheXMuc2hvcnRoYW5kKTtcbiAgICAgICAgICAgIGlmIChmaXJzdERheU9mV2VlayA+IDAgJiYgZmlyc3REYXlPZldlZWsgPCB3ZWVrZGF5cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB3ZWVrZGF5cyA9IF9fc3ByZWFkQXJyYXlzKHdlZWtkYXlzLnNwbGljZShmaXJzdERheU9mV2Vlaywgd2Vla2RheXMubGVuZ3RoKSwgd2Vla2RheXMuc3BsaWNlKDAsIGZpcnN0RGF5T2ZXZWVrKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gc2VsZi5jb25maWcuc2hvd01vbnRoczsgaS0tOykge1xuICAgICAgICAgICAgICAgIHNlbGYud2Vla2RheUNvbnRhaW5lci5jaGlsZHJlbltpXS5pbm5lckhUTUwgPSBcIlxcbiAgICAgIDxzcGFuIGNsYXNzPSdmbGF0cGlja3Itd2Vla2RheSc+XFxuICAgICAgICBcIiArIHdlZWtkYXlzLmpvaW4oXCI8L3NwYW4+PHNwYW4gY2xhc3M9J2ZsYXRwaWNrci13ZWVrZGF5Jz5cIikgKyBcIlxcbiAgICAgIDwvc3Bhbj5cXG4gICAgICBcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICBmdW5jdGlvbiBidWlsZFdlZWtzKCkge1xuICAgICAgICAgICAgc2VsZi5jYWxlbmRhckNvbnRhaW5lci5jbGFzc0xpc3QuYWRkKFwiaGFzV2Vla3NcIik7XG4gICAgICAgICAgICB2YXIgd2Vla1dyYXBwZXIgPSBjcmVhdGVFbGVtZW50KFwiZGl2XCIsIFwiZmxhdHBpY2tyLXdlZWt3cmFwcGVyXCIpO1xuICAgICAgICAgICAgd2Vla1dyYXBwZXIuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChcInNwYW5cIiwgXCJmbGF0cGlja3Itd2Vla2RheVwiLCBzZWxmLmwxMG4ud2Vla0FiYnJldmlhdGlvbikpO1xuICAgICAgICAgICAgdmFyIHdlZWtOdW1iZXJzID0gY3JlYXRlRWxlbWVudChcImRpdlwiLCBcImZsYXRwaWNrci13ZWVrc1wiKTtcbiAgICAgICAgICAgIHdlZWtXcmFwcGVyLmFwcGVuZENoaWxkKHdlZWtOdW1iZXJzKTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgd2Vla1dyYXBwZXI6IHdlZWtXcmFwcGVyLFxuICAgICAgICAgICAgICAgIHdlZWtOdW1iZXJzOiB3ZWVrTnVtYmVycyxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gY2hhbmdlTW9udGgodmFsdWUsIGlzT2Zmc2V0KSB7XG4gICAgICAgICAgICBpZiAoaXNPZmZzZXQgPT09IHZvaWQgMCkgeyBpc09mZnNldCA9IHRydWU7IH1cbiAgICAgICAgICAgIHZhciBkZWx0YSA9IGlzT2Zmc2V0ID8gdmFsdWUgOiB2YWx1ZSAtIHNlbGYuY3VycmVudE1vbnRoO1xuICAgICAgICAgICAgaWYgKChkZWx0YSA8IDAgJiYgc2VsZi5faGlkZVByZXZNb250aEFycm93ID09PSB0cnVlKSB8fFxuICAgICAgICAgICAgICAgIChkZWx0YSA+IDAgJiYgc2VsZi5faGlkZU5leHRNb250aEFycm93ID09PSB0cnVlKSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICBzZWxmLmN1cnJlbnRNb250aCArPSBkZWx0YTtcbiAgICAgICAgICAgIGlmIChzZWxmLmN1cnJlbnRNb250aCA8IDAgfHwgc2VsZi5jdXJyZW50TW9udGggPiAxMSkge1xuICAgICAgICAgICAgICAgIHNlbGYuY3VycmVudFllYXIgKz0gc2VsZi5jdXJyZW50TW9udGggPiAxMSA/IDEgOiAtMTtcbiAgICAgICAgICAgICAgICBzZWxmLmN1cnJlbnRNb250aCA9IChzZWxmLmN1cnJlbnRNb250aCArIDEyKSAlIDEyO1xuICAgICAgICAgICAgICAgIHRyaWdnZXJFdmVudChcIm9uWWVhckNoYW5nZVwiKTtcbiAgICAgICAgICAgICAgICBidWlsZE1vbnRoU3dpdGNoKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBidWlsZERheXMoKTtcbiAgICAgICAgICAgIHRyaWdnZXJFdmVudChcIm9uTW9udGhDaGFuZ2VcIik7XG4gICAgICAgICAgICB1cGRhdGVOYXZpZ2F0aW9uQ3VycmVudE1vbnRoKCk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gY2xlYXIodHJpZ2dlckNoYW5nZUV2ZW50LCB0b0luaXRpYWwpIHtcbiAgICAgICAgICAgIGlmICh0cmlnZ2VyQ2hhbmdlRXZlbnQgPT09IHZvaWQgMCkgeyB0cmlnZ2VyQ2hhbmdlRXZlbnQgPSB0cnVlOyB9XG4gICAgICAgICAgICBpZiAodG9Jbml0aWFsID09PSB2b2lkIDApIHsgdG9Jbml0aWFsID0gdHJ1ZTsgfVxuICAgICAgICAgICAgc2VsZi5pbnB1dC52YWx1ZSA9IFwiXCI7XG4gICAgICAgICAgICBpZiAoc2VsZi5hbHRJbnB1dCAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgICAgIHNlbGYuYWx0SW5wdXQudmFsdWUgPSBcIlwiO1xuICAgICAgICAgICAgaWYgKHNlbGYubW9iaWxlSW5wdXQgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICAgICAgICBzZWxmLm1vYmlsZUlucHV0LnZhbHVlID0gXCJcIjtcbiAgICAgICAgICAgIHNlbGYuc2VsZWN0ZWREYXRlcyA9IFtdO1xuICAgICAgICAgICAgc2VsZi5sYXRlc3RTZWxlY3RlZERhdGVPYmogPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBpZiAodG9Jbml0aWFsID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5jdXJyZW50WWVhciA9IHNlbGYuX2luaXRpYWxEYXRlLmdldEZ1bGxZZWFyKCk7XG4gICAgICAgICAgICAgICAgc2VsZi5jdXJyZW50TW9udGggPSBzZWxmLl9pbml0aWFsRGF0ZS5nZXRNb250aCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLmVuYWJsZVRpbWUgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICB2YXIgX2EgPSBnZXREZWZhdWx0SG91cnMoc2VsZi5jb25maWcpLCBob3VycyA9IF9hLmhvdXJzLCBtaW51dGVzID0gX2EubWludXRlcywgc2Vjb25kcyA9IF9hLnNlY29uZHM7XG4gICAgICAgICAgICAgICAgc2V0SG91cnMoaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2VsZi5yZWRyYXcoKTtcbiAgICAgICAgICAgIGlmICh0cmlnZ2VyQ2hhbmdlRXZlbnQpXG4gICAgICAgICAgICAgICAgLy8gdHJpZ2dlckNoYW5nZUV2ZW50IGlzIHRydWUgKGRlZmF1bHQpIG9yIGFuIEV2ZW50XG4gICAgICAgICAgICAgICAgdHJpZ2dlckV2ZW50KFwib25DaGFuZ2VcIik7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gY2xvc2UoKSB7XG4gICAgICAgICAgICBzZWxmLmlzT3BlbiA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKCFzZWxmLmlzTW9iaWxlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHNlbGYuY2FsZW5kYXJDb250YWluZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLmNhbGVuZGFyQ29udGFpbmVyLmNsYXNzTGlzdC5yZW1vdmUoXCJvcGVuXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5faW5wdXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLl9pbnB1dC5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZlXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRyaWdnZXJFdmVudChcIm9uQ2xvc2VcIik7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gZGVzdHJveSgpIHtcbiAgICAgICAgICAgIGlmIChzZWxmLmNvbmZpZyAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgICAgIHRyaWdnZXJFdmVudChcIm9uRGVzdHJveVwiKTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSBzZWxmLl9oYW5kbGVycy5sZW5ndGg7IGktLTspIHtcbiAgICAgICAgICAgICAgICBzZWxmLl9oYW5kbGVyc1tpXS5yZW1vdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNlbGYuX2hhbmRsZXJzID0gW107XG4gICAgICAgICAgICBpZiAoc2VsZi5tb2JpbGVJbnB1dCkge1xuICAgICAgICAgICAgICAgIGlmIChzZWxmLm1vYmlsZUlucHV0LnBhcmVudE5vZGUpXG4gICAgICAgICAgICAgICAgICAgIHNlbGYubW9iaWxlSW5wdXQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChzZWxmLm1vYmlsZUlucHV0KTtcbiAgICAgICAgICAgICAgICBzZWxmLm1vYmlsZUlucHV0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoc2VsZi5jYWxlbmRhckNvbnRhaW5lciAmJiBzZWxmLmNhbGVuZGFyQ29udGFpbmVyLnBhcmVudE5vZGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5jb25maWcuc3RhdGljICYmIHNlbGYuY2FsZW5kYXJDb250YWluZXIucGFyZW50Tm9kZSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgd3JhcHBlciA9IHNlbGYuY2FsZW5kYXJDb250YWluZXIucGFyZW50Tm9kZTtcbiAgICAgICAgICAgICAgICAgICAgd3JhcHBlci5sYXN0Q2hpbGQgJiYgd3JhcHBlci5yZW1vdmVDaGlsZCh3cmFwcGVyLmxhc3RDaGlsZCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh3cmFwcGVyLnBhcmVudE5vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICh3cmFwcGVyLmZpcnN0Q2hpbGQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JhcHBlci5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh3cmFwcGVyLmZpcnN0Q2hpbGQsIHdyYXBwZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgd3JhcHBlci5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHdyYXBwZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5jYWxlbmRhckNvbnRhaW5lci5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHNlbGYuY2FsZW5kYXJDb250YWluZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHNlbGYuYWx0SW5wdXQpIHtcbiAgICAgICAgICAgICAgICBzZWxmLmlucHV0LnR5cGUgPSBcInRleHRcIjtcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5hbHRJbnB1dC5wYXJlbnROb2RlKVxuICAgICAgICAgICAgICAgICAgICBzZWxmLmFsdElucHV0LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc2VsZi5hbHRJbnB1dCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHNlbGYuYWx0SW5wdXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc2VsZi5pbnB1dCkge1xuICAgICAgICAgICAgICAgIHNlbGYuaW5wdXQudHlwZSA9IHNlbGYuaW5wdXQuX3R5cGU7XG4gICAgICAgICAgICAgICAgc2VsZi5pbnB1dC5jbGFzc0xpc3QucmVtb3ZlKFwiZmxhdHBpY2tyLWlucHV0XCIpO1xuICAgICAgICAgICAgICAgIHNlbGYuaW5wdXQucmVtb3ZlQXR0cmlidXRlKFwicmVhZG9ubHlcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgXCJfc2hvd1RpbWVJbnB1dFwiLFxuICAgICAgICAgICAgICAgIFwibGF0ZXN0U2VsZWN0ZWREYXRlT2JqXCIsXG4gICAgICAgICAgICAgICAgXCJfaGlkZU5leHRNb250aEFycm93XCIsXG4gICAgICAgICAgICAgICAgXCJfaGlkZVByZXZNb250aEFycm93XCIsXG4gICAgICAgICAgICAgICAgXCJfX2hpZGVOZXh0TW9udGhBcnJvd1wiLFxuICAgICAgICAgICAgICAgIFwiX19oaWRlUHJldk1vbnRoQXJyb3dcIixcbiAgICAgICAgICAgICAgICBcImlzTW9iaWxlXCIsXG4gICAgICAgICAgICAgICAgXCJpc09wZW5cIixcbiAgICAgICAgICAgICAgICBcInNlbGVjdGVkRGF0ZUVsZW1cIixcbiAgICAgICAgICAgICAgICBcIm1pbkRhdGVIYXNUaW1lXCIsXG4gICAgICAgICAgICAgICAgXCJtYXhEYXRlSGFzVGltZVwiLFxuICAgICAgICAgICAgICAgIFwiZGF5c1wiLFxuICAgICAgICAgICAgICAgIFwiZGF5c0NvbnRhaW5lclwiLFxuICAgICAgICAgICAgICAgIFwiX2lucHV0XCIsXG4gICAgICAgICAgICAgICAgXCJfcG9zaXRpb25FbGVtZW50XCIsXG4gICAgICAgICAgICAgICAgXCJpbm5lckNvbnRhaW5lclwiLFxuICAgICAgICAgICAgICAgIFwickNvbnRhaW5lclwiLFxuICAgICAgICAgICAgICAgIFwibW9udGhOYXZcIixcbiAgICAgICAgICAgICAgICBcInRvZGF5RGF0ZUVsZW1cIixcbiAgICAgICAgICAgICAgICBcImNhbGVuZGFyQ29udGFpbmVyXCIsXG4gICAgICAgICAgICAgICAgXCJ3ZWVrZGF5Q29udGFpbmVyXCIsXG4gICAgICAgICAgICAgICAgXCJwcmV2TW9udGhOYXZcIixcbiAgICAgICAgICAgICAgICBcIm5leHRNb250aE5hdlwiLFxuICAgICAgICAgICAgICAgIFwibW9udGhzRHJvcGRvd25Db250YWluZXJcIixcbiAgICAgICAgICAgICAgICBcImN1cnJlbnRNb250aEVsZW1lbnRcIixcbiAgICAgICAgICAgICAgICBcImN1cnJlbnRZZWFyRWxlbWVudFwiLFxuICAgICAgICAgICAgICAgIFwibmF2aWdhdGlvbkN1cnJlbnRNb250aFwiLFxuICAgICAgICAgICAgICAgIFwic2VsZWN0ZWREYXRlRWxlbVwiLFxuICAgICAgICAgICAgICAgIFwiY29uZmlnXCIsXG4gICAgICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKGspIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgc2VsZltrXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2F0Y2ggKF8pIHsgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gaXNDYWxlbmRhckVsZW0oZWxlbSkge1xuICAgICAgICAgICAgcmV0dXJuIHNlbGYuY2FsZW5kYXJDb250YWluZXIuY29udGFpbnMoZWxlbSk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gZG9jdW1lbnRDbGljayhlKSB7XG4gICAgICAgICAgICBpZiAoc2VsZi5pc09wZW4gJiYgIXNlbGYuY29uZmlnLmlubGluZSkge1xuICAgICAgICAgICAgICAgIHZhciBldmVudFRhcmdldF8xID0gZ2V0RXZlbnRUYXJnZXQoZSk7XG4gICAgICAgICAgICAgICAgdmFyIGlzQ2FsZW5kYXJFbGVtZW50ID0gaXNDYWxlbmRhckVsZW0oZXZlbnRUYXJnZXRfMSk7XG4gICAgICAgICAgICAgICAgdmFyIGlzSW5wdXQgPSBldmVudFRhcmdldF8xID09PSBzZWxmLmlucHV0IHx8XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50VGFyZ2V0XzEgPT09IHNlbGYuYWx0SW5wdXQgfHxcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5lbGVtZW50LmNvbnRhaW5zKGV2ZW50VGFyZ2V0XzEpIHx8XG4gICAgICAgICAgICAgICAgICAgIC8vIHdlYiBjb21wb25lbnRzXG4gICAgICAgICAgICAgICAgICAgIC8vIGUucGF0aCBpcyBub3QgcHJlc2VudCBpbiBhbGwgYnJvd3NlcnMuIGNpcmN1bXZlbnRpbmcgdHlwZWNoZWNrc1xuICAgICAgICAgICAgICAgICAgICAoZS5wYXRoICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBlLnBhdGguaW5kZXhPZiAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKH5lLnBhdGguaW5kZXhPZihzZWxmLmlucHV0KSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH5lLnBhdGguaW5kZXhPZihzZWxmLmFsdElucHV0KSkpO1xuICAgICAgICAgICAgICAgIHZhciBsb3N0Rm9jdXMgPSAhaXNJbnB1dCAmJlxuICAgICAgICAgICAgICAgICAgICAhaXNDYWxlbmRhckVsZW1lbnQgJiZcbiAgICAgICAgICAgICAgICAgICAgIWlzQ2FsZW5kYXJFbGVtKGUucmVsYXRlZFRhcmdldCk7XG4gICAgICAgICAgICAgICAgdmFyIGlzSWdub3JlZCA9ICFzZWxmLmNvbmZpZy5pZ25vcmVkRm9jdXNFbGVtZW50cy5zb21lKGZ1bmN0aW9uIChlbGVtKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBlbGVtLmNvbnRhaW5zKGV2ZW50VGFyZ2V0XzEpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmIChsb3N0Rm9jdXMgJiYgaXNJZ25vcmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLmNvbmZpZy5hbGxvd0lucHV0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnNldERhdGUoc2VsZi5faW5wdXQudmFsdWUsIGZhbHNlLCBzZWxmLmNvbmZpZy5hbHRJbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gc2VsZi5jb25maWcuYWx0Rm9ybWF0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBzZWxmLmNvbmZpZy5kYXRlRm9ybWF0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi50aW1lQ29udGFpbmVyICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubWludXRlRWxlbWVudCAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmhvdXJFbGVtZW50ICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuaW5wdXQudmFsdWUgIT09IFwiXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuaW5wdXQudmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlVGltZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuY2xvc2UoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZy5tb2RlID09PSBcInJhbmdlXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuc2VsZWN0ZWREYXRlcy5sZW5ndGggPT09IDEpXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmNsZWFyKGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gY2hhbmdlWWVhcihuZXdZZWFyKSB7XG4gICAgICAgICAgICBpZiAoIW5ld1llYXIgfHxcbiAgICAgICAgICAgICAgICAoc2VsZi5jb25maWcubWluRGF0ZSAmJiBuZXdZZWFyIDwgc2VsZi5jb25maWcubWluRGF0ZS5nZXRGdWxsWWVhcigpKSB8fFxuICAgICAgICAgICAgICAgIChzZWxmLmNvbmZpZy5tYXhEYXRlICYmIG5ld1llYXIgPiBzZWxmLmNvbmZpZy5tYXhEYXRlLmdldEZ1bGxZZWFyKCkpKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIHZhciBuZXdZZWFyTnVtID0gbmV3WWVhciwgaXNOZXdZZWFyID0gc2VsZi5jdXJyZW50WWVhciAhPT0gbmV3WWVhck51bTtcbiAgICAgICAgICAgIHNlbGYuY3VycmVudFllYXIgPSBuZXdZZWFyTnVtIHx8IHNlbGYuY3VycmVudFllYXI7XG4gICAgICAgICAgICBpZiAoc2VsZi5jb25maWcubWF4RGF0ZSAmJlxuICAgICAgICAgICAgICAgIHNlbGYuY3VycmVudFllYXIgPT09IHNlbGYuY29uZmlnLm1heERhdGUuZ2V0RnVsbFllYXIoKSkge1xuICAgICAgICAgICAgICAgIHNlbGYuY3VycmVudE1vbnRoID0gTWF0aC5taW4oc2VsZi5jb25maWcubWF4RGF0ZS5nZXRNb250aCgpLCBzZWxmLmN1cnJlbnRNb250aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChzZWxmLmNvbmZpZy5taW5EYXRlICYmXG4gICAgICAgICAgICAgICAgc2VsZi5jdXJyZW50WWVhciA9PT0gc2VsZi5jb25maWcubWluRGF0ZS5nZXRGdWxsWWVhcigpKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5jdXJyZW50TW9udGggPSBNYXRoLm1heChzZWxmLmNvbmZpZy5taW5EYXRlLmdldE1vbnRoKCksIHNlbGYuY3VycmVudE1vbnRoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc05ld1llYXIpIHtcbiAgICAgICAgICAgICAgICBzZWxmLnJlZHJhdygpO1xuICAgICAgICAgICAgICAgIHRyaWdnZXJFdmVudChcIm9uWWVhckNoYW5nZVwiKTtcbiAgICAgICAgICAgICAgICBidWlsZE1vbnRoU3dpdGNoKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gaXNFbmFibGVkKGRhdGUsIHRpbWVsZXNzKSB7XG4gICAgICAgICAgICB2YXIgX2E7XG4gICAgICAgICAgICBpZiAodGltZWxlc3MgPT09IHZvaWQgMCkgeyB0aW1lbGVzcyA9IHRydWU7IH1cbiAgICAgICAgICAgIHZhciBkYXRlVG9DaGVjayA9IHNlbGYucGFyc2VEYXRlKGRhdGUsIHVuZGVmaW5lZCwgdGltZWxlc3MpOyAvLyB0aW1lbGVzc1xuICAgICAgICAgICAgaWYgKChzZWxmLmNvbmZpZy5taW5EYXRlICYmXG4gICAgICAgICAgICAgICAgZGF0ZVRvQ2hlY2sgJiZcbiAgICAgICAgICAgICAgICBjb21wYXJlRGF0ZXMoZGF0ZVRvQ2hlY2ssIHNlbGYuY29uZmlnLm1pbkRhdGUsIHRpbWVsZXNzICE9PSB1bmRlZmluZWQgPyB0aW1lbGVzcyA6ICFzZWxmLm1pbkRhdGVIYXNUaW1lKSA8IDApIHx8XG4gICAgICAgICAgICAgICAgKHNlbGYuY29uZmlnLm1heERhdGUgJiZcbiAgICAgICAgICAgICAgICAgICAgZGF0ZVRvQ2hlY2sgJiZcbiAgICAgICAgICAgICAgICAgICAgY29tcGFyZURhdGVzKGRhdGVUb0NoZWNrLCBzZWxmLmNvbmZpZy5tYXhEYXRlLCB0aW1lbGVzcyAhPT0gdW5kZWZpbmVkID8gdGltZWxlc3MgOiAhc2VsZi5tYXhEYXRlSGFzVGltZSkgPiAwKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBpZiAoIXNlbGYuY29uZmlnLmVuYWJsZSAmJiBzZWxmLmNvbmZpZy5kaXNhYmxlLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChkYXRlVG9DaGVjayA9PT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIHZhciBib29sID0gISFzZWxmLmNvbmZpZy5lbmFibGUsIGFycmF5ID0gKF9hID0gc2VsZi5jb25maWcuZW5hYmxlKSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiBzZWxmLmNvbmZpZy5kaXNhYmxlO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGQgPSB2b2lkIDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGQgPSBhcnJheVtpXTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGQgPT09IFwiZnVuY3Rpb25cIiAmJlxuICAgICAgICAgICAgICAgICAgICBkKGRhdGVUb0NoZWNrKSAvLyBkaXNhYmxlZCBieSBmdW5jdGlvblxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJvb2w7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoZCBpbnN0YW5jZW9mIERhdGUgJiZcbiAgICAgICAgICAgICAgICAgICAgZGF0ZVRvQ2hlY2sgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgICAgICAgICBkLmdldFRpbWUoKSA9PT0gZGF0ZVRvQ2hlY2suZ2V0VGltZSgpKVxuICAgICAgICAgICAgICAgICAgICAvLyBkaXNhYmxlZCBieSBkYXRlXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBib29sO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBkID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGRpc2FibGVkIGJ5IGRhdGUgc3RyaW5nXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXJzZWQgPSBzZWxmLnBhcnNlRGF0ZShkLCB1bmRlZmluZWQsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VkICYmIHBhcnNlZC5nZXRUaW1lKCkgPT09IGRhdGVUb0NoZWNrLmdldFRpbWUoKVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBib29sXG4gICAgICAgICAgICAgICAgICAgICAgICA6ICFib29sO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChcbiAgICAgICAgICAgICAgICAvLyBkaXNhYmxlZCBieSByYW5nZVxuICAgICAgICAgICAgICAgIHR5cGVvZiBkID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgICAgICAgICAgICAgIGRhdGVUb0NoZWNrICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgICAgICAgICAgZC5mcm9tICYmXG4gICAgICAgICAgICAgICAgICAgIGQudG8gJiZcbiAgICAgICAgICAgICAgICAgICAgZGF0ZVRvQ2hlY2suZ2V0VGltZSgpID49IGQuZnJvbS5nZXRUaW1lKCkgJiZcbiAgICAgICAgICAgICAgICAgICAgZGF0ZVRvQ2hlY2suZ2V0VGltZSgpIDw9IGQudG8uZ2V0VGltZSgpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYm9vbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAhYm9vbDtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBpc0luVmlldyhlbGVtKSB7XG4gICAgICAgICAgICBpZiAoc2VsZi5kYXlzQ29udGFpbmVyICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgICAgICAgcmV0dXJuIChlbGVtLmNsYXNzTmFtZS5pbmRleE9mKFwiaGlkZGVuXCIpID09PSAtMSAmJlxuICAgICAgICAgICAgICAgICAgICBlbGVtLmNsYXNzTmFtZS5pbmRleE9mKFwiZmxhdHBpY2tyLWRpc2FibGVkXCIpID09PSAtMSAmJlxuICAgICAgICAgICAgICAgICAgICBzZWxmLmRheXNDb250YWluZXIuY29udGFpbnMoZWxlbSkpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG9uQmx1cihlKSB7XG4gICAgICAgICAgICB2YXIgaXNJbnB1dCA9IGUudGFyZ2V0ID09PSBzZWxmLl9pbnB1dDtcbiAgICAgICAgICAgIHZhciB2YWx1ZUNoYW5nZWQgPSBzZWxmLl9pbnB1dC52YWx1ZS50cmltRW5kKCkgIT09IGdldERhdGVTdHIoKTtcbiAgICAgICAgICAgIGlmIChpc0lucHV0ICYmXG4gICAgICAgICAgICAgICAgdmFsdWVDaGFuZ2VkICYmXG4gICAgICAgICAgICAgICAgIShlLnJlbGF0ZWRUYXJnZXQgJiYgaXNDYWxlbmRhckVsZW0oZS5yZWxhdGVkVGFyZ2V0KSkpIHtcbiAgICAgICAgICAgICAgICBzZWxmLnNldERhdGUoc2VsZi5faW5wdXQudmFsdWUsIHRydWUsIGUudGFyZ2V0ID09PSBzZWxmLmFsdElucHV0XG4gICAgICAgICAgICAgICAgICAgID8gc2VsZi5jb25maWcuYWx0Rm9ybWF0XG4gICAgICAgICAgICAgICAgICAgIDogc2VsZi5jb25maWcuZGF0ZUZvcm1hdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gb25LZXlEb3duKGUpIHtcbiAgICAgICAgICAgIC8vIGUua2V5ICAgICAgICAgICAgICAgICAgICAgIGUua2V5Q29kZVxuICAgICAgICAgICAgLy8gXCJCYWNrc3BhY2VcIiAgICAgICAgICAgICAgICAgICAgICAgIDhcbiAgICAgICAgICAgIC8vIFwiVGFiXCIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA5XG4gICAgICAgICAgICAvLyBcIkVudGVyXCIgICAgICAgICAgICAgICAgICAgICAgICAgICAxM1xuICAgICAgICAgICAgLy8gXCJFc2NhcGVcIiAgICAgKElFIFwiRXNjXCIpICAgICAgICAgICAyN1xuICAgICAgICAgICAgLy8gXCJBcnJvd0xlZnRcIiAgKElFIFwiTGVmdFwiKSAgICAgICAgICAzN1xuICAgICAgICAgICAgLy8gXCJBcnJvd1VwXCIgICAgKElFIFwiVXBcIikgICAgICAgICAgICAzOFxuICAgICAgICAgICAgLy8gXCJBcnJvd1JpZ2h0XCIgKElFIFwiUmlnaHRcIikgICAgICAgICAzOVxuICAgICAgICAgICAgLy8gXCJBcnJvd0Rvd25cIiAgKElFIFwiRG93blwiKSAgICAgICAgICA0MFxuICAgICAgICAgICAgLy8gXCJEZWxldGVcIiAgICAgKElFIFwiRGVsXCIpICAgICAgICAgICA0NlxuICAgICAgICAgICAgdmFyIGV2ZW50VGFyZ2V0ID0gZ2V0RXZlbnRUYXJnZXQoZSk7XG4gICAgICAgICAgICB2YXIgaXNJbnB1dCA9IHNlbGYuY29uZmlnLndyYXBcbiAgICAgICAgICAgICAgICA/IGVsZW1lbnQuY29udGFpbnMoZXZlbnRUYXJnZXQpXG4gICAgICAgICAgICAgICAgOiBldmVudFRhcmdldCA9PT0gc2VsZi5faW5wdXQ7XG4gICAgICAgICAgICB2YXIgYWxsb3dJbnB1dCA9IHNlbGYuY29uZmlnLmFsbG93SW5wdXQ7XG4gICAgICAgICAgICB2YXIgYWxsb3dLZXlkb3duID0gc2VsZi5pc09wZW4gJiYgKCFhbGxvd0lucHV0IHx8ICFpc0lucHV0KTtcbiAgICAgICAgICAgIHZhciBhbGxvd0lubGluZUtleWRvd24gPSBzZWxmLmNvbmZpZy5pbmxpbmUgJiYgaXNJbnB1dCAmJiAhYWxsb3dJbnB1dDtcbiAgICAgICAgICAgIGlmIChlLmtleUNvZGUgPT09IDEzICYmIGlzSW5wdXQpIHtcbiAgICAgICAgICAgICAgICBpZiAoYWxsb3dJbnB1dCkge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLnNldERhdGUoc2VsZi5faW5wdXQudmFsdWUsIHRydWUsIGV2ZW50VGFyZ2V0ID09PSBzZWxmLmFsdElucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICA/IHNlbGYuY29uZmlnLmFsdEZvcm1hdFxuICAgICAgICAgICAgICAgICAgICAgICAgOiBzZWxmLmNvbmZpZy5kYXRlRm9ybWF0KTtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5jbG9zZSgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXZlbnRUYXJnZXQuYmx1cigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5vcGVuKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaXNDYWxlbmRhckVsZW0oZXZlbnRUYXJnZXQpIHx8XG4gICAgICAgICAgICAgICAgYWxsb3dLZXlkb3duIHx8XG4gICAgICAgICAgICAgICAgYWxsb3dJbmxpbmVLZXlkb3duKSB7XG4gICAgICAgICAgICAgICAgdmFyIGlzVGltZU9iaiA9ICEhc2VsZi50aW1lQ29udGFpbmVyICYmXG4gICAgICAgICAgICAgICAgICAgIHNlbGYudGltZUNvbnRhaW5lci5jb250YWlucyhldmVudFRhcmdldCk7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlLmtleUNvZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxMzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1RpbWVPYmopIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlVGltZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvY3VzQW5kQ2xvc2UoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3REYXRlKGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjc6IC8vIGVzY2FwZVxuICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9jdXNBbmRDbG9zZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgODpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0NjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0lucHV0ICYmICFzZWxmLmNvbmZpZy5hbGxvd0lucHV0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY2xlYXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDM3OlxuICAgICAgICAgICAgICAgICAgICBjYXNlIDM5OlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1RpbWVPYmogJiYgIWlzSW5wdXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFjdGl2ZUVsZW1lbnQgPSBnZXRDbG9zZXN0QWN0aXZlRWxlbWVudCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLmRheXNDb250YWluZXIgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYWxsb3dJbnB1dCA9PT0gZmFsc2UgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhY3RpdmVFbGVtZW50ICYmIGlzSW5WaWV3KGFjdGl2ZUVsZW1lbnQpKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRlbHRhXzEgPSBlLmtleUNvZGUgPT09IDM5ID8gMSA6IC0xO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWUuY3RybEtleSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvY3VzT25EYXkodW5kZWZpbmVkLCBkZWx0YV8xKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlTW9udGgoZGVsdGFfMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb2N1c09uRGF5KGdldEZpcnN0QXZhaWxhYmxlRGF5KDEpLCAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHNlbGYuaG91ckVsZW1lbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5ob3VyRWxlbWVudC5mb2N1cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMzg6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNDA6XG4gICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVsdGEgPSBlLmtleUNvZGUgPT09IDQwID8gMSA6IC0xO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChzZWxmLmRheXNDb250YWluZXIgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudFRhcmdldC4kaSAhPT0gdW5kZWZpbmVkKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50VGFyZ2V0ID09PSBzZWxmLmlucHV0IHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRUYXJnZXQgPT09IHNlbGYuYWx0SW5wdXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZS5jdHJsS2V5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZVllYXIoc2VsZi5jdXJyZW50WWVhciAtIGRlbHRhKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9jdXNPbkRheShnZXRGaXJzdEF2YWlsYWJsZURheSgxKSwgMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFpc1RpbWVPYmopXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvY3VzT25EYXkodW5kZWZpbmVkLCBkZWx0YSAqIDcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoZXZlbnRUYXJnZXQgPT09IHNlbGYuY3VycmVudFllYXJFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlWWVhcihzZWxmLmN1cnJlbnRZZWFyIC0gZGVsdGEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoc2VsZi5jb25maWcuZW5hYmxlVGltZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNUaW1lT2JqICYmIHNlbGYuaG91ckVsZW1lbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuaG91ckVsZW1lbnQuZm9jdXMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVUaW1lKGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2RlYm91bmNlZENoYW5nZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgOTpcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1RpbWVPYmopIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbXMgPSBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuaG91ckVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubWludXRlRWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5zZWNvbmRFbGVtZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmFtUE0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KHNlbGYucGx1Z2luRWxlbWVudHMpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5maWx0ZXIoZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHg7IH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpID0gZWxlbXMuaW5kZXhPZihldmVudFRhcmdldCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSBlbGVtc1tpICsgKGUuc2hpZnRLZXkgPyAtMSA6IDEpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodGFyZ2V0IHx8IHNlbGYuX2lucHV0KS5mb2N1cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFzZWxmLmNvbmZpZy5ub0NhbGVuZGFyICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5kYXlzQ29udGFpbmVyICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5kYXlzQ29udGFpbmVyLmNvbnRhaW5zKGV2ZW50VGFyZ2V0KSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUuc2hpZnRLZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5faW5wdXQuZm9jdXMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzZWxmLmFtUE0gIT09IHVuZGVmaW5lZCAmJiBldmVudFRhcmdldCA9PT0gc2VsZi5hbVBNKSB7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlLmtleSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIHNlbGYubDEwbi5hbVBNWzBdLmNoYXJBdCgwKTpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBzZWxmLmwxMG4uYW1QTVswXS5jaGFyQXQoMCkudG9Mb3dlckNhc2UoKTpcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuYW1QTS50ZXh0Q29udGVudCA9IHNlbGYubDEwbi5hbVBNWzBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0SG91cnNGcm9tSW5wdXRzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVWYWx1ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2Ugc2VsZi5sMTBuLmFtUE1bMV0uY2hhckF0KDApOlxuICAgICAgICAgICAgICAgICAgICBjYXNlIHNlbGYubDEwbi5hbVBNWzFdLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpOlxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5hbVBNLnRleHRDb250ZW50ID0gc2VsZi5sMTBuLmFtUE1bMV07XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRIb3Vyc0Zyb21JbnB1dHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZVZhbHVlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNJbnB1dCB8fCBpc0NhbGVuZGFyRWxlbShldmVudFRhcmdldCkpIHtcbiAgICAgICAgICAgICAgICB0cmlnZ2VyRXZlbnQoXCJvbktleURvd25cIiwgZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gb25Nb3VzZU92ZXIoZWxlbSwgY2VsbENsYXNzKSB7XG4gICAgICAgICAgICBpZiAoY2VsbENsYXNzID09PSB2b2lkIDApIHsgY2VsbENsYXNzID0gXCJmbGF0cGlja3ItZGF5XCI7IH1cbiAgICAgICAgICAgIGlmIChzZWxmLnNlbGVjdGVkRGF0ZXMubGVuZ3RoICE9PSAxIHx8XG4gICAgICAgICAgICAgICAgKGVsZW0gJiZcbiAgICAgICAgICAgICAgICAgICAgKCFlbGVtLmNsYXNzTGlzdC5jb250YWlucyhjZWxsQ2xhc3MpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtLmNsYXNzTGlzdC5jb250YWlucyhcImZsYXRwaWNrci1kaXNhYmxlZFwiKSkpKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIHZhciBob3ZlckRhdGUgPSBlbGVtXG4gICAgICAgICAgICAgICAgPyBlbGVtLmRhdGVPYmouZ2V0VGltZSgpXG4gICAgICAgICAgICAgICAgOiBzZWxmLmRheXMuZmlyc3RFbGVtZW50Q2hpbGQuZGF0ZU9iai5nZXRUaW1lKCksIGluaXRpYWxEYXRlID0gc2VsZi5wYXJzZURhdGUoc2VsZi5zZWxlY3RlZERhdGVzWzBdLCB1bmRlZmluZWQsIHRydWUpLmdldFRpbWUoKSwgcmFuZ2VTdGFydERhdGUgPSBNYXRoLm1pbihob3ZlckRhdGUsIHNlbGYuc2VsZWN0ZWREYXRlc1swXS5nZXRUaW1lKCkpLCByYW5nZUVuZERhdGUgPSBNYXRoLm1heChob3ZlckRhdGUsIHNlbGYuc2VsZWN0ZWREYXRlc1swXS5nZXRUaW1lKCkpO1xuICAgICAgICAgICAgdmFyIGNvbnRhaW5zRGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHZhciBtaW5SYW5nZSA9IDAsIG1heFJhbmdlID0gMDtcbiAgICAgICAgICAgIGZvciAodmFyIHQgPSByYW5nZVN0YXJ0RGF0ZTsgdCA8IHJhbmdlRW5kRGF0ZTsgdCArPSBkdXJhdGlvbi5EQVkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWlzRW5hYmxlZChuZXcgRGF0ZSh0KSwgdHJ1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGFpbnNEaXNhYmxlZCA9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250YWluc0Rpc2FibGVkIHx8ICh0ID4gcmFuZ2VTdGFydERhdGUgJiYgdCA8IHJhbmdlRW5kRGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0IDwgaW5pdGlhbERhdGUgJiYgKCFtaW5SYW5nZSB8fCB0ID4gbWluUmFuZ2UpKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWluUmFuZ2UgPSB0O1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0ID4gaW5pdGlhbERhdGUgJiYgKCFtYXhSYW5nZSB8fCB0IDwgbWF4UmFuZ2UpKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWF4UmFuZ2UgPSB0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBob3ZlcmFibGVDZWxscyA9IEFycmF5LmZyb20oc2VsZi5yQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXCIqOm50aC1jaGlsZCgtbitcIiArIHNlbGYuY29uZmlnLnNob3dNb250aHMgKyBcIikgPiAuXCIgKyBjZWxsQ2xhc3MpKTtcbiAgICAgICAgICAgIGhvdmVyYWJsZUNlbGxzLmZvckVhY2goZnVuY3Rpb24gKGRheUVsZW0pIHtcbiAgICAgICAgICAgICAgICB2YXIgZGF0ZSA9IGRheUVsZW0uZGF0ZU9iajtcbiAgICAgICAgICAgICAgICB2YXIgdGltZXN0YW1wID0gZGF0ZS5nZXRUaW1lKCk7XG4gICAgICAgICAgICAgICAgdmFyIG91dE9mUmFuZ2UgPSAobWluUmFuZ2UgPiAwICYmIHRpbWVzdGFtcCA8IG1pblJhbmdlKSB8fFxuICAgICAgICAgICAgICAgICAgICAobWF4UmFuZ2UgPiAwICYmIHRpbWVzdGFtcCA+IG1heFJhbmdlKTtcbiAgICAgICAgICAgICAgICBpZiAob3V0T2ZSYW5nZSkge1xuICAgICAgICAgICAgICAgICAgICBkYXlFbGVtLmNsYXNzTGlzdC5hZGQoXCJub3RBbGxvd2VkXCIpO1xuICAgICAgICAgICAgICAgICAgICBbXCJpblJhbmdlXCIsIFwic3RhcnRSYW5nZVwiLCBcImVuZFJhbmdlXCJdLmZvckVhY2goZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRheUVsZW0uY2xhc3NMaXN0LnJlbW92ZShjKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoY29udGFpbnNEaXNhYmxlZCAmJiAhb3V0T2ZSYW5nZSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIFtcInN0YXJ0UmFuZ2VcIiwgXCJpblJhbmdlXCIsIFwiZW5kUmFuZ2VcIiwgXCJub3RBbGxvd2VkXCJdLmZvckVhY2goZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF5RWxlbS5jbGFzc0xpc3QucmVtb3ZlKGMpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmIChlbGVtICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbS5jbGFzc0xpc3QuYWRkKGhvdmVyRGF0ZSA8PSBzZWxmLnNlbGVjdGVkRGF0ZXNbMF0uZ2V0VGltZSgpXG4gICAgICAgICAgICAgICAgICAgICAgICA/IFwic3RhcnRSYW5nZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICA6IFwiZW5kUmFuZ2VcIik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbml0aWFsRGF0ZSA8IGhvdmVyRGF0ZSAmJiB0aW1lc3RhbXAgPT09IGluaXRpYWxEYXRlKVxuICAgICAgICAgICAgICAgICAgICAgICAgZGF5RWxlbS5jbGFzc0xpc3QuYWRkKFwic3RhcnRSYW5nZVwiKTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoaW5pdGlhbERhdGUgPiBob3ZlckRhdGUgJiYgdGltZXN0YW1wID09PSBpbml0aWFsRGF0ZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGRheUVsZW0uY2xhc3NMaXN0LmFkZChcImVuZFJhbmdlXCIpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGltZXN0YW1wID49IG1pblJhbmdlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAobWF4UmFuZ2UgPT09IDAgfHwgdGltZXN0YW1wIDw9IG1heFJhbmdlKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgaXNCZXR3ZWVuKHRpbWVzdGFtcCwgaW5pdGlhbERhdGUsIGhvdmVyRGF0ZSkpXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXlFbGVtLmNsYXNzTGlzdC5hZGQoXCJpblJhbmdlXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG9uUmVzaXplKCkge1xuICAgICAgICAgICAgaWYgKHNlbGYuaXNPcGVuICYmICFzZWxmLmNvbmZpZy5zdGF0aWMgJiYgIXNlbGYuY29uZmlnLmlubGluZSlcbiAgICAgICAgICAgICAgICBwb3NpdGlvbkNhbGVuZGFyKCk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gb3BlbihlLCBwb3NpdGlvbkVsZW1lbnQpIHtcbiAgICAgICAgICAgIGlmIChwb3NpdGlvbkVsZW1lbnQgPT09IHZvaWQgMCkgeyBwb3NpdGlvbkVsZW1lbnQgPSBzZWxmLl9wb3NpdGlvbkVsZW1lbnQ7IH1cbiAgICAgICAgICAgIGlmIChzZWxmLmlzTW9iaWxlID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXZlbnRUYXJnZXQgPSBnZXRFdmVudFRhcmdldChlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50VGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudFRhcmdldC5ibHVyKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHNlbGYubW9iaWxlSW5wdXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLm1vYmlsZUlucHV0LmZvY3VzKCk7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYubW9iaWxlSW5wdXQuY2xpY2soKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdHJpZ2dlckV2ZW50KFwib25PcGVuXCIpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHNlbGYuX2lucHV0LmRpc2FibGVkIHx8IHNlbGYuY29uZmlnLmlubGluZSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB3YXNPcGVuID0gc2VsZi5pc09wZW47XG4gICAgICAgICAgICBzZWxmLmlzT3BlbiA9IHRydWU7XG4gICAgICAgICAgICBpZiAoIXdhc09wZW4pIHtcbiAgICAgICAgICAgICAgICBzZWxmLmNhbGVuZGFyQ29udGFpbmVyLmNsYXNzTGlzdC5hZGQoXCJvcGVuXCIpO1xuICAgICAgICAgICAgICAgIHNlbGYuX2lucHV0LmNsYXNzTGlzdC5hZGQoXCJhY3RpdmVcIik7XG4gICAgICAgICAgICAgICAgdHJpZ2dlckV2ZW50KFwib25PcGVuXCIpO1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uQ2FsZW5kYXIocG9zaXRpb25FbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzZWxmLmNvbmZpZy5lbmFibGVUaW1lID09PSB0cnVlICYmIHNlbGYuY29uZmlnLm5vQ2FsZW5kYXIgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5jb25maWcuYWxsb3dJbnB1dCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICAgICAgKGUgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgIXNlbGYudGltZUNvbnRhaW5lci5jb250YWlucyhlLnJlbGF0ZWRUYXJnZXQpKSkge1xuICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNlbGYuaG91ckVsZW1lbnQuc2VsZWN0KCk7IH0sIDUwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gbWluTWF4RGF0ZVNldHRlcih0eXBlKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGRhdGUpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGF0ZU9iaiA9IChzZWxmLmNvbmZpZ1tcIl9cIiArIHR5cGUgKyBcIkRhdGVcIl0gPSBzZWxmLnBhcnNlRGF0ZShkYXRlLCBzZWxmLmNvbmZpZy5kYXRlRm9ybWF0KSk7XG4gICAgICAgICAgICAgICAgdmFyIGludmVyc2VEYXRlT2JqID0gc2VsZi5jb25maWdbXCJfXCIgKyAodHlwZSA9PT0gXCJtaW5cIiA/IFwibWF4XCIgOiBcIm1pblwiKSArIFwiRGF0ZVwiXTtcbiAgICAgICAgICAgICAgICBpZiAoZGF0ZU9iaiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGZbdHlwZSA9PT0gXCJtaW5cIiA/IFwibWluRGF0ZUhhc1RpbWVcIiA6IFwibWF4RGF0ZUhhc1RpbWVcIl0gPVxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0ZU9iai5nZXRIb3VycygpID4gMCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGVPYmouZ2V0TWludXRlcygpID4gMCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGVPYmouZ2V0U2Vjb25kcygpID4gMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHNlbGYuc2VsZWN0ZWREYXRlcykge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLnNlbGVjdGVkRGF0ZXMgPSBzZWxmLnNlbGVjdGVkRGF0ZXMuZmlsdGVyKGZ1bmN0aW9uIChkKSB7IHJldHVybiBpc0VuYWJsZWQoZCk7IH0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXNlbGYuc2VsZWN0ZWREYXRlcy5sZW5ndGggJiYgdHlwZSA9PT0gXCJtaW5cIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldEhvdXJzRnJvbURhdGUoZGF0ZU9iaik7XG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZVZhbHVlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzZWxmLmRheXNDb250YWluZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVkcmF3KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRlT2JqICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmN1cnJlbnRZZWFyRWxlbWVudFt0eXBlXSA9IGRhdGVPYmouZ2V0RnVsbFllYXIoKS50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmN1cnJlbnRZZWFyRWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUodHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuY3VycmVudFllYXJFbGVtZW50LmRpc2FibGVkID1cbiAgICAgICAgICAgICAgICAgICAgICAgICEhaW52ZXJzZURhdGVPYmogJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRlT2JqICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnZlcnNlRGF0ZU9iai5nZXRGdWxsWWVhcigpID09PSBkYXRlT2JqLmdldEZ1bGxZZWFyKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBwYXJzZUNvbmZpZygpIHtcbiAgICAgICAgICAgIHZhciBib29sT3B0cyA9IFtcbiAgICAgICAgICAgICAgICBcIndyYXBcIixcbiAgICAgICAgICAgICAgICBcIndlZWtOdW1iZXJzXCIsXG4gICAgICAgICAgICAgICAgXCJhbGxvd0lucHV0XCIsXG4gICAgICAgICAgICAgICAgXCJhbGxvd0ludmFsaWRQcmVsb2FkXCIsXG4gICAgICAgICAgICAgICAgXCJjbGlja09wZW5zXCIsXG4gICAgICAgICAgICAgICAgXCJ0aW1lXzI0aHJcIixcbiAgICAgICAgICAgICAgICBcImVuYWJsZVRpbWVcIixcbiAgICAgICAgICAgICAgICBcIm5vQ2FsZW5kYXJcIixcbiAgICAgICAgICAgICAgICBcImFsdElucHV0XCIsXG4gICAgICAgICAgICAgICAgXCJzaG9ydGhhbmRDdXJyZW50TW9udGhcIixcbiAgICAgICAgICAgICAgICBcImlubGluZVwiLFxuICAgICAgICAgICAgICAgIFwic3RhdGljXCIsXG4gICAgICAgICAgICAgICAgXCJlbmFibGVTZWNvbmRzXCIsXG4gICAgICAgICAgICAgICAgXCJkaXNhYmxlTW9iaWxlXCIsXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgdmFyIHVzZXJDb25maWcgPSBfX2Fzc2lnbihfX2Fzc2lnbih7fSwgSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShlbGVtZW50LmRhdGFzZXQgfHwge30pKSksIGluc3RhbmNlQ29uZmlnKTtcbiAgICAgICAgICAgIHZhciBmb3JtYXRzID0ge307XG4gICAgICAgICAgICBzZWxmLmNvbmZpZy5wYXJzZURhdGUgPSB1c2VyQ29uZmlnLnBhcnNlRGF0ZTtcbiAgICAgICAgICAgIHNlbGYuY29uZmlnLmZvcm1hdERhdGUgPSB1c2VyQ29uZmlnLmZvcm1hdERhdGU7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoc2VsZi5jb25maWcsIFwiZW5hYmxlXCIsIHtcbiAgICAgICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNlbGYuY29uZmlnLl9lbmFibGU7IH0sXG4gICAgICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAoZGF0ZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5jb25maWcuX2VuYWJsZSA9IHBhcnNlRGF0ZVJ1bGVzKGRhdGVzKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoc2VsZi5jb25maWcsIFwiZGlzYWJsZVwiLCB7XG4gICAgICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBzZWxmLmNvbmZpZy5fZGlzYWJsZTsgfSxcbiAgICAgICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uIChkYXRlcykge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZy5fZGlzYWJsZSA9IHBhcnNlRGF0ZVJ1bGVzKGRhdGVzKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2YXIgdGltZU1vZGUgPSB1c2VyQ29uZmlnLm1vZGUgPT09IFwidGltZVwiO1xuICAgICAgICAgICAgaWYgKCF1c2VyQ29uZmlnLmRhdGVGb3JtYXQgJiYgKHVzZXJDb25maWcuZW5hYmxlVGltZSB8fCB0aW1lTW9kZSkpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGVmYXVsdERhdGVGb3JtYXQgPSBmbGF0cGlja3IuZGVmYXVsdENvbmZpZy5kYXRlRm9ybWF0IHx8IGRlZmF1bHRzLmRhdGVGb3JtYXQ7XG4gICAgICAgICAgICAgICAgZm9ybWF0cy5kYXRlRm9ybWF0ID1cbiAgICAgICAgICAgICAgICAgICAgdXNlckNvbmZpZy5ub0NhbGVuZGFyIHx8IHRpbWVNb2RlXG4gICAgICAgICAgICAgICAgICAgICAgICA/IFwiSDppXCIgKyAodXNlckNvbmZpZy5lbmFibGVTZWNvbmRzID8gXCI6U1wiIDogXCJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIDogZGVmYXVsdERhdGVGb3JtYXQgKyBcIiBIOmlcIiArICh1c2VyQ29uZmlnLmVuYWJsZVNlY29uZHMgPyBcIjpTXCIgOiBcIlwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh1c2VyQ29uZmlnLmFsdElucHV0ICYmXG4gICAgICAgICAgICAgICAgKHVzZXJDb25maWcuZW5hYmxlVGltZSB8fCB0aW1lTW9kZSkgJiZcbiAgICAgICAgICAgICAgICAhdXNlckNvbmZpZy5hbHRGb3JtYXQpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGVmYXVsdEFsdEZvcm1hdCA9IGZsYXRwaWNrci5kZWZhdWx0Q29uZmlnLmFsdEZvcm1hdCB8fCBkZWZhdWx0cy5hbHRGb3JtYXQ7XG4gICAgICAgICAgICAgICAgZm9ybWF0cy5hbHRGb3JtYXQgPVxuICAgICAgICAgICAgICAgICAgICB1c2VyQ29uZmlnLm5vQ2FsZW5kYXIgfHwgdGltZU1vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgID8gXCJoOmlcIiArICh1c2VyQ29uZmlnLmVuYWJsZVNlY29uZHMgPyBcIjpTIEtcIiA6IFwiIEtcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIDogZGVmYXVsdEFsdEZvcm1hdCArIChcIiBoOmlcIiArICh1c2VyQ29uZmlnLmVuYWJsZVNlY29uZHMgPyBcIjpTXCIgOiBcIlwiKSArIFwiIEtcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoc2VsZi5jb25maWcsIFwibWluRGF0ZVwiLCB7XG4gICAgICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBzZWxmLmNvbmZpZy5fbWluRGF0ZTsgfSxcbiAgICAgICAgICAgICAgICBzZXQ6IG1pbk1heERhdGVTZXR0ZXIoXCJtaW5cIiksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzZWxmLmNvbmZpZywgXCJtYXhEYXRlXCIsIHtcbiAgICAgICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNlbGYuY29uZmlnLl9tYXhEYXRlOyB9LFxuICAgICAgICAgICAgICAgIHNldDogbWluTWF4RGF0ZVNldHRlcihcIm1heFwiKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdmFyIG1pbk1heFRpbWVTZXR0ZXIgPSBmdW5jdGlvbiAodHlwZSkgeyByZXR1cm4gZnVuY3Rpb24gKHZhbCkge1xuICAgICAgICAgICAgICAgIHNlbGYuY29uZmlnW3R5cGUgPT09IFwibWluXCIgPyBcIl9taW5UaW1lXCIgOiBcIl9tYXhUaW1lXCJdID0gc2VsZi5wYXJzZURhdGUodmFsLCBcIkg6aTpTXCIpO1xuICAgICAgICAgICAgfTsgfTtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzZWxmLmNvbmZpZywgXCJtaW5UaW1lXCIsIHtcbiAgICAgICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNlbGYuY29uZmlnLl9taW5UaW1lOyB9LFxuICAgICAgICAgICAgICAgIHNldDogbWluTWF4VGltZVNldHRlcihcIm1pblwiKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHNlbGYuY29uZmlnLCBcIm1heFRpbWVcIiwge1xuICAgICAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gc2VsZi5jb25maWcuX21heFRpbWU7IH0sXG4gICAgICAgICAgICAgICAgc2V0OiBtaW5NYXhUaW1lU2V0dGVyKFwibWF4XCIpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAodXNlckNvbmZpZy5tb2RlID09PSBcInRpbWVcIikge1xuICAgICAgICAgICAgICAgIHNlbGYuY29uZmlnLm5vQ2FsZW5kYXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHNlbGYuY29uZmlnLmVuYWJsZVRpbWUgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihzZWxmLmNvbmZpZywgZm9ybWF0cywgdXNlckNvbmZpZyk7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJvb2xPcHRzLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvVHlwZVNjcmlwdC9pc3N1ZXMvMzE2NjNcbiAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZ1tib29sT3B0c1tpXV0gPVxuICAgICAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZ1tib29sT3B0c1tpXV0gPT09IHRydWUgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY29uZmlnW2Jvb2xPcHRzW2ldXSA9PT0gXCJ0cnVlXCI7XG4gICAgICAgICAgICBIT09LUy5maWx0ZXIoZnVuY3Rpb24gKGhvb2spIHsgcmV0dXJuIHNlbGYuY29uZmlnW2hvb2tdICE9PSB1bmRlZmluZWQ7IH0pLmZvckVhY2goZnVuY3Rpb24gKGhvb2spIHtcbiAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZ1tob29rXSA9IGFycmF5aWZ5KHNlbGYuY29uZmlnW2hvb2tdIHx8IFtdKS5tYXAoYmluZFRvSW5zdGFuY2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBzZWxmLmlzTW9iaWxlID1cbiAgICAgICAgICAgICAgICAhc2VsZi5jb25maWcuZGlzYWJsZU1vYmlsZSAmJlxuICAgICAgICAgICAgICAgICAgICAhc2VsZi5jb25maWcuaW5saW5lICYmXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuY29uZmlnLm1vZGUgPT09IFwic2luZ2xlXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgIXNlbGYuY29uZmlnLmRpc2FibGUubGVuZ3RoICYmXG4gICAgICAgICAgICAgICAgICAgICFzZWxmLmNvbmZpZy5lbmFibGUgJiZcbiAgICAgICAgICAgICAgICAgICAgIXNlbGYuY29uZmlnLndlZWtOdW1iZXJzICYmXG4gICAgICAgICAgICAgICAgICAgIC9BbmRyb2lkfHdlYk9TfGlQaG9uZXxpUGFkfGlQb2R8QmxhY2tCZXJyeXxJRU1vYmlsZXxPcGVyYSBNaW5pL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2VsZi5jb25maWcucGx1Z2lucy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHZhciBwbHVnaW5Db25mID0gc2VsZi5jb25maWcucGx1Z2luc1tpXShzZWxmKSB8fCB7fTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gcGx1Z2luQ29uZikge1xuICAgICAgICAgICAgICAgICAgICBpZiAoSE9PS1MuaW5kZXhPZihrZXkpID4gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY29uZmlnW2tleV0gPSBhcnJheWlmeShwbHVnaW5Db25mW2tleV0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLm1hcChiaW5kVG9JbnN0YW5jZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KHNlbGYuY29uZmlnW2tleV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB1c2VyQ29uZmlnW2tleV0gPT09IFwidW5kZWZpbmVkXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZ1trZXldID0gcGx1Z2luQ29uZltrZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghdXNlckNvbmZpZy5hbHRJbnB1dENsYXNzKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5jb25maWcuYWx0SW5wdXRDbGFzcyA9XG4gICAgICAgICAgICAgICAgICAgIGdldElucHV0RWxlbSgpLmNsYXNzTmFtZSArIFwiIFwiICsgc2VsZi5jb25maWcuYWx0SW5wdXRDbGFzcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRyaWdnZXJFdmVudChcIm9uUGFyc2VDb25maWdcIik7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gZ2V0SW5wdXRFbGVtKCkge1xuICAgICAgICAgICAgcmV0dXJuIHNlbGYuY29uZmlnLndyYXBcbiAgICAgICAgICAgICAgICA/IGVsZW1lbnQucXVlcnlTZWxlY3RvcihcIltkYXRhLWlucHV0XVwiKVxuICAgICAgICAgICAgICAgIDogZWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBzZXR1cExvY2FsZSgpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc2VsZi5jb25maWcubG9jYWxlICE9PSBcIm9iamVjdFwiICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIGZsYXRwaWNrci5sMTBuc1tzZWxmLmNvbmZpZy5sb2NhbGVdID09PSBcInVuZGVmaW5lZFwiKVxuICAgICAgICAgICAgICAgIHNlbGYuY29uZmlnLmVycm9ySGFuZGxlcihuZXcgRXJyb3IoXCJmbGF0cGlja3I6IGludmFsaWQgbG9jYWxlIFwiICsgc2VsZi5jb25maWcubG9jYWxlKSk7XG4gICAgICAgICAgICBzZWxmLmwxMG4gPSBfX2Fzc2lnbihfX2Fzc2lnbih7fSwgZmxhdHBpY2tyLmwxMG5zLmRlZmF1bHQpLCAodHlwZW9mIHNlbGYuY29uZmlnLmxvY2FsZSA9PT0gXCJvYmplY3RcIlxuICAgICAgICAgICAgICAgID8gc2VsZi5jb25maWcubG9jYWxlXG4gICAgICAgICAgICAgICAgOiBzZWxmLmNvbmZpZy5sb2NhbGUgIT09IFwiZGVmYXVsdFwiXG4gICAgICAgICAgICAgICAgICAgID8gZmxhdHBpY2tyLmwxMG5zW3NlbGYuY29uZmlnLmxvY2FsZV1cbiAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQpKTtcbiAgICAgICAgICAgIHRva2VuUmVnZXguRCA9IFwiKFwiICsgc2VsZi5sMTBuLndlZWtkYXlzLnNob3J0aGFuZC5qb2luKFwifFwiKSArIFwiKVwiO1xuICAgICAgICAgICAgdG9rZW5SZWdleC5sID0gXCIoXCIgKyBzZWxmLmwxMG4ud2Vla2RheXMubG9uZ2hhbmQuam9pbihcInxcIikgKyBcIilcIjtcbiAgICAgICAgICAgIHRva2VuUmVnZXguTSA9IFwiKFwiICsgc2VsZi5sMTBuLm1vbnRocy5zaG9ydGhhbmQuam9pbihcInxcIikgKyBcIilcIjtcbiAgICAgICAgICAgIHRva2VuUmVnZXguRiA9IFwiKFwiICsgc2VsZi5sMTBuLm1vbnRocy5sb25naGFuZC5qb2luKFwifFwiKSArIFwiKVwiO1xuICAgICAgICAgICAgdG9rZW5SZWdleC5LID0gXCIoXCIgKyBzZWxmLmwxMG4uYW1QTVswXSArIFwifFwiICsgc2VsZi5sMTBuLmFtUE1bMV0gKyBcInxcIiArIHNlbGYubDEwbi5hbVBNWzBdLnRvTG93ZXJDYXNlKCkgKyBcInxcIiArIHNlbGYubDEwbi5hbVBNWzFdLnRvTG93ZXJDYXNlKCkgKyBcIilcIjtcbiAgICAgICAgICAgIHZhciB1c2VyQ29uZmlnID0gX19hc3NpZ24oX19hc3NpZ24oe30sIGluc3RhbmNlQ29uZmlnKSwgSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShlbGVtZW50LmRhdGFzZXQgfHwge30pKSk7XG4gICAgICAgICAgICBpZiAodXNlckNvbmZpZy50aW1lXzI0aHIgPT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgICAgIGZsYXRwaWNrci5kZWZhdWx0Q29uZmlnLnRpbWVfMjRociA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5jb25maWcudGltZV8yNGhyID0gc2VsZi5sMTBuLnRpbWVfMjRocjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNlbGYuZm9ybWF0RGF0ZSA9IGNyZWF0ZURhdGVGb3JtYXR0ZXIoc2VsZik7XG4gICAgICAgICAgICBzZWxmLnBhcnNlRGF0ZSA9IGNyZWF0ZURhdGVQYXJzZXIoeyBjb25maWc6IHNlbGYuY29uZmlnLCBsMTBuOiBzZWxmLmwxMG4gfSk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gcG9zaXRpb25DYWxlbmRhcihjdXN0b21Qb3NpdGlvbkVsZW1lbnQpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc2VsZi5jb25maWcucG9zaXRpb24gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgIHJldHVybiB2b2lkIHNlbGYuY29uZmlnLnBvc2l0aW9uKHNlbGYsIGN1c3RvbVBvc2l0aW9uRWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc2VsZi5jYWxlbmRhckNvbnRhaW5lciA9PT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIHRyaWdnZXJFdmVudChcIm9uUHJlQ2FsZW5kYXJQb3NpdGlvblwiKTtcbiAgICAgICAgICAgIHZhciBwb3NpdGlvbkVsZW1lbnQgPSBjdXN0b21Qb3NpdGlvbkVsZW1lbnQgfHwgc2VsZi5fcG9zaXRpb25FbGVtZW50O1xuICAgICAgICAgICAgdmFyIGNhbGVuZGFySGVpZ2h0ID0gQXJyYXkucHJvdG90eXBlLnJlZHVjZS5jYWxsKHNlbGYuY2FsZW5kYXJDb250YWluZXIuY2hpbGRyZW4sIChmdW5jdGlvbiAoYWNjLCBjaGlsZCkgeyByZXR1cm4gYWNjICsgY2hpbGQub2Zmc2V0SGVpZ2h0OyB9KSwgMCksIGNhbGVuZGFyV2lkdGggPSBzZWxmLmNhbGVuZGFyQ29udGFpbmVyLm9mZnNldFdpZHRoLCBjb25maWdQb3MgPSBzZWxmLmNvbmZpZy5wb3NpdGlvbi5zcGxpdChcIiBcIiksIGNvbmZpZ1Bvc1ZlcnRpY2FsID0gY29uZmlnUG9zWzBdLCBjb25maWdQb3NIb3Jpem9udGFsID0gY29uZmlnUG9zLmxlbmd0aCA+IDEgPyBjb25maWdQb3NbMV0gOiBudWxsLCBpbnB1dEJvdW5kcyA9IHBvc2l0aW9uRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSwgZGlzdGFuY2VGcm9tQm90dG9tID0gd2luZG93LmlubmVySGVpZ2h0IC0gaW5wdXRCb3VuZHMuYm90dG9tLCBzaG93T25Ub3AgPSBjb25maWdQb3NWZXJ0aWNhbCA9PT0gXCJhYm92ZVwiIHx8XG4gICAgICAgICAgICAgICAgKGNvbmZpZ1Bvc1ZlcnRpY2FsICE9PSBcImJlbG93XCIgJiZcbiAgICAgICAgICAgICAgICAgICAgZGlzdGFuY2VGcm9tQm90dG9tIDwgY2FsZW5kYXJIZWlnaHQgJiZcbiAgICAgICAgICAgICAgICAgICAgaW5wdXRCb3VuZHMudG9wID4gY2FsZW5kYXJIZWlnaHQpO1xuICAgICAgICAgICAgdmFyIHRvcCA9IHdpbmRvdy5wYWdlWU9mZnNldCArXG4gICAgICAgICAgICAgICAgaW5wdXRCb3VuZHMudG9wICtcbiAgICAgICAgICAgICAgICAoIXNob3dPblRvcCA/IHBvc2l0aW9uRWxlbWVudC5vZmZzZXRIZWlnaHQgKyAyIDogLWNhbGVuZGFySGVpZ2h0IC0gMik7XG4gICAgICAgICAgICB0b2dnbGVDbGFzcyhzZWxmLmNhbGVuZGFyQ29udGFpbmVyLCBcImFycm93VG9wXCIsICFzaG93T25Ub3ApO1xuICAgICAgICAgICAgdG9nZ2xlQ2xhc3Moc2VsZi5jYWxlbmRhckNvbnRhaW5lciwgXCJhcnJvd0JvdHRvbVwiLCBzaG93T25Ub3ApO1xuICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLmlubGluZSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB2YXIgbGVmdCA9IHdpbmRvdy5wYWdlWE9mZnNldCArIGlucHV0Qm91bmRzLmxlZnQ7XG4gICAgICAgICAgICB2YXIgaXNDZW50ZXIgPSBmYWxzZTtcbiAgICAgICAgICAgIHZhciBpc1JpZ2h0ID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoY29uZmlnUG9zSG9yaXpvbnRhbCA9PT0gXCJjZW50ZXJcIikge1xuICAgICAgICAgICAgICAgIGxlZnQgLT0gKGNhbGVuZGFyV2lkdGggLSBpbnB1dEJvdW5kcy53aWR0aCkgLyAyO1xuICAgICAgICAgICAgICAgIGlzQ2VudGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNvbmZpZ1Bvc0hvcml6b250YWwgPT09IFwicmlnaHRcIikge1xuICAgICAgICAgICAgICAgIGxlZnQgLT0gY2FsZW5kYXJXaWR0aCAtIGlucHV0Qm91bmRzLndpZHRoO1xuICAgICAgICAgICAgICAgIGlzUmlnaHQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdG9nZ2xlQ2xhc3Moc2VsZi5jYWxlbmRhckNvbnRhaW5lciwgXCJhcnJvd0xlZnRcIiwgIWlzQ2VudGVyICYmICFpc1JpZ2h0KTtcbiAgICAgICAgICAgIHRvZ2dsZUNsYXNzKHNlbGYuY2FsZW5kYXJDb250YWluZXIsIFwiYXJyb3dDZW50ZXJcIiwgaXNDZW50ZXIpO1xuICAgICAgICAgICAgdG9nZ2xlQ2xhc3Moc2VsZi5jYWxlbmRhckNvbnRhaW5lciwgXCJhcnJvd1JpZ2h0XCIsIGlzUmlnaHQpO1xuICAgICAgICAgICAgdmFyIHJpZ2h0ID0gd2luZG93LmRvY3VtZW50LmJvZHkub2Zmc2V0V2lkdGggLVxuICAgICAgICAgICAgICAgICh3aW5kb3cucGFnZVhPZmZzZXQgKyBpbnB1dEJvdW5kcy5yaWdodCk7XG4gICAgICAgICAgICB2YXIgcmlnaHRNb3N0ID0gbGVmdCArIGNhbGVuZGFyV2lkdGggPiB3aW5kb3cuZG9jdW1lbnQuYm9keS5vZmZzZXRXaWR0aDtcbiAgICAgICAgICAgIHZhciBjZW50ZXJNb3N0ID0gcmlnaHQgKyBjYWxlbmRhcldpZHRoID4gd2luZG93LmRvY3VtZW50LmJvZHkub2Zmc2V0V2lkdGg7XG4gICAgICAgICAgICB0b2dnbGVDbGFzcyhzZWxmLmNhbGVuZGFyQ29udGFpbmVyLCBcInJpZ2h0TW9zdFwiLCByaWdodE1vc3QpO1xuICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLnN0YXRpYylcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICBzZWxmLmNhbGVuZGFyQ29udGFpbmVyLnN0eWxlLnRvcCA9IHRvcCArIFwicHhcIjtcbiAgICAgICAgICAgIGlmICghcmlnaHRNb3N0KSB7XG4gICAgICAgICAgICAgICAgc2VsZi5jYWxlbmRhckNvbnRhaW5lci5zdHlsZS5sZWZ0ID0gbGVmdCArIFwicHhcIjtcbiAgICAgICAgICAgICAgICBzZWxmLmNhbGVuZGFyQ29udGFpbmVyLnN0eWxlLnJpZ2h0ID0gXCJhdXRvXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghY2VudGVyTW9zdCkge1xuICAgICAgICAgICAgICAgIHNlbGYuY2FsZW5kYXJDb250YWluZXIuc3R5bGUubGVmdCA9IFwiYXV0b1wiO1xuICAgICAgICAgICAgICAgIHNlbGYuY2FsZW5kYXJDb250YWluZXIuc3R5bGUucmlnaHQgPSByaWdodCArIFwicHhcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBkb2MgPSBnZXREb2N1bWVudFN0eWxlU2hlZXQoKTtcbiAgICAgICAgICAgICAgICAvLyBzb21lIHRlc3RpbmcgZW52aXJvbm1lbnRzIGRvbid0IGhhdmUgY3NzIHN1cHBvcnRcbiAgICAgICAgICAgICAgICBpZiAoZG9jID09PSB1bmRlZmluZWQpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB2YXIgYm9keVdpZHRoID0gd2luZG93LmRvY3VtZW50LmJvZHkub2Zmc2V0V2lkdGg7XG4gICAgICAgICAgICAgICAgdmFyIGNlbnRlckxlZnQgPSBNYXRoLm1heCgwLCBib2R5V2lkdGggLyAyIC0gY2FsZW5kYXJXaWR0aCAvIDIpO1xuICAgICAgICAgICAgICAgIHZhciBjZW50ZXJCZWZvcmUgPSBcIi5mbGF0cGlja3ItY2FsZW5kYXIuY2VudGVyTW9zdDpiZWZvcmVcIjtcbiAgICAgICAgICAgICAgICB2YXIgY2VudGVyQWZ0ZXIgPSBcIi5mbGF0cGlja3ItY2FsZW5kYXIuY2VudGVyTW9zdDphZnRlclwiO1xuICAgICAgICAgICAgICAgIHZhciBjZW50ZXJJbmRleCA9IGRvYy5jc3NSdWxlcy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgdmFyIGNlbnRlclN0eWxlID0gXCJ7bGVmdDpcIiArIGlucHV0Qm91bmRzLmxlZnQgKyBcInB4O3JpZ2h0OmF1dG87fVwiO1xuICAgICAgICAgICAgICAgIHRvZ2dsZUNsYXNzKHNlbGYuY2FsZW5kYXJDb250YWluZXIsIFwicmlnaHRNb3N0XCIsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB0b2dnbGVDbGFzcyhzZWxmLmNhbGVuZGFyQ29udGFpbmVyLCBcImNlbnRlck1vc3RcIiwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgZG9jLmluc2VydFJ1bGUoY2VudGVyQmVmb3JlICsgXCIsXCIgKyBjZW50ZXJBZnRlciArIGNlbnRlclN0eWxlLCBjZW50ZXJJbmRleCk7XG4gICAgICAgICAgICAgICAgc2VsZi5jYWxlbmRhckNvbnRhaW5lci5zdHlsZS5sZWZ0ID0gY2VudGVyTGVmdCArIFwicHhcIjtcbiAgICAgICAgICAgICAgICBzZWxmLmNhbGVuZGFyQ29udGFpbmVyLnN0eWxlLnJpZ2h0ID0gXCJhdXRvXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gZ2V0RG9jdW1lbnRTdHlsZVNoZWV0KCkge1xuICAgICAgICAgICAgdmFyIGVkaXRhYmxlU2hlZXQgPSBudWxsO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkb2N1bWVudC5zdHlsZVNoZWV0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHZhciBzaGVldCA9IGRvY3VtZW50LnN0eWxlU2hlZXRzW2ldO1xuICAgICAgICAgICAgICAgIGlmICghc2hlZXQuY3NzUnVsZXMpXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHNoZWV0LmNzc1J1bGVzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlZGl0YWJsZVNoZWV0ID0gc2hlZXQ7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZWRpdGFibGVTaGVldCAhPSBudWxsID8gZWRpdGFibGVTaGVldCA6IGNyZWF0ZVN0eWxlU2hlZXQoKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBjcmVhdGVTdHlsZVNoZWV0KCkge1xuICAgICAgICAgICAgdmFyIHN0eWxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInN0eWxlXCIpO1xuICAgICAgICAgICAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7XG4gICAgICAgICAgICByZXR1cm4gc3R5bGUuc2hlZXQ7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gcmVkcmF3KCkge1xuICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLm5vQ2FsZW5kYXIgfHwgc2VsZi5pc01vYmlsZSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICBidWlsZE1vbnRoU3dpdGNoKCk7XG4gICAgICAgICAgICB1cGRhdGVOYXZpZ2F0aW9uQ3VycmVudE1vbnRoKCk7XG4gICAgICAgICAgICBidWlsZERheXMoKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBmb2N1c0FuZENsb3NlKCkge1xuICAgICAgICAgICAgc2VsZi5faW5wdXQuZm9jdXMoKTtcbiAgICAgICAgICAgIGlmICh3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKFwiTVNJRVwiKSAhPT0gLTEgfHxcbiAgICAgICAgICAgICAgICBuYXZpZ2F0b3IubXNNYXhUb3VjaFBvaW50cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgLy8gaGFjayAtIGJ1Z3MgaW4gdGhlIHdheSBJRSBoYW5kbGVzIGZvY3VzIGtlZXBzIHRoZSBjYWxlbmRhciBvcGVuXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChzZWxmLmNsb3NlLCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHNlbGYuY2xvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBzZWxlY3REYXRlKGUpIHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICB2YXIgaXNTZWxlY3RhYmxlID0gZnVuY3Rpb24gKGRheSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBkYXkuY2xhc3NMaXN0ICYmXG4gICAgICAgICAgICAgICAgICAgIGRheS5jbGFzc0xpc3QuY29udGFpbnMoXCJmbGF0cGlja3ItZGF5XCIpICYmXG4gICAgICAgICAgICAgICAgICAgICFkYXkuY2xhc3NMaXN0LmNvbnRhaW5zKFwiZmxhdHBpY2tyLWRpc2FibGVkXCIpICYmXG4gICAgICAgICAgICAgICAgICAgICFkYXkuY2xhc3NMaXN0LmNvbnRhaW5zKFwibm90QWxsb3dlZFwiKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB2YXIgdCA9IGZpbmRQYXJlbnQoZ2V0RXZlbnRUYXJnZXQoZSksIGlzU2VsZWN0YWJsZSk7XG4gICAgICAgICAgICBpZiAodCA9PT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIHZhciB0YXJnZXQgPSB0O1xuICAgICAgICAgICAgdmFyIHNlbGVjdGVkRGF0ZSA9IChzZWxmLmxhdGVzdFNlbGVjdGVkRGF0ZU9iaiA9IG5ldyBEYXRlKHRhcmdldC5kYXRlT2JqLmdldFRpbWUoKSkpO1xuICAgICAgICAgICAgdmFyIHNob3VsZENoYW5nZU1vbnRoID0gKHNlbGVjdGVkRGF0ZS5nZXRNb250aCgpIDwgc2VsZi5jdXJyZW50TW9udGggfHxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZERhdGUuZ2V0TW9udGgoKSA+XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuY3VycmVudE1vbnRoICsgc2VsZi5jb25maWcuc2hvd01vbnRocyAtIDEpICYmXG4gICAgICAgICAgICAgICAgc2VsZi5jb25maWcubW9kZSAhPT0gXCJyYW5nZVwiO1xuICAgICAgICAgICAgc2VsZi5zZWxlY3RlZERhdGVFbGVtID0gdGFyZ2V0O1xuICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLm1vZGUgPT09IFwic2luZ2xlXCIpXG4gICAgICAgICAgICAgICAgc2VsZi5zZWxlY3RlZERhdGVzID0gW3NlbGVjdGVkRGF0ZV07XG4gICAgICAgICAgICBlbHNlIGlmIChzZWxmLmNvbmZpZy5tb2RlID09PSBcIm11bHRpcGxlXCIpIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ZWRJbmRleCA9IGlzRGF0ZVNlbGVjdGVkKHNlbGVjdGVkRGF0ZSk7XG4gICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkSW5kZXgpXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuc2VsZWN0ZWREYXRlcy5zcGxpY2UocGFyc2VJbnQoc2VsZWN0ZWRJbmRleCksIDEpO1xuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZWxlY3RlZERhdGVzLnB1c2goc2VsZWN0ZWREYXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHNlbGYuY29uZmlnLm1vZGUgPT09IFwicmFuZ2VcIikge1xuICAgICAgICAgICAgICAgIGlmIChzZWxmLnNlbGVjdGVkRGF0ZXMubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuY2xlYXIoZmFsc2UsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc2VsZi5sYXRlc3RTZWxlY3RlZERhdGVPYmogPSBzZWxlY3RlZERhdGU7XG4gICAgICAgICAgICAgICAgc2VsZi5zZWxlY3RlZERhdGVzLnB1c2goc2VsZWN0ZWREYXRlKTtcbiAgICAgICAgICAgICAgICAvLyB1bmxlc3Mgc2VsZWN0aW5nIHNhbWUgZGF0ZSB0d2ljZSwgc29ydCBhc2NlbmRpbmdseVxuICAgICAgICAgICAgICAgIGlmIChjb21wYXJlRGF0ZXMoc2VsZWN0ZWREYXRlLCBzZWxmLnNlbGVjdGVkRGF0ZXNbMF0sIHRydWUpICE9PSAwKVxuICAgICAgICAgICAgICAgICAgICBzZWxmLnNlbGVjdGVkRGF0ZXMuc29ydChmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYS5nZXRUaW1lKCkgLSBiLmdldFRpbWUoKTsgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZXRIb3Vyc0Zyb21JbnB1dHMoKTtcbiAgICAgICAgICAgIGlmIChzaG91bGRDaGFuZ2VNb250aCkge1xuICAgICAgICAgICAgICAgIHZhciBpc05ld1llYXIgPSBzZWxmLmN1cnJlbnRZZWFyICE9PSBzZWxlY3RlZERhdGUuZ2V0RnVsbFllYXIoKTtcbiAgICAgICAgICAgICAgICBzZWxmLmN1cnJlbnRZZWFyID0gc2VsZWN0ZWREYXRlLmdldEZ1bGxZZWFyKCk7XG4gICAgICAgICAgICAgICAgc2VsZi5jdXJyZW50TW9udGggPSBzZWxlY3RlZERhdGUuZ2V0TW9udGgoKTtcbiAgICAgICAgICAgICAgICBpZiAoaXNOZXdZZWFyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyaWdnZXJFdmVudChcIm9uWWVhckNoYW5nZVwiKTtcbiAgICAgICAgICAgICAgICAgICAgYnVpbGRNb250aFN3aXRjaCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0cmlnZ2VyRXZlbnQoXCJvbk1vbnRoQ2hhbmdlXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdXBkYXRlTmF2aWdhdGlvbkN1cnJlbnRNb250aCgpO1xuICAgICAgICAgICAgYnVpbGREYXlzKCk7XG4gICAgICAgICAgICB1cGRhdGVWYWx1ZSgpO1xuICAgICAgICAgICAgLy8gbWFpbnRhaW4gZm9jdXNcbiAgICAgICAgICAgIGlmICghc2hvdWxkQ2hhbmdlTW9udGggJiZcbiAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZy5tb2RlICE9PSBcInJhbmdlXCIgJiZcbiAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZy5zaG93TW9udGhzID09PSAxKVxuICAgICAgICAgICAgICAgIGZvY3VzT25EYXlFbGVtKHRhcmdldCk7XG4gICAgICAgICAgICBlbHNlIGlmIChzZWxmLnNlbGVjdGVkRGF0ZUVsZW0gIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgICAgIHNlbGYuaG91ckVsZW1lbnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHNlbGYuc2VsZWN0ZWREYXRlRWxlbSAmJiBzZWxmLnNlbGVjdGVkRGF0ZUVsZW0uZm9jdXMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzZWxmLmhvdXJFbGVtZW50ICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgICAgICAgc2VsZi5ob3VyRWxlbWVudCAhPT0gdW5kZWZpbmVkICYmIHNlbGYuaG91ckVsZW1lbnQuZm9jdXMoKTtcbiAgICAgICAgICAgIGlmIChzZWxmLmNvbmZpZy5jbG9zZU9uU2VsZWN0KSB7XG4gICAgICAgICAgICAgICAgdmFyIHNpbmdsZSA9IHNlbGYuY29uZmlnLm1vZGUgPT09IFwic2luZ2xlXCIgJiYgIXNlbGYuY29uZmlnLmVuYWJsZVRpbWU7XG4gICAgICAgICAgICAgICAgdmFyIHJhbmdlID0gc2VsZi5jb25maWcubW9kZSA9PT0gXCJyYW5nZVwiICYmXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuc2VsZWN0ZWREYXRlcy5sZW5ndGggPT09IDIgJiZcbiAgICAgICAgICAgICAgICAgICAgIXNlbGYuY29uZmlnLmVuYWJsZVRpbWU7XG4gICAgICAgICAgICAgICAgaWYgKHNpbmdsZSB8fCByYW5nZSkge1xuICAgICAgICAgICAgICAgICAgICBmb2N1c0FuZENsb3NlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdHJpZ2dlckNoYW5nZSgpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBDQUxMQkFDS1MgPSB7XG4gICAgICAgICAgICBsb2NhbGU6IFtzZXR1cExvY2FsZSwgdXBkYXRlV2Vla2RheXNdLFxuICAgICAgICAgICAgc2hvd01vbnRoczogW2J1aWxkTW9udGhzLCBzZXRDYWxlbmRhcldpZHRoLCBidWlsZFdlZWtkYXlzXSxcbiAgICAgICAgICAgIG1pbkRhdGU6IFtqdW1wVG9EYXRlXSxcbiAgICAgICAgICAgIG1heERhdGU6IFtqdW1wVG9EYXRlXSxcbiAgICAgICAgICAgIHBvc2l0aW9uRWxlbWVudDogW3VwZGF0ZVBvc2l0aW9uRWxlbWVudF0sXG4gICAgICAgICAgICBjbGlja09wZW5zOiBbXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5jb25maWcuY2xpY2tPcGVucyA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYmluZChzZWxmLl9pbnB1dCwgXCJmb2N1c1wiLCBzZWxmLm9wZW4pO1xuICAgICAgICAgICAgICAgICAgICAgICAgYmluZChzZWxmLl9pbnB1dCwgXCJjbGlja1wiLCBzZWxmLm9wZW4pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5faW5wdXQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImZvY3VzXCIsIHNlbGYub3Blbik7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9pbnB1dC5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgc2VsZi5vcGVuKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICB9O1xuICAgICAgICBmdW5jdGlvbiBzZXQob3B0aW9uLCB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKG9wdGlvbiAhPT0gbnVsbCAmJiB0eXBlb2Ygb3B0aW9uID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihzZWxmLmNvbmZpZywgb3B0aW9uKTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gb3B0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChDQUxMQkFDS1Nba2V5XSAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgICAgICAgICAgICAgQ0FMTEJBQ0tTW2tleV0uZm9yRWFjaChmdW5jdGlvbiAoeCkgeyByZXR1cm4geCgpOyB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZ1tvcHRpb25dID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgaWYgKENBTExCQUNLU1tvcHRpb25dICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgICAgICAgICAgIENBTExCQUNLU1tvcHRpb25dLmZvckVhY2goZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHgoKTsgfSk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoSE9PS1MuaW5kZXhPZihvcHRpb24pID4gLTEpXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuY29uZmlnW29wdGlvbl0gPSBhcnJheWlmeSh2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZWxmLnJlZHJhdygpO1xuICAgICAgICAgICAgdXBkYXRlVmFsdWUodHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gc2V0U2VsZWN0ZWREYXRlKGlucHV0RGF0ZSwgZm9ybWF0KSB7XG4gICAgICAgICAgICB2YXIgZGF0ZXMgPSBbXTtcbiAgICAgICAgICAgIGlmIChpbnB1dERhdGUgaW5zdGFuY2VvZiBBcnJheSlcbiAgICAgICAgICAgICAgICBkYXRlcyA9IGlucHV0RGF0ZS5tYXAoZnVuY3Rpb24gKGQpIHsgcmV0dXJuIHNlbGYucGFyc2VEYXRlKGQsIGZvcm1hdCk7IH0pO1xuICAgICAgICAgICAgZWxzZSBpZiAoaW5wdXREYXRlIGluc3RhbmNlb2YgRGF0ZSB8fCB0eXBlb2YgaW5wdXREYXRlID09PSBcIm51bWJlclwiKVxuICAgICAgICAgICAgICAgIGRhdGVzID0gW3NlbGYucGFyc2VEYXRlKGlucHV0RGF0ZSwgZm9ybWF0KV07XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgaW5wdXREYXRlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChzZWxmLmNvbmZpZy5tb2RlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJzaW5nbGVcIjpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInRpbWVcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGVzID0gW3NlbGYucGFyc2VEYXRlKGlucHV0RGF0ZSwgZm9ybWF0KV07XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIm11bHRpcGxlXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRlcyA9IGlucHV0RGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zcGxpdChzZWxmLmNvbmZpZy5jb25qdW5jdGlvbilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAubWFwKGZ1bmN0aW9uIChkYXRlKSB7IHJldHVybiBzZWxmLnBhcnNlRGF0ZShkYXRlLCBmb3JtYXQpOyB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwicmFuZ2VcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGVzID0gaW5wdXREYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNwbGl0KHNlbGYubDEwbi5yYW5nZVNlcGFyYXRvcilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAubWFwKGZ1bmN0aW9uIChkYXRlKSB7IHJldHVybiBzZWxmLnBhcnNlRGF0ZShkYXRlLCBmb3JtYXQpOyB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZy5lcnJvckhhbmRsZXIobmV3IEVycm9yKFwiSW52YWxpZCBkYXRlIHN1cHBsaWVkOiBcIiArIEpTT04uc3RyaW5naWZ5KGlucHV0RGF0ZSkpKTtcbiAgICAgICAgICAgIHNlbGYuc2VsZWN0ZWREYXRlcyA9IChzZWxmLmNvbmZpZy5hbGxvd0ludmFsaWRQcmVsb2FkXG4gICAgICAgICAgICAgICAgPyBkYXRlc1xuICAgICAgICAgICAgICAgIDogZGF0ZXMuZmlsdGVyKGZ1bmN0aW9uIChkKSB7IHJldHVybiBkIGluc3RhbmNlb2YgRGF0ZSAmJiBpc0VuYWJsZWQoZCwgZmFsc2UpOyB9KSk7XG4gICAgICAgICAgICBpZiAoc2VsZi5jb25maWcubW9kZSA9PT0gXCJyYW5nZVwiKVxuICAgICAgICAgICAgICAgIHNlbGYuc2VsZWN0ZWREYXRlcy5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBhLmdldFRpbWUoKSAtIGIuZ2V0VGltZSgpOyB9KTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBzZXREYXRlKGRhdGUsIHRyaWdnZXJDaGFuZ2UsIGZvcm1hdCkge1xuICAgICAgICAgICAgaWYgKHRyaWdnZXJDaGFuZ2UgPT09IHZvaWQgMCkgeyB0cmlnZ2VyQ2hhbmdlID0gZmFsc2U7IH1cbiAgICAgICAgICAgIGlmIChmb3JtYXQgPT09IHZvaWQgMCkgeyBmb3JtYXQgPSBzZWxmLmNvbmZpZy5kYXRlRm9ybWF0OyB9XG4gICAgICAgICAgICBpZiAoKGRhdGUgIT09IDAgJiYgIWRhdGUpIHx8IChkYXRlIGluc3RhbmNlb2YgQXJyYXkgJiYgZGF0ZS5sZW5ndGggPT09IDApKVxuICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLmNsZWFyKHRyaWdnZXJDaGFuZ2UpO1xuICAgICAgICAgICAgc2V0U2VsZWN0ZWREYXRlKGRhdGUsIGZvcm1hdCk7XG4gICAgICAgICAgICBzZWxmLmxhdGVzdFNlbGVjdGVkRGF0ZU9iaiA9XG4gICAgICAgICAgICAgICAgc2VsZi5zZWxlY3RlZERhdGVzW3NlbGYuc2VsZWN0ZWREYXRlcy5sZW5ndGggLSAxXTtcbiAgICAgICAgICAgIHNlbGYucmVkcmF3KCk7XG4gICAgICAgICAgICBqdW1wVG9EYXRlKHVuZGVmaW5lZCwgdHJpZ2dlckNoYW5nZSk7XG4gICAgICAgICAgICBzZXRIb3Vyc0Zyb21EYXRlKCk7XG4gICAgICAgICAgICBpZiAoc2VsZi5zZWxlY3RlZERhdGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHNlbGYuY2xlYXIoZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdXBkYXRlVmFsdWUodHJpZ2dlckNoYW5nZSk7XG4gICAgICAgICAgICBpZiAodHJpZ2dlckNoYW5nZSlcbiAgICAgICAgICAgICAgICB0cmlnZ2VyRXZlbnQoXCJvbkNoYW5nZVwiKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBwYXJzZURhdGVSdWxlcyhhcnIpIHtcbiAgICAgICAgICAgIHJldHVybiBhcnJcbiAgICAgICAgICAgICAgICAuc2xpY2UoKVxuICAgICAgICAgICAgICAgIC5tYXAoZnVuY3Rpb24gKHJ1bGUpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHJ1bGUgPT09IFwic3RyaW5nXCIgfHxcbiAgICAgICAgICAgICAgICAgICAgdHlwZW9mIHJ1bGUgPT09IFwibnVtYmVyXCIgfHxcbiAgICAgICAgICAgICAgICAgICAgcnVsZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYucGFyc2VEYXRlKHJ1bGUsIHVuZGVmaW5lZCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJ1bGUgJiZcbiAgICAgICAgICAgICAgICAgICAgdHlwZW9mIHJ1bGUgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgICAgICAgICAgICAgcnVsZS5mcm9tICYmXG4gICAgICAgICAgICAgICAgICAgIHJ1bGUudG8pXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmcm9tOiBzZWxmLnBhcnNlRGF0ZShydWxlLmZyb20sIHVuZGVmaW5lZCksXG4gICAgICAgICAgICAgICAgICAgICAgICB0bzogc2VsZi5wYXJzZURhdGUocnVsZS50bywgdW5kZWZpbmVkKSxcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcnVsZTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmZpbHRlcihmdW5jdGlvbiAoeCkgeyByZXR1cm4geDsgfSk7IC8vIHJlbW92ZSBmYWxzeSB2YWx1ZXNcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBzZXR1cERhdGVzKCkge1xuICAgICAgICAgICAgc2VsZi5zZWxlY3RlZERhdGVzID0gW107XG4gICAgICAgICAgICBzZWxmLm5vdyA9IHNlbGYucGFyc2VEYXRlKHNlbGYuY29uZmlnLm5vdykgfHwgbmV3IERhdGUoKTtcbiAgICAgICAgICAgIC8vIFdvcmthcm91bmQgSUUxMSBzZXR0aW5nIHBsYWNlaG9sZGVyIGFzIHRoZSBpbnB1dCdzIHZhbHVlXG4gICAgICAgICAgICB2YXIgcHJlbG9hZGVkRGF0ZSA9IHNlbGYuY29uZmlnLmRlZmF1bHREYXRlIHx8XG4gICAgICAgICAgICAgICAgKChzZWxmLmlucHV0Lm5vZGVOYW1lID09PSBcIklOUFVUXCIgfHxcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5pbnB1dC5ub2RlTmFtZSA9PT0gXCJURVhUQVJFQVwiKSAmJlxuICAgICAgICAgICAgICAgICAgICBzZWxmLmlucHV0LnBsYWNlaG9sZGVyICYmXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuaW5wdXQudmFsdWUgPT09IHNlbGYuaW5wdXQucGxhY2Vob2xkZXJcbiAgICAgICAgICAgICAgICAgICAgPyBudWxsXG4gICAgICAgICAgICAgICAgICAgIDogc2VsZi5pbnB1dC52YWx1ZSk7XG4gICAgICAgICAgICBpZiAocHJlbG9hZGVkRGF0ZSlcbiAgICAgICAgICAgICAgICBzZXRTZWxlY3RlZERhdGUocHJlbG9hZGVkRGF0ZSwgc2VsZi5jb25maWcuZGF0ZUZvcm1hdCk7XG4gICAgICAgICAgICBzZWxmLl9pbml0aWFsRGF0ZSA9XG4gICAgICAgICAgICAgICAgc2VsZi5zZWxlY3RlZERhdGVzLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICAgICAgPyBzZWxmLnNlbGVjdGVkRGF0ZXNbMF1cbiAgICAgICAgICAgICAgICAgICAgOiBzZWxmLmNvbmZpZy5taW5EYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZy5taW5EYXRlLmdldFRpbWUoKSA+IHNlbGYubm93LmdldFRpbWUoKVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBzZWxmLmNvbmZpZy5taW5EYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHNlbGYuY29uZmlnLm1heERhdGUgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZy5tYXhEYXRlLmdldFRpbWUoKSA8IHNlbGYubm93LmdldFRpbWUoKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gc2VsZi5jb25maWcubWF4RGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogc2VsZi5ub3c7XG4gICAgICAgICAgICBzZWxmLmN1cnJlbnRZZWFyID0gc2VsZi5faW5pdGlhbERhdGUuZ2V0RnVsbFllYXIoKTtcbiAgICAgICAgICAgIHNlbGYuY3VycmVudE1vbnRoID0gc2VsZi5faW5pdGlhbERhdGUuZ2V0TW9udGgoKTtcbiAgICAgICAgICAgIGlmIChzZWxmLnNlbGVjdGVkRGF0ZXMubGVuZ3RoID4gMClcbiAgICAgICAgICAgICAgICBzZWxmLmxhdGVzdFNlbGVjdGVkRGF0ZU9iaiA9IHNlbGYuc2VsZWN0ZWREYXRlc1swXTtcbiAgICAgICAgICAgIGlmIChzZWxmLmNvbmZpZy5taW5UaW1lICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgICAgICAgc2VsZi5jb25maWcubWluVGltZSA9IHNlbGYucGFyc2VEYXRlKHNlbGYuY29uZmlnLm1pblRpbWUsIFwiSDppXCIpO1xuICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLm1heFRpbWUgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZy5tYXhUaW1lID0gc2VsZi5wYXJzZURhdGUoc2VsZi5jb25maWcubWF4VGltZSwgXCJIOmlcIik7XG4gICAgICAgICAgICBzZWxmLm1pbkRhdGVIYXNUaW1lID1cbiAgICAgICAgICAgICAgICAhIXNlbGYuY29uZmlnLm1pbkRhdGUgJiZcbiAgICAgICAgICAgICAgICAgICAgKHNlbGYuY29uZmlnLm1pbkRhdGUuZ2V0SG91cnMoKSA+IDAgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY29uZmlnLm1pbkRhdGUuZ2V0TWludXRlcygpID4gMCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5jb25maWcubWluRGF0ZS5nZXRTZWNvbmRzKCkgPiAwKTtcbiAgICAgICAgICAgIHNlbGYubWF4RGF0ZUhhc1RpbWUgPVxuICAgICAgICAgICAgICAgICEhc2VsZi5jb25maWcubWF4RGF0ZSAmJlxuICAgICAgICAgICAgICAgICAgICAoc2VsZi5jb25maWcubWF4RGF0ZS5nZXRIb3VycygpID4gMCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5jb25maWcubWF4RGF0ZS5nZXRNaW51dGVzKCkgPiAwIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZy5tYXhEYXRlLmdldFNlY29uZHMoKSA+IDApO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHNldHVwSW5wdXRzKCkge1xuICAgICAgICAgICAgc2VsZi5pbnB1dCA9IGdldElucHV0RWxlbSgpO1xuICAgICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgICAgIGlmICghc2VsZi5pbnB1dCkge1xuICAgICAgICAgICAgICAgIHNlbGYuY29uZmlnLmVycm9ySGFuZGxlcihuZXcgRXJyb3IoXCJJbnZhbGlkIGlucHV0IGVsZW1lbnQgc3BlY2lmaWVkXCIpKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBoYWNrOiBzdG9yZSBwcmV2aW91cyB0eXBlIHRvIHJlc3RvcmUgaXQgYWZ0ZXIgZGVzdHJveSgpXG4gICAgICAgICAgICBzZWxmLmlucHV0Ll90eXBlID0gc2VsZi5pbnB1dC50eXBlO1xuICAgICAgICAgICAgc2VsZi5pbnB1dC50eXBlID0gXCJ0ZXh0XCI7XG4gICAgICAgICAgICBzZWxmLmlucHV0LmNsYXNzTGlzdC5hZGQoXCJmbGF0cGlja3ItaW5wdXRcIik7XG4gICAgICAgICAgICBzZWxmLl9pbnB1dCA9IHNlbGYuaW5wdXQ7XG4gICAgICAgICAgICBpZiAoc2VsZi5jb25maWcuYWx0SW5wdXQpIHtcbiAgICAgICAgICAgICAgICAvLyByZXBsaWNhdGUgc2VsZi5lbGVtZW50XG4gICAgICAgICAgICAgICAgc2VsZi5hbHRJbnB1dCA9IGNyZWF0ZUVsZW1lbnQoc2VsZi5pbnB1dC5ub2RlTmFtZSwgc2VsZi5jb25maWcuYWx0SW5wdXRDbGFzcyk7XG4gICAgICAgICAgICAgICAgc2VsZi5faW5wdXQgPSBzZWxmLmFsdElucHV0O1xuICAgICAgICAgICAgICAgIHNlbGYuYWx0SW5wdXQucGxhY2Vob2xkZXIgPSBzZWxmLmlucHV0LnBsYWNlaG9sZGVyO1xuICAgICAgICAgICAgICAgIHNlbGYuYWx0SW5wdXQuZGlzYWJsZWQgPSBzZWxmLmlucHV0LmRpc2FibGVkO1xuICAgICAgICAgICAgICAgIHNlbGYuYWx0SW5wdXQucmVxdWlyZWQgPSBzZWxmLmlucHV0LnJlcXVpcmVkO1xuICAgICAgICAgICAgICAgIHNlbGYuYWx0SW5wdXQudGFiSW5kZXggPSBzZWxmLmlucHV0LnRhYkluZGV4O1xuICAgICAgICAgICAgICAgIHNlbGYuYWx0SW5wdXQudHlwZSA9IFwidGV4dFwiO1xuICAgICAgICAgICAgICAgIHNlbGYuaW5wdXQuc2V0QXR0cmlidXRlKFwidHlwZVwiLCBcImhpZGRlblwiKTtcbiAgICAgICAgICAgICAgICBpZiAoIXNlbGYuY29uZmlnLnN0YXRpYyAmJiBzZWxmLmlucHV0LnBhcmVudE5vZGUpXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuaW5wdXQucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoc2VsZi5hbHRJbnB1dCwgc2VsZi5pbnB1dC5uZXh0U2libGluZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXNlbGYuY29uZmlnLmFsbG93SW5wdXQpXG4gICAgICAgICAgICAgICAgc2VsZi5faW5wdXQuc2V0QXR0cmlidXRlKFwicmVhZG9ubHlcIiwgXCJyZWFkb25seVwiKTtcbiAgICAgICAgICAgIHVwZGF0ZVBvc2l0aW9uRWxlbWVudCgpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHVwZGF0ZVBvc2l0aW9uRWxlbWVudCgpIHtcbiAgICAgICAgICAgIHNlbGYuX3Bvc2l0aW9uRWxlbWVudCA9IHNlbGYuY29uZmlnLnBvc2l0aW9uRWxlbWVudCB8fCBzZWxmLl9pbnB1dDtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBzZXR1cE1vYmlsZSgpIHtcbiAgICAgICAgICAgIHZhciBpbnB1dFR5cGUgPSBzZWxmLmNvbmZpZy5lbmFibGVUaW1lXG4gICAgICAgICAgICAgICAgPyBzZWxmLmNvbmZpZy5ub0NhbGVuZGFyXG4gICAgICAgICAgICAgICAgICAgID8gXCJ0aW1lXCJcbiAgICAgICAgICAgICAgICAgICAgOiBcImRhdGV0aW1lLWxvY2FsXCJcbiAgICAgICAgICAgICAgICA6IFwiZGF0ZVwiO1xuICAgICAgICAgICAgc2VsZi5tb2JpbGVJbnB1dCA9IGNyZWF0ZUVsZW1lbnQoXCJpbnB1dFwiLCBzZWxmLmlucHV0LmNsYXNzTmFtZSArIFwiIGZsYXRwaWNrci1tb2JpbGVcIik7XG4gICAgICAgICAgICBzZWxmLm1vYmlsZUlucHV0LnRhYkluZGV4ID0gMTtcbiAgICAgICAgICAgIHNlbGYubW9iaWxlSW5wdXQudHlwZSA9IGlucHV0VHlwZTtcbiAgICAgICAgICAgIHNlbGYubW9iaWxlSW5wdXQuZGlzYWJsZWQgPSBzZWxmLmlucHV0LmRpc2FibGVkO1xuICAgICAgICAgICAgc2VsZi5tb2JpbGVJbnB1dC5yZXF1aXJlZCA9IHNlbGYuaW5wdXQucmVxdWlyZWQ7XG4gICAgICAgICAgICBzZWxmLm1vYmlsZUlucHV0LnBsYWNlaG9sZGVyID0gc2VsZi5pbnB1dC5wbGFjZWhvbGRlcjtcbiAgICAgICAgICAgIHNlbGYubW9iaWxlRm9ybWF0U3RyID1cbiAgICAgICAgICAgICAgICBpbnB1dFR5cGUgPT09IFwiZGF0ZXRpbWUtbG9jYWxcIlxuICAgICAgICAgICAgICAgICAgICA/IFwiWS1tLWRcXFxcVEg6aTpTXCJcbiAgICAgICAgICAgICAgICAgICAgOiBpbnB1dFR5cGUgPT09IFwiZGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICA/IFwiWS1tLWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgOiBcIkg6aTpTXCI7XG4gICAgICAgICAgICBpZiAoc2VsZi5zZWxlY3RlZERhdGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBzZWxmLm1vYmlsZUlucHV0LmRlZmF1bHRWYWx1ZSA9IHNlbGYubW9iaWxlSW5wdXQudmFsdWUgPSBzZWxmLmZvcm1hdERhdGUoc2VsZi5zZWxlY3RlZERhdGVzWzBdLCBzZWxmLm1vYmlsZUZvcm1hdFN0cik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc2VsZi5jb25maWcubWluRGF0ZSlcbiAgICAgICAgICAgICAgICBzZWxmLm1vYmlsZUlucHV0Lm1pbiA9IHNlbGYuZm9ybWF0RGF0ZShzZWxmLmNvbmZpZy5taW5EYXRlLCBcIlktbS1kXCIpO1xuICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLm1heERhdGUpXG4gICAgICAgICAgICAgICAgc2VsZi5tb2JpbGVJbnB1dC5tYXggPSBzZWxmLmZvcm1hdERhdGUoc2VsZi5jb25maWcubWF4RGF0ZSwgXCJZLW0tZFwiKTtcbiAgICAgICAgICAgIGlmIChzZWxmLmlucHV0LmdldEF0dHJpYnV0ZShcInN0ZXBcIikpXG4gICAgICAgICAgICAgICAgc2VsZi5tb2JpbGVJbnB1dC5zdGVwID0gU3RyaW5nKHNlbGYuaW5wdXQuZ2V0QXR0cmlidXRlKFwic3RlcFwiKSk7XG4gICAgICAgICAgICBzZWxmLmlucHV0LnR5cGUgPSBcImhpZGRlblwiO1xuICAgICAgICAgICAgaWYgKHNlbGYuYWx0SW5wdXQgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICAgICAgICBzZWxmLmFsdElucHV0LnR5cGUgPSBcImhpZGRlblwiO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5pbnB1dC5wYXJlbnROb2RlKVxuICAgICAgICAgICAgICAgICAgICBzZWxmLmlucHV0LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHNlbGYubW9iaWxlSW5wdXQsIHNlbGYuaW5wdXQubmV4dFNpYmxpbmcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKF9hKSB7IH1cbiAgICAgICAgICAgIGJpbmQoc2VsZi5tb2JpbGVJbnB1dCwgXCJjaGFuZ2VcIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICBzZWxmLnNldERhdGUoZ2V0RXZlbnRUYXJnZXQoZSkudmFsdWUsIGZhbHNlLCBzZWxmLm1vYmlsZUZvcm1hdFN0cik7XG4gICAgICAgICAgICAgICAgdHJpZ2dlckV2ZW50KFwib25DaGFuZ2VcIik7XG4gICAgICAgICAgICAgICAgdHJpZ2dlckV2ZW50KFwib25DbG9zZVwiKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHRvZ2dsZShlKSB7XG4gICAgICAgICAgICBpZiAoc2VsZi5pc09wZW4gPT09IHRydWUpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYuY2xvc2UoKTtcbiAgICAgICAgICAgIHNlbGYub3BlbihlKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiB0cmlnZ2VyRXZlbnQoZXZlbnQsIGRhdGEpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbnN0YW5jZSBoYXMgYmVlbiBkZXN0cm95ZWQgYWxyZWFkeSwgYWxsIGhvb2tzIGhhdmUgYmVlbiByZW1vdmVkXG4gICAgICAgICAgICBpZiAoc2VsZi5jb25maWcgPT09IHVuZGVmaW5lZClcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB2YXIgaG9va3MgPSBzZWxmLmNvbmZpZ1tldmVudF07XG4gICAgICAgICAgICBpZiAoaG9va3MgIT09IHVuZGVmaW5lZCAmJiBob29rcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGhvb2tzW2ldICYmIGkgPCBob29rcy5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgICAgICAgICAgaG9va3NbaV0oc2VsZi5zZWxlY3RlZERhdGVzLCBzZWxmLmlucHV0LnZhbHVlLCBzZWxmLCBkYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChldmVudCA9PT0gXCJvbkNoYW5nZVwiKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5pbnB1dC5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KFwiY2hhbmdlXCIpKTtcbiAgICAgICAgICAgICAgICAvLyBtYW55IGZyb250LWVuZCBmcmFtZXdvcmtzIGJpbmQgdG8gdGhlIGlucHV0IGV2ZW50XG4gICAgICAgICAgICAgICAgc2VsZi5pbnB1dC5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KFwiaW5wdXRcIikpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGNyZWF0ZUV2ZW50KG5hbWUpIHtcbiAgICAgICAgICAgIHZhciBlID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoXCJFdmVudFwiKTtcbiAgICAgICAgICAgIGUuaW5pdEV2ZW50KG5hbWUsIHRydWUsIHRydWUpO1xuICAgICAgICAgICAgcmV0dXJuIGU7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gaXNEYXRlU2VsZWN0ZWQoZGF0ZSkge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZWxmLnNlbGVjdGVkRGF0ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ZWREYXRlID0gc2VsZi5zZWxlY3RlZERhdGVzW2ldO1xuICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZERhdGUgaW5zdGFuY2VvZiBEYXRlICYmXG4gICAgICAgICAgICAgICAgICAgIGNvbXBhcmVEYXRlcyhzZWxlY3RlZERhdGUsIGRhdGUpID09PSAwKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcIiArIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gaXNEYXRlSW5SYW5nZShkYXRlKSB7XG4gICAgICAgICAgICBpZiAoc2VsZi5jb25maWcubW9kZSAhPT0gXCJyYW5nZVwiIHx8IHNlbGYuc2VsZWN0ZWREYXRlcy5sZW5ndGggPCAyKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybiAoY29tcGFyZURhdGVzKGRhdGUsIHNlbGYuc2VsZWN0ZWREYXRlc1swXSkgPj0gMCAmJlxuICAgICAgICAgICAgICAgIGNvbXBhcmVEYXRlcyhkYXRlLCBzZWxmLnNlbGVjdGVkRGF0ZXNbMV0pIDw9IDApO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHVwZGF0ZU5hdmlnYXRpb25DdXJyZW50TW9udGgoKSB7XG4gICAgICAgICAgICBpZiAoc2VsZi5jb25maWcubm9DYWxlbmRhciB8fCBzZWxmLmlzTW9iaWxlIHx8ICFzZWxmLm1vbnRoTmF2KVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIHNlbGYueWVhckVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKHllYXJFbGVtZW50LCBpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGQgPSBuZXcgRGF0ZShzZWxmLmN1cnJlbnRZZWFyLCBzZWxmLmN1cnJlbnRNb250aCwgMSk7XG4gICAgICAgICAgICAgICAgZC5zZXRNb250aChzZWxmLmN1cnJlbnRNb250aCArIGkpO1xuICAgICAgICAgICAgICAgIGlmIChzZWxmLmNvbmZpZy5zaG93TW9udGhzID4gMSB8fFxuICAgICAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZy5tb250aFNlbGVjdG9yVHlwZSA9PT0gXCJzdGF0aWNcIikge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLm1vbnRoRWxlbWVudHNbaV0udGV4dENvbnRlbnQgPVxuICAgICAgICAgICAgICAgICAgICAgICAgbW9udGhUb1N0cihkLmdldE1vbnRoKCksIHNlbGYuY29uZmlnLnNob3J0aGFuZEN1cnJlbnRNb250aCwgc2VsZi5sMTBuKSArIFwiIFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5tb250aHNEcm9wZG93bkNvbnRhaW5lci52YWx1ZSA9IGQuZ2V0TW9udGgoKS50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB5ZWFyRWxlbWVudC52YWx1ZSA9IGQuZ2V0RnVsbFllYXIoKS50b1N0cmluZygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBzZWxmLl9oaWRlUHJldk1vbnRoQXJyb3cgPVxuICAgICAgICAgICAgICAgIHNlbGYuY29uZmlnLm1pbkRhdGUgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgICAgICAgICAoc2VsZi5jdXJyZW50WWVhciA9PT0gc2VsZi5jb25maWcubWluRGF0ZS5nZXRGdWxsWWVhcigpXG4gICAgICAgICAgICAgICAgICAgICAgICA/IHNlbGYuY3VycmVudE1vbnRoIDw9IHNlbGYuY29uZmlnLm1pbkRhdGUuZ2V0TW9udGgoKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBzZWxmLmN1cnJlbnRZZWFyIDwgc2VsZi5jb25maWcubWluRGF0ZS5nZXRGdWxsWWVhcigpKTtcbiAgICAgICAgICAgIHNlbGYuX2hpZGVOZXh0TW9udGhBcnJvdyA9XG4gICAgICAgICAgICAgICAgc2VsZi5jb25maWcubWF4RGF0ZSAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgICAgICAgICAgIChzZWxmLmN1cnJlbnRZZWFyID09PSBzZWxmLmNvbmZpZy5tYXhEYXRlLmdldEZ1bGxZZWFyKClcbiAgICAgICAgICAgICAgICAgICAgICAgID8gc2VsZi5jdXJyZW50TW9udGggKyAxID4gc2VsZi5jb25maWcubWF4RGF0ZS5nZXRNb250aCgpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHNlbGYuY3VycmVudFllYXIgPiBzZWxmLmNvbmZpZy5tYXhEYXRlLmdldEZ1bGxZZWFyKCkpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGdldERhdGVTdHIoc3BlY2lmaWNGb3JtYXQpIHtcbiAgICAgICAgICAgIHZhciBmb3JtYXQgPSBzcGVjaWZpY0Zvcm1hdCB8fFxuICAgICAgICAgICAgICAgIChzZWxmLmNvbmZpZy5hbHRJbnB1dCA/IHNlbGYuY29uZmlnLmFsdEZvcm1hdCA6IHNlbGYuY29uZmlnLmRhdGVGb3JtYXQpO1xuICAgICAgICAgICAgcmV0dXJuIHNlbGYuc2VsZWN0ZWREYXRlc1xuICAgICAgICAgICAgICAgIC5tYXAoZnVuY3Rpb24gKGRPYmopIHsgcmV0dXJuIHNlbGYuZm9ybWF0RGF0ZShkT2JqLCBmb3JtYXQpOyB9KVxuICAgICAgICAgICAgICAgIC5maWx0ZXIoZnVuY3Rpb24gKGQsIGksIGFycikge1xuICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLmNvbmZpZy5tb2RlICE9PSBcInJhbmdlXCIgfHxcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5jb25maWcuZW5hYmxlVGltZSB8fFxuICAgICAgICAgICAgICAgICAgICBhcnIuaW5kZXhPZihkKSA9PT0gaTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmpvaW4oc2VsZi5jb25maWcubW9kZSAhPT0gXCJyYW5nZVwiXG4gICAgICAgICAgICAgICAgPyBzZWxmLmNvbmZpZy5jb25qdW5jdGlvblxuICAgICAgICAgICAgICAgIDogc2VsZi5sMTBuLnJhbmdlU2VwYXJhdG9yKTtcbiAgICAgICAgfVxuICAgICAgICAvKipcbiAgICAgICAgICogVXBkYXRlcyB0aGUgdmFsdWVzIG9mIGlucHV0cyBhc3NvY2lhdGVkIHdpdGggdGhlIGNhbGVuZGFyXG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiB1cGRhdGVWYWx1ZSh0cmlnZ2VyQ2hhbmdlKSB7XG4gICAgICAgICAgICBpZiAodHJpZ2dlckNoYW5nZSA9PT0gdm9pZCAwKSB7IHRyaWdnZXJDaGFuZ2UgPSB0cnVlOyB9XG4gICAgICAgICAgICBpZiAoc2VsZi5tb2JpbGVJbnB1dCAhPT0gdW5kZWZpbmVkICYmIHNlbGYubW9iaWxlRm9ybWF0U3RyKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5tb2JpbGVJbnB1dC52YWx1ZSA9XG4gICAgICAgICAgICAgICAgICAgIHNlbGYubGF0ZXN0U2VsZWN0ZWREYXRlT2JqICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgID8gc2VsZi5mb3JtYXREYXRlKHNlbGYubGF0ZXN0U2VsZWN0ZWREYXRlT2JqLCBzZWxmLm1vYmlsZUZvcm1hdFN0cilcbiAgICAgICAgICAgICAgICAgICAgICAgIDogXCJcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNlbGYuaW5wdXQudmFsdWUgPSBnZXREYXRlU3RyKHNlbGYuY29uZmlnLmRhdGVGb3JtYXQpO1xuICAgICAgICAgICAgaWYgKHNlbGYuYWx0SW5wdXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHNlbGYuYWx0SW5wdXQudmFsdWUgPSBnZXREYXRlU3RyKHNlbGYuY29uZmlnLmFsdEZvcm1hdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHJpZ2dlckNoYW5nZSAhPT0gZmFsc2UpXG4gICAgICAgICAgICAgICAgdHJpZ2dlckV2ZW50KFwib25WYWx1ZVVwZGF0ZVwiKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBvbk1vbnRoTmF2Q2xpY2soZSkge1xuICAgICAgICAgICAgdmFyIGV2ZW50VGFyZ2V0ID0gZ2V0RXZlbnRUYXJnZXQoZSk7XG4gICAgICAgICAgICB2YXIgaXNQcmV2TW9udGggPSBzZWxmLnByZXZNb250aE5hdi5jb250YWlucyhldmVudFRhcmdldCk7XG4gICAgICAgICAgICB2YXIgaXNOZXh0TW9udGggPSBzZWxmLm5leHRNb250aE5hdi5jb250YWlucyhldmVudFRhcmdldCk7XG4gICAgICAgICAgICBpZiAoaXNQcmV2TW9udGggfHwgaXNOZXh0TW9udGgpIHtcbiAgICAgICAgICAgICAgICBjaGFuZ2VNb250aChpc1ByZXZNb250aCA/IC0xIDogMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChzZWxmLnllYXJFbGVtZW50cy5pbmRleE9mKGV2ZW50VGFyZ2V0KSA+PSAwKSB7XG4gICAgICAgICAgICAgICAgZXZlbnRUYXJnZXQuc2VsZWN0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChldmVudFRhcmdldC5jbGFzc0xpc3QuY29udGFpbnMoXCJhcnJvd1VwXCIpKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5jaGFuZ2VZZWFyKHNlbGYuY3VycmVudFllYXIgKyAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGV2ZW50VGFyZ2V0LmNsYXNzTGlzdC5jb250YWlucyhcImFycm93RG93blwiKSkge1xuICAgICAgICAgICAgICAgIHNlbGYuY2hhbmdlWWVhcihzZWxmLmN1cnJlbnRZZWFyIC0gMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gdGltZVdyYXBwZXIoZSkge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdmFyIGlzS2V5RG93biA9IGUudHlwZSA9PT0gXCJrZXlkb3duXCIsIGV2ZW50VGFyZ2V0ID0gZ2V0RXZlbnRUYXJnZXQoZSksIGlucHV0ID0gZXZlbnRUYXJnZXQ7XG4gICAgICAgICAgICBpZiAoc2VsZi5hbVBNICE9PSB1bmRlZmluZWQgJiYgZXZlbnRUYXJnZXQgPT09IHNlbGYuYW1QTSkge1xuICAgICAgICAgICAgICAgIHNlbGYuYW1QTS50ZXh0Q29udGVudCA9XG4gICAgICAgICAgICAgICAgICAgIHNlbGYubDEwbi5hbVBNW2ludChzZWxmLmFtUE0udGV4dENvbnRlbnQgPT09IHNlbGYubDEwbi5hbVBNWzBdKV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgbWluID0gcGFyc2VGbG9hdChpbnB1dC5nZXRBdHRyaWJ1dGUoXCJtaW5cIikpLCBtYXggPSBwYXJzZUZsb2F0KGlucHV0LmdldEF0dHJpYnV0ZShcIm1heFwiKSksIHN0ZXAgPSBwYXJzZUZsb2F0KGlucHV0LmdldEF0dHJpYnV0ZShcInN0ZXBcIikpLCBjdXJWYWx1ZSA9IHBhcnNlSW50KGlucHV0LnZhbHVlLCAxMCksIGRlbHRhID0gZS5kZWx0YSB8fFxuICAgICAgICAgICAgICAgIChpc0tleURvd24gPyAoZS53aGljaCA9PT0gMzggPyAxIDogLTEpIDogMCk7XG4gICAgICAgICAgICB2YXIgbmV3VmFsdWUgPSBjdXJWYWx1ZSArIHN0ZXAgKiBkZWx0YTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgaW5wdXQudmFsdWUgIT09IFwidW5kZWZpbmVkXCIgJiYgaW5wdXQudmFsdWUubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICAgICAgdmFyIGlzSG91ckVsZW0gPSBpbnB1dCA9PT0gc2VsZi5ob3VyRWxlbWVudCwgaXNNaW51dGVFbGVtID0gaW5wdXQgPT09IHNlbGYubWludXRlRWxlbWVudDtcbiAgICAgICAgICAgICAgICBpZiAobmV3VmFsdWUgPCBtaW4pIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWUgPVxuICAgICAgICAgICAgICAgICAgICAgICAgbWF4ICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50KCFpc0hvdXJFbGVtKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludChpc0hvdXJFbGVtKSAmJiBpbnQoIXNlbGYuYW1QTSkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNNaW51dGVFbGVtKVxuICAgICAgICAgICAgICAgICAgICAgICAgaW5jcmVtZW50TnVtSW5wdXQodW5kZWZpbmVkLCAtMSwgc2VsZi5ob3VyRWxlbWVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5ld1ZhbHVlID4gbWF4KSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlID1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0ID09PSBzZWxmLmhvdXJFbGVtZW50ID8gbmV3VmFsdWUgLSBtYXggLSBpbnQoIXNlbGYuYW1QTSkgOiBtaW47XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc01pbnV0ZUVsZW0pXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmNyZW1lbnROdW1JbnB1dCh1bmRlZmluZWQsIDEsIHNlbGYuaG91ckVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5hbVBNICYmXG4gICAgICAgICAgICAgICAgICAgIGlzSG91ckVsZW0gJiZcbiAgICAgICAgICAgICAgICAgICAgKHN0ZXAgPT09IDFcbiAgICAgICAgICAgICAgICAgICAgICAgID8gbmV3VmFsdWUgKyBjdXJWYWx1ZSA9PT0gMjNcbiAgICAgICAgICAgICAgICAgICAgICAgIDogTWF0aC5hYnMobmV3VmFsdWUgLSBjdXJWYWx1ZSkgPiBzdGVwKSkge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLmFtUE0udGV4dENvbnRlbnQgPVxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sMTBuLmFtUE1baW50KHNlbGYuYW1QTS50ZXh0Q29udGVudCA9PT0gc2VsZi5sMTBuLmFtUE1bMF0pXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaW5wdXQudmFsdWUgPSBwYWQobmV3VmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGluaXQoKTtcbiAgICAgICAgcmV0dXJuIHNlbGY7XG4gICAgfVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgZnVuY3Rpb24gX2ZsYXRwaWNrcihub2RlTGlzdCwgY29uZmlnKSB7XG4gICAgICAgIC8vIHN0YXRpYyBsaXN0XG4gICAgICAgIHZhciBub2RlcyA9IEFycmF5LnByb3RvdHlwZS5zbGljZVxuICAgICAgICAgICAgLmNhbGwobm9kZUxpc3QpXG4gICAgICAgICAgICAuZmlsdGVyKGZ1bmN0aW9uICh4KSB7IHJldHVybiB4IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQ7IH0pO1xuICAgICAgICB2YXIgaW5zdGFuY2VzID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBub2RlID0gbm9kZXNbaV07XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmIChub2RlLmdldEF0dHJpYnV0ZShcImRhdGEtZnAtb21pdFwiKSAhPT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuX2ZsYXRwaWNrciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGUuX2ZsYXRwaWNrci5kZXN0cm95KCk7XG4gICAgICAgICAgICAgICAgICAgIG5vZGUuX2ZsYXRwaWNrciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbm9kZS5fZmxhdHBpY2tyID0gRmxhdHBpY2tySW5zdGFuY2Uobm9kZSwgY29uZmlnIHx8IHt9KTtcbiAgICAgICAgICAgICAgICBpbnN0YW5jZXMucHVzaChub2RlLl9mbGF0cGlja3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnN0YW5jZXMubGVuZ3RoID09PSAxID8gaW5zdGFuY2VzWzBdIDogaW5zdGFuY2VzO1xuICAgIH1cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIGlmICh0eXBlb2YgSFRNTEVsZW1lbnQgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgdHlwZW9mIEhUTUxDb2xsZWN0aW9uICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgIHR5cGVvZiBOb2RlTGlzdCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAvLyBicm93c2VyIGVudlxuICAgICAgICBIVE1MQ29sbGVjdGlvbi5wcm90b3R5cGUuZmxhdHBpY2tyID0gTm9kZUxpc3QucHJvdG90eXBlLmZsYXRwaWNrciA9IGZ1bmN0aW9uIChjb25maWcpIHtcbiAgICAgICAgICAgIHJldHVybiBfZmxhdHBpY2tyKHRoaXMsIGNvbmZpZyk7XG4gICAgICAgIH07XG4gICAgICAgIEhUTUxFbGVtZW50LnByb3RvdHlwZS5mbGF0cGlja3IgPSBmdW5jdGlvbiAoY29uZmlnKSB7XG4gICAgICAgICAgICByZXR1cm4gX2ZsYXRwaWNrcihbdGhpc10sIGNvbmZpZyk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgdmFyIGZsYXRwaWNrciA9IGZ1bmN0aW9uIChzZWxlY3RvciwgY29uZmlnKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBfZmxhdHBpY2tyKHdpbmRvdy5kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSwgY29uZmlnKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzZWxlY3RvciBpbnN0YW5jZW9mIE5vZGUpIHtcbiAgICAgICAgICAgIHJldHVybiBfZmxhdHBpY2tyKFtzZWxlY3Rvcl0sIGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gX2ZsYXRwaWNrcihzZWxlY3RvciwgY29uZmlnKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBmbGF0cGlja3IuZGVmYXVsdENvbmZpZyA9IHt9O1xuICAgIGZsYXRwaWNrci5sMTBucyA9IHtcbiAgICAgICAgZW46IF9fYXNzaWduKHt9LCBlbmdsaXNoKSxcbiAgICAgICAgZGVmYXVsdDogX19hc3NpZ24oe30sIGVuZ2xpc2gpLFxuICAgIH07XG4gICAgZmxhdHBpY2tyLmxvY2FsaXplID0gZnVuY3Rpb24gKGwxMG4pIHtcbiAgICAgICAgZmxhdHBpY2tyLmwxMG5zLmRlZmF1bHQgPSBfX2Fzc2lnbihfX2Fzc2lnbih7fSwgZmxhdHBpY2tyLmwxMG5zLmRlZmF1bHQpLCBsMTBuKTtcbiAgICB9O1xuICAgIGZsYXRwaWNrci5zZXREZWZhdWx0cyA9IGZ1bmN0aW9uIChjb25maWcpIHtcbiAgICAgICAgZmxhdHBpY2tyLmRlZmF1bHRDb25maWcgPSBfX2Fzc2lnbihfX2Fzc2lnbih7fSwgZmxhdHBpY2tyLmRlZmF1bHRDb25maWcpLCBjb25maWcpO1xuICAgIH07XG4gICAgZmxhdHBpY2tyLnBhcnNlRGF0ZSA9IGNyZWF0ZURhdGVQYXJzZXIoe30pO1xuICAgIGZsYXRwaWNrci5mb3JtYXREYXRlID0gY3JlYXRlRGF0ZUZvcm1hdHRlcih7fSk7XG4gICAgZmxhdHBpY2tyLmNvbXBhcmVEYXRlcyA9IGNvbXBhcmVEYXRlcztcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIGlmICh0eXBlb2YgalF1ZXJ5ICE9PSBcInVuZGVmaW5lZFwiICYmIHR5cGVvZiBqUXVlcnkuZm4gIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgalF1ZXJ5LmZuLmZsYXRwaWNrciA9IGZ1bmN0aW9uIChjb25maWcpIHtcbiAgICAgICAgICAgIHJldHVybiBfZmxhdHBpY2tyKHRoaXMsIGNvbmZpZyk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIERhdGUucHJvdG90eXBlLmZwX2luY3IgPSBmdW5jdGlvbiAoZGF5cykge1xuICAgICAgICByZXR1cm4gbmV3IERhdGUodGhpcy5nZXRGdWxsWWVhcigpLCB0aGlzLmdldE1vbnRoKCksIHRoaXMuZ2V0RGF0ZSgpICsgKHR5cGVvZiBkYXlzID09PSBcInN0cmluZ1wiID8gcGFyc2VJbnQoZGF5cywgMTApIDogZGF5cykpO1xuICAgIH07XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgd2luZG93LmZsYXRwaWNrciA9IGZsYXRwaWNrcjtcbiAgICB9XG5cbiAgICByZXR1cm4gZmxhdHBpY2tyO1xuXG59KSkpO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/flatpickr/dist/flatpickr.js\n"); /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ !function() { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function() { return module['default']; } : /******/ function() { return module; }; /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; /******/ }(); /******/ /******/ /* webpack/runtime/define property getters */ /******/ !function() { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = function(exports, definition) { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ }(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ !function() { /******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } /******/ }(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ !function() { /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ }(); /******/ /************************************************************************/ /******/ /******/ // startup /******/ // Load entry module and return exports /******/ // This entry module can't be inlined because the eval-source-map devtool is used. /******/ var __webpack_exports__ = __webpack_require__("./libs/flatpickr/flatpickr.js"); /******/ /******/ return __webpack_exports__; /******/ })() ; });