capibara 1.3.40 → 1.3.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/util/tableElements.js +85 -14
package/dist/index.js
CHANGED
|
@@ -255,7 +255,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _uti
|
|
|
255
255
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
256
256
|
|
|
257
257
|
"use strict";
|
|
258
|
-
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _util_domUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/domUtils */ \"./src/util/domUtils.js\");\n/* harmony import */ var _util_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/utils */ \"./src/util/utils.js\");\n/* harmony import */ var _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../util/dateUtils */ \"./src/util/dateUtils.js\");\n/* harmony import */ var _util_icons__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../util/icons */ \"./src/util/icons.js\");\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n /**\n * Crea elemento Table\n * Contendrá los elementos que apareceran dentro de la tabla de planilla\n * Se Usa para :\n * - Agregar background con patron estilo tabla\n * - Agregar dayMouseOver, div que indica posicion de mouse\n * - Agregar DetailDay, para detalles de datos en tabla\n * - Agregar SelectedContainer, para dias seleccionados\n * - Agregar FloatBoxContainer, para visualizacion de datos en tabla\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom creado\n */\n createAgTable(config) {\n let e = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"capibara\"\n });\n\n if (config.timeline.dark) {\n e.classList.add(\"dark-theme\");\n }\n\n if (config.timeline.header.extend.isShow) {\n e.classList.add(\"header-extended\");\n }\n\n return e;\n },\n\n /**\n * Recrea Background, que es el fondo grid, como tabla\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} $elem - Elemento relacionado, donde se cre el background\n * @return {Object} Elemento Dom Corner Footer\n */\n redrawBackground(config, $elem) {\n return this.createBackground(config, $elem);\n },\n\n /**\n * Crea y posiciona fondo de tabla\n * Este fondo contiene un patron de CSS que le da la apariencia de tabla\n * por lo cual se debe reposicionar segun la fecha de inicio, para hacer\n * calzar los fines de semana\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} [$elem = null] - Elemento background, si es null, lo crea\n * @return {Object} elemento Dom Background\n */\n createBackground(config, $elem = null) {\n let {\n height,\n width,\n dayWidth\n } = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getTableDimensions(config);\n let start = new Date(config.timeline.start);\n let end = new Date(config.timeline.end);\n end.setTime(end.getTime() + _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].dayInMilliseconds); // add 24 hours\n\n let dCorrected = new Date(start.valueOf() + start.getTimezoneOffset() * 60000);\n let weekDay = dCorrected.getDay();\n let diffWeekDays = (weekDay - 1) * dayWidth * -1;\n $elem = $elem || _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"background-grid\"\n });\n $elem.style[\"background-position\"] = diffWeekDays + \"px 0, 0 0, \" + diffWeekDays + \"px 0\";\n $elem.style.width = width + \"px\";\n $elem.style.height = height + 1 + \"px\";\n return $elem;\n },\n\n /**\n * Crea Plot Container Vertical\n * Los plots son elementos que agregan secciones de fondo en la planilla\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom plotVerticalContainer\n */\n createPlotVerticalContainer(config) {\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"plot-vertical-container\"\n });\n return this.redrawPlotVerticalContainer(config, $elem);\n },\n\n createPlotHorizontalContainer(config) {\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"plot-horizontal-container\"\n });\n return this.redrawPlotHorizontalContainer(config, $elem);\n },\n\n /**\n * Recrea plotVerticalContainer, usando elemento existente\n * usa un elemento existente para usar la funcion para redibujar el elemento\n *\n * Los Plots se insertan como divs, con posicion especificada,\n * con ancho de dia\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} $elem - Elemento Dom donde crea plotVerticalContainer\n * @return {Object} Elemento Dom plotVerticalContainer\n */\n redrawPlotVerticalContainer(config, $elem) {\n $elem.innerHTML = \"\";\n\n if (config.timeline.plots && config.timeline.plots.vertical) {\n let {\n height,\n dayWidth\n } = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getTableDimensions(config);\n config.timeline.plots.vertical.forEach(p => {\n let diffDays = Math.floor(_util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].diffDays(config.timeline.start, p.date));\n let left = diffDays * dayWidth;\n let plot = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n classNames: [\"plot-vertical\", p.className || \"\"],\n style: {\n \"margin-left\": left + \"px\",\n height: height + \"px\"\n }\n });\n $elem.appendChild(plot);\n });\n }\n\n return $elem;\n },\n\n redrawPlotHorizontalContainer(config, $elem) {\n $elem.innerHTML = \"\";\n\n if (config.timeline.plots && config.timeline.plots.horizontal) {\n let {\n width,\n itemHeight\n } = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getTableDimensions(config);\n config.timeline.plots.horizontal.forEach(p => {\n let item = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getItemById(config, p.idNode, p.typeNode);\n let topPosition = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getPositionByItem(config, item, \"parent\");\n let plot = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n classNames: [\"plot-horizontal\", p.className || \"\"],\n style: {\n \"margin-top\": topPosition * itemHeight + \"px\",\n width: width + \"px\"\n }\n });\n $elem.appendChild(plot);\n });\n }\n\n return $elem;\n },\n\n /**\n * Crea Corner Izquierdo\n * Se usa para :\n * - titulos relacionados con los datos del sidebar izquierdo\n * - titulos para inputs de header, absolute a la derecha\n * - boton para mostrar/ocultar sidebar izquierdo\n * - promedios\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom Corner\n */\n createCorner(config, tab = null) {\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"corner\"\n });\n return this.redrawCorner($elem, config, tab);\n },\n\n redrawCorner($elem, config, tab = null) {\n let labelsInitialCorner = config.timeline.nav.left.initial.vars.filter(v => v.onlyTab == undefined || v.onlyTab && tab && v.onlyTab == tab.key).map(d => `<span class=\"item-col\">${d.label}</span>`).join(\"\");\n let labelsExtendCorner = config.timeline.nav.left.extend.vars.filter(v => v.onlyTab == undefined || v.onlyTab && tab && v.onlyTab == tab.key).map(d => `<span class=\"item-col\">${d.label}</span>`).join(\"\");\n let labelsHeaderExtend = config.timeline.header.extend.data.map(d => {\n if (d.isHidden) return \"\";\n let avg = \"\";\n let tooltip = \"\";\n let className = \"\";\n let isAccent = d.isAccent;\n\n if (d.average) {\n avg = ` <span class=\"average \"> ( <span> <span class=\"symbol\">x̄</span> ${d.average} </span>) </span> `;\n tooltip = `cap-tooltip=\"Promedio ${d.label} : ${d.average} ${d.suffix || \"\"}\"`;\n }\n\n if (d.color) {\n if (isAccent) {\n className = d.color ? \"c-\" + d.color + \"--background\" : \"\";\n } else {\n className = d.color ? \"c-\" + d.color + \"--text \" : \"\";\n }\n }\n\n return `<div class=\"input-title-container ${isAccent ? \"input-title--accent\" : \"\"} ${d.isPersistent ? \"persistent\" : \"\"}\">\n <span ${tooltip} class=\"input-title ${className}\">\n ${avg}\n ${d.label}\n </span>\n\n </div>`;\n }).join(\"\");\n let toggleSidebarBtnString = `\n <button toggle-sidebar class=\"cap-btn-icon cap-btn-icon-raised cap-btn-toggle-sidebar \">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].chevronRight}\n </button> `;\n\n if (config.timeline.nav.left.hideToggleSidebarButton) {\n toggleSidebarBtnString = \"\";\n }\n\n let template = `<div>\n\n ${toggleSidebarBtnString}\n <div class=\"corner-title\">\n <span class=\"bottom-text\">\n ${config.timeline.corner.left.label}\n </span>\n </div>\n\n <div class=\"initial-corner\">\n <div class=\"initial-corner-title\">\n <span class=\"bottom-container hide\">\n ${config.timeline.corner.initial.label}\n </span>\n\n <div class=\"bottom-container\">\n ${labelsInitialCorner}\n </div>\n\n </div>\n </div>\n\n\n <div class=\"extend-corner\">\n <div class=\"ex-corner-title\">\n <span class=\"bottom-container hide\">\n ${config.timeline.corner.extend.label}\n </span>\n\n <div class=\"bottom-container\">\n ${labelsExtendCorner}\n </div>\n\n </div>\n </div>\n\n\n <div class=\"cap-btn-nav-corner\">\n <div class=\"input-titles\">\n ${labelsHeaderExtend}\n </div>\n </div>\n\n <div class=\"progress-bar progress-bar-left hide-progress\"></div>\n\n </div>`;\n let r = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(template);\n $elem.innerHTML = \"\";\n $elem.append(r);\n let toggleSidebar = $elem.querySelector(\"[toggle-sidebar]\");\n\n if (toggleSidebar) {\n toggleSidebar.addEventListener(\"click\", e => {\n r.dispatchEvent(new CustomEvent(\"toggleSidebar\", {\n bubbles: true,\n cancelable: false\n }));\n });\n }\n\n return $elem;\n },\n\n /**\n * Crea Corner Derecho\n * Se usa para :\n * - titulos relacionados con los datos del sidebar Derecho\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom corner\n */\n createCornerRight(config, tab = null) {\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n classNames: [\"corner\", \"right\"]\n });\n return this.redrawCornerRight($elem, config, tab);\n },\n\n redrawCornerRight($el, config, tab = null) {\n let label = \"\";\n\n if (config.timeline.corner.right.label) {\n ` <span>\n ${config.timeline.corner.right.label}\n </span>`;\n }\n\n let str = `\n <div class=\"corner-title\">\n ${label}\n <div class=\"btn-container\"></div>\n </div>\n <div class=\"progress-bar progress-bar-right hide-progress\"></div>\n `;\n $el.innerHTML = str.trim();\n let $btnContainer = $el.querySelector(\".btn-container\");\n\n if (config.timeline.corner.right.buttons) {\n config.timeline.corner.right.buttons.forEach(btn => {\n let isEnabled = btn.getIsEnabled ? btn.getIsEnabled() : true;\n\n if (isEnabled) {\n let $btn = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <button class=\"corner-btn cap-btn-raised\">\n ${btn.label || \"\"}\n </button> `);\n\n if (btn.onClick) {\n $btn.addEventListener(\"click\", btn.onClick);\n }\n\n $btnContainer.appendChild($btn);\n }\n });\n }\n\n if (config.timeline.corner.right.inputs) {\n config.timeline.corner.right.inputs.forEach(input => {\n let $input = this.createCornerRightInput({\n inputConfig: input\n });\n $btnContainer.appendChild($btn);\n });\n }\n\n return $el;\n },\n\n createCornerRightInput({\n inputConfig,\n dataDay = null,\n daySelected = null\n }) {\n let r = null;\n\n switch (inputConfig.type) {\n case \"autocomplete-crud\":\n r = this.createCornerRightInputAutocompleteCrud({\n inputConfig,\n dataDay,\n daySelected\n });\n break;\n }\n\n return r;\n },\n\n createCornerRightInputAutocompleteCrud({\n inputConfig,\n dataDay,\n daySelected\n }) {\n let elem = \"test\";\n return elem;\n },\n\n /**\n * Crea Header Top\n * Se usa para :\n * - Manejo de tabs\n * - Botones de navegación y selección de fecha\n * - Boton toggle Dark mode\n * - Boton toggle Header extended\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom\n */\n createHeaderTop(config, tabSelected = null) {\n return this.redrawHeaderTop(config, tabSelected, _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\"));\n },\n\n redrawHeaderTop(config, tabSelected = null, $elem) {\n let str = `\n <div class=\"header-top\">`;\n\n if (config.timeline.tabs) {\n let showTabs = true;\n\n if (config.timeline.tabs.filter(t => !t.isHidden).length == 0) {\n showTabs = false;\n }\n\n if (showTabs) {\n str += ` <div class=\"tab-select-container c-d-desktop-none c-d-mobile-flex\">\n <select class=\"tabs-select\" >`;\n config.timeline.tabs.forEach(tab => {\n if (!tab.isHidden) {\n str += ` <option ${tab == tabSelected ? 'selected=\"selected\"' : \"\"} value=\"${tab.id}\"> ${tab.label} </option>`;\n }\n });\n str += `</select> </div>`;\n str += ` <div class=\"tabs-container c-d-desktop-flex c-d-mobile-none\">`;\n config.timeline.tabs.forEach(tab => {\n if (!tab.isHidden) {\n str += ` <button\n class=\"tab ${tab.disabled ? \"disabled\" : \"\"} ${tab == tabSelected ? \"active\" : \"\"} ${tab.color}\"\n color=\"${tab.color}\"\n input-key=\"${tab.id}\"\n ${tab.tooltip ? 'cap-tooltip=\"' + tab.tooltip + '\"' : \"\"} >\n <span>${tab.label}</span>\n ${tab.icon || \"\"}\n </button>\n `;\n }\n });\n str += `</div>`;\n }\n }\n\n if (tabSelected) {\n if (tabSelected.legends) {\n str += ` \n <button toggle-legends class=\"cap-btn-icon cap-btn-icon-raised \">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].toggleLegends}\n </button> \n\n <div class=\"legends-container force-mobile-style hide\"> `;\n tabSelected.legends.forEach(legend => {\n let colorClass = \"\";\n let colorBg = \"\";\n\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(legend.color)) {\n colorBg = \"background:\" + legend.color;\n } else {\n colorClass = legend.color ? legend.color + \"--background\" : \"\";\n }\n\n str += ` <div\n class=\"legend ${legend.active ? \"active\" : \"\"}\"\n input-key=\"${legend.key}\"\n ${legend.tooltip ? `cap-tooltip=\"${legend.tooltip}\"` : \"\"} >\n <div class=\"icon-legend ${colorClass} ${legend.shape}\" style=\"${colorBg}\"></div>\n <span>${legend.label}</span>\n </div>`;\n });\n str += `</div>`;\n }\n }\n\n str += `\n\n <div class=\"spacer\"></div>\n\n\n\n <button cap-btn-prev class=\"cap-btn-icon cap-btn-icon-raised\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].arrowLeft}\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].loadingIcon} \n </button>\n\n\n <button cap-btn-calendar class=\"cap-btn-icon cap-btn-icon-raised\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].calendar}\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].loadingIcon}\n </button>\n\n <button cap-btn-next class=\"cap-btn-icon cap-btn-icon-raised\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].arrowRight}\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].loadingIcon}\n </button>\n\n <div class=\"spacer\"></div>\n\n <button toggle-dark class=\"cap-btn-icon cap-btn-header c-d-mobile-none ${config.timeline.withDarkToggle == false ? \"hide\" : \"\"}\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].dark}\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].light}\n </button>`;\n\n if (config.timeline.header.extend.enabled !== false) {\n str += `<button toggle-header class=\"cap-btn-icon cap-btn-icon-raised\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].chevronDown}\n </button>`;\n }\n\n str += ` <div class=\"button-right-container\"></div>\n </div>`;\n /*\n `\n <button toggle-sidebar-right class=\"cap-btn-icon cap-btn-icon-raised\">\n <span>\n <svg style=\"width:24px;height:24px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z\" />\n </svg>\n </span>\n </button>\n </div>\n `;\n */\n\n let $r = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n $elem.replaceWith($r);\n\n if (config.timeline.header.rightButtons) {\n let $buttonContainer = $r.querySelector(\".button-right-container\");\n config.timeline.header.rightButtons.forEach(button => {\n let hasBadge = false;\n\n if (button.hasBadge) {\n hasBadge = button.hasBadge();\n }\n\n let str = `<button class=\"cap-btn-icon cap-btn-icon-raised ${hasBadge ? \"cap-btn-has-badge\" : \"\"}\">\n <span>\n <svg style=\"width:24px;height:24px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"${button.icon}\" />\n </svg>\n </span>\n </button>`;\n let $button = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n $button.addEventListener(\"click\", evt => button.onClick({\n evt\n }));\n $buttonContainer.append($button);\n });\n }\n\n let $toggleDark = $r.querySelector(\"[toggle-dark]\");\n\n if ($toggleDark) {\n $toggleDark.addEventListener(\"click\", e => {\n $r.dispatchEvent(new CustomEvent(\"toggleDark\", {\n bubbles: true,\n cancelable: false\n }));\n });\n }\n\n let $btnCalendar = $r.querySelector(\"[cap-btn-calendar]\");\n\n if ($btnCalendar) {\n $btnCalendar.addEventListener(\"click\", e => {\n let x = e.x;\n let y = e.y;\n $r.dispatchEvent(new CustomEvent(\"clickCalendarIcon\", {\n bubbles: true,\n cancelable: false,\n detail: {\n x,\n y\n }\n }));\n });\n }\n\n let $btnToggleHeader = $r.querySelector(\"[toggle-header]\");\n\n if ($btnToggleHeader) {\n $btnToggleHeader.addEventListener(\"click\", e => {\n $r.dispatchEvent(new CustomEvent(\"toggleHeader\", {\n bubbles: true,\n cancelable: false\n }));\n });\n }\n /*\n $r.querySelector(\"[toggle-sidebar-right]\").addEventListener(\"click\", e => {\n $r.dispatchEvent(new CustomEvent(\"toggleSidebarRight\", {\n bubbles: true,\n cancelable: false,\n }));\n });\n */\n\n\n $r.querySelector(\"[cap-btn-prev]\").addEventListener(\"click\", e => {\n $r.dispatchEvent(new CustomEvent(\"headerPrev\", {\n bubbles: true,\n cancelable: false,\n detail: {\n originalEvt: e\n }\n }));\n });\n $r.querySelector(\"[cap-btn-calendar]\").addEventListener(\"click\", e => {\n $r.dispatchEvent(new CustomEvent(\"headerCalendar\", {\n bubbles: true,\n cancelable: false,\n detail: {\n originalEvt: e\n }\n }));\n });\n $r.querySelector(\"[cap-btn-next]\").addEventListener(\"click\", e => {\n $r.dispatchEvent(new CustomEvent(\"headerNext\", {\n bubbles: true,\n cancelable: false,\n detail: {\n originalEvt: e\n }\n }));\n });\n let $toggleLegendsBtn = $r.querySelector(\"[toggle-legends]\");\n\n if ($toggleLegendsBtn) {\n $toggleLegendsBtn.addEventListener(\"click\", e => {\n let $legendContainer = $r.querySelector(\".legends-container\");\n\n if ($legendContainer) {\n $legendContainer.classList.toggle(\"hide\");\n }\n });\n }\n\n $r.querySelectorAll(\".legend\").forEach($legend => {\n $legend.addEventListener(\"click\", e => {\n let key = e.currentTarget.getAttribute(\"input-key\");\n\n if (key) {\n let legendSelected = tabSelected.legends.find(tab => tab.key === key);\n\n if (legendSelected) {\n $r.dispatchEvent(new CustomEvent(\"selectLegendHeader\", {\n bubbles: true,\n cancelable: false,\n detail: {\n legend: legendSelected,\n $legend\n }\n }));\n }\n }\n });\n });\n $r.querySelectorAll(\".tab:not(.disabled)\").forEach($tab => {\n $tab.addEventListener(\"click\", e => {\n let key = e.currentTarget.getAttribute(\"input-key\");\n\n if (key) {\n let tabSelected = config.timeline.tabs.find(tab => tab.id == key);\n\n if (tabSelected) {\n $r.dispatchEvent(new CustomEvent(\"selectTabHeader\", {\n bubbles: true,\n cancelable: false,\n detail: {\n tab: tabSelected\n }\n }));\n }\n }\n });\n });\n $r.querySelectorAll(\".tabs-select:not(.disabled)\").forEach($tab => {\n $tab.addEventListener(\"change\", e => {\n let key = parseFloat(e.currentTarget.value);\n\n if (key) {\n let tabSelected = config.timeline.tabs.find(tab => tab.id == key);\n\n if (tabSelected) {\n $r.dispatchEvent(new CustomEvent(\"selectTabHeader\", {\n bubbles: true,\n cancelable: false,\n detail: {\n tab: tabSelected\n }\n }));\n }\n }\n });\n });\n return $r;\n },\n\n /**\n * Crea Header\n * Se usa para :\n * - Mostrar fechas en header\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom\n */\n createHeader(config) {\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"header\");\n return this.redrawHeader(config, $elem);\n },\n\n /**\n * Recrea Header, usado para redibujar\n * utiliza $elem como elemento dom donde recrearlo\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} $elem - Elemento Dom donde crea Header\n * @return {Object} Elemento Dom\n */\n redrawHeader(config, $elem) {\n let datesTree = _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getDateTreeRange(new Date(config.timeline.start), new Date(config.timeline.end));\n let str = `<div class=\"header-container\"> `;\n Object.keys(datesTree).forEach(keyY => {\n let year = datesTree[keyY];\n str += `<div class=\"agno-calendario\">\n <span class=\"agno hide\">${keyY}</span>\n <div class=\"meses\">`;\n Object.keys(year).forEach(keyM => {\n let month = datesTree[keyY][keyM];\n str += ` <div class=\"mes-calendario\">\n <div class=\"mes ${Object.keys(month).length < 4 ? \"mes-reduced mes-reduced-\" + Object.keys(month).length : \"\"}\">\n <div class=\"mes-label\">\n ${_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getMonthByPosition(keyM)} ${keyY}\n </div>\n </div>\n <div class=\"dias\">`;\n Object.keys(month).forEach(keyD => {\n let day = datesTree[keyY][keyM][keyD];\n let isWeekend = day.isWeekend;\n let isToday = day.isToday;\n let hasAlert = config.timeline.header.dateHasAlert ? config.timeline.header.dateHasAlert(day) : false;\n let date = _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].formatDate(day.date);\n str += `<div class=\"dia-calendario \n ${isToday ? \"today\" : \"\"}\n ${isWeekend ? \"weekend\" : \"\"}\n ${hasAlert ? \"has-alert\" : \"\"}\n ${config.timeline.dateSelectable ? \"is-clickeable\" : \"\"}\n ${config.timeline.dateWithContextMenu ? \"is-clickeable\" : \"\"}\n \" date=\"${date}\">${keyD}</div>`;\n });\n str += `</div></div>`;\n });\n str += `</div> </div>`;\n });\n str += `</div>`;\n $elem.innerHTML = \"\";\n $elem.append(_util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str));\n let $days = $elem.querySelectorAll(\".dia-calendario[date]\");\n $days.forEach($dia => {\n if (config.timeline.dateWithContextMenu) {\n $dia.addEventListener(\"contextmenu\", evt => {\n $elem.dispatchEvent(new CustomEvent(\"contextMenuDate\", {\n bubbles: true,\n cancelable: false,\n detail: {\n $elem: $dia,\n date: $dia.getAttribute(\"date\"),\n clientX: evt.clientX,\n clientY: evt.clientY\n }\n }));\n });\n }\n\n if (config.timeline.dateSelectable) {\n $dia.addEventListener(\"click\", evt => {\n $elem.dispatchEvent(new CustomEvent(\"clickDate\", {\n bubbles: true,\n cancelable: false,\n detail: {\n $elem: $dia,\n date: $dia.getAttribute(\"date\")\n }\n }));\n });\n }\n\n if (config.timeline.onMouseOverDate) {\n $dia.addEventListener(\"mouseover\", evt => {\n config.timeline.onMouseOverDate({\n $dia,\n $elem,\n date: $dia.getAttribute(\"date\"),\n evt\n });\n });\n }\n\n if (config.timeline.onMouseOutDate) {\n $dia.addEventListener(\"mouseout\", evt => {\n config.timeline.onMouseOutDate({\n $dia,\n $elem,\n date: $dia.getAttribute(\"date\"),\n evt\n });\n });\n }\n });\n return $elem;\n },\n\n /**\n * Crea Header extended\n * Se usa para :\n * -Mostrar inputs y datos para fechas en header\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom headerExtended\n */\n createHeaderExtended(config) {\n if (config.timeline.header.extend.enabled == false) return null;\n let dates = _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getDateRange(new Date(config.timeline.start), new Date(config.timeline.end));\n let str = `<div class=\"header-container-extended\">`;\n config.timeline.header.extend.data.forEach((d, d_index) => {\n if (d.isHidden) return \"\";\n let isPersistent = d.isPersistent;\n str += `<div class=\"input-list ${isPersistent ? \"persistent\" : \"\"}\">`;\n str += dates.map(date => {\n let value = \"\";\n let className = \"\";\n let isFuture = _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].isFuture(date);\n let isToday = _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].isToday(date);\n\n if (d.data) {\n let dataFounded = d.data.find(dataInput => {\n return _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].isSameDate(new Date(dataInput.date + \"T00:00:00\"), date);\n });\n\n if (dataFounded) {\n value = dataFounded.value || \"\";\n className += dataFounded.className + \" \" || false;\n }\n }\n\n if (d.editable === false || isFuture && d.editableFuture == false || isToday && d.editableToday == false) {\n return `<div>\n <span date=\"${_util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].formatDate(date)}\" \n index=\"${d_index}\" \n class=\" ${className} ${date.varName || \"\"} ${d.color ? \"c-\" + d.color + \"--text\" : \"\"}\" > \n ${value} \n </span>\n </div>`;\n }\n\n let isDisabled = false;\n\n if (config.timeline.editable === false) {\n isDisabled = true;\n }\n\n return `<div class=\"dia-input\">\n <input \n date=\"${_util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].formatDate(date)}\" \n index=\"${d_index}\" \n class=\"header-input \n ${date.varName} ${d.color ? \"c-\" + d.color + \"--text\" : \"\"}\" \n type=\"number\"\n ${isDisabled ? \"disabled\" : \"\"} \n value=\"${value}\">\n </div>`;\n }).join(\"\");\n str += `</div>`;\n });\n str += `</div>`;\n let r = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n r.querySelectorAll(\"input.header-input\").forEach(input => {\n input.addEventListener(\"input\", e => {\n let date = e.currentTarget.getAttribute(\"date\");\n let index = e.currentTarget.getAttribute(\"index\");\n let value = e.currentTarget.value;\n let typeData = config.timeline.header.extend.data[index]; //refresh config value\n\n let data = typeData.data.find(d => _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].isSameDate(new Date(d.date + \"T00:00:00\"), new Date(date + \"T00:00:00\")));\n\n if (data) {\n data.value = value;\n } else {\n typeData.data.push({\n date: date,\n value: value\n });\n }\n\n r.dispatchEvent(new CustomEvent(\"changeInputHeader\", {\n bubbles: true,\n cancelable: false,\n detail: {\n date: date,\n typeData: typeData,\n value: value\n }\n }));\n });\n });\n return r;\n },\n\n /**\n * Crear Sidebar Izquierdo\n * - Maneja items como arbol de 2 niveles (parent, children)\n * - El sidebar se divide en navList - InitialNav - extendedNav - BtnNav\n * - Se agrega itemDetail, para detalles de items\n *\n *\n * TODO: para evitar incrustar las ids en los inputs, se deben crear\n * los nodos uno por uno como elemento DOM, y agregarles los eventos directamente\n * ahora se hace seleccionando todos los inputs con querySelectorAll\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom Sidebar Izquierdo\n */\n createNavLeft(config, tab = null) {\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"nav\", {\n className: \"left\"\n });\n return this.redrawNavLeft($elem, config, tab);\n },\n\n /**\n * Recrea Sidebar izquierdo, usado para redibujar\n * Utiliza $elem como elemento dom donde recrearlo\n *\n *\n * @param {Object} $elem - Elemento Dom donde crea el sidebar izquierdo\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom navLeft\n */\n redrawNavLeft($elem, config, tab = null) {\n let navList = \"\";\n let initialNavList = \"\";\n let exNavList = \"\";\n let btnNavList = \"\";\n let isDisabled = false;\n\n if (config.timeline.editable === false) {\n isDisabled = true;\n }\n\n config.data.forEach(d => {\n if (d.isHidden) return;\n const hasBtn = !!d.onClickDetailButton;\n const detailBtn = hasBtn ? `<button class=\"detail-btn\" item-id=\"${d.id || -1}\" type-node=\"${d.type || \"\"}\" >\n ${d.labelDetailButton}\n </button>` : \"\";\n navList += `\n <div class=\"nav-item\">\n\n\n <div class=\"nav-item-container parent\">`;\n\n if (d.children) {\n navList += `<button class=\"tree-icon ${d.isClosed ? \"\" : \"cap-rotate\"}\" item-id=\"${d.id || -1}\" type-node=\"${d.type || \"\"}\" >\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].chevronDown}\n </button>`;\n }\n\n navList += `\n <div class=\"item-title truncate full-width ${d.clickeable ? \"clickeable\" : \"\"}\n ${d.navOver ? \"hoverable\" : \"\"} \" item-id=\"${d.id || -1}\" type-node=\"${d.type || \"\"}\" >\n <div class=\"item-title-content\">\n ${d.label}\n </div>\n <div class=\"detail-btn-container\">\n ${detailBtn}\n </div>\n </div>\n </div>`;\n\n if (d.children) {\n navList += `\n <div class=\"children-items ${d.isClosed ? \"hide\" : \"\"} \" child-list=\"${d.id || -1}\">`;\n d.children.forEach(c => {\n if (c.isHidden) return;\n let lightColor = null;\n let lightClass = null;\n let lightSpan = \"\";\n let multiButtonsDetailTmpl = \"\";\n\n if (c.light) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(c.light)) {\n lightColor = c.light;\n } else {\n lightClass = c.light;\n }\n }\n\n if (c.light) {\n lightSpan = `<span \n class=\"light ${lightClass ? lightClass + \"-light\" : \"\"}\" \n style=\"${lightColor ? \"--light-color:\" + lightColor : \"\"}\">\n </span>`;\n }\n\n if (c.hasMultibuttons) {\n let iconFormatter = null;\n\n if (config.timeline.nav.left.initial.multibuttons && config.timeline.nav.left.initial.multibuttons.iconFormatter) {\n iconFormatter = config.timeline.nav.left.initial.multibuttons.iconFormatter;\n }\n\n let btnContent = iconFormatter ? iconFormatter({\n item: c,\n config\n }) : \"\";\n multiButtonsDetailTmpl = `<button class=\"multibuttons-btn\" \n item-id=\"${c.id || -1}\" \n type-node=\"${c.type || \"\"}\" \n ${isDisabled ? \"disabled\" : \"\"}>\n ${btnContent} \n </button>`;\n }\n\n navList += `\n <div class=\"child-nav-item\">\n <div class=\"nav-item-container\">\n `;\n /*\n <span class=\"nav-item-icon\">\n <svg style=\"width:24px;height:24px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M19,15L13,21L11.58,19.58L15.17,16H4V4H6V14H15.17L11.58,10.42L13,9L19,15Z\" />\n </svg>\n </span>\n */\n\n navList += `\n ${lightSpan}\n ${multiButtonsDetailTmpl}\n <div \n class=\"item-title ${c.clickeable ? \"clickeable\" : \"\"} ${c.navOver ? \"hoverable\" : \"\"}\" \n item-id=\"${c.id || -1}\" \n type-node=\"${c.type || \"\"}\">\n\n <div class=\"truncate\">\n ${c.label}\n </div>\n </div>\n </div>\n </div>`;\n });\n navList += `\n </div>`;\n }\n\n navList += `</div>`; //initial\n\n initialNavList += `<div class=\"initial-nav-item parent\">`;\n\n if (d.withNav) {\n config.timeline.nav.left.initial.vars.forEach(v => {\n let value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(d.values, v.varName);\n\n if (v.round && !isNaN(value)) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].round(value, v.round);\n }\n\n if (v.input) {\n switch (v.input) {\n case \"hour\":\n value = value.split(\":\");\n let hhValue = value[0];\n let mmValue = value[1];\n initialNavList += `\n <div class=\"item-col has-input\">\n <div class=\"hour-input\">\n <input type=\"number\"\n input-type=\"time\"\n max=\"23\"\n min=\"00\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${d.id || -1}\"\n type-node=\"${d.type || \"\"}\"\n value=\"${hhValue}\"\n ${isDisabled ? \"disabled\" : \"\"}\n class=\"hh\">\n <span>:</span>\n <input type=\"number\"\n input-type=\"time\"\n max=\"59\"\n min=\"00\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${d.id || -1}\"\n type-node=\"${d.type || \"\"}\"\n value=\"${mmValue}\"\n ${isDisabled ? \"disabled\" : \"\"}\n class=\"mm\">\n </div>\n </div>`;\n break;\n\n case \"text\":\n case \"number\":\n default:\n initialNavList += `\n <div class=\"item-col has-input\">\n <input \n type=\"${v.input || \"text\"}\"\n input-type=\"${v.input || \"text\"}\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${d.id || -1}\"\n type-node=\"${d.type || \"\"}\"\n ${isDisabled ? \"disabled\" : \"\"}\n value=\"${value}\"/>\n </div>`;\n }\n } else {\n initialNavList += `\n <div class=\"item-col\">\n ${value}\n </div>`;\n }\n });\n }\n\n initialNavList += `\n </div>`;\n\n if (d.children) {\n d.children.forEach(c => {\n if (c.isHidden) return;\n initialNavList += `<div class=\"child-initial-nav-item ${d.isClosed ? \"hide\" : \"\"}\" child=\"${d.id || -1}\">`;\n\n if (c.withNav !== false) {\n config.timeline.nav.left.initial.vars.forEach(v => {\n if (v.onlyTab && tab && v.onlyTab !== tab.key) return;\n let value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(c.values, v.varName);\n\n if (v.round && !isNaN(value)) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].round(value, v.round);\n }\n\n if (v.input) {\n switch (v.input) {\n case \"hour\":\n value = value.split(\":\");\n let hhValue = value[0];\n let mmValue = value[1];\n initialNavList += `\n <div class=\"item-col has-input\">\n <div class=\"hour-input\">\n <input type=\"number\"\n input-type=\"time\"\n max=\"23\"\n min=\"00\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${c.id || -1}\"\n type-node=\"${c.type || \"\"}\"\n value=\"${hhValue}\"\n ${isDisabled ? \"disabled\" : \"\"}\n class=\"hh\">\n <span>:</span>\n <input type=\"number\"\n input-type=\"time\"\n max=\"59\"\n min=\"00\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${c.id || -1}\"\n type-node=\"${c.type || \"\"}\"\n value=\"${mmValue}\"\n ${isDisabled ? \"disabled\" : \"\"}\n class=\"mm\">\n </div>\n </div>`;\n break;\n\n case \"text\":\n case \"number\":\n default:\n initialNavList += `\n <div class=\"item-col has-input\">\n <input\n type=\"${v.input || \"text\"}\"\n input-type=\"${v.input || \"text\"}\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${c.id || -1}\"\n type-node=\"${c.type || \"\"}\"\n ${isDisabled ? \"disabled\" : \"\"}\n value=\"${value}\"/>\n </div>`;\n }\n } else {\n initialNavList += `\n <div class=\"item-col\">\n ${value}\n </div>`;\n }\n });\n }\n\n initialNavList += `\n </div>`;\n });\n } //Ext\n\n\n exNavList += `<div class=\"ex-nav-item parent\">`;\n\n if (d.withExNav) {\n config.timeline.nav.left.extend.vars.forEach(v => {\n let value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(d.values, v.varName);\n\n if (v.round && !isNaN(value)) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].round(value, v.round);\n }\n\n if (v.input) {\n switch (v.input) {\n case \"hour\":\n value = value.split(\":\");\n let hhValue = value[0];\n let mmValue = value[1];\n exNavList += `\n <div class=\"item-col has-input\">\n <div class=\"hour-input\">\n <input type=\"number\"\n input-type=\"time\"\n max=\"23\"\n min=\"0\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${d.id || -1}\"\n type-node=\"${d.type || \"\"}\"\n value=\"${hhValue}\"\n ${isDisabled ? \"disabled\" : \"\"}\n class=\"hh\">\n <span>:</span>\n <input type=\"number\"\n input-type=\"time\"\n max=\"59\"\n min=\"0\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${d.id || -1}\"\n type-node=\"${d.type || \"\"}\"\n value=\"${mmValue}\"\n ${isDisabled ? \"disabled\" : \"\"}\n class=\"mm\">\n </div>\n </div>`;\n break;\n\n case \"text\":\n case \"number\":\n default:\n exNavList += `\n <div class=\"item-col has-input\">\n <input\n type=\"${v.input || \"text\"}\"\n input-type=\"${v.input || \"text\"}\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${d.id || -1}\"\n type-node=\"${d.type || \"\"}\"\n ${isDisabled ? \"disabled\" : \"\"}\n value=\"${value}\"/>\n </div>`;\n }\n } else {\n exNavList += `\n <div class=\"item-col\">\n ${value}\n </div>`;\n }\n });\n }\n\n exNavList += `\n </div>`;\n\n if (d.children) {\n d.children.forEach(c => {\n if (c.isHidden) return;\n exNavList += `<div class=\"child-ex-nav-item ${d.isClosed ? \"hide\" : \"\"}\" child=\"${d.id || -1}\">`;\n\n if (c.withNav !== false) {\n config.timeline.nav.left.extend.vars.forEach(v => {\n if (v.onlyTab && tab && v.onlyTab !== tab.key) return;\n let value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(c.values, v.varName);\n\n if (v.round && !isNaN(value)) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].round(value, v.round);\n }\n\n if (v.input) {\n switch (v.input) {\n case \"hour\":\n value = value ? value.split(\":\") : [0, 0];\n let hhValue = value[0];\n let mmValue = value[1];\n exNavList += `\n <div class=\"item-col has-input\">\n <div class=\"hour-input\">\n <input type=\"number\"\n input-type=\"time\"\n max=\"23\"\n min=\"0\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${c.id || -1}\"\n type-node=\"${c.type || \"\"}\"\n value=\"${hhValue}\"\n ${isDisabled ? \"disabled\" : \"\"}\n class=\"hh\">\n <span>:</span>\n <input type=\"number\"\n input-type=\"time\"\n max=\"59\"\n min=\"0\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${c.id || -1}\"\n type-node=\"${c.type || \"\"}\"\n value=\"${mmValue}\"\n ${isDisabled ? \"disabled\" : \"\"}\n class=\"mm\">\n </div>\n </div>`;\n break;\n\n case \"text\":\n case \"number\":\n default:\n exNavList += `\n <div class=\"item-col has-input\">\n <input \n type=\"${v.input || \"text\"}\"\n input-type=\"${v.input || \"text\"}\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${c.id || -1}\"\n type-node=\"${c.type || \"\"}\"\n ${isDisabled ? \"disabled\" : \"\"}\n value=\"${value}\"/>\n </div>`;\n }\n } else {\n exNavList += `\n <div class=\"item-col\">\n ${value}\n </div>`;\n }\n });\n }\n\n exNavList += `\n </div>`;\n });\n } //buttons\n\n\n btnNavList += `<div class=\"cap-btn-nav-item parent\">\n <div class=\"cap-btn-nav-item-content\">`;\n\n if (config.timeline.nav.left.buttons && config.timeline.nav.left.buttons.vars) {\n config.timeline.nav.left.buttons.vars.forEach(btn => {\n if (d.withBtnNav) {\n let btnContent = \"\";\n let className = btn.className || \"\";\n\n if (btn.icon) {\n btnContent = btn.icon ? btn.icon : \"\";\n }\n\n if (btn.iconFormatter) {\n btnContent = btn.iconFormatter ? btn.iconFormatter(d, btn) : \"\";\n }\n\n if (btn.shape) {\n className += \" cap-btn-\" + btn.shape;\n btnContent += `<span> ${btn.formatter ? btn.formatter(d, btn) : \"\"} </span> `;\n }\n\n if (btn.btnClassNameFormatter) {\n let newClassName = btn.btnClassNameFormatter(d, btn);\n\n if (newClassName) {\n className += \" \" + newClassName;\n }\n }\n\n btnNavList += `\n <button class=\"cap-btn-shape ${className}\"\n input-key=\"${btn.key || \"\"}\"\n item-id=\"${d.id || -1}\"\n ${isDisabled ? \"disabled\" : \"\"}\n type-node=\"${d.type || \"\"}\">\n ${btnContent}\n </button>`;\n }\n });\n }\n\n btnNavList += `\n </div>\n </div>`;\n\n if (d.children) {\n d.children.forEach(c => {\n if (c.isHidden) return; //buttons\n\n btnNavList += `<div class=\"cap-btn-child-nav-item parent ${d.isClosed ? \"hide\" : \"\"}\" child=\"${d.id || -1}\">\n <div class=\"cap-btn-nav-item-content\">`;\n\n if (config.timeline.nav.left.buttons && config.timeline.nav.left.buttons.vars) {\n config.timeline.nav.left.buttons.vars.forEach(btn => {\n if (c.withNav !== false) {\n let btnContent = \"\";\n let className = btn.className || \"\";\n\n if (btn.icon) {\n btnContent = btn.icon ? btn.icon : \"\";\n }\n\n if (btn.iconFormatter) {\n btnContent = btn.iconFormatter ? btn.iconFormatter(c, btn) : \"\";\n }\n\n if (btn.shape) {\n className += \" cap-btn-\" + btn.shape;\n btnContent += `<span> ${btn.formatter ? btn.formatter(c, btn) : \"\"} </span> `;\n }\n\n if (btn.btnClassNameFormatter) {\n let newClassName = btn.btnClassNameFormatter(c, btn);\n\n if (newClassName) {\n className += \" \" + newClassName;\n }\n }\n\n btnNavList += `\n <button class=\"cap-btn-shape ${className}\"\n input-key=\"${btn.key || \"\"}\"\n item-id=\"${c.id || -1}\"\n ${isDisabled ? \"disabled\" : \"\"}\n type-node=\"${c.type || \"\"}\">\n ${btnContent}\n </button>`;\n }\n });\n }\n\n btnNavList += `\n </div>\n </div>`;\n });\n }\n });\n let itemDetail = ` <div class=\"detail-nav-item hide\">\n ${this.getDetailNavItemContent()}\n </div>`;\n let str = `<div class=\"nav-container\">\n ${itemDetail}\n <div class=\"nav-item-list\">\n ${navList}\n </div>\n <div class=\"initial-nav-list\">\n ${initialNavList}\n </div>\n <div class=\"extend-nav-list\">\n ${exNavList}\n </div>\n <div class=\"cap-btn-nav-list\">\n ${btnNavList}\n </div>\n </div>`;\n let navContainer = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n $elem.innerHTML = \"\";\n $elem.append(navContainer); //detalle de nav-item\n\n $elem.querySelectorAll(\".item-title.hoverable\").forEach(i => {\n i.addEventListener(\"mouseover\", e => {\n let pos = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].eventToPositionNavLeft(config, e, $elem);\n let itemId = i.getAttribute(\"item-id\");\n let item = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getItemById(config, itemId);\n let typeNode = i.getAttribute(\"type-node\");\n i.dispatchEvent(new CustomEvent(\"overNavItem\", {\n bubbles: true,\n cancelable: false,\n detail: {\n originalEvt: e,\n item: item,\n type: typeNode,\n pos: pos\n }\n }));\n });\n }); //oculta detalle de nav-item, al salir del nav-item-list\n\n $elem.querySelectorAll(\".nav-item-list\").forEach(i => {\n i.addEventListener(\"mouseleave\", e => {\n i.dispatchEvent(new CustomEvent(\"leaveNavItem\", {\n bubbles: true,\n cancelable: false\n }));\n });\n }); //oculta detalle de nav-item-list, al salir de nav-item\n\n $elem.querySelectorAll(\".item-title:not(.hoverable)\").forEach(i => {\n i.addEventListener(\"mousemove\", e => {\n i.dispatchEvent(new CustomEvent(\"leaveNavItem\", {\n bubbles: true,\n cancelable: false\n }));\n });\n });\n $elem.querySelectorAll(\".item-title.clickeable\").forEach(i => {\n i.addEventListener(\"click\", e => {\n let itemId = i.getAttribute(\"item-id\");\n let typeNode = i.getAttribute(\"type-node\");\n let value = i.value;\n i.dispatchEvent(new CustomEvent(\"clickNavLeftItem\", {\n bubbles: true,\n cancelable: false,\n detail: {\n itemId: itemId,\n type: typeNode,\n value: value\n }\n }));\n });\n });\n $elem.querySelectorAll(\".multibuttons-btn\").forEach(i => {\n i.addEventListener(\"click\", e => {\n let pos = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].eventToPositionNavLeft(config, e, $elem);\n let itemId = i.getAttribute(\"item-id\");\n let typeNode = i.getAttribute(\"type-node\");\n i.dispatchEvent(new CustomEvent(\"clickMultiButtonsBtn\", {\n bubbles: true,\n cancelable: false,\n detail: {\n itemId: itemId,\n type: typeNode,\n pos,\n button: i,\n event: e\n }\n }));\n });\n });\n $elem.querySelectorAll(\"input\").forEach(i => {\n i.addEventListener(\"change\", e => {\n let inputType = i.getAttribute(\"input-type\");\n let key = i.getAttribute(\"input-key\");\n let itemId = i.getAttribute(\"item-id\");\n let typeNode = i.getAttribute(\"type-node\");\n let item = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getItemById(config, itemId);\n let value = i.value;\n\n if (inputType == \"time\") {\n let hh_input = i.parentElement.querySelector(\"input.hh\").value;\n let mm_input = i.parentElement.querySelector(\"input.mm\").value;\n mm_input = mm_input < 10 ? \"0\" + parseFloat(mm_input) : mm_input;\n i.parentElement.querySelector(\"input.mm\").value = mm_input;\n value = hh_input + \":\" + mm_input;\n }\n\n i.dispatchEvent(new CustomEvent(\"saveNavLeftInput\", {\n bubbles: true,\n cancelable: false,\n detail: {\n key: key,\n itemId: itemId,\n item: item,\n type: typeNode,\n value: value,\n tabSelected: tab\n }\n }));\n });\n });\n $elem.querySelectorAll(\"button.cap-btn-shape\").forEach(i => {\n i.addEventListener(\"click\", e => {\n let key = i.getAttribute(\"input-key\");\n let itemId = i.getAttribute(\"item-id\");\n let typeNode = i.getAttribute(\"type-node\");\n i.dispatchEvent(new CustomEvent(\"clickNavLeftButton\", {\n bubbles: true,\n cancelable: false,\n detail: {\n key: key,\n itemId: itemId,\n type: typeNode\n }\n }));\n });\n });\n $elem.querySelectorAll(\"button.detail-btn\").forEach(i => {\n i.addEventListener(\"click\", e => {\n let itemId = i.getAttribute(\"item-id\");\n let typeNode = i.getAttribute(\"type-node\");\n let item = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getItemById(config, itemId, \"parent\");\n\n if (item && item.onClickDetailButton) {\n item.onClickDetailButton({\n itemId: itemId,\n type: typeNode,\n item: item,\n event: e,\n button: i\n });\n }\n });\n });\n $elem.querySelectorAll(\"button.tree-icon\").forEach(i => {\n i.addEventListener(\"click\", e => {\n let itemId = i.getAttribute(\"item-id\");\n let typeNode = i.getAttribute(\"type-node\");\n let dataConfig = config.data.find(d => d.id == itemId);\n let $navItem = e.currentTarget.closest(\".nav-item\");\n let $children = $navItem.querySelector(\".children-items\");\n let itemsToHide = e.currentTarget.closest(\"nav.left\").querySelectorAll(\"[child='\" + itemId + \"'], [child-list='\" + itemId + \"']\");\n\n if ($children) {\n if ($children.classList.contains(\"hide\")) {\n e.currentTarget.classList.add(\"cap-rotate\");\n itemsToHide.forEach(i => i.classList.remove(\"hide\"));\n dataConfig.isClosed = false;\n } else {\n e.currentTarget.classList.remove(\"cap-rotate\");\n itemsToHide.forEach(i => i.classList.add(\"hide\"));\n dataConfig.isClosed = true;\n }\n }\n\n i.dispatchEvent(new CustomEvent(\"clickNavLeftTreeIcon\", {\n bubbles: true,\n cancelable: false,\n detail: {\n itemId: itemId,\n type: typeNode\n }\n })); //e.currentTarget.parent\n });\n });\n return $elem;\n },\n\n /**\n * Crea Html como String, para el detalle de items en el Sidebar Izquierdo\n *\n * @param {Object} [item={}] - Configuracion de item\n * @return {String} Html de ventana de detalle\n */\n getDetailNavItemContent(item = {}) {\n if (item.navOver == undefined) item.navOver = {};\n return `\n <div class=\"header-detail\">\n <div class=\"detail-title truncate\">\n ${item.label || \"\"}\n </div>\n <div class=\"detail-subtitle\">\n ${item.navOver.subtitle || \"\"}\n </div>\n <div class=\"header-chip ${item.light ? item.light + \"-light\" : \"\"} ${item.navOver.chip ? \"\" : \"hide\"}\">\n ${item.navOver.chip || \"\"}\n </div>\n </div>\n\n <div class=\"detail-container\">\n ${item.navOver.content || \"\"}\n </div>`;\n },\n\n /**\n * Crea Sidebar Derecho\n * Usado principalmente para formulario de ingreso de datos para los dias\n * seleccionados\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} tab - Tab de referencia, para la creacion del formulario\n * @return {Object} {element, inputs}, element es el elemento Dom del sidebar,\n * inputs es un array de elementos Dom de cada input creado\n * (no son elementos html de tipo input)\n */\n createNavRight(config, tab = null) {\n var $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"nav\", {\n className: \"right\"\n });\n return this.redrawNavRight(config, $elem, tab, null, [], null);\n },\n\n /**\n * Recrea Sidebar Derecho\n * Utiliza $elem como elemento dom donde recrearlo\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} $elem - Elemento Dom donde crea el sidebar derecho\n * @param {Object} tab - Tab de referencia, para la creacion del formulario\n * @param {Object} dataDay - datos del dia seleccionando, para autorrelleno de formulario\n * @param {Object} daySelected - datos del dia seleccionado\n * @param {String} daySelected.date - fecha del dia seleccionado\n * @param {Object} daySelected.item - Item de Sidebar relacionado al dia seleccionado\n * @param {Object} daySelected.pos - posicion de dia seleccionado\n * @return {Object} Elemento Dom Sidebar Derecho\n */\n redrawNavRight(config, $elem, selected = null, tab = null, dataDay = null, daySelected = null) {\n let $navRight = $elem; //dom.createElement(\"nav\",{className:\"right\"});\n\n let $divContainer = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"nav-input-container\"\n });\n let $inputs = [];\n let checkboxInputs = [];\n let inputsWithReload = [];\n let tabSelected = tab;\n selected = selected || [daySelected];\n\n if (tabSelected && tabSelected.inputs) {\n tabSelected.inputs.forEach(i => {\n if (i.disabled) return;\n\n if (i.showInputIf && !i.showInputIf(dataDay, daySelected, selected, tabSelected)) {\n return;\n }\n\n let $input = this.createInput(i, dataDay, daySelected, selected, tabSelected);\n\n if ($input) {\n $divContainer.appendChild($input);\n $inputs.push($input);\n\n if (i.type == \"checkbox\") {\n checkboxInputs.push($input);\n }\n\n if (i.reloadOnSelect != null) {\n inputsWithReload.push({\n $input,\n config: i\n });\n }\n }\n });\n } //manejo de eventos para inputs con showIf\n\n\n if (checkboxInputs) {\n checkboxInputs.forEach($c => {\n //obtiene key de checkbox\n let key = $c.getAttribute(\"input-key\");\n let props = tabSelected.inputs.find(i => {\n return i.key == key;\n });\n let isChecked = false;\n\n if (dataDay) {\n isChecked = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n } //obtiene inputs relacionados desde config para mostrar/ocultar\n\n\n let inputsToHide = tabSelected.inputs.filter(i => {\n return i.showIf && i.showIf == key;\n });\n let inputsToHideKeys = inputsToHide.map(i => i.key); //obtiene inputs del dom, filtrando con inputsToHide\n\n let $inputsHidden = $inputs.filter($i => {\n let inputKey = $i.getAttribute(\"input-key\");\n return inputsToHideKeys.indexOf(inputKey) > -1;\n }); //si hay inputs,\n\n if ($inputsHidden) {\n if (!isChecked) {\n $inputsHidden.forEach($i => {\n $i.classList.add(\"hide\");\n });\n }\n\n $c.addEventListener(\"input\", e => {\n $inputsHidden.forEach($i => {\n let fn = $c.querySelector(\"input[type='checkbox']\").checked ? \"remove\" : \"add\";\n $i.classList[fn](\"hide\");\n });\n });\n }\n });\n }\n\n let saveCancelBtns = this.createNavRightbuttons(config);\n $divContainer.appendChild(saveCancelBtns);\n $navRight.innerHTML = \"\";\n $navRight.appendChild($divContainer);\n return {\n element: $navRight,\n inputs: $inputs,\n inputsWithReload,\n saveCancelBtns\n };\n },\n\n /**\n * Crea Corner inferior izquierdo, como titulo para footer\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom Corner Footer\n */\n createCornerFooter(config) {\n if (config.timeline.footer === undefined || config.timeline.footer.enabled == false) return null;\n let str = \"\";\n\n if (config.timeline.footer) {\n str += `<div class=\"corner-footer\">\n <div class=\"corner-title\">\n <span>\n ${config.timeline.footer.label}\n </span>\n </div>\n </div>`;\n }\n\n return _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n },\n\n /**\n * Crea Footer para planilla\n * Inicialmente creado para totales\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom Corner Footer\n */\n createFooter(config) {\n if (config.timeline.footer === undefined || config.timeline.footer.enabled == false) return null;\n let str = `\n <footer>\n <div class=\"footer-container\">\n `;\n config.timeline.footer.data.forEach(d => {\n str += `\n <div class=\"footer-item\">${d.value}</div>\n `;\n });\n str += `\n </div>\n </footer>\n `;\n return _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n },\n\n /**\n * Crea Footer para planilla\n * Inicialmente creado para totales\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object[]} selected - array de objetos, de dias seleccionados\n * @return {Object} Elemento Dom Corner Footer\n */\n createSelectBoard(config, selected) {\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"select-container\"\n });\n return this.redrawSelectBoard($elem, selected);\n },\n\n /**\n * Crea linea vertical para fecha Actual\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom Corner Footer\n */\n createTodayLine(config) {\n return this.redrawTodayLine(config, _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"today-line\"\n }));\n },\n\n /**\n * Recrea linea vertical para fecha Actual\n * si el elemento $elem no es enviado, se crea un nuevo elemento\n *\n * Si el dia actual no esta dentro del rango de fechas del config,\n * deshabilita la linea con la clase css .disable-line\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} [$elem=null] - Elemento Dom donde recrea la linea, si es null, la crea\n * @return {Object} Elemento Dom Corner Footer\n */\n redrawTodayLine(config, $elem = null) {\n let endTime = new Date(config.timeline.end).getTime();\n let todayTime = new Date().getTime();\n let {\n height,\n dayWidth\n } = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getTableDimensions(config);\n if ($elem == null) $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"today-line\"\n });\n\n if (endTime < todayTime) {\n $elem.classList.add(\"disable-line\");\n } else {\n $elem.classList.remove(\"disable-line\");\n }\n\n let diffDays = Math.floor(_util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].diffDays(config.timeline.start, _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].formatDate(new Date())));\n let diff = diffDays * dayWidth;\n diff += dayWidth / 2 - 2; // para centrar linea\n\n Object.assign($elem.style, {\n \"margin-left\": diff + \"px\",\n height: height + \"px\"\n });\n return $elem;\n },\n\n /**\n * Crea elemento FloatBox, que contiene los datos que se muestra en la tabla\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} tab - Tab de referencia, para mostrar datos configurados por tab\n * @return {Object} Elemento Dom Corner Footer\n */\n createFloatBox(config, tab) {\n let $container = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"float-box-container\"\n });\n return this.redrawFloatBox(config, tab, $container);\n },\n\n /**\n * Recrea elemento FloatBox, que contiene los datos que se muestra en la tabla\n * Se usa principalmente para mostrar datos en la tabla de la planilla\n * los muestra de manera flotante, calculando el Top y el Left segun la poscion\n *\n * Se consideran los elementos padres ocultos, para ocultar los datos\n *\n * Se insertan los elementos FloatBox, como elemento con datos de un item y dia especifico\n *\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} tab - Tab de referencia, para mostrar datos configurados por tab\n * @return {Object} Elemento Dom Corner Footer\n */\n redrawFloatBox(config, tab, $container) {\n $container.innerHTML = \"\"; //let tabSelected = tab || null;\n\n config.data.forEach(dataParent => {\n if (dataParent.isHidden) return;\n (dataParent.data || []).forEach(data => {\n this.createFloatBoxItem({\n container: $container,\n data,\n item: dataParent,\n isClosed: dataParent.isClosed,\n tab,\n config,\n typeNode: \"parent\"\n });\n });\n dataParent.children.forEach(dataChild => {\n if (dataChild.isHidden) return;\n dataChild.data.forEach(data => {\n this.createFloatBoxItem({\n container: $container,\n data,\n item: dataChild,\n isClosed: dataParent.isClosed,\n tab,\n config,\n typeNode: \"child\"\n });\n });\n });\n });\n return $container;\n },\n\n createFloatBoxItem({\n container,\n data,\n item,\n isClosed,\n tab,\n config,\n typeNode = \"child\"\n }) {\n if ((!data.message || data.message.value == null) && (data.values == null || data.values == undefined || Object.entries(data.values).length === 0)) {\n return null;\n } //children Data\n\n\n let position = this.getPositionFloatBox(config, data, item, typeNode);\n let className = \"\";\n let hasMessage = false;\n\n if (data.errors && data.errors.length > 0) {\n className += \"has-errors \";\n\n if (data.errors[0]) {\n className += data.errors[0].classNameIcon + \" \";\n }\n }\n\n if (isClosed) {\n className += \"hide \";\n }\n\n let msg = null;\n\n if (tab.floatBox && tab.floatBox.messagePath) {\n msg = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data, tab.floatBox.messagePath);\n }\n\n if (msg || data.message && data.message.value) {\n className += \"has-message \";\n hasMessage = true;\n }\n\n let strMsg = \"\";\n\n if (hasMessage) {\n let viewBox = \"0 0 24 24\"; //email outline icon\n\n let icon = \"M22 6C22 4.9 21.1 4 20 4H4C2.9 4 2 4.9 2 6V18C2 19.1 2.9 20 4 20H20C21.1 20 22 19.1 22 18V6M20 6L12 11L4 6H20M20 18H4V8L12 13L20 8V18Z\";\n strMsg = `\n <div class=\"icon-message\">\n <svg viewBox=\"${viewBox}\">\n <path d=\"${icon}\" />\n </svg>\n </div>\n `;\n }\n\n let str = `\n <div class=\"float-box ${className} \"\n style=\"${position ? position : \"\"}\"\n item-id=\"${item.id || -1}\"\n type-node=\"${item.type || \"\"}\">\n\n ${strMsg}\n <div class=\"float-box-content\">`;\n let strExt = `\n <div class=\"float-box-ext ${isClosed ? \"hide\" : \"\"}\"\n style=\"${position ? position : \"\"}\"\n item-id=\"${item.id || -1}-ext\"\n type-node=\"${item.type || \"\"}\">\n <div class=\"long-bar-container\">`;\n\n if (tab && tab.floatBox) {\n if (tab.floatBox.plots) {\n str += `<div class=\"plot-floatbox-container\">`;\n tab.floatBox.plots.forEach(n => {\n let cssVars = \"\";\n let className = \"\";\n\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.varName) !== null) {\n if (n.color) {\n cssVars = `--local-color:${n.color};`;\n }\n\n className = n.className || \"\";\n str += `<div class=\"plot-floatbox ${className} ${n.style || \"\"}\" style=\"${cssVars} \"></div>`;\n }\n });\n str += `\n </div>`;\n }\n\n if (tab.floatBox.icons) {\n tab.floatBox.icons.forEach(iconConfig => {\n let className = \"\";\n let colorClass = \"\";\n let colorStyle = \"\";\n let viewBox = \"0 0 24 24\";\n let icon = iconConfig.icon || null;\n\n if (iconConfig.varName) {\n let iconVar = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, iconConfig.varName);\n\n if (iconVar) {\n icon = iconVar;\n }\n }\n\n if (iconConfig.className) {\n className = iconConfig.className;\n }\n\n if (iconConfig.color) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(iconConfig.color)) {\n colorStyle = `--local-color: ${iconConfig.color};`;\n } else {\n colorClass = iconConfig.color;\n }\n }\n\n if (iconConfig.colorVarName) {\n let colorVar = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, iconConfig.colorVarName);\n\n if (colorVar) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(colorVar)) {\n colorStyle = `--local-color: ${colorVar};`;\n } else {\n colorClass = colorVar;\n }\n }\n }\n\n str += `\n <div class=\"icon-floatbox ${className} ${colorClass ? \"has-color\" : \"\"}\" style=\"${colorStyle}\">\n <svg viewBox=\"${viewBox}\">\n <path d=\"${icon}\" />\n </svg>\n </div>\n `;\n });\n } //numeros en el floatBox\n\n\n if (tab.floatBox.nums) {\n tab.floatBox.nums.forEach(n => {\n if (tab.legends && n.tabKey) {\n let legend = tab.legends.find(l => l.key == n.tabKey);\n if (legend && !legend.active) return;\n }\n\n let dataFloatBox = null;\n let className = \"\";\n let showIf = true;\n let hideIf = false;\n let colorClass = \"\";\n let colorStyle = \"\";\n let classNamesExt = \"\";\n let colorStyleExt = \"\";\n let cssVars = \"\";\n\n if (n.varName) {\n dataFloatBox = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.varName);\n }\n\n if (n.varShow) {\n showIf = Boolean(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.varShow));\n dataFloatBox = dataFloatBox || \"\";\n }\n\n if (n.varHide) {\n hideIf = Boolean(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.varHide));\n }\n\n if (n.hidden === true) {\n hideIf = true;\n }\n\n if (n.shape) {\n className += \"shape-\" + n.shape;\n }\n\n if (n.color) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(n.color)) {\n colorStyle = `--local-color: ${n.color};`;\n } else {\n colorClass = n.color;\n }\n }\n\n if (n.longBar) {\n let longBarColor = \"\";\n let longBarOpacity = \"\";\n\n if (n.longBarColor) {\n longBarColor = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.longBarColor);\n }\n\n if (longBarColor) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(longBarColor)) {\n colorStyleExt = `--local-color: ${longBarColor};`;\n } else {\n classNamesExt += longBarColor + \"-light \";\n }\n } else if (colorClass && colorClass != \"\") {\n classNamesExt += colorClass;\n } else if (colorStyle && colorStyle != \"\") {\n colorStyleExt = colorStyle;\n }\n\n if (n.longBarOpacity) {\n longBarOpacity = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.longBarOpacity) || null;\n\n if (longBarOpacity) {\n colorStyleExt += \"--local-opacity: \" + longBarOpacity + \";\";\n }\n }\n\n if (n.longBarClassName) {\n classNamesExt += _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.longBarClassName) || \"\";\n }\n\n let longBar = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.longBar);\n\n if (longBar) {\n cssVars = `--long:${longBar};`;\n }\n }\n\n if (dataFloatBox !== null && showIf && !hideIf) {\n str += `<span class=\"data ${colorClass} ${className}\" style=\"${colorStyle}\">\n ${typeof dataFloatBox == \"string\" ? dataFloatBox : \"\"}\n ${typeof dataFloatBox == \"number\" ? _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].round(dataFloatBox, n.round) : \"\"}\n </span>`;\n\n if (n.longBar && cssVars) {\n strExt += `<div class=\"long-bar ${classNamesExt}\" style=\"${colorStyleExt} ${cssVars} \"></div> `;\n }\n }\n });\n } //puntos en el floatBox\n\n\n if (tab.floatBox.dots) {\n str += `<div class=\"dot-container-middle\">`;\n tab.floatBox.dots.forEach(dot => {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, dot.varName) !== null) {\n let className = \"\";\n let colorClass = \"\";\n let colorStyle = \"\";\n\n if (dot.shape) {\n className += dot.shape;\n }\n\n if (dot.color) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(dot.color)) {\n colorStyle = `--local-color: ${dot.color}`;\n } else {\n colorClass = dot.color;\n }\n }\n\n str += `\n <div class=\"dot ${colorClass} ${className}\" style=\"${colorStyle}\" ></div>`;\n }\n });\n str += `\n </div>`;\n } //fila de puntos en floatBox\n\n\n if (tab.floatBox.rowDots) {\n tab.floatBox.rowDots.forEach(row => {\n let freeColumns = 4;\n str += `<span class=\"rowdot--row \">`;\n row.forEach(dot => {\n if (tab.legends && dot.tabKey) {\n let legend = tab.legends.find(l => l.key == dot.tabKey);\n if (legend && !legend.active) return;\n }\n\n let dataFloatBox = null;\n let className = \"\";\n let showIf = true;\n let hideIf = false;\n let colorClass = \"\";\n let colorStyle = \"\";\n\n if (dot.varName) {\n dataFloatBox = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, dot.varName);\n dataFloatBox = parseInt(dataFloatBox);\n }\n\n if (dot.varShow) {\n showIf = Boolean(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, dot.varShow));\n dataFloatBox = dataFloatBox || \"\";\n }\n\n if (dot.varHide) {\n hideIf = Boolean(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, dot.varHide));\n }\n\n if (dot.shape) {\n className += \" shape-\" + dot.shape;\n }\n\n if (dot.color) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(dot.color)) {\n colorStyle = `--local-color: ${dot.color}`;\n } else {\n colorClass = dot.color;\n }\n }\n\n if (dataFloatBox !== null && dataFloatBox > 0 && showIf && !hideIf && freeColumns > 0) {\n let n = dataFloatBox > freeColumns ? freeColumns : dataFloatBox;\n freeColumns -= n;\n\n for (let index = 0; index < n; index++) {\n str += `<div class=\"rowdot--dot ${colorClass} ${className}\" style=\"${colorStyle}\"></div>`;\n }\n }\n });\n str += `</span>`;\n });\n }\n }\n\n str += `\n </div>\n </div>`;\n strExt += `\n </div>\n </div>`;\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n let $elemExt = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(strExt);\n $elem.addEventListener(\"mouseover\", e => {\n $elem.dispatchEvent(new CustomEvent(\"mouseOverFloatBox\", {\n bubbles: true,\n cancelable: false,\n detail: {\n item: item,\n data: data,\n originalEvt: e\n }\n }));\n });\n $elem.addEventListener(\"click\", e => {\n $elem.dispatchEvent(new CustomEvent(\"clickFloatBox\", {\n bubbles: true,\n cancelable: false,\n detail: {\n item: item,\n data: data,\n originalEvt: e\n }\n }));\n });\n container.appendChild($elem);\n container.appendChild($elemExt);\n },\n\n /**\n * Crea DetailDay, detalle de valores de item y Dia\n * se usa para:\n * - Muestra nombre de item y detalles\n * - Muestra capsulas de datos\n * - Muestra Pills, pildoras de datos resumidos\n * - Muestra alertas\n * - Muestra Mensaje\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} item - Item relacionado\n * @param {Object} dataDay - valores de item y Dia\n * @param {Boolean} [onlyStringContent = false] - para escoger si devuelve String o DomElement\n * @return {String|Object} Elemento como String o DomElement\n */\n createDetailDay(config, item = {}, dataDay, tabSelected, onlyStringContent = false) {\n let str = `\n <div class=\"header-detail\">\n <div class=\"title truncate\">\n ${item.label || \"\"}\n </div>\n <div class=\"subtitle\">\n ${dataDay ? _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].formatDateReadeable(dataDay.date) : \"\"}\n </div>\n </div>\n\n <div class=\"list-detail list column-flex\">`; //CAPSULES\n\n let visibleItemsCount = 0; // Contador de elementos visibles\n\n if (dataDay) {\n config.timeline.detailDay.capsules.forEach(cap => {\n //para comprobar si tiene datos, se obtiene el primer valor\n //de la lista de values de una capsula\n let hasValues = cap.values.filter(v => {\n let value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay.values, v.varName);\n return value !== null && !(Array.isArray(value) && value.length === 0);\n }).length > 0;\n let hideIf = false;\n\n if (cap.hideIf) {\n hideIf = Boolean(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay.values, cap.hideIf));\n }\n\n let colorClass = \"\";\n let colorStyle = \"\";\n\n if (cap.color) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(cap.color)) {\n colorStyle = `--local-color: ${cap.color};`;\n colorStyle += `--local-color-font: ${cap.color};`;\n } else {\n colorClass = cap.color;\n }\n }\n\n if (hasValues && !hideIf) {\n visibleItemsCount++; // Incrementar contador de elementos visibles\n\n str += `\n <div class=\"item-detail ${colorClass}\" style=\"${colorStyle}\">\n\n <div class=\"left-icon ${cap.shape || \"\"} \"></div>\n\n <div class=\"name\">\n <span>\n ${cap.title || \"\"}\n </span>\n </div>`;\n str += `\n <div class=\"item-description\"> `;\n cap.values.forEach(v => {\n let value = v.varName ? _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay.values, v.varName) : null;\n\n if (cap.isLabeledArray) {\n value.forEach(valueLabeled => {\n let outputValue = null;\n let valueName = v.valueName ? v.valueName : \"value\";\n let tempValue = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(valueLabeled, valueName);\n\n if (tempValue) {\n outputValue = v.round ? _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].round(tempValue, v.round) : tempValue;\n }\n\n if (v.formatter) {\n outputValue = v.formatter(valueLabeled);\n }\n\n if (typeof outputValue == \"number\") {\n outputValue = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].formatNumber(outputValue);\n }\n\n str += outputValue == null ? \"\" : `\n <div class=\"desc ${v.showColumn ? \"desc-column\" : \"\"}\">\n \n <div class=\"label\">\n ${v.hideLabel ? \"\" : valueLabeled.label}\n </div >\n <div class=\"val\">` + (v.hidePreffix !== true ? `\n <span class=\"prefix\">\n ${v.prefix || \"\"}\n </span>` : \"\") + `<span class=\"value\">\n ${outputValue}\n </span>` + (v.hideSuffix !== true ? `\n <span class=\"suffix\">\n ${valueLabeled.suffix || v.suffix || \"\"}\n </span>` : \"\") + `\n </div>\n </div>`;\n });\n } else {\n let outputValue = v.round ? _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].round(value, v.round) : value;\n\n if (v.formatter) {\n outputValue = v.formatter({\n options: v,\n dataDay,\n outputValue\n });\n }\n\n if (typeof outputValue == \"number\") {\n outputValue = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].formatNumber(outputValue);\n }\n\n if (outputValue) {\n str += `\n <div class=\"desc\">\n <span class=\"prefix\">\n ${v.prefix || \"\"}\n </span>\n <span class=\"value\">\n ${outputValue}\n </span>\n <span class=\"suffix\">\n ${v.suffix || \"\"}\n </span>\n </div>`;\n }\n }\n });\n str += `\n </div>`;\n str += `\n </div>`; // end .item-detail\n }\n });\n } // Agregar clase single-item si solo hay un elemento visible\n\n\n const columnClass = visibleItemsCount === 1 ? \"list column-flex single-item\" : \"list column-flex\";\n str = str.replace(\"list column-flex\", columnClass);\n str += `\n </div>`; // list-detail\n //PILLS\n\n if (config.timeline.detailDay.pillsVarName && dataDay && dataDay.values[config.timeline.detailDay.pillsVarName]) {\n str += `\n <div class=\"elements-detail\">\n <div class=\"name\"> ${config.timeline.detailDay.pillsTitle} </div>\n <div class=\"elements-list\">`;\n dataDay.values[config.timeline.detailDay.pillsVarName].forEach(e => {\n let value = e.value;\n\n if (typeof outputValue == \"number\") {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].formatNumber(value);\n }\n\n str += `\n <div class=\"element-detail\">\n <b>${e.label}</b>\n ${value}\n </div>`;\n });\n str += `\n </div>\n </div>`; //end .element-detail > .element-list\n } //str += `</div>`;\n\n\n if (dataDay && dataDay.errors && dataDay.errors.length > 0) {\n dataDay.errors.forEach(err => {\n str += `\n <div class=\"alert\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].alert}\n ${err.label}\n </div>`;\n });\n }\n\n let msg = null;\n let author = null;\n let dateMsg = null;\n\n if (dataDay && tabSelected.floatBox && tabSelected.floatBox.messagePath) {\n msg = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, tabSelected.floatBox.messagePath);\n }\n\n if (!msg && dataDay && dataDay.message && dataDay.message.value) {\n msg = dataDay.message.value;\n author = dataDay.message.author;\n dateMsg = _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].formatDateReadeable(new Date(dataDay.message.date));\n }\n\n if (msg) {\n //msg = msg.replace(/(\\r\\n|\\r|\\n)/g, '<br>');\n str += `\n <div class=\"msj-container\">\n <div class=\"msj\">\n <pre>${msg || \"\"}</pre>\n </div>\n <div class=\"msj-detail\">\n <span class=\"email\"> ${author || \"\"} </span>\n <span class=\"date\"> ${dateMsg || \"\"} </span>\n </div>\n </div>`;\n }\n\n let strContainer = `<div class=\"detail-day dd-hide\"> ${str} </div>`;\n if (onlyStringContent) return str;\n return _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(strContainer);\n },\n\n /**\n * Recrea HTML de detailDay\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} item - Item relacionado\n * @param {Object} dataDay - valores de item y Dia\n * @return {String} Elemento como String, de detailDay\n */\n redrawDetailDay(config, item, dataDay, tabSelected) {\n return this.createDetailDay(config, item, dataDay, tabSelected, true);\n },\n\n /**\n * Reposiciona FloatBox\n * verifica si el parent esta desplegado, para ocultar los datos\n *\n * Solo actualiza las alturas de los floatbox\n * no recrea los floatbox, es mas optimo\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} item - Item relacionado\n */\n repositionFloatBox(config, $floatBoxContainer) {\n $floatBoxContainer.querySelectorAll(\".float-box\").forEach($f => {\n let itemId = $f.getAttribute(\"item-id\");\n let itemHeight = parseFloat(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getCSSVariable(config, \"--item-height\"));\n let item, parent;\n ({\n item,\n parent\n } = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getItemById(config, itemId, \"child\", true));\n\n if (item) {\n let top = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getPositionByItem(config, item);\n $f.style.top = top * itemHeight + \"px\";\n\n if (parent && parent.isClosed) {\n $f.classList.add(\"hide\");\n } else if ($f.classList.contains(\"hide\")) {\n $f.classList.remove(\"hide\");\n }\n }\n });\n },\n\n /**\n * Recrea indicadores de dias seleccionados\n *\n * @param {Object} $elem - Elemento Dom donde crea los elementos seleccionados\n * @param {Object[]} selected - Array con los dias seleccionados\n * @return {Object} Elemento Dom que contiene los indicadores de dias seleccionados\n */\n redrawSelectBoard($elem, selected) {\n $elem.innerHTML = \"\";\n let hasNumber = true;\n\n if (selected) {\n if (selected.length == 1) hasNumber = false;\n selected.forEach(s => {\n let attributes = [];\n\n if (hasNumber) {\n attributes.push({\n name: \"cap-badge\",\n value: s.index\n });\n }\n\n let $s = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"selected-day\",\n attributes\n });\n $s.style.left = s.pos.left + \"px\";\n $s.style.top = s.pos.top + \"px\";\n $elem.append($s);\n });\n }\n\n return $elem;\n },\n\n /**\n * Obtiene String con estilos CSS de la posicion de un floatBox\n * calculado segun item y fecha de los valores\n *\n * @param {Object} config - Configuracion capibara, para ver fecha de inicio\n * @param {Object} data - Datos del dia indicado\n * @param {Object} item - Item relacionado\n * @return {String} String CSS top y left , para posicionar floatBox en table\n */\n getPositionFloatBox(config, data, item, typeNode) {\n let left = _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].diffDays(config.timeline.start, data.date);\n let top = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getPositionByItem(config, item, typeNode);\n let dayWidth = parseFloat(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getCSSVariable(config, \"--day-width\"));\n let itemHeight = parseFloat(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getCSSVariable(config, \"--item-height\"));\n left *= dayWidth;\n top *= itemHeight;\n return \"top: \" + top + \".5px; left:\" + left + \".5px;\";\n },\n\n /**\n * Crea Boton como elemento Dom\n *\n * @param {Object} props - propiedades para boton\n * @param {String} props.className - classes css para boton\n * @param {*} props.key - key para identificar a boton\n * @param {String} props.label - Texto boton\n * @return {Object} Elemento Dom del boton creado\n */\n createButton(props) {\n return _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <button class=\"${props.className || \"\"}\" input-key=\"${props.key || \"\"}\">\n ${props.label || \"\"}\n </button>`);\n },\n\n /**\n * Crea Botones de guardar y cancelar los datos de formulario del sidebar derecho\n *\n * @return {Object} Elemento Dom del botones creados\n */\n createNavRightbuttons(config) {\n let btnSection = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`<div class=\"button-section\"></div>`);\n\n if (config.timeline.nav.right && config.timeline.nav.right.hideSaveButton != true) {\n let saveBtn = this.createButton({\n label: \"Guardar\",\n className: \"cap-btn-raised\"\n });\n btnSection.appendChild(saveBtn);\n saveBtn.addEventListener(\"click\", e => {\n saveBtn.dispatchEvent(new CustomEvent(\"saveMultiInput\", {\n bubbles: true,\n cancelable: false\n }));\n });\n }\n\n if (config.timeline.nav.right && config.timeline.nav.right.hideCancelButton != true) {\n const cancelLabelButton = config.timeline.nav.right.cancelLabelButton || \"Cancelar\";\n let cancelBtn = this.createButton({\n label: cancelLabelButton,\n className: \"cap-btn-outline\"\n });\n btnSection.appendChild(cancelBtn);\n cancelBtn.addEventListener(\"click\", e => {\n cancelBtn.dispatchEvent(new CustomEvent(\"cancelMultiInput\", {\n bubbles: true,\n cancelable: false\n }));\n });\n }\n\n return btnSection;\n },\n\n /**\n * Crea Input como elemento Dom\n *\n * @param {Object} props - config para Input\n * @param {Object} [dataDay = null] - valores de item y Dia, opcional\n * @param {Object} [daySelected = null] - datos del dia seleccionado\n * @param {Object[]} [selected = []] - array de objetos, de dias seleccionados\n * @return {Object} Elemento Dom del input creado\n */\n createInput(props, dataDay = null, daySelected = null, selected = [], tabSelected) {\n let r = null;\n if (props.ignoreRender == true) return r;\n\n switch (props.type) {\n case \"custom\":\n r = props.render ? props.render({\n props,\n dataDay,\n daySelected,\n selected\n }) : null;\n r.setAttribute(\"input-key\", props.key);\n break;\n\n case \"select\":\n r = this.createInputSelect(props, dataDay, daySelected);\n break;\n\n case \"file\":\n r = this.createInputFile(props, dataDay);\n break;\n\n case \"fileLink\":\n r = this.createFileLink(props, dataDay);\n break;\n\n case \"text\":\n r = this.createText(props, selected);\n break;\n\n case \"title\":\n r = this.createTitle(props);\n break;\n\n case \"number\":\n r = this.createInputNumber(props, dataDay);\n break;\n\n case \"float\":\n r = this.createInputFloat(props, dataDay);\n break;\n\n case \"message\":\n r = this.createInputMessage(props, dataDay);\n break;\n\n case \"textarea\":\n r = this.createInputTextArea(props, dataDay);\n break;\n\n case \"checkbox\":\n r = this.createInputCheckbox(props, dataDay);\n break;\n\n case \"inputList\":\n r = this.createInputList(props, dataDay, daySelected);\n break;\n\n case \"input-box\":\n r = this.createInputBox(props, dataDay);\n break;\n\n case \"list\":\n r = this.createList(props, dataDay);\n break;\n\n case \"data-list\":\n r = this.createDataList(props, dataDay, daySelected, selected, tabSelected);\n break;\n\n case \"button\":\n r = this.createInputButton(props, dataDay);\n break;\n\n case \"buttons-group\":\n r = this.createInputButtonsGroup(props, dataDay);\n break;\n\n case \"time\":\n r = this.createInputTime(props, dataDay);\n break;\n\n case \"input-text\":\n default:\n r = this.createInputText(props, dataDay);\n }\n\n return r;\n },\n\n /**\n * Crea Input con formato Hora, como elemento Dom\n *\n * Usa 2 inputs, hora y minutos\n *\n * el value que interpreta es String HH:MM\n *\n * @param {Object} props - config para Input\n * @param {Object} [dataDay = null] - valores de item y Dia, opcional\n * @return {Object} Elemento Dom del input creado\n */\n createInputTime(props, dataDay) {\n let hhValue = \"\";\n let mmValue = \"\";\n\n if (dataDay && dataDay.values) {\n let value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n\n if (value) {\n value = value.split(\":\");\n hhValue = value[0];\n mmValue = value[1];\n }\n }\n\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <span class=\"text-subtitle d-block\">\n ${props.label || \"\"}\n </span>\n <div class=\"d-flex\">\n <div class=\"time\">\n <input type=\"number\"\n class=\"hour\"\n id=\"test\"\n placeholder=\"00\"\n min=\"0\"\n max=\"99\"\n value=\"${hhValue}\">\n <span class=\"symbol\">:</span>\n <input type=\"number\"\n class=\"minutes\"\n placeholder=\"00\"\n min=\"0\"\n max=\"59\"\n value=\"${mmValue}\">\n </div>\n <span class=\"text-hint\">\n ${props.textHint || \"\"}\n </span>\n </div>\n </div>`);\n let $hhInput = $elem.querySelector(\".hour\");\n let $mmInput = $elem.querySelector(\".minutes\");\n $hhInput.addEventListener(\"input\", e => {\n $hhInput.dispatchEvent(new CustomEvent(\"changeTimeInputHH\", {\n bubbles: true,\n cancelable: false,\n detail: {\n key: props.key,\n value: e.srcElement.value\n }\n }));\n });\n $mmInput.addEventListener(\"input\", e => {\n $mmInput.dispatchEvent(new CustomEvent(\"changeTimeInputMM\", {\n bubbles: true,\n cancelable: false,\n detail: {\n key: props.key,\n value: e.srcElement.value\n }\n }));\n });\n this.addKeyDownInputEvents($hhInput, $elem, props);\n this.addKeyDownInputEvents($mmInput, $elem, props);\n return $elem;\n },\n\n /**\n * Crea Text como elemento Dom\n * Se configura como input, pero no devuelve datos, es un texto\n *\n * @param {Object} props - config para Input\n * @return {Object} Elemento Dom del input creado\n */\n createText(props, selected) {\n let label = props.label;\n\n if (props.formatter) {\n label = props.formatter({\n selected\n });\n }\n\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.isHidden ? \"hide \" : \"\"} ${props.toLeft ? \"to-left \" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <span class=\"${props.classNames || \"\"}\">\n ${label}\n </span>\n </div>`);\n return $elem;\n },\n\n /**\n * Crea Title como elemento Dom\n * Se configura como input, pero no devuelve datos, es un texto\n *\n * @param {Object} props - config para Input\n * @return {Object} Elemento Dom del input creado\n */\n createTitle(props) {\n let classNames = \"text-title\";\n\n if (props.isSubtitle) {\n classNames = \"text-subtitle\";\n }\n\n return _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <span class=\"${classNames}\">\n ${props.label}\n </span>\n </div>`);\n },\n\n /**\n * Crea Input tipo Numerico como elemento Dom\n *\n * @param {Object} props - config para Input\n * @param {Object} dataDay - valores de item y Dia, opcional\n * @return {Object} Elemento Dom del input creado\n */\n createInputNumber(props, dataDay) {\n let value = \"\";\n\n if (dataDay && dataDay.values) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n }\n\n value = value || \"\";\n let elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.classNames || \"\"} ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <div class=\"input-section-title\">\n <span class=\"text-subtitle\">\n ${props.label}\n </span>\n <span class=\"text-subtitle-2 \">\n ${props.suffix ? \"(\" + props.suffix + \")\" : \"\"}\n </span>\n </div>\n <div class=\"d-flex\">\n <input type=\"number\"\n class=\"nav-input\"\n value=\"${value}\">\n\n <span class=\"text-hint\">\n ${props.textHint || \"\"}\n </span>\n </div>\n </div>`);\n let inputElem = elem.querySelector(\"input\");\n this.addKeyDownInputEvents(inputElem, elem, props);\n return elem;\n },\n\n /**\n * Crea Input tipo FIlepicker como elemento Dom\n *\n * @param {Object} props - config para Input\n * @param {Object} dataDay - valores de item y Dia, opcional\n * @return {Object} Elemento Dom del input creado\n */\n createInputFile(props, dataDay) {\n let value = \"\";\n let fileName = \"\";\n let filePath = \"\";\n\n if (dataDay && dataDay.values) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n fileName = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.fileNameValue);\n filePath = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.filePathValue);\n }\n\n value = value || \"\";\n fileName = fileName || \"\";\n filePath = filePath || \"\";\n let elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.classNames || \"\"} ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n\n <div class=\"input-section-title\">\n <span class=\"text-subtitle\">\n ${props.label}\n </span>\n </div>\n\n <div class=\"nav-input-file\" >\n <button class=\"small-close clear-file-input\">x</button>\n <label >\n <span class=\"nav-input-file-label\">\n ${props.pickerLabel || \"Seleccionar Archivo\"}\n </span>\n <input type=\"file\" value=\"${value}\">\n </label>\n </div>\n\n <div class=\"input-section-link\">\n <a href=\"${filePath}\" target=\"_blank\" >\n ${fileName}\n </a>\n </div>\n\n </div>`);\n let $inputElem = elem.querySelector(\"input\");\n let $clearBtn = elem.querySelector(\".clear-file-input\");\n let $fileInputLabel = elem.querySelector(\".nav-input-file-label\");\n $inputElem.addEventListener(\"change\", evt => {\n let fileName = $inputElem.files[0].name;\n $fileInputLabel.textContent = fileName;\n });\n $clearBtn.addEventListener(\"click\", evt => {\n $inputElem.value = \"\";\n $fileInputLabel.textContent = props.pickerLabel || \"Seleccionar Archivo\";\n evt.stopPropagation();\n });\n return elem;\n },\n\n createFileLink(props, dataDay) {\n let fileName = \"\";\n let filePath = \"\";\n\n if (dataDay && dataDay.values) {\n //value = utils.getVarByPath(dataDay, props.varName);\n fileName = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.fileNameValue);\n filePath = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.filePathValue);\n }\n\n if (fileName == \"\") return null;\n fileName = fileName || \"\";\n filePath = filePath || \"\";\n let elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.classNames || \"\"} ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n\n <div class=\"input-section-title\">\n <span class=\"text-subtitle\">\n ${props.label}\n </span>\n </div>\n\n <div class=\"input-section-link\">\n <a href=\"${filePath}\" target=\"_blank\" >\n ${fileName}\n </a>\n </div>\n\n </div>`);\n return elem;\n },\n\n /**\n * Crea lista de Inputs, con array de valores, como elemento Dom\n *\n * @param {Object} props - config para Input\n * @param {Object} dataDay - valores de item y Dia, opcional\n * @param {Object} [daySelected = null] - datos del dia seleccionado\n * @return {Object} Elemento Dom del input creado\n */\n createInputList(props, dataDay, daySelected = null) {\n let inputList = []; //obtiene inputs default, para crearlos, sin valores\n\n if (daySelected && Array.isArray(daySelected.item.values[props.inputList])) {\n inputList = daySelected.item.values[props.inputList].map(inputRow => {\n //limpia inputList inputs\n inputRow.inputs.map(input => {\n input.value = null;\n return input;\n }); //obtiene valores del dia\n\n if (dataDay && dataDay.values) {\n let inputValues = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.valuesPath); //autorrellena\n\n if (inputValues) {\n inputRow.inputs.forEach(input => {\n let values = inputValues.find(v => v.id == inputRow.id);\n input.value = values ? values[input.varName] : null;\n });\n }\n }\n\n return inputRow;\n });\n }\n\n let str = `<div input-key=\"${props.key || \"\"}\" class=\"input-section-list ${props.isHidden ? \"hide\" : \"\"} \">\n <div class=\"input-section-title\">\n <span class=\"text-title\">\n ${props.label}\n </span> \n </div>`;\n inputList.forEach(inputRow => {\n str += `\n <div class=\"input-section ${props.toRight ? \"to-right\" : \"\"}\" >\n <span class=\"text-subtitle\">\n ${inputRow.label}\n </span>`;\n inputRow.inputs.forEach(input => {\n str += ` \n <div class=\"input-section-col\" >\n <span class=\"text-subtitle \">\n ${input.label}\n </span>\n <input type=\"number\"\n input-id=\"${inputRow.id}\"\n input-label=\"${input.label}\"\n class=\"nav-input small\"\n value=\"${input.value}\">\n </div>`;\n });\n str += `\n </div>`;\n });\n str += `</div>`;\n let elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n let inputsElem = elem.querySelectorAll(\"input\");\n inputsElem.forEach(inputElem => this.addKeyDownInputEvents(inputElem, elem, props));\n return elem;\n },\n\n createInputSelect(props, dataDay, daySelected = null) {\n let value = null;\n let options = props.options;\n\n if (dataDay && dataDay.values) {\n let val = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n value = val ? val.value : null;\n }\n\n let str = `<div input-key=\"${props.key || \"\"}\" class=\"${props.isHidden ? \"hide\" : \"\"}\" >\n <div class=\"input-section \" >\n <span class=\"text-subtitle\">\n ${props.label}\n </span>\n\n <select class=\"input-select\">\n\n <option value=\"\" ${value == null ? \"selected\" : \"\"}>\n ${props.noDataLabel || \"-- sin asignar --\"}\n </option>\n\n `;\n options.forEach(option => {\n str += `\n <option value=\"${option.id}\" ${option.id == value ? \"selected\" : \"\"}>\n ${option.label}\n </option>\n `;\n });\n str += `\n\n </select>\n </div>\n\n </div>`;\n let elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n return elem;\n },\n\n /**\n * Crea Input de texto TextArea como elemento Dom\n *\n * @param {Object} props - config para Input\n * @param {Object} dataDay - valores de item y Dia, opcional\n * @return {Object} Elemento Dom del input creado\n */\n createInputTextArea(props, dataDay) {\n let value = \"\";\n\n if (dataDay && dataDay.values) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n }\n\n let elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <span class=\"text-subtitle d-block\">\n ${props.label}\n </span>\n <textarea class=\"\" value=\"${value}\"></textarea>\n </div>`);\n let inputElem = elem.querySelector(\"textarea\");\n this.addKeyDownInputEvents(inputElem, elem, props);\n return elem;\n },\n\n /**\n * Crea Input de Mensaje como elemento Dom\n * utiliza TextArea\n *\n * @param {Object} props - config para Input\n * @param {Object} dataDay - valores de item y Dia, opcional\n * @return {Object} Elemento Dom del input creado\n */\n createInputMessage(props, dataDay) {\n let value = dataDay ? _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName) : null;\n let elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section to-left msj-input-container ${props.isHidden ? \"hide\" : \"\"} \"\n input-key=\"${props.key || \"\"}\">\n <span class=\"text-subtitle d-block\">\n Mensaje\n </span>\n <textarea class=\"msj\">${value || \"\"}</textarea>\n </div>`);\n let inputElem = elem.querySelector(\"textarea\"); //this.addKeyDownInputEvents(inputElem);\n\n return elem;\n },\n\n /**\n * Crea Input de texto como elemento Dom\n *\n * @param {Object} props - config para Input\n * @param {Object} dataDay - valores de item y Dia, opcional\n * @return {Object} Elemento Dom del input creado\n */\n createInputText(props, dataDay) {\n let value = \"\";\n\n if (dataDay && dataDay.values) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n }\n\n let elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <span class=\"text-subtitle d-block\">\n ${props.label}\n </span>\n <input type=\"text\" class=\"nav-input\" value=\"${value}\">\n </div>`);\n let inputElem = elem.querySelector(\"input\");\n this.addKeyDownInputEvents(inputElem, elem, props);\n return elem;\n },\n\n /**\n * Crea Input Numero Flotante, como elemento Dom\n *\n * @param {Object} props - config para Input\n * @param {Object} dataDay - valores de item y Dia, opcional\n * @return {Object} Elemento Dom del input creado\n */\n createInputFloat(props, dataDay) {\n let value = \"\";\n\n if (dataDay && dataDay.values) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n }\n\n let elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <span class=\"text-subtitle d-block\">\n ${props.label}\n </span>\n <input type=\"number\" class=\"nav-input\" value=\"${value}\">\n </div>`);\n let inputElem = elem.querySelector(\"input\");\n this.addKeyDownInputEvents(inputElem, elem, props);\n return elem;\n },\n\n createDataList(props, dataDay, daySelected, selected, tabSelected) {\n let list = [];\n\n if (dataDay && dataDay.values) {\n list = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName) || [];\n }\n\n let searchInput = props.hideSearch ? \"\" : ` <div class=\"search-input-container\">\n <input id=\"\" type=\"text\" name=\"\" class=\"search-input\" placeholder=\"buscar\">\n <button class=\"search-input-clear\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].closeIcon}\n </button>\n </div>`;\n let editBtn = \"\";\n\n if (props.editButton) {\n editBtn = `<button class=\"cap-btn-raised cap-btn-sm edit-btn\" input-key=\"${props.editButton.key}\">\n ${props.editButton.label} \n </button> `;\n }\n\n let str = `\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <div class=\"input-section-title\">\n <span class=\"text-subtitle d-block\">\n ${props.label}\n </span>\n ${editBtn}\t\n </div>\n <div class=\"input-box \" input-key=\"${props.key || \"\"}\">\n ${searchInput}\n </div>\n </div> `;\n let $el = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n let $searchInput = $el.querySelector(\".search-input\");\n let $searchInputClear = $el.querySelector(\".search-input-clear\");\n let $inputBox = $el.querySelector(\".input-box\");\n let $items = list.map((item, j) => {\n let label = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(item, props.varNameLabel) || dataDay.label || \"__\";\n let $elItem = this.createDataListItem({\n label,\n valueText: _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(item, props.varNameValueText) || \"\",\n subText: _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(item, props.varNameSubText) || \"\",\n id: \"list-item-\" + (dataDay.id || j),\n key: \"list-item-\" + (dataDay.id || j),\n tooltip: _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(item, props.varNameTooltip) || label,\n //colorIcon: \"c-red\",\n link: _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(item, props.varNameLink) || null,\n suffix: _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(item, props.varNameSuffix) || \"\" //value: JSON.stringify(utils.getVarByPath(item, props.varNameInput)) || {}\n\n });\n $inputBox.appendChild($elItem);\n });\n\n if ($searchInput) {\n $searchInputClear.addEventListener(\"click\", e => {\n $searchInput.value = \"\";\n $searchInput.dispatchEvent(new Event(\"input\", {\n bubbles: true\n }));\n });\n $searchInput.addEventListener(\"keydown\", e => {\n if (e.key === \"Escape\") {\n $searchInput.value = \"\";\n $searchInput.dispatchEvent(new Event(\"input\", {\n bubbles: true\n }));\n }\n });\n $searchInput.addEventListener(\"input\", e => {\n let $inputs = [];\n $inputs = $el.querySelectorAll(\".mini-input-section\") || [];\n $inputs.forEach($i => {\n let label = $i.getAttribute(\"label\");\n let search = $searchInput.value;\n\n if (label.toLowerCase().includes(search.toLowerCase())) {\n $i.classList.remove(\"hide\");\n } else {\n $i.classList.add(\"hide\");\n }\n });\n });\n }\n\n if (props.editButton.onClick) {\n let button = $el.querySelector(\"button.edit-btn\");\n\n if (button && props.editButton) {\n button.addEventListener(\"click\", e => props.editButton.onClick({\n event: e,\n props,\n dataDay,\n daySelected,\n selected,\n $element: $el,\n tabSelected\n }));\n }\n\n $items.forEach($i => {\n $el.addEventListener(\"click\", e => {\n props.editButton.onClick({\n event: e,\n props,\n dataDay,\n daySelected,\n selected,\n $element: $el,\n tabSelected\n });\n });\n });\n }\n\n return $el;\n },\n\n createDataListItem({\n label = \"\",\n valueText = \"\",\n subText = \"\",\n id = \"\",\n key = \"\",\n tooltip = \"\",\n colorIcon = \"\",\n link = null,\n suffix = null,\n value = \"\"\n }) {\n let tooltipStr = \"\";\n let iconStr = null;\n let linkStr = \"\";\n let str = \"\";\n\n if (tooltip) {\n tooltipStr = `\n <div class=\"mini-input-section--tooltip\">\n ${tooltip}\n </div>`;\n }\n\n if (colorIcon) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(itemFormated.colorIcon)) {\n iconStr = `<div class=\"mini-input-section--icon\" style=\"background:${colorIcon}\"> </div>`;\n } else {\n iconStr = `<div class=\"mini-input-section--icon ${colorIcon}\"> </div>`;\n }\n }\n\n if (link) {\n linkStr = `<a class=\"mini-input-section--link\" target=\"_blank\" href=\"${link}\">${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].linkIcon}</a> `;\n }\n\n str += `\n <div class=\"mini-input-section clickeable ${iconStr ? \"has-icon\" : \"\"} \" \n label=\"${label}\" \n data-id=\"${id}\"\n data-key=\"${key}\"\n data-value=\"${value || \"\"}\"\n >\n <label>\n ${iconStr || \"\"}\n\n <div class=\"mini-input-section--titles\">\n <div class=\"mini-input-section--title truncate\">\n ${label}\n </div>\n <div class=\"mini-input-section--subtitle truncate\">\n ${subText}\n </div>\n </div>\n\n <div class=\"mini-input-section--content\" >\n ${valueText}\n </div>\n <div class=\"mini-input-section--suffix\" >\n ${suffix}\n </div>\n\n ${linkStr}\n\n </label>\n ${tooltipStr}\n </div>`;\n return _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n },\n\n createList(props, dataDay) {\n let tabsContainer = \"\";\n\n if (props.tabs) {\n let tabs = \"\";\n props.tabs.forEach(tab => {\n tabs += `\n <div class=\"input-box-tab\" tab-key=\"${tab.key}\">\n ${tab.name}\n </div>`;\n });\n tabsContainer = `\n <div class=\"input-box-tab-container\">\n ${tabs}\n </div>\n `;\n }\n\n let searchInput = `\n <div class=\"search-input-container\">\n <input id=\"\" type=\"text\" name=\"\" class=\"search-input\" placeholder=\"buscar\">\n <button class=\"search-input-clear\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].closeIcon}\n </button>\n </div>\n `;\n let str = `\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <span class=\"text-subtitle d-block\">\n ${props.label}\n </span>\n\n ${tabsContainer}\n <div class=\"input-box \" input-key=\"${props.key || \"\"}\">\n\n ${searchInput}\n `; //TODO obtener input segun fila\n\n if (props.inputs) {\n props.inputs.forEach(i => {\n if (i.isTitle) {\n let tooltip = \"\";\n let icon = null;\n\n if (i.tooltip) {\n tooltip = `\n <div class=\"mini-input-section--tooltip\">\n ${i.tooltip}\n ${i.suffix ? \"(\" + i.suffix + \")\" : \"\"}\n </div>`;\n }\n\n if (i.colorIcon) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(i.colorIcon)) {\n icon = `<div class=\"mini-input-section--icon\" style=\"background:${i.colorIcon}\"> </div>`;\n } else {\n icon = `<div class=\"mini-input-section--icon ${i.colorIcon}\"> </div>`;\n }\n }\n\n str += `\n <div class=\"mini-input-section is-title ${icon ? \"has-icon\" : \"\"}\" input-tab-key=\"${i.tabKey || \"\"}\" label=\"${i.label}\">\n <label>\n ${icon || \"\"}\n <div class=\"mini-input-section--title truncate\">\n ${i.label}\n </div>\n </label>\n ${tooltip}\n </div>`;\n } else {\n let tooltip = \"\";\n let icon = null;\n let link = \"\";\n\n if (i.tooltip) {\n tooltip = `\n <div class=\"mini-input-section--tooltip\">\n ${i.tooltip}\n </div>`;\n }\n\n if (i.colorIcon) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(i.colorIcon)) {\n icon = `<div class=\"mini-input-section--icon\" style=\"background:${i.colorIcon}\"> </div>`;\n } else {\n icon = `<div class=\"mini-input-section--icon ${i.colorIcon}\"> </div>`;\n }\n }\n\n if (i.link) {\n link = `<a class=\"mini-input-section--link\" target=\"_blank\" href=\"${i.link}\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].linkIcon}\n </a> `;\n }\n\n str += `\n <div class=\"mini-input-section ${icon ? \"has-icon\" : \"\"}\" input-tab-key=\"${i.tabKey || \"\"}\" label=\"${i.label}\">\n <label>\n\n ${icon}\n\n <div class=\"mini-input-section--title truncate\">\n ${i.label}\n </div>\n\n <div class=\"mini-input-section--suffix\" >${i.suffix ? \"(\" + i.suffix + \")\" : \"\"}</div>\n\n ${link}\n\n </label>\n <div class=\"mini-input-section--footer\">\n <span class=\"start\"> start</span>\n <span class=\"end\"> end </span>\n </div>\n ${tooltip}\n </div>`;\n }\n });\n }\n\n str += `\n </div>\n </div> `;\n let $el = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n let $tabs = $el.querySelectorAll(\".input-box-tab[tab-key]\") || [];\n let $searchInput = $el.querySelector(\".search-input\") || null;\n let $searchInputClear = $el.querySelector(\".search-input-clear\") || null;\n $tabs.forEach(t => {\n t.addEventListener(\"click\", e => {\n this.selectInputBoxTab(t, $el);\n $searchInput.value = \"\";\n $searchInput.dispatchEvent(new Event(\"input\", {\n bubbles: true\n }));\n });\n });\n\n if ($searchInputClear) {\n $searchInputClear.addEventListener(\"click\", e => {\n $searchInput.value = \"\";\n $searchInput.dispatchEvent(new Event(\"input\", {\n bubbles: true\n }));\n });\n }\n\n if ($searchInput) {\n $searchInput.addEventListener(\"keydown\", e => {\n if (e.key === \"Escape\") {\n $searchInput.value = \"\";\n $searchInput.dispatchEvent(new Event(\"input\", {\n bubbles: true\n }));\n }\n });\n $searchInput.addEventListener(\"input\", e => {\n let $tabSelected = $el.querySelector(\".input-box-tab[tab-key].active\") || null;\n let $inputs = [];\n\n if ($tabSelected) {\n let tabKey = $tabSelected.getAttribute(\"tab-key\");\n $inputs = $el.querySelectorAll(\".mini-input-section[input-tab-key='\" + tabKey + \"']\") || [];\n } else {\n $inputs = $el.querySelectorAll(\".mini-input-section\") || [];\n }\n\n $inputs.forEach($i => {\n let label = $i.getAttribute(\"label\");\n let search = $searchInput.value;\n\n if (label.toLowerCase().includes(search.toLowerCase())) {\n $i.classList.remove(\"hide\");\n } else {\n $i.classList.add(\"hide\");\n }\n });\n });\n }\n\n this.selectInputBoxTab(_.first($tabs), $el);\n return $el;\n },\n\n /**\n * Crea InputBox, como elemento Dom\n * un InputBox es un contenedor con una lista de inputs\n *\n * @param {Object} props - config para Input\n * @param {Object} dataDay - valores de item y Dia, opcional\n * @return {Object} Elemento Dom del input creado\n */\n createInputBox(props, dataDay) {\n let value = [];\n\n if (dataDay && dataDay.values) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n }\n\n let tabsContainer = \"\";\n\n if (props.tabs) {\n let tabs = \"\";\n props.tabs.forEach(tab => {\n tabs += `\n <div class=\"input-box-tab\" tab-key=\"${tab.key}\">\n ${tab.name}\n </div>`;\n });\n tabsContainer = `\n <div class=\"input-box-tab-container\">\n ${tabs}\n </div>\n `;\n }\n\n let searchInput = `\n <div class=\"search-input-container\">\n <input id=\"\" type=\"text\" name=\"\" class=\"search-input\" placeholder=\"buscar\">\n <button class=\"search-input-clear\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].closeIcon}\n </button>\n </div>\n `;\n let str = `\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <span class=\"text-subtitle d-block\">\n ${props.label}\n </span>\n\n ${tabsContainer}\n\n <div class=\"input-box \" input-key=\"${props.key || \"\"}\">\n\n ${searchInput}\n `;\n\n if (props.inputs) {\n props.inputs.forEach(i => {\n if (i.isTitle) {\n let tooltip = \"\";\n let icon = \"\";\n\n if (i.tooltip) {\n tooltip = `\n <div class=\"mini-input-section--tooltip\">\n ${i.tooltip}\n ${i.suffix ? \"(\" + i.suffix + \")\" : \"\"}\n </div>`;\n }\n\n if (i.colorIcon) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(i.colorIcon)) {\n icon = `<div class=\"mini-input-section--icon\" style=\"background:${i.colorIcon}\"> </div>`;\n } else {\n icon = `<div class=\"mini-input-section--icon ${i.colorIcon}\"> </div>`;\n }\n }\n\n str += `\n <div class=\"mini-input-section is-title\" input-tab-key=\"${i.tabKey || \"\"}\" label=\"${i.label}\">\n <label>\n ${icon}\n <div class=\"mini-input-section--title truncate\">\n ${i.label}\n </div>\n </label>\n ${tooltip}\n </div>`;\n } else {\n let value_found = value ? value.find(val => val.id == i.id) : null;\n let v = value_found || \"\";\n let inputValue = props.varNameInput && v[props.varNameInput] ? v[props.varNameInput] : v.value;\n let tooltip = \"\";\n let icon = \"\";\n let link = \"\";\n\n if (i.tooltip) {\n tooltip = `\n <div class=\"mini-input-section--tooltip\">\n ${i.tooltip}\n </div>`;\n }\n\n if (i.colorIcon) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(i.colorIcon)) {\n icon = `<div class=\"mini-input-section--icon\" style=\"background:${i.colorIcon}\"> </div>`;\n } else {\n icon = `<div class=\"mini-input-section--icon ${i.colorIcon}\"> </div>`;\n }\n }\n\n if (i.link) {\n link = `<a class=\"mini-input-section--link\" target=\"_blank\" href=\"${i.link}\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].linkIcon}\n </a> `;\n }\n\n str += `\n <div class=\"mini-input-section ${icon ? \"has-icon\" : \"\"}\" input-tab-key=\"${i.tabKey || \"\"}\" label=\"${i.label}\">\n <label>\n <input type=\"number\"\n class=\"mini-input\"\n input-id=\"${i.id || \"\"}\"\n input-key=\"${i.key || i.label}\"\n value=\"${inputValue || \"\"}\">\n\n ${icon || \"\"}\n\n <div class=\"mini-input-section--title truncate\">\n ${i.label}\n </div>\n\n <div class=\"mini-input-section--suffix\" >${i.suffix ? \"(\" + i.suffix + \")\" : \"\"}</div>\n\n ${link}\n\n </label>\n ${tooltip}\n </div>`;\n }\n });\n }\n\n str += `\n </div>\n </div> `;\n let $el = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n let $tabs = $el.querySelectorAll(\".input-box-tab[tab-key]\") || [];\n let $inputs = $el.querySelectorAll(\"input.mini-input\") || [];\n let $searchInput = $el.querySelector(\".search-input\") || null;\n let $searchInputClear = $el.querySelector(\".search-input-clear\") || null;\n $tabs.forEach(t => {\n t.addEventListener(\"click\", e => {\n this.selectInputBoxTab(t, $el);\n $searchInput.value = \"\";\n $searchInput.dispatchEvent(new Event(\"input\", {\n bubbles: true\n }));\n });\n });\n\n if ($searchInputClear) {\n $searchInputClear.addEventListener(\"click\", e => {\n $searchInput.value = \"\";\n $searchInput.dispatchEvent(new Event(\"input\", {\n bubbles: true\n }));\n });\n }\n\n if ($searchInput) {\n $searchInput.addEventListener(\"keydown\", e => {\n if (e.key === \"Escape\") {\n $searchInput.value = \"\";\n $searchInput.dispatchEvent(new Event(\"input\", {\n bubbles: true\n }));\n }\n });\n $searchInput.addEventListener(\"input\", e => {\n let $tabSelected = $el.querySelector(\".input-box-tab[tab-key].active\") || null;\n let $inputs = [];\n\n if ($tabSelected) {\n let tabKey = $tabSelected.getAttribute(\"tab-key\");\n $inputs = $el.querySelectorAll(\".mini-input-section[input-tab-key='\" + tabKey + \"']\") || [];\n } else {\n $inputs = $el.querySelectorAll(\".mini-input-section\") || [];\n }\n\n $inputs.forEach($i => {\n let label = $i.getAttribute(\"label\");\n let search = $searchInput.value;\n\n if (label.toLowerCase().includes(search.toLowerCase())) {\n $i.classList.remove(\"hide\");\n } else {\n $i.classList.add(\"hide\");\n }\n });\n });\n }\n\n this.selectInputBoxTab(_.first($tabs), $el);\n $inputs.forEach(i => this.addKeyDownInputEvents(i, $el, props));\n return $el;\n },\n\n selectInputBoxTab($tab, $el) {\n let $tabs = $el.querySelectorAll(\".input-box-tab[tab-key]\") || [];\n let $inputSections = $el.querySelectorAll(\".mini-input-section\") || [];\n $tabs.forEach(t => {\n t.classList.remove(\"active\");\n });\n\n if ($tab) {\n $tab.classList.add(\"active\");\n $inputSections.forEach(i => {\n let key = i.getAttribute(\"input-tab-key\");\n\n if (key == $tab.getAttribute(\"tab-key\")) {\n i.classList.remove(\"hide\");\n } else {\n i.classList.add(\"hide\");\n }\n });\n }\n },\n\n /**\n * Crea Checkbox, como elemento Dom\n *\n * @param {Object} props - config para Input\n * @param {Object} dataDay - valores de item y Dia, opcional\n * @return {Object} Elemento Dom del input creado\n */\n createInputCheckbox(props, dataDay) {\n let value = \"\";\n\n if (dataDay && dataDay.values) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n }\n\n let r = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <label>\n <input type=\"checkbox\" name=\"${props.key || \"\"}\" input-key=\"${props.key || \"\"}\" ${value ? \"checked\" : \"\"}>\n ${props.label}\n </label>\n </div>`);\n return r;\n },\n\n createInputButtonsGroup(props) {\n let $container = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <div class=\"buttons-group\"> </div>\n </div>`);\n let $containerButtonGroup = $container.querySelector(\".buttons-group\");\n let $buttons = [];\n $buttons = props.buttons.map(buttonProp => {\n let buttonStr = `\n <button \n name=\"${buttonProp.key || \"\"}\" \n input-key=\"${buttonProp.key || \"\"}\"\n class=\"cap-btn-outline cap-btn-sm ${buttonProp.isSelected ? \"selected\" : \"\"} \">\n ${buttonProp.label}\n </button>`;\n let $button = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(buttonStr);\n $containerButtonGroup.append($button);\n $button.addEventListener(\"click\", e => {\n if (props.isSelectable) {\n $buttons.forEach($b => $b.classList.remove(\"selected\"));\n $button.classList.add(\"selected\");\n }\n\n buttonProp.onClick({\n props,\n event: e,\n buttonsElements: $buttons\n });\n });\n return $button;\n });\n return $container;\n },\n\n createInputButton(props, dataDay) {\n let r = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <button \n name=\"${props.key || \"\"}\"\n input-key=\"${props.key || \"\"}\"\n class=\"cap-btn-outline\">\n ${props.label}\n </button>\n </div>`);\n let button = r.querySelector(\"button\");\n button.addEventListener(\"click\", e => props.onClick({\n props,\n event: e,\n dataDay\n }));\n return r;\n },\n\n addKeyDownInputEvents($input, $inputContainer, props) {\n $input.addEventListener(\"keydown\", function (event) {\n if (event.keyCode === 13) {\n //ENTER\n $input.dispatchEvent(new CustomEvent(\"saveMultiInput\", {\n bubbles: true,\n cancelable: false\n }));\n }\n\n if (event.keyCode === 27) {\n //ESC\n $input.dispatchEvent(new CustomEvent(\"cancelMultiInput\", {\n bubbles: true,\n cancelable: false\n }));\n }\n });\n $input.addEventListener(\"input\", e => {\n if (props.onInput) {\n props.onInput({\n event: e,\n value: e.srcElement.value,\n props,\n $element: $inputContainer\n });\n }\n });\n },\n\n createContextMenu({\n config,\n target,\n $capibaraElem = null,\n evt = null,\n date = null,\n item = null,\n selected = [],\n tabSelected = null,\n left = null,\n top = null,\n name = \"\"\n }) {\n if (config.timeline.contextMenu === undefined || config.timeline.contextMenu.options == undefined) return {\n elem: null,\n isVisible: false\n };\n let className = \"\";\n let style = \"\";\n let strHtml = \"\";\n let leftPosition = null;\n let topPosition = null;\n let isVisible = true;\n let boundRectCapibara = null;\n let gap = 15; //px\n\n if ($capibaraElem) {\n boundRectCapibara = $capibaraElem.getBoundingClientRect();\n }\n\n if (evt && boundRectCapibara) {\n left = evt.clientX;\n top = evt.clientY - boundRectCapibara.top;\n }\n\n if (left) {\n leftPosition = left;\n }\n\n if (top) {\n topPosition = top;\n }\n\n if (leftPosition !== null & topPosition !== null) {\n if (boundRectCapibara) {\n let transformStyle = \"\";\n\n if (topPosition > boundRectCapibara.height * 2 / 6 && topPosition <= boundRectCapibara.height * 4 / 6) {\n transformStyle += `translateY(-50%)`;\n }\n\n if (topPosition > boundRectCapibara.height * 4 / 6) {\n transformStyle += `translateY(-100%)`;\n }\n\n if (leftPosition > boundRectCapibara.width * 4 / 6) {\n transformStyle += `translateX(-100%)`;\n leftPosition -= gap;\n } else {\n leftPosition += gap;\n }\n\n if (transformStyle != \"\") {\n style += ` transform: ${transformStyle};`;\n }\n }\n\n style += `top: ${topPosition}px; left: ${leftPosition}px;`;\n } else {\n className += \"cm-hide\";\n isVisible = false;\n }\n\n strHtml += ` <div class=\"cap-context-menu-container ${className}\">\n <div class=\"cap-context-menu\" style=\"${style}\">\n </div>\n </div>`;\n let $contextMenuContainer = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(strHtml);\n let $contextMenu = $contextMenuContainer.querySelector(\".cap-context-menu\");\n let hasSomeoption = false;\n config.timeline.contextMenu.options.forEach(option => {\n if (option.showIf) {\n let show = option.showIf({\n item,\n date,\n selected,\n name,\n tabSelected\n });\n if (!show) return;\n }\n\n let isEnabled = true;\n let isClickeable = true;\n\n if (option.enableIf) {\n isEnabled = option.enableIf({\n item,\n date,\n selected,\n name,\n tabSelected\n });\n }\n\n let optionClassName = \"\";\n let strIcon = \"\";\n let label = \"\";\n\n if (!isEnabled) {\n optionClassName += \"is-disabled \";\n }\n\n if (option.isDivider) {\n isClickeable = false;\n optionClassName += \"is-divider \";\n }\n\n if (option.label) {\n label = `<span>${option.label}</span>`;\n }\n\n if (option.icon) {\n strIcon = `<div class=\"cap-context-menu_item_icon\">\n <svg viewBox=\"0 0 24 24\">\n <path d=\"${option.icon}\" />\n </svg>\n </div>`;\n }\n\n let optionStrHtml = `\n <div class=\"cap-context-menu_item ${optionClassName}\">\n ${strIcon}\n ${label}\n </div>`;\n let $option = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(optionStrHtml);\n\n if (isEnabled && isClickeable) {\n $option.addEventListener(\"click\", evtClick => option.onClick({\n config,\n evt: evtClick,\n date,\n item,\n selected,\n tabSelected,\n target\n }));\n } else {\n $option.addEventListener(\"click\", evtClick => {\n evtClick.preventDefault();\n evtClick.stopPropagation();\n });\n }\n\n $contextMenu.append($option);\n hasSomeoption = true;\n });\n return {\n elem: $contextMenuContainer,\n isVisible\n };\n }\n\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvdXRpbC90YWJsZUVsZW1lbnRzLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vQ2FwaWJhcmEvLi9zcmMvdXRpbC90YWJsZUVsZW1lbnRzLmpzPzFkODYiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGRvbSBmcm9tIFwiLi4vdXRpbC9kb21VdGlsc1wiO1xuaW1wb3J0IHV0aWxzIGZyb20gXCIuLi91dGlsL3V0aWxzXCI7XG5pbXBvcnQgZGF0ZVV0aWxzIGZyb20gXCIuLi91dGlsL2RhdGVVdGlsc1wiO1xuaW1wb3J0IGljb25zIGZyb20gXCIuLi91dGlsL2ljb25zXCI7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIENyZWEgZWxlbWVudG8gVGFibGVcbiAgICogQ29udGVuZHLDoSBsb3MgZWxlbWVudG9zIHF1ZSBhcGFyZWNlcmFuIGRlbnRybyBkZSBsYSB0YWJsYSBkZSBwbGFuaWxsYVxuICAgKiBTZSBVc2EgcGFyYSA6XG4gICAqICAgIC0gQWdyZWdhciBiYWNrZ3JvdW5kIGNvbiBwYXRyb24gZXN0aWxvIHRhYmxhXG4gICAqICAgIC0gQWdyZWdhciBkYXlNb3VzZU92ZXIsIGRpdiBxdWUgaW5kaWNhIHBvc2ljaW9uIGRlIG1vdXNlXG4gICAqICAgIC0gQWdyZWdhciBEZXRhaWxEYXksIHBhcmEgZGV0YWxsZXMgZGUgZGF0b3MgZW4gdGFibGFcbiAgICogICAgLSBBZ3JlZ2FyIFNlbGVjdGVkQ29udGFpbmVyLCBwYXJhIGRpYXMgc2VsZWNjaW9uYWRvc1xuICAgKiAgICAtIEFncmVnYXIgRmxvYXRCb3hDb250YWluZXIsIHBhcmEgdmlzdWFsaXphY2lvbiBkZSBkYXRvcyBlbiB0YWJsYVxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gQ29uZmlndXJhY2lvbiBjYXBpYmFyYVxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBjcmVhZG9cbiAgICovXG4gIGNyZWF0ZUFnVGFibGUoY29uZmlnKSB7XG4gICAgbGV0IGUgPSBkb20uY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJjYXBpYmFyYVwiIH0pO1xuICAgIGlmIChjb25maWcudGltZWxpbmUuZGFyaykge1xuICAgICAgZS5jbGFzc0xpc3QuYWRkKFwiZGFyay10aGVtZVwiKTtcbiAgICB9XG4gICAgaWYgKGNvbmZpZy50aW1lbGluZS5oZWFkZXIuZXh0ZW5kLmlzU2hvdykge1xuICAgICAgZS5jbGFzc0xpc3QuYWRkKFwiaGVhZGVyLWV4dGVuZGVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4gZTtcbiAgfSxcblxuICAvKipcbiAgICogUmVjcmVhIEJhY2tncm91bmQsIHF1ZSBlcyBlbCBmb25kbyBncmlkLCBjb21vIHRhYmxhXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgLSBDb25maWd1cmFjaW9uIGNhcGliYXJhXG4gICAqIEBwYXJhbSB7T2JqZWN0fSAkZWxlbSAtIEVsZW1lbnRvIHJlbGFjaW9uYWRvLCBkb25kZSBzZSBjcmUgZWwgYmFja2dyb3VuZFxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBDb3JuZXIgRm9vdGVyXG4gICAqL1xuICByZWRyYXdCYWNrZ3JvdW5kKGNvbmZpZywgJGVsZW0pIHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVCYWNrZ3JvdW5kKGNvbmZpZywgJGVsZW0pO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhIHkgcG9zaWNpb25hIGZvbmRvIGRlIHRhYmxhXG4gICAqIEVzdGUgZm9uZG8gY29udGllbmUgdW4gcGF0cm9uIGRlIENTUyBxdWUgbGUgZGEgbGEgYXBhcmllbmNpYSBkZSB0YWJsYVxuICAgKiBwb3IgbG8gY3VhbCBzZSBkZWJlIHJlcG9zaWNpb25hciBzZWd1biBsYSBmZWNoYSBkZSBpbmljaW8sIHBhcmEgaGFjZXJcbiAgICogY2FsemFyIGxvcyBmaW5lcyBkZSBzZW1hbmFcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHBhcmFtIHtPYmplY3R9IFskZWxlbSA9IG51bGxdIC0gRWxlbWVudG8gYmFja2dyb3VuZCwgc2kgZXMgbnVsbCwgbG8gY3JlYVxuICAgKiBAcmV0dXJuIHtPYmplY3R9IGVsZW1lbnRvIERvbSBCYWNrZ3JvdW5kXG4gICAqL1xuICBjcmVhdGVCYWNrZ3JvdW5kKGNvbmZpZywgJGVsZW0gPSBudWxsKSB7XG4gICAgbGV0IHsgaGVpZ2h0LCB3aWR0aCwgZGF5V2lkdGggfSA9IHV0aWxzLmdldFRhYmxlRGltZW5zaW9ucyhjb25maWcpO1xuXG4gICAgbGV0IHN0YXJ0ID0gbmV3IERhdGUoY29uZmlnLnRpbWVsaW5lLnN0YXJ0KTtcbiAgICBsZXQgZW5kID0gbmV3IERhdGUoY29uZmlnLnRpbWVsaW5lLmVuZCk7XG5cbiAgICBlbmQuc2V0VGltZShlbmQuZ2V0VGltZSgpICsgZGF0ZVV0aWxzLmRheUluTWlsbGlzZWNvbmRzKTsgLy8gYWRkIDI0IGhvdXJzXG5cbiAgICBsZXQgZENvcnJlY3RlZCA9IG5ldyBEYXRlKFxuICAgICAgc3RhcnQudmFsdWVPZigpICsgc3RhcnQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwMDAwXG4gICAgKTtcbiAgICBsZXQgd2Vla0RheSA9IGRDb3JyZWN0ZWQuZ2V0RGF5KCk7XG4gICAgbGV0IGRpZmZXZWVrRGF5cyA9ICh3ZWVrRGF5IC0gMSkgKiBkYXlXaWR0aCAqIC0xO1xuXG4gICAgJGVsZW0gPSAkZWxlbSB8fCBkb20uY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJiYWNrZ3JvdW5kLWdyaWRcIiB9KTtcbiAgICAkZWxlbS5zdHlsZVtcImJhY2tncm91bmQtcG9zaXRpb25cIl0gPVxuICAgICAgZGlmZldlZWtEYXlzICsgXCJweCAwLCAwIDAsIFwiICsgZGlmZldlZWtEYXlzICsgXCJweCAwXCI7XG4gICAgJGVsZW0uc3R5bGUud2lkdGggPSB3aWR0aCArIFwicHhcIjtcbiAgICAkZWxlbS5zdHlsZS5oZWlnaHQgPSBoZWlnaHQgKyAxICsgXCJweFwiO1xuICAgIHJldHVybiAkZWxlbTtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBQbG90IENvbnRhaW5lciBWZXJ0aWNhbFxuICAgKiBMb3MgcGxvdHMgc29uIGVsZW1lbnRvcyBxdWUgYWdyZWdhbiBzZWNjaW9uZXMgZGUgZm9uZG8gZW4gbGEgcGxhbmlsbGFcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gcGxvdFZlcnRpY2FsQ29udGFpbmVyXG4gICAqL1xuICBjcmVhdGVQbG90VmVydGljYWxDb250YWluZXIoY29uZmlnKSB7XG4gICAgbGV0ICRlbGVtID0gZG9tLmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgICAgY2xhc3NOYW1lOiBcInBsb3QtdmVydGljYWwtY29udGFpbmVyXCIsXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMucmVkcmF3UGxvdFZlcnRpY2FsQ29udGFpbmVyKGNvbmZpZywgJGVsZW0pO1xuICB9LFxuXG4gIGNyZWF0ZVBsb3RIb3Jpem9udGFsQ29udGFpbmVyKGNvbmZpZykge1xuICAgIGxldCAkZWxlbSA9IGRvbS5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICAgIGNsYXNzTmFtZTogXCJwbG90LWhvcml6b250YWwtY29udGFpbmVyXCIsXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMucmVkcmF3UGxvdEhvcml6b250YWxDb250YWluZXIoY29uZmlnLCAkZWxlbSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJlY3JlYSBwbG90VmVydGljYWxDb250YWluZXIsIHVzYW5kbyBlbGVtZW50byBleGlzdGVudGVcbiAgICogdXNhIHVuIGVsZW1lbnRvIGV4aXN0ZW50ZSBwYXJhIHVzYXIgbGEgZnVuY2lvbiBwYXJhIHJlZGlidWphciBlbCBlbGVtZW50b1xuICAgKlxuICAgKiBMb3MgUGxvdHMgc2UgaW5zZXJ0YW4gY29tbyBkaXZzLCBjb24gcG9zaWNpb24gZXNwZWNpZmljYWRhLFxuICAgKiBjb24gYW5jaG8gZGUgZGlhXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgLSBDb25maWd1cmFjaW9uIGNhcGliYXJhXG4gICAqIEBwYXJhbSB7T2JqZWN0fSAkZWxlbSAtIEVsZW1lbnRvIERvbSBkb25kZSBjcmVhIHBsb3RWZXJ0aWNhbENvbnRhaW5lclxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBwbG90VmVydGljYWxDb250YWluZXJcbiAgICovXG4gIHJlZHJhd1Bsb3RWZXJ0aWNhbENvbnRhaW5lcihjb25maWcsICRlbGVtKSB7XG4gICAgJGVsZW0uaW5uZXJIVE1MID0gXCJcIjtcbiAgICBpZiAoY29uZmlnLnRpbWVsaW5lLnBsb3RzICYmIGNvbmZpZy50aW1lbGluZS5wbG90cy52ZXJ0aWNhbCkge1xuICAgICAgbGV0IHsgaGVpZ2h0LCBkYXlXaWR0aCB9ID0gdXRpbHMuZ2V0VGFibGVEaW1lbnNpb25zKGNvbmZpZyk7XG5cbiAgICAgIGNvbmZpZy50aW1lbGluZS5wbG90cy52ZXJ0aWNhbC5mb3JFYWNoKChwKSA9PiB7XG4gICAgICAgIGxldCBkaWZmRGF5cyA9IE1hdGguZmxvb3IoXG4gICAgICAgICAgZGF0ZVV0aWxzLmRpZmZEYXlzKGNvbmZpZy50aW1lbGluZS5zdGFydCwgcC5kYXRlKVxuICAgICAgICApO1xuICAgICAgICBsZXQgbGVmdCA9IGRpZmZEYXlzICogZGF5V2lkdGg7XG4gICAgICAgIGxldCBwbG90ID0gZG9tLmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgICAgICAgIGNsYXNzTmFtZXM6IFtcInBsb3QtdmVydGljYWxcIiwgcC5jbGFzc05hbWUgfHwgXCJcIl0sXG4gICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgIFwibWFyZ2luLWxlZnRcIjogbGVmdCArIFwicHhcIixcbiAgICAgICAgICAgIGhlaWdodDogaGVpZ2h0ICsgXCJweFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICAkZWxlbS5hcHBlbmRDaGlsZChwbG90KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gJGVsZW07XG4gIH0sXG5cbiAgcmVkcmF3UGxvdEhvcml6b250YWxDb250YWluZXIoY29uZmlnLCAkZWxlbSkge1xuICAgICRlbGVtLmlubmVySFRNTCA9IFwiXCI7XG4gICAgaWYgKGNvbmZpZy50aW1lbGluZS5wbG90cyAmJiBjb25maWcudGltZWxpbmUucGxvdHMuaG9yaXpvbnRhbCkge1xuICAgICAgbGV0IHsgd2lkdGgsIGl0ZW1IZWlnaHQgfSA9IHV0aWxzLmdldFRhYmxlRGltZW5zaW9ucyhjb25maWcpO1xuICAgICAgY29uZmlnLnRpbWVsaW5lLnBsb3RzLmhvcml6b250YWwuZm9yRWFjaCgocCkgPT4ge1xuICAgICAgICBsZXQgaXRlbSA9IHV0aWxzLmdldEl0ZW1CeUlkKGNvbmZpZywgcC5pZE5vZGUsIHAudHlwZU5vZGUpO1xuICAgICAgICBsZXQgdG9wUG9zaXRpb24gPSB1dGlscy5nZXRQb3NpdGlvbkJ5SXRlbShjb25maWcsIGl0ZW0sIFwicGFyZW50XCIpO1xuICAgICAgICBsZXQgcGxvdCA9IGRvbS5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICAgICAgICBjbGFzc05hbWVzOiBbXCJwbG90LWhvcml6b250YWxcIiwgcC5jbGFzc05hbWUgfHwgXCJcIl0sXG4gICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgIFwibWFyZ2luLXRvcFwiOiB0b3BQb3NpdGlvbiAqIGl0ZW1IZWlnaHQgKyBcInB4XCIsXG4gICAgICAgICAgICB3aWR0aDogd2lkdGggKyBcInB4XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgICRlbGVtLmFwcGVuZENoaWxkKHBsb3QpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiAkZWxlbTtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBDb3JuZXIgSXpxdWllcmRvXG4gICAqIFNlIHVzYSBwYXJhIDpcbiAgICogICAgLSB0aXR1bG9zIHJlbGFjaW9uYWRvcyBjb24gbG9zIGRhdG9zIGRlbCBzaWRlYmFyIGl6cXVpZXJkb1xuICAgKiAgICAtIHRpdHVsb3MgcGFyYSBpbnB1dHMgZGUgaGVhZGVyLCBhYnNvbHV0ZSBhIGxhIGRlcmVjaGFcbiAgICogICAgLSBib3RvbiBwYXJhIG1vc3RyYXIvb2N1bHRhciBzaWRlYmFyIGl6cXVpZXJkb1xuICAgKiAgICAtIHByb21lZGlvc1xuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gQ29uZmlndXJhY2lvbiBjYXBpYmFyYVxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBDb3JuZXJcbiAgICovXG4gIGNyZWF0ZUNvcm5lcihjb25maWcsIHRhYiA9IG51bGwpIHtcbiAgICBsZXQgJGVsZW0gPSBkb20uY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJjb3JuZXJcIiB9KTtcbiAgICByZXR1cm4gdGhpcy5yZWRyYXdDb3JuZXIoJGVsZW0sIGNvbmZpZywgdGFiKTtcbiAgfSxcblxuICByZWRyYXdDb3JuZXIoJGVsZW0sIGNvbmZpZywgdGFiID0gbnVsbCkge1xuICAgIGxldCBsYWJlbHNJbml0aWFsQ29ybmVyID0gY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmluaXRpYWwudmFyc1xuICAgICAgLmZpbHRlcihcbiAgICAgICAgKHYpID0+XG4gICAgICAgICAgdi5vbmx5VGFiID09IHVuZGVmaW5lZCB8fCAodi5vbmx5VGFiICYmIHRhYiAmJiB2Lm9ubHlUYWIgPT0gdGFiLmtleSlcbiAgICAgIClcbiAgICAgIC5tYXAoKGQpID0+IGA8c3BhbiBjbGFzcz1cIml0ZW0tY29sXCI+JHtkLmxhYmVsfTwvc3Bhbj5gKVxuICAgICAgLmpvaW4oXCJcIik7XG5cbiAgICBsZXQgbGFiZWxzRXh0ZW5kQ29ybmVyID0gY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmV4dGVuZC52YXJzXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAodikgPT5cbiAgICAgICAgICB2Lm9ubHlUYWIgPT0gdW5kZWZpbmVkIHx8ICh2Lm9ubHlUYWIgJiYgdGFiICYmIHYub25seVRhYiA9PSB0YWIua2V5KVxuICAgICAgKVxuICAgICAgLm1hcCgoZCkgPT4gYDxzcGFuIGNsYXNzPVwiaXRlbS1jb2xcIj4ke2QubGFiZWx9PC9zcGFuPmApXG4gICAgICAuam9pbihcIlwiKTtcblxuICAgIGxldCBsYWJlbHNIZWFkZXJFeHRlbmQgPSBjb25maWcudGltZWxpbmUuaGVhZGVyLmV4dGVuZC5kYXRhXG4gICAgICAubWFwKChkKSA9PiB7XG4gICAgICAgIGlmIChkLmlzSGlkZGVuKSByZXR1cm4gXCJcIjtcblxuICAgICAgICBsZXQgYXZnID0gXCJcIjtcbiAgICAgICAgbGV0IHRvb2x0aXAgPSBcIlwiO1xuICAgICAgICBsZXQgY2xhc3NOYW1lID0gXCJcIjtcbiAgICAgICAgbGV0IGlzQWNjZW50ID0gZC5pc0FjY2VudDtcblxuICAgICAgICBpZiAoZC5hdmVyYWdlKSB7XG4gICAgICAgICAgYXZnID0gYCA8c3BhbiBjbGFzcz1cImF2ZXJhZ2UgXCI+ICggPHNwYW4+IDxzcGFuIGNsYXNzPVwic3ltYm9sXCI+eMyEPC9zcGFuPiAke2QuYXZlcmFnZX0gPC9zcGFuPikgIDwvc3Bhbj4gICBgO1xuXG4gICAgICAgICAgdG9vbHRpcCA9IGBjYXAtdG9vbHRpcD1cIlByb21lZGlvICR7ZC5sYWJlbH0gOiAke2QuYXZlcmFnZX0gJHtcbiAgICAgICAgICAgIGQuc3VmZml4IHx8IFwiXCJcbiAgICAgICAgICB9XCJgO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGQuY29sb3IpIHtcbiAgICAgICAgICBpZiAoaXNBY2NlbnQpIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZSA9IGQuY29sb3IgPyBcImMtXCIgKyBkLmNvbG9yICsgXCItLWJhY2tncm91bmRcIiA6IFwiXCI7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZSA9IGQuY29sb3IgPyBcImMtXCIgKyBkLmNvbG9yICsgXCItLXRleHQgXCIgOiBcIlwiO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBgPGRpdiBjbGFzcz1cImlucHV0LXRpdGxlLWNvbnRhaW5lciAke1xuICAgICAgICAgIGlzQWNjZW50ID8gXCJpbnB1dC10aXRsZS0tYWNjZW50XCIgOiBcIlwiXG4gICAgICAgIH0gJHtkLmlzUGVyc2lzdGVudCA/IFwicGVyc2lzdGVudFwiIDogXCJcIn1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAke3Rvb2x0aXB9IGNsYXNzPVwiaW5wdXQtdGl0bGUgJHtjbGFzc05hbWV9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2F2Z31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7ZC5sYWJlbH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgIH0pXG4gICAgICAuam9pbihcIlwiKTtcblxuICAgIGxldCB0b2dnbGVTaWRlYmFyQnRuU3RyaW5nID0gYFxuICAgICAgICAgIDxidXR0b24gdG9nZ2xlLXNpZGViYXIgY2xhc3M9XCJjYXAtYnRuLWljb24gY2FwLWJ0bi1pY29uLXJhaXNlZCBjYXAtYnRuLXRvZ2dsZS1zaWRlYmFyIFwiPlxuICAgICAgICAgICR7aWNvbnMuY2hldnJvblJpZ2h0fVxuICAgICAgICAgIDwvYnV0dG9uPiBgO1xuXG4gICAgaWYgKGNvbmZpZy50aW1lbGluZS5uYXYubGVmdC5oaWRlVG9nZ2xlU2lkZWJhckJ1dHRvbikge1xuICAgICAgdG9nZ2xlU2lkZWJhckJ0blN0cmluZyA9IFwiXCI7XG4gICAgfVxuXG4gICAgbGV0IHRlbXBsYXRlID0gYDxkaXY+XG5cbiAgICAgICAgICAke3RvZ2dsZVNpZGViYXJCdG5TdHJpbmd9XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb3JuZXItdGl0bGVcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImJvdHRvbS10ZXh0XCI+XG4gICAgICAgICAgICAke2NvbmZpZy50aW1lbGluZS5jb3JuZXIubGVmdC5sYWJlbH1cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJpbml0aWFsLWNvcm5lclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbml0aWFsLWNvcm5lci10aXRsZVwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJib3R0b20tY29udGFpbmVyIGhpZGVcIj5cbiAgICAgICAgICAgICAgJHtjb25maWcudGltZWxpbmUuY29ybmVyLmluaXRpYWwubGFiZWx9XG4gICAgICAgICAgICA8L3NwYW4+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJib3R0b20tY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICR7bGFiZWxzSW5pdGlhbENvcm5lcn1cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImV4dGVuZC1jb3JuZXJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZXgtY29ybmVyLXRpdGxlXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJvdHRvbS1jb250YWluZXIgaGlkZVwiPlxuICAgICAgICAgICAgICAke2NvbmZpZy50aW1lbGluZS5jb3JuZXIuZXh0ZW5kLmxhYmVsfVxuICAgICAgICAgICAgPC9zcGFuPlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYm90dG9tLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAke2xhYmVsc0V4dGVuZENvcm5lcn1cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNhcC1idG4tbmF2LWNvcm5lclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC10aXRsZXNcIj5cbiAgICAgICAgICAgICAgJHtsYWJlbHNIZWFkZXJFeHRlbmR9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJwcm9ncmVzcy1iYXIgcHJvZ3Jlc3MtYmFyLWxlZnQgaGlkZS1wcm9ncmVzc1wiPjwvZGl2PlxuXG4gICAgICA8L2Rpdj5gO1xuXG4gICAgbGV0IHIgPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKHRlbXBsYXRlKTtcblxuICAgICRlbGVtLmlubmVySFRNTCA9IFwiXCI7XG4gICAgJGVsZW0uYXBwZW5kKHIpO1xuXG4gICAgbGV0IHRvZ2dsZVNpZGViYXIgPSAkZWxlbS5xdWVyeVNlbGVjdG9yKFwiW3RvZ2dsZS1zaWRlYmFyXVwiKTtcbiAgICBpZiAodG9nZ2xlU2lkZWJhcikge1xuICAgICAgdG9nZ2xlU2lkZWJhci5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgci5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgIG5ldyBDdXN0b21FdmVudChcInRvZ2dsZVNpZGViYXJcIiwge1xuICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgIGNhbmNlbGFibGU6IGZhbHNlLFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gJGVsZW07XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgQ29ybmVyIERlcmVjaG9cbiAgICogU2UgdXNhIHBhcmEgOlxuICAgKiAgICAtIHRpdHVsb3MgcmVsYWNpb25hZG9zIGNvbiBsb3MgZGF0b3MgZGVsIHNpZGViYXIgRGVyZWNob1xuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gQ29uZmlndXJhY2lvbiBjYXBpYmFyYVxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBjb3JuZXJcbiAgICovXG4gIGNyZWF0ZUNvcm5lclJpZ2h0KGNvbmZpZywgdGFiID0gbnVsbCkge1xuICAgIGxldCAkZWxlbSA9IGRvbS5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsgY2xhc3NOYW1lczogW1wiY29ybmVyXCIsIFwicmlnaHRcIl0gfSk7XG4gICAgcmV0dXJuIHRoaXMucmVkcmF3Q29ybmVyUmlnaHQoJGVsZW0sIGNvbmZpZywgdGFiKTtcbiAgfSxcblxuICByZWRyYXdDb3JuZXJSaWdodCgkZWwsIGNvbmZpZywgdGFiID0gbnVsbCkge1xuICAgIGxldCBsYWJlbCA9IFwiXCI7XG5cbiAgICBpZiAoY29uZmlnLnRpbWVsaW5lLmNvcm5lci5yaWdodC5sYWJlbCkge1xuICAgICAgYCA8c3Bhbj5cbiAgICAgICAgICAgICR7Y29uZmlnLnRpbWVsaW5lLmNvcm5lci5yaWdodC5sYWJlbH1cbiAgICAgICAgICA8L3NwYW4+YDtcbiAgICB9XG5cbiAgICBsZXQgc3RyID0gYFxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29ybmVyLXRpdGxlXCI+XG4gICAgICAgICR7bGFiZWx9XG4gICAgICAgIDxkaXYgY2xhc3M9XCJidG4tY29udGFpbmVyXCI+PC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwicHJvZ3Jlc3MtYmFyIHByb2dyZXNzLWJhci1yaWdodCBoaWRlLXByb2dyZXNzXCI+PC9kaXY+XG4gICAgYDtcbiAgICAkZWwuaW5uZXJIVE1MID0gc3RyLnRyaW0oKTtcbiAgICBsZXQgJGJ0bkNvbnRhaW5lciA9ICRlbC5xdWVyeVNlbGVjdG9yKFwiLmJ0bi1jb250YWluZXJcIik7XG5cbiAgICBpZiAoY29uZmlnLnRpbWVsaW5lLmNvcm5lci5yaWdodC5idXR0b25zKSB7XG4gICAgICBjb25maWcudGltZWxpbmUuY29ybmVyLnJpZ2h0LmJ1dHRvbnMuZm9yRWFjaCgoYnRuKSA9PiB7XG4gICAgICAgIGxldCBpc0VuYWJsZWQgPSBidG4uZ2V0SXNFbmFibGVkID8gYnRuLmdldElzRW5hYmxlZCgpIDogdHJ1ZTtcbiAgICAgICAgaWYgKGlzRW5hYmxlZCkge1xuICAgICAgICAgIGxldCAkYnRuID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChgXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiY29ybmVyLWJ0biBjYXAtYnRuLXJhaXNlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAke2J0bi5sYWJlbCB8fCBcIlwifVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+IGApO1xuXG4gICAgICAgICAgaWYgKGJ0bi5vbkNsaWNrKSB7XG4gICAgICAgICAgICAkYnRuLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBidG4ub25DbGljayk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgJGJ0bkNvbnRhaW5lci5hcHBlbmRDaGlsZCgkYnRuKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChjb25maWcudGltZWxpbmUuY29ybmVyLnJpZ2h0LmlucHV0cykge1xuICAgICAgY29uZmlnLnRpbWVsaW5lLmNvcm5lci5yaWdodC5pbnB1dHMuZm9yRWFjaCgoaW5wdXQpID0+IHtcbiAgICAgICAgbGV0ICRpbnB1dCA9IHRoaXMuY3JlYXRlQ29ybmVyUmlnaHRJbnB1dCh7IGlucHV0Q29uZmlnOiBpbnB1dCB9KTtcbiAgICAgICAgJGJ0bkNvbnRhaW5lci5hcHBlbmRDaGlsZCgkYnRuKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gJGVsO1xuICB9LFxuXG4gIGNyZWF0ZUNvcm5lclJpZ2h0SW5wdXQoeyBpbnB1dENvbmZpZywgZGF0YURheSA9IG51bGwsIGRheVNlbGVjdGVkID0gbnVsbCB9KSB7XG4gICAgbGV0IHIgPSBudWxsO1xuICAgIHN3aXRjaCAoaW5wdXRDb25maWcudHlwZSkge1xuICAgICAgY2FzZSBcImF1dG9jb21wbGV0ZS1jcnVkXCI6XG4gICAgICAgIHIgPSB0aGlzLmNyZWF0ZUNvcm5lclJpZ2h0SW5wdXRBdXRvY29tcGxldGVDcnVkKHtcbiAgICAgICAgICBpbnB1dENvbmZpZyxcbiAgICAgICAgICBkYXRhRGF5LFxuICAgICAgICAgIGRheVNlbGVjdGVkLFxuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiByO1xuICB9LFxuXG4gIGNyZWF0ZUNvcm5lclJpZ2h0SW5wdXRBdXRvY29tcGxldGVDcnVkKHtcbiAgICBpbnB1dENvbmZpZyxcbiAgICBkYXRhRGF5LFxuICAgIGRheVNlbGVjdGVkLFxuICB9KSB7XG4gICAgbGV0IGVsZW0gPSBcInRlc3RcIjtcbiAgICByZXR1cm4gZWxlbTtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBIZWFkZXIgVG9wXG4gICAqIFNlIHVzYSBwYXJhIDpcbiAgICogICAgLSBNYW5lam8gZGUgdGFic1xuICAgKiAgICAtIEJvdG9uZXMgZGUgbmF2ZWdhY2nDs24geSBzZWxlY2Npw7NuIGRlIGZlY2hhXG4gICAqICAgIC0gQm90b24gdG9nZ2xlIERhcmsgbW9kZVxuICAgKiAgICAtIEJvdG9uIHRvZ2dsZSBIZWFkZXIgZXh0ZW5kZWRcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb21cbiAgICovXG5cbiAgY3JlYXRlSGVhZGVyVG9wKGNvbmZpZywgdGFiU2VsZWN0ZWQgPSBudWxsKSB7XG4gICAgcmV0dXJuIHRoaXMucmVkcmF3SGVhZGVyVG9wKGNvbmZpZywgdGFiU2VsZWN0ZWQsIGRvbS5jcmVhdGVFbGVtZW50KFwiZGl2XCIpKTtcbiAgfSxcblxuICByZWRyYXdIZWFkZXJUb3AoY29uZmlnLCB0YWJTZWxlY3RlZCA9IG51bGwsICRlbGVtKSB7XG4gICAgbGV0IHN0ciA9IGBcbiAgICAgIDxkaXYgY2xhc3M9XCJoZWFkZXItdG9wXCI+YDtcblxuICAgIGlmIChjb25maWcudGltZWxpbmUudGFicykge1xuICAgICAgbGV0IHNob3dUYWJzID0gdHJ1ZTtcblxuICAgICAgaWYgKGNvbmZpZy50aW1lbGluZS50YWJzLmZpbHRlcigodCkgPT4gIXQuaXNIaWRkZW4pLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgIHNob3dUYWJzID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmIChzaG93VGFicykge1xuICAgICAgICBzdHIgKz0gYCA8ZGl2IGNsYXNzPVwidGFiLXNlbGVjdC1jb250YWluZXIgYy1kLWRlc2t0b3Atbm9uZSBjLWQtbW9iaWxlLWZsZXhcIj5cbiAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJ0YWJzLXNlbGVjdFwiID5gO1xuXG4gICAgICAgIGNvbmZpZy50aW1lbGluZS50YWJzLmZvckVhY2goKHRhYikgPT4ge1xuICAgICAgICAgIGlmICghdGFiLmlzSGlkZGVuKSB7XG4gICAgICAgICAgICBzdHIgKz0gYCA8b3B0aW9uICR7XG4gICAgICAgICAgICAgIHRhYiA9PSB0YWJTZWxlY3RlZCA/ICdzZWxlY3RlZD1cInNlbGVjdGVkXCInIDogXCJcIlxuICAgICAgICAgICAgfSB2YWx1ZT1cIiR7dGFiLmlkfVwiPiAke3RhYi5sYWJlbH0gPC9vcHRpb24+YDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHN0ciArPSBgPC9zZWxlY3Q+IDwvZGl2PmA7XG5cbiAgICAgICAgc3RyICs9IGAgPGRpdiBjbGFzcz1cInRhYnMtY29udGFpbmVyIGMtZC1kZXNrdG9wLWZsZXggYy1kLW1vYmlsZS1ub25lXCI+YDtcblxuICAgICAgICBjb25maWcudGltZWxpbmUudGFicy5mb3JFYWNoKCh0YWIpID0+IHtcbiAgICAgICAgICBpZiAoIXRhYi5pc0hpZGRlbikge1xuICAgICAgICAgICAgc3RyICs9IGAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0YWIgJHt0YWIuZGlzYWJsZWQgPyBcImRpc2FibGVkXCIgOiBcIlwifSAgJHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGFiID09IHRhYlNlbGVjdGVkID8gXCJhY3RpdmVcIiA6IFwiXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gICR7dGFiLmNvbG9yfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1cIiR7dGFiLmNvbG9yfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC1rZXk9XCIke3RhYi5pZH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgJHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGFiLnRvb2x0aXAgPyAnY2FwLXRvb2x0aXA9XCInICsgdGFiLnRvb2x0aXAgKyAnXCInIDogXCJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgfSA+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPiR7dGFiLmxhYmVsfTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgJHt0YWIuaWNvbiB8fCBcIlwifVxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICBgO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgc3RyICs9IGA8L2Rpdj5gO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0YWJTZWxlY3RlZCkge1xuICAgICAgaWYgKHRhYlNlbGVjdGVkLmxlZ2VuZHMpIHtcbiAgICAgICAgc3RyICs9IGAgXG4gICAgICAgIDxidXR0b24gdG9nZ2xlLWxlZ2VuZHMgY2xhc3M9XCJjYXAtYnRuLWljb24gY2FwLWJ0bi1pY29uLXJhaXNlZCBcIj5cbiAgICAgICAgICAke2ljb25zLnRvZ2dsZUxlZ2VuZHN9XG4gICAgICAgIDwvYnV0dG9uPiBcblxuICAgICAgICA8ZGl2IGNsYXNzPVwibGVnZW5kcy1jb250YWluZXIgZm9yY2UtbW9iaWxlLXN0eWxlIGhpZGVcIj4gYDtcblxuICAgICAgICB0YWJTZWxlY3RlZC5sZWdlbmRzLmZvckVhY2goKGxlZ2VuZCkgPT4ge1xuICAgICAgICAgIGxldCBjb2xvckNsYXNzID0gXCJcIjtcbiAgICAgICAgICBsZXQgY29sb3JCZyA9IFwiXCI7XG5cbiAgICAgICAgICBpZiAodXRpbHMuaXNIZXhDb2xvcihsZWdlbmQuY29sb3IpKSB7XG4gICAgICAgICAgICBjb2xvckJnID0gXCJiYWNrZ3JvdW5kOlwiICsgbGVnZW5kLmNvbG9yO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb2xvckNsYXNzID0gbGVnZW5kLmNvbG9yID8gbGVnZW5kLmNvbG9yICsgXCItLWJhY2tncm91bmRcIiA6IFwiXCI7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3RyICs9IGAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibGVnZW5kICR7bGVnZW5kLmFjdGl2ZSA/IFwiYWN0aXZlXCIgOiBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgaW5wdXQta2V5PVwiJHtsZWdlbmQua2V5fVwiXG4gICAgICAgICAgICAgICAgICAgICAgJHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZC50b29sdGlwID8gYGNhcC10b29sdGlwPVwiJHtsZWdlbmQudG9vbHRpcH1cImAgOiBcIlwiXG4gICAgICAgICAgICAgICAgICAgICAgfSA+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaWNvbi1sZWdlbmQgJHtjb2xvckNsYXNzfSAke1xuICAgICAgICAgICAgICAgICAgICBsZWdlbmQuc2hhcGVcbiAgICAgICAgICAgICAgICAgIH1cIiBzdHlsZT1cIiR7Y29sb3JCZ31cIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPiR7bGVnZW5kLmxhYmVsfTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICB9KTtcblxuICAgICAgICBzdHIgKz0gYDwvZGl2PmA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc3RyICs9IGBcblxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcGFjZXJcIj48L2Rpdj5cblxuXG5cbiAgICAgICAgICA8YnV0dG9uIGNhcC1idG4tcHJldiBjbGFzcz1cImNhcC1idG4taWNvbiBjYXAtYnRuLWljb24tcmFpc2VkXCI+XG4gICAgICAgICAgICAgJHtpY29ucy5hcnJvd0xlZnR9XG4gICAgICAgICAgICAgJHtpY29ucy5sb2FkaW5nSWNvbn0gXG4gICAgICAgICAgPC9idXR0b24+XG5cblxuICAgICAgICAgIDxidXR0b24gY2FwLWJ0bi1jYWxlbmRhciBjbGFzcz1cImNhcC1idG4taWNvbiBjYXAtYnRuLWljb24tcmFpc2VkXCI+XG4gICAgICAgICAgICAke2ljb25zLmNhbGVuZGFyfVxuICAgICAgICAgICAgJHtpY29ucy5sb2FkaW5nSWNvbn1cbiAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICAgIDxidXR0b24gY2FwLWJ0bi1uZXh0IGNsYXNzPVwiY2FwLWJ0bi1pY29uIGNhcC1idG4taWNvbi1yYWlzZWRcIj5cbiAgICAgICAgICAgICR7aWNvbnMuYXJyb3dSaWdodH1cbiAgICAgICAgICAgICR7aWNvbnMubG9hZGluZ0ljb259XG4gICAgICAgICAgPC9idXR0b24+XG5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic3BhY2VyXCI+PC9kaXY+XG5cbiAgICAgICAgICA8YnV0dG9uIHRvZ2dsZS1kYXJrIGNsYXNzPVwiY2FwLWJ0bi1pY29uIGNhcC1idG4taGVhZGVyIGMtZC1tb2JpbGUtbm9uZSAke1xuICAgICAgICAgICAgY29uZmlnLnRpbWVsaW5lLndpdGhEYXJrVG9nZ2xlID09IGZhbHNlID8gXCJoaWRlXCIgOiBcIlwiXG4gICAgICAgICAgfVwiPlxuICAgICAgICAgICAgJHtpY29ucy5kYXJrfVxuICAgICAgICAgICAgJHtpY29ucy5saWdodH1cbiAgICAgICAgICA8L2J1dHRvbj5gO1xuXG4gICAgaWYgKGNvbmZpZy50aW1lbGluZS5oZWFkZXIuZXh0ZW5kLmVuYWJsZWQgIT09IGZhbHNlKSB7XG4gICAgICBzdHIgKz0gYDxidXR0b24gdG9nZ2xlLWhlYWRlciBjbGFzcz1cImNhcC1idG4taWNvbiBjYXAtYnRuLWljb24tcmFpc2VkXCI+XG4gICAgICAgICAgJHtpY29ucy5jaGV2cm9uRG93bn1cbiAgICAgICAgICA8L2J1dHRvbj5gO1xuICAgIH1cblxuICAgIHN0ciArPSBgIDxkaXYgY2xhc3M9XCJidXR0b24tcmlnaHQtY29udGFpbmVyXCI+PC9kaXY+XG4gICAgICAgIDwvZGl2PmA7XG4gICAgLypcbiAgICAgICAgICBgXG4gICAgICAgICAgPGJ1dHRvbiB0b2dnbGUtc2lkZWJhci1yaWdodCBjbGFzcz1cImNhcC1idG4taWNvbiBjYXAtYnRuLWljb24tcmFpc2VkXCI+XG4gICAgICAgICAgICA8c3Bhbj5cbiAgICAgICAgICAgICAgPHN2ZyBzdHlsZT1cIndpZHRoOjI0cHg7aGVpZ2h0OjI0cHhcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCI+XG4gICAgICAgICAgICAgICAgICA8cGF0aCBmaWxsPVwiY3VycmVudENvbG9yXCIgZD1cIk0xNS40MSwxNi41OEwxMC44MywxMkwxNS40MSw3LjQxTDE0LDZMOCwxMkwxNCwxOEwxNS40MSwxNi41OFpcIiAvPlxuICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgPC9kaXY+XG4gICAgYDtcbiAgICAqL1xuXG4gICAgbGV0ICRyID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChzdHIpO1xuICAgICRlbGVtLnJlcGxhY2VXaXRoKCRyKTtcblxuICAgIGlmIChjb25maWcudGltZWxpbmUuaGVhZGVyLnJpZ2h0QnV0dG9ucykge1xuICAgICAgbGV0ICRidXR0b25Db250YWluZXIgPSAkci5xdWVyeVNlbGVjdG9yKFwiLmJ1dHRvbi1yaWdodC1jb250YWluZXJcIik7XG4gICAgICBjb25maWcudGltZWxpbmUuaGVhZGVyLnJpZ2h0QnV0dG9ucy5mb3JFYWNoKChidXR0b24pID0+IHtcbiAgICAgICAgbGV0IGhhc0JhZGdlID0gZmFsc2U7XG4gICAgICAgIGlmIChidXR0b24uaGFzQmFkZ2UpIHtcbiAgICAgICAgICBoYXNCYWRnZSA9IGJ1dHRvbi5oYXNCYWRnZSgpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBzdHIgPSBgPGJ1dHRvbiBjbGFzcz1cImNhcC1idG4taWNvbiBjYXAtYnRuLWljb24tcmFpc2VkICR7XG4gICAgICAgICAgaGFzQmFkZ2UgPyBcImNhcC1idG4taGFzLWJhZGdlXCIgOiBcIlwiXG4gICAgICAgIH1cIj5cbiAgICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgICA8c3ZnIHN0eWxlPVwid2lkdGg6MjRweDtoZWlnaHQ6MjRweFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIj5cbiAgICAgICAgICAgICAgICAgIDxwYXRoIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBkPVwiJHtidXR0b24uaWNvbn1cIiAvPlxuICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8L2J1dHRvbj5gO1xuICAgICAgICBsZXQgJGJ1dHRvbiA9IGRvbS5jcmVhdGVFbGVtZW50RnJvbUhUTUwoc3RyKTtcbiAgICAgICAgJGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGV2dCkgPT4gYnV0dG9uLm9uQ2xpY2soeyBldnQgfSkpO1xuICAgICAgICAkYnV0dG9uQ29udGFpbmVyLmFwcGVuZCgkYnV0dG9uKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGxldCAkdG9nZ2xlRGFyayA9ICRyLnF1ZXJ5U2VsZWN0b3IoXCJbdG9nZ2xlLWRhcmtdXCIpO1xuICAgIGlmICgkdG9nZ2xlRGFyaykge1xuICAgICAgJHRvZ2dsZURhcmsuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgICRyLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwidG9nZ2xlRGFya1wiLCB7XG4gICAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGxldCAkYnRuQ2FsZW5kYXIgPSAkci5xdWVyeVNlbGVjdG9yKFwiW2NhcC1idG4tY2FsZW5kYXJdXCIpO1xuICAgIGlmICgkYnRuQ2FsZW5kYXIpIHtcbiAgICAgICRidG5DYWxlbmRhci5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgbGV0IHggPSBlLng7XG4gICAgICAgIGxldCB5ID0gZS55O1xuICAgICAgICAkci5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgIG5ldyBDdXN0b21FdmVudChcImNsaWNrQ2FsZW5kYXJJY29uXCIsIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGRldGFpbDogeyB4LCB5IH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGxldCAkYnRuVG9nZ2xlSGVhZGVyID0gJHIucXVlcnlTZWxlY3RvcihcIlt0b2dnbGUtaGVhZGVyXVwiKTtcbiAgICBpZiAoJGJ0blRvZ2dsZUhlYWRlcikge1xuICAgICAgJGJ0blRvZ2dsZUhlYWRlci5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgJHIuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoXCJ0b2dnbGVIZWFkZXJcIiwge1xuICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgIGNhbmNlbGFibGU6IGZhbHNlLFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKlxuICAgICRyLnF1ZXJ5U2VsZWN0b3IoXCJbdG9nZ2xlLXNpZGViYXItcmlnaHRdXCIpLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBlID0+IHtcbiAgICAgICRyLmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KFwidG9nZ2xlU2lkZWJhclJpZ2h0XCIsIHtcbiAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICB9KSk7XG4gICAgfSk7XG4gICAgKi9cblxuICAgICRyLnF1ZXJ5U2VsZWN0b3IoXCJbY2FwLWJ0bi1wcmV2XVwiKS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICRyLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgIG5ldyBDdXN0b21FdmVudChcImhlYWRlclByZXZcIiwge1xuICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICBvcmlnaW5hbEV2dDogZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgICRyLnF1ZXJ5U2VsZWN0b3IoXCJbY2FwLWJ0bi1jYWxlbmRhcl1cIikuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAkci5kaXNwYXRjaEV2ZW50KFxuICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoXCJoZWFkZXJDYWxlbmRhclwiLCB7XG4gICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIG9yaWdpbmFsRXZ0OiBlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgJHIucXVlcnlTZWxlY3RvcihcIltjYXAtYnRuLW5leHRdXCIpLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZSkgPT4ge1xuICAgICAgJHIuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwiaGVhZGVyTmV4dFwiLCB7XG4gICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIG9yaWdpbmFsRXZ0OiBlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgbGV0ICR0b2dnbGVMZWdlbmRzQnRuID0gJHIucXVlcnlTZWxlY3RvcihcIlt0b2dnbGUtbGVnZW5kc11cIik7XG4gICAgaWYgKCR0b2dnbGVMZWdlbmRzQnRuKSB7XG4gICAgICAkdG9nZ2xlTGVnZW5kc0J0bi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgbGV0ICRsZWdlbmRDb250YWluZXIgPSAkci5xdWVyeVNlbGVjdG9yKFwiLmxlZ2VuZHMtY29udGFpbmVyXCIpO1xuICAgICAgICBpZiAoJGxlZ2VuZENvbnRhaW5lcikge1xuICAgICAgICAgICRsZWdlbmRDb250YWluZXIuY2xhc3NMaXN0LnRvZ2dsZShcImhpZGVcIik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgICRyLnF1ZXJ5U2VsZWN0b3JBbGwoXCIubGVnZW5kXCIpLmZvckVhY2goKCRsZWdlbmQpID0+IHtcbiAgICAgICRsZWdlbmQuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgIGxldCBrZXkgPSBlLmN1cnJlbnRUYXJnZXQuZ2V0QXR0cmlidXRlKFwiaW5wdXQta2V5XCIpO1xuXG4gICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICBsZXQgbGVnZW5kU2VsZWN0ZWQgPSB0YWJTZWxlY3RlZC5sZWdlbmRzLmZpbmQoXG4gICAgICAgICAgICAodGFiKSA9PiB0YWIua2V5ID09PSBrZXlcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChsZWdlbmRTZWxlY3RlZCkge1xuICAgICAgICAgICAgJHIuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwic2VsZWN0TGVnZW5kSGVhZGVyXCIsIHtcbiAgICAgICAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNhbmNlbGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICAgICAgbGVnZW5kOiBsZWdlbmRTZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICRsZWdlbmQsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgICRyLnF1ZXJ5U2VsZWN0b3JBbGwoXCIudGFiOm5vdCguZGlzYWJsZWQpXCIpLmZvckVhY2goKCR0YWIpID0+IHtcbiAgICAgICR0YWIuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgIGxldCBrZXkgPSBlLmN1cnJlbnRUYXJnZXQuZ2V0QXR0cmlidXRlKFwiaW5wdXQta2V5XCIpO1xuXG4gICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICBsZXQgdGFiU2VsZWN0ZWQgPSBjb25maWcudGltZWxpbmUudGFicy5maW5kKCh0YWIpID0+IHRhYi5pZCA9PSBrZXkpO1xuICAgICAgICAgIGlmICh0YWJTZWxlY3RlZCkge1xuICAgICAgICAgICAgJHIuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwic2VsZWN0VGFiSGVhZGVyXCIsIHtcbiAgICAgICAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNhbmNlbGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICAgICAgdGFiOiB0YWJTZWxlY3RlZCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgJHIucXVlcnlTZWxlY3RvckFsbChcIi50YWJzLXNlbGVjdDpub3QoLmRpc2FibGVkKVwiKS5mb3JFYWNoKCgkdGFiKSA9PiB7XG4gICAgICAkdGFiLmFkZEV2ZW50TGlzdGVuZXIoXCJjaGFuZ2VcIiwgKGUpID0+IHtcbiAgICAgICAgbGV0IGtleSA9IHBhcnNlRmxvYXQoZS5jdXJyZW50VGFyZ2V0LnZhbHVlKTtcblxuICAgICAgICBpZiAoa2V5KSB7XG4gICAgICAgICAgbGV0IHRhYlNlbGVjdGVkID0gY29uZmlnLnRpbWVsaW5lLnRhYnMuZmluZCgodGFiKSA9PiB0YWIuaWQgPT0ga2V5KTtcbiAgICAgICAgICBpZiAodGFiU2VsZWN0ZWQpIHtcbiAgICAgICAgICAgICRyLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgICAgIG5ldyBDdXN0b21FdmVudChcInNlbGVjdFRhYkhlYWRlclwiLCB7XG4gICAgICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgICAgICAgIHRhYjogdGFiU2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJldHVybiAkcjtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBIZWFkZXJcbiAgICogU2UgdXNhIHBhcmEgOlxuICAgKiAgICAtIE1vc3RyYXIgZmVjaGFzIGVuIGhlYWRlclxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gQ29uZmlndXJhY2lvbiBjYXBpYmFyYVxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbVxuICAgKi9cbiAgY3JlYXRlSGVhZGVyKGNvbmZpZykge1xuICAgIGxldCAkZWxlbSA9IGRvbS5jcmVhdGVFbGVtZW50KFwiaGVhZGVyXCIpO1xuICAgIHJldHVybiB0aGlzLnJlZHJhd0hlYWRlcihjb25maWcsICRlbGVtKTtcbiAgfSxcblxuICAvKipcbiAgICogUmVjcmVhIEhlYWRlciwgdXNhZG8gcGFyYSByZWRpYnVqYXJcbiAgICogdXRpbGl6YSAkZWxlbSBjb21vIGVsZW1lbnRvIGRvbSBkb25kZSByZWNyZWFybG9cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHBhcmFtIHtPYmplY3R9ICRlbGVtIC0gRWxlbWVudG8gRG9tIGRvbmRlIGNyZWEgSGVhZGVyXG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tXG4gICAqL1xuICByZWRyYXdIZWFkZXIoY29uZmlnLCAkZWxlbSkge1xuICAgIGxldCBkYXRlc1RyZWUgPSBkYXRlVXRpbHMuZ2V0RGF0ZVRyZWVSYW5nZShcbiAgICAgIG5ldyBEYXRlKGNvbmZpZy50aW1lbGluZS5zdGFydCksXG4gICAgICBuZXcgRGF0ZShjb25maWcudGltZWxpbmUuZW5kKVxuICAgICk7XG5cbiAgICBsZXQgc3RyID0gYDxkaXYgY2xhc3M9XCJoZWFkZXItY29udGFpbmVyXCI+IGA7XG5cbiAgICBPYmplY3Qua2V5cyhkYXRlc1RyZWUpLmZvckVhY2goKGtleVkpID0+IHtcbiAgICAgIGxldCB5ZWFyID0gZGF0ZXNUcmVlW2tleVldO1xuICAgICAgc3RyICs9IGA8ZGl2IGNsYXNzPVwiYWduby1jYWxlbmRhcmlvXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYWdubyBoaWRlXCI+JHtrZXlZfTwvc3Bhbj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1lc2VzXCI+YDtcblxuICAgICAgT2JqZWN0LmtleXMoeWVhcikuZm9yRWFjaCgoa2V5TSkgPT4ge1xuICAgICAgICBsZXQgbW9udGggPSBkYXRlc1RyZWVba2V5WV1ba2V5TV07XG4gICAgICAgIHN0ciArPSBgIDxkaXYgY2xhc3M9XCJtZXMtY2FsZW5kYXJpb1wiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWVzICR7XG4gICAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmtleXMobW9udGgpLmxlbmd0aCA8IDRcbiAgICAgICAgICAgICAgICAgICAgICAgID8gXCJtZXMtcmVkdWNlZCBtZXMtcmVkdWNlZC1cIiArIE9iamVjdC5rZXlzKG1vbnRoKS5sZW5ndGhcbiAgICAgICAgICAgICAgICAgICAgICAgIDogXCJcIlxuICAgICAgICAgICAgICAgICAgICB9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1lcy1sYWJlbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgJHt1dGlscy5nZXRNb250aEJ5UG9zaXRpb24oa2V5TSl9ICR7a2V5WX1cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkaWFzXCI+YDtcbiAgICAgICAgT2JqZWN0LmtleXMobW9udGgpLmZvckVhY2goKGtleUQpID0+IHtcbiAgICAgICAgICBsZXQgZGF5ID0gZGF0ZXNUcmVlW2tleVldW2tleU1dW2tleURdO1xuICAgICAgICAgIGxldCBpc1dlZWtlbmQgPSBkYXkuaXNXZWVrZW5kO1xuICAgICAgICAgIGxldCBpc1RvZGF5ID0gZGF5LmlzVG9kYXk7XG4gICAgICAgICAgbGV0IGhhc0FsZXJ0ID0gY29uZmlnLnRpbWVsaW5lLmhlYWRlci5kYXRlSGFzQWxlcnRcbiAgICAgICAgICAgID8gY29uZmlnLnRpbWVsaW5lLmhlYWRlci5kYXRlSGFzQWxlcnQoZGF5KVxuICAgICAgICAgICAgOiBmYWxzZTtcbiAgICAgICAgICBsZXQgZGF0ZSA9IGRhdGVVdGlscy5mb3JtYXREYXRlKGRheS5kYXRlKTtcbiAgICAgICAgICBzdHIgKz0gYDxkaXYgY2xhc3M9XCJkaWEtY2FsZW5kYXJpbyBcbiAgICAgICAgICAgICR7aXNUb2RheSA/IFwidG9kYXlcIiA6IFwiXCJ9XG4gICAgICAgICAgICAke2lzV2Vla2VuZCA/IFwid2Vla2VuZFwiIDogXCJcIn1cbiAgICAgICAgICAgICR7aGFzQWxlcnQgPyBcImhhcy1hbGVydFwiIDogXCJcIn1cbiAgICAgICAgICAgICR7Y29uZmlnLnRpbWVsaW5lLmRhdGVTZWxlY3RhYmxlID8gXCJpcy1jbGlja2VhYmxlXCIgOiBcIlwifVxuICAgICAgICAgICAgJHtjb25maWcudGltZWxpbmUuZGF0ZVdpdGhDb250ZXh0TWVudSA/IFwiaXMtY2xpY2tlYWJsZVwiIDogXCJcIn1cbiAgICAgICAgICAgIFwiIGRhdGU9XCIke2RhdGV9XCI+JHtrZXlEfTwvZGl2PmA7XG4gICAgICAgIH0pO1xuICAgICAgICBzdHIgKz0gYDwvZGl2PjwvZGl2PmA7XG4gICAgICB9KTtcbiAgICAgIHN0ciArPSBgPC9kaXY+IDwvZGl2PmA7XG4gICAgfSk7XG5cbiAgICBzdHIgKz0gYDwvZGl2PmA7XG4gICAgJGVsZW0uaW5uZXJIVE1MID0gXCJcIjtcbiAgICAkZWxlbS5hcHBlbmQoZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChzdHIpKTtcblxuICAgIGxldCAkZGF5cyA9ICRlbGVtLnF1ZXJ5U2VsZWN0b3JBbGwoXCIuZGlhLWNhbGVuZGFyaW9bZGF0ZV1cIik7XG4gICAgJGRheXMuZm9yRWFjaCgoJGRpYSkgPT4ge1xuICAgICAgaWYgKGNvbmZpZy50aW1lbGluZS5kYXRlV2l0aENvbnRleHRNZW51KSB7XG4gICAgICAgICRkaWEuYWRkRXZlbnRMaXN0ZW5lcihcImNvbnRleHRtZW51XCIsIChldnQpID0+IHtcbiAgICAgICAgICAkZWxlbS5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwiY29udGV4dE1lbnVEYXRlXCIsIHtcbiAgICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICAgICRlbGVtOiAkZGlhLFxuICAgICAgICAgICAgICAgIGRhdGU6ICRkaWEuZ2V0QXR0cmlidXRlKFwiZGF0ZVwiKSxcbiAgICAgICAgICAgICAgICBjbGllbnRYOiBldnQuY2xpZW50WCxcbiAgICAgICAgICAgICAgICBjbGllbnRZOiBldnQuY2xpZW50WSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoY29uZmlnLnRpbWVsaW5lLmRhdGVTZWxlY3RhYmxlKSB7XG4gICAgICAgICRkaWEuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChldnQpID0+IHtcbiAgICAgICAgICAkZWxlbS5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwiY2xpY2tEYXRlXCIsIHtcbiAgICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICAgICRlbGVtOiAkZGlhLFxuICAgICAgICAgICAgICAgIGRhdGU6ICRkaWEuZ2V0QXR0cmlidXRlKFwiZGF0ZVwiKSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoY29uZmlnLnRpbWVsaW5lLm9uTW91c2VPdmVyRGF0ZSkge1xuICAgICAgICAkZGlhLmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW92ZXJcIiwgKGV2dCkgPT4ge1xuICAgICAgICAgIGNvbmZpZy50aW1lbGluZS5vbk1vdXNlT3ZlckRhdGUoe1xuICAgICAgICAgICAgJGRpYSxcbiAgICAgICAgICAgICRlbGVtLFxuICAgICAgICAgICAgZGF0ZTogJGRpYS5nZXRBdHRyaWJ1dGUoXCJkYXRlXCIpLFxuICAgICAgICAgICAgZXZ0LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChjb25maWcudGltZWxpbmUub25Nb3VzZU91dERhdGUpIHtcbiAgICAgICAgJGRpYS5hZGRFdmVudExpc3RlbmVyKFwibW91c2VvdXRcIiwgKGV2dCkgPT4ge1xuICAgICAgICAgIGNvbmZpZy50aW1lbGluZS5vbk1vdXNlT3V0RGF0ZSh7XG4gICAgICAgICAgICAkZGlhLFxuICAgICAgICAgICAgJGVsZW0sXG4gICAgICAgICAgICBkYXRlOiAkZGlhLmdldEF0dHJpYnV0ZShcImRhdGVcIiksXG4gICAgICAgICAgICBldnQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuICRlbGVtO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhIEhlYWRlciBleHRlbmRlZFxuICAgKiBTZSB1c2EgcGFyYSA6XG4gICAqICAgIC1Nb3N0cmFyIGlucHV0cyB5IGRhdG9zIHBhcmEgZmVjaGFzIGVuIGhlYWRlclxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gQ29uZmlndXJhY2lvbiBjYXBpYmFyYVxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBoZWFkZXJFeHRlbmRlZFxuICAgKi9cbiAgY3JlYXRlSGVhZGVyRXh0ZW5kZWQoY29uZmlnKSB7XG4gICAgaWYgKGNvbmZpZy50aW1lbGluZS5oZWFkZXIuZXh0ZW5kLmVuYWJsZWQgPT0gZmFsc2UpIHJldHVybiBudWxsO1xuXG4gICAgbGV0IGRhdGVzID0gZGF0ZVV0aWxzLmdldERhdGVSYW5nZShcbiAgICAgIG5ldyBEYXRlKGNvbmZpZy50aW1lbGluZS5zdGFydCksXG4gICAgICBuZXcgRGF0ZShjb25maWcudGltZWxpbmUuZW5kKVxuICAgICk7XG4gICAgbGV0IHN0ciA9IGA8ZGl2IGNsYXNzPVwiaGVhZGVyLWNvbnRhaW5lci1leHRlbmRlZFwiPmA7XG5cbiAgICBjb25maWcudGltZWxpbmUuaGVhZGVyLmV4dGVuZC5kYXRhLmZvckVhY2goKGQsIGRfaW5kZXgpID0+IHtcbiAgICAgIGlmIChkLmlzSGlkZGVuKSByZXR1cm4gXCJcIjtcblxuICAgICAgbGV0IGlzUGVyc2lzdGVudCA9IGQuaXNQZXJzaXN0ZW50O1xuICAgICAgc3RyICs9IGA8ZGl2IGNsYXNzPVwiaW5wdXQtbGlzdCAke2lzUGVyc2lzdGVudCA/IFwicGVyc2lzdGVudFwiIDogXCJcIn1cIj5gO1xuICAgICAgc3RyICs9IGRhdGVzXG4gICAgICAgIC5tYXAoKGRhdGUpID0+IHtcbiAgICAgICAgICBsZXQgdmFsdWUgPSBcIlwiO1xuICAgICAgICAgIGxldCBjbGFzc05hbWUgPSBcIlwiO1xuICAgICAgICAgIGxldCBpc0Z1dHVyZSA9IGRhdGVVdGlscy5pc0Z1dHVyZShkYXRlKTtcbiAgICAgICAgICBsZXQgaXNUb2RheSA9IGRhdGVVdGlscy5pc1RvZGF5KGRhdGUpO1xuXG4gICAgICAgICAgaWYgKGQuZGF0YSkge1xuICAgICAgICAgICAgbGV0IGRhdGFGb3VuZGVkID0gZC5kYXRhLmZpbmQoKGRhdGFJbnB1dCkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gZGF0ZVV0aWxzLmlzU2FtZURhdGUoXG4gICAgICAgICAgICAgICAgbmV3IERhdGUoZGF0YUlucHV0LmRhdGUgKyBcIlQwMDowMDowMFwiKSxcbiAgICAgICAgICAgICAgICBkYXRlXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChkYXRhRm91bmRlZCkge1xuICAgICAgICAgICAgICB2YWx1ZSA9IGRhdGFGb3VuZGVkLnZhbHVlIHx8IFwiXCI7XG4gICAgICAgICAgICAgIGNsYXNzTmFtZSArPSBkYXRhRm91bmRlZC5jbGFzc05hbWUgKyBcIiBcIiB8fCBcIlwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGQuZWRpdGFibGUgPT09IGZhbHNlIHx8XG4gICAgICAgICAgICAoaXNGdXR1cmUgJiYgZC5lZGl0YWJsZUZ1dHVyZSA9PSBmYWxzZSkgfHxcbiAgICAgICAgICAgIChpc1RvZGF5ICYmIGQuZWRpdGFibGVUb2RheSA9PSBmYWxzZSlcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiBgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBkYXRlPVwiJHtkYXRlVXRpbHMuZm9ybWF0RGF0ZShkYXRlKX1cIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleD1cIiR7ZF9pbmRleH1cIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIiAke2NsYXNzTmFtZX0gJHtkYXRlLnZhck5hbWUgfHwgXCJcIn0gJHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQuY29sb3IgPyBcImMtXCIgKyBkLmNvbG9yICsgXCItLXRleHRcIiA6IFwiXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XCIgPiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke3ZhbHVlfSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgbGV0IGlzRGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgICBpZiAoY29uZmlnLnRpbWVsaW5lLmVkaXRhYmxlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgaXNEaXNhYmxlZCA9IHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGA8ZGl2IGNsYXNzPVwiZGlhLWlucHV0XCI+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgXG4gICAgICAgICAgICAgICAgICBkYXRlPVwiJHtkYXRlVXRpbHMuZm9ybWF0RGF0ZShkYXRlKX1cIiBcbiAgICAgICAgICAgICAgICAgIGluZGV4PVwiJHtkX2luZGV4fVwiIFxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJoZWFkZXItaW5wdXQgXG4gICAgICAgICAgICAgICAgICAke2RhdGUudmFyTmFtZX0gJHtkLmNvbG9yID8gXCJjLVwiICsgZC5jb2xvciArIFwiLS10ZXh0XCIgOiBcIlwifVwiIFxuICAgICAgICAgICAgICAgICAgdHlwZT1cIm51bWJlclwiXG4gICAgICAgICAgICAgICAgICAke2lzRGlzYWJsZWQgPyBcImRpc2FibGVkXCIgOiBcIlwifSBcbiAgICAgICAgICAgICAgICAgIHZhbHVlPVwiJHt2YWx1ZX1cIj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICB9KVxuICAgICAgICAuam9pbihcIlwiKTtcbiAgICAgIHN0ciArPSBgPC9kaXY+YDtcbiAgICB9KTtcblxuICAgIHN0ciArPSBgPC9kaXY+YDtcblxuICAgIGxldCByID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChzdHIpO1xuXG4gICAgci5xdWVyeVNlbGVjdG9yQWxsKFwiaW5wdXQuaGVhZGVyLWlucHV0XCIpLmZvckVhY2goKGlucHV0KSA9PiB7XG4gICAgICBpbnB1dC5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIiwgKGUpID0+IHtcbiAgICAgICAgbGV0IGRhdGUgPSBlLmN1cnJlbnRUYXJnZXQuZ2V0QXR0cmlidXRlKFwiZGF0ZVwiKTtcbiAgICAgICAgbGV0IGluZGV4ID0gZS5jdXJyZW50VGFyZ2V0LmdldEF0dHJpYnV0ZShcImluZGV4XCIpO1xuICAgICAgICBsZXQgdmFsdWUgPSBlLmN1cnJlbnRUYXJnZXQudmFsdWU7XG4gICAgICAgIGxldCB0eXBlRGF0YSA9IGNvbmZpZy50aW1lbGluZS5oZWFkZXIuZXh0ZW5kLmRhdGFbaW5kZXhdO1xuXG4gICAgICAgIC8vcmVmcmVzaCBjb25maWcgdmFsdWVcbiAgICAgICAgbGV0IGRhdGEgPSB0eXBlRGF0YS5kYXRhLmZpbmQoKGQpID0+XG4gICAgICAgICAgZGF0ZVV0aWxzLmlzU2FtZURhdGUoXG4gICAgICAgICAgICBuZXcgRGF0ZShkLmRhdGUgKyBcIlQwMDowMDowMFwiKSxcbiAgICAgICAgICAgIG5ldyBEYXRlKGRhdGUgKyBcIlQwMDowMDowMFwiKVxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICBkYXRhLnZhbHVlID0gdmFsdWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdHlwZURhdGEuZGF0YS5wdXNoKHtcbiAgICAgICAgICAgIGRhdGU6IGRhdGUsXG4gICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwiY2hhbmdlSW5wdXRIZWFkZXJcIiwge1xuICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgIGNhbmNlbGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICAgIGRhdGU6IGRhdGUsXG4gICAgICAgICAgICAgIHR5cGVEYXRhOiB0eXBlRGF0YSxcbiAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcjtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYXIgU2lkZWJhciBJenF1aWVyZG9cbiAgICogICAgLSBNYW5lamEgaXRlbXMgY29tbyBhcmJvbCBkZSAyIG5pdmVsZXMgKHBhcmVudCwgY2hpbGRyZW4pXG4gICAqICAgIC0gRWwgc2lkZWJhciBzZSBkaXZpZGUgZW4gbmF2TGlzdCAtIEluaXRpYWxOYXYgLSBleHRlbmRlZE5hdiAtIEJ0bk5hdlxuICAgKiAgICAtIFNlIGFncmVnYSBpdGVtRGV0YWlsLCBwYXJhIGRldGFsbGVzIGRlIGl0ZW1zXG4gICAqXG4gICAqXG4gICAqIFRPRE86IHBhcmEgZXZpdGFyIGluY3J1c3RhciBsYXMgaWRzIGVuIGxvcyBpbnB1dHMsIHNlIGRlYmVuIGNyZWFyXG4gICAqIGxvcyBub2RvcyB1bm8gcG9yIHVubyBjb21vIGVsZW1lbnRvIERPTSwgeSBhZ3JlZ2FybGVzIGxvcyBldmVudG9zIGRpcmVjdGFtZW50ZVxuICAgKiBhaG9yYSBzZSBoYWNlIHNlbGVjY2lvbmFuZG8gdG9kb3MgbG9zIGlucHV0cyBjb24gcXVlcnlTZWxlY3RvckFsbFxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gQ29uZmlndXJhY2lvbiBjYXBpYmFyYVxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBTaWRlYmFyIEl6cXVpZXJkb1xuICAgKi9cbiAgY3JlYXRlTmF2TGVmdChjb25maWcsIHRhYiA9IG51bGwpIHtcbiAgICBsZXQgJGVsZW0gPSBkb20uY3JlYXRlRWxlbWVudChcIm5hdlwiLCB7IGNsYXNzTmFtZTogXCJsZWZ0XCIgfSk7XG4gICAgcmV0dXJuIHRoaXMucmVkcmF3TmF2TGVmdCgkZWxlbSwgY29uZmlnLCB0YWIpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZWNyZWEgU2lkZWJhciBpenF1aWVyZG8sIHVzYWRvIHBhcmEgcmVkaWJ1amFyXG4gICAqIFV0aWxpemEgJGVsZW0gY29tbyBlbGVtZW50byBkb20gZG9uZGUgcmVjcmVhcmxvXG4gICAqXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSAkZWxlbSAtIEVsZW1lbnRvIERvbSBkb25kZSBjcmVhIGVsIHNpZGViYXIgaXpxdWllcmRvXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgLSBDb25maWd1cmFjaW9uIGNhcGliYXJhXG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tIG5hdkxlZnRcbiAgICovXG5cbiAgcmVkcmF3TmF2TGVmdCgkZWxlbSwgY29uZmlnLCB0YWIgPSBudWxsKSB7XG4gICAgbGV0IG5hdkxpc3QgPSBcIlwiO1xuICAgIGxldCBpbml0aWFsTmF2TGlzdCA9IFwiXCI7XG4gICAgbGV0IGV4TmF2TGlzdCA9IFwiXCI7XG4gICAgbGV0IGJ0bk5hdkxpc3QgPSBcIlwiO1xuICAgIGxldCBpc0Rpc2FibGVkID0gZmFsc2U7XG4gICAgaWYgKGNvbmZpZy50aW1lbGluZS5lZGl0YWJsZSA9PT0gZmFsc2UpIHtcbiAgICAgIGlzRGlzYWJsZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGNvbmZpZy5kYXRhLmZvckVhY2goKGQpID0+IHtcbiAgICAgIGlmIChkLmlzSGlkZGVuKSByZXR1cm47XG5cbiAgICAgIGNvbnN0IGhhc0J0biA9ICEhZC5vbkNsaWNrRGV0YWlsQnV0dG9uO1xuICAgICAgY29uc3QgZGV0YWlsQnRuID0gaGFzQnRuXG4gICAgICAgID8gYDxidXR0b24gY2xhc3M9XCJkZXRhaWwtYnRuXCIgaXRlbS1pZD1cIiR7ZC5pZCB8fCAtMX1cIiB0eXBlLW5vZGU9XCIke1xuICAgICAgICAgICAgZC50eXBlIHx8IFwiXCJcbiAgICAgICAgICB9XCIgPlxuICAgICAgICAke2QubGFiZWxEZXRhaWxCdXR0b259XG4gICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPmBcbiAgICAgICAgOiBcIlwiO1xuXG4gICAgICBuYXZMaXN0ICs9IGBcbiAgICAgICA8ZGl2IGNsYXNzPVwibmF2LWl0ZW1cIj5cblxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJuYXYtaXRlbS1jb250YWluZXIgcGFyZW50XCI+YDtcblxuICAgICAgaWYgKGQuY2hpbGRyZW4pIHtcbiAgICAgICAgbmF2TGlzdCArPSBgPGJ1dHRvbiBjbGFzcz1cInRyZWUtaWNvbiAke1xuICAgICAgICAgIGQuaXNDbG9zZWQgPyBcIlwiIDogXCJjYXAtcm90YXRlXCJcbiAgICAgICAgfVwiIGl0ZW0taWQ9XCIke2QuaWQgfHwgLTF9XCIgdHlwZS1ub2RlPVwiJHtkLnR5cGUgfHwgXCJcIn1cIiA+XG4gICAgICAgICR7aWNvbnMuY2hldnJvbkRvd259XG4gICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPmA7XG4gICAgICB9XG5cbiAgICAgIG5hdkxpc3QgKz0gYFxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtLXRpdGxlIHRydW5jYXRlIGZ1bGwtd2lkdGggJHtcbiAgICAgICAgICAgIGQuY2xpY2tlYWJsZSA/IFwiY2xpY2tlYWJsZVwiIDogXCJcIlxuICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAke2QubmF2T3ZlciA/IFwiaG92ZXJhYmxlXCIgOiBcIlwifSBcIiBpdGVtLWlkPVwiJHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGQuaWQgfHwgLTFcbiAgICAgICAgICAgICAgICAgICAgICB9XCIgdHlwZS1ub2RlPVwiJHtkLnR5cGUgfHwgXCJcIn1cIiA+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbS10aXRsZS1jb250ZW50XCI+XG4gICAgICAgICAgICAgICR7ZC5sYWJlbH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbC1idG4tY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICR7ZGV0YWlsQnRufVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PmA7XG5cbiAgICAgIGlmIChkLmNoaWxkcmVuKSB7XG4gICAgICAgIG5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2hpbGRyZW4taXRlbXMgJHtcbiAgICAgICAgICAgICAgICBkLmlzQ2xvc2VkID8gXCJoaWRlXCIgOiBcIlwiXG4gICAgICAgICAgICAgIH0gXCIgY2hpbGQtbGlzdD1cIiR7ZC5pZCB8fCAtMX1cIj5gO1xuXG4gICAgICAgIGQuY2hpbGRyZW4uZm9yRWFjaCgoYykgPT4ge1xuICAgICAgICAgIGlmIChjLmlzSGlkZGVuKSByZXR1cm47XG5cbiAgICAgICAgICBsZXQgbGlnaHRDb2xvciA9IG51bGw7XG4gICAgICAgICAgbGV0IGxpZ2h0Q2xhc3MgPSBudWxsO1xuICAgICAgICAgIGxldCBsaWdodFNwYW4gPSBcIlwiO1xuICAgICAgICAgIGxldCBtdWx0aUJ1dHRvbnNEZXRhaWxUbXBsID0gXCJcIjtcblxuICAgICAgICAgIGlmIChjLmxpZ2h0KSB7XG4gICAgICAgICAgICBpZiAodXRpbHMuaXNIZXhDb2xvcihjLmxpZ2h0KSkge1xuICAgICAgICAgICAgICBsaWdodENvbG9yID0gYy5saWdodDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGxpZ2h0Q2xhc3MgPSBjLmxpZ2h0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChjLmxpZ2h0KSB7XG4gICAgICAgICAgICBsaWdodFNwYW4gPSBgPHNwYW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibGlnaHQgJHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaWdodENsYXNzID8gbGlnaHRDbGFzcyArIFwiLWxpZ2h0XCIgOiBcIlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCIke1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpZ2h0Q29sb3IgPyBcIi0tbGlnaHQtY29sb3I6XCIgKyBsaWdodENvbG9yIDogXCJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICB9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+YDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoYy5oYXNNdWx0aWJ1dHRvbnMpIHtcbiAgICAgICAgICAgIGxldCBpY29uRm9ybWF0dGVyID0gbnVsbDtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmluaXRpYWwubXVsdGlidXR0b25zICYmXG4gICAgICAgICAgICAgIGNvbmZpZy50aW1lbGluZS5uYXYubGVmdC5pbml0aWFsLm11bHRpYnV0dG9ucy5pY29uRm9ybWF0dGVyXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgaWNvbkZvcm1hdHRlciA9XG4gICAgICAgICAgICAgICAgY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmluaXRpYWwubXVsdGlidXR0b25zLmljb25Gb3JtYXR0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgYnRuQ29udGVudCA9IGljb25Gb3JtYXR0ZXJcbiAgICAgICAgICAgICAgPyBpY29uRm9ybWF0dGVyKHsgaXRlbTogYywgY29uZmlnIH0pXG4gICAgICAgICAgICAgIDogXCJcIjtcblxuICAgICAgICAgICAgbXVsdGlCdXR0b25zRGV0YWlsVG1wbCA9IGA8YnV0dG9uIGNsYXNzPVwibXVsdGlidXR0b25zLWJ0blwiIFxuICAgICAgICAgICAgICBpdGVtLWlkPVwiJHtjLmlkIHx8IC0xfVwiIFxuICAgICAgICAgICAgICB0eXBlLW5vZGU9XCIke2MudHlwZSB8fCBcIlwifVwiIFxuICAgICAgICAgICAgICAke2lzRGlzYWJsZWQgPyBcImRpc2FibGVkXCIgOiBcIlwifT5cbiAgICAgICAgICAgICAgICAke2J0bkNvbnRlbnR9IFxuICAgICAgICAgICAgICA8L2J1dHRvbj5gO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIG5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjaGlsZC1uYXYtaXRlbVwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm5hdi1pdGVtLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICBgO1xuXG4gICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJuYXYtaXRlbS1pY29uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHN2ZyBzdHlsZT1cIndpZHRoOjI0cHg7aGVpZ2h0OjI0cHhcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBkPVwiTTE5LDE1TDEzLDIxTDExLjU4LDE5LjU4TDE1LjE3LDE2SDRWNEg2VjE0SDE1LjE3TDExLjU4LDEwLjQyTDEzLDlMMTksMTVaXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICovXG5cbiAgICAgICAgICBuYXZMaXN0ICs9IGBcbiAgICAgICAgICAgICAgICAgICAgJHtsaWdodFNwYW59XG4gICAgICAgICAgICAgICAgICAgICR7bXVsdGlCdXR0b25zRGV0YWlsVG1wbH1cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBcbiAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIml0ZW0tdGl0bGUgJHtjLmNsaWNrZWFibGUgPyBcImNsaWNrZWFibGVcIiA6IFwiXCJ9ICR7XG4gICAgICAgICAgICAgICAgICAgICAgICBjLm5hdk92ZXIgPyBcImhvdmVyYWJsZVwiIDogXCJcIlxuICAgICAgICAgICAgICAgICAgICAgIH1cIiBcbiAgICAgICAgICAgICAgICAgICAgICBpdGVtLWlkPVwiJHtjLmlkIHx8IC0xfVwiIFxuICAgICAgICAgICAgICAgICAgICAgIHR5cGUtbm9kZT1cIiR7Yy50eXBlIHx8IFwiXCJ9XCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHJ1bmNhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICR7Yy5sYWJlbH1cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICB9KTtcblxuICAgICAgICBuYXZMaXN0ICs9IGBcbiAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgIH1cblxuICAgICAgbmF2TGlzdCArPSBgPC9kaXY+YDtcblxuICAgICAgLy9pbml0aWFsXG4gICAgICBpbml0aWFsTmF2TGlzdCArPSBgPGRpdiBjbGFzcz1cImluaXRpYWwtbmF2LWl0ZW0gcGFyZW50XCI+YDtcbiAgICAgIGlmIChkLndpdGhOYXYpIHtcbiAgICAgICAgY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmluaXRpYWwudmFycy5mb3JFYWNoKCh2KSA9PiB7XG4gICAgICAgICAgbGV0IHZhbHVlID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGQudmFsdWVzLCB2LnZhck5hbWUpO1xuXG4gICAgICAgICAgaWYgKHYucm91bmQgJiYgIWlzTmFOKHZhbHVlKSkge1xuICAgICAgICAgICAgdmFsdWUgPSB1dGlscy5yb3VuZCh2YWx1ZSwgdi5yb3VuZCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh2LmlucHV0KSB7XG4gICAgICAgICAgICBzd2l0Y2ggKHYuaW5wdXQpIHtcbiAgICAgICAgICAgICAgY2FzZSBcImhvdXJcIjpcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnNwbGl0KFwiOlwiKTtcbiAgICAgICAgICAgICAgICBsZXQgaGhWYWx1ZSA9IHZhbHVlWzBdO1xuICAgICAgICAgICAgICAgIGxldCBtbVZhbHVlID0gdmFsdWVbMV07XG4gICAgICAgICAgICAgICAgaW5pdGlhbE5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtLWNvbCBoYXMtaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJob3VyLWlucHV0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtdHlwZT1cInRpbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXg9XCIyM1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbj1cIjAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQta2V5PVwiJHt2LmtleSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0taWQ9XCIke2QuaWQgfHwgLTF9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS1ub2RlPVwiJHtkLnR5cGUgfHwgXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT1cIiR7aGhWYWx1ZX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2lzRGlzYWJsZWQgPyBcImRpc2FibGVkXCIgOiBcIlwifVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImhoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPjo8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtdHlwZT1cInRpbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXg9XCI1OVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbj1cIjAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQta2V5PVwiJHt2LmtleSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0taWQ9XCIke2QuaWQgfHwgLTF9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS1ub2RlPVwiJHtkLnR5cGUgfHwgXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT1cIiR7bW1WYWx1ZX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2lzRGlzYWJsZWQgPyBcImRpc2FibGVkXCIgOiBcIlwifVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1tXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlIFwidGV4dFwiOlxuICAgICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgaW5pdGlhbE5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtLWNvbCBoYXMtaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCAgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCIke3YuaW5wdXQgfHwgXCJ0ZXh0XCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtdHlwZT1cIiR7di5pbnB1dCB8fCBcInRleHRcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC1rZXk9XCIke3Yua2V5IHx8IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS1pZD1cIiR7ZC5pZCB8fCAtMX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLW5vZGU9XCIke2QudHlwZSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7aXNEaXNhYmxlZCA/IFwiZGlzYWJsZWRcIiA6IFwiXCJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPVwiJHt2YWx1ZX1cIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaW5pdGlhbE5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbS1jb2xcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke3ZhbHVlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGluaXRpYWxOYXZMaXN0ICs9IGBcbiAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG5cbiAgICAgIGlmIChkLmNoaWxkcmVuKSB7XG4gICAgICAgIGQuY2hpbGRyZW4uZm9yRWFjaCgoYykgPT4ge1xuICAgICAgICAgIGlmIChjLmlzSGlkZGVuKSByZXR1cm47XG4gICAgICAgICAgaW5pdGlhbE5hdkxpc3QgKz0gYDxkaXYgY2xhc3M9XCJjaGlsZC1pbml0aWFsLW5hdi1pdGVtICR7XG4gICAgICAgICAgICBkLmlzQ2xvc2VkID8gXCJoaWRlXCIgOiBcIlwiXG4gICAgICAgICAgfVwiIGNoaWxkPVwiJHtkLmlkIHx8IC0xfVwiPmA7XG5cbiAgICAgICAgICBpZiAoYy53aXRoTmF2ICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmluaXRpYWwudmFycy5mb3JFYWNoKCh2KSA9PiB7XG4gICAgICAgICAgICAgIGlmICh2Lm9ubHlUYWIgJiYgdGFiICYmIHYub25seVRhYiAhPT0gdGFiLmtleSkgcmV0dXJuO1xuXG4gICAgICAgICAgICAgIGxldCB2YWx1ZSA9IHV0aWxzLmdldFZhckJ5UGF0aChjLnZhbHVlcywgdi52YXJOYW1lKTtcbiAgICAgICAgICAgICAgaWYgKHYucm91bmQgJiYgIWlzTmFOKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdXRpbHMucm91bmQodmFsdWUsIHYucm91bmQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmICh2LmlucHV0KSB7XG4gICAgICAgICAgICAgICAgc3dpdGNoICh2LmlucHV0KSB7XG4gICAgICAgICAgICAgICAgICBjYXNlIFwiaG91clwiOlxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnNwbGl0KFwiOlwiKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGhoVmFsdWUgPSB2YWx1ZVswXTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG1tVmFsdWUgPSB2YWx1ZVsxXTtcbiAgICAgICAgICAgICAgICAgICAgaW5pdGlhbE5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtLWNvbCBoYXMtaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJob3VyLWlucHV0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtdHlwZT1cInRpbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXg9XCIyM1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbj1cIjAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQta2V5PVwiJHt2LmtleSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0taWQ9XCIke2MuaWQgfHwgLTF9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS1ub2RlPVwiJHtjLnR5cGUgfHwgXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT1cIiR7aGhWYWx1ZX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2lzRGlzYWJsZWQgPyBcImRpc2FibGVkXCIgOiBcIlwifVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImhoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPjo8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtdHlwZT1cInRpbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXg9XCI1OVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbj1cIjAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQta2V5PVwiJHt2LmtleSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0taWQ9XCIke2MuaWQgfHwgLTF9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS1ub2RlPVwiJHtjLnR5cGUgfHwgXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT1cIiR7bW1WYWx1ZX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2lzRGlzYWJsZWQgPyBcImRpc2FibGVkXCIgOiBcIlwifVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1tXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGNhc2UgXCJ0ZXh0XCI6XG4gICAgICAgICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBpbml0aWFsTmF2TGlzdCArPSBgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIml0ZW0tY29sIGhhcy1pbnB1dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCIke3YuaW5wdXQgfHwgXCJ0ZXh0XCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtdHlwZT1cIiR7di5pbnB1dCB8fCBcInRleHRcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC1rZXk9XCIke3Yua2V5IHx8IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS1pZD1cIiR7Yy5pZCB8fCAtMX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLW5vZGU9XCIke2MudHlwZSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7aXNEaXNhYmxlZCA/IFwiZGlzYWJsZWRcIiA6IFwiXCJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPVwiJHt2YWx1ZX1cIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaW5pdGlhbE5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbS1jb2xcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke3ZhbHVlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaW5pdGlhbE5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICAvL0V4dFxuICAgICAgZXhOYXZMaXN0ICs9IGA8ZGl2IGNsYXNzPVwiZXgtbmF2LWl0ZW0gcGFyZW50XCI+YDtcbiAgICAgIGlmIChkLndpdGhFeE5hdikge1xuICAgICAgICBjb25maWcudGltZWxpbmUubmF2LmxlZnQuZXh0ZW5kLnZhcnMuZm9yRWFjaCgodikgPT4ge1xuICAgICAgICAgIGxldCB2YWx1ZSA9IHV0aWxzLmdldFZhckJ5UGF0aChkLnZhbHVlcywgdi52YXJOYW1lKTtcbiAgICAgICAgICBpZiAodi5yb3VuZCAmJiAhaXNOYU4odmFsdWUpKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHV0aWxzLnJvdW5kKHZhbHVlLCB2LnJvdW5kKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHYuaW5wdXQpIHtcbiAgICAgICAgICAgIHN3aXRjaCAodi5pbnB1dCkge1xuICAgICAgICAgICAgICBjYXNlIFwiaG91clwiOlxuICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuc3BsaXQoXCI6XCIpO1xuICAgICAgICAgICAgICAgIGxldCBoaFZhbHVlID0gdmFsdWVbMF07XG4gICAgICAgICAgICAgICAgbGV0IG1tVmFsdWUgPSB2YWx1ZVsxXTtcbiAgICAgICAgICAgICAgICBleE5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtLWNvbCBoYXMtaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJob3VyLWlucHV0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtdHlwZT1cInRpbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXg9XCIyM1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbj1cIjBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC1rZXk9XCIke3Yua2V5IHx8IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS1pZD1cIiR7ZC5pZCB8fCAtMX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLW5vZGU9XCIke2QudHlwZSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPVwiJHtoaFZhbHVlfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7aXNEaXNhYmxlZCA/IFwiZGlzYWJsZWRcIiA6IFwiXCJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+Ojwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC10eXBlPVwidGltZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heD1cIjU5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluPVwiMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LWtleT1cIiR7di5rZXkgfHwgXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLWlkPVwiJHtkLmlkIHx8IC0xfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtbm9kZT1cIiR7ZC50eXBlIHx8IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9XCIke21tVmFsdWV9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtpc0Rpc2FibGVkID8gXCJkaXNhYmxlZFwiIDogXCJcIn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgY2FzZSBcInRleHRcIjpcbiAgICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGV4TmF2TGlzdCArPSBgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIml0ZW0tY29sIGhhcy1pbnB1dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCIke3YuaW5wdXQgfHwgXCJ0ZXh0XCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtdHlwZT1cIiR7di5pbnB1dCB8fCBcInRleHRcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC1rZXk9XCIke3Yua2V5IHx8IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS1pZD1cIiR7ZC5pZCB8fCAtMX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLW5vZGU9XCIke2QudHlwZSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7aXNEaXNhYmxlZCA/IFwiZGlzYWJsZWRcIiA6IFwiXCJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPVwiJHt2YWx1ZX1cIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZXhOYXZMaXN0ICs9IGBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIml0ZW0tY29sXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHt2YWx1ZX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBleE5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcblxuICAgICAgaWYgKGQuY2hpbGRyZW4pIHtcbiAgICAgICAgZC5jaGlsZHJlbi5mb3JFYWNoKChjKSA9PiB7XG4gICAgICAgICAgaWYgKGMuaXNIaWRkZW4pIHJldHVybjtcbiAgICAgICAgICBleE5hdkxpc3QgKz0gYDxkaXYgY2xhc3M9XCJjaGlsZC1leC1uYXYtaXRlbSAke1xuICAgICAgICAgICAgZC5pc0Nsb3NlZCA/IFwiaGlkZVwiIDogXCJcIlxuICAgICAgICAgIH1cIiBjaGlsZD1cIiR7ZC5pZCB8fCAtMX1cIj5gO1xuXG4gICAgICAgICAgaWYgKGMud2l0aE5hdiAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGNvbmZpZy50aW1lbGluZS5uYXYubGVmdC5leHRlbmQudmFycy5mb3JFYWNoKCh2KSA9PiB7XG4gICAgICAgICAgICAgIGlmICh2Lm9ubHlUYWIgJiYgdGFiICYmIHYub25seVRhYiAhPT0gdGFiLmtleSkgcmV0dXJuO1xuXG4gICAgICAgICAgICAgIGxldCB2YWx1ZSA9IHV0aWxzLmdldFZhckJ5UGF0aChjLnZhbHVlcywgdi52YXJOYW1lKTtcbiAgICAgICAgICAgICAgaWYgKHYucm91bmQgJiYgIWlzTmFOKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdXRpbHMucm91bmQodmFsdWUsIHYucm91bmQpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKHYuaW5wdXQpIHtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKHYuaW5wdXQpIHtcbiAgICAgICAgICAgICAgICAgIGNhc2UgXCJob3VyXCI6XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUgPyB2YWx1ZS5zcGxpdChcIjpcIikgOiBbMCwgMF07XG4gICAgICAgICAgICAgICAgICAgIGxldCBoaFZhbHVlID0gdmFsdWVbMF07XG4gICAgICAgICAgICAgICAgICAgIGxldCBtbVZhbHVlID0gdmFsdWVbMV07XG4gICAgICAgICAgICAgICAgICAgIGV4TmF2TGlzdCArPSBgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIml0ZW0tY29sIGhhcy1pbnB1dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhvdXItaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC10eXBlPVwidGltZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heD1cIjIzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluPVwiMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LWtleT1cIiR7di5rZXkgfHwgXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLWlkPVwiJHtjLmlkIHx8IC0xfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtbm9kZT1cIiR7Yy50eXBlIHx8IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9XCIke2hoVmFsdWV9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtpc0Rpc2FibGVkID8gXCJkaXNhYmxlZFwiIDogXCJcIn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJoaFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj46PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LXR5cGU9XCJ0aW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4PVwiNTlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW49XCIwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQta2V5PVwiJHt2LmtleSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0taWQ9XCIke2MuaWQgfHwgLTF9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS1ub2RlPVwiJHtjLnR5cGUgfHwgXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT1cIiR7bW1WYWx1ZX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2lzRGlzYWJsZWQgPyBcImRpc2FibGVkXCIgOiBcIlwifVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1tXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGNhc2UgXCJ0ZXh0XCI6XG4gICAgICAgICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBleE5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtLWNvbCBoYXMtaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCAgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCIke3YuaW5wdXQgfHwgXCJ0ZXh0XCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtdHlwZT1cIiR7di5pbnB1dCB8fCBcInRleHRcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC1rZXk9XCIke3Yua2V5IHx8IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS1pZD1cIiR7Yy5pZCB8fCAtMX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLW5vZGU9XCIke2MudHlwZSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7aXNEaXNhYmxlZCA/IFwiZGlzYWJsZWRcIiA6IFwiXCJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPVwiJHt2YWx1ZX1cIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZXhOYXZMaXN0ICs9IGBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIml0ZW0tY29sXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHt2YWx1ZX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGV4TmF2TGlzdCArPSBgXG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vYnV0dG9uc1xuICAgICAgYnRuTmF2TGlzdCArPSBgPGRpdiBjbGFzcz1cImNhcC1idG4tbmF2LWl0ZW0gcGFyZW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FwLWJ0bi1uYXYtaXRlbS1jb250ZW50XCI+YDtcbiAgICAgIGlmIChcbiAgICAgICAgY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmJ1dHRvbnMgJiZcbiAgICAgICAgY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmJ1dHRvbnMudmFyc1xuICAgICAgKSB7XG4gICAgICAgIGNvbmZpZy50aW1lbGluZS5uYXYubGVmdC5idXR0b25zLnZhcnMuZm9yRWFjaCgoYnRuKSA9PiB7XG4gICAgICAgICAgaWYgKGQud2l0aEJ0bk5hdikge1xuICAgICAgICAgICAgbGV0IGJ0bkNvbnRlbnQgPSBcIlwiO1xuICAgICAgICAgICAgbGV0IGNsYXNzTmFtZSA9IGJ0bi5jbGFzc05hbWUgfHwgXCJcIjtcblxuICAgICAgICAgICAgaWYgKGJ0bi5pY29uKSB7XG4gICAgICAgICAgICAgIGJ0bkNvbnRlbnQgPSBidG4uaWNvbiA/IGJ0bi5pY29uIDogXCJcIjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGJ0bi5pY29uRm9ybWF0dGVyKSB7XG4gICAgICAgICAgICAgIGJ0bkNvbnRlbnQgPSBidG4uaWNvbkZvcm1hdHRlciA/IGJ0bi5pY29uRm9ybWF0dGVyKGQsIGJ0bikgOiBcIlwiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoYnRuLnNoYXBlKSB7XG4gICAgICAgICAgICAgIGNsYXNzTmFtZSArPSBcIiBjYXAtYnRuLVwiICsgYnRuLnNoYXBlO1xuICAgICAgICAgICAgICBidG5Db250ZW50ICs9IGA8c3Bhbj4gJHtcbiAgICAgICAgICAgICAgICBidG4uZm9ybWF0dGVyID8gYnRuLmZvcm1hdHRlcihkLCBidG4pIDogXCJcIlxuICAgICAgICAgICAgICB9IDwvc3Bhbj4gYDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChidG4uYnRuQ2xhc3NOYW1lRm9ybWF0dGVyKSB7XG4gICAgICAgICAgICAgIGxldCBuZXdDbGFzc05hbWUgPSBidG4uYnRuQ2xhc3NOYW1lRm9ybWF0dGVyKGQsIGJ0bik7XG4gICAgICAgICAgICAgIGlmIChuZXdDbGFzc05hbWUpIHtcbiAgICAgICAgICAgICAgICBjbGFzc05hbWUgKz0gXCIgXCIgKyBuZXdDbGFzc05hbWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYnRuTmF2TGlzdCArPSBgXG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJjYXAtYnRuLXNoYXBlICR7Y2xhc3NOYW1lfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQta2V5PVwiJHtidG4ua2V5IHx8IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLWlkPVwiJHtkLmlkIHx8IC0xfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtpc0Rpc2FibGVkID8gXCJkaXNhYmxlZFwiIDogXCJcIn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLW5vZGU9XCIke2QudHlwZSB8fCBcIlwifVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7YnRuQ29udGVudH1cbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+YDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgYnRuTmF2TGlzdCArPSBgXG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG5cbiAgICAgIGlmIChkLmNoaWxkcmVuKSB7XG4gICAgICAgIGQuY2hpbGRyZW4uZm9yRWFjaCgoYykgPT4ge1xuICAgICAgICAgIGlmIChjLmlzSGlkZGVuKSByZXR1cm47XG5cbiAgICAgICAgICAvL2J1dHRvbnNcbiAgICAgICAgICBidG5OYXZMaXN0ICs9IGA8ZGl2IGNsYXNzPVwiY2FwLWJ0bi1jaGlsZC1uYXYtaXRlbSBwYXJlbnQgJHtcbiAgICAgICAgICAgIGQuaXNDbG9zZWQgPyBcImhpZGVcIiA6IFwiXCJcbiAgICAgICAgICB9XCIgY2hpbGQ9XCIke2QuaWQgfHwgLTF9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcC1idG4tbmF2LWl0ZW0tY29udGVudFwiPmA7XG5cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBjb25maWcudGltZWxpbmUubmF2LmxlZnQuYnV0dG9ucyAmJlxuICAgICAgICAgICAgY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmJ1dHRvbnMudmFyc1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmJ1dHRvbnMudmFycy5mb3JFYWNoKChidG4pID0+IHtcbiAgICAgICAgICAgICAgaWYgKGMud2l0aE5hdiAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBsZXQgYnRuQ29udGVudCA9IFwiXCI7XG4gICAgICAgICAgICAgICAgbGV0IGNsYXNzTmFtZSA9IGJ0bi5jbGFzc05hbWUgfHwgXCJcIjtcblxuICAgICAgICAgICAgICAgIGlmIChidG4uaWNvbikge1xuICAgICAgICAgICAgICAgICAgYnRuQ29udGVudCA9IGJ0bi5pY29uID8gYnRuLmljb24gOiBcIlwiO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChidG4uaWNvbkZvcm1hdHRlcikge1xuICAgICAgICAgICAgICAgICAgYnRuQ29udGVudCA9IGJ0bi5pY29uRm9ybWF0dGVyXG4gICAgICAgICAgICAgICAgICAgID8gYnRuLmljb25Gb3JtYXR0ZXIoYywgYnRuKVxuICAgICAgICAgICAgICAgICAgICA6IFwiXCI7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGJ0bi5zaGFwZSkge1xuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lICs9IFwiIGNhcC1idG4tXCIgKyBidG4uc2hhcGU7XG4gICAgICAgICAgICAgICAgICBidG5Db250ZW50ICs9IGA8c3Bhbj4gJHtcbiAgICAgICAgICAgICAgICAgICAgYnRuLmZvcm1hdHRlciA/IGJ0bi5mb3JtYXR0ZXIoYywgYnRuKSA6IFwiXCJcbiAgICAgICAgICAgICAgICAgIH0gPC9zcGFuPiBgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYnRuLmJ0bkNsYXNzTmFtZUZvcm1hdHRlcikge1xuICAgICAgICAgICAgICAgICAgbGV0IG5ld0NsYXNzTmFtZSA9IGJ0bi5idG5DbGFzc05hbWVGb3JtYXR0ZXIoYywgYnRuKTtcbiAgICAgICAgICAgICAgICAgIGlmIChuZXdDbGFzc05hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lICs9IFwiIFwiICsgbmV3Q2xhc3NOYW1lO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJ0bk5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJjYXAtYnRuLXNoYXBlICR7Y2xhc3NOYW1lfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC1rZXk9XCIke2J0bi5rZXkgfHwgXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS1pZD1cIiR7Yy5pZCB8fCAtMX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtpc0Rpc2FibGVkID8gXCJkaXNhYmxlZFwiIDogXCJcIn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtbm9kZT1cIiR7Yy50eXBlIHx8IFwiXCJ9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2J0bkNvbnRlbnR9XG4gICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+YDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnRuTmF2TGlzdCArPSBgXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBsZXQgaXRlbURldGFpbCA9IGAgPGRpdiBjbGFzcz1cImRldGFpbC1uYXYtaXRlbSBoaWRlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICR7dGhpcy5nZXREZXRhaWxOYXZJdGVtQ29udGVudCgpfVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcblxuICAgIGxldCBzdHIgPSBgPGRpdiBjbGFzcz1cIm5hdi1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAke2l0ZW1EZXRhaWx9XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJuYXYtaXRlbS1saXN0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgJHtuYXZMaXN0fVxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImluaXRpYWwtbmF2LWxpc3RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAke2luaXRpYWxOYXZMaXN0fVxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImV4dGVuZC1uYXYtbGlzdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICR7ZXhOYXZMaXN0fVxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcC1idG4tbmF2LWxpc3RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAke2J0bk5hdkxpc3R9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcblxuICAgIGxldCBuYXZDb250YWluZXIgPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKHN0cik7XG4gICAgJGVsZW0uaW5uZXJIVE1MID0gXCJcIjtcbiAgICAkZWxlbS5hcHBlbmQobmF2Q29udGFpbmVyKTtcblxuICAgIC8vZGV0YWxsZSBkZSBuYXYtaXRlbVxuICAgICRlbGVtLnF1ZXJ5U2VsZWN0b3JBbGwoXCIuaXRlbS10aXRsZS5ob3ZlcmFibGVcIikuZm9yRWFjaCgoaSkgPT4ge1xuICAgICAgaS5hZGRFdmVudExpc3RlbmVyKFwibW91c2VvdmVyXCIsIChlKSA9PiB7XG4gICAgICAgIGxldCBwb3MgPSB1dGlscy5ldmVudFRvUG9zaXRpb25OYXZMZWZ0KGNvbmZpZywgZSwgJGVsZW0pO1xuICAgICAgICBsZXQgaXRlbUlkID0gaS5nZXRBdHRyaWJ1dGUoXCJpdGVtLWlkXCIpO1xuICAgICAgICBsZXQgaXRlbSA9IHV0aWxzLmdldEl0ZW1CeUlkKGNvbmZpZywgaXRlbUlkKTtcbiAgICAgICAgbGV0IHR5cGVOb2RlID0gaS5nZXRBdHRyaWJ1dGUoXCJ0eXBlLW5vZGVcIik7XG4gICAgICAgIGkuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoXCJvdmVyTmF2SXRlbVwiLCB7XG4gICAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgICAgb3JpZ2luYWxFdnQ6IGUsXG4gICAgICAgICAgICAgIGl0ZW06IGl0ZW0sXG4gICAgICAgICAgICAgIHR5cGU6IHR5cGVOb2RlLFxuICAgICAgICAgICAgICBwb3M6IHBvcyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy9vY3VsdGEgZGV0YWxsZSBkZSBuYXYtaXRlbSwgYWwgc2FsaXIgZGVsIG5hdi1pdGVtLWxpc3RcbiAgICAkZWxlbS5xdWVyeVNlbGVjdG9yQWxsKFwiLm5hdi1pdGVtLWxpc3RcIikuZm9yRWFjaCgoaSkgPT4ge1xuICAgICAgaS5hZGRFdmVudExpc3RlbmVyKFwibW91c2VsZWF2ZVwiLCAoZSkgPT4ge1xuICAgICAgICBpLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwibGVhdmVOYXZJdGVtXCIsIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvL29jdWx0YSBkZXRhbGxlIGRlIG5hdi1pdGVtLWxpc3QsIGFsIHNhbGlyIGRlIG5hdi1pdGVtXG4gICAgJGVsZW0ucXVlcnlTZWxlY3RvckFsbChcIi5pdGVtLXRpdGxlOm5vdCguaG92ZXJhYmxlKVwiKS5mb3JFYWNoKChpKSA9PiB7XG4gICAgICBpLmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgKGUpID0+IHtcbiAgICAgICAgaS5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgIG5ldyBDdXN0b21FdmVudChcImxlYXZlTmF2SXRlbVwiLCB7XG4gICAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgJGVsZW0ucXVlcnlTZWxlY3RvckFsbChcIi5pdGVtLXRpdGxlLmNsaWNrZWFibGVcIikuZm9yRWFjaCgoaSkgPT4ge1xuICAgICAgaS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgbGV0IGl0ZW1JZCA9IGkuZ2V0QXR0cmlidXRlKFwiaXRlbS1pZFwiKTtcbiAgICAgICAgbGV0IHR5cGVOb2RlID0gaS5nZXRBdHRyaWJ1dGUoXCJ0eXBlLW5vZGVcIik7XG4gICAgICAgIGxldCB2YWx1ZSA9IGkudmFsdWU7XG4gICAgICAgIGkuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoXCJjbGlja05hdkxlZnRJdGVtXCIsIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICBpdGVtSWQ6IGl0ZW1JZCxcbiAgICAgICAgICAgICAgdHlwZTogdHlwZU5vZGUsXG4gICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgJGVsZW0ucXVlcnlTZWxlY3RvckFsbChcIi5tdWx0aWJ1dHRvbnMtYnRuXCIpLmZvckVhY2goKGkpID0+IHtcbiAgICAgIGkuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgIGxldCBwb3MgPSB1dGlscy5ldmVudFRvUG9zaXRpb25OYXZMZWZ0KGNvbmZpZywgZSwgJGVsZW0pO1xuICAgICAgICBsZXQgaXRlbUlkID0gaS5nZXRBdHRyaWJ1dGUoXCJpdGVtLWlkXCIpO1xuICAgICAgICBsZXQgdHlwZU5vZGUgPSBpLmdldEF0dHJpYnV0ZShcInR5cGUtbm9kZVwiKTtcbiAgICAgICAgaS5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgIG5ldyBDdXN0b21FdmVudChcImNsaWNrTXVsdGlCdXR0b25zQnRuXCIsIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICBpdGVtSWQ6IGl0ZW1JZCxcbiAgICAgICAgICAgICAgdHlwZTogdHlwZU5vZGUsXG4gICAgICAgICAgICAgIHBvcyxcbiAgICAgICAgICAgICAgYnV0dG9uOiBpLFxuICAgICAgICAgICAgICBldmVudDogZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgJGVsZW0ucXVlcnlTZWxlY3RvckFsbChcImlucHV0XCIpLmZvckVhY2goKGkpID0+IHtcbiAgICAgIGkuYWRkRXZlbnRMaXN0ZW5lcihcImNoYW5nZVwiLCAoZSkgPT4ge1xuICAgICAgICBsZXQgaW5wdXRUeXBlID0gaS5nZXRBdHRyaWJ1dGUoXCJpbnB1dC10eXBlXCIpO1xuICAgICAgICBsZXQga2V5ID0gaS5nZXRBdHRyaWJ1dGUoXCJpbnB1dC1rZXlcIik7XG4gICAgICAgIGxldCBpdGVtSWQgPSBpLmdldEF0dHJpYnV0ZShcIml0ZW0taWRcIik7XG4gICAgICAgIGxldCB0eXBlTm9kZSA9IGkuZ2V0QXR0cmlidXRlKFwidHlwZS1ub2RlXCIpO1xuICAgICAgICBsZXQgaXRlbSA9IHV0aWxzLmdldEl0ZW1CeUlkKGNvbmZpZywgaXRlbUlkKTtcbiAgICAgICAgbGV0IHZhbHVlID0gaS52YWx1ZTtcbiAgICAgICAgaWYgKGlucHV0VHlwZSA9PSBcInRpbWVcIikge1xuICAgICAgICAgIGxldCBoaF9pbnB1dCA9IGkucGFyZW50RWxlbWVudC5xdWVyeVNlbGVjdG9yKFwiaW5wdXQuaGhcIikudmFsdWU7XG4gICAgICAgICAgbGV0IG1tX2lucHV0ID0gaS5wYXJlbnRFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXCJpbnB1dC5tbVwiKS52YWx1ZTtcbiAgICAgICAgICBtbV9pbnB1dCA9IG1tX2lucHV0IDwgMTAgPyBcIjBcIiArIHBhcnNlRmxvYXQobW1faW5wdXQpIDogbW1faW5wdXQ7XG4gICAgICAgICAgaS5wYXJlbnRFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXCJpbnB1dC5tbVwiKS52YWx1ZSA9IG1tX2lucHV0O1xuICAgICAgICAgIHZhbHVlID0gaGhfaW5wdXQgKyBcIjpcIiArIG1tX2lucHV0O1xuICAgICAgICB9XG4gICAgICAgIGkuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoXCJzYXZlTmF2TGVmdElucHV0XCIsIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgaXRlbUlkOiBpdGVtSWQsXG4gICAgICAgICAgICAgIGl0ZW06IGl0ZW0sXG4gICAgICAgICAgICAgIHR5cGU6IHR5cGVOb2RlLFxuICAgICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICAgIHRhYlNlbGVjdGVkOiB0YWIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgICRlbGVtLnF1ZXJ5U2VsZWN0b3JBbGwoXCJidXR0b24uY2FwLWJ0bi1zaGFwZVwiKS5mb3JFYWNoKChpKSA9PiB7XG4gICAgICBpLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZSkgPT4ge1xuICAgICAgICBsZXQga2V5ID0gaS5nZXRBdHRyaWJ1dGUoXCJpbnB1dC1rZXlcIik7XG4gICAgICAgIGxldCBpdGVtSWQgPSBpLmdldEF0dHJpYnV0ZShcIml0ZW0taWRcIik7XG4gICAgICAgIGxldCB0eXBlTm9kZSA9IGkuZ2V0QXR0cmlidXRlKFwidHlwZS1ub2RlXCIpO1xuICAgICAgICBpLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwiY2xpY2tOYXZMZWZ0QnV0dG9uXCIsIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgaXRlbUlkOiBpdGVtSWQsXG4gICAgICAgICAgICAgIHR5cGU6IHR5cGVOb2RlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAkZWxlbS5xdWVyeVNlbGVjdG9yQWxsKFwiYnV0dG9uLmRldGFpbC1idG5cIikuZm9yRWFjaCgoaSkgPT4ge1xuICAgICAgaS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgbGV0IGl0ZW1JZCA9IGkuZ2V0QXR0cmlidXRlKFwiaXRlbS1pZFwiKTtcbiAgICAgICAgbGV0IHR5cGVOb2RlID0gaS5nZXRBdHRyaWJ1dGUoXCJ0eXBlLW5vZGVcIik7XG4gICAgICAgIGxldCBpdGVtID0gdXRpbHMuZ2V0SXRlbUJ5SWQoY29uZmlnLCBpdGVtSWQsIFwicGFyZW50XCIpO1xuXG4gICAgICAgIGlmIChpdGVtICYmIGl0ZW0ub25DbGlja0RldGFpbEJ1dHRvbikge1xuICAgICAgICAgIGl0ZW0ub25DbGlja0RldGFpbEJ1dHRvbih7XG4gICAgICAgICAgICBpdGVtSWQ6IGl0ZW1JZCxcbiAgICAgICAgICAgIHR5cGU6IHR5cGVOb2RlLFxuICAgICAgICAgICAgaXRlbTogaXRlbSxcbiAgICAgICAgICAgIGV2ZW50OiBlLFxuICAgICAgICAgICAgYnV0dG9uOiBpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgICRlbGVtLnF1ZXJ5U2VsZWN0b3JBbGwoXCJidXR0b24udHJlZS1pY29uXCIpLmZvckVhY2goKGkpID0+IHtcbiAgICAgIGkuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgIGxldCBpdGVtSWQgPSBpLmdldEF0dHJpYnV0ZShcIml0ZW0taWRcIik7XG4gICAgICAgIGxldCB0eXBlTm9kZSA9IGkuZ2V0QXR0cmlidXRlKFwidHlwZS1ub2RlXCIpO1xuICAgICAgICBsZXQgZGF0YUNvbmZpZyA9IGNvbmZpZy5kYXRhLmZpbmQoKGQpID0+IGQuaWQgPT0gaXRlbUlkKTtcblxuICAgICAgICBsZXQgJG5hdkl0ZW0gPSBlLmN1cnJlbnRUYXJnZXQuY2xvc2VzdChcIi5uYXYtaXRlbVwiKTtcbiAgICAgICAgbGV0ICRjaGlsZHJlbiA9ICRuYXZJdGVtLnF1ZXJ5U2VsZWN0b3IoXCIuY2hpbGRyZW4taXRlbXNcIik7XG4gICAgICAgIGxldCBpdGVtc1RvSGlkZSA9IGUuY3VycmVudFRhcmdldFxuICAgICAgICAgIC5jbG9zZXN0KFwibmF2LmxlZnRcIilcbiAgICAgICAgICAucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgICAgIFwiW2NoaWxkPSdcIiArIGl0ZW1JZCArIFwiJ10sIFtjaGlsZC1saXN0PSdcIiArIGl0ZW1JZCArIFwiJ11cIlxuICAgICAgICAgICk7XG5cbiAgICAgICAgaWYgKCRjaGlsZHJlbikge1xuICAgICAgICAgIGlmICgkY2hpbGRyZW4uY2xhc3NMaXN0LmNvbnRhaW5zKFwiaGlkZVwiKSkge1xuICAgICAgICAgICAgZS5jdXJyZW50VGFyZ2V0LmNsYXNzTGlzdC5hZGQoXCJjYXAtcm90YXRlXCIpO1xuICAgICAgICAgICAgaXRlbXNUb0hpZGUuZm9yRWFjaCgoaSkgPT4gaS5jbGFzc0xpc3QucmVtb3ZlKFwiaGlkZVwiKSk7XG4gICAgICAgICAgICBkYXRhQ29uZmlnLmlzQ2xvc2VkID0gZmFsc2U7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGUuY3VycmVudFRhcmdldC5jbGFzc0xpc3QucmVtb3ZlKFwiY2FwLXJvdGF0ZVwiKTtcbiAgICAgICAgICAgIGl0ZW1zVG9IaWRlLmZvckVhY2goKGkpID0+IGkuY2xhc3NMaXN0LmFkZChcImhpZGVcIikpO1xuICAgICAgICAgICAgZGF0YUNvbmZpZy5pc0Nsb3NlZCA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaS5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgIG5ldyBDdXN0b21FdmVudChcImNsaWNrTmF2TGVmdFRyZWVJY29uXCIsIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICBpdGVtSWQ6IGl0ZW1JZCxcbiAgICAgICAgICAgICAgdHlwZTogdHlwZU5vZGUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG5cbiAgICAgICAgLy9lLmN1cnJlbnRUYXJnZXQucGFyZW50XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJldHVybiAkZWxlbTtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBIdG1sIGNvbW8gU3RyaW5nLCBwYXJhIGVsIGRldGFsbGUgZGUgaXRlbXMgZW4gZWwgU2lkZWJhciBJenF1aWVyZG9cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IFtpdGVtPXt9XSAtIENvbmZpZ3VyYWNpb24gZGUgaXRlbVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IEh0bWwgZGUgdmVudGFuYSBkZSBkZXRhbGxlXG4gICAqL1xuICBnZXREZXRhaWxOYXZJdGVtQ29udGVudChpdGVtID0ge30pIHtcbiAgICBpZiAoaXRlbS5uYXZPdmVyID09IHVuZGVmaW5lZCkgaXRlbS5uYXZPdmVyID0ge307XG5cbiAgICByZXR1cm4gYFxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZGVyLWRldGFpbFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWwtdGl0bGUgdHJ1bmNhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICR7aXRlbS5sYWJlbCB8fCBcIlwifVxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWwtc3VidGl0bGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICR7aXRlbS5uYXZPdmVyLnN1YnRpdGxlIHx8IFwiXCJ9XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhlYWRlci1jaGlwICR7XG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtLmxpZ2h0ID8gaXRlbS5saWdodCArIFwiLWxpZ2h0XCIgOiBcIlwiXG4gICAgICAgICAgICAgICAgICAgICAgfSAgJHtpdGVtLm5hdk92ZXIuY2hpcCA/IFwiXCIgOiBcImhpZGVcIn1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICR7aXRlbS5uYXZPdmVyLmNoaXAgfHwgXCJcIn1cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAke2l0ZW0ubmF2T3Zlci5jb250ZW50IHx8IFwiXCJ9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgU2lkZWJhciBEZXJlY2hvXG4gICAqIFVzYWRvIHByaW5jaXBhbG1lbnRlIHBhcmEgZm9ybXVsYXJpbyBkZSBpbmdyZXNvIGRlIGRhdG9zIHBhcmEgbG9zIGRpYXNcbiAgICogc2VsZWNjaW9uYWRvc1xuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gQ29uZmlndXJhY2lvbiBjYXBpYmFyYVxuICAgKiBAcGFyYW0ge09iamVjdH0gdGFiIC0gVGFiIGRlIHJlZmVyZW5jaWEsIHBhcmEgbGEgY3JlYWNpb24gZGVsIGZvcm11bGFyaW9cbiAgICogQHJldHVybiB7T2JqZWN0fSB7ZWxlbWVudCwgaW5wdXRzfSwgZWxlbWVudCBlcyBlbCBlbGVtZW50byBEb20gZGVsIHNpZGViYXIsXG4gICAqICAgICAgICAgICAgICAgICAgaW5wdXRzIGVzIHVuIGFycmF5IGRlIGVsZW1lbnRvcyBEb20gZGUgY2FkYSBpbnB1dCBjcmVhZG9cbiAgICogICAgICAgICAgICAgICAgICAobm8gc29uIGVsZW1lbnRvcyBodG1sIGRlIHRpcG8gaW5wdXQpXG4gICAqL1xuICBjcmVhdGVOYXZSaWdodChjb25maWcsIHRhYiA9IG51bGwpIHtcbiAgICB2YXIgJGVsZW0gPSBkb20uY3JlYXRlRWxlbWVudChcIm5hdlwiLCB7IGNsYXNzTmFtZTogXCJyaWdodFwiIH0pO1xuICAgIHJldHVybiB0aGlzLnJlZHJhd05hdlJpZ2h0KGNvbmZpZywgJGVsZW0sIHRhYiwgbnVsbCwgW10sIG51bGwpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZWNyZWEgU2lkZWJhciBEZXJlY2hvXG4gICAqIFV0aWxpemEgJGVsZW0gY29tbyBlbGVtZW50byBkb20gZG9uZGUgcmVjcmVhcmxvXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgLSBDb25maWd1cmFjaW9uIGNhcGliYXJhXG4gICAqIEBwYXJhbSB7T2JqZWN0fSAkZWxlbSAtIEVsZW1lbnRvIERvbSBkb25kZSBjcmVhIGVsIHNpZGViYXIgZGVyZWNob1xuICAgKiBAcGFyYW0ge09iamVjdH0gdGFiIC0gVGFiIGRlIHJlZmVyZW5jaWEsIHBhcmEgbGEgY3JlYWNpb24gZGVsIGZvcm11bGFyaW9cbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGFEYXkgLSBkYXRvcyBkZWwgZGlhIHNlbGVjY2lvbmFuZG8sIHBhcmEgYXV0b3JyZWxsZW5vIGRlIGZvcm11bGFyaW9cbiAgICogQHBhcmFtIHtPYmplY3R9IGRheVNlbGVjdGVkIC0gZGF0b3MgZGVsIGRpYSBzZWxlY2Npb25hZG9cbiAgICogQHBhcmFtIHtTdHJpbmd9IGRheVNlbGVjdGVkLmRhdGUgLSBmZWNoYSBkZWwgZGlhIHNlbGVjY2lvbmFkb1xuICAgKiBAcGFyYW0ge09iamVjdH0gZGF5U2VsZWN0ZWQuaXRlbSAtIEl0ZW0gZGUgU2lkZWJhciByZWxhY2lvbmFkbyBhbCBkaWEgc2VsZWNjaW9uYWRvXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkYXlTZWxlY3RlZC5wb3MgLSBwb3NpY2lvbiBkZSBkaWEgc2VsZWNjaW9uYWRvXG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tIFNpZGViYXIgRGVyZWNob1xuICAgKi9cbiAgcmVkcmF3TmF2UmlnaHQoXG4gICAgY29uZmlnLFxuICAgICRlbGVtLFxuICAgIHNlbGVjdGVkID0gbnVsbCxcbiAgICB0YWIgPSBudWxsLFxuICAgIGRhdGFEYXkgPSBudWxsLFxuICAgIGRheVNlbGVjdGVkID0gbnVsbFxuICApIHtcbiAgICBsZXQgJG5hdlJpZ2h0ID0gJGVsZW07IC8vZG9tLmNyZWF0ZUVsZW1lbnQoXCJuYXZcIix7Y2xhc3NOYW1lOlwicmlnaHRcIn0pO1xuICAgIGxldCAkZGl2Q29udGFpbmVyID0gZG9tLmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgICAgY2xhc3NOYW1lOiBcIm5hdi1pbnB1dC1jb250YWluZXJcIixcbiAgICB9KTtcbiAgICBsZXQgJGlucHV0cyA9IFtdO1xuICAgIGxldCBjaGVja2JveElucHV0cyA9IFtdO1xuICAgIGxldCBpbnB1dHNXaXRoUmVsb2FkID0gW107XG4gICAgbGV0IHRhYlNlbGVjdGVkID0gdGFiO1xuICAgIHNlbGVjdGVkID0gc2VsZWN0ZWQgfHwgW2RheVNlbGVjdGVkXTtcblxuICAgIGlmICh0YWJTZWxlY3RlZCAmJiB0YWJTZWxlY3RlZC5pbnB1dHMpIHtcbiAgICAgIHRhYlNlbGVjdGVkLmlucHV0cy5mb3JFYWNoKChpKSA9PiB7XG4gICAgICAgIGlmIChpLmRpc2FibGVkKSByZXR1cm47XG4gICAgICAgIGlmIChcbiAgICAgICAgICBpLnNob3dJbnB1dElmICYmXG4gICAgICAgICAgIWkuc2hvd0lucHV0SWYoZGF0YURheSwgZGF5U2VsZWN0ZWQsIHNlbGVjdGVkLCB0YWJTZWxlY3RlZClcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0ICRpbnB1dCA9IHRoaXMuY3JlYXRlSW5wdXQoXG4gICAgICAgICAgaSxcbiAgICAgICAgICBkYXRhRGF5LFxuICAgICAgICAgIGRheVNlbGVjdGVkLFxuICAgICAgICAgIHNlbGVjdGVkLFxuICAgICAgICAgIHRhYlNlbGVjdGVkXG4gICAgICAgICk7XG4gICAgICAgIGlmICgkaW5wdXQpIHtcbiAgICAgICAgICAkZGl2Q29udGFpbmVyLmFwcGVuZENoaWxkKCRpbnB1dCk7XG4gICAgICAgICAgJGlucHV0cy5wdXNoKCRpbnB1dCk7XG5cbiAgICAgICAgICBpZiAoaS50eXBlID09IFwiY2hlY2tib3hcIikge1xuICAgICAgICAgICAgY2hlY2tib3hJbnB1dHMucHVzaCgkaW5wdXQpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChpLnJlbG9hZE9uU2VsZWN0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlucHV0c1dpdGhSZWxvYWQucHVzaCh7ICRpbnB1dCwgY29uZmlnOiBpIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy9tYW5lam8gZGUgZXZlbnRvcyBwYXJhIGlucHV0cyBjb24gc2hvd0lmXG4gICAgaWYgKGNoZWNrYm94SW5wdXRzKSB7XG4gICAgICBjaGVja2JveElucHV0cy5mb3JFYWNoKCgkYykgPT4ge1xuICAgICAgICAvL29idGllbmUga2V5IGRlIGNoZWNrYm94XG4gICAgICAgIGxldCBrZXkgPSAkYy5nZXRBdHRyaWJ1dGUoXCJpbnB1dC1rZXlcIik7XG4gICAgICAgIGxldCBwcm9wcyA9IHRhYlNlbGVjdGVkLmlucHV0cy5maW5kKChpKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGkua2V5ID09IGtleTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbGV0IGlzQ2hlY2tlZCA9IGZhbHNlO1xuICAgICAgICBpZiAoZGF0YURheSkge1xuICAgICAgICAgIGlzQ2hlY2tlZCA9IHV0aWxzLmdldFZhckJ5UGF0aChkYXRhRGF5LCBwcm9wcy52YXJOYW1lKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vb2J0aWVuZSBpbnB1dHMgcmVsYWNpb25hZG9zIGRlc2RlIGNvbmZpZyBwYXJhIG1vc3RyYXIvb2N1bHRhclxuICAgICAgICBsZXQgaW5wdXRzVG9IaWRlID0gdGFiU2VsZWN0ZWQuaW5wdXRzLmZpbHRlcigoaSkgPT4ge1xuICAgICAgICAgIHJldHVybiBpLnNob3dJZiAmJiBpLnNob3dJZiA9PSBrZXk7XG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgaW5wdXRzVG9IaWRlS2V5cyA9IGlucHV0c1RvSGlkZS5tYXAoKGkpID0+IGkua2V5KTtcblxuICAgICAgICAvL29idGllbmUgaW5wdXRzIGRlbCBkb20sIGZpbHRyYW5kbyBjb24gaW5wdXRzVG9IaWRlXG4gICAgICAgIGxldCAkaW5wdXRzSGlkZGVuID0gJGlucHV0cy5maWx0ZXIoKCRpKSA9PiB7XG4gICAgICAgICAgbGV0IGlucHV0S2V5ID0gJGkuZ2V0QXR0cmlidXRlKFwiaW5wdXQta2V5XCIpO1xuICAgICAgICAgIHJldHVybiBpbnB1dHNUb0hpZGVLZXlzLmluZGV4T2YoaW5wdXRLZXkpID4gLTE7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vc2kgaGF5IGlucHV0cyxcbiAgICAgICAgaWYgKCRpbnB1dHNIaWRkZW4pIHtcbiAgICAgICAgICBpZiAoIWlzQ2hlY2tlZCkge1xuICAgICAgICAgICAgJGlucHV0c0hpZGRlbi5mb3JFYWNoKCgkaSkgPT4ge1xuICAgICAgICAgICAgICAkaS5jbGFzc0xpc3QuYWRkKFwiaGlkZVwiKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICAkYy5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIiwgKGUpID0+IHtcbiAgICAgICAgICAgICRpbnB1dHNIaWRkZW4uZm9yRWFjaCgoJGkpID0+IHtcbiAgICAgICAgICAgICAgbGV0IGZuID0gJGMucXVlcnlTZWxlY3RvcihcImlucHV0W3R5cGU9J2NoZWNrYm94J11cIikuY2hlY2tlZFxuICAgICAgICAgICAgICAgID8gXCJyZW1vdmVcIlxuICAgICAgICAgICAgICAgIDogXCJhZGRcIjtcbiAgICAgICAgICAgICAgJGkuY2xhc3NMaXN0W2ZuXShcImhpZGVcIik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbGV0IHNhdmVDYW5jZWxCdG5zID0gdGhpcy5jcmVhdGVOYXZSaWdodGJ1dHRvbnMoY29uZmlnKTtcbiAgICAkZGl2Q29udGFpbmVyLmFwcGVuZENoaWxkKHNhdmVDYW5jZWxCdG5zKTtcbiAgICAkbmF2UmlnaHQuaW5uZXJIVE1MID0gXCJcIjtcbiAgICAkbmF2UmlnaHQuYXBwZW5kQ2hpbGQoJGRpdkNvbnRhaW5lcik7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZWxlbWVudDogJG5hdlJpZ2h0LFxuICAgICAgaW5wdXRzOiAkaW5wdXRzLFxuICAgICAgaW5wdXRzV2l0aFJlbG9hZCxcbiAgICAgIHNhdmVDYW5jZWxCdG5zLFxuICAgIH07XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgQ29ybmVyIGluZmVyaW9yIGl6cXVpZXJkbywgY29tbyB0aXR1bG8gcGFyYSBmb290ZXJcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gQ29ybmVyIEZvb3RlclxuICAgKi9cbiAgY3JlYXRlQ29ybmVyRm9vdGVyKGNvbmZpZykge1xuICAgIGlmIChcbiAgICAgIGNvbmZpZy50aW1lbGluZS5mb290ZXIgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgY29uZmlnLnRpbWVsaW5lLmZvb3Rlci5lbmFibGVkID09IGZhbHNlXG4gICAgKVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgbGV0IHN0ciA9IFwiXCI7XG5cbiAgICBpZiAoY29uZmlnLnRpbWVsaW5lLmZvb3Rlcikge1xuICAgICAgc3RyICs9IGA8ZGl2IGNsYXNzPVwiY29ybmVyLWZvb3RlclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb3JuZXItdGl0bGVcIj5cbiAgICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgICAke2NvbmZpZy50aW1lbGluZS5mb290ZXIubGFiZWx9XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PmA7XG4gICAgfVxuICAgIHJldHVybiBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKHN0cik7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgRm9vdGVyIHBhcmEgcGxhbmlsbGFcbiAgICogSW5pY2lhbG1lbnRlIGNyZWFkbyBwYXJhIHRvdGFsZXNcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gQ29ybmVyIEZvb3RlclxuICAgKi9cbiAgY3JlYXRlRm9vdGVyKGNvbmZpZykge1xuICAgIGlmIChcbiAgICAgIGNvbmZpZy50aW1lbGluZS5mb290ZXIgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgY29uZmlnLnRpbWVsaW5lLmZvb3Rlci5lbmFibGVkID09IGZhbHNlXG4gICAgKVxuICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICBsZXQgc3RyID0gYFxuICAgICAgICA8Zm9vdGVyPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb290ZXItY29udGFpbmVyXCI+XG4gICAgICAgICAgYDtcbiAgICBjb25maWcudGltZWxpbmUuZm9vdGVyLmRhdGEuZm9yRWFjaCgoZCkgPT4ge1xuICAgICAgc3RyICs9IGBcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvb3Rlci1pdGVtXCI+JHtkLnZhbHVlfTwvZGl2PlxuICAgICAgICAgICAgYDtcbiAgICB9KTtcbiAgICBzdHIgKz0gYFxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Zvb3Rlcj5cbiAgICAgICAgYDtcblxuICAgIHJldHVybiBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKHN0cik7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgRm9vdGVyIHBhcmEgcGxhbmlsbGFcbiAgICogSW5pY2lhbG1lbnRlIGNyZWFkbyBwYXJhIHRvdGFsZXNcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHBhcmFtIHtPYmplY3RbXX0gc2VsZWN0ZWQgLSBhcnJheSBkZSBvYmpldG9zLCBkZSBkaWFzIHNlbGVjY2lvbmFkb3NcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gQ29ybmVyIEZvb3RlclxuICAgKi9cbiAgY3JlYXRlU2VsZWN0Qm9hcmQoY29uZmlnLCBzZWxlY3RlZCkge1xuICAgIGxldCAkZWxlbSA9IGRvbS5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsgY2xhc3NOYW1lOiBcInNlbGVjdC1jb250YWluZXJcIiB9KTtcbiAgICByZXR1cm4gdGhpcy5yZWRyYXdTZWxlY3RCb2FyZCgkZWxlbSwgc2VsZWN0ZWQpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhIGxpbmVhIHZlcnRpY2FsIHBhcmEgZmVjaGEgQWN0dWFsXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgLSBDb25maWd1cmFjaW9uIGNhcGliYXJhXG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tIENvcm5lciBGb290ZXJcbiAgICovXG4gIGNyZWF0ZVRvZGF5TGluZShjb25maWcpIHtcbiAgICByZXR1cm4gdGhpcy5yZWRyYXdUb2RheUxpbmUoXG4gICAgICBjb25maWcsXG4gICAgICBkb20uY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJ0b2RheS1saW5lXCIgfSlcbiAgICApO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZWNyZWEgbGluZWEgdmVydGljYWwgcGFyYSBmZWNoYSBBY3R1YWxcbiAgICogc2kgZWwgZWxlbWVudG8gJGVsZW0gbm8gZXMgZW52aWFkbywgc2UgY3JlYSB1biBudWV2byBlbGVtZW50b1xuICAgKlxuICAgKiBTaSBlbCBkaWEgYWN0dWFsIG5vIGVzdGEgZGVudHJvIGRlbCByYW5nbyBkZSBmZWNoYXMgZGVsIGNvbmZpZyxcbiAgICogZGVzaGFiaWxpdGEgbGEgbGluZWEgY29uIGxhIGNsYXNlIGNzcyAuZGlzYWJsZS1saW5lXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgLSBDb25maWd1cmFjaW9uIGNhcGliYXJhXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbJGVsZW09bnVsbF0gLSBFbGVtZW50byBEb20gZG9uZGUgcmVjcmVhIGxhIGxpbmVhLCBzaSBlcyBudWxsLCBsYSBjcmVhXG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tIENvcm5lciBGb290ZXJcbiAgICovXG4gIHJlZHJhd1RvZGF5TGluZShjb25maWcsICRlbGVtID0gbnVsbCkge1xuICAgIGxldCBlbmRUaW1lID0gbmV3IERhdGUoY29uZmlnLnRpbWVsaW5lLmVuZCkuZ2V0VGltZSgpO1xuICAgIGxldCB0b2RheVRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICBsZXQgeyBoZWlnaHQsIGRheVdpZHRoIH0gPSB1dGlscy5nZXRUYWJsZURpbWVuc2lvbnMoY29uZmlnKTtcblxuICAgIGlmICgkZWxlbSA9PSBudWxsKVxuICAgICAgJGVsZW0gPSBkb20uY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJ0b2RheS1saW5lXCIgfSk7XG5cbiAgICBpZiAoZW5kVGltZSA8IHRvZGF5VGltZSkge1xuICAgICAgJGVsZW0uY2xhc3NMaXN0LmFkZChcImRpc2FibGUtbGluZVwiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgJGVsZW0uY2xhc3NMaXN0LnJlbW92ZShcImRpc2FibGUtbGluZVwiKTtcbiAgICB9XG5cbiAgICBsZXQgZGlmZkRheXMgPSBNYXRoLmZsb29yKFxuICAgICAgZGF0ZVV0aWxzLmRpZmZEYXlzKFxuICAgICAgICBjb25maWcudGltZWxpbmUuc3RhcnQsXG4gICAgICAgIGRhdGVVdGlscy5mb3JtYXREYXRlKG5ldyBEYXRlKCkpXG4gICAgICApXG4gICAgKTtcbiAgICBsZXQgZGlmZiA9IGRpZmZEYXlzICogZGF5V2lkdGg7XG4gICAgZGlmZiArPSBkYXlXaWR0aCAvIDIgLSAyOyAvLyBwYXJhIGNlbnRyYXIgbGluZWFcbiAgICBPYmplY3QuYXNzaWduKCRlbGVtLnN0eWxlLCB7XG4gICAgICBcIm1hcmdpbi1sZWZ0XCI6IGRpZmYgKyBcInB4XCIsXG4gICAgICBoZWlnaHQ6IGhlaWdodCArIFwicHhcIixcbiAgICB9KTtcbiAgICByZXR1cm4gJGVsZW07XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgZWxlbWVudG8gRmxvYXRCb3gsIHF1ZSBjb250aWVuZSBsb3MgZGF0b3MgcXVlIHNlIG11ZXN0cmEgZW4gbGEgdGFibGFcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHBhcmFtIHtPYmplY3R9IHRhYiAtIFRhYiBkZSByZWZlcmVuY2lhLCBwYXJhIG1vc3RyYXIgZGF0b3MgY29uZmlndXJhZG9zIHBvciB0YWJcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gQ29ybmVyIEZvb3RlclxuICAgKi9cbiAgY3JlYXRlRmxvYXRCb3goY29uZmlnLCB0YWIpIHtcbiAgICBsZXQgJGNvbnRhaW5lciA9IGRvbS5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICAgIGNsYXNzTmFtZTogXCJmbG9hdC1ib3gtY29udGFpbmVyXCIsXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMucmVkcmF3RmxvYXRCb3goY29uZmlnLCB0YWIsICRjb250YWluZXIpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZWNyZWEgZWxlbWVudG8gRmxvYXRCb3gsIHF1ZSBjb250aWVuZSBsb3MgZGF0b3MgcXVlIHNlIG11ZXN0cmEgZW4gbGEgdGFibGFcbiAgICogU2UgdXNhIHByaW5jaXBhbG1lbnRlIHBhcmEgbW9zdHJhciBkYXRvcyBlbiBsYSB0YWJsYSBkZSBsYSBwbGFuaWxsYVxuICAgKiBsb3MgbXVlc3RyYSBkZSBtYW5lcmEgZmxvdGFudGUsIGNhbGN1bGFuZG8gZWwgVG9wIHkgZWwgTGVmdCBzZWd1biBsYSBwb3NjaW9uXG4gICAqXG4gICAqIFNlIGNvbnNpZGVyYW4gbG9zIGVsZW1lbnRvcyBwYWRyZXMgb2N1bHRvcywgcGFyYSBvY3VsdGFyIGxvcyBkYXRvc1xuICAgKlxuICAgKiBTZSBpbnNlcnRhbiBsb3MgZWxlbWVudG9zIEZsb2F0Qm94LCBjb21vIGVsZW1lbnRvIGNvbiBkYXRvcyBkZSB1biBpdGVtIHkgZGlhIGVzcGVjaWZpY29cbiAgICpcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHBhcmFtIHtPYmplY3R9IHRhYiAtIFRhYiBkZSByZWZlcmVuY2lhLCBwYXJhIG1vc3RyYXIgZGF0b3MgY29uZmlndXJhZG9zIHBvciB0YWJcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gQ29ybmVyIEZvb3RlclxuICAgKi9cbiAgcmVkcmF3RmxvYXRCb3goY29uZmlnLCB0YWIsICRjb250YWluZXIpIHtcbiAgICAkY29udGFpbmVyLmlubmVySFRNTCA9IFwiXCI7XG4gICAgLy9sZXQgdGFiU2VsZWN0ZWQgPSB0YWIgfHwgbnVsbDtcblxuICAgIGNvbmZpZy5kYXRhLmZvckVhY2goKGRhdGFQYXJlbnQpID0+IHtcbiAgICAgIGlmIChkYXRhUGFyZW50LmlzSGlkZGVuKSByZXR1cm47XG5cbiAgICAgIChkYXRhUGFyZW50LmRhdGEgfHwgW10pLmZvckVhY2goKGRhdGEpID0+IHtcbiAgICAgICAgdGhpcy5jcmVhdGVGbG9hdEJveEl0ZW0oe1xuICAgICAgICAgIGNvbnRhaW5lcjogJGNvbnRhaW5lcixcbiAgICAgICAgICBkYXRhLFxuICAgICAgICAgIGl0ZW06IGRhdGFQYXJlbnQsXG4gICAgICAgICAgaXNDbG9zZWQ6IGRhdGFQYXJlbnQuaXNDbG9zZWQsXG4gICAgICAgICAgdGFiLFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICB0eXBlTm9kZTogXCJwYXJlbnRcIixcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGF0YVBhcmVudC5jaGlsZHJlbi5mb3JFYWNoKChkYXRhQ2hpbGQpID0+IHtcbiAgICAgICAgaWYgKGRhdGFDaGlsZC5pc0hpZGRlbikgcmV0dXJuO1xuXG4gICAgICAgIGRhdGFDaGlsZC5kYXRhLmZvckVhY2goKGRhdGEpID0+IHtcbiAgICAgICAgICB0aGlzLmNyZWF0ZUZsb2F0Qm94SXRlbSh7XG4gICAgICAgICAgICBjb250YWluZXI6ICRjb250YWluZXIsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgaXRlbTogZGF0YUNoaWxkLFxuICAgICAgICAgICAgaXNDbG9zZWQ6IGRhdGFQYXJlbnQuaXNDbG9zZWQsXG4gICAgICAgICAgICB0YWIsXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICB0eXBlTm9kZTogXCJjaGlsZFwiLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuICRjb250YWluZXI7XG4gIH0sXG5cbiAgY3JlYXRlRmxvYXRCb3hJdGVtKHtcbiAgICBjb250YWluZXIsXG4gICAgZGF0YSxcbiAgICBpdGVtLFxuICAgIGlzQ2xvc2VkLFxuICAgIHRhYixcbiAgICBjb25maWcsXG4gICAgdHlwZU5vZGUgPSBcImNoaWxkXCIsXG4gIH0pIHtcbiAgICBpZiAoXG4gICAgICAoIWRhdGEubWVzc2FnZSB8fCBkYXRhLm1lc3NhZ2UudmFsdWUgPT0gbnVsbCkgJiZcbiAgICAgIChkYXRhLnZhbHVlcyA9PSBudWxsIHx8XG4gICAgICAgIGRhdGEudmFsdWVzID09IHVuZGVmaW5lZCB8fFxuICAgICAgICBPYmplY3QuZW50cmllcyhkYXRhLnZhbHVlcykubGVuZ3RoID09PSAwKVxuICAgICkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy9jaGlsZHJlbiBEYXRhXG4gICAgbGV0IHBvc2l0aW9uID0gdGhpcy5nZXRQb3NpdGlvbkZsb2F0Qm94KGNvbmZpZywgZGF0YSwgaXRlbSwgdHlwZU5vZGUpO1xuXG4gICAgbGV0IGNsYXNzTmFtZSA9IFwiXCI7XG4gICAgbGV0IGhhc01lc3NhZ2UgPSBmYWxzZTtcblxuICAgIGlmIChkYXRhLmVycm9ycyAmJiBkYXRhLmVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICBjbGFzc05hbWUgKz0gXCJoYXMtZXJyb3JzIFwiO1xuICAgICAgaWYgKGRhdGEuZXJyb3JzWzBdKSB7XG4gICAgICAgIGNsYXNzTmFtZSArPSBkYXRhLmVycm9yc1swXS5jbGFzc05hbWVJY29uICsgXCIgXCI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlzQ2xvc2VkKSB7XG4gICAgICBjbGFzc05hbWUgKz0gXCJoaWRlIFwiO1xuICAgIH1cblxuICAgIGxldCBtc2cgPSBudWxsO1xuICAgIGlmICh0YWIuZmxvYXRCb3ggJiYgdGFiLmZsb2F0Qm94Lm1lc3NhZ2VQYXRoKSB7XG4gICAgICBtc2cgPSB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YSwgdGFiLmZsb2F0Qm94Lm1lc3NhZ2VQYXRoKTtcbiAgICB9XG5cbiAgICBpZiAobXNnIHx8IChkYXRhLm1lc3NhZ2UgJiYgZGF0YS5tZXNzYWdlLnZhbHVlKSkge1xuICAgICAgY2xhc3NOYW1lICs9IFwiaGFzLW1lc3NhZ2UgXCI7XG4gICAgICBoYXNNZXNzYWdlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBsZXQgc3RyTXNnID0gXCJcIjtcbiAgICBpZiAoaGFzTWVzc2FnZSkge1xuICAgICAgbGV0IHZpZXdCb3ggPSBcIjAgMCAyNCAyNFwiO1xuICAgICAgLy9lbWFpbCBvdXRsaW5lIGljb25cbiAgICAgIGxldCBpY29uID1cbiAgICAgICAgXCJNMjIgNkMyMiA0LjkgMjEuMSA0IDIwIDRINEMyLjkgNCAyIDQuOSAyIDZWMThDMiAxOS4xIDIuOSAyMCA0IDIwSDIwQzIxLjEgMjAgMjIgMTkuMSAyMiAxOFY2TTIwIDZMMTIgMTFMNCA2SDIwTTIwIDE4SDRWOEwxMiAxM0wyMCA4VjE4WlwiO1xuXG4gICAgICBzdHJNc2cgPSBgXG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpY29uLW1lc3NhZ2VcIj5cbiAgICAgICAgICAgICAgICA8c3ZnIHZpZXdCb3g9XCIke3ZpZXdCb3h9XCI+XG4gICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiJHtpY29ufVwiIC8+XG4gICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgYDtcbiAgICB9XG5cbiAgICBsZXQgc3RyID0gYFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbG9hdC1ib3ggJHtjbGFzc05hbWV9IFwiXG4gICAgICAgICAgICAgICAgICAgICBzdHlsZT1cIiR7cG9zaXRpb24gPyBwb3NpdGlvbiA6IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgIGl0ZW0taWQ9XCIke2l0ZW0uaWQgfHwgLTF9XCJcbiAgICAgICAgICAgICAgICAgICAgIHR5cGUtbm9kZT1cIiR7aXRlbS50eXBlIHx8IFwiXCJ9XCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICR7c3RyTXNnfVxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsb2F0LWJveC1jb250ZW50XCI+YDtcblxuICAgIGxldCBzdHJFeHQgPSBgXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsb2F0LWJveC1leHQgJHtpc0Nsb3NlZCA/IFwiaGlkZVwiIDogXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgIHN0eWxlPVwiJHtwb3NpdGlvbiA/IHBvc2l0aW9uIDogXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgIGl0ZW0taWQ9XCIke2l0ZW0uaWQgfHwgLTF9LWV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgdHlwZS1ub2RlPVwiJHtpdGVtLnR5cGUgfHwgXCJcIn1cIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsb25nLWJhci1jb250YWluZXJcIj5gO1xuXG4gICAgaWYgKHRhYiAmJiB0YWIuZmxvYXRCb3gpIHtcbiAgICAgIGlmICh0YWIuZmxvYXRCb3gucGxvdHMpIHtcbiAgICAgICAgc3RyICs9IGA8ZGl2IGNsYXNzPVwicGxvdC1mbG9hdGJveC1jb250YWluZXJcIj5gO1xuICAgICAgICB0YWIuZmxvYXRCb3gucGxvdHMuZm9yRWFjaCgobikgPT4ge1xuICAgICAgICAgIGxldCBjc3NWYXJzID0gXCJcIjtcbiAgICAgICAgICBsZXQgY2xhc3NOYW1lID0gXCJcIjtcbiAgICAgICAgICBpZiAodXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGEudmFsdWVzLCBuLnZhck5hbWUpICE9PSBudWxsKSB7XG4gICAgICAgICAgICBpZiAobi5jb2xvcikge1xuICAgICAgICAgICAgICBjc3NWYXJzID0gYC0tbG9jYWwtY29sb3I6JHtuLmNvbG9yfTtgO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjbGFzc05hbWUgPSBuLmNsYXNzTmFtZSB8fCBcIlwiO1xuXG4gICAgICAgICAgICBzdHIgKz0gYDxkaXYgY2xhc3M9XCJwbG90LWZsb2F0Ym94ICR7Y2xhc3NOYW1lfSAke1xuICAgICAgICAgICAgICBuLnN0eWxlIHx8IFwiXCJcbiAgICAgICAgICAgIH1cIiBzdHlsZT1cIiR7Y3NzVmFyc30gXCI+PC9kaXY+YDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBzdHIgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgIH1cblxuICAgICAgaWYgKHRhYi5mbG9hdEJveC5pY29ucykge1xuICAgICAgICB0YWIuZmxvYXRCb3guaWNvbnMuZm9yRWFjaCgoaWNvbkNvbmZpZykgPT4ge1xuICAgICAgICAgIGxldCBjbGFzc05hbWUgPSBcIlwiO1xuICAgICAgICAgIGxldCBjb2xvckNsYXNzID0gXCJcIjtcbiAgICAgICAgICBsZXQgY29sb3JTdHlsZSA9IFwiXCI7XG4gICAgICAgICAgbGV0IHZpZXdCb3ggPSBcIjAgMCAyNCAyNFwiO1xuICAgICAgICAgIGxldCBpY29uID0gaWNvbkNvbmZpZy5pY29uIHx8IG51bGw7XG5cbiAgICAgICAgICBpZiAoaWNvbkNvbmZpZy52YXJOYW1lKSB7XG4gICAgICAgICAgICBsZXQgaWNvblZhciA9IHV0aWxzLmdldFZhckJ5UGF0aChkYXRhLnZhbHVlcywgaWNvbkNvbmZpZy52YXJOYW1lKTtcbiAgICAgICAgICAgIGlmIChpY29uVmFyKSB7XG4gICAgICAgICAgICAgIGljb24gPSBpY29uVmFyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChpY29uQ29uZmlnLmNsYXNzTmFtZSkge1xuICAgICAgICAgICAgY2xhc3NOYW1lID0gaWNvbkNvbmZpZy5jbGFzc05hbWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGljb25Db25maWcuY29sb3IpIHtcbiAgICAgICAgICAgIGlmICh1dGlscy5pc0hleENvbG9yKGljb25Db25maWcuY29sb3IpKSB7XG4gICAgICAgICAgICAgIGNvbG9yU3R5bGUgPSBgLS1sb2NhbC1jb2xvcjogJHtpY29uQ29uZmlnLmNvbG9yfTtgO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgY29sb3JDbGFzcyA9IGljb25Db25maWcuY29sb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGljb25Db25maWcuY29sb3JWYXJOYW1lKSB7XG4gICAgICAgICAgICBsZXQgY29sb3JWYXIgPSB1dGlscy5nZXRWYXJCeVBhdGgoXG4gICAgICAgICAgICAgIGRhdGEudmFsdWVzLFxuICAgICAgICAgICAgICBpY29uQ29uZmlnLmNvbG9yVmFyTmFtZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChjb2xvclZhcikge1xuICAgICAgICAgICAgICBpZiAodXRpbHMuaXNIZXhDb2xvcihjb2xvclZhcikpIHtcbiAgICAgICAgICAgICAgICBjb2xvclN0eWxlID0gYC0tbG9jYWwtY29sb3I6ICR7Y29sb3JWYXJ9O2A7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29sb3JDbGFzcyA9IGNvbG9yVmFyO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3RyICs9IGBcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaWNvbi1mbG9hdGJveCAke2NsYXNzTmFtZX0gJHtcbiAgICAgICAgICAgICAgICAgIGNvbG9yQ2xhc3MgPyBcImhhcy1jb2xvclwiIDogXCJcIlxuICAgICAgICAgICAgICAgIH1cIiBzdHlsZT1cIiR7Y29sb3JTdHlsZX1cIj5cbiAgICAgICAgICAgICAgICAgIDxzdmcgdmlld0JveD1cIiR7dmlld0JveH1cIj5cbiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIiR7aWNvbn1cIiAvPlxuICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgYDtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vbnVtZXJvcyBlbiBlbCBmbG9hdEJveFxuICAgICAgaWYgKHRhYi5mbG9hdEJveC5udW1zKSB7XG4gICAgICAgIHRhYi5mbG9hdEJveC5udW1zLmZvckVhY2goKG4pID0+IHtcbiAgICAgICAgICBpZiAodGFiLmxlZ2VuZHMgJiYgbi50YWJLZXkpIHtcbiAgICAgICAgICAgIGxldCBsZWdlbmQgPSB0YWIubGVnZW5kcy5maW5kKChsKSA9PiBsLmtleSA9PSBuLnRhYktleSk7XG4gICAgICAgICAgICBpZiAobGVnZW5kICYmICFsZWdlbmQuYWN0aXZlKSByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgbGV0IGRhdGFGbG9hdEJveCA9IG51bGw7XG4gICAgICAgICAgbGV0IGNsYXNzTmFtZSA9IFwiXCI7XG4gICAgICAgICAgbGV0IHNob3dJZiA9IHRydWU7XG4gICAgICAgICAgbGV0IGhpZGVJZiA9IGZhbHNlO1xuICAgICAgICAgIGxldCBjb2xvckNsYXNzID0gXCJcIjtcbiAgICAgICAgICBsZXQgY29sb3JTdHlsZSA9IFwiXCI7XG4gICAgICAgICAgbGV0IGNsYXNzTmFtZXNFeHQgPSBcIlwiO1xuICAgICAgICAgIGxldCBjb2xvclN0eWxlRXh0ID0gXCJcIjtcbiAgICAgICAgICBsZXQgY3NzVmFycyA9IFwiXCI7XG5cbiAgICAgICAgICBpZiAobi52YXJOYW1lKSB7XG4gICAgICAgICAgICBkYXRhRmxvYXRCb3ggPSB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YS52YWx1ZXMsIG4udmFyTmFtZSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG4udmFyU2hvdykge1xuICAgICAgICAgICAgc2hvd0lmID0gQm9vbGVhbih1dGlscy5nZXRWYXJCeVBhdGgoZGF0YS52YWx1ZXMsIG4udmFyU2hvdykpO1xuICAgICAgICAgICAgZGF0YUZsb2F0Qm94ID0gZGF0YUZsb2F0Qm94IHx8IFwiXCI7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG4udmFySGlkZSkge1xuICAgICAgICAgICAgaGlkZUlmID0gQm9vbGVhbih1dGlscy5nZXRWYXJCeVBhdGgoZGF0YS52YWx1ZXMsIG4udmFySGlkZSkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChuLmhpZGRlbiA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgaGlkZUlmID0gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAobi5zaGFwZSkge1xuICAgICAgICAgICAgY2xhc3NOYW1lICs9IFwic2hhcGUtXCIgKyBuLnNoYXBlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChuLmNvbG9yKSB7XG4gICAgICAgICAgICBpZiAodXRpbHMuaXNIZXhDb2xvcihuLmNvbG9yKSkge1xuICAgICAgICAgICAgICBjb2xvclN0eWxlID0gYC0tbG9jYWwtY29sb3I6ICR7bi5jb2xvcn07YDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGNvbG9yQ2xhc3MgPSBuLmNvbG9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChuLmxvbmdCYXIpIHtcbiAgICAgICAgICAgIGxldCBsb25nQmFyQ29sb3IgPSBcIlwiO1xuICAgICAgICAgICAgbGV0IGxvbmdCYXJPcGFjaXR5ID0gXCJcIjtcblxuICAgICAgICAgICAgaWYgKG4ubG9uZ0JhckNvbG9yKSB7XG4gICAgICAgICAgICAgIGxvbmdCYXJDb2xvciA9IHV0aWxzLmdldFZhckJ5UGF0aChkYXRhLnZhbHVlcywgbi5sb25nQmFyQ29sb3IpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobG9uZ0JhckNvbG9yKSB7XG4gICAgICAgICAgICAgIGlmICh1dGlscy5pc0hleENvbG9yKGxvbmdCYXJDb2xvcikpIHtcbiAgICAgICAgICAgICAgICBjb2xvclN0eWxlRXh0ID0gYC0tbG9jYWwtY29sb3I6ICR7bG9uZ0JhckNvbG9yfTtgO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNsYXNzTmFtZXNFeHQgKz0gbG9uZ0JhckNvbG9yICsgXCItbGlnaHQgXCI7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY29sb3JDbGFzcyAmJiBjb2xvckNsYXNzICE9IFwiXCIpIHtcbiAgICAgICAgICAgICAgY2xhc3NOYW1lc0V4dCArPSBjb2xvckNsYXNzO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjb2xvclN0eWxlICYmIGNvbG9yU3R5bGUgIT0gXCJcIikge1xuICAgICAgICAgICAgICBjb2xvclN0eWxlRXh0ID0gY29sb3JTdHlsZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG4ubG9uZ0Jhck9wYWNpdHkpIHtcbiAgICAgICAgICAgICAgbG9uZ0Jhck9wYWNpdHkgPVxuICAgICAgICAgICAgICAgIHV0aWxzLmdldFZhckJ5UGF0aChkYXRhLnZhbHVlcywgbi5sb25nQmFyT3BhY2l0eSkgfHwgbnVsbDtcbiAgICAgICAgICAgICAgaWYgKGxvbmdCYXJPcGFjaXR5KSB7XG4gICAgICAgICAgICAgICAgY29sb3JTdHlsZUV4dCArPSBcIi0tbG9jYWwtb3BhY2l0eTogXCIgKyBsb25nQmFyT3BhY2l0eSArIFwiO1wiO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChuLmxvbmdCYXJDbGFzc05hbWUpIHtcbiAgICAgICAgICAgICAgY2xhc3NOYW1lc0V4dCArPVxuICAgICAgICAgICAgICAgIHV0aWxzLmdldFZhckJ5UGF0aChkYXRhLnZhbHVlcywgbi5sb25nQmFyQ2xhc3NOYW1lKSB8fCBcIlwiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgbG9uZ0JhciA9IHV0aWxzLmdldFZhckJ5UGF0aChkYXRhLnZhbHVlcywgbi5sb25nQmFyKTtcbiAgICAgICAgICAgIGlmIChsb25nQmFyKSB7XG4gICAgICAgICAgICAgIGNzc1ZhcnMgPSBgLS1sb25nOiR7bG9uZ0Jhcn07YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoZGF0YUZsb2F0Qm94ICE9PSBudWxsICYmIHNob3dJZiAmJiAhaGlkZUlmKSB7XG4gICAgICAgICAgICBzdHIgKz0gYDxzcGFuIGNsYXNzPVwiZGF0YSAke2NvbG9yQ2xhc3N9ICR7Y2xhc3NOYW1lfVwiIHN0eWxlPVwiJHtjb2xvclN0eWxlfVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiBkYXRhRmxvYXRCb3ggPT0gXCJzdHJpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBkYXRhRmxvYXRCb3hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogXCJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW9mIGRhdGFGbG9hdEJveCA9PSBcIm51bWJlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHV0aWxzLnJvdW5kKGRhdGFGbG9hdEJveCwgbi5yb3VuZClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogXCJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+YDtcblxuICAgICAgICAgICAgaWYgKG4ubG9uZ0JhciAmJiBjc3NWYXJzKSB7XG4gICAgICAgICAgICAgIHN0ckV4dCArPSBgPGRpdiBjbGFzcz1cImxvbmctYmFyICR7Y2xhc3NOYW1lc0V4dH1cIiBzdHlsZT1cIiR7Y29sb3JTdHlsZUV4dH0gJHtjc3NWYXJzfSBcIj48L2Rpdj4gYDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICAvL3B1bnRvcyBlbiBlbCBmbG9hdEJveFxuICAgICAgaWYgKHRhYi5mbG9hdEJveC5kb3RzKSB7XG4gICAgICAgIHN0ciArPSBgPGRpdiBjbGFzcz1cImRvdC1jb250YWluZXItbWlkZGxlXCI+YDtcbiAgICAgICAgdGFiLmZsb2F0Qm94LmRvdHMuZm9yRWFjaCgoZG90KSA9PiB7XG4gICAgICAgICAgaWYgKHV0aWxzLmdldFZhckJ5UGF0aChkYXRhLnZhbHVlcywgZG90LnZhck5hbWUpICE9PSBudWxsKSB7XG4gICAgICAgICAgICBsZXQgY2xhc3NOYW1lID0gXCJcIjtcbiAgICAgICAgICAgIGxldCBjb2xvckNsYXNzID0gXCJcIjtcbiAgICAgICAgICAgIGxldCBjb2xvclN0eWxlID0gXCJcIjtcblxuICAgICAgICAgICAgaWYgKGRvdC5zaGFwZSkge1xuICAgICAgICAgICAgICBjbGFzc05hbWUgKz0gZG90LnNoYXBlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZG90LmNvbG9yKSB7XG4gICAgICAgICAgICAgIGlmICh1dGlscy5pc0hleENvbG9yKGRvdC5jb2xvcikpIHtcbiAgICAgICAgICAgICAgICBjb2xvclN0eWxlID0gYC0tbG9jYWwtY29sb3I6ICR7ZG90LmNvbG9yfWA7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29sb3JDbGFzcyA9IGRvdC5jb2xvcjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzdHIgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZG90ICR7Y29sb3JDbGFzc30gJHtjbGFzc05hbWV9XCIgc3R5bGU9XCIke2NvbG9yU3R5bGV9XCIgPjwvZGl2PmA7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgc3RyICs9IGBcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG4gICAgICB9XG5cbiAgICAgIC8vZmlsYSBkZSBwdW50b3MgZW4gZmxvYXRCb3hcbiAgICAgIGlmICh0YWIuZmxvYXRCb3gucm93RG90cykge1xuICAgICAgICB0YWIuZmxvYXRCb3gucm93RG90cy5mb3JFYWNoKChyb3cpID0+IHtcbiAgICAgICAgICBsZXQgZnJlZUNvbHVtbnMgPSA0O1xuICAgICAgICAgIHN0ciArPSBgPHNwYW4gY2xhc3M9XCJyb3dkb3QtLXJvdyBcIj5gO1xuXG4gICAgICAgICAgcm93LmZvckVhY2goKGRvdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRhYi5sZWdlbmRzICYmIGRvdC50YWJLZXkpIHtcbiAgICAgICAgICAgICAgbGV0IGxlZ2VuZCA9IHRhYi5sZWdlbmRzLmZpbmQoKGwpID0+IGwua2V5ID09IGRvdC50YWJLZXkpO1xuICAgICAgICAgICAgICBpZiAobGVnZW5kICYmICFsZWdlbmQuYWN0aXZlKSByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBkYXRhRmxvYXRCb3ggPSBudWxsO1xuICAgICAgICAgICAgbGV0IGNsYXNzTmFtZSA9IFwiXCI7XG4gICAgICAgICAgICBsZXQgc2hvd0lmID0gdHJ1ZTtcbiAgICAgICAgICAgIGxldCBoaWRlSWYgPSBmYWxzZTtcbiAgICAgICAgICAgIGxldCBjb2xvckNsYXNzID0gXCJcIjtcbiAgICAgICAgICAgIGxldCBjb2xvclN0eWxlID0gXCJcIjtcblxuICAgICAgICAgICAgaWYgKGRvdC52YXJOYW1lKSB7XG4gICAgICAgICAgICAgIGRhdGFGbG9hdEJveCA9IHV0aWxzLmdldFZhckJ5UGF0aChkYXRhLnZhbHVlcywgZG90LnZhck5hbWUpO1xuICAgICAgICAgICAgICBkYXRhRmxvYXRCb3ggPSBwYXJzZUludChkYXRhRmxvYXRCb3gpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZG90LnZhclNob3cpIHtcbiAgICAgICAgICAgICAgc2hvd0lmID0gQm9vbGVhbih1dGlscy5nZXRWYXJCeVBhdGgoZGF0YS52YWx1ZXMsIGRvdC52YXJTaG93KSk7XG4gICAgICAgICAgICAgIGRhdGFGbG9hdEJveCA9IGRhdGFGbG9hdEJveCB8fCBcIlwiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZG90LnZhckhpZGUpIHtcbiAgICAgICAgICAgICAgaGlkZUlmID0gQm9vbGVhbih1dGlscy5nZXRWYXJCeVBhdGgoZGF0YS52YWx1ZXMsIGRvdC52YXJIaWRlKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChkb3Quc2hhcGUpIHtcbiAgICAgICAgICAgICAgY2xhc3NOYW1lICs9IFwiIHNoYXBlLVwiICsgZG90LnNoYXBlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZG90LmNvbG9yKSB7XG4gICAgICAgICAgICAgIGlmICh1dGlscy5pc0hleENvbG9yKGRvdC5jb2xvcikpIHtcbiAgICAgICAgICAgICAgICBjb2xvclN0eWxlID0gYC0tbG9jYWwtY29sb3I6ICR7ZG90LmNvbG9yfWA7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29sb3JDbGFzcyA9IGRvdC5jb2xvcjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgIGRhdGFGbG9hdEJveCAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgICBkYXRhRmxvYXRCb3ggPiAwICYmXG4gICAgICAgICAgICAgIHNob3dJZiAmJlxuICAgICAgICAgICAgICAhaGlkZUlmICYmXG4gICAgICAgICAgICAgIGZyZWVDb2x1bW5zID4gMFxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIGxldCBuID0gZGF0YUZsb2F0Qm94ID4gZnJlZUNvbHVtbnMgPyBmcmVlQ29sdW1ucyA6IGRhdGFGbG9hdEJveDtcbiAgICAgICAgICAgICAgZnJlZUNvbHVtbnMgLT0gbjtcbiAgICAgICAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IG47IGluZGV4KyspIHtcbiAgICAgICAgICAgICAgICBzdHIgKz0gYDxkaXYgY2xhc3M9XCJyb3dkb3QtLWRvdCAke2NvbG9yQ2xhc3N9ICR7Y2xhc3NOYW1lfVwiIHN0eWxlPVwiJHtjb2xvclN0eWxlfVwiPjwvZGl2PmA7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHN0ciArPSBgPC9zcGFuPmA7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHN0ciArPSBgXG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICBzdHJFeHQgKz0gYFxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuXG4gICAgbGV0ICRlbGVtID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChzdHIpO1xuXG4gICAgbGV0ICRlbGVtRXh0ID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChzdHJFeHQpO1xuXG4gICAgJGVsZW0uYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlb3ZlclwiLCAoZSkgPT4ge1xuICAgICAgJGVsZW0uZGlzcGF0Y2hFdmVudChcbiAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwibW91c2VPdmVyRmxvYXRCb3hcIiwge1xuICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICBpdGVtOiBpdGVtLFxuICAgICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICAgIG9yaWdpbmFsRXZ0OiBlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgJGVsZW0uYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAkZWxlbS5kaXNwYXRjaEV2ZW50KFxuICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoXCJjbGlja0Zsb2F0Qm94XCIsIHtcbiAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgIGNhbmNlbGFibGU6IGZhbHNlLFxuICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgaXRlbTogaXRlbSxcbiAgICAgICAgICAgIGRhdGE6IGRhdGEsXG4gICAgICAgICAgICBvcmlnaW5hbEV2dDogZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZCgkZWxlbSk7XG4gICAgY29udGFpbmVyLmFwcGVuZENoaWxkKCRlbGVtRXh0KTtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBEZXRhaWxEYXksIGRldGFsbGUgZGUgdmFsb3JlcyBkZSBpdGVtIHkgRGlhXG4gICAqIHNlIHVzYSBwYXJhOlxuICAgKiAgICAtIE11ZXN0cmEgbm9tYnJlIGRlIGl0ZW0geSBkZXRhbGxlc1xuICAgKiAgICAtIE11ZXN0cmEgY2Fwc3VsYXMgZGUgZGF0b3NcbiAgICogICAgLSBNdWVzdHJhIFBpbGxzLCBwaWxkb3JhcyBkZSBkYXRvcyByZXN1bWlkb3NcbiAgICogICAgLSBNdWVzdHJhIGFsZXJ0YXNcbiAgICogICAgLSBNdWVzdHJhIE1lbnNhamVcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHBhcmFtIHtPYmplY3R9IGl0ZW0gLSBJdGVtIHJlbGFjaW9uYWRvXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhRGF5IC0gdmFsb3JlcyBkZSBpdGVtIHkgRGlhXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gW29ubHlTdHJpbmdDb250ZW50ID0gZmFsc2VdIC0gcGFyYSBlc2NvZ2VyIHNpIGRldnVlbHZlIFN0cmluZyBvIERvbUVsZW1lbnRcbiAgICogQHJldHVybiB7U3RyaW5nfE9iamVjdH0gRWxlbWVudG8gY29tbyBTdHJpbmcgbyBEb21FbGVtZW50XG4gICAqL1xuICBjcmVhdGVEZXRhaWxEYXkoXG4gICAgY29uZmlnLFxuICAgIGl0ZW0gPSB7fSxcbiAgICBkYXRhRGF5LFxuICAgIHRhYlNlbGVjdGVkLFxuICAgIG9ubHlTdHJpbmdDb250ZW50ID0gZmFsc2VcbiAgKSB7XG4gICAgbGV0IHN0ciA9IGBcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZGVyLWRldGFpbFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRpdGxlIHRydW5jYXRlXCI+XG4gICAgICAgICAgICAgICR7aXRlbS5sYWJlbCB8fCBcIlwifVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VidGl0bGVcIj5cbiAgICAgICAgICAgICAgJHtkYXRhRGF5ID8gZGF0ZVV0aWxzLmZvcm1hdERhdGVSZWFkZWFibGUoZGF0YURheS5kYXRlKSA6IFwiXCJ9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJsaXN0LWRldGFpbCBsaXN0IGNvbHVtbi1mbGV4XCI+YDtcblxuICAgIC8vQ0FQU1VMRVNcbiAgICBsZXQgdmlzaWJsZUl0ZW1zQ291bnQgPSAwOyAvLyBDb250YWRvciBkZSBlbGVtZW50b3MgdmlzaWJsZXNcblxuICAgIGlmIChkYXRhRGF5KSB7XG4gICAgICBjb25maWcudGltZWxpbmUuZGV0YWlsRGF5LmNhcHN1bGVzLmZvckVhY2goKGNhcCkgPT4ge1xuICAgICAgICAvL3BhcmEgY29tcHJvYmFyIHNpIHRpZW5lIGRhdG9zLCBzZSBvYnRpZW5lIGVsIHByaW1lciB2YWxvclxuICAgICAgICAvL2RlIGxhIGxpc3RhIGRlIHZhbHVlcyBkZSB1bmEgY2Fwc3VsYVxuICAgICAgICBsZXQgaGFzVmFsdWVzID1cbiAgICAgICAgICBjYXAudmFsdWVzLmZpbHRlcigodikgPT4ge1xuICAgICAgICAgICAgbGV0IHZhbHVlID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGFEYXkudmFsdWVzLCB2LnZhck5hbWUpO1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgdmFsdWUgIT09IG51bGwgJiYgIShBcnJheS5pc0FycmF5KHZhbHVlKSAmJiB2YWx1ZS5sZW5ndGggPT09IDApXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pLmxlbmd0aCA+IDA7XG5cbiAgICAgICAgbGV0IGhpZGVJZiA9IGZhbHNlO1xuXG4gICAgICAgIGlmIChjYXAuaGlkZUlmKSB7XG4gICAgICAgICAgaGlkZUlmID0gQm9vbGVhbih1dGlscy5nZXRWYXJCeVBhdGgoZGF0YURheS52YWx1ZXMsIGNhcC5oaWRlSWYpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBjb2xvckNsYXNzID0gXCJcIjtcbiAgICAgICAgbGV0IGNvbG9yU3R5bGUgPSBcIlwiO1xuXG4gICAgICAgIGlmIChjYXAuY29sb3IpIHtcbiAgICAgICAgICBpZiAodXRpbHMuaXNIZXhDb2xvcihjYXAuY29sb3IpKSB7XG4gICAgICAgICAgICBjb2xvclN0eWxlID0gYC0tbG9jYWwtY29sb3I6ICR7Y2FwLmNvbG9yfTtgO1xuICAgICAgICAgICAgY29sb3JTdHlsZSArPSBgLS1sb2NhbC1jb2xvci1mb250OiAke2NhcC5jb2xvcn07YDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29sb3JDbGFzcyA9IGNhcC5jb2xvcjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhhc1ZhbHVlcyAmJiAhaGlkZUlmKSB7XG4gICAgICAgICAgdmlzaWJsZUl0ZW1zQ291bnQrKzsgLy8gSW5jcmVtZW50YXIgY29udGFkb3IgZGUgZWxlbWVudG9zIHZpc2libGVzXG4gICAgICAgICAgc3RyICs9IGBcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIml0ZW0tZGV0YWlsICR7Y29sb3JDbGFzc31cIiBzdHlsZT1cIiR7Y29sb3JTdHlsZX1cIj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsZWZ0LWljb24gJHtjYXAuc2hhcGUgfHwgXCJcIn0gXCI+PC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibmFtZVwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+XG4gICAgICAgICAgICAgICAgICAgICR7Y2FwLnRpdGxlIHx8IFwiXCJ9XG4gICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+YDtcblxuICAgICAgICAgIHN0ciArPSBgXG4gICAgICAgICAgPGRpdiBjbGFzcz1cIml0ZW0tZGVzY3JpcHRpb25cIj4gYDtcblxuICAgICAgICAgIGNhcC52YWx1ZXMuZm9yRWFjaCgodikgPT4ge1xuICAgICAgICAgICAgbGV0IHZhbHVlID0gdi52YXJOYW1lXG4gICAgICAgICAgICAgID8gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGFEYXkudmFsdWVzLCB2LnZhck5hbWUpXG4gICAgICAgICAgICAgIDogbnVsbDtcblxuICAgICAgICAgICAgaWYgKGNhcC5pc0xhYmVsZWRBcnJheSkge1xuICAgICAgICAgICAgICB2YWx1ZS5mb3JFYWNoKCh2YWx1ZUxhYmVsZWQpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgb3V0cHV0VmFsdWUgPSBudWxsO1xuICAgICAgICAgICAgICAgIGxldCB2YWx1ZU5hbWUgPSB2LnZhbHVlTmFtZSA/IHYudmFsdWVOYW1lIDogXCJ2YWx1ZVwiO1xuXG4gICAgICAgICAgICAgICAgbGV0IHRlbXBWYWx1ZSA9IHV0aWxzLmdldFZhckJ5UGF0aCh2YWx1ZUxhYmVsZWQsIHZhbHVlTmFtZSk7XG5cbiAgICAgICAgICAgICAgICBpZiAodGVtcFZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXRWYWx1ZSA9IHYucm91bmRcbiAgICAgICAgICAgICAgICAgICAgPyB1dGlscy5yb3VuZCh0ZW1wVmFsdWUsIHYucm91bmQpXG4gICAgICAgICAgICAgICAgICAgIDogdGVtcFZhbHVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh2LmZvcm1hdHRlcikge1xuICAgICAgICAgICAgICAgICAgb3V0cHV0VmFsdWUgPSB2LmZvcm1hdHRlcih2YWx1ZUxhYmVsZWQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb3V0cHV0VmFsdWUgPT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgICAgb3V0cHV0VmFsdWUgPSB1dGlscy5mb3JtYXROdW1iZXIob3V0cHV0VmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHN0ciArPVxuICAgICAgICAgICAgICAgICAgb3V0cHV0VmFsdWUgPT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/IFwiXCJcbiAgICAgICAgICAgICAgICAgICAgOiBgXG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRlc2MgJHt2LnNob3dDb2x1bW4gPyBcImRlc2MtY29sdW1uXCIgOiBcIlwifVwiPlxuICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxhYmVsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICR7di5oaWRlTGFiZWwgPyBcIlwiIDogdmFsdWVMYWJlbGVkLmxhYmVsfVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXYgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInZhbFwiPmAgK1xuICAgICAgICAgICAgICAgICAgICAgICh2LmhpZGVQcmVmZml4ICE9PSB0cnVlXG4gICAgICAgICAgICAgICAgICAgICAgICA/IGBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwcmVmaXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke3YucHJlZml4IHx8IFwiXCJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5gXG4gICAgICAgICAgICAgICAgICAgICAgICA6IFwiXCIpICtcbiAgICAgICAgICAgICAgICAgICAgICBgPHNwYW4gY2xhc3M9XCJ2YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7b3V0cHV0VmFsdWV9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5gICtcbiAgICAgICAgICAgICAgICAgICAgICAodi5oaWRlU3VmZml4ICE9PSB0cnVlXG4gICAgICAgICAgICAgICAgICAgICAgICA/IGBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdWZmaXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke3ZhbHVlTGFiZWxlZC5zdWZmaXggfHwgdi5zdWZmaXggfHwgXCJcIn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPmBcbiAgICAgICAgICAgICAgICAgICAgICAgIDogXCJcIikgK1xuICAgICAgICAgICAgICAgICAgICAgIGBcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgbGV0IG91dHB1dFZhbHVlID0gdi5yb3VuZCA/IHV0aWxzLnJvdW5kKHZhbHVlLCB2LnJvdW5kKSA6IHZhbHVlO1xuXG4gICAgICAgICAgICAgIGlmICh2LmZvcm1hdHRlcikge1xuICAgICAgICAgICAgICAgIG91dHB1dFZhbHVlID0gdi5mb3JtYXR0ZXIoeyBvcHRpb25zOiB2LCBkYXRhRGF5LCBvdXRwdXRWYWx1ZSB9KTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmICh0eXBlb2Ygb3V0cHV0VmFsdWUgPT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgIG91dHB1dFZhbHVlID0gdXRpbHMuZm9ybWF0TnVtYmVyKG91dHB1dFZhbHVlKTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChvdXRwdXRWYWx1ZSkge1xuICAgICAgICAgICAgICAgIHN0ciArPSBgXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXNjXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicHJlZml4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHt2LnByZWZpeCB8fCBcIlwifVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke291dHB1dFZhbHVlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3VmZml4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHt2LnN1ZmZpeCB8fCBcIlwifVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHN0ciArPSBgXG4gICAgICAgICAgICAgICAgPC9kaXY+YDtcblxuICAgICAgICAgIHN0ciArPSBgXG4gICAgICAgICAgICAgIDwvZGl2PmA7IC8vIGVuZCAuaXRlbS1kZXRhaWxcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQWdyZWdhciBjbGFzZSBzaW5nbGUtaXRlbSBzaSBzb2xvIGhheSB1biBlbGVtZW50byB2aXNpYmxlXG4gICAgY29uc3QgY29sdW1uQ2xhc3MgPVxuICAgICAgdmlzaWJsZUl0ZW1zQ291bnQgPT09IDFcbiAgICAgICAgPyBcImxpc3QgY29sdW1uLWZsZXggc2luZ2xlLWl0ZW1cIlxuICAgICAgICA6IFwibGlzdCBjb2x1bW4tZmxleFwiO1xuICAgIHN0ciA9IHN0ci5yZXBsYWNlKFwibGlzdCBjb2x1bW4tZmxleFwiLCBjb2x1bW5DbGFzcyk7XG5cbiAgICBzdHIgKz0gYFxuICAgICAgICA8L2Rpdj5gOyAvLyBsaXN0LWRldGFpbFxuXG4gICAgLy9QSUxMU1xuICAgIGlmIChcbiAgICAgIGNvbmZpZy50aW1lbGluZS5kZXRhaWxEYXkucGlsbHNWYXJOYW1lICYmXG4gICAgICBkYXRhRGF5ICYmXG4gICAgICBkYXRhRGF5LnZhbHVlc1tjb25maWcudGltZWxpbmUuZGV0YWlsRGF5LnBpbGxzVmFyTmFtZV1cbiAgICApIHtcbiAgICAgIHN0ciArPSBgXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImVsZW1lbnRzLWRldGFpbFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm5hbWVcIj4gJHtjb25maWcudGltZWxpbmUuZGV0YWlsRGF5LnBpbGxzVGl0bGV9IDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImVsZW1lbnRzLWxpc3RcIj5gO1xuXG4gICAgICBkYXRhRGF5LnZhbHVlc1tjb25maWcudGltZWxpbmUuZGV0YWlsRGF5LnBpbGxzVmFyTmFtZV0uZm9yRWFjaCgoZSkgPT4ge1xuICAgICAgICBsZXQgdmFsdWUgPSBlLnZhbHVlO1xuXG4gICAgICAgIGlmICh0eXBlb2Ygb3V0cHV0VmFsdWUgPT0gXCJudW1iZXJcIikge1xuICAgICAgICAgIHZhbHVlID0gdXRpbHMuZm9ybWF0TnVtYmVyKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0ciArPSBgXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZWxlbWVudC1kZXRhaWxcIj5cbiAgICAgICAgICAgICAgPGI+JHtlLmxhYmVsfTwvYj5cbiAgICAgICAgICAgICAgJHt2YWx1ZX1cbiAgICAgICAgICAgIDwvZGl2PmA7XG4gICAgICB9KTtcblxuICAgICAgc3RyICs9IGBcbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+YDsgLy9lbmQgLmVsZW1lbnQtZGV0YWlsID4gLmVsZW1lbnQtbGlzdFxuICAgIH1cblxuICAgIC8vc3RyICs9IGA8L2Rpdj5gO1xuXG4gICAgaWYgKGRhdGFEYXkgJiYgZGF0YURheS5lcnJvcnMgJiYgZGF0YURheS5lcnJvcnMubGVuZ3RoID4gMCkge1xuICAgICAgZGF0YURheS5lcnJvcnMuZm9yRWFjaCgoZXJyKSA9PiB7XG4gICAgICAgIHN0ciArPSBgXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImFsZXJ0XCI+XG4gICAgICAgICAgICAke2ljb25zLmFsZXJ0fVxuICAgICAgICAgICAgJHtlcnIubGFiZWx9XG4gICAgICAgICAgPC9kaXY+YDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGxldCBtc2cgPSBudWxsO1xuICAgIGxldCBhdXRob3IgPSBudWxsO1xuICAgIGxldCBkYXRlTXNnID0gbnVsbDtcbiAgICBpZiAoZGF0YURheSAmJiB0YWJTZWxlY3RlZC5mbG9hdEJveCAmJiB0YWJTZWxlY3RlZC5mbG9hdEJveC5tZXNzYWdlUGF0aCkge1xuICAgICAgbXNnID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGFEYXksIHRhYlNlbGVjdGVkLmZsb2F0Qm94Lm1lc3NhZ2VQYXRoKTtcbiAgICB9XG5cbiAgICBpZiAoIW1zZyAmJiBkYXRhRGF5ICYmIGRhdGFEYXkubWVzc2FnZSAmJiBkYXRhRGF5Lm1lc3NhZ2UudmFsdWUpIHtcbiAgICAgIG1zZyA9IGRhdGFEYXkubWVzc2FnZS52YWx1ZTtcbiAgICAgIGF1dGhvciA9IGRhdGFEYXkubWVzc2FnZS5hdXRob3I7XG4gICAgICBkYXRlTXNnID0gZGF0ZVV0aWxzLmZvcm1hdERhdGVSZWFkZWFibGUobmV3IERhdGUoZGF0YURheS5tZXNzYWdlLmRhdGUpKTtcbiAgICB9XG5cbiAgICBpZiAobXNnKSB7XG4gICAgICAvL21zZyA9IG1zZy5yZXBsYWNlKC8oXFxyXFxufFxccnxcXG4pL2csICc8YnI+Jyk7XG4gICAgICBzdHIgKz0gYFxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJtc2otY29udGFpbmVyXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXNqXCI+XG4gICAgICAgICAgICA8cHJlPiR7bXNnIHx8IFwiXCJ9PC9wcmU+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtc2otZGV0YWlsXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZW1haWxcIj4gJHthdXRob3IgfHwgXCJcIn0gPC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRhdGVcIj4gJHtkYXRlTXNnIHx8IFwiXCJ9IDwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5gO1xuICAgIH1cblxuICAgIGxldCBzdHJDb250YWluZXIgPSBgPGRpdiBjbGFzcz1cImRldGFpbC1kYXkgZGQtaGlkZVwiPiAke3N0cn0gPC9kaXY+YDtcblxuICAgIGlmIChvbmx5U3RyaW5nQ29udGVudCkgcmV0dXJuIHN0cjtcblxuICAgIHJldHVybiBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKHN0ckNvbnRhaW5lcik7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJlY3JlYSBIVE1MIGRlIGRldGFpbERheVxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gQ29uZmlndXJhY2lvbiBjYXBpYmFyYVxuICAgKiBAcGFyYW0ge09iamVjdH0gaXRlbSAtIEl0ZW0gcmVsYWNpb25hZG9cbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGFEYXkgLSB2YWxvcmVzIGRlIGl0ZW0geSBEaWFcbiAgICogQHJldHVybiB7U3RyaW5nfSBFbGVtZW50byBjb21vIFN0cmluZywgZGUgZGV0YWlsRGF5XG4gICAqL1xuICByZWRyYXdEZXRhaWxEYXkoY29uZmlnLCBpdGVtLCBkYXRhRGF5LCB0YWJTZWxlY3RlZCkge1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZURldGFpbERheShjb25maWcsIGl0ZW0sIGRhdGFEYXksIHRhYlNlbGVjdGVkLCB0cnVlKTtcbiAgfSxcblxuICAvKipcbiAgICogUmVwb3NpY2lvbmEgRmxvYXRCb3hcbiAgICogdmVyaWZpY2Egc2kgZWwgcGFyZW50IGVzdGEgZGVzcGxlZ2FkbywgcGFyYSBvY3VsdGFyIGxvcyBkYXRvc1xuICAgKlxuICAgKiBTb2xvIGFjdHVhbGl6YSBsYXMgYWx0dXJhcyBkZSBsb3MgZmxvYXRib3hcbiAgICogbm8gcmVjcmVhIGxvcyBmbG9hdGJveCwgZXMgbWFzIG9wdGltb1xuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gQ29uZmlndXJhY2lvbiBjYXBpYmFyYVxuICAgKiBAcGFyYW0ge09iamVjdH0gaXRlbSAtIEl0ZW0gcmVsYWNpb25hZG9cbiAgICovXG4gIHJlcG9zaXRpb25GbG9hdEJveChjb25maWcsICRmbG9hdEJveENvbnRhaW5lcikge1xuICAgICRmbG9hdEJveENvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFwiLmZsb2F0LWJveFwiKS5mb3JFYWNoKCgkZikgPT4ge1xuICAgICAgbGV0IGl0ZW1JZCA9ICRmLmdldEF0dHJpYnV0ZShcIml0ZW0taWRcIik7XG4gICAgICBsZXQgaXRlbUhlaWdodCA9IHBhcnNlRmxvYXQoXG4gICAgICAgIHV0aWxzLmdldENTU1ZhcmlhYmxlKGNvbmZpZywgXCItLWl0ZW0taGVpZ2h0XCIpXG4gICAgICApO1xuICAgICAgbGV0IGl0ZW0sIHBhcmVudDtcbiAgICAgICh7IGl0ZW0sIHBhcmVudCB9ID0gdXRpbHMuZ2V0SXRlbUJ5SWQoY29uZmlnLCBpdGVtSWQsIFwiY2hpbGRcIiwgdHJ1ZSkpO1xuICAgICAgaWYgKGl0ZW0pIHtcbiAgICAgICAgbGV0IHRvcCA9IHV0aWxzLmdldFBvc2l0aW9uQnlJdGVtKGNvbmZpZywgaXRlbSk7XG4gICAgICAgICRmLnN0eWxlLnRvcCA9IHRvcCAqIGl0ZW1IZWlnaHQgKyBcInB4XCI7XG4gICAgICAgIGlmIChwYXJlbnQgJiYgcGFyZW50LmlzQ2xvc2VkKSB7XG4gICAgICAgICAgJGYuY2xhc3NMaXN0LmFkZChcImhpZGVcIik7XG4gICAgICAgIH0gZWxzZSBpZiAoJGYuY2xhc3NMaXN0LmNvbnRhaW5zKFwiaGlkZVwiKSkge1xuICAgICAgICAgICRmLmNsYXNzTGlzdC5yZW1vdmUoXCJoaWRlXCIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJlY3JlYSBpbmRpY2Fkb3JlcyBkZSBkaWFzIHNlbGVjY2lvbmFkb3NcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9ICRlbGVtIC0gRWxlbWVudG8gRG9tIGRvbmRlIGNyZWEgbG9zIGVsZW1lbnRvcyBzZWxlY2Npb25hZG9zXG4gICAqIEBwYXJhbSB7T2JqZWN0W119IHNlbGVjdGVkIC0gQXJyYXkgY29uIGxvcyBkaWFzIHNlbGVjY2lvbmFkb3NcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gcXVlIGNvbnRpZW5lIGxvcyBpbmRpY2Fkb3JlcyBkZSBkaWFzIHNlbGVjY2lvbmFkb3NcbiAgICovXG4gIHJlZHJhd1NlbGVjdEJvYXJkKCRlbGVtLCBzZWxlY3RlZCkge1xuICAgICRlbGVtLmlubmVySFRNTCA9IFwiXCI7XG4gICAgbGV0IGhhc051bWJlciA9IHRydWU7XG5cbiAgICBpZiAoc2VsZWN0ZWQpIHtcbiAgICAgIGlmIChzZWxlY3RlZC5sZW5ndGggPT0gMSkgaGFzTnVtYmVyID0gZmFsc2U7XG5cbiAgICAgIHNlbGVjdGVkLmZvckVhY2goKHMpID0+IHtcbiAgICAgICAgbGV0IGF0dHJpYnV0ZXMgPSBbXTtcblxuICAgICAgICBpZiAoaGFzTnVtYmVyKSB7XG4gICAgICAgICAgYXR0cmlidXRlcy5wdXNoKHsgbmFtZTogXCJjYXAtYmFkZ2VcIiwgdmFsdWU6IHMuaW5kZXggfSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0ICRzID0gZG9tLmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgICAgICAgIGNsYXNzTmFtZTogXCJzZWxlY3RlZC1kYXlcIixcbiAgICAgICAgICBhdHRyaWJ1dGVzLFxuICAgICAgICB9KTtcbiAgICAgICAgJHMuc3R5bGUubGVmdCA9IHMucG9zLmxlZnQgKyBcInB4XCI7XG4gICAgICAgICRzLnN0eWxlLnRvcCA9IHMucG9zLnRvcCArIFwicHhcIjtcbiAgICAgICAgJGVsZW0uYXBwZW5kKCRzKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gJGVsZW07XG4gIH0sXG5cbiAgLyoqXG4gICAqIE9idGllbmUgU3RyaW5nIGNvbiBlc3RpbG9zIENTUyBkZSBsYSBwb3NpY2lvbiBkZSB1biBmbG9hdEJveFxuICAgKiBjYWxjdWxhZG8gc2VndW4gaXRlbSB5IGZlY2hhIGRlIGxvcyB2YWxvcmVzXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgLSBDb25maWd1cmFjaW9uIGNhcGliYXJhLCBwYXJhIHZlciBmZWNoYSBkZSBpbmljaW9cbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGEgLSBEYXRvcyBkZWwgZGlhIGluZGljYWRvXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBpdGVtIC0gSXRlbSByZWxhY2lvbmFkb1xuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyBDU1MgdG9wIHkgbGVmdCAsIHBhcmEgcG9zaWNpb25hciBmbG9hdEJveCBlbiB0YWJsZVxuICAgKi9cbiAgZ2V0UG9zaXRpb25GbG9hdEJveChjb25maWcsIGRhdGEsIGl0ZW0sIHR5cGVOb2RlKSB7XG4gICAgbGV0IGxlZnQgPSBkYXRlVXRpbHMuZGlmZkRheXMoY29uZmlnLnRpbWVsaW5lLnN0YXJ0LCBkYXRhLmRhdGUpO1xuICAgIGxldCB0b3AgPSB1dGlscy5nZXRQb3NpdGlvbkJ5SXRlbShjb25maWcsIGl0ZW0sIHR5cGVOb2RlKTtcbiAgICBsZXQgZGF5V2lkdGggPSBwYXJzZUZsb2F0KHV0aWxzLmdldENTU1ZhcmlhYmxlKGNvbmZpZywgXCItLWRheS13aWR0aFwiKSk7XG4gICAgbGV0IGl0ZW1IZWlnaHQgPSBwYXJzZUZsb2F0KHV0aWxzLmdldENTU1ZhcmlhYmxlKGNvbmZpZywgXCItLWl0ZW0taGVpZ2h0XCIpKTtcbiAgICBsZWZ0ICo9IGRheVdpZHRoO1xuICAgIHRvcCAqPSBpdGVtSGVpZ2h0O1xuICAgIHJldHVybiBcInRvcDogXCIgKyB0b3AgKyBcIi41cHg7IGxlZnQ6XCIgKyBsZWZ0ICsgXCIuNXB4O1wiO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhIEJvdG9uIGNvbW8gZWxlbWVudG8gRG9tXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwcm9wcyAtIHByb3BpZWRhZGVzIHBhcmEgYm90b25cbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BzLmNsYXNzTmFtZSAtIGNsYXNzZXMgY3NzIHBhcmEgYm90b25cbiAgICogQHBhcmFtIHsqfSBwcm9wcy5rZXkgLSBrZXkgcGFyYSBpZGVudGlmaWNhciBhIGJvdG9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wcy5sYWJlbCAtIFRleHRvIGJvdG9uXG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tIGRlbCBib3RvbiBjcmVhZG9cbiAgICovXG4gIGNyZWF0ZUJ1dHRvbihwcm9wcykge1xuICAgIHJldHVybiBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKGBcbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCIke3Byb3BzLmNsYXNzTmFtZSB8fCBcIlwifVwiIGlucHV0LWtleT1cIiR7XG4gICAgICAgICAgICAgIHByb3BzLmtleSB8fCBcIlwiXG4gICAgICAgICAgICB9XCI+XG4gICAgICAgICAgICAgICR7cHJvcHMubGFiZWwgfHwgXCJcIn1cbiAgICAgICAgICAgIDwvYnV0dG9uPmApO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhIEJvdG9uZXMgZGUgZ3VhcmRhciB5IGNhbmNlbGFyIGxvcyBkYXRvcyBkZSBmb3JtdWxhcmlvIGRlbCBzaWRlYmFyIGRlcmVjaG9cbiAgICpcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gZGVsIGJvdG9uZXMgY3JlYWRvc1xuICAgKi9cbiAgY3JlYXRlTmF2UmlnaHRidXR0b25zKGNvbmZpZykge1xuICAgIGxldCBidG5TZWN0aW9uID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChcbiAgICAgIGA8ZGl2IGNsYXNzPVwiYnV0dG9uLXNlY3Rpb25cIj48L2Rpdj5gXG4gICAgKTtcbiAgICBpZiAoXG4gICAgICBjb25maWcudGltZWxpbmUubmF2LnJpZ2h0ICYmXG4gICAgICBjb25maWcudGltZWxpbmUubmF2LnJpZ2h0LmhpZGVTYXZlQnV0dG9uICE9IHRydWVcbiAgICApIHtcbiAgICAgIGxldCBzYXZlQnRuID0gdGhpcy5jcmVhdGVCdXR0b24oe1xuICAgICAgICBsYWJlbDogXCJHdWFyZGFyXCIsXG4gICAgICAgIGNsYXNzTmFtZTogXCJjYXAtYnRuLXJhaXNlZFwiLFxuICAgICAgfSk7XG5cbiAgICAgIGJ0blNlY3Rpb24uYXBwZW5kQ2hpbGQoc2F2ZUJ0bik7XG4gICAgICBzYXZlQnRuLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZSkgPT4ge1xuICAgICAgICBzYXZlQnRuLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwic2F2ZU11bHRpSW5wdXRcIiwge1xuICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgIGNhbmNlbGFibGU6IGZhbHNlLFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBjb25maWcudGltZWxpbmUubmF2LnJpZ2h0ICYmXG4gICAgICBjb25maWcudGltZWxpbmUubmF2LnJpZ2h0LmhpZGVDYW5jZWxCdXR0b24gIT0gdHJ1ZVxuICAgICkge1xuICAgICAgY29uc3QgY2FuY2VsTGFiZWxCdXR0b24gPVxuICAgICAgICBjb25maWcudGltZWxpbmUubmF2LnJpZ2h0LmNhbmNlbExhYmVsQnV0dG9uIHx8IFwiQ2FuY2VsYXJcIjtcbiAgICAgIGxldCBjYW5jZWxCdG4gPSB0aGlzLmNyZWF0ZUJ1dHRvbih7XG4gICAgICAgIGxhYmVsOiBjYW5jZWxMYWJlbEJ1dHRvbixcbiAgICAgICAgY2xhc3NOYW1lOiBcImNhcC1idG4tb3V0bGluZVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGJ0blNlY3Rpb24uYXBwZW5kQ2hpbGQoY2FuY2VsQnRuKTtcblxuICAgICAgY2FuY2VsQnRuLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZSkgPT4ge1xuICAgICAgICBjYW5jZWxCdG4uZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoXCJjYW5jZWxNdWx0aUlucHV0XCIsIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ0blNlY3Rpb247XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgSW5wdXQgY29tbyBlbGVtZW50byBEb21cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHByb3BzIC0gY29uZmlnIHBhcmEgSW5wdXRcbiAgICogQHBhcmFtIHtPYmplY3R9IFtkYXRhRGF5ID0gbnVsbF0gLSB2YWxvcmVzIGRlIGl0ZW0geSBEaWEsIG9wY2lvbmFsXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbZGF5U2VsZWN0ZWQgPSBudWxsXSAtIGRhdG9zIGRlbCBkaWEgc2VsZWNjaW9uYWRvXG4gICAqIEBwYXJhbSB7T2JqZWN0W119IFtzZWxlY3RlZCA9IFtdXSAtIGFycmF5IGRlIG9iamV0b3MsIGRlIGRpYXMgc2VsZWNjaW9uYWRvc1xuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBkZWwgaW5wdXQgY3JlYWRvXG4gICAqL1xuICBjcmVhdGVJbnB1dChcbiAgICBwcm9wcyxcbiAgICBkYXRhRGF5ID0gbnVsbCxcbiAgICBkYXlTZWxlY3RlZCA9IG51bGwsXG4gICAgc2VsZWN0ZWQgPSBbXSxcbiAgICB0YWJTZWxlY3RlZFxuICApIHtcbiAgICBsZXQgciA9IG51bGw7XG5cbiAgICBpZiAocHJvcHMuaWdub3JlUmVuZGVyID09IHRydWUpIHJldHVybiByO1xuXG4gICAgc3dpdGNoIChwcm9wcy50eXBlKSB7XG4gICAgICBjYXNlIFwiY3VzdG9tXCI6XG4gICAgICAgIHIgPSBwcm9wcy5yZW5kZXJcbiAgICAgICAgICA/IHByb3BzLnJlbmRlcih7IHByb3BzLCBkYXRhRGF5LCBkYXlTZWxlY3RlZCwgc2VsZWN0ZWQgfSlcbiAgICAgICAgICA6IG51bGw7XG4gICAgICAgIHIuc2V0QXR0cmlidXRlKFwiaW5wdXQta2V5XCIsIHByb3BzLmtleSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcInNlbGVjdFwiOlxuICAgICAgICByID0gdGhpcy5jcmVhdGVJbnB1dFNlbGVjdChwcm9wcywgZGF0YURheSwgZGF5U2VsZWN0ZWQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJmaWxlXCI6XG4gICAgICAgIHIgPSB0aGlzLmNyZWF0ZUlucHV0RmlsZShwcm9wcywgZGF0YURheSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcImZpbGVMaW5rXCI6XG4gICAgICAgIHIgPSB0aGlzLmNyZWF0ZUZpbGVMaW5rKHByb3BzLCBkYXRhRGF5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwidGV4dFwiOlxuICAgICAgICByID0gdGhpcy5jcmVhdGVUZXh0KHByb3BzLCBzZWxlY3RlZCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcInRpdGxlXCI6XG4gICAgICAgIHIgPSB0aGlzLmNyZWF0ZVRpdGxlKHByb3BzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgIHIgPSB0aGlzLmNyZWF0ZUlucHV0TnVtYmVyKHByb3BzLCBkYXRhRGF5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiZmxvYXRcIjpcbiAgICAgICAgciA9IHRoaXMuY3JlYXRlSW5wdXRGbG9hdChwcm9wcywgZGF0YURheSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcIm1lc3NhZ2VcIjpcbiAgICAgICAgciA9IHRoaXMuY3JlYXRlSW5wdXRNZXNzYWdlKHByb3BzLCBkYXRhRGF5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwidGV4dGFyZWFcIjpcbiAgICAgICAgciA9IHRoaXMuY3JlYXRlSW5wdXRUZXh0QXJlYShwcm9wcywgZGF0YURheSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcImNoZWNrYm94XCI6XG4gICAgICAgIHIgPSB0aGlzLmNyZWF0ZUlucHV0Q2hlY2tib3gocHJvcHMsIGRhdGFEYXkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJpbnB1dExpc3RcIjpcbiAgICAgICAgciA9IHRoaXMuY3JlYXRlSW5wdXRMaXN0KHByb3BzLCBkYXRhRGF5LCBkYXlTZWxlY3RlZCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcImlucHV0LWJveFwiOlxuICAgICAgICByID0gdGhpcy5jcmVhdGVJbnB1dEJveChwcm9wcywgZGF0YURheSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcImxpc3RcIjpcbiAgICAgICAgciA9IHRoaXMuY3JlYXRlTGlzdChwcm9wcywgZGF0YURheSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcImRhdGEtbGlzdFwiOlxuICAgICAgICByID0gdGhpcy5jcmVhdGVEYXRhTGlzdChcbiAgICAgICAgICBwcm9wcyxcbiAgICAgICAgICBkYXRhRGF5LFxuICAgICAgICAgIGRheVNlbGVjdGVkLFxuICAgICAgICAgIHNlbGVjdGVkLFxuICAgICAgICAgIHRhYlNlbGVjdGVkXG4gICAgICAgICk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcImJ1dHRvblwiOlxuICAgICAgICByID0gdGhpcy5jcmVhdGVJbnB1dEJ1dHRvbihwcm9wcywgZGF0YURheSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcImJ1dHRvbnMtZ3JvdXBcIjpcbiAgICAgICAgciA9IHRoaXMuY3JlYXRlSW5wdXRCdXR0b25zR3JvdXAocHJvcHMsIGRhdGFEYXkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJ0aW1lXCI6XG4gICAgICAgIHIgPSB0aGlzLmNyZWF0ZUlucHV0VGltZShwcm9wcywgZGF0YURheSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcImlucHV0LXRleHRcIjpcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHIgPSB0aGlzLmNyZWF0ZUlucHV0VGV4dChwcm9wcywgZGF0YURheSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHI7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgSW5wdXQgY29uIGZvcm1hdG8gSG9yYSwgY29tbyBlbGVtZW50byBEb21cbiAgICpcbiAgICogVXNhIDIgaW5wdXRzLCBob3JhIHkgbWludXRvc1xuICAgKlxuICAgKiBlbCB2YWx1ZSBxdWUgaW50ZXJwcmV0YSBlcyBTdHJpbmcgSEg6TU1cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHByb3BzIC0gY29uZmlnIHBhcmEgSW5wdXRcbiAgICogQHBhcmFtIHtPYmplY3R9IFtkYXRhRGF5ID0gbnVsbF0gLSB2YWxvcmVzIGRlIGl0ZW0geSBEaWEsIG9wY2lvbmFsXG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tIGRlbCBpbnB1dCBjcmVhZG9cbiAgICovXG4gIGNyZWF0ZUlucHV0VGltZShwcm9wcywgZGF0YURheSkge1xuICAgIGxldCBoaFZhbHVlID0gXCJcIjtcbiAgICBsZXQgbW1WYWx1ZSA9IFwiXCI7XG5cbiAgICBpZiAoZGF0YURheSAmJiBkYXRhRGF5LnZhbHVlcykge1xuICAgICAgbGV0IHZhbHVlID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGFEYXksIHByb3BzLnZhck5hbWUpO1xuXG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgdmFsdWUgPSB2YWx1ZS5zcGxpdChcIjpcIik7XG4gICAgICAgIGhoVmFsdWUgPSB2YWx1ZVswXTtcbiAgICAgICAgbW1WYWx1ZSA9IHZhbHVlWzFdO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCAkZWxlbSA9IGRvbS5jcmVhdGVFbGVtZW50RnJvbUhUTUwoYFxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWN0aW9uICR7XG4gICAgICAgICAgICBwcm9wcy5pc0hpZGRlbiA/IFwiaGlkZVwiIDogXCJcIlxuICAgICAgICAgIH0gXCIgaW5wdXQta2V5PVwiJHtwcm9wcy5rZXkgfHwgXCJcIn1cIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1zdWJ0aXRsZSBkLWJsb2NrXCI+XG4gICAgICAgICAgICAgICR7cHJvcHMubGFiZWwgfHwgXCJcIn1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXhcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRpbWVcIj5cbiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiXG4gICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJob3VyXCJcbiAgICAgICAgICAgICAgICAgICAgICBpZD1cInRlc3RcIlxuICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiMDBcIlxuICAgICAgICAgICAgICAgICAgICAgIG1pbj1cIjBcIlxuICAgICAgICAgICAgICAgICAgICAgIG1heD1cIjk5XCJcbiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT1cIiR7aGhWYWx1ZX1cIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN5bWJvbFwiPjo8L3NwYW4+XG4gICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibWludXRlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCIwMFwiXG4gICAgICAgICAgICAgICAgICAgICAgbWluPVwiMFwiXG4gICAgICAgICAgICAgICAgICAgICAgbWF4PVwiNTlcIlxuICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPVwiJHttbVZhbHVlfVwiPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LWhpbnRcIj5cbiAgICAgICAgICAgICAgICAke3Byb3BzLnRleHRIaW50IHx8IFwiXCJ9XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PmApO1xuXG4gICAgbGV0ICRoaElucHV0ID0gJGVsZW0ucXVlcnlTZWxlY3RvcihcIi5ob3VyXCIpO1xuICAgIGxldCAkbW1JbnB1dCA9ICRlbGVtLnF1ZXJ5U2VsZWN0b3IoXCIubWludXRlc1wiKTtcblxuICAgICRoaElucHV0LmFkZEV2ZW50TGlzdGVuZXIoXCJpbnB1dFwiLCAoZSkgPT4ge1xuICAgICAgJGhoSW5wdXQuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwiY2hhbmdlVGltZUlucHV0SEhcIiwge1xuICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICBrZXk6IHByb3BzLmtleSxcbiAgICAgICAgICAgIHZhbHVlOiBlLnNyY0VsZW1lbnQudmFsdWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICAkbW1JbnB1dC5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIiwgKGUpID0+IHtcbiAgICAgICRtbUlucHV0LmRpc3BhdGNoRXZlbnQoXG4gICAgICAgIG5ldyBDdXN0b21FdmVudChcImNoYW5nZVRpbWVJbnB1dE1NXCIsIHtcbiAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgIGNhbmNlbGFibGU6IGZhbHNlLFxuICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAga2V5OiBwcm9wcy5rZXksXG4gICAgICAgICAgICB2YWx1ZTogZS5zcmNFbGVtZW50LnZhbHVlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgdGhpcy5hZGRLZXlEb3duSW5wdXRFdmVudHMoJGhoSW5wdXQsICRlbGVtLCBwcm9wcyk7XG4gICAgdGhpcy5hZGRLZXlEb3duSW5wdXRFdmVudHMoJG1tSW5wdXQsICRlbGVtLCBwcm9wcyk7XG5cbiAgICByZXR1cm4gJGVsZW07XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgVGV4dCBjb21vIGVsZW1lbnRvIERvbVxuICAgKiBTZSBjb25maWd1cmEgY29tbyBpbnB1dCwgcGVybyBubyBkZXZ1ZWx2ZSBkYXRvcywgZXMgdW4gdGV4dG9cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHByb3BzIC0gY29uZmlnIHBhcmEgSW5wdXRcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gZGVsIGlucHV0IGNyZWFkb1xuICAgKi9cbiAgY3JlYXRlVGV4dChwcm9wcywgc2VsZWN0ZWQpIHtcbiAgICBsZXQgbGFiZWwgPSBwcm9wcy5sYWJlbDtcbiAgICBpZiAocHJvcHMuZm9ybWF0dGVyKSB7XG4gICAgICBsYWJlbCA9IHByb3BzLmZvcm1hdHRlcih7IHNlbGVjdGVkIH0pO1xuICAgIH1cbiAgICBsZXQgJGVsZW0gPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKGBcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtc2VjdGlvbiAke3Byb3BzLmlzSGlkZGVuID8gXCJoaWRlIFwiIDogXCJcIn0gJHtcbiAgICAgICAgICAgIHByb3BzLnRvTGVmdCA/IFwidG8tbGVmdCBcIiA6IFwiXCJcbiAgICAgICAgICB9IFwiIGlucHV0LWtleT1cIiR7cHJvcHMua2V5IHx8IFwiXCJ9XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cIiR7cHJvcHMuY2xhc3NOYW1lcyB8fCBcIlwifVwiPlxuICAgICAgICAgICAgJHtsYWJlbH1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5gKTtcbiAgICByZXR1cm4gJGVsZW07XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgVGl0bGUgY29tbyBlbGVtZW50byBEb21cbiAgICogU2UgY29uZmlndXJhIGNvbW8gaW5wdXQsIHBlcm8gbm8gZGV2dWVsdmUgZGF0b3MsIGVzIHVuIHRleHRvXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwcm9wcyAtIGNvbmZpZyBwYXJhIElucHV0XG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tIGRlbCBpbnB1dCBjcmVhZG9cbiAgICovXG4gIGNyZWF0ZVRpdGxlKHByb3BzKSB7XG4gICAgbGV0IGNsYXNzTmFtZXMgPSBcInRleHQtdGl0bGVcIjtcbiAgICBpZiAocHJvcHMuaXNTdWJ0aXRsZSkge1xuICAgICAgY2xhc3NOYW1lcyA9IFwidGV4dC1zdWJ0aXRsZVwiO1xuICAgIH1cbiAgICByZXR1cm4gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChgXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXNlY3Rpb24gJHtcbiAgICAgICAgICAgIHByb3BzLmlzSGlkZGVuID8gXCJoaWRlXCIgOiBcIlwiXG4gICAgICAgICAgfSBcIiBpbnB1dC1rZXk9XCIke3Byb3BzLmtleSB8fCBcIlwifVwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCIke2NsYXNzTmFtZXN9XCI+XG4gICAgICAgICAgICAgICR7cHJvcHMubGFiZWx9XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPC9kaXY+YCk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgSW5wdXQgdGlwbyBOdW1lcmljbyBjb21vIGVsZW1lbnRvIERvbVxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcHMgLSBjb25maWcgcGFyYSBJbnB1dFxuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YURheSAtIHZhbG9yZXMgZGUgaXRlbSB5IERpYSwgb3BjaW9uYWxcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gZGVsIGlucHV0IGNyZWFkb1xuICAgKi9cbiAgY3JlYXRlSW5wdXROdW1iZXIocHJvcHMsIGRhdGFEYXkpIHtcbiAgICBsZXQgdmFsdWUgPSBcIlwiO1xuICAgIGlmIChkYXRhRGF5ICYmIGRhdGFEYXkudmFsdWVzKSB7XG4gICAgICB2YWx1ZSA9IHV0aWxzLmdldFZhckJ5UGF0aChkYXRhRGF5LCBwcm9wcy52YXJOYW1lKTtcbiAgICB9XG4gICAgdmFsdWUgPSB2YWx1ZSB8fCBcIlwiO1xuXG4gICAgbGV0IGVsZW0gPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKGBcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtc2VjdGlvbiAke3Byb3BzLmNsYXNzTmFtZXMgfHwgXCJcIn0gJHtcbiAgICAgICAgICAgIHByb3BzLmlzSGlkZGVuID8gXCJoaWRlXCIgOiBcIlwiXG4gICAgICAgICAgfSBcIiBpbnB1dC1rZXk9XCIke3Byb3BzLmtleSB8fCBcIlwifVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXNlY3Rpb24tdGl0bGVcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXN1YnRpdGxlXCI+XG4gICAgICAgICAgICAgICAgJHtwcm9wcy5sYWJlbH1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtc3VidGl0bGUtMiBcIj5cbiAgICAgICAgICAgICAgICAke3Byb3BzLnN1ZmZpeCA/IFwiKFwiICsgcHJvcHMuc3VmZml4ICsgXCIpXCIgOiBcIlwifVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXhcIj5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm5hdi1pbnB1dFwiXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlPVwiJHt2YWx1ZX1cIj5cblxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtaGludFwiPlxuICAgICAgICAgICAgICAgICAgJHtwcm9wcy50ZXh0SGludCB8fCBcIlwifVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5gKTtcblxuICAgIGxldCBpbnB1dEVsZW0gPSBlbGVtLnF1ZXJ5U2VsZWN0b3IoXCJpbnB1dFwiKTtcblxuICAgIHRoaXMuYWRkS2V5RG93bklucHV0RXZlbnRzKGlucHV0RWxlbSwgZWxlbSwgcHJvcHMpO1xuXG4gICAgcmV0dXJuIGVsZW07XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgSW5wdXQgdGlwbyBGSWxlcGlja2VyIGNvbW8gZWxlbWVudG8gRG9tXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwcm9wcyAtIGNvbmZpZyBwYXJhIElucHV0XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhRGF5IC0gdmFsb3JlcyBkZSBpdGVtIHkgRGlhLCBvcGNpb25hbFxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBkZWwgaW5wdXQgY3JlYWRvXG4gICAqL1xuICBjcmVhdGVJbnB1dEZpbGUocHJvcHMsIGRhdGFEYXkpIHtcbiAgICBsZXQgdmFsdWUgPSBcIlwiO1xuICAgIGxldCBmaWxlTmFtZSA9IFwiXCI7XG4gICAgbGV0IGZpbGVQYXRoID0gXCJcIjtcblxuICAgIGlmIChkYXRhRGF5ICYmIGRhdGFEYXkudmFsdWVzKSB7XG4gICAgICB2YWx1ZSA9IHV0aWxzLmdldFZhckJ5UGF0aChkYXRhRGF5LCBwcm9wcy52YXJOYW1lKTtcbiAgICAgIGZpbGVOYW1lID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGFEYXksIHByb3BzLmZpbGVOYW1lVmFsdWUpO1xuICAgICAgZmlsZVBhdGggPSB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YURheSwgcHJvcHMuZmlsZVBhdGhWYWx1ZSk7XG4gICAgfVxuXG4gICAgdmFsdWUgPSB2YWx1ZSB8fCBcIlwiO1xuICAgIGZpbGVOYW1lID0gZmlsZU5hbWUgfHwgXCJcIjtcbiAgICBmaWxlUGF0aCA9IGZpbGVQYXRoIHx8IFwiXCI7XG5cbiAgICBsZXQgZWxlbSA9IGRvbS5jcmVhdGVFbGVtZW50RnJvbUhUTUwoYFxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWN0aW9uICR7cHJvcHMuY2xhc3NOYW1lcyB8fCBcIlwifSAke1xuICAgICAgICAgICAgcHJvcHMuaXNIaWRkZW4gPyBcImhpZGVcIiA6IFwiXCJcbiAgICAgICAgICB9IFwiIGlucHV0LWtleT1cIiR7cHJvcHMua2V5IHx8IFwiXCJ9XCI+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWN0aW9uLXRpdGxlXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1zdWJ0aXRsZVwiPlxuICAgICAgICAgICAgICAgICR7cHJvcHMubGFiZWx9XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibmF2LWlucHV0LWZpbGVcIiA+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJzbWFsbC1jbG9zZSBjbGVhci1maWxlLWlucHV0XCI+eDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8bGFiZWwgPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibmF2LWlucHV0LWZpbGUtbGFiZWxcIj5cbiAgICAgICAgICAgICAgICAgICR7cHJvcHMucGlja2VyTGFiZWwgfHwgXCJTZWxlY2Npb25hciBBcmNoaXZvXCJ9XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiZmlsZVwiIHZhbHVlPVwiJHt2YWx1ZX1cIj5cbiAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtc2VjdGlvbi1saW5rXCI+XG4gICAgICAgICAgICAgIDxhIGhyZWY9XCIke2ZpbGVQYXRofVwiIHRhcmdldD1cIl9ibGFua1wiID5cbiAgICAgICAgICAgICAgICAke2ZpbGVOYW1lfVxuICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwvZGl2PmApO1xuXG4gICAgbGV0ICRpbnB1dEVsZW0gPSBlbGVtLnF1ZXJ5U2VsZWN0b3IoXCJpbnB1dFwiKTtcbiAgICBsZXQgJGNsZWFyQnRuID0gZWxlbS5xdWVyeVNlbGVjdG9yKFwiLmNsZWFyLWZpbGUtaW5wdXRcIik7XG4gICAgbGV0ICRmaWxlSW5wdXRMYWJlbCA9IGVsZW0ucXVlcnlTZWxlY3RvcihcIi5uYXYtaW5wdXQtZmlsZS1sYWJlbFwiKTtcblxuICAgICRpbnB1dEVsZW0uYWRkRXZlbnRMaXN0ZW5lcihcImNoYW5nZVwiLCAoZXZ0KSA9PiB7XG4gICAgICBsZXQgZmlsZU5hbWUgPSAkaW5wdXRFbGVtLmZpbGVzWzBdLm5hbWU7XG4gICAgICAkZmlsZUlucHV0TGFiZWwudGV4dENvbnRlbnQgPSBmaWxlTmFtZTtcbiAgICB9KTtcblxuICAgICRjbGVhckJ0bi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGV2dCkgPT4ge1xuICAgICAgJGlucHV0RWxlbS52YWx1ZSA9IFwiXCI7XG4gICAgICAkZmlsZUlucHV0TGFiZWwudGV4dENvbnRlbnQgPSBwcm9wcy5waWNrZXJMYWJlbCB8fCBcIlNlbGVjY2lvbmFyIEFyY2hpdm9cIjtcbiAgICAgIGV2dC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBlbGVtO1xuICB9LFxuXG4gIGNyZWF0ZUZpbGVMaW5rKHByb3BzLCBkYXRhRGF5KSB7XG4gICAgbGV0IGZpbGVOYW1lID0gXCJcIjtcbiAgICBsZXQgZmlsZVBhdGggPSBcIlwiO1xuXG4gICAgaWYgKGRhdGFEYXkgJiYgZGF0YURheS52YWx1ZXMpIHtcbiAgICAgIC8vdmFsdWUgPSB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YURheSwgcHJvcHMudmFyTmFtZSk7XG4gICAgICBmaWxlTmFtZSA9IHV0aWxzLmdldFZhckJ5UGF0aChkYXRhRGF5LCBwcm9wcy5maWxlTmFtZVZhbHVlKTtcbiAgICAgIGZpbGVQYXRoID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGFEYXksIHByb3BzLmZpbGVQYXRoVmFsdWUpO1xuICAgIH1cblxuICAgIGlmIChmaWxlTmFtZSA9PSBcIlwiKSByZXR1cm4gbnVsbDtcblxuICAgIGZpbGVOYW1lID0gZmlsZU5hbWUgfHwgXCJcIjtcbiAgICBmaWxlUGF0aCA9IGZpbGVQYXRoIHx8IFwiXCI7XG5cbiAgICBsZXQgZWxlbSA9IGRvbS5jcmVhdGVFbGVtZW50RnJvbUhUTUwoYFxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWN0aW9uICR7cHJvcHMuY2xhc3NOYW1lcyB8fCBcIlwifSAke1xuICAgICAgICAgICAgcHJvcHMuaXNIaWRkZW4gPyBcImhpZGVcIiA6IFwiXCJcbiAgICAgICAgICB9IFwiIGlucHV0LWtleT1cIiR7cHJvcHMua2V5IHx8IFwiXCJ9XCI+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWN0aW9uLXRpdGxlXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1zdWJ0aXRsZVwiPlxuICAgICAgICAgICAgICAgICR7cHJvcHMubGFiZWx9XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtc2VjdGlvbi1saW5rXCI+XG4gICAgICAgICAgICAgIDxhIGhyZWY9XCIke2ZpbGVQYXRofVwiIHRhcmdldD1cIl9ibGFua1wiID5cbiAgICAgICAgICAgICAgICAke2ZpbGVOYW1lfVxuICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwvZGl2PmApO1xuXG4gICAgcmV0dXJuIGVsZW07XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgbGlzdGEgZGUgSW5wdXRzLCBjb24gYXJyYXkgZGUgdmFsb3JlcywgY29tbyBlbGVtZW50byBEb21cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHByb3BzIC0gY29uZmlnIHBhcmEgSW5wdXRcbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGFEYXkgLSB2YWxvcmVzIGRlIGl0ZW0geSBEaWEsIG9wY2lvbmFsXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbZGF5U2VsZWN0ZWQgPSBudWxsXSAtIGRhdG9zIGRlbCBkaWEgc2VsZWNjaW9uYWRvXG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tIGRlbCBpbnB1dCBjcmVhZG9cbiAgICovXG4gIGNyZWF0ZUlucHV0TGlzdChwcm9wcywgZGF0YURheSwgZGF5U2VsZWN0ZWQgPSBudWxsKSB7XG4gICAgbGV0IGlucHV0TGlzdCA9IFtdO1xuXG4gICAgLy9vYnRpZW5lIGlucHV0cyBkZWZhdWx0LCBwYXJhIGNyZWFybG9zLCBzaW4gdmFsb3Jlc1xuICAgIGlmIChcbiAgICAgIGRheVNlbGVjdGVkICYmXG4gICAgICBBcnJheS5pc0FycmF5KGRheVNlbGVjdGVkLml0ZW0udmFsdWVzW3Byb3BzLmlucHV0TGlzdF0pXG4gICAgKSB7XG4gICAgICBpbnB1dExpc3QgPSBkYXlTZWxlY3RlZC5pdGVtLnZhbHVlc1twcm9wcy5pbnB1dExpc3RdLm1hcCgoaW5wdXRSb3cpID0+IHtcbiAgICAgICAgLy9saW1waWEgaW5wdXRMaXN0IGlucHV0c1xuICAgICAgICBpbnB1dFJvdy5pbnB1dHMubWFwKChpbnB1dCkgPT4ge1xuICAgICAgICAgIGlucHV0LnZhbHVlID0gbnVsbDtcbiAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vb2J0aWVuZSB2YWxvcmVzIGRlbCBkaWFcbiAgICAgICAgaWYgKGRhdGFEYXkgJiYgZGF0YURheS52YWx1ZXMpIHtcbiAgICAgICAgICBsZXQgaW5wdXRWYWx1ZXMgPSB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YURheSwgcHJvcHMudmFsdWVzUGF0aCk7XG5cbiAgICAgICAgICAvL2F1dG9ycmVsbGVuYVxuICAgICAgICAgIGlmIChpbnB1dFZhbHVlcykge1xuICAgICAgICAgICAgaW5wdXRSb3cuaW5wdXRzLmZvckVhY2goKGlucHV0KSA9PiB7XG4gICAgICAgICAgICAgIGxldCB2YWx1ZXMgPSBpbnB1dFZhbHVlcy5maW5kKCh2KSA9PiB2LmlkID09IGlucHV0Um93LmlkKTtcbiAgICAgICAgICAgICAgaW5wdXQudmFsdWUgPSB2YWx1ZXMgPyB2YWx1ZXNbaW5wdXQudmFyTmFtZV0gOiBudWxsO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGlucHV0Um93O1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbGV0IHN0ciA9IGA8ZGl2IGlucHV0LWtleT1cIiR7cHJvcHMua2V5IHx8IFwiXCJ9XCIgY2xhc3M9XCJpbnB1dC1zZWN0aW9uLWxpc3QgJHtcbiAgICAgIHByb3BzLmlzSGlkZGVuID8gXCJoaWRlXCIgOiBcIlwiXG4gICAgfSBcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWN0aW9uLXRpdGxlXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC10aXRsZVwiPlxuICAgICAgICAgICAgICAgICR7cHJvcHMubGFiZWx9XG4gICAgICAgICAgICAgIDwvc3Bhbj4gXG4gICAgICAgICAgICA8L2Rpdj5gO1xuICAgIGlucHV0TGlzdC5mb3JFYWNoKChpbnB1dFJvdykgPT4ge1xuICAgICAgc3RyICs9IGBcbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWN0aW9uICR7XG4gICAgICAgICAgICAgICAgICAgIHByb3BzLnRvUmlnaHQgPyBcInRvLXJpZ2h0XCIgOiBcIlwiXG4gICAgICAgICAgICAgICAgICB9XCIgPlxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1zdWJ0aXRsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgJHtpbnB1dFJvdy5sYWJlbH1cbiAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+YDtcblxuICAgICAgaW5wdXRSb3cuaW5wdXRzLmZvckVhY2goKGlucHV0KSA9PiB7XG4gICAgICAgIHN0ciArPSBgIFxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtc2VjdGlvbi1jb2xcIiA+XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXN1YnRpdGxlIFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgJHtpbnB1dC5sYWJlbH1cbiAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LWlkPVwiJHtpbnB1dFJvdy5pZH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LWxhYmVsPVwiJHtpbnB1dC5sYWJlbH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibmF2LWlucHV0IHNtYWxsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT1cIiR7aW5wdXQudmFsdWV9XCI+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG4gICAgICB9KTtcbiAgICAgIHN0ciArPSBgXG4gICAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgIH0pO1xuICAgIHN0ciArPSBgPC9kaXY+YDtcblxuICAgIGxldCBlbGVtID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChzdHIpO1xuXG4gICAgbGV0IGlucHV0c0VsZW0gPSBlbGVtLnF1ZXJ5U2VsZWN0b3JBbGwoXCJpbnB1dFwiKTtcbiAgICBpbnB1dHNFbGVtLmZvckVhY2goKGlucHV0RWxlbSkgPT5cbiAgICAgIHRoaXMuYWRkS2V5RG93bklucHV0RXZlbnRzKGlucHV0RWxlbSwgZWxlbSwgcHJvcHMpXG4gICAgKTtcbiAgICByZXR1cm4gZWxlbTtcbiAgfSxcblxuICBjcmVhdGVJbnB1dFNlbGVjdChwcm9wcywgZGF0YURheSwgZGF5U2VsZWN0ZWQgPSBudWxsKSB7XG4gICAgbGV0IHZhbHVlID0gbnVsbDtcbiAgICBsZXQgb3B0aW9ucyA9IHByb3BzLm9wdGlvbnM7XG5cbiAgICBpZiAoZGF0YURheSAmJiBkYXRhRGF5LnZhbHVlcykge1xuICAgICAgbGV0IHZhbCA9IHV0aWxzLmdldFZhckJ5UGF0aChkYXRhRGF5LCBwcm9wcy52YXJOYW1lKTtcbiAgICAgIHZhbHVlID0gdmFsID8gdmFsLnZhbHVlIDogbnVsbDtcbiAgICB9XG5cbiAgICBsZXQgc3RyID0gYDxkaXYgaW5wdXQta2V5PVwiJHtwcm9wcy5rZXkgfHwgXCJcIn1cIiBjbGFzcz1cIiR7XG4gICAgICBwcm9wcy5pc0hpZGRlbiA/IFwiaGlkZVwiIDogXCJcIlxuICAgIH1cIiA+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtc2VjdGlvbiBcIiA+XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXN1YnRpdGxlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAke3Byb3BzLmxhYmVsfVxuICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cblxuICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJpbnB1dC1zZWxlY3RcIj5cblxuICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCIgJHt2YWx1ZSA9PSBudWxsID8gXCJzZWxlY3RlZFwiIDogXCJcIn0+XG4gICAgICAgICAgICAgICAgICAke3Byb3BzLm5vRGF0YUxhYmVsIHx8IFwiLS0gc2luIGFzaWduYXIgLS1cIn1cbiAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG5cbiAgICAgICAgYDtcblxuICAgIG9wdGlvbnMuZm9yRWFjaCgob3B0aW9uKSA9PiB7XG4gICAgICBzdHIgKz0gYFxuICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiJHtvcHRpb24uaWR9XCIgJHtcbiAgICAgICAgICAgICAgICAgICBvcHRpb24uaWQgPT0gdmFsdWUgPyBcInNlbGVjdGVkXCIgOiBcIlwiXG4gICAgICAgICAgICAgICAgIH0+XG4gICAgICAgICAgICAgICAgICR7b3B0aW9uLmxhYmVsfVxuICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICBgO1xuICAgIH0pO1xuICAgIHN0ciArPSBgXG5cbiAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICA8L2Rpdj5gO1xuXG4gICAgbGV0IGVsZW0gPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKHN0cik7XG5cbiAgICByZXR1cm4gZWxlbTtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBJbnB1dCBkZSB0ZXh0byBUZXh0QXJlYSBjb21vIGVsZW1lbnRvIERvbVxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcHMgLSBjb25maWcgcGFyYSBJbnB1dFxuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YURheSAtIHZhbG9yZXMgZGUgaXRlbSB5IERpYSwgb3BjaW9uYWxcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gZGVsIGlucHV0IGNyZWFkb1xuICAgKi9cbiAgY3JlYXRlSW5wdXRUZXh0QXJlYShwcm9wcywgZGF0YURheSkge1xuICAgIGxldCB2YWx1ZSA9IFwiXCI7XG4gICAgaWYgKGRhdGFEYXkgJiYgZGF0YURheS52YWx1ZXMpIHtcbiAgICAgIHZhbHVlID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGFEYXksIHByb3BzLnZhck5hbWUpO1xuICAgIH1cbiAgICBsZXQgZWxlbSA9IGRvbS5jcmVhdGVFbGVtZW50RnJvbUhUTUwoYFxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWN0aW9uICR7XG4gICAgICAgICAgICBwcm9wcy5pc0hpZGRlbiA/IFwiaGlkZVwiIDogXCJcIlxuICAgICAgICAgIH0gXCIgaW5wdXQta2V5PVwiJHtwcm9wcy5rZXkgfHwgXCJcIn1cIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1zdWJ0aXRsZSBkLWJsb2NrXCI+XG4gICAgICAgICAgICAgICR7cHJvcHMubGFiZWx9XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8dGV4dGFyZWEgY2xhc3M9XCJcIiB2YWx1ZT1cIiR7dmFsdWV9XCI+PC90ZXh0YXJlYT5cbiAgICAgICAgICA8L2Rpdj5gKTtcblxuICAgIGxldCBpbnB1dEVsZW0gPSBlbGVtLnF1ZXJ5U2VsZWN0b3IoXCJ0ZXh0YXJlYVwiKTtcbiAgICB0aGlzLmFkZEtleURvd25JbnB1dEV2ZW50cyhpbnB1dEVsZW0sIGVsZW0sIHByb3BzKTtcbiAgICByZXR1cm4gZWxlbTtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBJbnB1dCBkZSBNZW5zYWplIGNvbW8gZWxlbWVudG8gRG9tXG4gICAqIHV0aWxpemEgVGV4dEFyZWFcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHByb3BzIC0gY29uZmlnIHBhcmEgSW5wdXRcbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGFEYXkgLSB2YWxvcmVzIGRlIGl0ZW0geSBEaWEsIG9wY2lvbmFsXG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tIGRlbCBpbnB1dCBjcmVhZG9cbiAgICovXG4gIGNyZWF0ZUlucHV0TWVzc2FnZShwcm9wcywgZGF0YURheSkge1xuICAgIGxldCB2YWx1ZSA9IGRhdGFEYXkgPyB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YURheSwgcHJvcHMudmFyTmFtZSkgOiBudWxsO1xuICAgIGxldCBlbGVtID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChgXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXNlY3Rpb24gdG8tbGVmdCBtc2otaW5wdXQtY29udGFpbmVyICR7XG4gICAgICAgICAgICBwcm9wcy5pc0hpZGRlbiA/IFwiaGlkZVwiIDogXCJcIlxuICAgICAgICAgIH0gXCJcbiAgICAgICAgICAgICAgaW5wdXQta2V5PVwiJHtwcm9wcy5rZXkgfHwgXCJcIn1cIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1zdWJ0aXRsZSBkLWJsb2NrXCI+XG4gICAgICAgICAgICAgIE1lbnNhamVcbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDx0ZXh0YXJlYSBjbGFzcz1cIm1zalwiPiR7dmFsdWUgfHwgXCJcIn08L3RleHRhcmVhPlxuICAgICAgICAgIDwvZGl2PmApO1xuXG4gICAgbGV0IGlucHV0RWxlbSA9IGVsZW0ucXVlcnlTZWxlY3RvcihcInRleHRhcmVhXCIpO1xuICAgIC8vdGhpcy5hZGRLZXlEb3duSW5wdXRFdmVudHMoaW5wdXRFbGVtKTtcbiAgICByZXR1cm4gZWxlbTtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBJbnB1dCBkZSB0ZXh0byBjb21vIGVsZW1lbnRvIERvbVxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcHMgLSBjb25maWcgcGFyYSBJbnB1dFxuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YURheSAtIHZhbG9yZXMgZGUgaXRlbSB5IERpYSwgb3BjaW9uYWxcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gZGVsIGlucHV0IGNyZWFkb1xuICAgKi9cbiAgY3JlYXRlSW5wdXRUZXh0KHByb3BzLCBkYXRhRGF5KSB7XG4gICAgbGV0IHZhbHVlID0gXCJcIjtcbiAgICBpZiAoZGF0YURheSAmJiBkYXRhRGF5LnZhbHVlcykge1xuICAgICAgdmFsdWUgPSB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YURheSwgcHJvcHMudmFyTmFtZSk7XG4gICAgfVxuICAgIGxldCBlbGVtID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChgXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXNlY3Rpb24gJHtcbiAgICAgICAgICAgIHByb3BzLmlzSGlkZGVuID8gXCJoaWRlXCIgOiBcIlwiXG4gICAgICAgICAgfSBcIiBpbnB1dC1rZXk9XCIke3Byb3BzLmtleSB8fCBcIlwifVwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXN1YnRpdGxlIGQtYmxvY2tcIj5cbiAgICAgICAgICAgICAgJHtwcm9wcy5sYWJlbH1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwibmF2LWlucHV0XCIgdmFsdWU9XCIke3ZhbHVlfVwiPlxuICAgICAgICAgIDwvZGl2PmApO1xuXG4gICAgbGV0IGlucHV0RWxlbSA9IGVsZW0ucXVlcnlTZWxlY3RvcihcImlucHV0XCIpO1xuICAgIHRoaXMuYWRkS2V5RG93bklucHV0RXZlbnRzKGlucHV0RWxlbSwgZWxlbSwgcHJvcHMpO1xuICAgIHJldHVybiBlbGVtO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhIElucHV0IE51bWVybyBGbG90YW50ZSwgY29tbyBlbGVtZW50byBEb21cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHByb3BzIC0gY29uZmlnIHBhcmEgSW5wdXRcbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGFEYXkgLSB2YWxvcmVzIGRlIGl0ZW0geSBEaWEsIG9wY2lvbmFsXG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tIGRlbCBpbnB1dCBjcmVhZG9cbiAgICovXG4gIGNyZWF0ZUlucHV0RmxvYXQocHJvcHMsIGRhdGFEYXkpIHtcbiAgICBsZXQgdmFsdWUgPSBcIlwiO1xuICAgIGlmIChkYXRhRGF5ICYmIGRhdGFEYXkudmFsdWVzKSB7XG4gICAgICB2YWx1ZSA9IHV0aWxzLmdldFZhckJ5UGF0aChkYXRhRGF5LCBwcm9wcy52YXJOYW1lKTtcbiAgICB9XG4gICAgbGV0IGVsZW0gPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKGBcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtc2VjdGlvbiAke1xuICAgICAgICAgICAgcHJvcHMuaXNIaWRkZW4gPyBcImhpZGVcIiA6IFwiXCJcbiAgICAgICAgICB9IFwiIGlucHV0LWtleT1cIiR7cHJvcHMua2V5IHx8IFwiXCJ9XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtc3VidGl0bGUgZC1ibG9ja1wiPlxuICAgICAgICAgICAgICAke3Byb3BzLmxhYmVsfVxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBjbGFzcz1cIm5hdi1pbnB1dFwiIHZhbHVlPVwiJHt2YWx1ZX1cIj5cbiAgICAgICAgICA8L2Rpdj5gKTtcblxuICAgIGxldCBpbnB1dEVsZW0gPSBlbGVtLnF1ZXJ5U2VsZWN0b3IoXCJpbnB1dFwiKTtcbiAgICB0aGlzLmFkZEtleURvd25JbnB1dEV2ZW50cyhpbnB1dEVsZW0sIGVsZW0sIHByb3BzKTtcbiAgICByZXR1cm4gZWxlbTtcbiAgfSxcblxuICBjcmVhdGVEYXRhTGlzdChwcm9wcywgZGF0YURheSwgZGF5U2VsZWN0ZWQsIHNlbGVjdGVkLCB0YWJTZWxlY3RlZCkge1xuICAgIGxldCBsaXN0ID0gW107XG4gICAgaWYgKGRhdGFEYXkgJiYgZGF0YURheS52YWx1ZXMpIHtcbiAgICAgIGxpc3QgPSB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YURheSwgcHJvcHMudmFyTmFtZSkgfHwgW107XG4gICAgfVxuXG4gICAgbGV0IHNlYXJjaElucHV0ID0gcHJvcHMuaGlkZVNlYXJjaFxuICAgICAgPyBcIlwiXG4gICAgICA6IGAgPGRpdiBjbGFzcz1cInNlYXJjaC1pbnB1dC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPVwiXCIgdHlwZT1cInRleHRcIiBuYW1lPVwiXCIgY2xhc3M9XCJzZWFyY2gtaW5wdXRcIiBwbGFjZWhvbGRlcj1cImJ1c2NhclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwic2VhcmNoLWlucHV0LWNsZWFyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICR7aWNvbnMuY2xvc2VJY29ufVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG5cbiAgICBsZXQgZWRpdEJ0biA9IFwiXCI7XG5cbiAgICBpZiAocHJvcHMuZWRpdEJ1dHRvbikge1xuICAgICAgZWRpdEJ0biA9IGA8YnV0dG9uIGNsYXNzPVwiY2FwLWJ0bi1yYWlzZWQgY2FwLWJ0bi1zbSBlZGl0LWJ0blwiIGlucHV0LWtleT1cIiR7cHJvcHMuZWRpdEJ1dHRvbi5rZXl9XCI+XG4gICAgICAgICAgICAgICAgICAgICR7cHJvcHMuZWRpdEJ1dHRvbi5sYWJlbH0gXG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj4gYDtcbiAgICB9XG5cbiAgICBsZXQgc3RyID0gYFxuICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXNlY3Rpb24gJHtwcm9wcy5pc0hpZGRlbiA/IFwiaGlkZVwiIDogXCJcIn0gXCIgaW5wdXQta2V5PVwiJHtcbiAgICAgICAgcHJvcHMua2V5IHx8IFwiXCJcbiAgICAgIH1cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXNlY3Rpb24tdGl0bGVcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1zdWJ0aXRsZSBkLWJsb2NrXCI+XG4gICAgICAgICAgICAgICAgJHtwcm9wcy5sYWJlbH1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAke2VkaXRCdG59XHRcbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ib3ggXCIgaW5wdXQta2V5PVwiJHtwcm9wcy5rZXkgfHwgXCJcIn1cIj5cbiAgICAgICAgICAgICR7c2VhcmNoSW5wdXR9XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+IGA7XG5cbiAgICBsZXQgJGVsID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChzdHIpO1xuICAgIGxldCAkc2VhcmNoSW5wdXQgPSAkZWwucXVlcnlTZWxlY3RvcihcIi5zZWFyY2gtaW5wdXRcIik7XG4gICAgbGV0ICRzZWFyY2hJbnB1dENsZWFyID0gJGVsLnF1ZXJ5U2VsZWN0b3IoXCIuc2VhcmNoLWlucHV0LWNsZWFyXCIpO1xuICAgIGxldCAkaW5wdXRCb3ggPSAkZWwucXVlcnlTZWxlY3RvcihcIi5pbnB1dC1ib3hcIik7XG5cbiAgICBsZXQgJGl0ZW1zID0gbGlzdC5tYXAoKGl0ZW0sIGopID0+IHtcbiAgICAgIGxldCBsYWJlbCA9XG4gICAgICAgIHV0aWxzLmdldFZhckJ5UGF0aChpdGVtLCBwcm9wcy52YXJOYW1lTGFiZWwpIHx8IGRhdGFEYXkubGFiZWwgfHwgXCJfX1wiO1xuXG4gICAgICBsZXQgJGVsSXRlbSA9IHRoaXMuY3JlYXRlRGF0YUxpc3RJdGVtKHtcbiAgICAgICAgbGFiZWwsXG4gICAgICAgIHZhbHVlVGV4dDogdXRpbHMuZ2V0VmFyQnlQYXRoKGl0ZW0sIHByb3BzLnZhck5hbWVWYWx1ZVRleHQpIHx8IFwiXCIsXG4gICAgICAgIHN1YlRleHQ6IHV0aWxzLmdldFZhckJ5UGF0aChpdGVtLCBwcm9wcy52YXJOYW1lU3ViVGV4dCkgfHwgXCJcIixcbiAgICAgICAgaWQ6IFwibGlzdC1pdGVtLVwiICsgKGRhdGFEYXkuaWQgfHwgaiksXG4gICAgICAgIGtleTogXCJsaXN0LWl0ZW0tXCIgKyAoZGF0YURheS5pZCB8fCBqKSxcbiAgICAgICAgdG9vbHRpcDogdXRpbHMuZ2V0VmFyQnlQYXRoKGl0ZW0sIHByb3BzLnZhck5hbWVUb29sdGlwKSB8fCBsYWJlbCxcbiAgICAgICAgLy9jb2xvckljb246IFwiYy1yZWRcIixcbiAgICAgICAgbGluazogdXRpbHMuZ2V0VmFyQnlQYXRoKGl0ZW0sIHByb3BzLnZhck5hbWVMaW5rKSB8fCBudWxsLFxuICAgICAgICBzdWZmaXg6IHV0aWxzLmdldFZhckJ5UGF0aChpdGVtLCBwcm9wcy52YXJOYW1lU3VmZml4KSB8fCBcIlwiLFxuICAgICAgICAvL3ZhbHVlOiBKU09OLnN0cmluZ2lmeSh1dGlscy5nZXRWYXJCeVBhdGgoaXRlbSwgcHJvcHMudmFyTmFtZUlucHV0KSkgfHwge31cbiAgICAgIH0pO1xuICAgICAgJGlucHV0Qm94LmFwcGVuZENoaWxkKCRlbEl0ZW0pO1xuICAgIH0pO1xuXG4gICAgaWYgKCRzZWFyY2hJbnB1dCkge1xuICAgICAgJHNlYXJjaElucHV0Q2xlYXIuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgICRzZWFyY2hJbnB1dC52YWx1ZSA9IFwiXCI7XG4gICAgICAgICRzZWFyY2hJbnB1dC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcImlucHV0XCIsIHsgYnViYmxlczogdHJ1ZSB9KSk7XG4gICAgICB9KTtcblxuICAgICAgJHNlYXJjaElucHV0LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXlkb3duXCIsIChlKSA9PiB7XG4gICAgICAgIGlmIChlLmtleSA9PT0gXCJFc2NhcGVcIikge1xuICAgICAgICAgICRzZWFyY2hJbnB1dC52YWx1ZSA9IFwiXCI7XG4gICAgICAgICAgJHNlYXJjaElucHV0LmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwiaW5wdXRcIiwgeyBidWJibGVzOiB0cnVlIH0pKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgICRzZWFyY2hJbnB1dC5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIiwgKGUpID0+IHtcbiAgICAgICAgbGV0ICRpbnB1dHMgPSBbXTtcbiAgICAgICAgJGlucHV0cyA9ICRlbC5xdWVyeVNlbGVjdG9yQWxsKFwiLm1pbmktaW5wdXQtc2VjdGlvblwiKSB8fCBbXTtcbiAgICAgICAgJGlucHV0cy5mb3JFYWNoKCgkaSkgPT4ge1xuICAgICAgICAgIGxldCBsYWJlbCA9ICRpLmdldEF0dHJpYnV0ZShcImxhYmVsXCIpO1xuICAgICAgICAgIGxldCBzZWFyY2ggPSAkc2VhcmNoSW5wdXQudmFsdWU7XG4gICAgICAgICAgaWYgKGxhYmVsLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoc2VhcmNoLnRvTG93ZXJDYXNlKCkpKSB7XG4gICAgICAgICAgICAkaS5jbGFzc0xpc3QucmVtb3ZlKFwiaGlkZVwiKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgJGkuY2xhc3NMaXN0LmFkZChcImhpZGVcIik7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChwcm9wcy5lZGl0QnV0dG9uLm9uQ2xpY2spIHtcbiAgICAgIGxldCBidXR0b24gPSAkZWwucXVlcnlTZWxlY3RvcihcImJ1dHRvbi5lZGl0LWJ0blwiKTtcbiAgICAgIGlmIChidXR0b24gJiYgcHJvcHMuZWRpdEJ1dHRvbikge1xuICAgICAgICBidXR0b24uYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PlxuICAgICAgICAgIHByb3BzLmVkaXRCdXR0b24ub25DbGljayh7XG4gICAgICAgICAgICBldmVudDogZSxcbiAgICAgICAgICAgIHByb3BzLFxuICAgICAgICAgICAgZGF0YURheSxcbiAgICAgICAgICAgIGRheVNlbGVjdGVkLFxuICAgICAgICAgICAgc2VsZWN0ZWQsXG4gICAgICAgICAgICAkZWxlbWVudDogJGVsLFxuICAgICAgICAgICAgdGFiU2VsZWN0ZWQsXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgICRpdGVtcy5mb3JFYWNoKCgkaSkgPT4ge1xuICAgICAgICAkZWwuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgICAgcHJvcHMuZWRpdEJ1dHRvbi5vbkNsaWNrKHtcbiAgICAgICAgICAgIGV2ZW50OiBlLFxuICAgICAgICAgICAgcHJvcHMsXG4gICAgICAgICAgICBkYXRhRGF5LFxuICAgICAgICAgICAgZGF5U2VsZWN0ZWQsXG4gICAgICAgICAgICBzZWxlY3RlZCxcbiAgICAgICAgICAgICRlbGVtZW50OiAkZWwsXG4gICAgICAgICAgICB0YWJTZWxlY3RlZCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gJGVsO1xuICB9LFxuXG4gIGNyZWF0ZURhdGFMaXN0SXRlbSh7XG4gICAgbGFiZWwgPSBcIlwiLFxuICAgIHZhbHVlVGV4dCA9IFwiXCIsXG4gICAgc3ViVGV4dCA9IFwiXCIsXG4gICAgaWQgPSBcIlwiLFxuICAgIGtleSA9IFwiXCIsXG4gICAgdG9vbHRpcCA9IFwiXCIsXG4gICAgY29sb3JJY29uID0gXCJcIixcbiAgICBsaW5rID0gbnVsbCxcbiAgICBzdWZmaXggPSBudWxsLFxuICAgIHZhbHVlID0gXCJcIixcbiAgfSkge1xuICAgIGxldCB0b29sdGlwU3RyID0gXCJcIjtcbiAgICBsZXQgaWNvblN0ciA9IG51bGw7XG4gICAgbGV0IGxpbmtTdHIgPSBcIlwiO1xuICAgIGxldCBzdHIgPSBcIlwiO1xuXG4gICAgaWYgKHRvb2x0aXApIHtcbiAgICAgIHRvb2x0aXBTdHIgPSBgXG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS10b29sdGlwXCI+XG4gICAgICAgICAgICAgICAgICAgICR7dG9vbHRpcH1cbiAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG4gICAgfVxuXG4gICAgaWYgKGNvbG9ySWNvbikge1xuICAgICAgaWYgKHV0aWxzLmlzSGV4Q29sb3IoaXRlbUZvcm1hdGVkLmNvbG9ySWNvbikpIHtcbiAgICAgICAgaWNvblN0ciA9IGA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS1pY29uXCIgc3R5bGU9XCJiYWNrZ3JvdW5kOiR7Y29sb3JJY29ufVwiPiA8L2Rpdj5gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWNvblN0ciA9IGA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS1pY29uICR7Y29sb3JJY29ufVwiPiA8L2Rpdj5gO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChsaW5rKSB7XG4gICAgICBsaW5rU3RyID0gYDxhIGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS1saW5rXCIgdGFyZ2V0PVwiX2JsYW5rXCIgaHJlZj1cIiR7bGlua31cIj4ke2ljb25zLmxpbmtJY29ufTwvYT4gYDtcbiAgICB9XG5cbiAgICBzdHIgKz0gYFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbiBjbGlja2VhYmxlICR7XG4gICAgICAgICAgICAgIGljb25TdHIgPyBcImhhcy1pY29uXCIgOiBcIlwiXG4gICAgICAgICAgICB9IFwiIFxuICAgICAgICAgICAgICAgIGxhYmVsPVwiJHtsYWJlbH1cIiBcbiAgICAgICAgICAgICAgICBkYXRhLWlkPVwiJHtpZH1cIlxuICAgICAgICAgICAgICAgIGRhdGEta2V5PVwiJHtrZXl9XCJcbiAgICAgICAgICAgICAgICBkYXRhLXZhbHVlPVwiJHt2YWx1ZSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8bGFiZWw+XG4gICAgICAgICAgICAgICAgJHtpY29uU3RyIHx8IFwiXCJ9XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS10aXRsZXNcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLXRpdGxlIHRydW5jYXRlXCI+XG4gICAgICAgICAgICAgICAgICAgICR7bGFiZWx9XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLXN1YnRpdGxlIHRydW5jYXRlXCI+XG4gICAgICAgICAgICAgICAgICAgICR7c3ViVGV4dH1cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbi0tY29udGVudFwiID5cbiAgICAgICAgICAgICAgICAgICR7dmFsdWVUZXh0fVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLXN1ZmZpeFwiID5cbiAgICAgICAgICAgICAgICAgICR7c3VmZml4fVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgJHtsaW5rU3RyfVxuXG4gICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICR7dG9vbHRpcFN0cn1cbiAgICAgICAgICAgIDwvZGl2PmA7XG4gICAgcmV0dXJuIGRvbS5jcmVhdGVFbGVtZW50RnJvbUhUTUwoc3RyKTtcbiAgfSxcblxuICBjcmVhdGVMaXN0KHByb3BzLCBkYXRhRGF5KSB7XG4gICAgbGV0IHRhYnNDb250YWluZXIgPSBcIlwiO1xuXG4gICAgaWYgKHByb3BzLnRhYnMpIHtcbiAgICAgIGxldCB0YWJzID0gXCJcIjtcbiAgICAgIHByb3BzLnRhYnMuZm9yRWFjaCgodGFiKSA9PiB7XG4gICAgICAgIHRhYnMgKz0gYFxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtYm94LXRhYlwiIHRhYi1rZXk9XCIke3RhYi5rZXl9XCI+XG4gICAgICAgICAgJHt0YWIubmFtZX1cbiAgICAgICAgPC9kaXY+YDtcbiAgICAgIH0pO1xuXG4gICAgICB0YWJzQ29udGFpbmVyID0gYFxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtYm94LXRhYi1jb250YWluZXJcIj5cbiAgICAgICAgJHt0YWJzfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIGA7XG4gICAgfVxuXG4gICAgbGV0IHNlYXJjaElucHV0ID0gYFxuICAgICAgPGRpdiBjbGFzcz1cInNlYXJjaC1pbnB1dC1jb250YWluZXJcIj5cbiAgICAgICAgPGlucHV0IGlkPVwiXCIgdHlwZT1cInRleHRcIiBuYW1lPVwiXCIgY2xhc3M9XCJzZWFyY2gtaW5wdXRcIiBwbGFjZWhvbGRlcj1cImJ1c2NhclwiPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwic2VhcmNoLWlucHV0LWNsZWFyXCI+XG4gICAgICAgICAke2ljb25zLmNsb3NlSWNvbn1cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICBgO1xuXG4gICAgbGV0IHN0ciA9IGBcbiAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWN0aW9uICR7cHJvcHMuaXNIaWRkZW4gPyBcImhpZGVcIiA6IFwiXCJ9IFwiIGlucHV0LWtleT1cIiR7XG4gICAgICAgIHByb3BzLmtleSB8fCBcIlwiXG4gICAgICB9XCI+XG4gICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1zdWJ0aXRsZSBkLWJsb2NrXCI+XG4gICAgICAgICAgICAgICR7cHJvcHMubGFiZWx9XG4gICAgICAgICAgICA8L3NwYW4+XG5cbiAgICAgICAgICAgICR7dGFic0NvbnRhaW5lcn1cbiAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWJveCBcIiBpbnB1dC1rZXk9XCIke3Byb3BzLmtleSB8fCBcIlwifVwiPlxuXG4gICAgICAgICAgICAke3NlYXJjaElucHV0fVxuICAgICAgYDtcblxuICAgIC8vVE9ETyBvYnRlbmVyIGlucHV0IHNlZ3VuIGZpbGFcbiAgICBpZiAocHJvcHMuaW5wdXRzKSB7XG4gICAgICBwcm9wcy5pbnB1dHMuZm9yRWFjaCgoaSkgPT4ge1xuICAgICAgICBpZiAoaS5pc1RpdGxlKSB7XG4gICAgICAgICAgbGV0IHRvb2x0aXAgPSBcIlwiO1xuICAgICAgICAgIGxldCBpY29uID0gbnVsbDtcblxuICAgICAgICAgIGlmIChpLnRvb2x0aXApIHtcbiAgICAgICAgICAgIHRvb2x0aXAgPSBgXG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS10b29sdGlwXCI+XG4gICAgICAgICAgICAgICAgICAgICR7aS50b29sdGlwfVxuICAgICAgICAgICAgICAgICAgICAke2kuc3VmZml4ID8gXCIoXCIgKyBpLnN1ZmZpeCArIFwiKVwiIDogXCJcIn1cbiAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGkuY29sb3JJY29uKSB7XG4gICAgICAgICAgICBpZiAodXRpbHMuaXNIZXhDb2xvcihpLmNvbG9ySWNvbikpIHtcbiAgICAgICAgICAgICAgaWNvbiA9IGA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS1pY29uXCIgc3R5bGU9XCJiYWNrZ3JvdW5kOiR7aS5jb2xvckljb259XCI+IDwvZGl2PmA7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpY29uID0gYDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLWljb24gJHtpLmNvbG9ySWNvbn1cIj4gPC9kaXY+YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzdHIgKz0gYFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbiBpcy10aXRsZSAgJHtcbiAgICAgICAgICAgICAgaWNvbiA/IFwiaGFzLWljb25cIiA6IFwiXCJcbiAgICAgICAgICAgIH1cIiBpbnB1dC10YWIta2V5PVwiJHtpLnRhYktleSB8fCBcIlwifVwiIGxhYmVsPVwiJHtpLmxhYmVsfVwiPlxuICAgICAgICAgICAgICA8bGFiZWw+XG4gICAgICAgICAgICAgICAgJHtpY29uIHx8IFwiXCJ9XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbi0tdGl0bGUgdHJ1bmNhdGVcIj5cbiAgICAgICAgICAgICAgICAgICR7aS5sYWJlbH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgJHt0b29sdGlwfVxuICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsZXQgdG9vbHRpcCA9IFwiXCI7XG4gICAgICAgICAgbGV0IGljb24gPSBudWxsO1xuICAgICAgICAgIGxldCBsaW5rID0gXCJcIjtcblxuICAgICAgICAgIGlmIChpLnRvb2x0aXApIHtcbiAgICAgICAgICAgIHRvb2x0aXAgPSBgXG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS10b29sdGlwXCI+XG4gICAgICAgICAgICAgICAgICAgICR7aS50b29sdGlwfVxuICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaS5jb2xvckljb24pIHtcbiAgICAgICAgICAgIGlmICh1dGlscy5pc0hleENvbG9yKGkuY29sb3JJY29uKSkge1xuICAgICAgICAgICAgICBpY29uID0gYDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLWljb25cIiBzdHlsZT1cImJhY2tncm91bmQ6JHtpLmNvbG9ySWNvbn1cIj4gPC9kaXY+YDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGljb24gPSBgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbi0taWNvbiAke2kuY29sb3JJY29ufVwiPiA8L2Rpdj5gO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChpLmxpbmspIHtcbiAgICAgICAgICAgIGxpbmsgPSBgPGEgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLWxpbmtcIiB0YXJnZXQ9XCJfYmxhbmtcIiBocmVmPVwiJHtpLmxpbmt9XCI+XG4gICAgICAgICAgICAgICAgJHtpY29ucy5saW5rSWNvbn1cbiAgICAgICAgICAgICAgICA8L2E+IGA7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3RyICs9IGBcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24gICR7XG4gICAgICAgICAgICAgIGljb24gPyBcImhhcy1pY29uXCIgOiBcIlwiXG4gICAgICAgICAgICB9XCIgaW5wdXQtdGFiLWtleT1cIiR7aS50YWJLZXkgfHwgXCJcIn1cIiBsYWJlbD1cIiR7aS5sYWJlbH1cIj5cbiAgICAgICAgICAgICAgPGxhYmVsPlxuXG4gICAgICAgICAgICAgICAgJHtpY29ufVxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbi0tdGl0bGUgdHJ1bmNhdGVcIj5cbiAgICAgICAgICAgICAgICAgICR7aS5sYWJlbH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLXN1ZmZpeFwiID4ke1xuICAgICAgICAgICAgICAgICAgaS5zdWZmaXggPyBcIihcIiArIGkuc3VmZml4ICsgXCIpXCIgOiBcIlwiXG4gICAgICAgICAgICAgICAgfTwvZGl2PlxuXG4gICAgICAgICAgICAgICAgJHtsaW5rfVxuXG4gICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLWZvb3RlclwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhcnRcIj4gc3RhcnQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJlbmRcIj4gZW5kIDwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICR7dG9vbHRpcH1cbiAgICAgICAgICAgIDwvZGl2PmA7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHN0ciArPSBgXG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+IGA7XG5cbiAgICBsZXQgJGVsID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChzdHIpO1xuICAgIGxldCAkdGFicyA9ICRlbC5xdWVyeVNlbGVjdG9yQWxsKFwiLmlucHV0LWJveC10YWJbdGFiLWtleV1cIikgfHwgW107XG4gICAgbGV0ICRzZWFyY2hJbnB1dCA9ICRlbC5xdWVyeVNlbGVjdG9yKFwiLnNlYXJjaC1pbnB1dFwiKSB8fCBudWxsO1xuICAgIGxldCAkc2VhcmNoSW5wdXRDbGVhciA9ICRlbC5xdWVyeVNlbGVjdG9yKFwiLnNlYXJjaC1pbnB1dC1jbGVhclwiKSB8fCBudWxsO1xuXG4gICAgJHRhYnMuZm9yRWFjaCgodCkgPT4ge1xuICAgICAgdC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgdGhpcy5zZWxlY3RJbnB1dEJveFRhYih0LCAkZWwpO1xuICAgICAgICAkc2VhcmNoSW5wdXQudmFsdWUgPSBcIlwiO1xuICAgICAgICAkc2VhcmNoSW5wdXQuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJpbnB1dFwiLCB7IGJ1YmJsZXM6IHRydWUgfSkpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpZiAoJHNlYXJjaElucHV0Q2xlYXIpIHtcbiAgICAgICRzZWFyY2hJbnB1dENsZWFyLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZSkgPT4ge1xuICAgICAgICAkc2VhcmNoSW5wdXQudmFsdWUgPSBcIlwiO1xuICAgICAgICAkc2VhcmNoSW5wdXQuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJpbnB1dFwiLCB7IGJ1YmJsZXM6IHRydWUgfSkpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKCRzZWFyY2hJbnB1dCkge1xuICAgICAgJHNlYXJjaElucHV0LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXlkb3duXCIsIChlKSA9PiB7XG4gICAgICAgIGlmIChlLmtleSA9PT0gXCJFc2NhcGVcIikge1xuICAgICAgICAgICRzZWFyY2hJbnB1dC52YWx1ZSA9IFwiXCI7XG4gICAgICAgICAgJHNlYXJjaElucHV0LmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwiaW5wdXRcIiwgeyBidWJibGVzOiB0cnVlIH0pKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgICRzZWFyY2hJbnB1dC5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIiwgKGUpID0+IHtcbiAgICAgICAgbGV0ICR0YWJTZWxlY3RlZCA9XG4gICAgICAgICAgJGVsLnF1ZXJ5U2VsZWN0b3IoXCIuaW5wdXQtYm94LXRhYlt0YWIta2V5XS5hY3RpdmVcIikgfHwgbnVsbDtcbiAgICAgICAgbGV0ICRpbnB1dHMgPSBbXTtcbiAgICAgICAgaWYgKCR0YWJTZWxlY3RlZCkge1xuICAgICAgICAgIGxldCB0YWJLZXkgPSAkdGFiU2VsZWN0ZWQuZ2V0QXR0cmlidXRlKFwidGFiLWtleVwiKTtcbiAgICAgICAgICAkaW5wdXRzID1cbiAgICAgICAgICAgICRlbC5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgICAgICAgICBcIi5taW5pLWlucHV0LXNlY3Rpb25baW5wdXQtdGFiLWtleT0nXCIgKyB0YWJLZXkgKyBcIiddXCJcbiAgICAgICAgICAgICkgfHwgW107XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgJGlucHV0cyA9ICRlbC5xdWVyeVNlbGVjdG9yQWxsKFwiLm1pbmktaW5wdXQtc2VjdGlvblwiKSB8fCBbXTtcbiAgICAgICAgfVxuICAgICAgICAkaW5wdXRzLmZvckVhY2goKCRpKSA9PiB7XG4gICAgICAgICAgbGV0IGxhYmVsID0gJGkuZ2V0QXR0cmlidXRlKFwibGFiZWxcIik7XG4gICAgICAgICAgbGV0IHNlYXJjaCA9ICRzZWFyY2hJbnB1dC52YWx1ZTtcbiAgICAgICAgICBpZiAobGFiZWwudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhzZWFyY2gudG9Mb3dlckNhc2UoKSkpIHtcbiAgICAgICAgICAgICRpLmNsYXNzTGlzdC5yZW1vdmUoXCJoaWRlXCIpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAkaS5jbGFzc0xpc3QuYWRkKFwiaGlkZVwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5zZWxlY3RJbnB1dEJveFRhYihfLmZpcnN0KCR0YWJzKSwgJGVsKTtcblxuICAgIHJldHVybiAkZWw7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgSW5wdXRCb3gsIGNvbW8gZWxlbWVudG8gRG9tXG4gICAqIHVuIElucHV0Qm94IGVzIHVuIGNvbnRlbmVkb3IgY29uIHVuYSBsaXN0YSBkZSBpbnB1dHNcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHByb3BzIC0gY29uZmlnIHBhcmEgSW5wdXRcbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGFEYXkgLSB2YWxvcmVzIGRlIGl0ZW0geSBEaWEsIG9wY2lvbmFsXG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tIGRlbCBpbnB1dCBjcmVhZG9cbiAgICovXG4gIGNyZWF0ZUlucHV0Qm94KHByb3BzLCBkYXRhRGF5KSB7XG4gICAgbGV0IHZhbHVlID0gW107XG4gICAgaWYgKGRhdGFEYXkgJiYgZGF0YURheS52YWx1ZXMpIHtcbiAgICAgIHZhbHVlID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGFEYXksIHByb3BzLnZhck5hbWUpO1xuICAgIH1cblxuICAgIGxldCB0YWJzQ29udGFpbmVyID0gXCJcIjtcblxuICAgIGlmIChwcm9wcy50YWJzKSB7XG4gICAgICBsZXQgdGFicyA9IFwiXCI7XG4gICAgICBwcm9wcy50YWJzLmZvckVhY2goKHRhYikgPT4ge1xuICAgICAgICB0YWJzICs9IGBcbiAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWJveC10YWJcIiB0YWIta2V5PVwiJHt0YWIua2V5fVwiPlxuICAgICAgICAgICR7dGFiLm5hbWV9XG4gICAgICAgIDwvZGl2PmA7XG4gICAgICB9KTtcblxuICAgICAgdGFic0NvbnRhaW5lciA9IGBcbiAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWJveC10YWItY29udGFpbmVyXCI+XG4gICAgICAgICR7dGFic31cbiAgICAgICAgPC9kaXY+XG4gICAgICBgO1xuICAgIH1cblxuICAgIGxldCBzZWFyY2hJbnB1dCA9IGBcbiAgICAgIDxkaXYgY2xhc3M9XCJzZWFyY2gtaW5wdXQtY29udGFpbmVyXCI+XG4gICAgICAgIDxpbnB1dCBpZD1cIlwiIHR5cGU9XCJ0ZXh0XCIgbmFtZT1cIlwiIGNsYXNzPVwic2VhcmNoLWlucHV0XCIgcGxhY2Vob2xkZXI9XCJidXNjYXJcIj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInNlYXJjaC1pbnB1dC1jbGVhclwiPlxuICAgICAgICAgJHtpY29ucy5jbG9zZUljb259XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgYDtcblxuICAgIGxldCBzdHIgPSBgXG4gICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtc2VjdGlvbiAke3Byb3BzLmlzSGlkZGVuID8gXCJoaWRlXCIgOiBcIlwifSBcIiBpbnB1dC1rZXk9XCIke1xuICAgICAgICBwcm9wcy5rZXkgfHwgXCJcIlxuICAgICAgfVwiPlxuICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtc3VidGl0bGUgZC1ibG9ja1wiPlxuICAgICAgICAgICAgICAke3Byb3BzLmxhYmVsfVxuICAgICAgICAgICAgPC9zcGFuPlxuXG4gICAgICAgICAgICAke3RhYnNDb250YWluZXJ9XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ib3ggXCIgaW5wdXQta2V5PVwiJHtwcm9wcy5rZXkgfHwgXCJcIn1cIj5cblxuICAgICAgICAgICAgJHtzZWFyY2hJbnB1dH1cbiAgICAgIGA7XG5cbiAgICBpZiAocHJvcHMuaW5wdXRzKSB7XG4gICAgICBwcm9wcy5pbnB1dHMuZm9yRWFjaCgoaSkgPT4ge1xuICAgICAgICBpZiAoaS5pc1RpdGxlKSB7XG4gICAgICAgICAgbGV0IHRvb2x0aXAgPSBcIlwiO1xuICAgICAgICAgIGxldCBpY29uID0gXCJcIjtcblxuICAgICAgICAgIGlmIChpLnRvb2x0aXApIHtcbiAgICAgICAgICAgIHRvb2x0aXAgPSBgXG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS10b29sdGlwXCI+XG4gICAgICAgICAgICAgICAgICAgICR7aS50b29sdGlwfVxuICAgICAgICAgICAgICAgICAgICAke2kuc3VmZml4ID8gXCIoXCIgKyBpLnN1ZmZpeCArIFwiKVwiIDogXCJcIn1cbiAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGkuY29sb3JJY29uKSB7XG4gICAgICAgICAgICBpZiAodXRpbHMuaXNIZXhDb2xvcihpLmNvbG9ySWNvbikpIHtcbiAgICAgICAgICAgICAgaWNvbiA9IGA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS1pY29uXCIgc3R5bGU9XCJiYWNrZ3JvdW5kOiR7aS5jb2xvckljb259XCI+IDwvZGl2PmA7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpY29uID0gYDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLWljb24gJHtpLmNvbG9ySWNvbn1cIj4gPC9kaXY+YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzdHIgKz0gYFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbiBpcy10aXRsZVwiIGlucHV0LXRhYi1rZXk9XCIke1xuICAgICAgICAgICAgICBpLnRhYktleSB8fCBcIlwiXG4gICAgICAgICAgICB9XCIgbGFiZWw9XCIke2kubGFiZWx9XCI+XG4gICAgICAgICAgICAgIDxsYWJlbD5cbiAgICAgICAgICAgICAgICAke2ljb259XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbi0tdGl0bGUgdHJ1bmNhdGVcIj5cbiAgICAgICAgICAgICAgICAgICR7aS5sYWJlbH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgJHt0b29sdGlwfVxuICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsZXQgdmFsdWVfZm91bmQgPSB2YWx1ZSA/IHZhbHVlLmZpbmQoKHZhbCkgPT4gdmFsLmlkID09IGkuaWQpIDogbnVsbDtcbiAgICAgICAgICBsZXQgdiA9IHZhbHVlX2ZvdW5kIHx8IFwiXCI7XG4gICAgICAgICAgbGV0IGlucHV0VmFsdWUgPVxuICAgICAgICAgICAgcHJvcHMudmFyTmFtZUlucHV0ICYmIHZbcHJvcHMudmFyTmFtZUlucHV0XVxuICAgICAgICAgICAgICA/IHZbcHJvcHMudmFyTmFtZUlucHV0XVxuICAgICAgICAgICAgICA6IHYudmFsdWU7XG4gICAgICAgICAgbGV0IHRvb2x0aXAgPSBcIlwiO1xuICAgICAgICAgIGxldCBpY29uID0gXCJcIjtcbiAgICAgICAgICBsZXQgbGluayA9IFwiXCI7XG5cbiAgICAgICAgICBpZiAoaS50b29sdGlwKSB7XG4gICAgICAgICAgICB0b29sdGlwID0gYFxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbi0tdG9vbHRpcFwiPlxuICAgICAgICAgICAgICAgICAgICAke2kudG9vbHRpcH1cbiAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGkuY29sb3JJY29uKSB7XG4gICAgICAgICAgICBpZiAodXRpbHMuaXNIZXhDb2xvcihpLmNvbG9ySWNvbikpIHtcbiAgICAgICAgICAgICAgaWNvbiA9IGA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS1pY29uXCIgc3R5bGU9XCJiYWNrZ3JvdW5kOiR7aS5jb2xvckljb259XCI+IDwvZGl2PmA7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpY29uID0gYDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLWljb24gJHtpLmNvbG9ySWNvbn1cIj4gPC9kaXY+YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaS5saW5rKSB7XG4gICAgICAgICAgICBsaW5rID0gYDxhIGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS1saW5rXCIgdGFyZ2V0PVwiX2JsYW5rXCIgaHJlZj1cIiR7aS5saW5rfVwiPlxuICAgICAgICAgICAgICAgICR7aWNvbnMubGlua0ljb259XG4gICAgICAgICAgICAgICAgPC9hPiBgO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHN0ciArPSBgXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uICR7XG4gICAgICAgICAgICAgIGljb24gPyBcImhhcy1pY29uXCIgOiBcIlwiXG4gICAgICAgICAgICB9XCIgaW5wdXQtdGFiLWtleT1cIiR7aS50YWJLZXkgfHwgXCJcIn1cIiBsYWJlbD1cIiR7aS5sYWJlbH1cIj5cbiAgICAgICAgICAgICAgPGxhYmVsPlxuICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1pbmktaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgIGlucHV0LWlkPVwiJHtpLmlkIHx8IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICBpbnB1dC1rZXk9XCIke2kua2V5IHx8IGkubGFiZWx9XCJcbiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT1cIiR7aW5wdXRWYWx1ZSB8fCBcIlwifVwiPlxuXG4gICAgICAgICAgICAgICAgJHtpY29uIHx8IFwiXCJ9XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS10aXRsZSB0cnVuY2F0ZVwiPlxuICAgICAgICAgICAgICAgICAgJHtpLmxhYmVsfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbi0tc3VmZml4XCIgPiR7XG4gICAgICAgICAgICAgICAgICBpLnN1ZmZpeCA/IFwiKFwiICsgaS5zdWZmaXggKyBcIilcIiA6IFwiXCJcbiAgICAgICAgICAgICAgICB9PC9kaXY+XG5cbiAgICAgICAgICAgICAgICAke2xpbmt9XG5cbiAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgJHt0b29sdGlwfVxuICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgc3RyICs9IGBcbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj4gYDtcblxuICAgIGxldCAkZWwgPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKHN0cik7XG4gICAgbGV0ICR0YWJzID0gJGVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCIuaW5wdXQtYm94LXRhYlt0YWIta2V5XVwiKSB8fCBbXTtcbiAgICBsZXQgJGlucHV0cyA9ICRlbC5xdWVyeVNlbGVjdG9yQWxsKFwiaW5wdXQubWluaS1pbnB1dFwiKSB8fCBbXTtcbiAgICBsZXQgJHNlYXJjaElucHV0ID0gJGVsLnF1ZXJ5U2VsZWN0b3IoXCIuc2VhcmNoLWlucHV0XCIpIHx8IG51bGw7XG4gICAgbGV0ICRzZWFyY2hJbnB1dENsZWFyID0gJGVsLnF1ZXJ5U2VsZWN0b3IoXCIuc2VhcmNoLWlucHV0LWNsZWFyXCIpIHx8IG51bGw7XG5cbiAgICAkdGFicy5mb3JFYWNoKCh0KSA9PiB7XG4gICAgICB0LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZSkgPT4ge1xuICAgICAgICB0aGlzLnNlbGVjdElucHV0Qm94VGFiKHQsICRlbCk7XG4gICAgICAgICRzZWFyY2hJbnB1dC52YWx1ZSA9IFwiXCI7XG4gICAgICAgICRzZWFyY2hJbnB1dC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcImlucHV0XCIsIHsgYnViYmxlczogdHJ1ZSB9KSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGlmICgkc2VhcmNoSW5wdXRDbGVhcikge1xuICAgICAgJHNlYXJjaElucHV0Q2xlYXIuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgICRzZWFyY2hJbnB1dC52YWx1ZSA9IFwiXCI7XG4gICAgICAgICRzZWFyY2hJbnB1dC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcImlucHV0XCIsIHsgYnViYmxlczogdHJ1ZSB9KSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoJHNlYXJjaElucHV0KSB7XG4gICAgICAkc2VhcmNoSW5wdXQuYWRkRXZlbnRMaXN0ZW5lcihcImtleWRvd25cIiwgKGUpID0+IHtcbiAgICAgICAgaWYgKGUua2V5ID09PSBcIkVzY2FwZVwiKSB7XG4gICAgICAgICAgJHNlYXJjaElucHV0LnZhbHVlID0gXCJcIjtcbiAgICAgICAgICAkc2VhcmNoSW5wdXQuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJpbnB1dFwiLCB7IGJ1YmJsZXM6IHRydWUgfSkpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgJHNlYXJjaElucHV0LmFkZEV2ZW50TGlzdGVuZXIoXCJpbnB1dFwiLCAoZSkgPT4ge1xuICAgICAgICBsZXQgJHRhYlNlbGVjdGVkID1cbiAgICAgICAgICAkZWwucXVlcnlTZWxlY3RvcihcIi5pbnB1dC1ib3gtdGFiW3RhYi1rZXldLmFjdGl2ZVwiKSB8fCBudWxsO1xuICAgICAgICBsZXQgJGlucHV0cyA9IFtdO1xuICAgICAgICBpZiAoJHRhYlNlbGVjdGVkKSB7XG4gICAgICAgICAgbGV0IHRhYktleSA9ICR0YWJTZWxlY3RlZC5nZXRBdHRyaWJ1dGUoXCJ0YWIta2V5XCIpO1xuICAgICAgICAgICRpbnB1dHMgPVxuICAgICAgICAgICAgJGVsLnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgICAgICAgIFwiLm1pbmktaW5wdXQtc2VjdGlvbltpbnB1dC10YWIta2V5PSdcIiArIHRhYktleSArIFwiJ11cIlxuICAgICAgICAgICAgKSB8fCBbXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAkaW5wdXRzID0gJGVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCIubWluaS1pbnB1dC1zZWN0aW9uXCIpIHx8IFtdO1xuICAgICAgICB9XG4gICAgICAgICRpbnB1dHMuZm9yRWFjaCgoJGkpID0+IHtcbiAgICAgICAgICBsZXQgbGFiZWwgPSAkaS5nZXRBdHRyaWJ1dGUoXCJsYWJlbFwiKTtcbiAgICAgICAgICBsZXQgc2VhcmNoID0gJHNlYXJjaElucHV0LnZhbHVlO1xuICAgICAgICAgIGlmIChsYWJlbC50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHNlYXJjaC50b0xvd2VyQ2FzZSgpKSkge1xuICAgICAgICAgICAgJGkuY2xhc3NMaXN0LnJlbW92ZShcImhpZGVcIik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICRpLmNsYXNzTGlzdC5hZGQoXCJoaWRlXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLnNlbGVjdElucHV0Qm94VGFiKF8uZmlyc3QoJHRhYnMpLCAkZWwpO1xuXG4gICAgJGlucHV0cy5mb3JFYWNoKChpKSA9PiB0aGlzLmFkZEtleURvd25JbnB1dEV2ZW50cyhpLCAkZWwsIHByb3BzKSk7XG5cbiAgICByZXR1cm4gJGVsO1xuICB9LFxuXG4gIHNlbGVjdElucHV0Qm94VGFiKCR0YWIsICRlbCkge1xuICAgIGxldCAkdGFicyA9ICRlbC5xdWVyeVNlbGVjdG9yQWxsKFwiLmlucHV0LWJveC10YWJbdGFiLWtleV1cIikgfHwgW107XG4gICAgbGV0ICRpbnB1dFNlY3Rpb25zID0gJGVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCIubWluaS1pbnB1dC1zZWN0aW9uXCIpIHx8IFtdO1xuXG4gICAgJHRhYnMuZm9yRWFjaCgodCkgPT4ge1xuICAgICAgdC5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZlXCIpO1xuICAgIH0pO1xuXG4gICAgaWYgKCR0YWIpIHtcbiAgICAgICR0YWIuY2xhc3NMaXN0LmFkZChcImFjdGl2ZVwiKTtcblxuICAgICAgJGlucHV0U2VjdGlvbnMuZm9yRWFjaCgoaSkgPT4ge1xuICAgICAgICBsZXQga2V5ID0gaS5nZXRBdHRyaWJ1dGUoXCJpbnB1dC10YWIta2V5XCIpO1xuICAgICAgICBpZiAoa2V5ID09ICR0YWIuZ2V0QXR0cmlidXRlKFwidGFiLWtleVwiKSkge1xuICAgICAgICAgIGkuY2xhc3NMaXN0LnJlbW92ZShcImhpZGVcIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaS5jbGFzc0xpc3QuYWRkKFwiaGlkZVwiKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhIENoZWNrYm94LCBjb21vIGVsZW1lbnRvIERvbVxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcHMgLSBjb25maWcgcGFyYSBJbnB1dFxuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YURheSAtIHZhbG9yZXMgZGUgaXRlbSB5IERpYSwgb3BjaW9uYWxcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gZGVsIGlucHV0IGNyZWFkb1xuICAgKi9cbiAgY3JlYXRlSW5wdXRDaGVja2JveChwcm9wcywgZGF0YURheSkge1xuICAgIGxldCB2YWx1ZSA9IFwiXCI7XG4gICAgaWYgKGRhdGFEYXkgJiYgZGF0YURheS52YWx1ZXMpIHtcbiAgICAgIHZhbHVlID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGFEYXksIHByb3BzLnZhck5hbWUpO1xuICAgIH1cbiAgICBsZXQgciA9IGRvbS5jcmVhdGVFbGVtZW50RnJvbUhUTUwoYFxuICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXNlY3Rpb24gJHtwcm9wcy5pc0hpZGRlbiA/IFwiaGlkZVwiIDogXCJcIn0gXCIgaW5wdXQta2V5PVwiJHtcbiAgICAgICAgcHJvcHMua2V5IHx8IFwiXCJcbiAgICAgIH1cIj5cbiAgICAgICAgPGxhYmVsPlxuICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBuYW1lPVwiJHtwcm9wcy5rZXkgfHwgXCJcIn1cIiBpbnB1dC1rZXk9XCIke1xuICAgICAgICAgICAgcHJvcHMua2V5IHx8IFwiXCJcbiAgICAgICAgICB9XCIgJHt2YWx1ZSA/IFwiY2hlY2tlZFwiIDogXCJcIn0+XG4gICAgICAgICAgJHtwcm9wcy5sYWJlbH1cbiAgICAgICAgPC9sYWJlbD5cbiAgICAgIDwvZGl2PmApO1xuXG4gICAgcmV0dXJuIHI7XG4gIH0sXG5cbiAgY3JlYXRlSW5wdXRCdXR0b25zR3JvdXAocHJvcHMpIHtcbiAgICBsZXQgJGNvbnRhaW5lciA9IGRvbS5jcmVhdGVFbGVtZW50RnJvbUhUTUwoYFxuICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXNlY3Rpb24gJHtwcm9wcy5pc0hpZGRlbiA/IFwiaGlkZVwiIDogXCJcIn0gXCIgaW5wdXQta2V5PVwiJHtcbiAgICAgICAgcHJvcHMua2V5IHx8IFwiXCJcbiAgICAgIH1cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImJ1dHRvbnMtZ3JvdXBcIj4gPC9kaXY+XG4gICAgICA8L2Rpdj5gKTtcblxuICAgIGxldCAkY29udGFpbmVyQnV0dG9uR3JvdXAgPSAkY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoXCIuYnV0dG9ucy1ncm91cFwiKTtcblxuICAgIGxldCAkYnV0dG9ucyA9IFtdO1xuICAgICRidXR0b25zID0gcHJvcHMuYnV0dG9ucy5tYXAoKGJ1dHRvblByb3ApID0+IHtcbiAgICAgIGxldCBidXR0b25TdHIgPSBgXG4gICAgICAgIDxidXR0b24gXG4gICAgICAgICAgbmFtZT1cIiR7YnV0dG9uUHJvcC5rZXkgfHwgXCJcIn1cIiBcbiAgICAgICAgICBpbnB1dC1rZXk9XCIke2J1dHRvblByb3Aua2V5IHx8IFwiXCJ9XCJcbiAgICAgICAgICBjbGFzcz1cImNhcC1idG4tb3V0bGluZSBjYXAtYnRuLXNtICR7XG4gICAgICAgICAgICBidXR0b25Qcm9wLmlzU2VsZWN0ZWQgPyBcInNlbGVjdGVkXCIgOiBcIlwiXG4gICAgICAgICAgfSBcIj5cbiAgICAgICAgICAke2J1dHRvblByb3AubGFiZWx9XG4gICAgICAgIDwvYnV0dG9uPmA7XG5cbiAgICAgIGxldCAkYnV0dG9uID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChidXR0b25TdHIpO1xuICAgICAgJGNvbnRhaW5lckJ1dHRvbkdyb3VwLmFwcGVuZCgkYnV0dG9uKTtcblxuICAgICAgJGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgaWYgKHByb3BzLmlzU2VsZWN0YWJsZSkge1xuICAgICAgICAgICRidXR0b25zLmZvckVhY2goKCRiKSA9PiAkYi5jbGFzc0xpc3QucmVtb3ZlKFwic2VsZWN0ZWRcIikpO1xuICAgICAgICAgICRidXR0b24uY2xhc3NMaXN0LmFkZChcInNlbGVjdGVkXCIpO1xuICAgICAgICB9XG4gICAgICAgIGJ1dHRvblByb3Aub25DbGljayh7IHByb3BzLCBldmVudDogZSwgYnV0dG9uc0VsZW1lbnRzOiAkYnV0dG9ucyB9KTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuICRidXR0b247XG4gICAgfSk7XG5cbiAgICByZXR1cm4gJGNvbnRhaW5lcjtcbiAgfSxcblxuICBjcmVhdGVJbnB1dEJ1dHRvbihwcm9wcywgZGF0YURheSkge1xuICAgIGxldCByID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChgXG4gICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtc2VjdGlvbiAke3Byb3BzLmlzSGlkZGVuID8gXCJoaWRlXCIgOiBcIlwifSBcIiBpbnB1dC1rZXk9XCIke1xuICAgICAgICBwcm9wcy5rZXkgfHwgXCJcIlxuICAgICAgfVwiPlxuICAgICAgICAgIDxidXR0b24gXG4gICAgICAgICAgICBuYW1lPVwiJHtwcm9wcy5rZXkgfHwgXCJcIn1cIlxuICAgICAgICAgICAgaW5wdXQta2V5PVwiJHtwcm9wcy5rZXkgfHwgXCJcIn1cIlxuICAgICAgICAgICAgY2xhc3M9XCJjYXAtYnRuLW91dGxpbmVcIj5cbiAgICAgICAgICAgICR7cHJvcHMubGFiZWx9XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5gKTtcblxuICAgIGxldCBidXR0b24gPSByLnF1ZXJ5U2VsZWN0b3IoXCJidXR0b25cIik7XG4gICAgYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZSkgPT5cbiAgICAgIHByb3BzLm9uQ2xpY2soeyBwcm9wcywgZXZlbnQ6IGUsIGRhdGFEYXkgfSlcbiAgICApO1xuXG4gICAgcmV0dXJuIHI7XG4gIH0sXG5cbiAgYWRkS2V5RG93bklucHV0RXZlbnRzKCRpbnB1dCwgJGlucHV0Q29udGFpbmVyLCBwcm9wcykge1xuICAgICRpbnB1dC5hZGRFdmVudExpc3RlbmVyKFwia2V5ZG93blwiLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgIGlmIChldmVudC5rZXlDb2RlID09PSAxMykge1xuICAgICAgICAvL0VOVEVSXG4gICAgICAgICRpbnB1dC5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgIG5ldyBDdXN0b21FdmVudChcInNhdmVNdWx0aUlucHV0XCIsIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LmtleUNvZGUgPT09IDI3KSB7XG4gICAgICAgIC8vRVNDXG4gICAgICAgICRpbnB1dC5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgIG5ldyBDdXN0b21FdmVudChcImNhbmNlbE11bHRpSW5wdXRcIiwge1xuICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgIGNhbmNlbGFibGU6IGZhbHNlLFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgJGlucHV0LmFkZEV2ZW50TGlzdGVuZXIoXCJpbnB1dFwiLCAoZSkgPT4ge1xuICAgICAgaWYgKHByb3BzLm9uSW5wdXQpIHtcbiAgICAgICAgcHJvcHMub25JbnB1dCh7XG4gICAgICAgICAgZXZlbnQ6IGUsXG4gICAgICAgICAgdmFsdWU6IGUuc3JjRWxlbWVudC52YWx1ZSxcbiAgICAgICAgICBwcm9wcyxcbiAgICAgICAgICAkZWxlbWVudDogJGlucHV0Q29udGFpbmVyLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSxcblxuICBjcmVhdGVDb250ZXh0TWVudSh7XG4gICAgY29uZmlnLFxuICAgIHRhcmdldCxcbiAgICAkY2FwaWJhcmFFbGVtID0gbnVsbCxcbiAgICBldnQgPSBudWxsLFxuICAgIGRhdGUgPSBudWxsLFxuICAgIGl0ZW0gPSBudWxsLFxuICAgIHNlbGVjdGVkID0gW10sXG4gICAgdGFiU2VsZWN0ZWQgPSBudWxsLFxuICAgIGxlZnQgPSBudWxsLFxuICAgIHRvcCA9IG51bGwsXG4gICAgbmFtZSA9IFwiXCIsXG4gIH0pIHtcbiAgICBpZiAoXG4gICAgICBjb25maWcudGltZWxpbmUuY29udGV4dE1lbnUgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgY29uZmlnLnRpbWVsaW5lLmNvbnRleHRNZW51Lm9wdGlvbnMgPT0gdW5kZWZpbmVkXG4gICAgKVxuICAgICAgcmV0dXJuIHsgZWxlbTogbnVsbCwgaXNWaXNpYmxlOiBmYWxzZSB9O1xuXG4gICAgbGV0IGNsYXNzTmFtZSA9IFwiXCI7XG4gICAgbGV0IHN0eWxlID0gXCJcIjtcbiAgICBsZXQgc3RySHRtbCA9IFwiXCI7XG4gICAgbGV0IGxlZnRQb3NpdGlvbiA9IG51bGw7XG4gICAgbGV0IHRvcFBvc2l0aW9uID0gbnVsbDtcbiAgICBsZXQgaXNWaXNpYmxlID0gdHJ1ZTtcbiAgICBsZXQgYm91bmRSZWN0Q2FwaWJhcmEgPSBudWxsO1xuICAgIGxldCBnYXAgPSAxNTsgLy9weFxuXG4gICAgaWYgKCRjYXBpYmFyYUVsZW0pIHtcbiAgICAgIGJvdW5kUmVjdENhcGliYXJhID0gJGNhcGliYXJhRWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB9XG5cbiAgICBpZiAoZXZ0ICYmIGJvdW5kUmVjdENhcGliYXJhKSB7XG4gICAgICBsZWZ0ID0gZXZ0LmNsaWVudFg7XG4gICAgICB0b3AgPSBldnQuY2xpZW50WSAtIGJvdW5kUmVjdENhcGliYXJhLnRvcDtcbiAgICB9XG5cbiAgICBpZiAobGVmdCkge1xuICAgICAgbGVmdFBvc2l0aW9uID0gbGVmdDtcbiAgICB9XG5cbiAgICBpZiAodG9wKSB7XG4gICAgICB0b3BQb3NpdGlvbiA9IHRvcDtcbiAgICB9XG5cbiAgICBpZiAoKGxlZnRQb3NpdGlvbiAhPT0gbnVsbCkgJiAodG9wUG9zaXRpb24gIT09IG51bGwpKSB7XG4gICAgICBpZiAoYm91bmRSZWN0Q2FwaWJhcmEpIHtcbiAgICAgICAgbGV0IHRyYW5zZm9ybVN0eWxlID0gXCJcIjtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRvcFBvc2l0aW9uID4gKGJvdW5kUmVjdENhcGliYXJhLmhlaWdodCAqIDIpIC8gNiAmJlxuICAgICAgICAgIHRvcFBvc2l0aW9uIDw9IChib3VuZFJlY3RDYXBpYmFyYS5oZWlnaHQgKiA0KSAvIDZcbiAgICAgICAgKSB7XG4gICAgICAgICAgdHJhbnNmb3JtU3R5bGUgKz0gYHRyYW5zbGF0ZVkoLTUwJSlgO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0b3BQb3NpdGlvbiA+IChib3VuZFJlY3RDYXBpYmFyYS5oZWlnaHQgKiA0KSAvIDYpIHtcbiAgICAgICAgICB0cmFuc2Zvcm1TdHlsZSArPSBgdHJhbnNsYXRlWSgtMTAwJSlgO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGxlZnRQb3NpdGlvbiA+IChib3VuZFJlY3RDYXBpYmFyYS53aWR0aCAqIDQpIC8gNikge1xuICAgICAgICAgIHRyYW5zZm9ybVN0eWxlICs9IGB0cmFuc2xhdGVYKC0xMDAlKWA7XG4gICAgICAgICAgbGVmdFBvc2l0aW9uIC09IGdhcDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsZWZ0UG9zaXRpb24gKz0gZ2FwO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0cmFuc2Zvcm1TdHlsZSAhPSBcIlwiKSB7XG4gICAgICAgICAgc3R5bGUgKz0gYCB0cmFuc2Zvcm06ICR7dHJhbnNmb3JtU3R5bGV9O2A7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc3R5bGUgKz0gYHRvcDogJHt0b3BQb3NpdGlvbn1weDsgbGVmdDogJHtsZWZ0UG9zaXRpb259cHg7YDtcbiAgICB9IGVsc2Uge1xuICAgICAgY2xhc3NOYW1lICs9IFwiY20taGlkZVwiO1xuICAgICAgaXNWaXNpYmxlID0gZmFsc2U7XG4gICAgfVxuXG4gICAgc3RySHRtbCArPSBgIDxkaXYgY2xhc3M9XCJjYXAtY29udGV4dC1tZW51LWNvbnRhaW5lciAke2NsYXNzTmFtZX1cIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcC1jb250ZXh0LW1lbnVcIiBzdHlsZT1cIiR7c3R5bGV9XCI+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuXG4gICAgbGV0ICRjb250ZXh0TWVudUNvbnRhaW5lciA9IGRvbS5jcmVhdGVFbGVtZW50RnJvbUhUTUwoc3RySHRtbCk7XG4gICAgbGV0ICRjb250ZXh0TWVudSA9ICRjb250ZXh0TWVudUNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKFwiLmNhcC1jb250ZXh0LW1lbnVcIik7XG4gICAgbGV0IGhhc1NvbWVvcHRpb24gPSBmYWxzZTtcblxuICAgIGNvbmZpZy50aW1lbGluZS5jb250ZXh0TWVudS5vcHRpb25zLmZvckVhY2goKG9wdGlvbikgPT4ge1xuICAgICAgaWYgKG9wdGlvbi5zaG93SWYpIHtcbiAgICAgICAgbGV0IHNob3cgPSBvcHRpb24uc2hvd0lmKHsgaXRlbSwgZGF0ZSwgc2VsZWN0ZWQsIG5hbWUsIHRhYlNlbGVjdGVkIH0pO1xuICAgICAgICBpZiAoIXNob3cpIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgbGV0IGlzRW5hYmxlZCA9IHRydWU7XG4gICAgICBsZXQgaXNDbGlja2VhYmxlID0gdHJ1ZTtcbiAgICAgIGlmIChvcHRpb24uZW5hYmxlSWYpIHtcbiAgICAgICAgaXNFbmFibGVkID0gb3B0aW9uLmVuYWJsZUlmKHtcbiAgICAgICAgICBpdGVtLFxuICAgICAgICAgIGRhdGUsXG4gICAgICAgICAgc2VsZWN0ZWQsXG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgICB0YWJTZWxlY3RlZCxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGxldCBvcHRpb25DbGFzc05hbWUgPSBcIlwiO1xuICAgICAgbGV0IHN0ckljb24gPSBcIlwiO1xuICAgICAgbGV0IGxhYmVsID0gXCJcIjtcblxuICAgICAgaWYgKCFpc0VuYWJsZWQpIHtcbiAgICAgICAgb3B0aW9uQ2xhc3NOYW1lICs9IFwiaXMtZGlzYWJsZWQgXCI7XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb24uaXNEaXZpZGVyKSB7XG4gICAgICAgIGlzQ2xpY2tlYWJsZSA9IGZhbHNlO1xuICAgICAgICBvcHRpb25DbGFzc05hbWUgKz0gXCJpcy1kaXZpZGVyIFwiO1xuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9uLmxhYmVsKSB7XG4gICAgICAgIGxhYmVsID0gYDxzcGFuPiR7b3B0aW9uLmxhYmVsfTwvc3Bhbj5gO1xuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9uLmljb24pIHtcbiAgICAgICAgc3RySWNvbiA9IGA8ZGl2IGNsYXNzPVwiY2FwLWNvbnRleHQtbWVudV9pdGVtX2ljb25cIj5cbiAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHZpZXdCb3g9XCIwIDAgMjQgMjRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCIke29wdGlvbi5pY29ufVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgfVxuXG4gICAgICBsZXQgb3B0aW9uU3RySHRtbCA9IGBcbiAgICAgICAgPGRpdiBjbGFzcz1cImNhcC1jb250ZXh0LW1lbnVfaXRlbSAke29wdGlvbkNsYXNzTmFtZX1cIj5cbiAgICAgICAgICAke3N0ckljb259XG4gICAgICAgICAgJHtsYWJlbH1cbiAgICAgICAgPC9kaXY+YDtcblxuICAgICAgbGV0ICRvcHRpb24gPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKG9wdGlvblN0ckh0bWwpO1xuXG4gICAgICBpZiAoaXNFbmFibGVkICYmIGlzQ2xpY2tlYWJsZSkge1xuICAgICAgICAkb3B0aW9uLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZXZ0Q2xpY2spID0+XG4gICAgICAgICAgb3B0aW9uLm9uQ2xpY2soe1xuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgZXZ0OiBldnRDbGljayxcbiAgICAgICAgICAgIGRhdGUsXG4gICAgICAgICAgICBpdGVtLFxuICAgICAgICAgICAgc2VsZWN0ZWQsXG4gICAgICAgICAgICB0YWJTZWxlY3RlZCxcbiAgICAgICAgICAgIHRhcmdldCxcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgJG9wdGlvbi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGV2dENsaWNrKSA9PiB7XG4gICAgICAgICAgZXZ0Q2xpY2sucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICBldnRDbGljay5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgICRjb250ZXh0TWVudS5hcHBlbmQoJG9wdGlvbik7XG4gICAgICBoYXNTb21lb3B0aW9uID0gdHJ1ZTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBlbGVtOiAkY29udGV4dE1lbnVDb250YWluZXIsXG4gICAgICBpc1Zpc2libGUsXG4gICAgfTtcbiAgfSxcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBRUE7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFEQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFGQTtBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUZBO0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBUUE7QUFRQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBS0E7QUFQQTtBQUNBO0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFHQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUZBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFIQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRkE7QUFLQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFEQTtBQUhBO0FBUUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFEQTtBQUhBO0FBUUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFEQTtBQUhBO0FBUUE7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFIQTtBQVNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFEQTtBQUhBO0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBSEE7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFLQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFKQTtBQUhBO0FBV0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSEE7QUFTQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUpBO0FBTUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFKQTtBQU1BO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFJQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUhBO0FBVUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUlBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFJQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBSUE7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUE3Q0E7QUErQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQTdDQTtBQStDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQTdDQTtBQStDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBN0NBO0FBK0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUdBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFKQTtBQUhBO0FBV0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUZBO0FBS0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUZBO0FBS0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBSEE7QUFVQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUxBO0FBSEE7QUFZQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTkE7QUFIQTtBQWFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUhBO0FBVUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTEE7QUFPQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUhBO0FBV0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFRQTtBQUNBO0FBQUE7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFKQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFQQTtBQVNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVBBO0FBU0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVBBO0FBU0E7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUtBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU9BO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUhBO0FBVUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFIQTtBQVVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUdBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUlBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFJQTtBQUNBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBSUE7QUFFQTtBQUNBO0FBQ0E7QUFGQTtBQUtBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBT0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQU9BO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFsRUE7QUFDQTtBQW9FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSEE7QUFTQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFIQTtBQVNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFWQTtBQVlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBUEE7QUFVQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFQQTtBQVNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVZBO0FBWUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFHQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRkE7QUFLQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUZBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSkE7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVhBO0FBYUE7QUFJQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUlBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUxBO0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFQQTtBQVVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBNzJJQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./src/util/tableElements.js\n");
|
|
258
|
+
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _util_domUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/domUtils */ \"./src/util/domUtils.js\");\n/* harmony import */ var _util_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/utils */ \"./src/util/utils.js\");\n/* harmony import */ var _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../util/dateUtils */ \"./src/util/dateUtils.js\");\n/* harmony import */ var _util_icons__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../util/icons */ \"./src/util/icons.js\");\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n /**\n * Crea elemento Table\n * Contendrá los elementos que apareceran dentro de la tabla de planilla\n * Se Usa para :\n * - Agregar background con patron estilo tabla\n * - Agregar dayMouseOver, div que indica posicion de mouse\n * - Agregar DetailDay, para detalles de datos en tabla\n * - Agregar SelectedContainer, para dias seleccionados\n * - Agregar FloatBoxContainer, para visualizacion de datos en tabla\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom creado\n */\n createAgTable(config) {\n let e = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"capibara\"\n });\n\n if (config.timeline.dark) {\n e.classList.add(\"dark-theme\");\n }\n\n if (config.timeline.header.extend.isShow) {\n e.classList.add(\"header-extended\");\n }\n\n return e;\n },\n\n /**\n * Recrea Background, que es el fondo grid, como tabla\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} $elem - Elemento relacionado, donde se cre el background\n * @return {Object} Elemento Dom Corner Footer\n */\n redrawBackground(config, $elem) {\n return this.createBackground(config, $elem);\n },\n\n /**\n * Crea y posiciona fondo de tabla\n * Este fondo contiene un patron de CSS que le da la apariencia de tabla\n * por lo cual se debe reposicionar segun la fecha de inicio, para hacer\n * calzar los fines de semana\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} [$elem = null] - Elemento background, si es null, lo crea\n * @return {Object} elemento Dom Background\n */\n createBackground(config, $elem = null) {\n let {\n height,\n width,\n dayWidth\n } = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getTableDimensions(config);\n let start = new Date(config.timeline.start);\n let end = new Date(config.timeline.end);\n end.setTime(end.getTime() + _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].dayInMilliseconds); // add 24 hours\n\n let dCorrected = new Date(start.valueOf() + start.getTimezoneOffset() * 60000);\n let weekDay = dCorrected.getDay();\n let diffWeekDays = (weekDay - 1) * dayWidth * -1;\n $elem = $elem || _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"background-grid\"\n });\n $elem.style[\"background-position\"] = diffWeekDays + \"px 0, 0 0, \" + diffWeekDays + \"px 0\";\n $elem.style.width = width + \"px\";\n $elem.style.height = height + 1 + \"px\";\n return $elem;\n },\n\n /**\n * Crea Plot Container Vertical\n * Los plots son elementos que agregan secciones de fondo en la planilla\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom plotVerticalContainer\n */\n createPlotVerticalContainer(config) {\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"plot-vertical-container\"\n });\n return this.redrawPlotVerticalContainer(config, $elem);\n },\n\n createPlotHorizontalContainer(config) {\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"plot-horizontal-container\"\n });\n return this.redrawPlotHorizontalContainer(config, $elem);\n },\n\n /**\n * Recrea plotVerticalContainer, usando elemento existente\n * usa un elemento existente para usar la funcion para redibujar el elemento\n *\n * Los Plots se insertan como divs, con posicion especificada,\n * con ancho de dia\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} $elem - Elemento Dom donde crea plotVerticalContainer\n * @return {Object} Elemento Dom plotVerticalContainer\n */\n redrawPlotVerticalContainer(config, $elem) {\n $elem.innerHTML = \"\";\n\n if (config.timeline.plots && config.timeline.plots.vertical) {\n let {\n height,\n dayWidth\n } = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getTableDimensions(config);\n config.timeline.plots.vertical.forEach(p => {\n let diffDays = Math.floor(_util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].diffDays(config.timeline.start, p.date));\n let left = diffDays * dayWidth;\n let plot = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n classNames: [\"plot-vertical\", p.className || \"\"],\n style: {\n \"margin-left\": left + \"px\",\n height: height + \"px\"\n }\n });\n $elem.appendChild(plot);\n });\n }\n\n return $elem;\n },\n\n redrawPlotHorizontalContainer(config, $elem) {\n $elem.innerHTML = \"\";\n\n if (config.timeline.plots && config.timeline.plots.horizontal) {\n let {\n width,\n itemHeight\n } = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getTableDimensions(config);\n config.timeline.plots.horizontal.forEach(p => {\n let item = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getItemById(config, p.idNode, p.typeNode);\n let topPosition = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getPositionByItem(config, item, \"parent\");\n let plot = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n classNames: [\"plot-horizontal\", p.className || \"\"],\n style: {\n \"margin-top\": topPosition * itemHeight + \"px\",\n width: width + \"px\"\n }\n });\n $elem.appendChild(plot);\n });\n }\n\n return $elem;\n },\n\n /**\n * Crea Corner Izquierdo\n * Se usa para :\n * - titulos relacionados con los datos del sidebar izquierdo\n * - titulos para inputs de header, absolute a la derecha\n * - boton para mostrar/ocultar sidebar izquierdo\n * - promedios\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom Corner\n */\n createCorner(config, tab = null) {\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"corner\"\n });\n return this.redrawCorner($elem, config, tab);\n },\n\n redrawCorner($elem, config, tab = null) {\n let labelsInitialCorner = config.timeline.nav.left.initial.vars.filter(v => v.onlyTab == undefined || v.onlyTab && tab && v.onlyTab == tab.key).map(d => `<span class=\"item-col\">${d.label}</span>`).join(\"\");\n let labelsExtendCorner = config.timeline.nav.left.extend.vars.filter(v => v.onlyTab == undefined || v.onlyTab && tab && v.onlyTab == tab.key).map(d => `<span class=\"item-col\">${d.label}</span>`).join(\"\");\n let labelsHeaderExtend = config.timeline.header.extend.data.map(d => {\n if (d.isHidden) return \"\";\n let avg = \"\";\n let tooltip = \"\";\n let className = \"\";\n let isAccent = d.isAccent;\n\n if (d.average) {\n avg = ` <span class=\"average \"> ( <span> <span class=\"symbol\">x̄</span> ${d.average} </span>) </span> `;\n tooltip = `cap-tooltip=\"Promedio ${d.label} : ${d.average} ${d.suffix || \"\"}\"`;\n }\n\n if (d.color) {\n if (isAccent) {\n className = d.color ? \"c-\" + d.color + \"--background\" : \"\";\n } else {\n className = d.color ? \"c-\" + d.color + \"--text \" : \"\";\n }\n }\n\n return `<div class=\"input-title-container ${isAccent ? \"input-title--accent\" : \"\"} ${d.isPersistent ? \"persistent\" : \"\"}\">\n <span ${tooltip} class=\"input-title ${className}\">\n ${avg}\n ${d.label}\n </span>\n\n </div>`;\n }).join(\"\");\n let toggleSidebarBtnString = `\n <button toggle-sidebar class=\"cap-btn-icon cap-btn-icon-raised cap-btn-toggle-sidebar \">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].chevronRight}\n </button> `;\n\n if (config.timeline.nav.left.hideToggleSidebarButton) {\n toggleSidebarBtnString = \"\";\n }\n\n let template = `<div>\n\n ${toggleSidebarBtnString}\n <div class=\"corner-title\">\n <span class=\"bottom-text\">\n ${config.timeline.corner.left.label}\n </span>\n </div>\n\n <div class=\"initial-corner\">\n <div class=\"initial-corner-title\">\n <span class=\"bottom-container hide\">\n ${config.timeline.corner.initial.label}\n </span>\n\n <div class=\"bottom-container\">\n ${labelsInitialCorner}\n </div>\n\n </div>\n </div>\n\n\n <div class=\"extend-corner\">\n <div class=\"ex-corner-title\">\n <span class=\"bottom-container hide\">\n ${config.timeline.corner.extend.label}\n </span>\n\n <div class=\"bottom-container\">\n ${labelsExtendCorner}\n </div>\n\n </div>\n </div>\n\n\n <div class=\"cap-btn-nav-corner\">\n <div class=\"input-titles\">\n ${labelsHeaderExtend}\n </div>\n </div>\n\n <div class=\"progress-bar progress-bar-left hide-progress\"></div>\n\n </div>`;\n let r = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(template);\n $elem.innerHTML = \"\";\n $elem.append(r);\n let toggleSidebar = $elem.querySelector(\"[toggle-sidebar]\");\n\n if (toggleSidebar) {\n toggleSidebar.addEventListener(\"click\", e => {\n r.dispatchEvent(new CustomEvent(\"toggleSidebar\", {\n bubbles: true,\n cancelable: false\n }));\n });\n }\n\n return $elem;\n },\n\n /**\n * Crea Corner Derecho\n * Se usa para :\n * - titulos relacionados con los datos del sidebar Derecho\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom corner\n */\n createCornerRight(config, tab = null) {\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n classNames: [\"corner\", \"right\"]\n });\n return this.redrawCornerRight($elem, config, tab);\n },\n\n redrawCornerRight($el, config, tab = null) {\n let label = \"\";\n\n if (config.timeline.corner.right.label) {\n ` <span>\n ${config.timeline.corner.right.label}\n </span>`;\n }\n\n let str = `\n <div class=\"corner-title\">\n ${label}\n <div class=\"btn-container\"></div>\n </div>\n <div class=\"progress-bar progress-bar-right hide-progress\"></div>\n `;\n $el.innerHTML = str.trim();\n let $btnContainer = $el.querySelector(\".btn-container\");\n\n if (config.timeline.corner.right.buttons) {\n config.timeline.corner.right.buttons.forEach(btn => {\n let isEnabled = btn.getIsEnabled ? btn.getIsEnabled() : true;\n\n if (isEnabled) {\n let $btn = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <button class=\"corner-btn cap-btn-raised\">\n ${btn.label || \"\"}\n </button> `);\n\n if (btn.onClick) {\n $btn.addEventListener(\"click\", btn.onClick);\n }\n\n $btnContainer.appendChild($btn);\n }\n });\n }\n\n if (config.timeline.corner.right.inputs) {\n config.timeline.corner.right.inputs.forEach(input => {\n let $input = this.createCornerRightInput({\n inputConfig: input\n });\n $btnContainer.appendChild($btn);\n });\n }\n\n return $el;\n },\n\n createCornerRightInput({\n inputConfig,\n dataDay = null,\n daySelected = null\n }) {\n let r = null;\n\n switch (inputConfig.type) {\n case \"autocomplete-crud\":\n r = this.createCornerRightInputAutocompleteCrud({\n inputConfig,\n dataDay,\n daySelected\n });\n break;\n }\n\n return r;\n },\n\n createCornerRightInputAutocompleteCrud({\n inputConfig,\n dataDay,\n daySelected\n }) {\n let elem = \"test\";\n return elem;\n },\n\n /**\n * Crea Header Top\n * Se usa para :\n * - Manejo de tabs\n * - Botones de navegación y selección de fecha\n * - Boton toggle Dark mode\n * - Boton toggle Header extended\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom\n */\n createHeaderTop(config, tabSelected = null) {\n return this.redrawHeaderTop(config, tabSelected, _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\"));\n },\n\n redrawHeaderTop(config, tabSelected = null, $elem) {\n let str = `\n <div class=\"header-top\">`;\n\n if (config.timeline.tabs) {\n let showTabs = true;\n\n if (config.timeline.tabs.filter(t => !t.isHidden).length == 0) {\n showTabs = false;\n }\n\n if (showTabs) {\n str += ` <div class=\"tab-select-container c-d-desktop-none c-d-mobile-flex\">\n <select class=\"tabs-select\" >`;\n config.timeline.tabs.forEach(tab => {\n if (!tab.isHidden) {\n str += ` <option ${tab == tabSelected ? 'selected=\"selected\"' : \"\"} value=\"${tab.id}\"> ${tab.label} </option>`;\n }\n });\n str += `</select> </div>`;\n str += ` <div class=\"tabs-container c-d-desktop-flex c-d-mobile-none\">`;\n config.timeline.tabs.forEach(tab => {\n if (!tab.isHidden) {\n str += ` <button\n class=\"tab ${tab.disabled ? \"disabled\" : \"\"} ${tab == tabSelected ? \"active\" : \"\"} ${tab.color}\"\n color=\"${tab.color}\"\n input-key=\"${tab.id}\"\n ${tab.tooltip ? 'cap-tooltip=\"' + tab.tooltip + '\"' : \"\"} >\n <span>${tab.label}</span>\n ${tab.icon || \"\"}\n </button>\n `;\n }\n });\n str += `</div>`;\n }\n }\n\n if (tabSelected) {\n if (tabSelected.legends) {\n str += ` \n <button toggle-legends class=\"cap-btn-icon cap-btn-icon-raised \">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].toggleLegends}\n </button> \n\n <div class=\"legends-container force-mobile-style hide\"> `;\n tabSelected.legends.forEach(legend => {\n let colorClass = \"\";\n let colorBg = \"\";\n\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(legend.color)) {\n colorBg = \"background:\" + legend.color;\n } else {\n colorClass = legend.color ? legend.color + \"--background\" : \"\";\n }\n\n str += ` <div\n class=\"legend ${legend.active ? \"active\" : \"\"}\"\n input-key=\"${legend.key}\"\n ${legend.tooltip ? `cap-tooltip=\"${legend.tooltip}\"` : \"\"} >\n <div class=\"icon-legend ${colorClass} ${legend.shape}\" style=\"${colorBg}\"></div>\n <span>${legend.label}</span>\n </div>`;\n });\n str += `</div>`;\n }\n }\n\n str += `\n\n <div class=\"spacer\"></div>\n\n\n\n <button cap-btn-prev class=\"cap-btn-icon cap-btn-icon-raised\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].arrowLeft}\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].loadingIcon} \n </button>\n\n\n <button cap-btn-calendar class=\"cap-btn-icon cap-btn-icon-raised\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].calendar}\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].loadingIcon}\n </button>\n\n <button cap-btn-next class=\"cap-btn-icon cap-btn-icon-raised\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].arrowRight}\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].loadingIcon}\n </button>\n\n <div class=\"spacer\"></div>\n\n <button toggle-dark class=\"cap-btn-icon cap-btn-header c-d-mobile-none ${config.timeline.withDarkToggle == false ? \"hide\" : \"\"}\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].dark}\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].light}\n </button>`;\n\n if (config.timeline.header.extend.enabled !== false) {\n str += `<button toggle-header class=\"cap-btn-icon cap-btn-icon-raised\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].chevronDown}\n </button>`;\n }\n\n str += ` <div class=\"button-right-container\"></div>\n </div>`;\n /*\n `\n <button toggle-sidebar-right class=\"cap-btn-icon cap-btn-icon-raised\">\n <span>\n <svg style=\"width:24px;height:24px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z\" />\n </svg>\n </span>\n </button>\n </div>\n `;\n */\n\n let $r = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n $elem.replaceWith($r);\n\n if (config.timeline.header.rightButtons) {\n let $buttonContainer = $r.querySelector(\".button-right-container\");\n config.timeline.header.rightButtons.forEach(button => {\n let hasBadge = false;\n\n if (button.hasBadge) {\n hasBadge = button.hasBadge();\n }\n\n let str = `<button class=\"cap-btn-icon cap-btn-icon-raised ${hasBadge ? \"cap-btn-has-badge\" : \"\"}\">\n <span>\n <svg style=\"width:24px;height:24px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"${button.icon}\" />\n </svg>\n </span>\n </button>`;\n let $button = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n $button.addEventListener(\"click\", evt => button.onClick({\n evt\n }));\n $buttonContainer.append($button);\n });\n }\n\n let $toggleDark = $r.querySelector(\"[toggle-dark]\");\n\n if ($toggleDark) {\n $toggleDark.addEventListener(\"click\", e => {\n $r.dispatchEvent(new CustomEvent(\"toggleDark\", {\n bubbles: true,\n cancelable: false\n }));\n });\n }\n\n let $btnCalendar = $r.querySelector(\"[cap-btn-calendar]\");\n\n if ($btnCalendar) {\n $btnCalendar.addEventListener(\"click\", e => {\n let x = e.x;\n let y = e.y;\n $r.dispatchEvent(new CustomEvent(\"clickCalendarIcon\", {\n bubbles: true,\n cancelable: false,\n detail: {\n x,\n y\n }\n }));\n });\n }\n\n let $btnToggleHeader = $r.querySelector(\"[toggle-header]\");\n\n if ($btnToggleHeader) {\n $btnToggleHeader.addEventListener(\"click\", e => {\n $r.dispatchEvent(new CustomEvent(\"toggleHeader\", {\n bubbles: true,\n cancelable: false\n }));\n });\n }\n /*\n $r.querySelector(\"[toggle-sidebar-right]\").addEventListener(\"click\", e => {\n $r.dispatchEvent(new CustomEvent(\"toggleSidebarRight\", {\n bubbles: true,\n cancelable: false,\n }));\n });\n */\n\n\n $r.querySelector(\"[cap-btn-prev]\").addEventListener(\"click\", e => {\n $r.dispatchEvent(new CustomEvent(\"headerPrev\", {\n bubbles: true,\n cancelable: false,\n detail: {\n originalEvt: e\n }\n }));\n });\n $r.querySelector(\"[cap-btn-calendar]\").addEventListener(\"click\", e => {\n $r.dispatchEvent(new CustomEvent(\"headerCalendar\", {\n bubbles: true,\n cancelable: false,\n detail: {\n originalEvt: e\n }\n }));\n });\n $r.querySelector(\"[cap-btn-next]\").addEventListener(\"click\", e => {\n $r.dispatchEvent(new CustomEvent(\"headerNext\", {\n bubbles: true,\n cancelable: false,\n detail: {\n originalEvt: e\n }\n }));\n });\n let $toggleLegendsBtn = $r.querySelector(\"[toggle-legends]\");\n\n if ($toggleLegendsBtn) {\n $toggleLegendsBtn.addEventListener(\"click\", e => {\n let $legendContainer = $r.querySelector(\".legends-container\");\n\n if ($legendContainer) {\n $legendContainer.classList.toggle(\"hide\");\n }\n });\n }\n\n $r.querySelectorAll(\".legend\").forEach($legend => {\n $legend.addEventListener(\"click\", e => {\n let key = e.currentTarget.getAttribute(\"input-key\");\n\n if (key) {\n let legendSelected = tabSelected.legends.find(tab => tab.key === key);\n\n if (legendSelected) {\n $r.dispatchEvent(new CustomEvent(\"selectLegendHeader\", {\n bubbles: true,\n cancelable: false,\n detail: {\n legend: legendSelected,\n $legend\n }\n }));\n }\n }\n });\n });\n $r.querySelectorAll(\".tab:not(.disabled)\").forEach($tab => {\n $tab.addEventListener(\"click\", e => {\n let key = e.currentTarget.getAttribute(\"input-key\");\n\n if (key) {\n let tabSelected = config.timeline.tabs.find(tab => tab.id == key);\n\n if (tabSelected) {\n $r.dispatchEvent(new CustomEvent(\"selectTabHeader\", {\n bubbles: true,\n cancelable: false,\n detail: {\n tab: tabSelected\n }\n }));\n }\n }\n });\n });\n $r.querySelectorAll(\".tabs-select:not(.disabled)\").forEach($tab => {\n $tab.addEventListener(\"change\", e => {\n let key = parseFloat(e.currentTarget.value);\n\n if (key) {\n let tabSelected = config.timeline.tabs.find(tab => tab.id == key);\n\n if (tabSelected) {\n $r.dispatchEvent(new CustomEvent(\"selectTabHeader\", {\n bubbles: true,\n cancelable: false,\n detail: {\n tab: tabSelected\n }\n }));\n }\n }\n });\n });\n return $r;\n },\n\n /**\n * Crea Header\n * Se usa para :\n * - Mostrar fechas en header\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom\n */\n createHeader(config) {\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"header\");\n return this.redrawHeader(config, $elem);\n },\n\n /**\n * Recrea Header, usado para redibujar\n * utiliza $elem como elemento dom donde recrearlo\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} $elem - Elemento Dom donde crea Header\n * @return {Object} Elemento Dom\n */\n redrawHeader(config, $elem) {\n let datesTree = _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getDateTreeRange(new Date(config.timeline.start), new Date(config.timeline.end));\n let str = `<div class=\"header-container\"> `;\n Object.keys(datesTree).forEach(keyY => {\n let year = datesTree[keyY];\n str += `<div class=\"agno-calendario\">\n <span class=\"agno hide\">${keyY}</span>\n <div class=\"meses\">`;\n Object.keys(year).forEach(keyM => {\n let month = datesTree[keyY][keyM];\n str += ` <div class=\"mes-calendario\">\n <div class=\"mes ${Object.keys(month).length < 4 ? \"mes-reduced mes-reduced-\" + Object.keys(month).length : \"\"}\">\n <div class=\"mes-label\">\n ${_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getMonthByPosition(keyM)} ${keyY}\n </div>\n </div>\n <div class=\"dias\">`;\n Object.keys(month).forEach(keyD => {\n let day = datesTree[keyY][keyM][keyD];\n let isWeekend = day.isWeekend;\n let isToday = day.isToday;\n let hasAlert = config.timeline.header.dateHasAlert ? config.timeline.header.dateHasAlert(day) : false;\n let date = _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].formatDate(day.date);\n str += `<div class=\"dia-calendario \n ${isToday ? \"today\" : \"\"}\n ${isWeekend ? \"weekend\" : \"\"}\n ${hasAlert ? \"has-alert\" : \"\"}\n ${config.timeline.dateSelectable ? \"is-clickeable\" : \"\"}\n ${config.timeline.dateWithContextMenu ? \"is-clickeable\" : \"\"}\n \" date=\"${date}\">${keyD}</div>`;\n });\n str += `</div></div>`;\n });\n str += `</div> </div>`;\n });\n str += `</div>`;\n $elem.innerHTML = \"\";\n $elem.append(_util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str));\n let $days = $elem.querySelectorAll(\".dia-calendario[date]\");\n $days.forEach($dia => {\n if (config.timeline.dateWithContextMenu) {\n $dia.addEventListener(\"contextmenu\", evt => {\n $elem.dispatchEvent(new CustomEvent(\"contextMenuDate\", {\n bubbles: true,\n cancelable: false,\n detail: {\n $elem: $dia,\n date: $dia.getAttribute(\"date\"),\n clientX: evt.clientX,\n clientY: evt.clientY\n }\n }));\n });\n }\n\n if (config.timeline.dateSelectable) {\n $dia.addEventListener(\"click\", evt => {\n $elem.dispatchEvent(new CustomEvent(\"clickDate\", {\n bubbles: true,\n cancelable: false,\n detail: {\n $elem: $dia,\n date: $dia.getAttribute(\"date\")\n }\n }));\n });\n }\n\n if (config.timeline.onMouseOverDate) {\n $dia.addEventListener(\"mouseover\", evt => {\n config.timeline.onMouseOverDate({\n $dia,\n $elem,\n date: $dia.getAttribute(\"date\"),\n evt\n });\n });\n }\n\n if (config.timeline.onMouseOutDate) {\n $dia.addEventListener(\"mouseout\", evt => {\n config.timeline.onMouseOutDate({\n $dia,\n $elem,\n date: $dia.getAttribute(\"date\"),\n evt\n });\n });\n }\n });\n return $elem;\n },\n\n /**\n * Crea Header extended\n * Se usa para :\n * -Mostrar inputs y datos para fechas en header\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom headerExtended\n */\n createHeaderExtended(config) {\n if (config.timeline.header.extend.enabled == false) return null;\n let dates = _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getDateRange(new Date(config.timeline.start), new Date(config.timeline.end));\n let str = `<div class=\"header-container-extended\">`;\n config.timeline.header.extend.data.forEach((d, d_index) => {\n if (d.isHidden) return \"\";\n let isPersistent = d.isPersistent;\n str += `<div class=\"input-list ${isPersistent ? \"persistent\" : \"\"}\">`;\n str += dates.map(date => {\n let value = \"\";\n let className = \"\";\n let isFuture = _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].isFuture(date);\n let isToday = _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].isToday(date);\n\n if (d.data) {\n let dataFounded = d.data.find(dataInput => {\n return _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].isSameDate(new Date(dataInput.date + \"T00:00:00\"), date);\n });\n\n if (dataFounded) {\n value = dataFounded.value || \"\";\n className += dataFounded.className + \" \" || false;\n }\n }\n\n if (d.editable === false || isFuture && d.editableFuture == false || isToday && d.editableToday == false) {\n return `<div>\n <span date=\"${_util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].formatDate(date)}\" \n index=\"${d_index}\" \n class=\" ${className} ${date.varName || \"\"} ${d.color ? \"c-\" + d.color + \"--text\" : \"\"}\" > \n ${value} \n </span>\n </div>`;\n }\n\n let isDisabled = false;\n\n if (config.timeline.editable === false) {\n isDisabled = true;\n }\n\n return `<div class=\"dia-input\">\n <input \n date=\"${_util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].formatDate(date)}\" \n index=\"${d_index}\" \n class=\"header-input \n ${date.varName} ${d.color ? \"c-\" + d.color + \"--text\" : \"\"}\" \n type=\"number\"\n ${isDisabled ? \"disabled\" : \"\"} \n value=\"${value}\">\n </div>`;\n }).join(\"\");\n str += `</div>`;\n });\n str += `</div>`;\n let r = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n r.querySelectorAll(\"input.header-input\").forEach(input => {\n input.addEventListener(\"input\", e => {\n let date = e.currentTarget.getAttribute(\"date\");\n let index = e.currentTarget.getAttribute(\"index\");\n let value = e.currentTarget.value;\n let typeData = config.timeline.header.extend.data[index]; //refresh config value\n\n let data = typeData.data.find(d => _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].isSameDate(new Date(d.date + \"T00:00:00\"), new Date(date + \"T00:00:00\")));\n\n if (data) {\n data.value = value;\n } else {\n typeData.data.push({\n date: date,\n value: value\n });\n }\n\n r.dispatchEvent(new CustomEvent(\"changeInputHeader\", {\n bubbles: true,\n cancelable: false,\n detail: {\n date: date,\n typeData: typeData,\n value: value\n }\n }));\n });\n });\n return r;\n },\n\n /**\n * Crear Sidebar Izquierdo\n * - Maneja items como arbol de 2 niveles (parent, children)\n * - El sidebar se divide en navList - InitialNav - extendedNav - BtnNav\n * - Se agrega itemDetail, para detalles de items\n *\n *\n * TODO: para evitar incrustar las ids en los inputs, se deben crear\n * los nodos uno por uno como elemento DOM, y agregarles los eventos directamente\n * ahora se hace seleccionando todos los inputs con querySelectorAll\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom Sidebar Izquierdo\n */\n createNavLeft(config, tab = null) {\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"nav\", {\n className: \"left\"\n });\n return this.redrawNavLeft($elem, config, tab);\n },\n\n /**\n * Recrea Sidebar izquierdo, usado para redibujar\n * Utiliza $elem como elemento dom donde recrearlo\n *\n *\n * @param {Object} $elem - Elemento Dom donde crea el sidebar izquierdo\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom navLeft\n */\n redrawNavLeft($elem, config, tab = null) {\n let navList = \"\";\n let initialNavList = \"\";\n let exNavList = \"\";\n let btnNavList = \"\";\n let isDisabled = false;\n\n if (config.timeline.editable === false) {\n isDisabled = true;\n }\n\n config.data.forEach(d => {\n if (d.isHidden) return;\n const hasBtn = !!d.onClickDetailButton;\n const detailBtn = hasBtn ? `<button class=\"detail-btn\" item-id=\"${d.id || -1}\" type-node=\"${d.type || \"\"}\" >\n ${d.labelDetailButton}\n </button>` : \"\";\n navList += `\n <div class=\"nav-item\">\n\n\n <div class=\"nav-item-container parent\">`;\n\n if (d.children) {\n navList += `<button class=\"tree-icon ${d.isClosed ? \"\" : \"cap-rotate\"}\" item-id=\"${d.id || -1}\" type-node=\"${d.type || \"\"}\" >\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].chevronDown}\n </button>`;\n }\n\n navList += `\n <div class=\"item-title truncate full-width ${d.clickeable ? \"clickeable\" : \"\"}\n ${d.navOver ? \"hoverable\" : \"\"} \" item-id=\"${d.id || -1}\" type-node=\"${d.type || \"\"}\" >\n <div class=\"item-title-content\">\n ${d.label}\n </div>\n <div class=\"detail-btn-container\">\n ${detailBtn}\n </div>\n </div>\n </div>`;\n\n if (d.children) {\n navList += `\n <div class=\"children-items ${d.isClosed ? \"hide\" : \"\"} \" child-list=\"${d.id || -1}\">`;\n d.children.forEach(c => {\n if (c.isHidden) return;\n let lightColor = null;\n let lightClass = null;\n let lightSpan = \"\";\n let multiButtonsDetailTmpl = \"\";\n\n if (c.light) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(c.light)) {\n lightColor = c.light;\n } else {\n lightClass = c.light;\n }\n }\n\n if (c.light) {\n lightSpan = `<span \n class=\"light ${lightClass ? lightClass + \"-light\" : \"\"}\" \n style=\"${lightColor ? \"--light-color:\" + lightColor : \"\"}\">\n </span>`;\n }\n\n if (c.hasMultibuttons) {\n let iconFormatter = null;\n\n if (config.timeline.nav.left.initial.multibuttons && config.timeline.nav.left.initial.multibuttons.iconFormatter) {\n iconFormatter = config.timeline.nav.left.initial.multibuttons.iconFormatter;\n }\n\n let btnContent = iconFormatter ? iconFormatter({\n item: c,\n config\n }) : \"\";\n multiButtonsDetailTmpl = `<button class=\"multibuttons-btn\" \n item-id=\"${c.id || -1}\" \n type-node=\"${c.type || \"\"}\" \n ${isDisabled ? \"disabled\" : \"\"}>\n ${btnContent} \n </button>`;\n }\n\n navList += `\n <div class=\"child-nav-item\">\n <div class=\"nav-item-container\">\n `;\n /*\n <span class=\"nav-item-icon\">\n <svg style=\"width:24px;height:24px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M19,15L13,21L11.58,19.58L15.17,16H4V4H6V14H15.17L11.58,10.42L13,9L19,15Z\" />\n </svg>\n </span>\n */\n\n navList += `\n ${lightSpan}\n ${multiButtonsDetailTmpl}\n <div \n class=\"item-title ${c.clickeable ? \"clickeable\" : \"\"} ${c.navOver ? \"hoverable\" : \"\"}\" \n item-id=\"${c.id || -1}\" \n type-node=\"${c.type || \"\"}\">\n\n <div class=\"truncate\">\n ${c.label}\n </div>\n </div>\n </div>\n </div>`;\n });\n navList += `\n </div>`;\n }\n\n navList += `</div>`; //initial\n\n initialNavList += `<div class=\"initial-nav-item parent\">`;\n\n if (d.withNav) {\n config.timeline.nav.left.initial.vars.forEach(v => {\n let value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(d.values, v.varName);\n\n if (v.round && !isNaN(value)) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].round(value, v.round);\n }\n\n if (v.input) {\n switch (v.input) {\n case \"hour\":\n value = value.split(\":\");\n let hhValue = value[0];\n let mmValue = value[1];\n initialNavList += `\n <div class=\"item-col has-input\">\n <div class=\"hour-input\">\n <input type=\"number\"\n input-type=\"time\"\n max=\"23\"\n min=\"00\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${d.id || -1}\"\n type-node=\"${d.type || \"\"}\"\n value=\"${hhValue}\"\n ${isDisabled ? \"disabled\" : \"\"}\n class=\"hh\">\n <span>:</span>\n <input type=\"number\"\n input-type=\"time\"\n max=\"59\"\n min=\"00\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${d.id || -1}\"\n type-node=\"${d.type || \"\"}\"\n value=\"${mmValue}\"\n ${isDisabled ? \"disabled\" : \"\"}\n class=\"mm\">\n </div>\n </div>`;\n break;\n\n case \"text\":\n case \"number\":\n default:\n initialNavList += `\n <div class=\"item-col has-input\">\n <input \n type=\"${v.input || \"text\"}\"\n input-type=\"${v.input || \"text\"}\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${d.id || -1}\"\n type-node=\"${d.type || \"\"}\"\n ${isDisabled ? \"disabled\" : \"\"}\n value=\"${value}\"/>\n </div>`;\n }\n } else {\n initialNavList += `\n <div class=\"item-col\">\n ${value}\n </div>`;\n }\n });\n }\n\n initialNavList += `\n </div>`;\n\n if (d.children) {\n d.children.forEach(c => {\n if (c.isHidden) return;\n initialNavList += `<div class=\"child-initial-nav-item ${d.isClosed ? \"hide\" : \"\"}\" child=\"${d.id || -1}\">`;\n\n if (c.withNav !== false) {\n config.timeline.nav.left.initial.vars.forEach(v => {\n if (v.onlyTab && tab && v.onlyTab !== tab.key) return;\n let value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(c.values, v.varName);\n\n if (v.round && !isNaN(value)) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].round(value, v.round);\n }\n\n if (v.input) {\n switch (v.input) {\n case \"hour\":\n value = value.split(\":\");\n let hhValue = value[0];\n let mmValue = value[1];\n initialNavList += `\n <div class=\"item-col has-input\">\n <div class=\"hour-input\">\n <input type=\"number\"\n input-type=\"time\"\n max=\"23\"\n min=\"00\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${c.id || -1}\"\n type-node=\"${c.type || \"\"}\"\n value=\"${hhValue}\"\n ${isDisabled ? \"disabled\" : \"\"}\n class=\"hh\">\n <span>:</span>\n <input type=\"number\"\n input-type=\"time\"\n max=\"59\"\n min=\"00\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${c.id || -1}\"\n type-node=\"${c.type || \"\"}\"\n value=\"${mmValue}\"\n ${isDisabled ? \"disabled\" : \"\"}\n class=\"mm\">\n </div>\n </div>`;\n break;\n\n case \"text\":\n case \"number\":\n default:\n initialNavList += `\n <div class=\"item-col has-input\">\n <input\n type=\"${v.input || \"text\"}\"\n input-type=\"${v.input || \"text\"}\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${c.id || -1}\"\n type-node=\"${c.type || \"\"}\"\n ${isDisabled ? \"disabled\" : \"\"}\n value=\"${value}\"/>\n </div>`;\n }\n } else {\n initialNavList += `\n <div class=\"item-col\">\n ${value}\n </div>`;\n }\n });\n }\n\n initialNavList += `\n </div>`;\n });\n } //Ext\n\n\n exNavList += `<div class=\"ex-nav-item parent\">`;\n\n if (d.withExNav) {\n config.timeline.nav.left.extend.vars.forEach(v => {\n let value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(d.values, v.varName);\n\n if (v.round && !isNaN(value)) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].round(value, v.round);\n }\n\n if (v.input) {\n switch (v.input) {\n case \"hour\":\n value = value.split(\":\");\n let hhValue = value[0];\n let mmValue = value[1];\n exNavList += `\n <div class=\"item-col has-input\">\n <div class=\"hour-input\">\n <input type=\"number\"\n input-type=\"time\"\n max=\"23\"\n min=\"0\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${d.id || -1}\"\n type-node=\"${d.type || \"\"}\"\n value=\"${hhValue}\"\n ${isDisabled ? \"disabled\" : \"\"}\n class=\"hh\">\n <span>:</span>\n <input type=\"number\"\n input-type=\"time\"\n max=\"59\"\n min=\"0\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${d.id || -1}\"\n type-node=\"${d.type || \"\"}\"\n value=\"${mmValue}\"\n ${isDisabled ? \"disabled\" : \"\"}\n class=\"mm\">\n </div>\n </div>`;\n break;\n\n case \"text\":\n case \"number\":\n default:\n exNavList += `\n <div class=\"item-col has-input\">\n <input\n type=\"${v.input || \"text\"}\"\n input-type=\"${v.input || \"text\"}\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${d.id || -1}\"\n type-node=\"${d.type || \"\"}\"\n ${isDisabled ? \"disabled\" : \"\"}\n value=\"${value}\"/>\n </div>`;\n }\n } else {\n exNavList += `\n <div class=\"item-col\">\n ${value}\n </div>`;\n }\n });\n }\n\n exNavList += `\n </div>`;\n\n if (d.children) {\n d.children.forEach(c => {\n if (c.isHidden) return;\n exNavList += `<div class=\"child-ex-nav-item ${d.isClosed ? \"hide\" : \"\"}\" child=\"${d.id || -1}\">`;\n\n if (c.withNav !== false) {\n config.timeline.nav.left.extend.vars.forEach(v => {\n if (v.onlyTab && tab && v.onlyTab !== tab.key) return;\n let value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(c.values, v.varName);\n\n if (v.round && !isNaN(value)) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].round(value, v.round);\n }\n\n if (v.input) {\n switch (v.input) {\n case \"hour\":\n value = value ? value.split(\":\") : [0, 0];\n let hhValue = value[0];\n let mmValue = value[1];\n exNavList += `\n <div class=\"item-col has-input\">\n <div class=\"hour-input\">\n <input type=\"number\"\n input-type=\"time\"\n max=\"23\"\n min=\"0\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${c.id || -1}\"\n type-node=\"${c.type || \"\"}\"\n value=\"${hhValue}\"\n ${isDisabled ? \"disabled\" : \"\"}\n class=\"hh\">\n <span>:</span>\n <input type=\"number\"\n input-type=\"time\"\n max=\"59\"\n min=\"0\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${c.id || -1}\"\n type-node=\"${c.type || \"\"}\"\n value=\"${mmValue}\"\n ${isDisabled ? \"disabled\" : \"\"}\n class=\"mm\">\n </div>\n </div>`;\n break;\n\n case \"text\":\n case \"number\":\n default:\n exNavList += `\n <div class=\"item-col has-input\">\n <input \n type=\"${v.input || \"text\"}\"\n input-type=\"${v.input || \"text\"}\"\n input-key=\"${v.key || \"\"}\"\n item-id=\"${c.id || -1}\"\n type-node=\"${c.type || \"\"}\"\n ${isDisabled ? \"disabled\" : \"\"}\n value=\"${value}\"/>\n </div>`;\n }\n } else {\n exNavList += `\n <div class=\"item-col\">\n ${value}\n </div>`;\n }\n });\n }\n\n exNavList += `\n </div>`;\n });\n } //buttons\n\n\n btnNavList += `<div class=\"cap-btn-nav-item parent\">\n <div class=\"cap-btn-nav-item-content\">`;\n\n if (config.timeline.nav.left.buttons && config.timeline.nav.left.buttons.vars) {\n config.timeline.nav.left.buttons.vars.forEach(btn => {\n if (d.withBtnNav) {\n let btnContent = \"\";\n let className = btn.className || \"\";\n\n if (btn.icon) {\n btnContent = btn.icon ? btn.icon : \"\";\n }\n\n if (btn.iconFormatter) {\n btnContent = btn.iconFormatter ? btn.iconFormatter(d, btn) : \"\";\n }\n\n if (btn.shape) {\n className += \" cap-btn-\" + btn.shape;\n btnContent += `<span> ${btn.formatter ? btn.formatter(d, btn) : \"\"} </span> `;\n }\n\n if (btn.btnClassNameFormatter) {\n let newClassName = btn.btnClassNameFormatter(d, btn);\n\n if (newClassName) {\n className += \" \" + newClassName;\n }\n }\n\n btnNavList += `\n <button class=\"cap-btn-shape ${className}\"\n input-key=\"${btn.key || \"\"}\"\n item-id=\"${d.id || -1}\"\n ${isDisabled ? \"disabled\" : \"\"}\n type-node=\"${d.type || \"\"}\">\n ${btnContent}\n </button>`;\n }\n });\n }\n\n btnNavList += `\n </div>\n </div>`;\n\n if (d.children) {\n d.children.forEach(c => {\n if (c.isHidden) return; //buttons\n\n btnNavList += `<div class=\"cap-btn-child-nav-item parent ${d.isClosed ? \"hide\" : \"\"}\" child=\"${d.id || -1}\">\n <div class=\"cap-btn-nav-item-content\">`;\n\n if (config.timeline.nav.left.buttons && config.timeline.nav.left.buttons.vars) {\n config.timeline.nav.left.buttons.vars.forEach(btn => {\n if (c.withNav !== false) {\n let btnContent = \"\";\n let className = btn.className || \"\";\n\n if (btn.icon) {\n btnContent = btn.icon ? btn.icon : \"\";\n }\n\n if (btn.iconFormatter) {\n btnContent = btn.iconFormatter ? btn.iconFormatter(c, btn) : \"\";\n }\n\n if (btn.shape) {\n className += \" cap-btn-\" + btn.shape;\n btnContent += `<span> ${btn.formatter ? btn.formatter(c, btn) : \"\"} </span> `;\n }\n\n if (btn.btnClassNameFormatter) {\n let newClassName = btn.btnClassNameFormatter(c, btn);\n\n if (newClassName) {\n className += \" \" + newClassName;\n }\n }\n\n btnNavList += `\n <button class=\"cap-btn-shape ${className}\"\n input-key=\"${btn.key || \"\"}\"\n item-id=\"${c.id || -1}\"\n ${isDisabled ? \"disabled\" : \"\"}\n type-node=\"${c.type || \"\"}\">\n ${btnContent}\n </button>`;\n }\n });\n }\n\n btnNavList += `\n </div>\n </div>`;\n });\n }\n });\n let itemDetail = ` <div class=\"detail-nav-item hide\">\n ${this.getDetailNavItemContent()}\n </div>`;\n let str = `<div class=\"nav-container\">\n ${itemDetail}\n <div class=\"nav-item-list\">\n ${navList}\n </div>\n <div class=\"initial-nav-list\">\n ${initialNavList}\n </div>\n <div class=\"extend-nav-list\">\n ${exNavList}\n </div>\n <div class=\"cap-btn-nav-list\">\n ${btnNavList}\n </div>\n </div>`;\n let navContainer = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n $elem.innerHTML = \"\";\n $elem.append(navContainer); //detalle de nav-item\n\n $elem.querySelectorAll(\".item-title.hoverable\").forEach(i => {\n i.addEventListener(\"mouseover\", e => {\n let pos = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].eventToPositionNavLeft(config, e, $elem);\n let itemId = i.getAttribute(\"item-id\");\n let item = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getItemById(config, itemId);\n let typeNode = i.getAttribute(\"type-node\");\n i.dispatchEvent(new CustomEvent(\"overNavItem\", {\n bubbles: true,\n cancelable: false,\n detail: {\n originalEvt: e,\n item: item,\n type: typeNode,\n pos: pos\n }\n }));\n });\n }); //oculta detalle de nav-item, al salir del nav-item-list\n\n $elem.querySelectorAll(\".nav-item-list\").forEach(i => {\n i.addEventListener(\"mouseleave\", e => {\n i.dispatchEvent(new CustomEvent(\"leaveNavItem\", {\n bubbles: true,\n cancelable: false\n }));\n });\n }); //oculta detalle de nav-item-list, al salir de nav-item\n\n $elem.querySelectorAll(\".item-title:not(.hoverable)\").forEach(i => {\n i.addEventListener(\"mousemove\", e => {\n i.dispatchEvent(new CustomEvent(\"leaveNavItem\", {\n bubbles: true,\n cancelable: false\n }));\n });\n });\n $elem.querySelectorAll(\".item-title.clickeable\").forEach(i => {\n i.addEventListener(\"click\", e => {\n let itemId = i.getAttribute(\"item-id\");\n let typeNode = i.getAttribute(\"type-node\");\n let value = i.value;\n i.dispatchEvent(new CustomEvent(\"clickNavLeftItem\", {\n bubbles: true,\n cancelable: false,\n detail: {\n itemId: itemId,\n type: typeNode,\n value: value\n }\n }));\n });\n });\n $elem.querySelectorAll(\".multibuttons-btn\").forEach(i => {\n i.addEventListener(\"click\", e => {\n let pos = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].eventToPositionNavLeft(config, e, $elem);\n let itemId = i.getAttribute(\"item-id\");\n let typeNode = i.getAttribute(\"type-node\");\n i.dispatchEvent(new CustomEvent(\"clickMultiButtonsBtn\", {\n bubbles: true,\n cancelable: false,\n detail: {\n itemId: itemId,\n type: typeNode,\n pos,\n button: i,\n event: e\n }\n }));\n });\n });\n $elem.querySelectorAll(\"input\").forEach(i => {\n i.addEventListener(\"change\", e => {\n let inputType = i.getAttribute(\"input-type\");\n let key = i.getAttribute(\"input-key\");\n let itemId = i.getAttribute(\"item-id\");\n let typeNode = i.getAttribute(\"type-node\");\n let item = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getItemById(config, itemId);\n let value = i.value;\n\n if (inputType == \"time\") {\n let hh_input = i.parentElement.querySelector(\"input.hh\").value;\n let mm_input = i.parentElement.querySelector(\"input.mm\").value;\n mm_input = mm_input < 10 ? \"0\" + parseFloat(mm_input) : mm_input;\n i.parentElement.querySelector(\"input.mm\").value = mm_input;\n value = hh_input + \":\" + mm_input;\n }\n\n i.dispatchEvent(new CustomEvent(\"saveNavLeftInput\", {\n bubbles: true,\n cancelable: false,\n detail: {\n key: key,\n itemId: itemId,\n item: item,\n type: typeNode,\n value: value,\n tabSelected: tab\n }\n }));\n });\n });\n $elem.querySelectorAll(\"button.cap-btn-shape\").forEach(i => {\n i.addEventListener(\"click\", e => {\n let key = i.getAttribute(\"input-key\");\n let itemId = i.getAttribute(\"item-id\");\n let typeNode = i.getAttribute(\"type-node\");\n i.dispatchEvent(new CustomEvent(\"clickNavLeftButton\", {\n bubbles: true,\n cancelable: false,\n detail: {\n key: key,\n itemId: itemId,\n type: typeNode\n }\n }));\n });\n });\n $elem.querySelectorAll(\"button.detail-btn\").forEach(i => {\n i.addEventListener(\"click\", e => {\n let itemId = i.getAttribute(\"item-id\");\n let typeNode = i.getAttribute(\"type-node\");\n let item = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getItemById(config, itemId, \"parent\");\n\n if (item && item.onClickDetailButton) {\n item.onClickDetailButton({\n itemId: itemId,\n type: typeNode,\n item: item,\n event: e,\n button: i\n });\n }\n });\n });\n $elem.querySelectorAll(\"button.tree-icon\").forEach(i => {\n i.addEventListener(\"click\", e => {\n let itemId = i.getAttribute(\"item-id\");\n let typeNode = i.getAttribute(\"type-node\");\n let dataConfig = config.data.find(d => d.id == itemId);\n let $navItem = e.currentTarget.closest(\".nav-item\");\n let $children = $navItem.querySelector(\".children-items\");\n let itemsToHide = e.currentTarget.closest(\"nav.left\").querySelectorAll(\"[child='\" + itemId + \"'], [child-list='\" + itemId + \"']\");\n\n if ($children) {\n if ($children.classList.contains(\"hide\")) {\n e.currentTarget.classList.add(\"cap-rotate\");\n itemsToHide.forEach(i => i.classList.remove(\"hide\"));\n dataConfig.isClosed = false;\n } else {\n e.currentTarget.classList.remove(\"cap-rotate\");\n itemsToHide.forEach(i => i.classList.add(\"hide\"));\n dataConfig.isClosed = true;\n }\n }\n\n i.dispatchEvent(new CustomEvent(\"clickNavLeftTreeIcon\", {\n bubbles: true,\n cancelable: false,\n detail: {\n itemId: itemId,\n type: typeNode\n }\n })); //e.currentTarget.parent\n });\n });\n return $elem;\n },\n\n /**\n * Crea Html como String, para el detalle de items en el Sidebar Izquierdo\n *\n * @param {Object} [item={}] - Configuracion de item\n * @return {String} Html de ventana de detalle\n */\n getDetailNavItemContent(item = {}) {\n if (item.navOver == undefined) item.navOver = {};\n return `\n <div class=\"header-detail\">\n <div class=\"detail-title truncate\">\n ${item.label || \"\"}\n </div>\n <div class=\"detail-subtitle\">\n ${item.navOver.subtitle || \"\"}\n </div>\n <div class=\"header-chip ${item.light ? item.light + \"-light\" : \"\"} ${item.navOver.chip ? \"\" : \"hide\"}\">\n ${item.navOver.chip || \"\"}\n </div>\n </div>\n\n <div class=\"detail-container\">\n ${item.navOver.content || \"\"}\n </div>`;\n },\n\n /**\n * Crea Sidebar Derecho\n * Usado principalmente para formulario de ingreso de datos para los dias\n * seleccionados\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} tab - Tab de referencia, para la creacion del formulario\n * @return {Object} {element, inputs}, element es el elemento Dom del sidebar,\n * inputs es un array de elementos Dom de cada input creado\n * (no son elementos html de tipo input)\n */\n createNavRight(config, tab = null) {\n var $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"nav\", {\n className: \"right\"\n });\n return this.redrawNavRight(config, $elem, tab, null, [], null);\n },\n\n /**\n * Recrea Sidebar Derecho\n * Utiliza $elem como elemento dom donde recrearlo\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} $elem - Elemento Dom donde crea el sidebar derecho\n * @param {Object} tab - Tab de referencia, para la creacion del formulario\n * @param {Object} dataDay - datos del dia seleccionando, para autorrelleno de formulario\n * @param {Object} daySelected - datos del dia seleccionado\n * @param {String} daySelected.date - fecha del dia seleccionado\n * @param {Object} daySelected.item - Item de Sidebar relacionado al dia seleccionado\n * @param {Object} daySelected.pos - posicion de dia seleccionado\n * @return {Object} Elemento Dom Sidebar Derecho\n */\n redrawNavRight(config, $elem, selected = null, tab = null, dataDay = null, daySelected = null) {\n let $navRight = $elem; //dom.createElement(\"nav\",{className:\"right\"});\n\n let $divContainer = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"nav-input-container\"\n });\n let $inputs = [];\n let checkboxInputs = [];\n let inputsWithReload = [];\n let tabSelected = tab;\n selected = selected || [daySelected];\n\n if (tabSelected && tabSelected.inputs) {\n tabSelected.inputs.forEach(i => {\n if (i.disabled) return;\n\n if (i.showInputIf && !i.showInputIf(dataDay, daySelected, selected, tabSelected)) {\n return;\n }\n\n let $input = this.createInput(i, dataDay, daySelected, selected, tabSelected);\n\n if ($input) {\n $divContainer.appendChild($input);\n $inputs.push($input);\n\n if (i.type == \"checkbox\") {\n checkboxInputs.push($input);\n }\n\n if (i.reloadOnSelect != null) {\n inputsWithReload.push({\n $input,\n config: i\n });\n }\n }\n });\n } //manejo de eventos para inputs con showIf\n\n\n if (checkboxInputs) {\n checkboxInputs.forEach($c => {\n //obtiene key de checkbox\n let key = $c.getAttribute(\"input-key\");\n let props = tabSelected.inputs.find(i => {\n return i.key == key;\n });\n let isChecked = false;\n\n if (dataDay) {\n isChecked = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n } //obtiene inputs relacionados desde config para mostrar/ocultar\n\n\n let inputsToHide = tabSelected.inputs.filter(i => {\n return i.showIf && i.showIf == key;\n });\n let inputsToHideKeys = inputsToHide.map(i => i.key); //obtiene inputs del dom, filtrando con inputsToHide\n\n let $inputsHidden = $inputs.filter($i => {\n let inputKey = $i.getAttribute(\"input-key\");\n return inputsToHideKeys.indexOf(inputKey) > -1;\n }); //si hay inputs,\n\n if ($inputsHidden) {\n if (!isChecked) {\n $inputsHidden.forEach($i => {\n $i.classList.add(\"hide\");\n });\n }\n\n $c.addEventListener(\"input\", e => {\n $inputsHidden.forEach($i => {\n let fn = $c.querySelector(\"input[type='checkbox']\").checked ? \"remove\" : \"add\";\n $i.classList[fn](\"hide\");\n });\n });\n }\n });\n }\n\n let saveCancelBtns = this.createNavRightbuttons(config);\n $divContainer.appendChild(saveCancelBtns);\n $navRight.innerHTML = \"\";\n $navRight.appendChild($divContainer);\n return {\n element: $navRight,\n inputs: $inputs,\n inputsWithReload,\n saveCancelBtns\n };\n },\n\n /**\n * Crea Corner inferior izquierdo, como titulo para footer\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom Corner Footer\n */\n createCornerFooter(config) {\n if (config.timeline.footer === undefined || config.timeline.footer.enabled == false) return null;\n let str = \"\";\n\n if (config.timeline.footer) {\n str += `<div class=\"corner-footer\">\n <div class=\"corner-title\">\n <span>\n ${config.timeline.footer.label}\n </span>\n </div>\n </div>`;\n }\n\n return _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n },\n\n /**\n * Crea Footer para planilla\n * Inicialmente creado para totales\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom Corner Footer\n */\n createFooter(config) {\n if (config.timeline.footer === undefined || config.timeline.footer.enabled == false) return null;\n let str = `\n <footer>\n <div class=\"footer-container\">\n `;\n config.timeline.footer.data.forEach(d => {\n str += `\n <div class=\"footer-item\">${d.value}</div>\n `;\n });\n str += `\n </div>\n </footer>\n `;\n return _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n },\n\n /**\n * Crea Footer para planilla\n * Inicialmente creado para totales\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object[]} selected - array de objetos, de dias seleccionados\n * @return {Object} Elemento Dom Corner Footer\n */\n createSelectBoard(config, selected) {\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"select-container\"\n });\n return this.redrawSelectBoard($elem, selected);\n },\n\n /**\n * Crea linea vertical para fecha Actual\n *\n * @param {Object} config - Configuracion capibara\n * @return {Object} Elemento Dom Corner Footer\n */\n createTodayLine(config) {\n return this.redrawTodayLine(config, _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"today-line\"\n }));\n },\n\n /**\n * Recrea linea vertical para fecha Actual\n * si el elemento $elem no es enviado, se crea un nuevo elemento\n *\n * Si el dia actual no esta dentro del rango de fechas del config,\n * deshabilita la linea con la clase css .disable-line\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} [$elem=null] - Elemento Dom donde recrea la linea, si es null, la crea\n * @return {Object} Elemento Dom Corner Footer\n */\n redrawTodayLine(config, $elem = null) {\n let endTime = new Date(config.timeline.end).getTime();\n let todayTime = new Date().getTime();\n let {\n height,\n dayWidth\n } = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getTableDimensions(config);\n if ($elem == null) $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"today-line\"\n });\n\n if (endTime < todayTime) {\n $elem.classList.add(\"disable-line\");\n } else {\n $elem.classList.remove(\"disable-line\");\n }\n\n let diffDays = Math.floor(_util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].diffDays(config.timeline.start, _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].formatDate(new Date())));\n let diff = diffDays * dayWidth;\n diff += dayWidth / 2 - 2; // para centrar linea\n\n Object.assign($elem.style, {\n \"margin-left\": diff + \"px\",\n height: height + \"px\"\n });\n return $elem;\n },\n\n /**\n * Crea elemento FloatBox, que contiene los datos que se muestra en la tabla\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} tab - Tab de referencia, para mostrar datos configurados por tab\n * @return {Object} Elemento Dom Corner Footer\n */\n createFloatBox(config, tab) {\n let $container = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"float-box-container\"\n });\n return this.redrawFloatBox(config, tab, $container);\n },\n\n /**\n * Recrea elemento FloatBox, que contiene los datos que se muestra en la tabla\n * Se usa principalmente para mostrar datos en la tabla de la planilla\n * los muestra de manera flotante, calculando el Top y el Left segun la poscion\n *\n * Se consideran los elementos padres ocultos, para ocultar los datos\n *\n * Se insertan los elementos FloatBox, como elemento con datos de un item y dia especifico\n *\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} tab - Tab de referencia, para mostrar datos configurados por tab\n * @return {Object} Elemento Dom Corner Footer\n */\n redrawFloatBox(config, tab, $container) {\n $container.innerHTML = \"\"; //let tabSelected = tab || null;\n\n config.data.forEach(dataParent => {\n if (dataParent.isHidden) return;\n (dataParent.data || []).forEach(data => {\n this.createFloatBoxItem({\n container: $container,\n data,\n item: dataParent,\n isClosed: dataParent.isClosed,\n tab,\n config,\n typeNode: \"parent\"\n });\n });\n dataParent.children.forEach(dataChild => {\n if (dataChild.isHidden) return;\n dataChild.data.forEach(data => {\n this.createFloatBoxItem({\n container: $container,\n data,\n item: dataChild,\n isClosed: dataParent.isClosed,\n tab,\n config,\n typeNode: \"child\"\n });\n });\n });\n });\n return $container;\n },\n\n createFloatBoxItem({\n container,\n data,\n item,\n isClosed,\n tab,\n config,\n typeNode = \"child\"\n }) {\n // Verificar si hay mensaje\n let msg = null;\n\n if (tab.floatBox && tab.floatBox.messagePath) {\n msg = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data, tab.floatBox.messagePath);\n }\n\n const hasMessage = msg || data.message && data.message.value; // Verificar si hay errores\n\n const hasErrors = data.errors && data.errors.length > 0; // Verificar si hay contenido visible en floatBox\n\n let hasVisibleContent = false;\n\n if (hasMessage || hasErrors) {\n hasVisibleContent = true;\n } else if (data.values && tab && tab.floatBox) {\n // Verificar si hay contenido visible en nums, dots, plots, icons\n if (tab.floatBox.nums) {\n hasVisibleContent = tab.floatBox.nums.some(n => {\n let value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.varName);\n if (value === null || value === undefined) return false;\n let showIf = true;\n let hideIf = false;\n\n if (n.varShow) {\n showIf = Boolean(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.varShow));\n }\n\n if (n.varHide) {\n hideIf = Boolean(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.varHide));\n }\n\n if (n.hidden === true) {\n hideIf = true;\n }\n\n return value !== null && showIf && !hideIf;\n });\n }\n\n if (!hasVisibleContent && tab.floatBox.dots) {\n hasVisibleContent = tab.floatBox.dots.some(dot => {\n return _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, dot.varName) !== null;\n });\n }\n\n if (!hasVisibleContent && tab.floatBox.plots) {\n hasVisibleContent = tab.floatBox.plots.some(n => {\n return _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.varName) !== null;\n });\n }\n\n if (!hasVisibleContent && tab.floatBox.icons) {\n hasVisibleContent = tab.floatBox.icons.some(iconConfig => {\n if (iconConfig.varName) {\n return _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, iconConfig.varName) !== null;\n }\n\n return iconConfig.icon !== null;\n });\n }\n\n if (!hasVisibleContent && tab.floatBox.rowDots) {\n hasVisibleContent = tab.floatBox.rowDots.some(row => {\n return Array.isArray(row) && row.some(dot => {\n let value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, dot.varName);\n if (value === null || value === undefined) return false;\n let showIf = true;\n let hideIf = false;\n\n if (dot.varShow) {\n showIf = Boolean(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, dot.varShow));\n }\n\n if (dot.varHide) {\n hideIf = Boolean(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, dot.varHide));\n }\n\n return showIf && !hideIf;\n });\n });\n }\n } // Si no hay contenido visible, no crear el floatBox\n\n\n if (!hasVisibleContent) {\n return null;\n } //children Data\n\n\n let position = this.getPositionFloatBox(config, data, item, typeNode);\n let className = \"\";\n\n if (data.errors && data.errors.length > 0) {\n className += \"has-errors \";\n\n if (data.errors[0]) {\n className += data.errors[0].classNameIcon + \" \";\n }\n }\n\n if (isClosed) {\n className += \"hide \";\n }\n\n if (hasMessage) {\n className += \"has-message \";\n }\n\n let strMsg = \"\";\n\n if (hasMessage) {\n let viewBox = \"0 0 24 24\"; //email outline icon\n\n let icon = \"M22 6C22 4.9 21.1 4 20 4H4C2.9 4 2 4.9 2 6V18C2 19.1 2.9 20 4 20H20C21.1 20 22 19.1 22 18V6M20 6L12 11L4 6H20M20 18H4V8L12 13L20 8V18Z\";\n strMsg = `\n <div class=\"icon-message\">\n <svg viewBox=\"${viewBox}\">\n <path d=\"${icon}\" />\n </svg>\n </div>\n `;\n }\n\n let str = `\n <div class=\"float-box ${className} \"\n style=\"${position ? position : \"\"}\"\n item-id=\"${item.id || -1}\"\n type-node=\"${item.type || \"\"}\">\n\n ${strMsg}\n <div class=\"float-box-content\">`;\n let strExt = `\n <div class=\"float-box-ext ${isClosed ? \"hide\" : \"\"}\"\n style=\"${position ? position : \"\"}\"\n item-id=\"${item.id || -1}-ext\"\n type-node=\"${item.type || \"\"}\">\n <div class=\"long-bar-container\">`;\n\n if (tab && tab.floatBox) {\n if (tab.floatBox.plots) {\n str += `<div class=\"plot-floatbox-container\">`;\n tab.floatBox.plots.forEach(n => {\n let cssVars = \"\";\n let className = \"\";\n\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.varName) !== null) {\n if (n.color) {\n cssVars = `--local-color:${n.color};`;\n }\n\n className = n.className || \"\";\n str += `<div class=\"plot-floatbox ${className} ${n.style || \"\"}\" style=\"${cssVars} \"></div>`;\n }\n });\n str += `\n </div>`;\n }\n\n if (tab.floatBox.icons) {\n tab.floatBox.icons.forEach(iconConfig => {\n let className = \"\";\n let colorClass = \"\";\n let colorStyle = \"\";\n let viewBox = \"0 0 24 24\";\n let icon = iconConfig.icon || null;\n\n if (iconConfig.varName) {\n let iconVar = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, iconConfig.varName);\n\n if (iconVar) {\n icon = iconVar;\n }\n }\n\n if (iconConfig.className) {\n className = iconConfig.className;\n }\n\n if (iconConfig.color) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(iconConfig.color)) {\n colorStyle = `--local-color: ${iconConfig.color};`;\n } else {\n colorClass = iconConfig.color;\n }\n }\n\n if (iconConfig.colorVarName) {\n let colorVar = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, iconConfig.colorVarName);\n\n if (colorVar) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(colorVar)) {\n colorStyle = `--local-color: ${colorVar};`;\n } else {\n colorClass = colorVar;\n }\n }\n }\n\n str += `\n <div class=\"icon-floatbox ${className} ${colorClass ? \"has-color\" : \"\"}\" style=\"${colorStyle}\">\n <svg viewBox=\"${viewBox}\">\n <path d=\"${icon}\" />\n </svg>\n </div>\n `;\n });\n } //numeros en el floatBox\n\n\n if (tab.floatBox.nums) {\n tab.floatBox.nums.forEach(n => {\n if (tab.legends && n.tabKey) {\n let legend = tab.legends.find(l => l.key == n.tabKey);\n if (legend && !legend.active) return;\n }\n\n let dataFloatBox = null;\n let className = \"\";\n let showIf = true;\n let hideIf = false;\n let colorClass = \"\";\n let colorStyle = \"\";\n let classNamesExt = \"\";\n let colorStyleExt = \"\";\n let cssVars = \"\";\n\n if (n.varName) {\n dataFloatBox = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.varName);\n }\n\n if (n.varShow) {\n showIf = Boolean(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.varShow));\n dataFloatBox = dataFloatBox || \"\";\n }\n\n if (n.varHide) {\n hideIf = Boolean(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.varHide));\n }\n\n if (n.hidden === true) {\n hideIf = true;\n }\n\n if (n.shape) {\n className += \"shape-\" + n.shape;\n }\n\n if (n.color) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(n.color)) {\n colorStyle = `--local-color: ${n.color};`;\n } else {\n colorClass = n.color;\n }\n }\n\n if (n.longBar) {\n let longBarColor = \"\";\n let longBarOpacity = \"\";\n\n if (n.longBarColor) {\n longBarColor = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.longBarColor);\n }\n\n if (longBarColor) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(longBarColor)) {\n colorStyleExt = `--local-color: ${longBarColor};`;\n } else {\n classNamesExt += longBarColor + \"-light \";\n }\n } else if (colorClass && colorClass != \"\") {\n classNamesExt += colorClass;\n } else if (colorStyle && colorStyle != \"\") {\n colorStyleExt = colorStyle;\n }\n\n if (n.longBarOpacity) {\n longBarOpacity = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.longBarOpacity) || null;\n\n if (longBarOpacity) {\n colorStyleExt += \"--local-opacity: \" + longBarOpacity + \";\";\n }\n }\n\n if (n.longBarClassName) {\n classNamesExt += _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.longBarClassName) || \"\";\n }\n\n let longBar = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, n.longBar);\n\n if (longBar) {\n cssVars = `--long:${longBar};`;\n }\n }\n\n if (dataFloatBox !== null && showIf && !hideIf) {\n str += `<span class=\"data ${colorClass} ${className}\" style=\"${colorStyle}\">\n ${typeof dataFloatBox == \"string\" ? dataFloatBox : \"\"}\n ${typeof dataFloatBox == \"number\" ? _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].round(dataFloatBox, n.round) : \"\"}\n </span>`;\n\n if (n.longBar && cssVars) {\n strExt += `<div class=\"long-bar ${classNamesExt}\" style=\"${colorStyleExt} ${cssVars} \"></div> `;\n }\n }\n });\n } //puntos en el floatBox\n\n\n if (tab.floatBox.dots) {\n str += `<div class=\"dot-container-middle\">`;\n tab.floatBox.dots.forEach(dot => {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, dot.varName) !== null) {\n let className = \"\";\n let colorClass = \"\";\n let colorStyle = \"\";\n\n if (dot.shape) {\n className += dot.shape;\n }\n\n if (dot.color) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(dot.color)) {\n colorStyle = `--local-color: ${dot.color}`;\n } else {\n colorClass = dot.color;\n }\n }\n\n str += `\n <div class=\"dot ${colorClass} ${className}\" style=\"${colorStyle}\" ></div>`;\n }\n });\n str += `\n </div>`;\n } //fila de puntos en floatBox\n\n\n if (tab.floatBox.rowDots) {\n tab.floatBox.rowDots.forEach(row => {\n let freeColumns = 4;\n str += `<span class=\"rowdot--row \">`;\n row.forEach(dot => {\n if (tab.legends && dot.tabKey) {\n let legend = tab.legends.find(l => l.key == dot.tabKey);\n if (legend && !legend.active) return;\n }\n\n let dataFloatBox = null;\n let className = \"\";\n let showIf = true;\n let hideIf = false;\n let colorClass = \"\";\n let colorStyle = \"\";\n\n if (dot.varName) {\n dataFloatBox = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, dot.varName);\n dataFloatBox = parseInt(dataFloatBox);\n }\n\n if (dot.varShow) {\n showIf = Boolean(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, dot.varShow));\n dataFloatBox = dataFloatBox || \"\";\n }\n\n if (dot.varHide) {\n hideIf = Boolean(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(data.values, dot.varHide));\n }\n\n if (dot.shape) {\n className += \" shape-\" + dot.shape;\n }\n\n if (dot.color) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(dot.color)) {\n colorStyle = `--local-color: ${dot.color}`;\n } else {\n colorClass = dot.color;\n }\n }\n\n if (dataFloatBox !== null && dataFloatBox > 0 && showIf && !hideIf && freeColumns > 0) {\n let n = dataFloatBox > freeColumns ? freeColumns : dataFloatBox;\n freeColumns -= n;\n\n for (let index = 0; index < n; index++) {\n str += `<div class=\"rowdot--dot ${colorClass} ${className}\" style=\"${colorStyle}\"></div>`;\n }\n }\n });\n str += `</span>`;\n });\n }\n }\n\n str += `\n </div>\n </div>`;\n strExt += `\n </div>\n </div>`;\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n let $elemExt = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(strExt);\n $elem.addEventListener(\"mouseover\", e => {\n $elem.dispatchEvent(new CustomEvent(\"mouseOverFloatBox\", {\n bubbles: true,\n cancelable: false,\n detail: {\n item: item,\n data: data,\n originalEvt: e\n }\n }));\n });\n $elem.addEventListener(\"click\", e => {\n $elem.dispatchEvent(new CustomEvent(\"clickFloatBox\", {\n bubbles: true,\n cancelable: false,\n detail: {\n item: item,\n data: data,\n originalEvt: e\n }\n }));\n });\n container.appendChild($elem);\n container.appendChild($elemExt);\n },\n\n /**\n * Crea DetailDay, detalle de valores de item y Dia\n * se usa para:\n * - Muestra nombre de item y detalles\n * - Muestra capsulas de datos\n * - Muestra Pills, pildoras de datos resumidos\n * - Muestra alertas\n * - Muestra Mensaje\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} item - Item relacionado\n * @param {Object} dataDay - valores de item y Dia\n * @param {Boolean} [onlyStringContent = false] - para escoger si devuelve String o DomElement\n * @return {String|Object} Elemento como String o DomElement\n */\n createDetailDay(config, item = {}, dataDay, tabSelected, onlyStringContent = false) {\n let str = `\n <div class=\"header-detail\">\n <div class=\"title truncate\">\n ${item.label || \"\"}\n </div>\n <div class=\"subtitle\">\n ${dataDay ? _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].formatDateReadeable(dataDay.date) : \"\"}\n </div>\n </div>\n\n <div class=\"list-detail list column-flex\">`; //CAPSULES\n\n let visibleItemsCount = 0; // Contador de elementos visibles\n\n if (dataDay) {\n config.timeline.detailDay.capsules.forEach(cap => {\n //para comprobar si tiene datos, se obtiene el primer valor\n //de la lista de values de una capsula\n let hasValues = cap.values.filter(v => {\n let value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay.values, v.varName);\n return value !== null && !(Array.isArray(value) && value.length === 0);\n }).length > 0;\n let hideIf = false;\n\n if (cap.hideIf) {\n hideIf = Boolean(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay.values, cap.hideIf));\n }\n\n let colorClass = \"\";\n let colorStyle = \"\";\n\n if (cap.color) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(cap.color)) {\n colorStyle = `--local-color: ${cap.color};`;\n colorStyle += `--local-color-font: ${cap.color};`;\n } else {\n colorClass = cap.color;\n }\n }\n\n if (hasValues && !hideIf) {\n visibleItemsCount++; // Incrementar contador de elementos visibles\n\n str += `\n <div class=\"item-detail ${colorClass}\" style=\"${colorStyle}\">\n\n <div class=\"left-icon ${cap.shape || \"\"} \"></div>\n\n <div class=\"name\">\n <span>\n ${cap.title || \"\"}\n </span>\n </div>`;\n str += `\n <div class=\"item-description\"> `;\n cap.values.forEach(v => {\n let value = v.varName ? _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay.values, v.varName) : null;\n\n if (cap.isLabeledArray) {\n value.forEach(valueLabeled => {\n let outputValue = null;\n let valueName = v.valueName ? v.valueName : \"value\";\n let tempValue = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(valueLabeled, valueName);\n\n if (tempValue) {\n outputValue = v.round ? _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].round(tempValue, v.round) : tempValue;\n }\n\n if (v.formatter) {\n outputValue = v.formatter(valueLabeled);\n }\n\n if (typeof outputValue == \"number\") {\n outputValue = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].formatNumber(outputValue);\n }\n\n str += outputValue == null ? \"\" : `\n <div class=\"desc ${v.showColumn ? \"desc-column\" : \"\"}\">\n \n <div class=\"label\">\n ${v.hideLabel ? \"\" : valueLabeled.label}\n </div >\n <div class=\"val\">` + (v.hidePreffix !== true ? `\n <span class=\"prefix\">\n ${v.prefix || \"\"}\n </span>` : \"\") + `<span class=\"value\">\n ${outputValue}\n </span>` + (v.hideSuffix !== true ? `\n <span class=\"suffix\">\n ${valueLabeled.suffix || v.suffix || \"\"}\n </span>` : \"\") + `\n </div>\n </div>`;\n });\n } else {\n let outputValue = v.round ? _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].round(value, v.round) : value;\n\n if (v.formatter) {\n outputValue = v.formatter({\n options: v,\n dataDay,\n outputValue\n });\n }\n\n if (typeof outputValue == \"number\") {\n outputValue = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].formatNumber(outputValue);\n }\n\n if (outputValue) {\n str += `\n <div class=\"desc\">\n <span class=\"prefix\">\n ${v.prefix || \"\"}\n </span>\n <span class=\"value\">\n ${outputValue}\n </span>\n <span class=\"suffix\">\n ${v.suffix || \"\"}\n </span>\n </div>`;\n }\n }\n });\n str += `\n </div>`;\n str += `\n </div>`; // end .item-detail\n }\n });\n } // Agregar clase single-item si solo hay un elemento visible\n\n\n const columnClass = visibleItemsCount === 1 ? \"list column-flex single-item\" : \"list column-flex\";\n str = str.replace(\"list column-flex\", columnClass);\n str += `\n </div>`; // list-detail\n //PILLS\n\n if (config.timeline.detailDay.pillsVarName && dataDay && dataDay.values[config.timeline.detailDay.pillsVarName]) {\n str += `\n <div class=\"elements-detail\">\n <div class=\"name\"> ${config.timeline.detailDay.pillsTitle} </div>\n <div class=\"elements-list\">`;\n dataDay.values[config.timeline.detailDay.pillsVarName].forEach(e => {\n let value = e.value;\n\n if (typeof outputValue == \"number\") {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].formatNumber(value);\n }\n\n str += `\n <div class=\"element-detail\">\n <b>${e.label}</b>\n ${value}\n </div>`;\n });\n str += `\n </div>\n </div>`; //end .element-detail > .element-list\n } //str += `</div>`;\n\n\n if (dataDay && dataDay.errors && dataDay.errors.length > 0) {\n dataDay.errors.forEach(err => {\n str += `\n <div class=\"alert\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].alert}\n ${err.label}\n </div>`;\n });\n }\n\n let msg = null;\n let author = null;\n let dateMsg = null;\n\n if (dataDay && tabSelected.floatBox && tabSelected.floatBox.messagePath) {\n msg = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, tabSelected.floatBox.messagePath);\n }\n\n if (!msg && dataDay && dataDay.message && dataDay.message.value) {\n msg = dataDay.message.value;\n author = dataDay.message.author;\n dateMsg = _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].formatDateReadeable(new Date(dataDay.message.date));\n }\n\n if (msg) {\n //msg = msg.replace(/(\\r\\n|\\r|\\n)/g, '<br>');\n str += `\n <div class=\"msj-container\">\n <div class=\"msj\">\n <pre>${msg || \"\"}</pre>\n </div>\n <div class=\"msj-detail\">\n <span class=\"email\"> ${author || \"\"} </span>\n <span class=\"date\"> ${dateMsg || \"\"} </span>\n </div>\n </div>`;\n }\n\n let strContainer = `<div class=\"detail-day dd-hide\"> ${str} </div>`;\n if (onlyStringContent) return str;\n return _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(strContainer);\n },\n\n /**\n * Recrea HTML de detailDay\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} item - Item relacionado\n * @param {Object} dataDay - valores de item y Dia\n * @return {String} Elemento como String, de detailDay\n */\n redrawDetailDay(config, item, dataDay, tabSelected) {\n return this.createDetailDay(config, item, dataDay, tabSelected, true);\n },\n\n /**\n * Reposiciona FloatBox\n * verifica si el parent esta desplegado, para ocultar los datos\n *\n * Solo actualiza las alturas de los floatbox\n * no recrea los floatbox, es mas optimo\n *\n * @param {Object} config - Configuracion capibara\n * @param {Object} item - Item relacionado\n */\n repositionFloatBox(config, $floatBoxContainer) {\n $floatBoxContainer.querySelectorAll(\".float-box\").forEach($f => {\n let itemId = $f.getAttribute(\"item-id\");\n let itemHeight = parseFloat(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getCSSVariable(config, \"--item-height\"));\n let item, parent;\n ({\n item,\n parent\n } = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getItemById(config, itemId, \"child\", true));\n\n if (item) {\n let top = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getPositionByItem(config, item);\n $f.style.top = top * itemHeight + \"px\";\n\n if (parent && parent.isClosed) {\n $f.classList.add(\"hide\");\n } else if ($f.classList.contains(\"hide\")) {\n $f.classList.remove(\"hide\");\n }\n }\n });\n },\n\n /**\n * Recrea indicadores de dias seleccionados\n *\n * @param {Object} $elem - Elemento Dom donde crea los elementos seleccionados\n * @param {Object[]} selected - Array con los dias seleccionados\n * @return {Object} Elemento Dom que contiene los indicadores de dias seleccionados\n */\n redrawSelectBoard($elem, selected) {\n $elem.innerHTML = \"\";\n let hasNumber = true;\n\n if (selected) {\n if (selected.length == 1) hasNumber = false;\n selected.forEach(s => {\n let attributes = [];\n\n if (hasNumber) {\n attributes.push({\n name: \"cap-badge\",\n value: s.index\n });\n }\n\n let $s = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElement(\"div\", {\n className: \"selected-day\",\n attributes\n });\n $s.style.left = s.pos.left + \"px\";\n $s.style.top = s.pos.top + \"px\";\n $elem.append($s);\n });\n }\n\n return $elem;\n },\n\n /**\n * Obtiene String con estilos CSS de la posicion de un floatBox\n * calculado segun item y fecha de los valores\n *\n * @param {Object} config - Configuracion capibara, para ver fecha de inicio\n * @param {Object} data - Datos del dia indicado\n * @param {Object} item - Item relacionado\n * @return {String} String CSS top y left , para posicionar floatBox en table\n */\n getPositionFloatBox(config, data, item, typeNode) {\n let left = _util_dateUtils__WEBPACK_IMPORTED_MODULE_2__[\"default\"].diffDays(config.timeline.start, data.date);\n let top = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getPositionByItem(config, item, typeNode);\n let dayWidth = parseFloat(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getCSSVariable(config, \"--day-width\"));\n let itemHeight = parseFloat(_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getCSSVariable(config, \"--item-height\"));\n left *= dayWidth;\n top *= itemHeight;\n return \"top: \" + top + \".5px; left:\" + left + \".5px;\";\n },\n\n /**\n * Crea Boton como elemento Dom\n *\n * @param {Object} props - propiedades para boton\n * @param {String} props.className - classes css para boton\n * @param {*} props.key - key para identificar a boton\n * @param {String} props.label - Texto boton\n * @return {Object} Elemento Dom del boton creado\n */\n createButton(props) {\n return _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <button class=\"${props.className || \"\"}\" input-key=\"${props.key || \"\"}\">\n ${props.label || \"\"}\n </button>`);\n },\n\n /**\n * Crea Botones de guardar y cancelar los datos de formulario del sidebar derecho\n *\n * @return {Object} Elemento Dom del botones creados\n */\n createNavRightbuttons(config) {\n let btnSection = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`<div class=\"button-section\"></div>`);\n\n if (config.timeline.nav.right && config.timeline.nav.right.hideSaveButton != true) {\n let saveBtn = this.createButton({\n label: \"Guardar\",\n className: \"cap-btn-raised\"\n });\n btnSection.appendChild(saveBtn);\n saveBtn.addEventListener(\"click\", e => {\n saveBtn.dispatchEvent(new CustomEvent(\"saveMultiInput\", {\n bubbles: true,\n cancelable: false\n }));\n });\n }\n\n if (config.timeline.nav.right && config.timeline.nav.right.hideCancelButton != true) {\n const cancelLabelButton = config.timeline.nav.right.cancelLabelButton || \"Cancelar\";\n let cancelBtn = this.createButton({\n label: cancelLabelButton,\n className: \"cap-btn-outline\"\n });\n btnSection.appendChild(cancelBtn);\n cancelBtn.addEventListener(\"click\", e => {\n cancelBtn.dispatchEvent(new CustomEvent(\"cancelMultiInput\", {\n bubbles: true,\n cancelable: false\n }));\n });\n }\n\n return btnSection;\n },\n\n /**\n * Crea Input como elemento Dom\n *\n * @param {Object} props - config para Input\n * @param {Object} [dataDay = null] - valores de item y Dia, opcional\n * @param {Object} [daySelected = null] - datos del dia seleccionado\n * @param {Object[]} [selected = []] - array de objetos, de dias seleccionados\n * @return {Object} Elemento Dom del input creado\n */\n createInput(props, dataDay = null, daySelected = null, selected = [], tabSelected) {\n let r = null;\n if (props.ignoreRender == true) return r;\n\n switch (props.type) {\n case \"custom\":\n r = props.render ? props.render({\n props,\n dataDay,\n daySelected,\n selected\n }) : null;\n r.setAttribute(\"input-key\", props.key);\n break;\n\n case \"select\":\n r = this.createInputSelect(props, dataDay, daySelected);\n break;\n\n case \"file\":\n r = this.createInputFile(props, dataDay);\n break;\n\n case \"fileLink\":\n r = this.createFileLink(props, dataDay);\n break;\n\n case \"text\":\n r = this.createText(props, selected);\n break;\n\n case \"title\":\n r = this.createTitle(props);\n break;\n\n case \"number\":\n r = this.createInputNumber(props, dataDay);\n break;\n\n case \"float\":\n r = this.createInputFloat(props, dataDay);\n break;\n\n case \"message\":\n r = this.createInputMessage(props, dataDay);\n break;\n\n case \"textarea\":\n r = this.createInputTextArea(props, dataDay);\n break;\n\n case \"checkbox\":\n r = this.createInputCheckbox(props, dataDay);\n break;\n\n case \"inputList\":\n r = this.createInputList(props, dataDay, daySelected);\n break;\n\n case \"input-box\":\n r = this.createInputBox(props, dataDay);\n break;\n\n case \"list\":\n r = this.createList(props, dataDay);\n break;\n\n case \"data-list\":\n r = this.createDataList(props, dataDay, daySelected, selected, tabSelected);\n break;\n\n case \"button\":\n r = this.createInputButton(props, dataDay);\n break;\n\n case \"buttons-group\":\n r = this.createInputButtonsGroup(props, dataDay);\n break;\n\n case \"time\":\n r = this.createInputTime(props, dataDay);\n break;\n\n case \"input-text\":\n default:\n r = this.createInputText(props, dataDay);\n }\n\n return r;\n },\n\n /**\n * Crea Input con formato Hora, como elemento Dom\n *\n * Usa 2 inputs, hora y minutos\n *\n * el value que interpreta es String HH:MM\n *\n * @param {Object} props - config para Input\n * @param {Object} [dataDay = null] - valores de item y Dia, opcional\n * @return {Object} Elemento Dom del input creado\n */\n createInputTime(props, dataDay) {\n let hhValue = \"\";\n let mmValue = \"\";\n\n if (dataDay && dataDay.values) {\n let value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n\n if (value) {\n value = value.split(\":\");\n hhValue = value[0];\n mmValue = value[1];\n }\n }\n\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <span class=\"text-subtitle d-block\">\n ${props.label || \"\"}\n </span>\n <div class=\"d-flex\">\n <div class=\"time\">\n <input type=\"number\"\n class=\"hour\"\n id=\"test\"\n placeholder=\"00\"\n min=\"0\"\n max=\"99\"\n value=\"${hhValue}\">\n <span class=\"symbol\">:</span>\n <input type=\"number\"\n class=\"minutes\"\n placeholder=\"00\"\n min=\"0\"\n max=\"59\"\n value=\"${mmValue}\">\n </div>\n <span class=\"text-hint\">\n ${props.textHint || \"\"}\n </span>\n </div>\n </div>`);\n let $hhInput = $elem.querySelector(\".hour\");\n let $mmInput = $elem.querySelector(\".minutes\");\n $hhInput.addEventListener(\"input\", e => {\n $hhInput.dispatchEvent(new CustomEvent(\"changeTimeInputHH\", {\n bubbles: true,\n cancelable: false,\n detail: {\n key: props.key,\n value: e.srcElement.value\n }\n }));\n });\n $mmInput.addEventListener(\"input\", e => {\n $mmInput.dispatchEvent(new CustomEvent(\"changeTimeInputMM\", {\n bubbles: true,\n cancelable: false,\n detail: {\n key: props.key,\n value: e.srcElement.value\n }\n }));\n });\n this.addKeyDownInputEvents($hhInput, $elem, props);\n this.addKeyDownInputEvents($mmInput, $elem, props);\n return $elem;\n },\n\n /**\n * Crea Text como elemento Dom\n * Se configura como input, pero no devuelve datos, es un texto\n *\n * @param {Object} props - config para Input\n * @return {Object} Elemento Dom del input creado\n */\n createText(props, selected) {\n let label = props.label;\n\n if (props.formatter) {\n label = props.formatter({\n selected\n });\n }\n\n let $elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.isHidden ? \"hide \" : \"\"} ${props.toLeft ? \"to-left \" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <span class=\"${props.classNames || \"\"}\">\n ${label}\n </span>\n </div>`);\n return $elem;\n },\n\n /**\n * Crea Title como elemento Dom\n * Se configura como input, pero no devuelve datos, es un texto\n *\n * @param {Object} props - config para Input\n * @return {Object} Elemento Dom del input creado\n */\n createTitle(props) {\n let classNames = \"text-title\";\n\n if (props.isSubtitle) {\n classNames = \"text-subtitle\";\n }\n\n return _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <span class=\"${classNames}\">\n ${props.label}\n </span>\n </div>`);\n },\n\n /**\n * Crea Input tipo Numerico como elemento Dom\n *\n * @param {Object} props - config para Input\n * @param {Object} dataDay - valores de item y Dia, opcional\n * @return {Object} Elemento Dom del input creado\n */\n createInputNumber(props, dataDay) {\n let value = \"\";\n\n if (dataDay && dataDay.values) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n }\n\n value = value || \"\";\n let elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.classNames || \"\"} ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <div class=\"input-section-title\">\n <span class=\"text-subtitle\">\n ${props.label}\n </span>\n <span class=\"text-subtitle-2 \">\n ${props.suffix ? \"(\" + props.suffix + \")\" : \"\"}\n </span>\n </div>\n <div class=\"d-flex\">\n <input type=\"number\"\n class=\"nav-input\"\n value=\"${value}\">\n\n <span class=\"text-hint\">\n ${props.textHint || \"\"}\n </span>\n </div>\n </div>`);\n let inputElem = elem.querySelector(\"input\");\n this.addKeyDownInputEvents(inputElem, elem, props);\n return elem;\n },\n\n /**\n * Crea Input tipo FIlepicker como elemento Dom\n *\n * @param {Object} props - config para Input\n * @param {Object} dataDay - valores de item y Dia, opcional\n * @return {Object} Elemento Dom del input creado\n */\n createInputFile(props, dataDay) {\n let value = \"\";\n let fileName = \"\";\n let filePath = \"\";\n\n if (dataDay && dataDay.values) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n fileName = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.fileNameValue);\n filePath = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.filePathValue);\n }\n\n value = value || \"\";\n fileName = fileName || \"\";\n filePath = filePath || \"\";\n let elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.classNames || \"\"} ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n\n <div class=\"input-section-title\">\n <span class=\"text-subtitle\">\n ${props.label}\n </span>\n </div>\n\n <div class=\"nav-input-file\" >\n <button class=\"small-close clear-file-input\">x</button>\n <label >\n <span class=\"nav-input-file-label\">\n ${props.pickerLabel || \"Seleccionar Archivo\"}\n </span>\n <input type=\"file\" value=\"${value}\">\n </label>\n </div>\n\n <div class=\"input-section-link\">\n <a href=\"${filePath}\" target=\"_blank\" >\n ${fileName}\n </a>\n </div>\n\n </div>`);\n let $inputElem = elem.querySelector(\"input\");\n let $clearBtn = elem.querySelector(\".clear-file-input\");\n let $fileInputLabel = elem.querySelector(\".nav-input-file-label\");\n $inputElem.addEventListener(\"change\", evt => {\n let fileName = $inputElem.files[0].name;\n $fileInputLabel.textContent = fileName;\n });\n $clearBtn.addEventListener(\"click\", evt => {\n $inputElem.value = \"\";\n $fileInputLabel.textContent = props.pickerLabel || \"Seleccionar Archivo\";\n evt.stopPropagation();\n });\n return elem;\n },\n\n createFileLink(props, dataDay) {\n let fileName = \"\";\n let filePath = \"\";\n\n if (dataDay && dataDay.values) {\n //value = utils.getVarByPath(dataDay, props.varName);\n fileName = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.fileNameValue);\n filePath = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.filePathValue);\n }\n\n if (fileName == \"\") return null;\n fileName = fileName || \"\";\n filePath = filePath || \"\";\n let elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.classNames || \"\"} ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n\n <div class=\"input-section-title\">\n <span class=\"text-subtitle\">\n ${props.label}\n </span>\n </div>\n\n <div class=\"input-section-link\">\n <a href=\"${filePath}\" target=\"_blank\" >\n ${fileName}\n </a>\n </div>\n\n </div>`);\n return elem;\n },\n\n /**\n * Crea lista de Inputs, con array de valores, como elemento Dom\n *\n * @param {Object} props - config para Input\n * @param {Object} dataDay - valores de item y Dia, opcional\n * @param {Object} [daySelected = null] - datos del dia seleccionado\n * @return {Object} Elemento Dom del input creado\n */\n createInputList(props, dataDay, daySelected = null) {\n let inputList = []; //obtiene inputs default, para crearlos, sin valores\n\n if (daySelected && Array.isArray(daySelected.item.values[props.inputList])) {\n inputList = daySelected.item.values[props.inputList].map(inputRow => {\n //limpia inputList inputs\n inputRow.inputs.map(input => {\n input.value = null;\n return input;\n }); //obtiene valores del dia\n\n if (dataDay && dataDay.values) {\n let inputValues = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.valuesPath); //autorrellena\n\n if (inputValues) {\n inputRow.inputs.forEach(input => {\n let values = inputValues.find(v => v.id == inputRow.id);\n input.value = values ? values[input.varName] : null;\n });\n }\n }\n\n return inputRow;\n });\n }\n\n let str = `<div input-key=\"${props.key || \"\"}\" class=\"input-section-list ${props.isHidden ? \"hide\" : \"\"} \">\n <div class=\"input-section-title\">\n <span class=\"text-title\">\n ${props.label}\n </span> \n </div>`;\n inputList.forEach(inputRow => {\n str += `\n <div class=\"input-section ${props.toRight ? \"to-right\" : \"\"}\" >\n <span class=\"text-subtitle\">\n ${inputRow.label}\n </span>`;\n inputRow.inputs.forEach(input => {\n str += ` \n <div class=\"input-section-col\" >\n <span class=\"text-subtitle \">\n ${input.label}\n </span>\n <input type=\"number\"\n input-id=\"${inputRow.id}\"\n input-label=\"${input.label}\"\n class=\"nav-input small\"\n value=\"${input.value}\">\n </div>`;\n });\n str += `\n </div>`;\n });\n str += `</div>`;\n let elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n let inputsElem = elem.querySelectorAll(\"input\");\n inputsElem.forEach(inputElem => this.addKeyDownInputEvents(inputElem, elem, props));\n return elem;\n },\n\n createInputSelect(props, dataDay, daySelected = null) {\n let value = null;\n let options = props.options;\n\n if (dataDay && dataDay.values) {\n let val = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n value = val ? val.value : null;\n }\n\n let str = `<div input-key=\"${props.key || \"\"}\" class=\"${props.isHidden ? \"hide\" : \"\"}\" >\n <div class=\"input-section \" >\n <span class=\"text-subtitle\">\n ${props.label}\n </span>\n\n <select class=\"input-select\">\n\n <option value=\"\" ${value == null ? \"selected\" : \"\"}>\n ${props.noDataLabel || \"-- sin asignar --\"}\n </option>\n\n `;\n options.forEach(option => {\n str += `\n <option value=\"${option.id}\" ${option.id == value ? \"selected\" : \"\"}>\n ${option.label}\n </option>\n `;\n });\n str += `\n\n </select>\n </div>\n\n </div>`;\n let elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n return elem;\n },\n\n /**\n * Crea Input de texto TextArea como elemento Dom\n *\n * @param {Object} props - config para Input\n * @param {Object} dataDay - valores de item y Dia, opcional\n * @return {Object} Elemento Dom del input creado\n */\n createInputTextArea(props, dataDay) {\n let value = \"\";\n\n if (dataDay && dataDay.values) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n }\n\n let elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <span class=\"text-subtitle d-block\">\n ${props.label}\n </span>\n <textarea class=\"\" value=\"${value}\"></textarea>\n </div>`);\n let inputElem = elem.querySelector(\"textarea\");\n this.addKeyDownInputEvents(inputElem, elem, props);\n return elem;\n },\n\n /**\n * Crea Input de Mensaje como elemento Dom\n * utiliza TextArea\n *\n * @param {Object} props - config para Input\n * @param {Object} dataDay - valores de item y Dia, opcional\n * @return {Object} Elemento Dom del input creado\n */\n createInputMessage(props, dataDay) {\n let value = dataDay ? _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName) : null;\n let elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section to-left msj-input-container ${props.isHidden ? \"hide\" : \"\"} \"\n input-key=\"${props.key || \"\"}\">\n <span class=\"text-subtitle d-block\">\n Mensaje\n </span>\n <textarea class=\"msj\">${value || \"\"}</textarea>\n </div>`);\n let inputElem = elem.querySelector(\"textarea\"); //this.addKeyDownInputEvents(inputElem);\n\n return elem;\n },\n\n /**\n * Crea Input de texto como elemento Dom\n *\n * @param {Object} props - config para Input\n * @param {Object} dataDay - valores de item y Dia, opcional\n * @return {Object} Elemento Dom del input creado\n */\n createInputText(props, dataDay) {\n let value = \"\";\n\n if (dataDay && dataDay.values) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n }\n\n let elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <span class=\"text-subtitle d-block\">\n ${props.label}\n </span>\n <input type=\"text\" class=\"nav-input\" value=\"${value}\">\n </div>`);\n let inputElem = elem.querySelector(\"input\");\n this.addKeyDownInputEvents(inputElem, elem, props);\n return elem;\n },\n\n /**\n * Crea Input Numero Flotante, como elemento Dom\n *\n * @param {Object} props - config para Input\n * @param {Object} dataDay - valores de item y Dia, opcional\n * @return {Object} Elemento Dom del input creado\n */\n createInputFloat(props, dataDay) {\n let value = \"\";\n\n if (dataDay && dataDay.values) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n }\n\n let elem = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <span class=\"text-subtitle d-block\">\n ${props.label}\n </span>\n <input type=\"number\" class=\"nav-input\" value=\"${value}\">\n </div>`);\n let inputElem = elem.querySelector(\"input\");\n this.addKeyDownInputEvents(inputElem, elem, props);\n return elem;\n },\n\n createDataList(props, dataDay, daySelected, selected, tabSelected) {\n let list = [];\n\n if (dataDay && dataDay.values) {\n list = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName) || [];\n }\n\n let searchInput = props.hideSearch ? \"\" : ` <div class=\"search-input-container\">\n <input id=\"\" type=\"text\" name=\"\" class=\"search-input\" placeholder=\"buscar\">\n <button class=\"search-input-clear\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].closeIcon}\n </button>\n </div>`;\n let editBtn = \"\";\n\n if (props.editButton) {\n editBtn = `<button class=\"cap-btn-raised cap-btn-sm edit-btn\" input-key=\"${props.editButton.key}\">\n ${props.editButton.label} \n </button> `;\n }\n\n let str = `\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <div class=\"input-section-title\">\n <span class=\"text-subtitle d-block\">\n ${props.label}\n </span>\n ${editBtn}\t\n </div>\n <div class=\"input-box \" input-key=\"${props.key || \"\"}\">\n ${searchInput}\n </div>\n </div> `;\n let $el = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n let $searchInput = $el.querySelector(\".search-input\");\n let $searchInputClear = $el.querySelector(\".search-input-clear\");\n let $inputBox = $el.querySelector(\".input-box\");\n let $items = list.map((item, j) => {\n let label = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(item, props.varNameLabel) || dataDay.label || \"__\";\n let $elItem = this.createDataListItem({\n label,\n valueText: _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(item, props.varNameValueText) || \"\",\n subText: _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(item, props.varNameSubText) || \"\",\n id: \"list-item-\" + (dataDay.id || j),\n key: \"list-item-\" + (dataDay.id || j),\n tooltip: _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(item, props.varNameTooltip) || label,\n //colorIcon: \"c-red\",\n link: _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(item, props.varNameLink) || null,\n suffix: _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(item, props.varNameSuffix) || \"\" //value: JSON.stringify(utils.getVarByPath(item, props.varNameInput)) || {}\n\n });\n $inputBox.appendChild($elItem);\n });\n\n if ($searchInput) {\n $searchInputClear.addEventListener(\"click\", e => {\n $searchInput.value = \"\";\n $searchInput.dispatchEvent(new Event(\"input\", {\n bubbles: true\n }));\n });\n $searchInput.addEventListener(\"keydown\", e => {\n if (e.key === \"Escape\") {\n $searchInput.value = \"\";\n $searchInput.dispatchEvent(new Event(\"input\", {\n bubbles: true\n }));\n }\n });\n $searchInput.addEventListener(\"input\", e => {\n let $inputs = [];\n $inputs = $el.querySelectorAll(\".mini-input-section\") || [];\n $inputs.forEach($i => {\n let label = $i.getAttribute(\"label\");\n let search = $searchInput.value;\n\n if (label.toLowerCase().includes(search.toLowerCase())) {\n $i.classList.remove(\"hide\");\n } else {\n $i.classList.add(\"hide\");\n }\n });\n });\n }\n\n if (props.editButton.onClick) {\n let button = $el.querySelector(\"button.edit-btn\");\n\n if (button && props.editButton) {\n button.addEventListener(\"click\", e => props.editButton.onClick({\n event: e,\n props,\n dataDay,\n daySelected,\n selected,\n $element: $el,\n tabSelected\n }));\n }\n\n $items.forEach($i => {\n $el.addEventListener(\"click\", e => {\n props.editButton.onClick({\n event: e,\n props,\n dataDay,\n daySelected,\n selected,\n $element: $el,\n tabSelected\n });\n });\n });\n }\n\n return $el;\n },\n\n createDataListItem({\n label = \"\",\n valueText = \"\",\n subText = \"\",\n id = \"\",\n key = \"\",\n tooltip = \"\",\n colorIcon = \"\",\n link = null,\n suffix = null,\n value = \"\"\n }) {\n let tooltipStr = \"\";\n let iconStr = null;\n let linkStr = \"\";\n let str = \"\";\n\n if (tooltip) {\n tooltipStr = `\n <div class=\"mini-input-section--tooltip\">\n ${tooltip}\n </div>`;\n }\n\n if (colorIcon) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(itemFormated.colorIcon)) {\n iconStr = `<div class=\"mini-input-section--icon\" style=\"background:${colorIcon}\"> </div>`;\n } else {\n iconStr = `<div class=\"mini-input-section--icon ${colorIcon}\"> </div>`;\n }\n }\n\n if (link) {\n linkStr = `<a class=\"mini-input-section--link\" target=\"_blank\" href=\"${link}\">${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].linkIcon}</a> `;\n }\n\n str += `\n <div class=\"mini-input-section clickeable ${iconStr ? \"has-icon\" : \"\"} \" \n label=\"${label}\" \n data-id=\"${id}\"\n data-key=\"${key}\"\n data-value=\"${value || \"\"}\"\n >\n <label>\n ${iconStr || \"\"}\n\n <div class=\"mini-input-section--titles\">\n <div class=\"mini-input-section--title truncate\">\n ${label}\n </div>\n <div class=\"mini-input-section--subtitle truncate\">\n ${subText}\n </div>\n </div>\n\n <div class=\"mini-input-section--content\" >\n ${valueText}\n </div>\n <div class=\"mini-input-section--suffix\" >\n ${suffix}\n </div>\n\n ${linkStr}\n\n </label>\n ${tooltipStr}\n </div>`;\n return _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n },\n\n createList(props, dataDay) {\n let tabsContainer = \"\";\n\n if (props.tabs) {\n let tabs = \"\";\n props.tabs.forEach(tab => {\n tabs += `\n <div class=\"input-box-tab\" tab-key=\"${tab.key}\">\n ${tab.name}\n </div>`;\n });\n tabsContainer = `\n <div class=\"input-box-tab-container\">\n ${tabs}\n </div>\n `;\n }\n\n let searchInput = `\n <div class=\"search-input-container\">\n <input id=\"\" type=\"text\" name=\"\" class=\"search-input\" placeholder=\"buscar\">\n <button class=\"search-input-clear\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].closeIcon}\n </button>\n </div>\n `;\n let str = `\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <span class=\"text-subtitle d-block\">\n ${props.label}\n </span>\n\n ${tabsContainer}\n <div class=\"input-box \" input-key=\"${props.key || \"\"}\">\n\n ${searchInput}\n `; //TODO obtener input segun fila\n\n if (props.inputs) {\n props.inputs.forEach(i => {\n if (i.isTitle) {\n let tooltip = \"\";\n let icon = null;\n\n if (i.tooltip) {\n tooltip = `\n <div class=\"mini-input-section--tooltip\">\n ${i.tooltip}\n ${i.suffix ? \"(\" + i.suffix + \")\" : \"\"}\n </div>`;\n }\n\n if (i.colorIcon) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(i.colorIcon)) {\n icon = `<div class=\"mini-input-section--icon\" style=\"background:${i.colorIcon}\"> </div>`;\n } else {\n icon = `<div class=\"mini-input-section--icon ${i.colorIcon}\"> </div>`;\n }\n }\n\n str += `\n <div class=\"mini-input-section is-title ${icon ? \"has-icon\" : \"\"}\" input-tab-key=\"${i.tabKey || \"\"}\" label=\"${i.label}\">\n <label>\n ${icon || \"\"}\n <div class=\"mini-input-section--title truncate\">\n ${i.label}\n </div>\n </label>\n ${tooltip}\n </div>`;\n } else {\n let tooltip = \"\";\n let icon = null;\n let link = \"\";\n\n if (i.tooltip) {\n tooltip = `\n <div class=\"mini-input-section--tooltip\">\n ${i.tooltip}\n </div>`;\n }\n\n if (i.colorIcon) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(i.colorIcon)) {\n icon = `<div class=\"mini-input-section--icon\" style=\"background:${i.colorIcon}\"> </div>`;\n } else {\n icon = `<div class=\"mini-input-section--icon ${i.colorIcon}\"> </div>`;\n }\n }\n\n if (i.link) {\n link = `<a class=\"mini-input-section--link\" target=\"_blank\" href=\"${i.link}\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].linkIcon}\n </a> `;\n }\n\n str += `\n <div class=\"mini-input-section ${icon ? \"has-icon\" : \"\"}\" input-tab-key=\"${i.tabKey || \"\"}\" label=\"${i.label}\">\n <label>\n\n ${icon}\n\n <div class=\"mini-input-section--title truncate\">\n ${i.label}\n </div>\n\n <div class=\"mini-input-section--suffix\" >${i.suffix ? \"(\" + i.suffix + \")\" : \"\"}</div>\n\n ${link}\n\n </label>\n <div class=\"mini-input-section--footer\">\n <span class=\"start\"> start</span>\n <span class=\"end\"> end </span>\n </div>\n ${tooltip}\n </div>`;\n }\n });\n }\n\n str += `\n </div>\n </div> `;\n let $el = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n let $tabs = $el.querySelectorAll(\".input-box-tab[tab-key]\") || [];\n let $searchInput = $el.querySelector(\".search-input\") || null;\n let $searchInputClear = $el.querySelector(\".search-input-clear\") || null;\n $tabs.forEach(t => {\n t.addEventListener(\"click\", e => {\n this.selectInputBoxTab(t, $el);\n $searchInput.value = \"\";\n $searchInput.dispatchEvent(new Event(\"input\", {\n bubbles: true\n }));\n });\n });\n\n if ($searchInputClear) {\n $searchInputClear.addEventListener(\"click\", e => {\n $searchInput.value = \"\";\n $searchInput.dispatchEvent(new Event(\"input\", {\n bubbles: true\n }));\n });\n }\n\n if ($searchInput) {\n $searchInput.addEventListener(\"keydown\", e => {\n if (e.key === \"Escape\") {\n $searchInput.value = \"\";\n $searchInput.dispatchEvent(new Event(\"input\", {\n bubbles: true\n }));\n }\n });\n $searchInput.addEventListener(\"input\", e => {\n let $tabSelected = $el.querySelector(\".input-box-tab[tab-key].active\") || null;\n let $inputs = [];\n\n if ($tabSelected) {\n let tabKey = $tabSelected.getAttribute(\"tab-key\");\n $inputs = $el.querySelectorAll(\".mini-input-section[input-tab-key='\" + tabKey + \"']\") || [];\n } else {\n $inputs = $el.querySelectorAll(\".mini-input-section\") || [];\n }\n\n $inputs.forEach($i => {\n let label = $i.getAttribute(\"label\");\n let search = $searchInput.value;\n\n if (label.toLowerCase().includes(search.toLowerCase())) {\n $i.classList.remove(\"hide\");\n } else {\n $i.classList.add(\"hide\");\n }\n });\n });\n }\n\n this.selectInputBoxTab(_.first($tabs), $el);\n return $el;\n },\n\n /**\n * Crea InputBox, como elemento Dom\n * un InputBox es un contenedor con una lista de inputs\n *\n * @param {Object} props - config para Input\n * @param {Object} dataDay - valores de item y Dia, opcional\n * @return {Object} Elemento Dom del input creado\n */\n createInputBox(props, dataDay) {\n let value = [];\n\n if (dataDay && dataDay.values) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n }\n\n let tabsContainer = \"\";\n\n if (props.tabs) {\n let tabs = \"\";\n props.tabs.forEach(tab => {\n tabs += `\n <div class=\"input-box-tab\" tab-key=\"${tab.key}\">\n ${tab.name}\n </div>`;\n });\n tabsContainer = `\n <div class=\"input-box-tab-container\">\n ${tabs}\n </div>\n `;\n }\n\n let searchInput = `\n <div class=\"search-input-container\">\n <input id=\"\" type=\"text\" name=\"\" class=\"search-input\" placeholder=\"buscar\">\n <button class=\"search-input-clear\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].closeIcon}\n </button>\n </div>\n `;\n let str = `\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <span class=\"text-subtitle d-block\">\n ${props.label}\n </span>\n\n ${tabsContainer}\n\n <div class=\"input-box \" input-key=\"${props.key || \"\"}\">\n\n ${searchInput}\n `;\n\n if (props.inputs) {\n props.inputs.forEach(i => {\n if (i.isTitle) {\n let tooltip = \"\";\n let icon = \"\";\n\n if (i.tooltip) {\n tooltip = `\n <div class=\"mini-input-section--tooltip\">\n ${i.tooltip}\n ${i.suffix ? \"(\" + i.suffix + \")\" : \"\"}\n </div>`;\n }\n\n if (i.colorIcon) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(i.colorIcon)) {\n icon = `<div class=\"mini-input-section--icon\" style=\"background:${i.colorIcon}\"> </div>`;\n } else {\n icon = `<div class=\"mini-input-section--icon ${i.colorIcon}\"> </div>`;\n }\n }\n\n str += `\n <div class=\"mini-input-section is-title\" input-tab-key=\"${i.tabKey || \"\"}\" label=\"${i.label}\">\n <label>\n ${icon}\n <div class=\"mini-input-section--title truncate\">\n ${i.label}\n </div>\n </label>\n ${tooltip}\n </div>`;\n } else {\n let value_found = value ? value.find(val => val.id == i.id) : null;\n let v = value_found || \"\";\n let inputValue = props.varNameInput && v[props.varNameInput] ? v[props.varNameInput] : v.value;\n let tooltip = \"\";\n let icon = \"\";\n let link = \"\";\n\n if (i.tooltip) {\n tooltip = `\n <div class=\"mini-input-section--tooltip\">\n ${i.tooltip}\n </div>`;\n }\n\n if (i.colorIcon) {\n if (_util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].isHexColor(i.colorIcon)) {\n icon = `<div class=\"mini-input-section--icon\" style=\"background:${i.colorIcon}\"> </div>`;\n } else {\n icon = `<div class=\"mini-input-section--icon ${i.colorIcon}\"> </div>`;\n }\n }\n\n if (i.link) {\n link = `<a class=\"mini-input-section--link\" target=\"_blank\" href=\"${i.link}\">\n ${_util_icons__WEBPACK_IMPORTED_MODULE_3__[\"default\"].linkIcon}\n </a> `;\n }\n\n str += `\n <div class=\"mini-input-section ${icon ? \"has-icon\" : \"\"}\" input-tab-key=\"${i.tabKey || \"\"}\" label=\"${i.label}\">\n <label>\n <input type=\"number\"\n class=\"mini-input\"\n input-id=\"${i.id || \"\"}\"\n input-key=\"${i.key || i.label}\"\n value=\"${inputValue || \"\"}\">\n\n ${icon || \"\"}\n\n <div class=\"mini-input-section--title truncate\">\n ${i.label}\n </div>\n\n <div class=\"mini-input-section--suffix\" >${i.suffix ? \"(\" + i.suffix + \")\" : \"\"}</div>\n\n ${link}\n\n </label>\n ${tooltip}\n </div>`;\n }\n });\n }\n\n str += `\n </div>\n </div> `;\n let $el = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(str);\n let $tabs = $el.querySelectorAll(\".input-box-tab[tab-key]\") || [];\n let $inputs = $el.querySelectorAll(\"input.mini-input\") || [];\n let $searchInput = $el.querySelector(\".search-input\") || null;\n let $searchInputClear = $el.querySelector(\".search-input-clear\") || null;\n $tabs.forEach(t => {\n t.addEventListener(\"click\", e => {\n this.selectInputBoxTab(t, $el);\n $searchInput.value = \"\";\n $searchInput.dispatchEvent(new Event(\"input\", {\n bubbles: true\n }));\n });\n });\n\n if ($searchInputClear) {\n $searchInputClear.addEventListener(\"click\", e => {\n $searchInput.value = \"\";\n $searchInput.dispatchEvent(new Event(\"input\", {\n bubbles: true\n }));\n });\n }\n\n if ($searchInput) {\n $searchInput.addEventListener(\"keydown\", e => {\n if (e.key === \"Escape\") {\n $searchInput.value = \"\";\n $searchInput.dispatchEvent(new Event(\"input\", {\n bubbles: true\n }));\n }\n });\n $searchInput.addEventListener(\"input\", e => {\n let $tabSelected = $el.querySelector(\".input-box-tab[tab-key].active\") || null;\n let $inputs = [];\n\n if ($tabSelected) {\n let tabKey = $tabSelected.getAttribute(\"tab-key\");\n $inputs = $el.querySelectorAll(\".mini-input-section[input-tab-key='\" + tabKey + \"']\") || [];\n } else {\n $inputs = $el.querySelectorAll(\".mini-input-section\") || [];\n }\n\n $inputs.forEach($i => {\n let label = $i.getAttribute(\"label\");\n let search = $searchInput.value;\n\n if (label.toLowerCase().includes(search.toLowerCase())) {\n $i.classList.remove(\"hide\");\n } else {\n $i.classList.add(\"hide\");\n }\n });\n });\n }\n\n this.selectInputBoxTab(_.first($tabs), $el);\n $inputs.forEach(i => this.addKeyDownInputEvents(i, $el, props));\n return $el;\n },\n\n selectInputBoxTab($tab, $el) {\n let $tabs = $el.querySelectorAll(\".input-box-tab[tab-key]\") || [];\n let $inputSections = $el.querySelectorAll(\".mini-input-section\") || [];\n $tabs.forEach(t => {\n t.classList.remove(\"active\");\n });\n\n if ($tab) {\n $tab.classList.add(\"active\");\n $inputSections.forEach(i => {\n let key = i.getAttribute(\"input-tab-key\");\n\n if (key == $tab.getAttribute(\"tab-key\")) {\n i.classList.remove(\"hide\");\n } else {\n i.classList.add(\"hide\");\n }\n });\n }\n },\n\n /**\n * Crea Checkbox, como elemento Dom\n *\n * @param {Object} props - config para Input\n * @param {Object} dataDay - valores de item y Dia, opcional\n * @return {Object} Elemento Dom del input creado\n */\n createInputCheckbox(props, dataDay) {\n let value = \"\";\n\n if (dataDay && dataDay.values) {\n value = _util_utils__WEBPACK_IMPORTED_MODULE_1__[\"default\"].getVarByPath(dataDay, props.varName);\n }\n\n let r = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <label>\n <input type=\"checkbox\" name=\"${props.key || \"\"}\" input-key=\"${props.key || \"\"}\" ${value ? \"checked\" : \"\"}>\n ${props.label}\n </label>\n </div>`);\n return r;\n },\n\n createInputButtonsGroup(props) {\n let $container = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <div class=\"buttons-group\"> </div>\n </div>`);\n let $containerButtonGroup = $container.querySelector(\".buttons-group\");\n let $buttons = [];\n $buttons = props.buttons.map(buttonProp => {\n let buttonStr = `\n <button \n name=\"${buttonProp.key || \"\"}\" \n input-key=\"${buttonProp.key || \"\"}\"\n class=\"cap-btn-outline cap-btn-sm ${buttonProp.isSelected ? \"selected\" : \"\"} \">\n ${buttonProp.label}\n </button>`;\n let $button = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(buttonStr);\n $containerButtonGroup.append($button);\n $button.addEventListener(\"click\", e => {\n if (props.isSelectable) {\n $buttons.forEach($b => $b.classList.remove(\"selected\"));\n $button.classList.add(\"selected\");\n }\n\n buttonProp.onClick({\n props,\n event: e,\n buttonsElements: $buttons\n });\n });\n return $button;\n });\n return $container;\n },\n\n createInputButton(props, dataDay) {\n let r = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(`\n <div class=\"input-section ${props.isHidden ? \"hide\" : \"\"} \" input-key=\"${props.key || \"\"}\">\n <button \n name=\"${props.key || \"\"}\"\n input-key=\"${props.key || \"\"}\"\n class=\"cap-btn-outline\">\n ${props.label}\n </button>\n </div>`);\n let button = r.querySelector(\"button\");\n button.addEventListener(\"click\", e => props.onClick({\n props,\n event: e,\n dataDay\n }));\n return r;\n },\n\n addKeyDownInputEvents($input, $inputContainer, props) {\n $input.addEventListener(\"keydown\", function (event) {\n if (event.keyCode === 13) {\n //ENTER\n $input.dispatchEvent(new CustomEvent(\"saveMultiInput\", {\n bubbles: true,\n cancelable: false\n }));\n }\n\n if (event.keyCode === 27) {\n //ESC\n $input.dispatchEvent(new CustomEvent(\"cancelMultiInput\", {\n bubbles: true,\n cancelable: false\n }));\n }\n });\n $input.addEventListener(\"input\", e => {\n if (props.onInput) {\n props.onInput({\n event: e,\n value: e.srcElement.value,\n props,\n $element: $inputContainer\n });\n }\n });\n },\n\n createContextMenu({\n config,\n target,\n $capibaraElem = null,\n evt = null,\n date = null,\n item = null,\n selected = [],\n tabSelected = null,\n left = null,\n top = null,\n name = \"\"\n }) {\n if (config.timeline.contextMenu === undefined || config.timeline.contextMenu.options == undefined) return {\n elem: null,\n isVisible: false\n };\n let className = \"\";\n let style = \"\";\n let strHtml = \"\";\n let leftPosition = null;\n let topPosition = null;\n let isVisible = true;\n let boundRectCapibara = null;\n let gap = 15; //px\n\n if ($capibaraElem) {\n boundRectCapibara = $capibaraElem.getBoundingClientRect();\n }\n\n if (evt && boundRectCapibara) {\n left = evt.clientX;\n top = evt.clientY - boundRectCapibara.top;\n }\n\n if (left) {\n leftPosition = left;\n }\n\n if (top) {\n topPosition = top;\n }\n\n if (leftPosition !== null & topPosition !== null) {\n if (boundRectCapibara) {\n let transformStyle = \"\";\n\n if (topPosition > boundRectCapibara.height * 2 / 6 && topPosition <= boundRectCapibara.height * 4 / 6) {\n transformStyle += `translateY(-50%)`;\n }\n\n if (topPosition > boundRectCapibara.height * 4 / 6) {\n transformStyle += `translateY(-100%)`;\n }\n\n if (leftPosition > boundRectCapibara.width * 4 / 6) {\n transformStyle += `translateX(-100%)`;\n leftPosition -= gap;\n } else {\n leftPosition += gap;\n }\n\n if (transformStyle != \"\") {\n style += ` transform: ${transformStyle};`;\n }\n }\n\n style += `top: ${topPosition}px; left: ${leftPosition}px;`;\n } else {\n className += \"cm-hide\";\n isVisible = false;\n }\n\n strHtml += ` <div class=\"cap-context-menu-container ${className}\">\n <div class=\"cap-context-menu\" style=\"${style}\">\n </div>\n </div>`;\n let $contextMenuContainer = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(strHtml);\n let $contextMenu = $contextMenuContainer.querySelector(\".cap-context-menu\");\n let hasSomeoption = false;\n config.timeline.contextMenu.options.forEach(option => {\n if (option.showIf) {\n let show = option.showIf({\n item,\n date,\n selected,\n name,\n tabSelected\n });\n if (!show) return;\n }\n\n let isEnabled = true;\n let isClickeable = true;\n\n if (option.enableIf) {\n isEnabled = option.enableIf({\n item,\n date,\n selected,\n name,\n tabSelected\n });\n }\n\n let optionClassName = \"\";\n let strIcon = \"\";\n let label = \"\";\n\n if (!isEnabled) {\n optionClassName += \"is-disabled \";\n }\n\n if (option.isDivider) {\n isClickeable = false;\n optionClassName += \"is-divider \";\n }\n\n if (option.label) {\n label = `<span>${option.label}</span>`;\n }\n\n if (option.icon) {\n strIcon = `<div class=\"cap-context-menu_item_icon\">\n <svg viewBox=\"0 0 24 24\">\n <path d=\"${option.icon}\" />\n </svg>\n </div>`;\n }\n\n let optionStrHtml = `\n <div class=\"cap-context-menu_item ${optionClassName}\">\n ${strIcon}\n ${label}\n </div>`;\n let $option = _util_domUtils__WEBPACK_IMPORTED_MODULE_0__[\"default\"].createElementFromHTML(optionStrHtml);\n\n if (isEnabled && isClickeable) {\n $option.addEventListener(\"click\", evtClick => option.onClick({\n config,\n evt: evtClick,\n date,\n item,\n selected,\n tabSelected,\n target\n }));\n } else {\n $option.addEventListener(\"click\", evtClick => {\n evtClick.preventDefault();\n evtClick.stopPropagation();\n });\n }\n\n $contextMenu.append($option);\n hasSomeoption = true;\n });\n return {\n elem: $contextMenuContainer,\n isVisible\n };\n }\n\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvdXRpbC90YWJsZUVsZW1lbnRzLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vQ2FwaWJhcmEvLi9zcmMvdXRpbC90YWJsZUVsZW1lbnRzLmpzPzFkODYiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGRvbSBmcm9tIFwiLi4vdXRpbC9kb21VdGlsc1wiO1xuaW1wb3J0IHV0aWxzIGZyb20gXCIuLi91dGlsL3V0aWxzXCI7XG5pbXBvcnQgZGF0ZVV0aWxzIGZyb20gXCIuLi91dGlsL2RhdGVVdGlsc1wiO1xuaW1wb3J0IGljb25zIGZyb20gXCIuLi91dGlsL2ljb25zXCI7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIENyZWEgZWxlbWVudG8gVGFibGVcbiAgICogQ29udGVuZHLDoSBsb3MgZWxlbWVudG9zIHF1ZSBhcGFyZWNlcmFuIGRlbnRybyBkZSBsYSB0YWJsYSBkZSBwbGFuaWxsYVxuICAgKiBTZSBVc2EgcGFyYSA6XG4gICAqICAgIC0gQWdyZWdhciBiYWNrZ3JvdW5kIGNvbiBwYXRyb24gZXN0aWxvIHRhYmxhXG4gICAqICAgIC0gQWdyZWdhciBkYXlNb3VzZU92ZXIsIGRpdiBxdWUgaW5kaWNhIHBvc2ljaW9uIGRlIG1vdXNlXG4gICAqICAgIC0gQWdyZWdhciBEZXRhaWxEYXksIHBhcmEgZGV0YWxsZXMgZGUgZGF0b3MgZW4gdGFibGFcbiAgICogICAgLSBBZ3JlZ2FyIFNlbGVjdGVkQ29udGFpbmVyLCBwYXJhIGRpYXMgc2VsZWNjaW9uYWRvc1xuICAgKiAgICAtIEFncmVnYXIgRmxvYXRCb3hDb250YWluZXIsIHBhcmEgdmlzdWFsaXphY2lvbiBkZSBkYXRvcyBlbiB0YWJsYVxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gQ29uZmlndXJhY2lvbiBjYXBpYmFyYVxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBjcmVhZG9cbiAgICovXG4gIGNyZWF0ZUFnVGFibGUoY29uZmlnKSB7XG4gICAgbGV0IGUgPSBkb20uY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJjYXBpYmFyYVwiIH0pO1xuICAgIGlmIChjb25maWcudGltZWxpbmUuZGFyaykge1xuICAgICAgZS5jbGFzc0xpc3QuYWRkKFwiZGFyay10aGVtZVwiKTtcbiAgICB9XG4gICAgaWYgKGNvbmZpZy50aW1lbGluZS5oZWFkZXIuZXh0ZW5kLmlzU2hvdykge1xuICAgICAgZS5jbGFzc0xpc3QuYWRkKFwiaGVhZGVyLWV4dGVuZGVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4gZTtcbiAgfSxcblxuICAvKipcbiAgICogUmVjcmVhIEJhY2tncm91bmQsIHF1ZSBlcyBlbCBmb25kbyBncmlkLCBjb21vIHRhYmxhXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgLSBDb25maWd1cmFjaW9uIGNhcGliYXJhXG4gICAqIEBwYXJhbSB7T2JqZWN0fSAkZWxlbSAtIEVsZW1lbnRvIHJlbGFjaW9uYWRvLCBkb25kZSBzZSBjcmUgZWwgYmFja2dyb3VuZFxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBDb3JuZXIgRm9vdGVyXG4gICAqL1xuICByZWRyYXdCYWNrZ3JvdW5kKGNvbmZpZywgJGVsZW0pIHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVCYWNrZ3JvdW5kKGNvbmZpZywgJGVsZW0pO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhIHkgcG9zaWNpb25hIGZvbmRvIGRlIHRhYmxhXG4gICAqIEVzdGUgZm9uZG8gY29udGllbmUgdW4gcGF0cm9uIGRlIENTUyBxdWUgbGUgZGEgbGEgYXBhcmllbmNpYSBkZSB0YWJsYVxuICAgKiBwb3IgbG8gY3VhbCBzZSBkZWJlIHJlcG9zaWNpb25hciBzZWd1biBsYSBmZWNoYSBkZSBpbmljaW8sIHBhcmEgaGFjZXJcbiAgICogY2FsemFyIGxvcyBmaW5lcyBkZSBzZW1hbmFcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHBhcmFtIHtPYmplY3R9IFskZWxlbSA9IG51bGxdIC0gRWxlbWVudG8gYmFja2dyb3VuZCwgc2kgZXMgbnVsbCwgbG8gY3JlYVxuICAgKiBAcmV0dXJuIHtPYmplY3R9IGVsZW1lbnRvIERvbSBCYWNrZ3JvdW5kXG4gICAqL1xuICBjcmVhdGVCYWNrZ3JvdW5kKGNvbmZpZywgJGVsZW0gPSBudWxsKSB7XG4gICAgbGV0IHsgaGVpZ2h0LCB3aWR0aCwgZGF5V2lkdGggfSA9IHV0aWxzLmdldFRhYmxlRGltZW5zaW9ucyhjb25maWcpO1xuXG4gICAgbGV0IHN0YXJ0ID0gbmV3IERhdGUoY29uZmlnLnRpbWVsaW5lLnN0YXJ0KTtcbiAgICBsZXQgZW5kID0gbmV3IERhdGUoY29uZmlnLnRpbWVsaW5lLmVuZCk7XG5cbiAgICBlbmQuc2V0VGltZShlbmQuZ2V0VGltZSgpICsgZGF0ZVV0aWxzLmRheUluTWlsbGlzZWNvbmRzKTsgLy8gYWRkIDI0IGhvdXJzXG5cbiAgICBsZXQgZENvcnJlY3RlZCA9IG5ldyBEYXRlKFxuICAgICAgc3RhcnQudmFsdWVPZigpICsgc3RhcnQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwMDAwXG4gICAgKTtcbiAgICBsZXQgd2Vla0RheSA9IGRDb3JyZWN0ZWQuZ2V0RGF5KCk7XG4gICAgbGV0IGRpZmZXZWVrRGF5cyA9ICh3ZWVrRGF5IC0gMSkgKiBkYXlXaWR0aCAqIC0xO1xuXG4gICAgJGVsZW0gPSAkZWxlbSB8fCBkb20uY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJiYWNrZ3JvdW5kLWdyaWRcIiB9KTtcbiAgICAkZWxlbS5zdHlsZVtcImJhY2tncm91bmQtcG9zaXRpb25cIl0gPVxuICAgICAgZGlmZldlZWtEYXlzICsgXCJweCAwLCAwIDAsIFwiICsgZGlmZldlZWtEYXlzICsgXCJweCAwXCI7XG4gICAgJGVsZW0uc3R5bGUud2lkdGggPSB3aWR0aCArIFwicHhcIjtcbiAgICAkZWxlbS5zdHlsZS5oZWlnaHQgPSBoZWlnaHQgKyAxICsgXCJweFwiO1xuICAgIHJldHVybiAkZWxlbTtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBQbG90IENvbnRhaW5lciBWZXJ0aWNhbFxuICAgKiBMb3MgcGxvdHMgc29uIGVsZW1lbnRvcyBxdWUgYWdyZWdhbiBzZWNjaW9uZXMgZGUgZm9uZG8gZW4gbGEgcGxhbmlsbGFcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gcGxvdFZlcnRpY2FsQ29udGFpbmVyXG4gICAqL1xuICBjcmVhdGVQbG90VmVydGljYWxDb250YWluZXIoY29uZmlnKSB7XG4gICAgbGV0ICRlbGVtID0gZG9tLmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgICAgY2xhc3NOYW1lOiBcInBsb3QtdmVydGljYWwtY29udGFpbmVyXCIsXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMucmVkcmF3UGxvdFZlcnRpY2FsQ29udGFpbmVyKGNvbmZpZywgJGVsZW0pO1xuICB9LFxuXG4gIGNyZWF0ZVBsb3RIb3Jpem9udGFsQ29udGFpbmVyKGNvbmZpZykge1xuICAgIGxldCAkZWxlbSA9IGRvbS5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICAgIGNsYXNzTmFtZTogXCJwbG90LWhvcml6b250YWwtY29udGFpbmVyXCIsXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMucmVkcmF3UGxvdEhvcml6b250YWxDb250YWluZXIoY29uZmlnLCAkZWxlbSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJlY3JlYSBwbG90VmVydGljYWxDb250YWluZXIsIHVzYW5kbyBlbGVtZW50byBleGlzdGVudGVcbiAgICogdXNhIHVuIGVsZW1lbnRvIGV4aXN0ZW50ZSBwYXJhIHVzYXIgbGEgZnVuY2lvbiBwYXJhIHJlZGlidWphciBlbCBlbGVtZW50b1xuICAgKlxuICAgKiBMb3MgUGxvdHMgc2UgaW5zZXJ0YW4gY29tbyBkaXZzLCBjb24gcG9zaWNpb24gZXNwZWNpZmljYWRhLFxuICAgKiBjb24gYW5jaG8gZGUgZGlhXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgLSBDb25maWd1cmFjaW9uIGNhcGliYXJhXG4gICAqIEBwYXJhbSB7T2JqZWN0fSAkZWxlbSAtIEVsZW1lbnRvIERvbSBkb25kZSBjcmVhIHBsb3RWZXJ0aWNhbENvbnRhaW5lclxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBwbG90VmVydGljYWxDb250YWluZXJcbiAgICovXG4gIHJlZHJhd1Bsb3RWZXJ0aWNhbENvbnRhaW5lcihjb25maWcsICRlbGVtKSB7XG4gICAgJGVsZW0uaW5uZXJIVE1MID0gXCJcIjtcbiAgICBpZiAoY29uZmlnLnRpbWVsaW5lLnBsb3RzICYmIGNvbmZpZy50aW1lbGluZS5wbG90cy52ZXJ0aWNhbCkge1xuICAgICAgbGV0IHsgaGVpZ2h0LCBkYXlXaWR0aCB9ID0gdXRpbHMuZ2V0VGFibGVEaW1lbnNpb25zKGNvbmZpZyk7XG5cbiAgICAgIGNvbmZpZy50aW1lbGluZS5wbG90cy52ZXJ0aWNhbC5mb3JFYWNoKChwKSA9PiB7XG4gICAgICAgIGxldCBkaWZmRGF5cyA9IE1hdGguZmxvb3IoXG4gICAgICAgICAgZGF0ZVV0aWxzLmRpZmZEYXlzKGNvbmZpZy50aW1lbGluZS5zdGFydCwgcC5kYXRlKVxuICAgICAgICApO1xuICAgICAgICBsZXQgbGVmdCA9IGRpZmZEYXlzICogZGF5V2lkdGg7XG4gICAgICAgIGxldCBwbG90ID0gZG9tLmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgICAgICAgIGNsYXNzTmFtZXM6IFtcInBsb3QtdmVydGljYWxcIiwgcC5jbGFzc05hbWUgfHwgXCJcIl0sXG4gICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgIFwibWFyZ2luLWxlZnRcIjogbGVmdCArIFwicHhcIixcbiAgICAgICAgICAgIGhlaWdodDogaGVpZ2h0ICsgXCJweFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICAkZWxlbS5hcHBlbmRDaGlsZChwbG90KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gJGVsZW07XG4gIH0sXG5cbiAgcmVkcmF3UGxvdEhvcml6b250YWxDb250YWluZXIoY29uZmlnLCAkZWxlbSkge1xuICAgICRlbGVtLmlubmVySFRNTCA9IFwiXCI7XG4gICAgaWYgKGNvbmZpZy50aW1lbGluZS5wbG90cyAmJiBjb25maWcudGltZWxpbmUucGxvdHMuaG9yaXpvbnRhbCkge1xuICAgICAgbGV0IHsgd2lkdGgsIGl0ZW1IZWlnaHQgfSA9IHV0aWxzLmdldFRhYmxlRGltZW5zaW9ucyhjb25maWcpO1xuICAgICAgY29uZmlnLnRpbWVsaW5lLnBsb3RzLmhvcml6b250YWwuZm9yRWFjaCgocCkgPT4ge1xuICAgICAgICBsZXQgaXRlbSA9IHV0aWxzLmdldEl0ZW1CeUlkKGNvbmZpZywgcC5pZE5vZGUsIHAudHlwZU5vZGUpO1xuICAgICAgICBsZXQgdG9wUG9zaXRpb24gPSB1dGlscy5nZXRQb3NpdGlvbkJ5SXRlbShjb25maWcsIGl0ZW0sIFwicGFyZW50XCIpO1xuICAgICAgICBsZXQgcGxvdCA9IGRvbS5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICAgICAgICBjbGFzc05hbWVzOiBbXCJwbG90LWhvcml6b250YWxcIiwgcC5jbGFzc05hbWUgfHwgXCJcIl0sXG4gICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgIFwibWFyZ2luLXRvcFwiOiB0b3BQb3NpdGlvbiAqIGl0ZW1IZWlnaHQgKyBcInB4XCIsXG4gICAgICAgICAgICB3aWR0aDogd2lkdGggKyBcInB4XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgICRlbGVtLmFwcGVuZENoaWxkKHBsb3QpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiAkZWxlbTtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBDb3JuZXIgSXpxdWllcmRvXG4gICAqIFNlIHVzYSBwYXJhIDpcbiAgICogICAgLSB0aXR1bG9zIHJlbGFjaW9uYWRvcyBjb24gbG9zIGRhdG9zIGRlbCBzaWRlYmFyIGl6cXVpZXJkb1xuICAgKiAgICAtIHRpdHVsb3MgcGFyYSBpbnB1dHMgZGUgaGVhZGVyLCBhYnNvbHV0ZSBhIGxhIGRlcmVjaGFcbiAgICogICAgLSBib3RvbiBwYXJhIG1vc3RyYXIvb2N1bHRhciBzaWRlYmFyIGl6cXVpZXJkb1xuICAgKiAgICAtIHByb21lZGlvc1xuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gQ29uZmlndXJhY2lvbiBjYXBpYmFyYVxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBDb3JuZXJcbiAgICovXG4gIGNyZWF0ZUNvcm5lcihjb25maWcsIHRhYiA9IG51bGwpIHtcbiAgICBsZXQgJGVsZW0gPSBkb20uY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJjb3JuZXJcIiB9KTtcbiAgICByZXR1cm4gdGhpcy5yZWRyYXdDb3JuZXIoJGVsZW0sIGNvbmZpZywgdGFiKTtcbiAgfSxcblxuICByZWRyYXdDb3JuZXIoJGVsZW0sIGNvbmZpZywgdGFiID0gbnVsbCkge1xuICAgIGxldCBsYWJlbHNJbml0aWFsQ29ybmVyID0gY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmluaXRpYWwudmFyc1xuICAgICAgLmZpbHRlcihcbiAgICAgICAgKHYpID0+XG4gICAgICAgICAgdi5vbmx5VGFiID09IHVuZGVmaW5lZCB8fCAodi5vbmx5VGFiICYmIHRhYiAmJiB2Lm9ubHlUYWIgPT0gdGFiLmtleSlcbiAgICAgIClcbiAgICAgIC5tYXAoKGQpID0+IGA8c3BhbiBjbGFzcz1cIml0ZW0tY29sXCI+JHtkLmxhYmVsfTwvc3Bhbj5gKVxuICAgICAgLmpvaW4oXCJcIik7XG5cbiAgICBsZXQgbGFiZWxzRXh0ZW5kQ29ybmVyID0gY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmV4dGVuZC52YXJzXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAodikgPT5cbiAgICAgICAgICB2Lm9ubHlUYWIgPT0gdW5kZWZpbmVkIHx8ICh2Lm9ubHlUYWIgJiYgdGFiICYmIHYub25seVRhYiA9PSB0YWIua2V5KVxuICAgICAgKVxuICAgICAgLm1hcCgoZCkgPT4gYDxzcGFuIGNsYXNzPVwiaXRlbS1jb2xcIj4ke2QubGFiZWx9PC9zcGFuPmApXG4gICAgICAuam9pbihcIlwiKTtcblxuICAgIGxldCBsYWJlbHNIZWFkZXJFeHRlbmQgPSBjb25maWcudGltZWxpbmUuaGVhZGVyLmV4dGVuZC5kYXRhXG4gICAgICAubWFwKChkKSA9PiB7XG4gICAgICAgIGlmIChkLmlzSGlkZGVuKSByZXR1cm4gXCJcIjtcblxuICAgICAgICBsZXQgYXZnID0gXCJcIjtcbiAgICAgICAgbGV0IHRvb2x0aXAgPSBcIlwiO1xuICAgICAgICBsZXQgY2xhc3NOYW1lID0gXCJcIjtcbiAgICAgICAgbGV0IGlzQWNjZW50ID0gZC5pc0FjY2VudDtcblxuICAgICAgICBpZiAoZC5hdmVyYWdlKSB7XG4gICAgICAgICAgYXZnID0gYCA8c3BhbiBjbGFzcz1cImF2ZXJhZ2UgXCI+ICggPHNwYW4+IDxzcGFuIGNsYXNzPVwic3ltYm9sXCI+eMyEPC9zcGFuPiAke2QuYXZlcmFnZX0gPC9zcGFuPikgIDwvc3Bhbj4gICBgO1xuXG4gICAgICAgICAgdG9vbHRpcCA9IGBjYXAtdG9vbHRpcD1cIlByb21lZGlvICR7ZC5sYWJlbH0gOiAke2QuYXZlcmFnZX0gJHtcbiAgICAgICAgICAgIGQuc3VmZml4IHx8IFwiXCJcbiAgICAgICAgICB9XCJgO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGQuY29sb3IpIHtcbiAgICAgICAgICBpZiAoaXNBY2NlbnQpIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZSA9IGQuY29sb3IgPyBcImMtXCIgKyBkLmNvbG9yICsgXCItLWJhY2tncm91bmRcIiA6IFwiXCI7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZSA9IGQuY29sb3IgPyBcImMtXCIgKyBkLmNvbG9yICsgXCItLXRleHQgXCIgOiBcIlwiO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBgPGRpdiBjbGFzcz1cImlucHV0LXRpdGxlLWNvbnRhaW5lciAke1xuICAgICAgICAgIGlzQWNjZW50ID8gXCJpbnB1dC10aXRsZS0tYWNjZW50XCIgOiBcIlwiXG4gICAgICAgIH0gJHtkLmlzUGVyc2lzdGVudCA/IFwicGVyc2lzdGVudFwiIDogXCJcIn1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAke3Rvb2x0aXB9IGNsYXNzPVwiaW5wdXQtdGl0bGUgJHtjbGFzc05hbWV9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2F2Z31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7ZC5sYWJlbH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgIH0pXG4gICAgICAuam9pbihcIlwiKTtcblxuICAgIGxldCB0b2dnbGVTaWRlYmFyQnRuU3RyaW5nID0gYFxuICAgICAgICAgIDxidXR0b24gdG9nZ2xlLXNpZGViYXIgY2xhc3M9XCJjYXAtYnRuLWljb24gY2FwLWJ0bi1pY29uLXJhaXNlZCBjYXAtYnRuLXRvZ2dsZS1zaWRlYmFyIFwiPlxuICAgICAgICAgICR7aWNvbnMuY2hldnJvblJpZ2h0fVxuICAgICAgICAgIDwvYnV0dG9uPiBgO1xuXG4gICAgaWYgKGNvbmZpZy50aW1lbGluZS5uYXYubGVmdC5oaWRlVG9nZ2xlU2lkZWJhckJ1dHRvbikge1xuICAgICAgdG9nZ2xlU2lkZWJhckJ0blN0cmluZyA9IFwiXCI7XG4gICAgfVxuXG4gICAgbGV0IHRlbXBsYXRlID0gYDxkaXY+XG5cbiAgICAgICAgICAke3RvZ2dsZVNpZGViYXJCdG5TdHJpbmd9XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb3JuZXItdGl0bGVcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImJvdHRvbS10ZXh0XCI+XG4gICAgICAgICAgICAke2NvbmZpZy50aW1lbGluZS5jb3JuZXIubGVmdC5sYWJlbH1cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJpbml0aWFsLWNvcm5lclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbml0aWFsLWNvcm5lci10aXRsZVwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJib3R0b20tY29udGFpbmVyIGhpZGVcIj5cbiAgICAgICAgICAgICAgJHtjb25maWcudGltZWxpbmUuY29ybmVyLmluaXRpYWwubGFiZWx9XG4gICAgICAgICAgICA8L3NwYW4+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJib3R0b20tY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICR7bGFiZWxzSW5pdGlhbENvcm5lcn1cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImV4dGVuZC1jb3JuZXJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZXgtY29ybmVyLXRpdGxlXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJvdHRvbS1jb250YWluZXIgaGlkZVwiPlxuICAgICAgICAgICAgICAke2NvbmZpZy50aW1lbGluZS5jb3JuZXIuZXh0ZW5kLmxhYmVsfVxuICAgICAgICAgICAgPC9zcGFuPlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYm90dG9tLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAke2xhYmVsc0V4dGVuZENvcm5lcn1cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNhcC1idG4tbmF2LWNvcm5lclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC10aXRsZXNcIj5cbiAgICAgICAgICAgICAgJHtsYWJlbHNIZWFkZXJFeHRlbmR9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJwcm9ncmVzcy1iYXIgcHJvZ3Jlc3MtYmFyLWxlZnQgaGlkZS1wcm9ncmVzc1wiPjwvZGl2PlxuXG4gICAgICA8L2Rpdj5gO1xuXG4gICAgbGV0IHIgPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKHRlbXBsYXRlKTtcblxuICAgICRlbGVtLmlubmVySFRNTCA9IFwiXCI7XG4gICAgJGVsZW0uYXBwZW5kKHIpO1xuXG4gICAgbGV0IHRvZ2dsZVNpZGViYXIgPSAkZWxlbS5xdWVyeVNlbGVjdG9yKFwiW3RvZ2dsZS1zaWRlYmFyXVwiKTtcbiAgICBpZiAodG9nZ2xlU2lkZWJhcikge1xuICAgICAgdG9nZ2xlU2lkZWJhci5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgci5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgIG5ldyBDdXN0b21FdmVudChcInRvZ2dsZVNpZGViYXJcIiwge1xuICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgIGNhbmNlbGFibGU6IGZhbHNlLFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gJGVsZW07XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgQ29ybmVyIERlcmVjaG9cbiAgICogU2UgdXNhIHBhcmEgOlxuICAgKiAgICAtIHRpdHVsb3MgcmVsYWNpb25hZG9zIGNvbiBsb3MgZGF0b3MgZGVsIHNpZGViYXIgRGVyZWNob1xuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gQ29uZmlndXJhY2lvbiBjYXBpYmFyYVxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBjb3JuZXJcbiAgICovXG4gIGNyZWF0ZUNvcm5lclJpZ2h0KGNvbmZpZywgdGFiID0gbnVsbCkge1xuICAgIGxldCAkZWxlbSA9IGRvbS5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsgY2xhc3NOYW1lczogW1wiY29ybmVyXCIsIFwicmlnaHRcIl0gfSk7XG4gICAgcmV0dXJuIHRoaXMucmVkcmF3Q29ybmVyUmlnaHQoJGVsZW0sIGNvbmZpZywgdGFiKTtcbiAgfSxcblxuICByZWRyYXdDb3JuZXJSaWdodCgkZWwsIGNvbmZpZywgdGFiID0gbnVsbCkge1xuICAgIGxldCBsYWJlbCA9IFwiXCI7XG5cbiAgICBpZiAoY29uZmlnLnRpbWVsaW5lLmNvcm5lci5yaWdodC5sYWJlbCkge1xuICAgICAgYCA8c3Bhbj5cbiAgICAgICAgICAgICR7Y29uZmlnLnRpbWVsaW5lLmNvcm5lci5yaWdodC5sYWJlbH1cbiAgICAgICAgICA8L3NwYW4+YDtcbiAgICB9XG5cbiAgICBsZXQgc3RyID0gYFxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29ybmVyLXRpdGxlXCI+XG4gICAgICAgICR7bGFiZWx9XG4gICAgICAgIDxkaXYgY2xhc3M9XCJidG4tY29udGFpbmVyXCI+PC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwicHJvZ3Jlc3MtYmFyIHByb2dyZXNzLWJhci1yaWdodCBoaWRlLXByb2dyZXNzXCI+PC9kaXY+XG4gICAgYDtcbiAgICAkZWwuaW5uZXJIVE1MID0gc3RyLnRyaW0oKTtcbiAgICBsZXQgJGJ0bkNvbnRhaW5lciA9ICRlbC5xdWVyeVNlbGVjdG9yKFwiLmJ0bi1jb250YWluZXJcIik7XG5cbiAgICBpZiAoY29uZmlnLnRpbWVsaW5lLmNvcm5lci5yaWdodC5idXR0b25zKSB7XG4gICAgICBjb25maWcudGltZWxpbmUuY29ybmVyLnJpZ2h0LmJ1dHRvbnMuZm9yRWFjaCgoYnRuKSA9PiB7XG4gICAgICAgIGxldCBpc0VuYWJsZWQgPSBidG4uZ2V0SXNFbmFibGVkID8gYnRuLmdldElzRW5hYmxlZCgpIDogdHJ1ZTtcbiAgICAgICAgaWYgKGlzRW5hYmxlZCkge1xuICAgICAgICAgIGxldCAkYnRuID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChgXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiY29ybmVyLWJ0biBjYXAtYnRuLXJhaXNlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAke2J0bi5sYWJlbCB8fCBcIlwifVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+IGApO1xuXG4gICAgICAgICAgaWYgKGJ0bi5vbkNsaWNrKSB7XG4gICAgICAgICAgICAkYnRuLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBidG4ub25DbGljayk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgJGJ0bkNvbnRhaW5lci5hcHBlbmRDaGlsZCgkYnRuKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChjb25maWcudGltZWxpbmUuY29ybmVyLnJpZ2h0LmlucHV0cykge1xuICAgICAgY29uZmlnLnRpbWVsaW5lLmNvcm5lci5yaWdodC5pbnB1dHMuZm9yRWFjaCgoaW5wdXQpID0+IHtcbiAgICAgICAgbGV0ICRpbnB1dCA9IHRoaXMuY3JlYXRlQ29ybmVyUmlnaHRJbnB1dCh7IGlucHV0Q29uZmlnOiBpbnB1dCB9KTtcbiAgICAgICAgJGJ0bkNvbnRhaW5lci5hcHBlbmRDaGlsZCgkYnRuKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gJGVsO1xuICB9LFxuXG4gIGNyZWF0ZUNvcm5lclJpZ2h0SW5wdXQoeyBpbnB1dENvbmZpZywgZGF0YURheSA9IG51bGwsIGRheVNlbGVjdGVkID0gbnVsbCB9KSB7XG4gICAgbGV0IHIgPSBudWxsO1xuICAgIHN3aXRjaCAoaW5wdXRDb25maWcudHlwZSkge1xuICAgICAgY2FzZSBcImF1dG9jb21wbGV0ZS1jcnVkXCI6XG4gICAgICAgIHIgPSB0aGlzLmNyZWF0ZUNvcm5lclJpZ2h0SW5wdXRBdXRvY29tcGxldGVDcnVkKHtcbiAgICAgICAgICBpbnB1dENvbmZpZyxcbiAgICAgICAgICBkYXRhRGF5LFxuICAgICAgICAgIGRheVNlbGVjdGVkLFxuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiByO1xuICB9LFxuXG4gIGNyZWF0ZUNvcm5lclJpZ2h0SW5wdXRBdXRvY29tcGxldGVDcnVkKHtcbiAgICBpbnB1dENvbmZpZyxcbiAgICBkYXRhRGF5LFxuICAgIGRheVNlbGVjdGVkLFxuICB9KSB7XG4gICAgbGV0IGVsZW0gPSBcInRlc3RcIjtcbiAgICByZXR1cm4gZWxlbTtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBIZWFkZXIgVG9wXG4gICAqIFNlIHVzYSBwYXJhIDpcbiAgICogICAgLSBNYW5lam8gZGUgdGFic1xuICAgKiAgICAtIEJvdG9uZXMgZGUgbmF2ZWdhY2nDs24geSBzZWxlY2Npw7NuIGRlIGZlY2hhXG4gICAqICAgIC0gQm90b24gdG9nZ2xlIERhcmsgbW9kZVxuICAgKiAgICAtIEJvdG9uIHRvZ2dsZSBIZWFkZXIgZXh0ZW5kZWRcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb21cbiAgICovXG5cbiAgY3JlYXRlSGVhZGVyVG9wKGNvbmZpZywgdGFiU2VsZWN0ZWQgPSBudWxsKSB7XG4gICAgcmV0dXJuIHRoaXMucmVkcmF3SGVhZGVyVG9wKGNvbmZpZywgdGFiU2VsZWN0ZWQsIGRvbS5jcmVhdGVFbGVtZW50KFwiZGl2XCIpKTtcbiAgfSxcblxuICByZWRyYXdIZWFkZXJUb3AoY29uZmlnLCB0YWJTZWxlY3RlZCA9IG51bGwsICRlbGVtKSB7XG4gICAgbGV0IHN0ciA9IGBcbiAgICAgIDxkaXYgY2xhc3M9XCJoZWFkZXItdG9wXCI+YDtcblxuICAgIGlmIChjb25maWcudGltZWxpbmUudGFicykge1xuICAgICAgbGV0IHNob3dUYWJzID0gdHJ1ZTtcblxuICAgICAgaWYgKGNvbmZpZy50aW1lbGluZS50YWJzLmZpbHRlcigodCkgPT4gIXQuaXNIaWRkZW4pLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgIHNob3dUYWJzID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmIChzaG93VGFicykge1xuICAgICAgICBzdHIgKz0gYCA8ZGl2IGNsYXNzPVwidGFiLXNlbGVjdC1jb250YWluZXIgYy1kLWRlc2t0b3Atbm9uZSBjLWQtbW9iaWxlLWZsZXhcIj5cbiAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJ0YWJzLXNlbGVjdFwiID5gO1xuXG4gICAgICAgIGNvbmZpZy50aW1lbGluZS50YWJzLmZvckVhY2goKHRhYikgPT4ge1xuICAgICAgICAgIGlmICghdGFiLmlzSGlkZGVuKSB7XG4gICAgICAgICAgICBzdHIgKz0gYCA8b3B0aW9uICR7XG4gICAgICAgICAgICAgIHRhYiA9PSB0YWJTZWxlY3RlZCA/ICdzZWxlY3RlZD1cInNlbGVjdGVkXCInIDogXCJcIlxuICAgICAgICAgICAgfSB2YWx1ZT1cIiR7dGFiLmlkfVwiPiAke3RhYi5sYWJlbH0gPC9vcHRpb24+YDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHN0ciArPSBgPC9zZWxlY3Q+IDwvZGl2PmA7XG5cbiAgICAgICAgc3RyICs9IGAgPGRpdiBjbGFzcz1cInRhYnMtY29udGFpbmVyIGMtZC1kZXNrdG9wLWZsZXggYy1kLW1vYmlsZS1ub25lXCI+YDtcblxuICAgICAgICBjb25maWcudGltZWxpbmUudGFicy5mb3JFYWNoKCh0YWIpID0+IHtcbiAgICAgICAgICBpZiAoIXRhYi5pc0hpZGRlbikge1xuICAgICAgICAgICAgc3RyICs9IGAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0YWIgJHt0YWIuZGlzYWJsZWQgPyBcImRpc2FibGVkXCIgOiBcIlwifSAgJHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGFiID09IHRhYlNlbGVjdGVkID8gXCJhY3RpdmVcIiA6IFwiXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gICR7dGFiLmNvbG9yfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1cIiR7dGFiLmNvbG9yfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC1rZXk9XCIke3RhYi5pZH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgJHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGFiLnRvb2x0aXAgPyAnY2FwLXRvb2x0aXA9XCInICsgdGFiLnRvb2x0aXAgKyAnXCInIDogXCJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgfSA+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPiR7dGFiLmxhYmVsfTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgJHt0YWIuaWNvbiB8fCBcIlwifVxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICBgO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgc3RyICs9IGA8L2Rpdj5gO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0YWJTZWxlY3RlZCkge1xuICAgICAgaWYgKHRhYlNlbGVjdGVkLmxlZ2VuZHMpIHtcbiAgICAgICAgc3RyICs9IGAgXG4gICAgICAgIDxidXR0b24gdG9nZ2xlLWxlZ2VuZHMgY2xhc3M9XCJjYXAtYnRuLWljb24gY2FwLWJ0bi1pY29uLXJhaXNlZCBcIj5cbiAgICAgICAgICAke2ljb25zLnRvZ2dsZUxlZ2VuZHN9XG4gICAgICAgIDwvYnV0dG9uPiBcblxuICAgICAgICA8ZGl2IGNsYXNzPVwibGVnZW5kcy1jb250YWluZXIgZm9yY2UtbW9iaWxlLXN0eWxlIGhpZGVcIj4gYDtcblxuICAgICAgICB0YWJTZWxlY3RlZC5sZWdlbmRzLmZvckVhY2goKGxlZ2VuZCkgPT4ge1xuICAgICAgICAgIGxldCBjb2xvckNsYXNzID0gXCJcIjtcbiAgICAgICAgICBsZXQgY29sb3JCZyA9IFwiXCI7XG5cbiAgICAgICAgICBpZiAodXRpbHMuaXNIZXhDb2xvcihsZWdlbmQuY29sb3IpKSB7XG4gICAgICAgICAgICBjb2xvckJnID0gXCJiYWNrZ3JvdW5kOlwiICsgbGVnZW5kLmNvbG9yO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb2xvckNsYXNzID0gbGVnZW5kLmNvbG9yID8gbGVnZW5kLmNvbG9yICsgXCItLWJhY2tncm91bmRcIiA6IFwiXCI7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3RyICs9IGAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibGVnZW5kICR7bGVnZW5kLmFjdGl2ZSA/IFwiYWN0aXZlXCIgOiBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgaW5wdXQta2V5PVwiJHtsZWdlbmQua2V5fVwiXG4gICAgICAgICAgICAgICAgICAgICAgJHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZC50b29sdGlwID8gYGNhcC10b29sdGlwPVwiJHtsZWdlbmQudG9vbHRpcH1cImAgOiBcIlwiXG4gICAgICAgICAgICAgICAgICAgICAgfSA+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaWNvbi1sZWdlbmQgJHtjb2xvckNsYXNzfSAke1xuICAgICAgICAgICAgICAgICAgICBsZWdlbmQuc2hhcGVcbiAgICAgICAgICAgICAgICAgIH1cIiBzdHlsZT1cIiR7Y29sb3JCZ31cIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPiR7bGVnZW5kLmxhYmVsfTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICB9KTtcblxuICAgICAgICBzdHIgKz0gYDwvZGl2PmA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc3RyICs9IGBcblxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcGFjZXJcIj48L2Rpdj5cblxuXG5cbiAgICAgICAgICA8YnV0dG9uIGNhcC1idG4tcHJldiBjbGFzcz1cImNhcC1idG4taWNvbiBjYXAtYnRuLWljb24tcmFpc2VkXCI+XG4gICAgICAgICAgICAgJHtpY29ucy5hcnJvd0xlZnR9XG4gICAgICAgICAgICAgJHtpY29ucy5sb2FkaW5nSWNvbn0gXG4gICAgICAgICAgPC9idXR0b24+XG5cblxuICAgICAgICAgIDxidXR0b24gY2FwLWJ0bi1jYWxlbmRhciBjbGFzcz1cImNhcC1idG4taWNvbiBjYXAtYnRuLWljb24tcmFpc2VkXCI+XG4gICAgICAgICAgICAke2ljb25zLmNhbGVuZGFyfVxuICAgICAgICAgICAgJHtpY29ucy5sb2FkaW5nSWNvbn1cbiAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICAgIDxidXR0b24gY2FwLWJ0bi1uZXh0IGNsYXNzPVwiY2FwLWJ0bi1pY29uIGNhcC1idG4taWNvbi1yYWlzZWRcIj5cbiAgICAgICAgICAgICR7aWNvbnMuYXJyb3dSaWdodH1cbiAgICAgICAgICAgICR7aWNvbnMubG9hZGluZ0ljb259XG4gICAgICAgICAgPC9idXR0b24+XG5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic3BhY2VyXCI+PC9kaXY+XG5cbiAgICAgICAgICA8YnV0dG9uIHRvZ2dsZS1kYXJrIGNsYXNzPVwiY2FwLWJ0bi1pY29uIGNhcC1idG4taGVhZGVyIGMtZC1tb2JpbGUtbm9uZSAke1xuICAgICAgICAgICAgY29uZmlnLnRpbWVsaW5lLndpdGhEYXJrVG9nZ2xlID09IGZhbHNlID8gXCJoaWRlXCIgOiBcIlwiXG4gICAgICAgICAgfVwiPlxuICAgICAgICAgICAgJHtpY29ucy5kYXJrfVxuICAgICAgICAgICAgJHtpY29ucy5saWdodH1cbiAgICAgICAgICA8L2J1dHRvbj5gO1xuXG4gICAgaWYgKGNvbmZpZy50aW1lbGluZS5oZWFkZXIuZXh0ZW5kLmVuYWJsZWQgIT09IGZhbHNlKSB7XG4gICAgICBzdHIgKz0gYDxidXR0b24gdG9nZ2xlLWhlYWRlciBjbGFzcz1cImNhcC1idG4taWNvbiBjYXAtYnRuLWljb24tcmFpc2VkXCI+XG4gICAgICAgICAgJHtpY29ucy5jaGV2cm9uRG93bn1cbiAgICAgICAgICA8L2J1dHRvbj5gO1xuICAgIH1cblxuICAgIHN0ciArPSBgIDxkaXYgY2xhc3M9XCJidXR0b24tcmlnaHQtY29udGFpbmVyXCI+PC9kaXY+XG4gICAgICAgIDwvZGl2PmA7XG4gICAgLypcbiAgICAgICAgICBgXG4gICAgICAgICAgPGJ1dHRvbiB0b2dnbGUtc2lkZWJhci1yaWdodCBjbGFzcz1cImNhcC1idG4taWNvbiBjYXAtYnRuLWljb24tcmFpc2VkXCI+XG4gICAgICAgICAgICA8c3Bhbj5cbiAgICAgICAgICAgICAgPHN2ZyBzdHlsZT1cIndpZHRoOjI0cHg7aGVpZ2h0OjI0cHhcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCI+XG4gICAgICAgICAgICAgICAgICA8cGF0aCBmaWxsPVwiY3VycmVudENvbG9yXCIgZD1cIk0xNS40MSwxNi41OEwxMC44MywxMkwxNS40MSw3LjQxTDE0LDZMOCwxMkwxNCwxOEwxNS40MSwxNi41OFpcIiAvPlxuICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgPC9kaXY+XG4gICAgYDtcbiAgICAqL1xuXG4gICAgbGV0ICRyID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChzdHIpO1xuICAgICRlbGVtLnJlcGxhY2VXaXRoKCRyKTtcblxuICAgIGlmIChjb25maWcudGltZWxpbmUuaGVhZGVyLnJpZ2h0QnV0dG9ucykge1xuICAgICAgbGV0ICRidXR0b25Db250YWluZXIgPSAkci5xdWVyeVNlbGVjdG9yKFwiLmJ1dHRvbi1yaWdodC1jb250YWluZXJcIik7XG4gICAgICBjb25maWcudGltZWxpbmUuaGVhZGVyLnJpZ2h0QnV0dG9ucy5mb3JFYWNoKChidXR0b24pID0+IHtcbiAgICAgICAgbGV0IGhhc0JhZGdlID0gZmFsc2U7XG4gICAgICAgIGlmIChidXR0b24uaGFzQmFkZ2UpIHtcbiAgICAgICAgICBoYXNCYWRnZSA9IGJ1dHRvbi5oYXNCYWRnZSgpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBzdHIgPSBgPGJ1dHRvbiBjbGFzcz1cImNhcC1idG4taWNvbiBjYXAtYnRuLWljb24tcmFpc2VkICR7XG4gICAgICAgICAgaGFzQmFkZ2UgPyBcImNhcC1idG4taGFzLWJhZGdlXCIgOiBcIlwiXG4gICAgICAgIH1cIj5cbiAgICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgICA8c3ZnIHN0eWxlPVwid2lkdGg6MjRweDtoZWlnaHQ6MjRweFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIj5cbiAgICAgICAgICAgICAgICAgIDxwYXRoIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBkPVwiJHtidXR0b24uaWNvbn1cIiAvPlxuICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8L2J1dHRvbj5gO1xuICAgICAgICBsZXQgJGJ1dHRvbiA9IGRvbS5jcmVhdGVFbGVtZW50RnJvbUhUTUwoc3RyKTtcbiAgICAgICAgJGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGV2dCkgPT4gYnV0dG9uLm9uQ2xpY2soeyBldnQgfSkpO1xuICAgICAgICAkYnV0dG9uQ29udGFpbmVyLmFwcGVuZCgkYnV0dG9uKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGxldCAkdG9nZ2xlRGFyayA9ICRyLnF1ZXJ5U2VsZWN0b3IoXCJbdG9nZ2xlLWRhcmtdXCIpO1xuICAgIGlmICgkdG9nZ2xlRGFyaykge1xuICAgICAgJHRvZ2dsZURhcmsuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgICRyLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwidG9nZ2xlRGFya1wiLCB7XG4gICAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGxldCAkYnRuQ2FsZW5kYXIgPSAkci5xdWVyeVNlbGVjdG9yKFwiW2NhcC1idG4tY2FsZW5kYXJdXCIpO1xuICAgIGlmICgkYnRuQ2FsZW5kYXIpIHtcbiAgICAgICRidG5DYWxlbmRhci5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgbGV0IHggPSBlLng7XG4gICAgICAgIGxldCB5ID0gZS55O1xuICAgICAgICAkci5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgIG5ldyBDdXN0b21FdmVudChcImNsaWNrQ2FsZW5kYXJJY29uXCIsIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGRldGFpbDogeyB4LCB5IH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGxldCAkYnRuVG9nZ2xlSGVhZGVyID0gJHIucXVlcnlTZWxlY3RvcihcIlt0b2dnbGUtaGVhZGVyXVwiKTtcbiAgICBpZiAoJGJ0blRvZ2dsZUhlYWRlcikge1xuICAgICAgJGJ0blRvZ2dsZUhlYWRlci5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgJHIuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoXCJ0b2dnbGVIZWFkZXJcIiwge1xuICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgIGNhbmNlbGFibGU6IGZhbHNlLFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKlxuICAgICRyLnF1ZXJ5U2VsZWN0b3IoXCJbdG9nZ2xlLXNpZGViYXItcmlnaHRdXCIpLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBlID0+IHtcbiAgICAgICRyLmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KFwidG9nZ2xlU2lkZWJhclJpZ2h0XCIsIHtcbiAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICB9KSk7XG4gICAgfSk7XG4gICAgKi9cblxuICAgICRyLnF1ZXJ5U2VsZWN0b3IoXCJbY2FwLWJ0bi1wcmV2XVwiKS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICRyLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgIG5ldyBDdXN0b21FdmVudChcImhlYWRlclByZXZcIiwge1xuICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICBvcmlnaW5hbEV2dDogZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgICRyLnF1ZXJ5U2VsZWN0b3IoXCJbY2FwLWJ0bi1jYWxlbmRhcl1cIikuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAkci5kaXNwYXRjaEV2ZW50KFxuICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoXCJoZWFkZXJDYWxlbmRhclwiLCB7XG4gICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIG9yaWdpbmFsRXZ0OiBlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgJHIucXVlcnlTZWxlY3RvcihcIltjYXAtYnRuLW5leHRdXCIpLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZSkgPT4ge1xuICAgICAgJHIuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwiaGVhZGVyTmV4dFwiLCB7XG4gICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIG9yaWdpbmFsRXZ0OiBlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgbGV0ICR0b2dnbGVMZWdlbmRzQnRuID0gJHIucXVlcnlTZWxlY3RvcihcIlt0b2dnbGUtbGVnZW5kc11cIik7XG4gICAgaWYgKCR0b2dnbGVMZWdlbmRzQnRuKSB7XG4gICAgICAkdG9nZ2xlTGVnZW5kc0J0bi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgbGV0ICRsZWdlbmRDb250YWluZXIgPSAkci5xdWVyeVNlbGVjdG9yKFwiLmxlZ2VuZHMtY29udGFpbmVyXCIpO1xuICAgICAgICBpZiAoJGxlZ2VuZENvbnRhaW5lcikge1xuICAgICAgICAgICRsZWdlbmRDb250YWluZXIuY2xhc3NMaXN0LnRvZ2dsZShcImhpZGVcIik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgICRyLnF1ZXJ5U2VsZWN0b3JBbGwoXCIubGVnZW5kXCIpLmZvckVhY2goKCRsZWdlbmQpID0+IHtcbiAgICAgICRsZWdlbmQuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgIGxldCBrZXkgPSBlLmN1cnJlbnRUYXJnZXQuZ2V0QXR0cmlidXRlKFwiaW5wdXQta2V5XCIpO1xuXG4gICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICBsZXQgbGVnZW5kU2VsZWN0ZWQgPSB0YWJTZWxlY3RlZC5sZWdlbmRzLmZpbmQoXG4gICAgICAgICAgICAodGFiKSA9PiB0YWIua2V5ID09PSBrZXlcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChsZWdlbmRTZWxlY3RlZCkge1xuICAgICAgICAgICAgJHIuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwic2VsZWN0TGVnZW5kSGVhZGVyXCIsIHtcbiAgICAgICAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNhbmNlbGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICAgICAgbGVnZW5kOiBsZWdlbmRTZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICRsZWdlbmQsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgICRyLnF1ZXJ5U2VsZWN0b3JBbGwoXCIudGFiOm5vdCguZGlzYWJsZWQpXCIpLmZvckVhY2goKCR0YWIpID0+IHtcbiAgICAgICR0YWIuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgIGxldCBrZXkgPSBlLmN1cnJlbnRUYXJnZXQuZ2V0QXR0cmlidXRlKFwiaW5wdXQta2V5XCIpO1xuXG4gICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICBsZXQgdGFiU2VsZWN0ZWQgPSBjb25maWcudGltZWxpbmUudGFicy5maW5kKCh0YWIpID0+IHRhYi5pZCA9PSBrZXkpO1xuICAgICAgICAgIGlmICh0YWJTZWxlY3RlZCkge1xuICAgICAgICAgICAgJHIuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwic2VsZWN0VGFiSGVhZGVyXCIsIHtcbiAgICAgICAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNhbmNlbGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICAgICAgdGFiOiB0YWJTZWxlY3RlZCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgJHIucXVlcnlTZWxlY3RvckFsbChcIi50YWJzLXNlbGVjdDpub3QoLmRpc2FibGVkKVwiKS5mb3JFYWNoKCgkdGFiKSA9PiB7XG4gICAgICAkdGFiLmFkZEV2ZW50TGlzdGVuZXIoXCJjaGFuZ2VcIiwgKGUpID0+IHtcbiAgICAgICAgbGV0IGtleSA9IHBhcnNlRmxvYXQoZS5jdXJyZW50VGFyZ2V0LnZhbHVlKTtcblxuICAgICAgICBpZiAoa2V5KSB7XG4gICAgICAgICAgbGV0IHRhYlNlbGVjdGVkID0gY29uZmlnLnRpbWVsaW5lLnRhYnMuZmluZCgodGFiKSA9PiB0YWIuaWQgPT0ga2V5KTtcbiAgICAgICAgICBpZiAodGFiU2VsZWN0ZWQpIHtcbiAgICAgICAgICAgICRyLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgICAgIG5ldyBDdXN0b21FdmVudChcInNlbGVjdFRhYkhlYWRlclwiLCB7XG4gICAgICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgICAgICAgIHRhYjogdGFiU2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJldHVybiAkcjtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBIZWFkZXJcbiAgICogU2UgdXNhIHBhcmEgOlxuICAgKiAgICAtIE1vc3RyYXIgZmVjaGFzIGVuIGhlYWRlclxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gQ29uZmlndXJhY2lvbiBjYXBpYmFyYVxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbVxuICAgKi9cbiAgY3JlYXRlSGVhZGVyKGNvbmZpZykge1xuICAgIGxldCAkZWxlbSA9IGRvbS5jcmVhdGVFbGVtZW50KFwiaGVhZGVyXCIpO1xuICAgIHJldHVybiB0aGlzLnJlZHJhd0hlYWRlcihjb25maWcsICRlbGVtKTtcbiAgfSxcblxuICAvKipcbiAgICogUmVjcmVhIEhlYWRlciwgdXNhZG8gcGFyYSByZWRpYnVqYXJcbiAgICogdXRpbGl6YSAkZWxlbSBjb21vIGVsZW1lbnRvIGRvbSBkb25kZSByZWNyZWFybG9cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHBhcmFtIHtPYmplY3R9ICRlbGVtIC0gRWxlbWVudG8gRG9tIGRvbmRlIGNyZWEgSGVhZGVyXG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tXG4gICAqL1xuICByZWRyYXdIZWFkZXIoY29uZmlnLCAkZWxlbSkge1xuICAgIGxldCBkYXRlc1RyZWUgPSBkYXRlVXRpbHMuZ2V0RGF0ZVRyZWVSYW5nZShcbiAgICAgIG5ldyBEYXRlKGNvbmZpZy50aW1lbGluZS5zdGFydCksXG4gICAgICBuZXcgRGF0ZShjb25maWcudGltZWxpbmUuZW5kKVxuICAgICk7XG5cbiAgICBsZXQgc3RyID0gYDxkaXYgY2xhc3M9XCJoZWFkZXItY29udGFpbmVyXCI+IGA7XG5cbiAgICBPYmplY3Qua2V5cyhkYXRlc1RyZWUpLmZvckVhY2goKGtleVkpID0+IHtcbiAgICAgIGxldCB5ZWFyID0gZGF0ZXNUcmVlW2tleVldO1xuICAgICAgc3RyICs9IGA8ZGl2IGNsYXNzPVwiYWduby1jYWxlbmRhcmlvXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYWdubyBoaWRlXCI+JHtrZXlZfTwvc3Bhbj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1lc2VzXCI+YDtcblxuICAgICAgT2JqZWN0LmtleXMoeWVhcikuZm9yRWFjaCgoa2V5TSkgPT4ge1xuICAgICAgICBsZXQgbW9udGggPSBkYXRlc1RyZWVba2V5WV1ba2V5TV07XG4gICAgICAgIHN0ciArPSBgIDxkaXYgY2xhc3M9XCJtZXMtY2FsZW5kYXJpb1wiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWVzICR7XG4gICAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmtleXMobW9udGgpLmxlbmd0aCA8IDRcbiAgICAgICAgICAgICAgICAgICAgICAgID8gXCJtZXMtcmVkdWNlZCBtZXMtcmVkdWNlZC1cIiArIE9iamVjdC5rZXlzKG1vbnRoKS5sZW5ndGhcbiAgICAgICAgICAgICAgICAgICAgICAgIDogXCJcIlxuICAgICAgICAgICAgICAgICAgICB9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1lcy1sYWJlbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgJHt1dGlscy5nZXRNb250aEJ5UG9zaXRpb24oa2V5TSl9ICR7a2V5WX1cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkaWFzXCI+YDtcbiAgICAgICAgT2JqZWN0LmtleXMobW9udGgpLmZvckVhY2goKGtleUQpID0+IHtcbiAgICAgICAgICBsZXQgZGF5ID0gZGF0ZXNUcmVlW2tleVldW2tleU1dW2tleURdO1xuICAgICAgICAgIGxldCBpc1dlZWtlbmQgPSBkYXkuaXNXZWVrZW5kO1xuICAgICAgICAgIGxldCBpc1RvZGF5ID0gZGF5LmlzVG9kYXk7XG4gICAgICAgICAgbGV0IGhhc0FsZXJ0ID0gY29uZmlnLnRpbWVsaW5lLmhlYWRlci5kYXRlSGFzQWxlcnRcbiAgICAgICAgICAgID8gY29uZmlnLnRpbWVsaW5lLmhlYWRlci5kYXRlSGFzQWxlcnQoZGF5KVxuICAgICAgICAgICAgOiBmYWxzZTtcbiAgICAgICAgICBsZXQgZGF0ZSA9IGRhdGVVdGlscy5mb3JtYXREYXRlKGRheS5kYXRlKTtcbiAgICAgICAgICBzdHIgKz0gYDxkaXYgY2xhc3M9XCJkaWEtY2FsZW5kYXJpbyBcbiAgICAgICAgICAgICR7aXNUb2RheSA/IFwidG9kYXlcIiA6IFwiXCJ9XG4gICAgICAgICAgICAke2lzV2Vla2VuZCA/IFwid2Vla2VuZFwiIDogXCJcIn1cbiAgICAgICAgICAgICR7aGFzQWxlcnQgPyBcImhhcy1hbGVydFwiIDogXCJcIn1cbiAgICAgICAgICAgICR7Y29uZmlnLnRpbWVsaW5lLmRhdGVTZWxlY3RhYmxlID8gXCJpcy1jbGlja2VhYmxlXCIgOiBcIlwifVxuICAgICAgICAgICAgJHtjb25maWcudGltZWxpbmUuZGF0ZVdpdGhDb250ZXh0TWVudSA/IFwiaXMtY2xpY2tlYWJsZVwiIDogXCJcIn1cbiAgICAgICAgICAgIFwiIGRhdGU9XCIke2RhdGV9XCI+JHtrZXlEfTwvZGl2PmA7XG4gICAgICAgIH0pO1xuICAgICAgICBzdHIgKz0gYDwvZGl2PjwvZGl2PmA7XG4gICAgICB9KTtcbiAgICAgIHN0ciArPSBgPC9kaXY+IDwvZGl2PmA7XG4gICAgfSk7XG5cbiAgICBzdHIgKz0gYDwvZGl2PmA7XG4gICAgJGVsZW0uaW5uZXJIVE1MID0gXCJcIjtcbiAgICAkZWxlbS5hcHBlbmQoZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChzdHIpKTtcblxuICAgIGxldCAkZGF5cyA9ICRlbGVtLnF1ZXJ5U2VsZWN0b3JBbGwoXCIuZGlhLWNhbGVuZGFyaW9bZGF0ZV1cIik7XG4gICAgJGRheXMuZm9yRWFjaCgoJGRpYSkgPT4ge1xuICAgICAgaWYgKGNvbmZpZy50aW1lbGluZS5kYXRlV2l0aENvbnRleHRNZW51KSB7XG4gICAgICAgICRkaWEuYWRkRXZlbnRMaXN0ZW5lcihcImNvbnRleHRtZW51XCIsIChldnQpID0+IHtcbiAgICAgICAgICAkZWxlbS5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwiY29udGV4dE1lbnVEYXRlXCIsIHtcbiAgICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICAgICRlbGVtOiAkZGlhLFxuICAgICAgICAgICAgICAgIGRhdGU6ICRkaWEuZ2V0QXR0cmlidXRlKFwiZGF0ZVwiKSxcbiAgICAgICAgICAgICAgICBjbGllbnRYOiBldnQuY2xpZW50WCxcbiAgICAgICAgICAgICAgICBjbGllbnRZOiBldnQuY2xpZW50WSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoY29uZmlnLnRpbWVsaW5lLmRhdGVTZWxlY3RhYmxlKSB7XG4gICAgICAgICRkaWEuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChldnQpID0+IHtcbiAgICAgICAgICAkZWxlbS5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwiY2xpY2tEYXRlXCIsIHtcbiAgICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICAgICRlbGVtOiAkZGlhLFxuICAgICAgICAgICAgICAgIGRhdGU6ICRkaWEuZ2V0QXR0cmlidXRlKFwiZGF0ZVwiKSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoY29uZmlnLnRpbWVsaW5lLm9uTW91c2VPdmVyRGF0ZSkge1xuICAgICAgICAkZGlhLmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW92ZXJcIiwgKGV2dCkgPT4ge1xuICAgICAgICAgIGNvbmZpZy50aW1lbGluZS5vbk1vdXNlT3ZlckRhdGUoe1xuICAgICAgICAgICAgJGRpYSxcbiAgICAgICAgICAgICRlbGVtLFxuICAgICAgICAgICAgZGF0ZTogJGRpYS5nZXRBdHRyaWJ1dGUoXCJkYXRlXCIpLFxuICAgICAgICAgICAgZXZ0LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChjb25maWcudGltZWxpbmUub25Nb3VzZU91dERhdGUpIHtcbiAgICAgICAgJGRpYS5hZGRFdmVudExpc3RlbmVyKFwibW91c2VvdXRcIiwgKGV2dCkgPT4ge1xuICAgICAgICAgIGNvbmZpZy50aW1lbGluZS5vbk1vdXNlT3V0RGF0ZSh7XG4gICAgICAgICAgICAkZGlhLFxuICAgICAgICAgICAgJGVsZW0sXG4gICAgICAgICAgICBkYXRlOiAkZGlhLmdldEF0dHJpYnV0ZShcImRhdGVcIiksXG4gICAgICAgICAgICBldnQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuICRlbGVtO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhIEhlYWRlciBleHRlbmRlZFxuICAgKiBTZSB1c2EgcGFyYSA6XG4gICAqICAgIC1Nb3N0cmFyIGlucHV0cyB5IGRhdG9zIHBhcmEgZmVjaGFzIGVuIGhlYWRlclxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gQ29uZmlndXJhY2lvbiBjYXBpYmFyYVxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBoZWFkZXJFeHRlbmRlZFxuICAgKi9cbiAgY3JlYXRlSGVhZGVyRXh0ZW5kZWQoY29uZmlnKSB7XG4gICAgaWYgKGNvbmZpZy50aW1lbGluZS5oZWFkZXIuZXh0ZW5kLmVuYWJsZWQgPT0gZmFsc2UpIHJldHVybiBudWxsO1xuXG4gICAgbGV0IGRhdGVzID0gZGF0ZVV0aWxzLmdldERhdGVSYW5nZShcbiAgICAgIG5ldyBEYXRlKGNvbmZpZy50aW1lbGluZS5zdGFydCksXG4gICAgICBuZXcgRGF0ZShjb25maWcudGltZWxpbmUuZW5kKVxuICAgICk7XG4gICAgbGV0IHN0ciA9IGA8ZGl2IGNsYXNzPVwiaGVhZGVyLWNvbnRhaW5lci1leHRlbmRlZFwiPmA7XG5cbiAgICBjb25maWcudGltZWxpbmUuaGVhZGVyLmV4dGVuZC5kYXRhLmZvckVhY2goKGQsIGRfaW5kZXgpID0+IHtcbiAgICAgIGlmIChkLmlzSGlkZGVuKSByZXR1cm4gXCJcIjtcblxuICAgICAgbGV0IGlzUGVyc2lzdGVudCA9IGQuaXNQZXJzaXN0ZW50O1xuICAgICAgc3RyICs9IGA8ZGl2IGNsYXNzPVwiaW5wdXQtbGlzdCAke2lzUGVyc2lzdGVudCA/IFwicGVyc2lzdGVudFwiIDogXCJcIn1cIj5gO1xuICAgICAgc3RyICs9IGRhdGVzXG4gICAgICAgIC5tYXAoKGRhdGUpID0+IHtcbiAgICAgICAgICBsZXQgdmFsdWUgPSBcIlwiO1xuICAgICAgICAgIGxldCBjbGFzc05hbWUgPSBcIlwiO1xuICAgICAgICAgIGxldCBpc0Z1dHVyZSA9IGRhdGVVdGlscy5pc0Z1dHVyZShkYXRlKTtcbiAgICAgICAgICBsZXQgaXNUb2RheSA9IGRhdGVVdGlscy5pc1RvZGF5KGRhdGUpO1xuXG4gICAgICAgICAgaWYgKGQuZGF0YSkge1xuICAgICAgICAgICAgbGV0IGRhdGFGb3VuZGVkID0gZC5kYXRhLmZpbmQoKGRhdGFJbnB1dCkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gZGF0ZVV0aWxzLmlzU2FtZURhdGUoXG4gICAgICAgICAgICAgICAgbmV3IERhdGUoZGF0YUlucHV0LmRhdGUgKyBcIlQwMDowMDowMFwiKSxcbiAgICAgICAgICAgICAgICBkYXRlXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChkYXRhRm91bmRlZCkge1xuICAgICAgICAgICAgICB2YWx1ZSA9IGRhdGFGb3VuZGVkLnZhbHVlIHx8IFwiXCI7XG4gICAgICAgICAgICAgIGNsYXNzTmFtZSArPSBkYXRhRm91bmRlZC5jbGFzc05hbWUgKyBcIiBcIiB8fCBcIlwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGQuZWRpdGFibGUgPT09IGZhbHNlIHx8XG4gICAgICAgICAgICAoaXNGdXR1cmUgJiYgZC5lZGl0YWJsZUZ1dHVyZSA9PSBmYWxzZSkgfHxcbiAgICAgICAgICAgIChpc1RvZGF5ICYmIGQuZWRpdGFibGVUb2RheSA9PSBmYWxzZSlcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiBgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBkYXRlPVwiJHtkYXRlVXRpbHMuZm9ybWF0RGF0ZShkYXRlKX1cIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleD1cIiR7ZF9pbmRleH1cIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIiAke2NsYXNzTmFtZX0gJHtkYXRlLnZhck5hbWUgfHwgXCJcIn0gJHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQuY29sb3IgPyBcImMtXCIgKyBkLmNvbG9yICsgXCItLXRleHRcIiA6IFwiXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XCIgPiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke3ZhbHVlfSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgbGV0IGlzRGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgICBpZiAoY29uZmlnLnRpbWVsaW5lLmVkaXRhYmxlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgaXNEaXNhYmxlZCA9IHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGA8ZGl2IGNsYXNzPVwiZGlhLWlucHV0XCI+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgXG4gICAgICAgICAgICAgICAgICBkYXRlPVwiJHtkYXRlVXRpbHMuZm9ybWF0RGF0ZShkYXRlKX1cIiBcbiAgICAgICAgICAgICAgICAgIGluZGV4PVwiJHtkX2luZGV4fVwiIFxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJoZWFkZXItaW5wdXQgXG4gICAgICAgICAgICAgICAgICAke2RhdGUudmFyTmFtZX0gJHtkLmNvbG9yID8gXCJjLVwiICsgZC5jb2xvciArIFwiLS10ZXh0XCIgOiBcIlwifVwiIFxuICAgICAgICAgICAgICAgICAgdHlwZT1cIm51bWJlclwiXG4gICAgICAgICAgICAgICAgICAke2lzRGlzYWJsZWQgPyBcImRpc2FibGVkXCIgOiBcIlwifSBcbiAgICAgICAgICAgICAgICAgIHZhbHVlPVwiJHt2YWx1ZX1cIj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICB9KVxuICAgICAgICAuam9pbihcIlwiKTtcbiAgICAgIHN0ciArPSBgPC9kaXY+YDtcbiAgICB9KTtcblxuICAgIHN0ciArPSBgPC9kaXY+YDtcblxuICAgIGxldCByID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChzdHIpO1xuXG4gICAgci5xdWVyeVNlbGVjdG9yQWxsKFwiaW5wdXQuaGVhZGVyLWlucHV0XCIpLmZvckVhY2goKGlucHV0KSA9PiB7XG4gICAgICBpbnB1dC5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIiwgKGUpID0+IHtcbiAgICAgICAgbGV0IGRhdGUgPSBlLmN1cnJlbnRUYXJnZXQuZ2V0QXR0cmlidXRlKFwiZGF0ZVwiKTtcbiAgICAgICAgbGV0IGluZGV4ID0gZS5jdXJyZW50VGFyZ2V0LmdldEF0dHJpYnV0ZShcImluZGV4XCIpO1xuICAgICAgICBsZXQgdmFsdWUgPSBlLmN1cnJlbnRUYXJnZXQudmFsdWU7XG4gICAgICAgIGxldCB0eXBlRGF0YSA9IGNvbmZpZy50aW1lbGluZS5oZWFkZXIuZXh0ZW5kLmRhdGFbaW5kZXhdO1xuXG4gICAgICAgIC8vcmVmcmVzaCBjb25maWcgdmFsdWVcbiAgICAgICAgbGV0IGRhdGEgPSB0eXBlRGF0YS5kYXRhLmZpbmQoKGQpID0+XG4gICAgICAgICAgZGF0ZVV0aWxzLmlzU2FtZURhdGUoXG4gICAgICAgICAgICBuZXcgRGF0ZShkLmRhdGUgKyBcIlQwMDowMDowMFwiKSxcbiAgICAgICAgICAgIG5ldyBEYXRlKGRhdGUgKyBcIlQwMDowMDowMFwiKVxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICBkYXRhLnZhbHVlID0gdmFsdWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdHlwZURhdGEuZGF0YS5wdXNoKHtcbiAgICAgICAgICAgIGRhdGU6IGRhdGUsXG4gICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwiY2hhbmdlSW5wdXRIZWFkZXJcIiwge1xuICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgIGNhbmNlbGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICAgIGRhdGU6IGRhdGUsXG4gICAgICAgICAgICAgIHR5cGVEYXRhOiB0eXBlRGF0YSxcbiAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcjtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYXIgU2lkZWJhciBJenF1aWVyZG9cbiAgICogICAgLSBNYW5lamEgaXRlbXMgY29tbyBhcmJvbCBkZSAyIG5pdmVsZXMgKHBhcmVudCwgY2hpbGRyZW4pXG4gICAqICAgIC0gRWwgc2lkZWJhciBzZSBkaXZpZGUgZW4gbmF2TGlzdCAtIEluaXRpYWxOYXYgLSBleHRlbmRlZE5hdiAtIEJ0bk5hdlxuICAgKiAgICAtIFNlIGFncmVnYSBpdGVtRGV0YWlsLCBwYXJhIGRldGFsbGVzIGRlIGl0ZW1zXG4gICAqXG4gICAqXG4gICAqIFRPRE86IHBhcmEgZXZpdGFyIGluY3J1c3RhciBsYXMgaWRzIGVuIGxvcyBpbnB1dHMsIHNlIGRlYmVuIGNyZWFyXG4gICAqIGxvcyBub2RvcyB1bm8gcG9yIHVubyBjb21vIGVsZW1lbnRvIERPTSwgeSBhZ3JlZ2FybGVzIGxvcyBldmVudG9zIGRpcmVjdGFtZW50ZVxuICAgKiBhaG9yYSBzZSBoYWNlIHNlbGVjY2lvbmFuZG8gdG9kb3MgbG9zIGlucHV0cyBjb24gcXVlcnlTZWxlY3RvckFsbFxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gQ29uZmlndXJhY2lvbiBjYXBpYmFyYVxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBTaWRlYmFyIEl6cXVpZXJkb1xuICAgKi9cbiAgY3JlYXRlTmF2TGVmdChjb25maWcsIHRhYiA9IG51bGwpIHtcbiAgICBsZXQgJGVsZW0gPSBkb20uY3JlYXRlRWxlbWVudChcIm5hdlwiLCB7IGNsYXNzTmFtZTogXCJsZWZ0XCIgfSk7XG4gICAgcmV0dXJuIHRoaXMucmVkcmF3TmF2TGVmdCgkZWxlbSwgY29uZmlnLCB0YWIpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZWNyZWEgU2lkZWJhciBpenF1aWVyZG8sIHVzYWRvIHBhcmEgcmVkaWJ1amFyXG4gICAqIFV0aWxpemEgJGVsZW0gY29tbyBlbGVtZW50byBkb20gZG9uZGUgcmVjcmVhcmxvXG4gICAqXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSAkZWxlbSAtIEVsZW1lbnRvIERvbSBkb25kZSBjcmVhIGVsIHNpZGViYXIgaXpxdWllcmRvXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgLSBDb25maWd1cmFjaW9uIGNhcGliYXJhXG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tIG5hdkxlZnRcbiAgICovXG5cbiAgcmVkcmF3TmF2TGVmdCgkZWxlbSwgY29uZmlnLCB0YWIgPSBudWxsKSB7XG4gICAgbGV0IG5hdkxpc3QgPSBcIlwiO1xuICAgIGxldCBpbml0aWFsTmF2TGlzdCA9IFwiXCI7XG4gICAgbGV0IGV4TmF2TGlzdCA9IFwiXCI7XG4gICAgbGV0IGJ0bk5hdkxpc3QgPSBcIlwiO1xuICAgIGxldCBpc0Rpc2FibGVkID0gZmFsc2U7XG4gICAgaWYgKGNvbmZpZy50aW1lbGluZS5lZGl0YWJsZSA9PT0gZmFsc2UpIHtcbiAgICAgIGlzRGlzYWJsZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGNvbmZpZy5kYXRhLmZvckVhY2goKGQpID0+IHtcbiAgICAgIGlmIChkLmlzSGlkZGVuKSByZXR1cm47XG5cbiAgICAgIGNvbnN0IGhhc0J0biA9ICEhZC5vbkNsaWNrRGV0YWlsQnV0dG9uO1xuICAgICAgY29uc3QgZGV0YWlsQnRuID0gaGFzQnRuXG4gICAgICAgID8gYDxidXR0b24gY2xhc3M9XCJkZXRhaWwtYnRuXCIgaXRlbS1pZD1cIiR7ZC5pZCB8fCAtMX1cIiB0eXBlLW5vZGU9XCIke1xuICAgICAgICAgICAgZC50eXBlIHx8IFwiXCJcbiAgICAgICAgICB9XCIgPlxuICAgICAgICAke2QubGFiZWxEZXRhaWxCdXR0b259XG4gICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPmBcbiAgICAgICAgOiBcIlwiO1xuXG4gICAgICBuYXZMaXN0ICs9IGBcbiAgICAgICA8ZGl2IGNsYXNzPVwibmF2LWl0ZW1cIj5cblxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJuYXYtaXRlbS1jb250YWluZXIgcGFyZW50XCI+YDtcblxuICAgICAgaWYgKGQuY2hpbGRyZW4pIHtcbiAgICAgICAgbmF2TGlzdCArPSBgPGJ1dHRvbiBjbGFzcz1cInRyZWUtaWNvbiAke1xuICAgICAgICAgIGQuaXNDbG9zZWQgPyBcIlwiIDogXCJjYXAtcm90YXRlXCJcbiAgICAgICAgfVwiIGl0ZW0taWQ9XCIke2QuaWQgfHwgLTF9XCIgdHlwZS1ub2RlPVwiJHtkLnR5cGUgfHwgXCJcIn1cIiA+XG4gICAgICAgICR7aWNvbnMuY2hldnJvbkRvd259XG4gICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPmA7XG4gICAgICB9XG5cbiAgICAgIG5hdkxpc3QgKz0gYFxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtLXRpdGxlIHRydW5jYXRlIGZ1bGwtd2lkdGggJHtcbiAgICAgICAgICAgIGQuY2xpY2tlYWJsZSA/IFwiY2xpY2tlYWJsZVwiIDogXCJcIlxuICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAke2QubmF2T3ZlciA/IFwiaG92ZXJhYmxlXCIgOiBcIlwifSBcIiBpdGVtLWlkPVwiJHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGQuaWQgfHwgLTFcbiAgICAgICAgICAgICAgICAgICAgICB9XCIgdHlwZS1ub2RlPVwiJHtkLnR5cGUgfHwgXCJcIn1cIiA+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbS10aXRsZS1jb250ZW50XCI+XG4gICAgICAgICAgICAgICR7ZC5sYWJlbH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbC1idG4tY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICR7ZGV0YWlsQnRufVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PmA7XG5cbiAgICAgIGlmIChkLmNoaWxkcmVuKSB7XG4gICAgICAgIG5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2hpbGRyZW4taXRlbXMgJHtcbiAgICAgICAgICAgICAgICBkLmlzQ2xvc2VkID8gXCJoaWRlXCIgOiBcIlwiXG4gICAgICAgICAgICAgIH0gXCIgY2hpbGQtbGlzdD1cIiR7ZC5pZCB8fCAtMX1cIj5gO1xuXG4gICAgICAgIGQuY2hpbGRyZW4uZm9yRWFjaCgoYykgPT4ge1xuICAgICAgICAgIGlmIChjLmlzSGlkZGVuKSByZXR1cm47XG5cbiAgICAgICAgICBsZXQgbGlnaHRDb2xvciA9IG51bGw7XG4gICAgICAgICAgbGV0IGxpZ2h0Q2xhc3MgPSBudWxsO1xuICAgICAgICAgIGxldCBsaWdodFNwYW4gPSBcIlwiO1xuICAgICAgICAgIGxldCBtdWx0aUJ1dHRvbnNEZXRhaWxUbXBsID0gXCJcIjtcblxuICAgICAgICAgIGlmIChjLmxpZ2h0KSB7XG4gICAgICAgICAgICBpZiAodXRpbHMuaXNIZXhDb2xvcihjLmxpZ2h0KSkge1xuICAgICAgICAgICAgICBsaWdodENvbG9yID0gYy5saWdodDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGxpZ2h0Q2xhc3MgPSBjLmxpZ2h0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChjLmxpZ2h0KSB7XG4gICAgICAgICAgICBsaWdodFNwYW4gPSBgPHNwYW4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibGlnaHQgJHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaWdodENsYXNzID8gbGlnaHRDbGFzcyArIFwiLWxpZ2h0XCIgOiBcIlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCIke1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpZ2h0Q29sb3IgPyBcIi0tbGlnaHQtY29sb3I6XCIgKyBsaWdodENvbG9yIDogXCJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICB9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+YDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoYy5oYXNNdWx0aWJ1dHRvbnMpIHtcbiAgICAgICAgICAgIGxldCBpY29uRm9ybWF0dGVyID0gbnVsbDtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmluaXRpYWwubXVsdGlidXR0b25zICYmXG4gICAgICAgICAgICAgIGNvbmZpZy50aW1lbGluZS5uYXYubGVmdC5pbml0aWFsLm11bHRpYnV0dG9ucy5pY29uRm9ybWF0dGVyXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgaWNvbkZvcm1hdHRlciA9XG4gICAgICAgICAgICAgICAgY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmluaXRpYWwubXVsdGlidXR0b25zLmljb25Gb3JtYXR0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgYnRuQ29udGVudCA9IGljb25Gb3JtYXR0ZXJcbiAgICAgICAgICAgICAgPyBpY29uRm9ybWF0dGVyKHsgaXRlbTogYywgY29uZmlnIH0pXG4gICAgICAgICAgICAgIDogXCJcIjtcblxuICAgICAgICAgICAgbXVsdGlCdXR0b25zRGV0YWlsVG1wbCA9IGA8YnV0dG9uIGNsYXNzPVwibXVsdGlidXR0b25zLWJ0blwiIFxuICAgICAgICAgICAgICBpdGVtLWlkPVwiJHtjLmlkIHx8IC0xfVwiIFxuICAgICAgICAgICAgICB0eXBlLW5vZGU9XCIke2MudHlwZSB8fCBcIlwifVwiIFxuICAgICAgICAgICAgICAke2lzRGlzYWJsZWQgPyBcImRpc2FibGVkXCIgOiBcIlwifT5cbiAgICAgICAgICAgICAgICAke2J0bkNvbnRlbnR9IFxuICAgICAgICAgICAgICA8L2J1dHRvbj5gO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIG5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjaGlsZC1uYXYtaXRlbVwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm5hdi1pdGVtLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICBgO1xuXG4gICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJuYXYtaXRlbS1pY29uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHN2ZyBzdHlsZT1cIndpZHRoOjI0cHg7aGVpZ2h0OjI0cHhcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBkPVwiTTE5LDE1TDEzLDIxTDExLjU4LDE5LjU4TDE1LjE3LDE2SDRWNEg2VjE0SDE1LjE3TDExLjU4LDEwLjQyTDEzLDlMMTksMTVaXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICovXG5cbiAgICAgICAgICBuYXZMaXN0ICs9IGBcbiAgICAgICAgICAgICAgICAgICAgJHtsaWdodFNwYW59XG4gICAgICAgICAgICAgICAgICAgICR7bXVsdGlCdXR0b25zRGV0YWlsVG1wbH1cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBcbiAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIml0ZW0tdGl0bGUgJHtjLmNsaWNrZWFibGUgPyBcImNsaWNrZWFibGVcIiA6IFwiXCJ9ICR7XG4gICAgICAgICAgICAgICAgICAgICAgICBjLm5hdk92ZXIgPyBcImhvdmVyYWJsZVwiIDogXCJcIlxuICAgICAgICAgICAgICAgICAgICAgIH1cIiBcbiAgICAgICAgICAgICAgICAgICAgICBpdGVtLWlkPVwiJHtjLmlkIHx8IC0xfVwiIFxuICAgICAgICAgICAgICAgICAgICAgIHR5cGUtbm9kZT1cIiR7Yy50eXBlIHx8IFwiXCJ9XCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHJ1bmNhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICR7Yy5sYWJlbH1cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICB9KTtcblxuICAgICAgICBuYXZMaXN0ICs9IGBcbiAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgIH1cblxuICAgICAgbmF2TGlzdCArPSBgPC9kaXY+YDtcblxuICAgICAgLy9pbml0aWFsXG4gICAgICBpbml0aWFsTmF2TGlzdCArPSBgPGRpdiBjbGFzcz1cImluaXRpYWwtbmF2LWl0ZW0gcGFyZW50XCI+YDtcbiAgICAgIGlmIChkLndpdGhOYXYpIHtcbiAgICAgICAgY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmluaXRpYWwudmFycy5mb3JFYWNoKCh2KSA9PiB7XG4gICAgICAgICAgbGV0IHZhbHVlID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGQudmFsdWVzLCB2LnZhck5hbWUpO1xuXG4gICAgICAgICAgaWYgKHYucm91bmQgJiYgIWlzTmFOKHZhbHVlKSkge1xuICAgICAgICAgICAgdmFsdWUgPSB1dGlscy5yb3VuZCh2YWx1ZSwgdi5yb3VuZCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh2LmlucHV0KSB7XG4gICAgICAgICAgICBzd2l0Y2ggKHYuaW5wdXQpIHtcbiAgICAgICAgICAgICAgY2FzZSBcImhvdXJcIjpcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnNwbGl0KFwiOlwiKTtcbiAgICAgICAgICAgICAgICBsZXQgaGhWYWx1ZSA9IHZhbHVlWzBdO1xuICAgICAgICAgICAgICAgIGxldCBtbVZhbHVlID0gdmFsdWVbMV07XG4gICAgICAgICAgICAgICAgaW5pdGlhbE5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtLWNvbCBoYXMtaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJob3VyLWlucHV0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtdHlwZT1cInRpbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXg9XCIyM1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbj1cIjAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQta2V5PVwiJHt2LmtleSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0taWQ9XCIke2QuaWQgfHwgLTF9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS1ub2RlPVwiJHtkLnR5cGUgfHwgXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT1cIiR7aGhWYWx1ZX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2lzRGlzYWJsZWQgPyBcImRpc2FibGVkXCIgOiBcIlwifVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImhoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPjo8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtdHlwZT1cInRpbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXg9XCI1OVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbj1cIjAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQta2V5PVwiJHt2LmtleSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0taWQ9XCIke2QuaWQgfHwgLTF9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS1ub2RlPVwiJHtkLnR5cGUgfHwgXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT1cIiR7bW1WYWx1ZX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2lzRGlzYWJsZWQgPyBcImRpc2FibGVkXCIgOiBcIlwifVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1tXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlIFwidGV4dFwiOlxuICAgICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgaW5pdGlhbE5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtLWNvbCBoYXMtaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCAgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCIke3YuaW5wdXQgfHwgXCJ0ZXh0XCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtdHlwZT1cIiR7di5pbnB1dCB8fCBcInRleHRcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC1rZXk9XCIke3Yua2V5IHx8IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS1pZD1cIiR7ZC5pZCB8fCAtMX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLW5vZGU9XCIke2QudHlwZSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7aXNEaXNhYmxlZCA/IFwiZGlzYWJsZWRcIiA6IFwiXCJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPVwiJHt2YWx1ZX1cIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaW5pdGlhbE5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbS1jb2xcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke3ZhbHVlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGluaXRpYWxOYXZMaXN0ICs9IGBcbiAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG5cbiAgICAgIGlmIChkLmNoaWxkcmVuKSB7XG4gICAgICAgIGQuY2hpbGRyZW4uZm9yRWFjaCgoYykgPT4ge1xuICAgICAgICAgIGlmIChjLmlzSGlkZGVuKSByZXR1cm47XG4gICAgICAgICAgaW5pdGlhbE5hdkxpc3QgKz0gYDxkaXYgY2xhc3M9XCJjaGlsZC1pbml0aWFsLW5hdi1pdGVtICR7XG4gICAgICAgICAgICBkLmlzQ2xvc2VkID8gXCJoaWRlXCIgOiBcIlwiXG4gICAgICAgICAgfVwiIGNoaWxkPVwiJHtkLmlkIHx8IC0xfVwiPmA7XG5cbiAgICAgICAgICBpZiAoYy53aXRoTmF2ICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmluaXRpYWwudmFycy5mb3JFYWNoKCh2KSA9PiB7XG4gICAgICAgICAgICAgIGlmICh2Lm9ubHlUYWIgJiYgdGFiICYmIHYub25seVRhYiAhPT0gdGFiLmtleSkgcmV0dXJuO1xuXG4gICAgICAgICAgICAgIGxldCB2YWx1ZSA9IHV0aWxzLmdldFZhckJ5UGF0aChjLnZhbHVlcywgdi52YXJOYW1lKTtcbiAgICAgICAgICAgICAgaWYgKHYucm91bmQgJiYgIWlzTmFOKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdXRpbHMucm91bmQodmFsdWUsIHYucm91bmQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmICh2LmlucHV0KSB7XG4gICAgICAgICAgICAgICAgc3dpdGNoICh2LmlucHV0KSB7XG4gICAgICAgICAgICAgICAgICBjYXNlIFwiaG91clwiOlxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnNwbGl0KFwiOlwiKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGhoVmFsdWUgPSB2YWx1ZVswXTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG1tVmFsdWUgPSB2YWx1ZVsxXTtcbiAgICAgICAgICAgICAgICAgICAgaW5pdGlhbE5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtLWNvbCBoYXMtaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJob3VyLWlucHV0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtdHlwZT1cInRpbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXg9XCIyM1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbj1cIjAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQta2V5PVwiJHt2LmtleSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0taWQ9XCIke2MuaWQgfHwgLTF9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS1ub2RlPVwiJHtjLnR5cGUgfHwgXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT1cIiR7aGhWYWx1ZX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2lzRGlzYWJsZWQgPyBcImRpc2FibGVkXCIgOiBcIlwifVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImhoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPjo8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtdHlwZT1cInRpbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXg9XCI1OVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbj1cIjAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQta2V5PVwiJHt2LmtleSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0taWQ9XCIke2MuaWQgfHwgLTF9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS1ub2RlPVwiJHtjLnR5cGUgfHwgXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT1cIiR7bW1WYWx1ZX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2lzRGlzYWJsZWQgPyBcImRpc2FibGVkXCIgOiBcIlwifVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1tXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGNhc2UgXCJ0ZXh0XCI6XG4gICAgICAgICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBpbml0aWFsTmF2TGlzdCArPSBgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIml0ZW0tY29sIGhhcy1pbnB1dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCIke3YuaW5wdXQgfHwgXCJ0ZXh0XCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtdHlwZT1cIiR7di5pbnB1dCB8fCBcInRleHRcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC1rZXk9XCIke3Yua2V5IHx8IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS1pZD1cIiR7Yy5pZCB8fCAtMX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLW5vZGU9XCIke2MudHlwZSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7aXNEaXNhYmxlZCA/IFwiZGlzYWJsZWRcIiA6IFwiXCJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPVwiJHt2YWx1ZX1cIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaW5pdGlhbE5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbS1jb2xcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke3ZhbHVlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaW5pdGlhbE5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICAvL0V4dFxuICAgICAgZXhOYXZMaXN0ICs9IGA8ZGl2IGNsYXNzPVwiZXgtbmF2LWl0ZW0gcGFyZW50XCI+YDtcbiAgICAgIGlmIChkLndpdGhFeE5hdikge1xuICAgICAgICBjb25maWcudGltZWxpbmUubmF2LmxlZnQuZXh0ZW5kLnZhcnMuZm9yRWFjaCgodikgPT4ge1xuICAgICAgICAgIGxldCB2YWx1ZSA9IHV0aWxzLmdldFZhckJ5UGF0aChkLnZhbHVlcywgdi52YXJOYW1lKTtcbiAgICAgICAgICBpZiAodi5yb3VuZCAmJiAhaXNOYU4odmFsdWUpKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHV0aWxzLnJvdW5kKHZhbHVlLCB2LnJvdW5kKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHYuaW5wdXQpIHtcbiAgICAgICAgICAgIHN3aXRjaCAodi5pbnB1dCkge1xuICAgICAgICAgICAgICBjYXNlIFwiaG91clwiOlxuICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuc3BsaXQoXCI6XCIpO1xuICAgICAgICAgICAgICAgIGxldCBoaFZhbHVlID0gdmFsdWVbMF07XG4gICAgICAgICAgICAgICAgbGV0IG1tVmFsdWUgPSB2YWx1ZVsxXTtcbiAgICAgICAgICAgICAgICBleE5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtLWNvbCBoYXMtaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJob3VyLWlucHV0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtdHlwZT1cInRpbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXg9XCIyM1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbj1cIjBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC1rZXk9XCIke3Yua2V5IHx8IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS1pZD1cIiR7ZC5pZCB8fCAtMX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLW5vZGU9XCIke2QudHlwZSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPVwiJHtoaFZhbHVlfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7aXNEaXNhYmxlZCA/IFwiZGlzYWJsZWRcIiA6IFwiXCJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+Ojwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC10eXBlPVwidGltZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heD1cIjU5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluPVwiMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LWtleT1cIiR7di5rZXkgfHwgXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLWlkPVwiJHtkLmlkIHx8IC0xfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtbm9kZT1cIiR7ZC50eXBlIHx8IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9XCIke21tVmFsdWV9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtpc0Rpc2FibGVkID8gXCJkaXNhYmxlZFwiIDogXCJcIn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgY2FzZSBcInRleHRcIjpcbiAgICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGV4TmF2TGlzdCArPSBgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIml0ZW0tY29sIGhhcy1pbnB1dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCIke3YuaW5wdXQgfHwgXCJ0ZXh0XCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtdHlwZT1cIiR7di5pbnB1dCB8fCBcInRleHRcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC1rZXk9XCIke3Yua2V5IHx8IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS1pZD1cIiR7ZC5pZCB8fCAtMX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLW5vZGU9XCIke2QudHlwZSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7aXNEaXNhYmxlZCA/IFwiZGlzYWJsZWRcIiA6IFwiXCJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPVwiJHt2YWx1ZX1cIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZXhOYXZMaXN0ICs9IGBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIml0ZW0tY29sXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHt2YWx1ZX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBleE5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcblxuICAgICAgaWYgKGQuY2hpbGRyZW4pIHtcbiAgICAgICAgZC5jaGlsZHJlbi5mb3JFYWNoKChjKSA9PiB7XG4gICAgICAgICAgaWYgKGMuaXNIaWRkZW4pIHJldHVybjtcbiAgICAgICAgICBleE5hdkxpc3QgKz0gYDxkaXYgY2xhc3M9XCJjaGlsZC1leC1uYXYtaXRlbSAke1xuICAgICAgICAgICAgZC5pc0Nsb3NlZCA/IFwiaGlkZVwiIDogXCJcIlxuICAgICAgICAgIH1cIiBjaGlsZD1cIiR7ZC5pZCB8fCAtMX1cIj5gO1xuXG4gICAgICAgICAgaWYgKGMud2l0aE5hdiAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGNvbmZpZy50aW1lbGluZS5uYXYubGVmdC5leHRlbmQudmFycy5mb3JFYWNoKCh2KSA9PiB7XG4gICAgICAgICAgICAgIGlmICh2Lm9ubHlUYWIgJiYgdGFiICYmIHYub25seVRhYiAhPT0gdGFiLmtleSkgcmV0dXJuO1xuXG4gICAgICAgICAgICAgIGxldCB2YWx1ZSA9IHV0aWxzLmdldFZhckJ5UGF0aChjLnZhbHVlcywgdi52YXJOYW1lKTtcbiAgICAgICAgICAgICAgaWYgKHYucm91bmQgJiYgIWlzTmFOKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdXRpbHMucm91bmQodmFsdWUsIHYucm91bmQpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKHYuaW5wdXQpIHtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKHYuaW5wdXQpIHtcbiAgICAgICAgICAgICAgICAgIGNhc2UgXCJob3VyXCI6XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUgPyB2YWx1ZS5zcGxpdChcIjpcIikgOiBbMCwgMF07XG4gICAgICAgICAgICAgICAgICAgIGxldCBoaFZhbHVlID0gdmFsdWVbMF07XG4gICAgICAgICAgICAgICAgICAgIGxldCBtbVZhbHVlID0gdmFsdWVbMV07XG4gICAgICAgICAgICAgICAgICAgIGV4TmF2TGlzdCArPSBgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIml0ZW0tY29sIGhhcy1pbnB1dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhvdXItaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC10eXBlPVwidGltZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heD1cIjIzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluPVwiMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LWtleT1cIiR7di5rZXkgfHwgXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLWlkPVwiJHtjLmlkIHx8IC0xfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtbm9kZT1cIiR7Yy50eXBlIHx8IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9XCIke2hoVmFsdWV9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtpc0Rpc2FibGVkID8gXCJkaXNhYmxlZFwiIDogXCJcIn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJoaFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj46PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LXR5cGU9XCJ0aW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4PVwiNTlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW49XCIwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQta2V5PVwiJHt2LmtleSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0taWQ9XCIke2MuaWQgfHwgLTF9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS1ub2RlPVwiJHtjLnR5cGUgfHwgXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT1cIiR7bW1WYWx1ZX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2lzRGlzYWJsZWQgPyBcImRpc2FibGVkXCIgOiBcIlwifVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1tXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGNhc2UgXCJ0ZXh0XCI6XG4gICAgICAgICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBleE5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtLWNvbCBoYXMtaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCAgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCIke3YuaW5wdXQgfHwgXCJ0ZXh0XCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtdHlwZT1cIiR7di5pbnB1dCB8fCBcInRleHRcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC1rZXk9XCIke3Yua2V5IHx8IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS1pZD1cIiR7Yy5pZCB8fCAtMX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLW5vZGU9XCIke2MudHlwZSB8fCBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7aXNEaXNhYmxlZCA/IFwiZGlzYWJsZWRcIiA6IFwiXCJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPVwiJHt2YWx1ZX1cIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZXhOYXZMaXN0ICs9IGBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIml0ZW0tY29sXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHt2YWx1ZX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGV4TmF2TGlzdCArPSBgXG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vYnV0dG9uc1xuICAgICAgYnRuTmF2TGlzdCArPSBgPGRpdiBjbGFzcz1cImNhcC1idG4tbmF2LWl0ZW0gcGFyZW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FwLWJ0bi1uYXYtaXRlbS1jb250ZW50XCI+YDtcbiAgICAgIGlmIChcbiAgICAgICAgY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmJ1dHRvbnMgJiZcbiAgICAgICAgY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmJ1dHRvbnMudmFyc1xuICAgICAgKSB7XG4gICAgICAgIGNvbmZpZy50aW1lbGluZS5uYXYubGVmdC5idXR0b25zLnZhcnMuZm9yRWFjaCgoYnRuKSA9PiB7XG4gICAgICAgICAgaWYgKGQud2l0aEJ0bk5hdikge1xuICAgICAgICAgICAgbGV0IGJ0bkNvbnRlbnQgPSBcIlwiO1xuICAgICAgICAgICAgbGV0IGNsYXNzTmFtZSA9IGJ0bi5jbGFzc05hbWUgfHwgXCJcIjtcblxuICAgICAgICAgICAgaWYgKGJ0bi5pY29uKSB7XG4gICAgICAgICAgICAgIGJ0bkNvbnRlbnQgPSBidG4uaWNvbiA/IGJ0bi5pY29uIDogXCJcIjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGJ0bi5pY29uRm9ybWF0dGVyKSB7XG4gICAgICAgICAgICAgIGJ0bkNvbnRlbnQgPSBidG4uaWNvbkZvcm1hdHRlciA/IGJ0bi5pY29uRm9ybWF0dGVyKGQsIGJ0bikgOiBcIlwiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoYnRuLnNoYXBlKSB7XG4gICAgICAgICAgICAgIGNsYXNzTmFtZSArPSBcIiBjYXAtYnRuLVwiICsgYnRuLnNoYXBlO1xuICAgICAgICAgICAgICBidG5Db250ZW50ICs9IGA8c3Bhbj4gJHtcbiAgICAgICAgICAgICAgICBidG4uZm9ybWF0dGVyID8gYnRuLmZvcm1hdHRlcihkLCBidG4pIDogXCJcIlxuICAgICAgICAgICAgICB9IDwvc3Bhbj4gYDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChidG4uYnRuQ2xhc3NOYW1lRm9ybWF0dGVyKSB7XG4gICAgICAgICAgICAgIGxldCBuZXdDbGFzc05hbWUgPSBidG4uYnRuQ2xhc3NOYW1lRm9ybWF0dGVyKGQsIGJ0bik7XG4gICAgICAgICAgICAgIGlmIChuZXdDbGFzc05hbWUpIHtcbiAgICAgICAgICAgICAgICBjbGFzc05hbWUgKz0gXCIgXCIgKyBuZXdDbGFzc05hbWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYnRuTmF2TGlzdCArPSBgXG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJjYXAtYnRuLXNoYXBlICR7Y2xhc3NOYW1lfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQta2V5PVwiJHtidG4ua2V5IHx8IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLWlkPVwiJHtkLmlkIHx8IC0xfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtpc0Rpc2FibGVkID8gXCJkaXNhYmxlZFwiIDogXCJcIn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLW5vZGU9XCIke2QudHlwZSB8fCBcIlwifVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7YnRuQ29udGVudH1cbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+YDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgYnRuTmF2TGlzdCArPSBgXG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG5cbiAgICAgIGlmIChkLmNoaWxkcmVuKSB7XG4gICAgICAgIGQuY2hpbGRyZW4uZm9yRWFjaCgoYykgPT4ge1xuICAgICAgICAgIGlmIChjLmlzSGlkZGVuKSByZXR1cm47XG5cbiAgICAgICAgICAvL2J1dHRvbnNcbiAgICAgICAgICBidG5OYXZMaXN0ICs9IGA8ZGl2IGNsYXNzPVwiY2FwLWJ0bi1jaGlsZC1uYXYtaXRlbSBwYXJlbnQgJHtcbiAgICAgICAgICAgIGQuaXNDbG9zZWQgPyBcImhpZGVcIiA6IFwiXCJcbiAgICAgICAgICB9XCIgY2hpbGQ9XCIke2QuaWQgfHwgLTF9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcC1idG4tbmF2LWl0ZW0tY29udGVudFwiPmA7XG5cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBjb25maWcudGltZWxpbmUubmF2LmxlZnQuYnV0dG9ucyAmJlxuICAgICAgICAgICAgY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmJ1dHRvbnMudmFyc1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29uZmlnLnRpbWVsaW5lLm5hdi5sZWZ0LmJ1dHRvbnMudmFycy5mb3JFYWNoKChidG4pID0+IHtcbiAgICAgICAgICAgICAgaWYgKGMud2l0aE5hdiAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBsZXQgYnRuQ29udGVudCA9IFwiXCI7XG4gICAgICAgICAgICAgICAgbGV0IGNsYXNzTmFtZSA9IGJ0bi5jbGFzc05hbWUgfHwgXCJcIjtcblxuICAgICAgICAgICAgICAgIGlmIChidG4uaWNvbikge1xuICAgICAgICAgICAgICAgICAgYnRuQ29udGVudCA9IGJ0bi5pY29uID8gYnRuLmljb24gOiBcIlwiO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChidG4uaWNvbkZvcm1hdHRlcikge1xuICAgICAgICAgICAgICAgICAgYnRuQ29udGVudCA9IGJ0bi5pY29uRm9ybWF0dGVyXG4gICAgICAgICAgICAgICAgICAgID8gYnRuLmljb25Gb3JtYXR0ZXIoYywgYnRuKVxuICAgICAgICAgICAgICAgICAgICA6IFwiXCI7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGJ0bi5zaGFwZSkge1xuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lICs9IFwiIGNhcC1idG4tXCIgKyBidG4uc2hhcGU7XG4gICAgICAgICAgICAgICAgICBidG5Db250ZW50ICs9IGA8c3Bhbj4gJHtcbiAgICAgICAgICAgICAgICAgICAgYnRuLmZvcm1hdHRlciA/IGJ0bi5mb3JtYXR0ZXIoYywgYnRuKSA6IFwiXCJcbiAgICAgICAgICAgICAgICAgIH0gPC9zcGFuPiBgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYnRuLmJ0bkNsYXNzTmFtZUZvcm1hdHRlcikge1xuICAgICAgICAgICAgICAgICAgbGV0IG5ld0NsYXNzTmFtZSA9IGJ0bi5idG5DbGFzc05hbWVGb3JtYXR0ZXIoYywgYnRuKTtcbiAgICAgICAgICAgICAgICAgIGlmIChuZXdDbGFzc05hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lICs9IFwiIFwiICsgbmV3Q2xhc3NOYW1lO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJ0bk5hdkxpc3QgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJjYXAtYnRuLXNoYXBlICR7Y2xhc3NOYW1lfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC1rZXk9XCIke2J0bi5rZXkgfHwgXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS1pZD1cIiR7Yy5pZCB8fCAtMX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtpc0Rpc2FibGVkID8gXCJkaXNhYmxlZFwiIDogXCJcIn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtbm9kZT1cIiR7Yy50eXBlIHx8IFwiXCJ9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2J0bkNvbnRlbnR9XG4gICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+YDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnRuTmF2TGlzdCArPSBgXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBsZXQgaXRlbURldGFpbCA9IGAgPGRpdiBjbGFzcz1cImRldGFpbC1uYXYtaXRlbSBoaWRlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICR7dGhpcy5nZXREZXRhaWxOYXZJdGVtQ29udGVudCgpfVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcblxuICAgIGxldCBzdHIgPSBgPGRpdiBjbGFzcz1cIm5hdi1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAke2l0ZW1EZXRhaWx9XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJuYXYtaXRlbS1saXN0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgJHtuYXZMaXN0fVxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImluaXRpYWwtbmF2LWxpc3RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAke2luaXRpYWxOYXZMaXN0fVxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImV4dGVuZC1uYXYtbGlzdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICR7ZXhOYXZMaXN0fVxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcC1idG4tbmF2LWxpc3RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAke2J0bk5hdkxpc3R9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcblxuICAgIGxldCBuYXZDb250YWluZXIgPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKHN0cik7XG4gICAgJGVsZW0uaW5uZXJIVE1MID0gXCJcIjtcbiAgICAkZWxlbS5hcHBlbmQobmF2Q29udGFpbmVyKTtcblxuICAgIC8vZGV0YWxsZSBkZSBuYXYtaXRlbVxuICAgICRlbGVtLnF1ZXJ5U2VsZWN0b3JBbGwoXCIuaXRlbS10aXRsZS5ob3ZlcmFibGVcIikuZm9yRWFjaCgoaSkgPT4ge1xuICAgICAgaS5hZGRFdmVudExpc3RlbmVyKFwibW91c2VvdmVyXCIsIChlKSA9PiB7XG4gICAgICAgIGxldCBwb3MgPSB1dGlscy5ldmVudFRvUG9zaXRpb25OYXZMZWZ0KGNvbmZpZywgZSwgJGVsZW0pO1xuICAgICAgICBsZXQgaXRlbUlkID0gaS5nZXRBdHRyaWJ1dGUoXCJpdGVtLWlkXCIpO1xuICAgICAgICBsZXQgaXRlbSA9IHV0aWxzLmdldEl0ZW1CeUlkKGNvbmZpZywgaXRlbUlkKTtcbiAgICAgICAgbGV0IHR5cGVOb2RlID0gaS5nZXRBdHRyaWJ1dGUoXCJ0eXBlLW5vZGVcIik7XG4gICAgICAgIGkuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoXCJvdmVyTmF2SXRlbVwiLCB7XG4gICAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgICAgb3JpZ2luYWxFdnQ6IGUsXG4gICAgICAgICAgICAgIGl0ZW06IGl0ZW0sXG4gICAgICAgICAgICAgIHR5cGU6IHR5cGVOb2RlLFxuICAgICAgICAgICAgICBwb3M6IHBvcyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy9vY3VsdGEgZGV0YWxsZSBkZSBuYXYtaXRlbSwgYWwgc2FsaXIgZGVsIG5hdi1pdGVtLWxpc3RcbiAgICAkZWxlbS5xdWVyeVNlbGVjdG9yQWxsKFwiLm5hdi1pdGVtLWxpc3RcIikuZm9yRWFjaCgoaSkgPT4ge1xuICAgICAgaS5hZGRFdmVudExpc3RlbmVyKFwibW91c2VsZWF2ZVwiLCAoZSkgPT4ge1xuICAgICAgICBpLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwibGVhdmVOYXZJdGVtXCIsIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvL29jdWx0YSBkZXRhbGxlIGRlIG5hdi1pdGVtLWxpc3QsIGFsIHNhbGlyIGRlIG5hdi1pdGVtXG4gICAgJGVsZW0ucXVlcnlTZWxlY3RvckFsbChcIi5pdGVtLXRpdGxlOm5vdCguaG92ZXJhYmxlKVwiKS5mb3JFYWNoKChpKSA9PiB7XG4gICAgICBpLmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgKGUpID0+IHtcbiAgICAgICAgaS5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgIG5ldyBDdXN0b21FdmVudChcImxlYXZlTmF2SXRlbVwiLCB7XG4gICAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgJGVsZW0ucXVlcnlTZWxlY3RvckFsbChcIi5pdGVtLXRpdGxlLmNsaWNrZWFibGVcIikuZm9yRWFjaCgoaSkgPT4ge1xuICAgICAgaS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgbGV0IGl0ZW1JZCA9IGkuZ2V0QXR0cmlidXRlKFwiaXRlbS1pZFwiKTtcbiAgICAgICAgbGV0IHR5cGVOb2RlID0gaS5nZXRBdHRyaWJ1dGUoXCJ0eXBlLW5vZGVcIik7XG4gICAgICAgIGxldCB2YWx1ZSA9IGkudmFsdWU7XG4gICAgICAgIGkuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoXCJjbGlja05hdkxlZnRJdGVtXCIsIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICBpdGVtSWQ6IGl0ZW1JZCxcbiAgICAgICAgICAgICAgdHlwZTogdHlwZU5vZGUsXG4gICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgJGVsZW0ucXVlcnlTZWxlY3RvckFsbChcIi5tdWx0aWJ1dHRvbnMtYnRuXCIpLmZvckVhY2goKGkpID0+IHtcbiAgICAgIGkuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgIGxldCBwb3MgPSB1dGlscy5ldmVudFRvUG9zaXRpb25OYXZMZWZ0KGNvbmZpZywgZSwgJGVsZW0pO1xuICAgICAgICBsZXQgaXRlbUlkID0gaS5nZXRBdHRyaWJ1dGUoXCJpdGVtLWlkXCIpO1xuICAgICAgICBsZXQgdHlwZU5vZGUgPSBpLmdldEF0dHJpYnV0ZShcInR5cGUtbm9kZVwiKTtcbiAgICAgICAgaS5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgIG5ldyBDdXN0b21FdmVudChcImNsaWNrTXVsdGlCdXR0b25zQnRuXCIsIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICBpdGVtSWQ6IGl0ZW1JZCxcbiAgICAgICAgICAgICAgdHlwZTogdHlwZU5vZGUsXG4gICAgICAgICAgICAgIHBvcyxcbiAgICAgICAgICAgICAgYnV0dG9uOiBpLFxuICAgICAgICAgICAgICBldmVudDogZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgJGVsZW0ucXVlcnlTZWxlY3RvckFsbChcImlucHV0XCIpLmZvckVhY2goKGkpID0+IHtcbiAgICAgIGkuYWRkRXZlbnRMaXN0ZW5lcihcImNoYW5nZVwiLCAoZSkgPT4ge1xuICAgICAgICBsZXQgaW5wdXRUeXBlID0gaS5nZXRBdHRyaWJ1dGUoXCJpbnB1dC10eXBlXCIpO1xuICAgICAgICBsZXQga2V5ID0gaS5nZXRBdHRyaWJ1dGUoXCJpbnB1dC1rZXlcIik7XG4gICAgICAgIGxldCBpdGVtSWQgPSBpLmdldEF0dHJpYnV0ZShcIml0ZW0taWRcIik7XG4gICAgICAgIGxldCB0eXBlTm9kZSA9IGkuZ2V0QXR0cmlidXRlKFwidHlwZS1ub2RlXCIpO1xuICAgICAgICBsZXQgaXRlbSA9IHV0aWxzLmdldEl0ZW1CeUlkKGNvbmZpZywgaXRlbUlkKTtcbiAgICAgICAgbGV0IHZhbHVlID0gaS52YWx1ZTtcbiAgICAgICAgaWYgKGlucHV0VHlwZSA9PSBcInRpbWVcIikge1xuICAgICAgICAgIGxldCBoaF9pbnB1dCA9IGkucGFyZW50RWxlbWVudC5xdWVyeVNlbGVjdG9yKFwiaW5wdXQuaGhcIikudmFsdWU7XG4gICAgICAgICAgbGV0IG1tX2lucHV0ID0gaS5wYXJlbnRFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXCJpbnB1dC5tbVwiKS52YWx1ZTtcbiAgICAgICAgICBtbV9pbnB1dCA9IG1tX2lucHV0IDwgMTAgPyBcIjBcIiArIHBhcnNlRmxvYXQobW1faW5wdXQpIDogbW1faW5wdXQ7XG4gICAgICAgICAgaS5wYXJlbnRFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXCJpbnB1dC5tbVwiKS52YWx1ZSA9IG1tX2lucHV0O1xuICAgICAgICAgIHZhbHVlID0gaGhfaW5wdXQgKyBcIjpcIiArIG1tX2lucHV0O1xuICAgICAgICB9XG4gICAgICAgIGkuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoXCJzYXZlTmF2TGVmdElucHV0XCIsIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgaXRlbUlkOiBpdGVtSWQsXG4gICAgICAgICAgICAgIGl0ZW06IGl0ZW0sXG4gICAgICAgICAgICAgIHR5cGU6IHR5cGVOb2RlLFxuICAgICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICAgIHRhYlNlbGVjdGVkOiB0YWIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgICRlbGVtLnF1ZXJ5U2VsZWN0b3JBbGwoXCJidXR0b24uY2FwLWJ0bi1zaGFwZVwiKS5mb3JFYWNoKChpKSA9PiB7XG4gICAgICBpLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZSkgPT4ge1xuICAgICAgICBsZXQga2V5ID0gaS5nZXRBdHRyaWJ1dGUoXCJpbnB1dC1rZXlcIik7XG4gICAgICAgIGxldCBpdGVtSWQgPSBpLmdldEF0dHJpYnV0ZShcIml0ZW0taWRcIik7XG4gICAgICAgIGxldCB0eXBlTm9kZSA9IGkuZ2V0QXR0cmlidXRlKFwidHlwZS1ub2RlXCIpO1xuICAgICAgICBpLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwiY2xpY2tOYXZMZWZ0QnV0dG9uXCIsIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgaXRlbUlkOiBpdGVtSWQsXG4gICAgICAgICAgICAgIHR5cGU6IHR5cGVOb2RlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAkZWxlbS5xdWVyeVNlbGVjdG9yQWxsKFwiYnV0dG9uLmRldGFpbC1idG5cIikuZm9yRWFjaCgoaSkgPT4ge1xuICAgICAgaS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgbGV0IGl0ZW1JZCA9IGkuZ2V0QXR0cmlidXRlKFwiaXRlbS1pZFwiKTtcbiAgICAgICAgbGV0IHR5cGVOb2RlID0gaS5nZXRBdHRyaWJ1dGUoXCJ0eXBlLW5vZGVcIik7XG4gICAgICAgIGxldCBpdGVtID0gdXRpbHMuZ2V0SXRlbUJ5SWQoY29uZmlnLCBpdGVtSWQsIFwicGFyZW50XCIpO1xuXG4gICAgICAgIGlmIChpdGVtICYmIGl0ZW0ub25DbGlja0RldGFpbEJ1dHRvbikge1xuICAgICAgICAgIGl0ZW0ub25DbGlja0RldGFpbEJ1dHRvbih7XG4gICAgICAgICAgICBpdGVtSWQ6IGl0ZW1JZCxcbiAgICAgICAgICAgIHR5cGU6IHR5cGVOb2RlLFxuICAgICAgICAgICAgaXRlbTogaXRlbSxcbiAgICAgICAgICAgIGV2ZW50OiBlLFxuICAgICAgICAgICAgYnV0dG9uOiBpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgICRlbGVtLnF1ZXJ5U2VsZWN0b3JBbGwoXCJidXR0b24udHJlZS1pY29uXCIpLmZvckVhY2goKGkpID0+IHtcbiAgICAgIGkuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgIGxldCBpdGVtSWQgPSBpLmdldEF0dHJpYnV0ZShcIml0ZW0taWRcIik7XG4gICAgICAgIGxldCB0eXBlTm9kZSA9IGkuZ2V0QXR0cmlidXRlKFwidHlwZS1ub2RlXCIpO1xuICAgICAgICBsZXQgZGF0YUNvbmZpZyA9IGNvbmZpZy5kYXRhLmZpbmQoKGQpID0+IGQuaWQgPT0gaXRlbUlkKTtcblxuICAgICAgICBsZXQgJG5hdkl0ZW0gPSBlLmN1cnJlbnRUYXJnZXQuY2xvc2VzdChcIi5uYXYtaXRlbVwiKTtcbiAgICAgICAgbGV0ICRjaGlsZHJlbiA9ICRuYXZJdGVtLnF1ZXJ5U2VsZWN0b3IoXCIuY2hpbGRyZW4taXRlbXNcIik7XG4gICAgICAgIGxldCBpdGVtc1RvSGlkZSA9IGUuY3VycmVudFRhcmdldFxuICAgICAgICAgIC5jbG9zZXN0KFwibmF2LmxlZnRcIilcbiAgICAgICAgICAucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgICAgIFwiW2NoaWxkPSdcIiArIGl0ZW1JZCArIFwiJ10sIFtjaGlsZC1saXN0PSdcIiArIGl0ZW1JZCArIFwiJ11cIlxuICAgICAgICAgICk7XG5cbiAgICAgICAgaWYgKCRjaGlsZHJlbikge1xuICAgICAgICAgIGlmICgkY2hpbGRyZW4uY2xhc3NMaXN0LmNvbnRhaW5zKFwiaGlkZVwiKSkge1xuICAgICAgICAgICAgZS5jdXJyZW50VGFyZ2V0LmNsYXNzTGlzdC5hZGQoXCJjYXAtcm90YXRlXCIpO1xuICAgICAgICAgICAgaXRlbXNUb0hpZGUuZm9yRWFjaCgoaSkgPT4gaS5jbGFzc0xpc3QucmVtb3ZlKFwiaGlkZVwiKSk7XG4gICAgICAgICAgICBkYXRhQ29uZmlnLmlzQ2xvc2VkID0gZmFsc2U7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGUuY3VycmVudFRhcmdldC5jbGFzc0xpc3QucmVtb3ZlKFwiY2FwLXJvdGF0ZVwiKTtcbiAgICAgICAgICAgIGl0ZW1zVG9IaWRlLmZvckVhY2goKGkpID0+IGkuY2xhc3NMaXN0LmFkZChcImhpZGVcIikpO1xuICAgICAgICAgICAgZGF0YUNvbmZpZy5pc0Nsb3NlZCA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaS5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgIG5ldyBDdXN0b21FdmVudChcImNsaWNrTmF2TGVmdFRyZWVJY29uXCIsIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICBpdGVtSWQ6IGl0ZW1JZCxcbiAgICAgICAgICAgICAgdHlwZTogdHlwZU5vZGUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG5cbiAgICAgICAgLy9lLmN1cnJlbnRUYXJnZXQucGFyZW50XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJldHVybiAkZWxlbTtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBIdG1sIGNvbW8gU3RyaW5nLCBwYXJhIGVsIGRldGFsbGUgZGUgaXRlbXMgZW4gZWwgU2lkZWJhciBJenF1aWVyZG9cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IFtpdGVtPXt9XSAtIENvbmZpZ3VyYWNpb24gZGUgaXRlbVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IEh0bWwgZGUgdmVudGFuYSBkZSBkZXRhbGxlXG4gICAqL1xuICBnZXREZXRhaWxOYXZJdGVtQ29udGVudChpdGVtID0ge30pIHtcbiAgICBpZiAoaXRlbS5uYXZPdmVyID09IHVuZGVmaW5lZCkgaXRlbS5uYXZPdmVyID0ge307XG5cbiAgICByZXR1cm4gYFxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZGVyLWRldGFpbFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWwtdGl0bGUgdHJ1bmNhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICR7aXRlbS5sYWJlbCB8fCBcIlwifVxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWwtc3VidGl0bGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICR7aXRlbS5uYXZPdmVyLnN1YnRpdGxlIHx8IFwiXCJ9XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhlYWRlci1jaGlwICR7XG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtLmxpZ2h0ID8gaXRlbS5saWdodCArIFwiLWxpZ2h0XCIgOiBcIlwiXG4gICAgICAgICAgICAgICAgICAgICAgfSAgJHtpdGVtLm5hdk92ZXIuY2hpcCA/IFwiXCIgOiBcImhpZGVcIn1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICR7aXRlbS5uYXZPdmVyLmNoaXAgfHwgXCJcIn1cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAke2l0ZW0ubmF2T3Zlci5jb250ZW50IHx8IFwiXCJ9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgU2lkZWJhciBEZXJlY2hvXG4gICAqIFVzYWRvIHByaW5jaXBhbG1lbnRlIHBhcmEgZm9ybXVsYXJpbyBkZSBpbmdyZXNvIGRlIGRhdG9zIHBhcmEgbG9zIGRpYXNcbiAgICogc2VsZWNjaW9uYWRvc1xuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gQ29uZmlndXJhY2lvbiBjYXBpYmFyYVxuICAgKiBAcGFyYW0ge09iamVjdH0gdGFiIC0gVGFiIGRlIHJlZmVyZW5jaWEsIHBhcmEgbGEgY3JlYWNpb24gZGVsIGZvcm11bGFyaW9cbiAgICogQHJldHVybiB7T2JqZWN0fSB7ZWxlbWVudCwgaW5wdXRzfSwgZWxlbWVudCBlcyBlbCBlbGVtZW50byBEb20gZGVsIHNpZGViYXIsXG4gICAqICAgICAgICAgICAgICAgICAgaW5wdXRzIGVzIHVuIGFycmF5IGRlIGVsZW1lbnRvcyBEb20gZGUgY2FkYSBpbnB1dCBjcmVhZG9cbiAgICogICAgICAgICAgICAgICAgICAobm8gc29uIGVsZW1lbnRvcyBodG1sIGRlIHRpcG8gaW5wdXQpXG4gICAqL1xuICBjcmVhdGVOYXZSaWdodChjb25maWcsIHRhYiA9IG51bGwpIHtcbiAgICB2YXIgJGVsZW0gPSBkb20uY3JlYXRlRWxlbWVudChcIm5hdlwiLCB7IGNsYXNzTmFtZTogXCJyaWdodFwiIH0pO1xuICAgIHJldHVybiB0aGlzLnJlZHJhd05hdlJpZ2h0KGNvbmZpZywgJGVsZW0sIHRhYiwgbnVsbCwgW10sIG51bGwpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZWNyZWEgU2lkZWJhciBEZXJlY2hvXG4gICAqIFV0aWxpemEgJGVsZW0gY29tbyBlbGVtZW50byBkb20gZG9uZGUgcmVjcmVhcmxvXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgLSBDb25maWd1cmFjaW9uIGNhcGliYXJhXG4gICAqIEBwYXJhbSB7T2JqZWN0fSAkZWxlbSAtIEVsZW1lbnRvIERvbSBkb25kZSBjcmVhIGVsIHNpZGViYXIgZGVyZWNob1xuICAgKiBAcGFyYW0ge09iamVjdH0gdGFiIC0gVGFiIGRlIHJlZmVyZW5jaWEsIHBhcmEgbGEgY3JlYWNpb24gZGVsIGZvcm11bGFyaW9cbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGFEYXkgLSBkYXRvcyBkZWwgZGlhIHNlbGVjY2lvbmFuZG8sIHBhcmEgYXV0b3JyZWxsZW5vIGRlIGZvcm11bGFyaW9cbiAgICogQHBhcmFtIHtPYmplY3R9IGRheVNlbGVjdGVkIC0gZGF0b3MgZGVsIGRpYSBzZWxlY2Npb25hZG9cbiAgICogQHBhcmFtIHtTdHJpbmd9IGRheVNlbGVjdGVkLmRhdGUgLSBmZWNoYSBkZWwgZGlhIHNlbGVjY2lvbmFkb1xuICAgKiBAcGFyYW0ge09iamVjdH0gZGF5U2VsZWN0ZWQuaXRlbSAtIEl0ZW0gZGUgU2lkZWJhciByZWxhY2lvbmFkbyBhbCBkaWEgc2VsZWNjaW9uYWRvXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkYXlTZWxlY3RlZC5wb3MgLSBwb3NpY2lvbiBkZSBkaWEgc2VsZWNjaW9uYWRvXG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tIFNpZGViYXIgRGVyZWNob1xuICAgKi9cbiAgcmVkcmF3TmF2UmlnaHQoXG4gICAgY29uZmlnLFxuICAgICRlbGVtLFxuICAgIHNlbGVjdGVkID0gbnVsbCxcbiAgICB0YWIgPSBudWxsLFxuICAgIGRhdGFEYXkgPSBudWxsLFxuICAgIGRheVNlbGVjdGVkID0gbnVsbFxuICApIHtcbiAgICBsZXQgJG5hdlJpZ2h0ID0gJGVsZW07IC8vZG9tLmNyZWF0ZUVsZW1lbnQoXCJuYXZcIix7Y2xhc3NOYW1lOlwicmlnaHRcIn0pO1xuICAgIGxldCAkZGl2Q29udGFpbmVyID0gZG9tLmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgICAgY2xhc3NOYW1lOiBcIm5hdi1pbnB1dC1jb250YWluZXJcIixcbiAgICB9KTtcbiAgICBsZXQgJGlucHV0cyA9IFtdO1xuICAgIGxldCBjaGVja2JveElucHV0cyA9IFtdO1xuICAgIGxldCBpbnB1dHNXaXRoUmVsb2FkID0gW107XG4gICAgbGV0IHRhYlNlbGVjdGVkID0gdGFiO1xuICAgIHNlbGVjdGVkID0gc2VsZWN0ZWQgfHwgW2RheVNlbGVjdGVkXTtcblxuICAgIGlmICh0YWJTZWxlY3RlZCAmJiB0YWJTZWxlY3RlZC5pbnB1dHMpIHtcbiAgICAgIHRhYlNlbGVjdGVkLmlucHV0cy5mb3JFYWNoKChpKSA9PiB7XG4gICAgICAgIGlmIChpLmRpc2FibGVkKSByZXR1cm47XG4gICAgICAgIGlmIChcbiAgICAgICAgICBpLnNob3dJbnB1dElmICYmXG4gICAgICAgICAgIWkuc2hvd0lucHV0SWYoZGF0YURheSwgZGF5U2VsZWN0ZWQsIHNlbGVjdGVkLCB0YWJTZWxlY3RlZClcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0ICRpbnB1dCA9IHRoaXMuY3JlYXRlSW5wdXQoXG4gICAgICAgICAgaSxcbiAgICAgICAgICBkYXRhRGF5LFxuICAgICAgICAgIGRheVNlbGVjdGVkLFxuICAgICAgICAgIHNlbGVjdGVkLFxuICAgICAgICAgIHRhYlNlbGVjdGVkXG4gICAgICAgICk7XG4gICAgICAgIGlmICgkaW5wdXQpIHtcbiAgICAgICAgICAkZGl2Q29udGFpbmVyLmFwcGVuZENoaWxkKCRpbnB1dCk7XG4gICAgICAgICAgJGlucHV0cy5wdXNoKCRpbnB1dCk7XG5cbiAgICAgICAgICBpZiAoaS50eXBlID09IFwiY2hlY2tib3hcIikge1xuICAgICAgICAgICAgY2hlY2tib3hJbnB1dHMucHVzaCgkaW5wdXQpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChpLnJlbG9hZE9uU2VsZWN0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlucHV0c1dpdGhSZWxvYWQucHVzaCh7ICRpbnB1dCwgY29uZmlnOiBpIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy9tYW5lam8gZGUgZXZlbnRvcyBwYXJhIGlucHV0cyBjb24gc2hvd0lmXG4gICAgaWYgKGNoZWNrYm94SW5wdXRzKSB7XG4gICAgICBjaGVja2JveElucHV0cy5mb3JFYWNoKCgkYykgPT4ge1xuICAgICAgICAvL29idGllbmUga2V5IGRlIGNoZWNrYm94XG4gICAgICAgIGxldCBrZXkgPSAkYy5nZXRBdHRyaWJ1dGUoXCJpbnB1dC1rZXlcIik7XG4gICAgICAgIGxldCBwcm9wcyA9IHRhYlNlbGVjdGVkLmlucHV0cy5maW5kKChpKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGkua2V5ID09IGtleTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbGV0IGlzQ2hlY2tlZCA9IGZhbHNlO1xuICAgICAgICBpZiAoZGF0YURheSkge1xuICAgICAgICAgIGlzQ2hlY2tlZCA9IHV0aWxzLmdldFZhckJ5UGF0aChkYXRhRGF5LCBwcm9wcy52YXJOYW1lKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vb2J0aWVuZSBpbnB1dHMgcmVsYWNpb25hZG9zIGRlc2RlIGNvbmZpZyBwYXJhIG1vc3RyYXIvb2N1bHRhclxuICAgICAgICBsZXQgaW5wdXRzVG9IaWRlID0gdGFiU2VsZWN0ZWQuaW5wdXRzLmZpbHRlcigoaSkgPT4ge1xuICAgICAgICAgIHJldHVybiBpLnNob3dJZiAmJiBpLnNob3dJZiA9PSBrZXk7XG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgaW5wdXRzVG9IaWRlS2V5cyA9IGlucHV0c1RvSGlkZS5tYXAoKGkpID0+IGkua2V5KTtcblxuICAgICAgICAvL29idGllbmUgaW5wdXRzIGRlbCBkb20sIGZpbHRyYW5kbyBjb24gaW5wdXRzVG9IaWRlXG4gICAgICAgIGxldCAkaW5wdXRzSGlkZGVuID0gJGlucHV0cy5maWx0ZXIoKCRpKSA9PiB7XG4gICAgICAgICAgbGV0IGlucHV0S2V5ID0gJGkuZ2V0QXR0cmlidXRlKFwiaW5wdXQta2V5XCIpO1xuICAgICAgICAgIHJldHVybiBpbnB1dHNUb0hpZGVLZXlzLmluZGV4T2YoaW5wdXRLZXkpID4gLTE7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vc2kgaGF5IGlucHV0cyxcbiAgICAgICAgaWYgKCRpbnB1dHNIaWRkZW4pIHtcbiAgICAgICAgICBpZiAoIWlzQ2hlY2tlZCkge1xuICAgICAgICAgICAgJGlucHV0c0hpZGRlbi5mb3JFYWNoKCgkaSkgPT4ge1xuICAgICAgICAgICAgICAkaS5jbGFzc0xpc3QuYWRkKFwiaGlkZVwiKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICAkYy5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIiwgKGUpID0+IHtcbiAgICAgICAgICAgICRpbnB1dHNIaWRkZW4uZm9yRWFjaCgoJGkpID0+IHtcbiAgICAgICAgICAgICAgbGV0IGZuID0gJGMucXVlcnlTZWxlY3RvcihcImlucHV0W3R5cGU9J2NoZWNrYm94J11cIikuY2hlY2tlZFxuICAgICAgICAgICAgICAgID8gXCJyZW1vdmVcIlxuICAgICAgICAgICAgICAgIDogXCJhZGRcIjtcbiAgICAgICAgICAgICAgJGkuY2xhc3NMaXN0W2ZuXShcImhpZGVcIik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbGV0IHNhdmVDYW5jZWxCdG5zID0gdGhpcy5jcmVhdGVOYXZSaWdodGJ1dHRvbnMoY29uZmlnKTtcbiAgICAkZGl2Q29udGFpbmVyLmFwcGVuZENoaWxkKHNhdmVDYW5jZWxCdG5zKTtcbiAgICAkbmF2UmlnaHQuaW5uZXJIVE1MID0gXCJcIjtcbiAgICAkbmF2UmlnaHQuYXBwZW5kQ2hpbGQoJGRpdkNvbnRhaW5lcik7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZWxlbWVudDogJG5hdlJpZ2h0LFxuICAgICAgaW5wdXRzOiAkaW5wdXRzLFxuICAgICAgaW5wdXRzV2l0aFJlbG9hZCxcbiAgICAgIHNhdmVDYW5jZWxCdG5zLFxuICAgIH07XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgQ29ybmVyIGluZmVyaW9yIGl6cXVpZXJkbywgY29tbyB0aXR1bG8gcGFyYSBmb290ZXJcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gQ29ybmVyIEZvb3RlclxuICAgKi9cbiAgY3JlYXRlQ29ybmVyRm9vdGVyKGNvbmZpZykge1xuICAgIGlmIChcbiAgICAgIGNvbmZpZy50aW1lbGluZS5mb290ZXIgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgY29uZmlnLnRpbWVsaW5lLmZvb3Rlci5lbmFibGVkID09IGZhbHNlXG4gICAgKVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgbGV0IHN0ciA9IFwiXCI7XG5cbiAgICBpZiAoY29uZmlnLnRpbWVsaW5lLmZvb3Rlcikge1xuICAgICAgc3RyICs9IGA8ZGl2IGNsYXNzPVwiY29ybmVyLWZvb3RlclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb3JuZXItdGl0bGVcIj5cbiAgICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgICAke2NvbmZpZy50aW1lbGluZS5mb290ZXIubGFiZWx9XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PmA7XG4gICAgfVxuICAgIHJldHVybiBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKHN0cik7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgRm9vdGVyIHBhcmEgcGxhbmlsbGFcbiAgICogSW5pY2lhbG1lbnRlIGNyZWFkbyBwYXJhIHRvdGFsZXNcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gQ29ybmVyIEZvb3RlclxuICAgKi9cbiAgY3JlYXRlRm9vdGVyKGNvbmZpZykge1xuICAgIGlmIChcbiAgICAgIGNvbmZpZy50aW1lbGluZS5mb290ZXIgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgY29uZmlnLnRpbWVsaW5lLmZvb3Rlci5lbmFibGVkID09IGZhbHNlXG4gICAgKVxuICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICBsZXQgc3RyID0gYFxuICAgICAgICA8Zm9vdGVyPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb290ZXItY29udGFpbmVyXCI+XG4gICAgICAgICAgYDtcbiAgICBjb25maWcudGltZWxpbmUuZm9vdGVyLmRhdGEuZm9yRWFjaCgoZCkgPT4ge1xuICAgICAgc3RyICs9IGBcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvb3Rlci1pdGVtXCI+JHtkLnZhbHVlfTwvZGl2PlxuICAgICAgICAgICAgYDtcbiAgICB9KTtcbiAgICBzdHIgKz0gYFxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Zvb3Rlcj5cbiAgICAgICAgYDtcblxuICAgIHJldHVybiBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKHN0cik7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgRm9vdGVyIHBhcmEgcGxhbmlsbGFcbiAgICogSW5pY2lhbG1lbnRlIGNyZWFkbyBwYXJhIHRvdGFsZXNcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHBhcmFtIHtPYmplY3RbXX0gc2VsZWN0ZWQgLSBhcnJheSBkZSBvYmpldG9zLCBkZSBkaWFzIHNlbGVjY2lvbmFkb3NcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gQ29ybmVyIEZvb3RlclxuICAgKi9cbiAgY3JlYXRlU2VsZWN0Qm9hcmQoY29uZmlnLCBzZWxlY3RlZCkge1xuICAgIGxldCAkZWxlbSA9IGRvbS5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsgY2xhc3NOYW1lOiBcInNlbGVjdC1jb250YWluZXJcIiB9KTtcbiAgICByZXR1cm4gdGhpcy5yZWRyYXdTZWxlY3RCb2FyZCgkZWxlbSwgc2VsZWN0ZWQpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhIGxpbmVhIHZlcnRpY2FsIHBhcmEgZmVjaGEgQWN0dWFsXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgLSBDb25maWd1cmFjaW9uIGNhcGliYXJhXG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tIENvcm5lciBGb290ZXJcbiAgICovXG4gIGNyZWF0ZVRvZGF5TGluZShjb25maWcpIHtcbiAgICByZXR1cm4gdGhpcy5yZWRyYXdUb2RheUxpbmUoXG4gICAgICBjb25maWcsXG4gICAgICBkb20uY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJ0b2RheS1saW5lXCIgfSlcbiAgICApO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZWNyZWEgbGluZWEgdmVydGljYWwgcGFyYSBmZWNoYSBBY3R1YWxcbiAgICogc2kgZWwgZWxlbWVudG8gJGVsZW0gbm8gZXMgZW52aWFkbywgc2UgY3JlYSB1biBudWV2byBlbGVtZW50b1xuICAgKlxuICAgKiBTaSBlbCBkaWEgYWN0dWFsIG5vIGVzdGEgZGVudHJvIGRlbCByYW5nbyBkZSBmZWNoYXMgZGVsIGNvbmZpZyxcbiAgICogZGVzaGFiaWxpdGEgbGEgbGluZWEgY29uIGxhIGNsYXNlIGNzcyAuZGlzYWJsZS1saW5lXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgLSBDb25maWd1cmFjaW9uIGNhcGliYXJhXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbJGVsZW09bnVsbF0gLSBFbGVtZW50byBEb20gZG9uZGUgcmVjcmVhIGxhIGxpbmVhLCBzaSBlcyBudWxsLCBsYSBjcmVhXG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tIENvcm5lciBGb290ZXJcbiAgICovXG4gIHJlZHJhd1RvZGF5TGluZShjb25maWcsICRlbGVtID0gbnVsbCkge1xuICAgIGxldCBlbmRUaW1lID0gbmV3IERhdGUoY29uZmlnLnRpbWVsaW5lLmVuZCkuZ2V0VGltZSgpO1xuICAgIGxldCB0b2RheVRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICBsZXQgeyBoZWlnaHQsIGRheVdpZHRoIH0gPSB1dGlscy5nZXRUYWJsZURpbWVuc2lvbnMoY29uZmlnKTtcblxuICAgIGlmICgkZWxlbSA9PSBudWxsKVxuICAgICAgJGVsZW0gPSBkb20uY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJ0b2RheS1saW5lXCIgfSk7XG5cbiAgICBpZiAoZW5kVGltZSA8IHRvZGF5VGltZSkge1xuICAgICAgJGVsZW0uY2xhc3NMaXN0LmFkZChcImRpc2FibGUtbGluZVwiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgJGVsZW0uY2xhc3NMaXN0LnJlbW92ZShcImRpc2FibGUtbGluZVwiKTtcbiAgICB9XG5cbiAgICBsZXQgZGlmZkRheXMgPSBNYXRoLmZsb29yKFxuICAgICAgZGF0ZVV0aWxzLmRpZmZEYXlzKFxuICAgICAgICBjb25maWcudGltZWxpbmUuc3RhcnQsXG4gICAgICAgIGRhdGVVdGlscy5mb3JtYXREYXRlKG5ldyBEYXRlKCkpXG4gICAgICApXG4gICAgKTtcbiAgICBsZXQgZGlmZiA9IGRpZmZEYXlzICogZGF5V2lkdGg7XG4gICAgZGlmZiArPSBkYXlXaWR0aCAvIDIgLSAyOyAvLyBwYXJhIGNlbnRyYXIgbGluZWFcbiAgICBPYmplY3QuYXNzaWduKCRlbGVtLnN0eWxlLCB7XG4gICAgICBcIm1hcmdpbi1sZWZ0XCI6IGRpZmYgKyBcInB4XCIsXG4gICAgICBoZWlnaHQ6IGhlaWdodCArIFwicHhcIixcbiAgICB9KTtcbiAgICByZXR1cm4gJGVsZW07XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgZWxlbWVudG8gRmxvYXRCb3gsIHF1ZSBjb250aWVuZSBsb3MgZGF0b3MgcXVlIHNlIG11ZXN0cmEgZW4gbGEgdGFibGFcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHBhcmFtIHtPYmplY3R9IHRhYiAtIFRhYiBkZSByZWZlcmVuY2lhLCBwYXJhIG1vc3RyYXIgZGF0b3MgY29uZmlndXJhZG9zIHBvciB0YWJcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gQ29ybmVyIEZvb3RlclxuICAgKi9cbiAgY3JlYXRlRmxvYXRCb3goY29uZmlnLCB0YWIpIHtcbiAgICBsZXQgJGNvbnRhaW5lciA9IGRvbS5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICAgIGNsYXNzTmFtZTogXCJmbG9hdC1ib3gtY29udGFpbmVyXCIsXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMucmVkcmF3RmxvYXRCb3goY29uZmlnLCB0YWIsICRjb250YWluZXIpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZWNyZWEgZWxlbWVudG8gRmxvYXRCb3gsIHF1ZSBjb250aWVuZSBsb3MgZGF0b3MgcXVlIHNlIG11ZXN0cmEgZW4gbGEgdGFibGFcbiAgICogU2UgdXNhIHByaW5jaXBhbG1lbnRlIHBhcmEgbW9zdHJhciBkYXRvcyBlbiBsYSB0YWJsYSBkZSBsYSBwbGFuaWxsYVxuICAgKiBsb3MgbXVlc3RyYSBkZSBtYW5lcmEgZmxvdGFudGUsIGNhbGN1bGFuZG8gZWwgVG9wIHkgZWwgTGVmdCBzZWd1biBsYSBwb3NjaW9uXG4gICAqXG4gICAqIFNlIGNvbnNpZGVyYW4gbG9zIGVsZW1lbnRvcyBwYWRyZXMgb2N1bHRvcywgcGFyYSBvY3VsdGFyIGxvcyBkYXRvc1xuICAgKlxuICAgKiBTZSBpbnNlcnRhbiBsb3MgZWxlbWVudG9zIEZsb2F0Qm94LCBjb21vIGVsZW1lbnRvIGNvbiBkYXRvcyBkZSB1biBpdGVtIHkgZGlhIGVzcGVjaWZpY29cbiAgICpcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmFcbiAgICogQHBhcmFtIHtPYmplY3R9IHRhYiAtIFRhYiBkZSByZWZlcmVuY2lhLCBwYXJhIG1vc3RyYXIgZGF0b3MgY29uZmlndXJhZG9zIHBvciB0YWJcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gQ29ybmVyIEZvb3RlclxuICAgKi9cbiAgcmVkcmF3RmxvYXRCb3goY29uZmlnLCB0YWIsICRjb250YWluZXIpIHtcbiAgICAkY29udGFpbmVyLmlubmVySFRNTCA9IFwiXCI7XG4gICAgLy9sZXQgdGFiU2VsZWN0ZWQgPSB0YWIgfHwgbnVsbDtcblxuICAgIGNvbmZpZy5kYXRhLmZvckVhY2goKGRhdGFQYXJlbnQpID0+IHtcbiAgICAgIGlmIChkYXRhUGFyZW50LmlzSGlkZGVuKSByZXR1cm47XG5cbiAgICAgIChkYXRhUGFyZW50LmRhdGEgfHwgW10pLmZvckVhY2goKGRhdGEpID0+IHtcbiAgICAgICAgdGhpcy5jcmVhdGVGbG9hdEJveEl0ZW0oe1xuICAgICAgICAgIGNvbnRhaW5lcjogJGNvbnRhaW5lcixcbiAgICAgICAgICBkYXRhLFxuICAgICAgICAgIGl0ZW06IGRhdGFQYXJlbnQsXG4gICAgICAgICAgaXNDbG9zZWQ6IGRhdGFQYXJlbnQuaXNDbG9zZWQsXG4gICAgICAgICAgdGFiLFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICB0eXBlTm9kZTogXCJwYXJlbnRcIixcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGF0YVBhcmVudC5jaGlsZHJlbi5mb3JFYWNoKChkYXRhQ2hpbGQpID0+IHtcbiAgICAgICAgaWYgKGRhdGFDaGlsZC5pc0hpZGRlbikgcmV0dXJuO1xuXG4gICAgICAgIGRhdGFDaGlsZC5kYXRhLmZvckVhY2goKGRhdGEpID0+IHtcbiAgICAgICAgICB0aGlzLmNyZWF0ZUZsb2F0Qm94SXRlbSh7XG4gICAgICAgICAgICBjb250YWluZXI6ICRjb250YWluZXIsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgaXRlbTogZGF0YUNoaWxkLFxuICAgICAgICAgICAgaXNDbG9zZWQ6IGRhdGFQYXJlbnQuaXNDbG9zZWQsXG4gICAgICAgICAgICB0YWIsXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICB0eXBlTm9kZTogXCJjaGlsZFwiLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuICRjb250YWluZXI7XG4gIH0sXG5cbiAgY3JlYXRlRmxvYXRCb3hJdGVtKHtcbiAgICBjb250YWluZXIsXG4gICAgZGF0YSxcbiAgICBpdGVtLFxuICAgIGlzQ2xvc2VkLFxuICAgIHRhYixcbiAgICBjb25maWcsXG4gICAgdHlwZU5vZGUgPSBcImNoaWxkXCIsXG4gIH0pIHtcbiAgICAvLyBWZXJpZmljYXIgc2kgaGF5IG1lbnNhamVcbiAgICBsZXQgbXNnID0gbnVsbDtcbiAgICBpZiAodGFiLmZsb2F0Qm94ICYmIHRhYi5mbG9hdEJveC5tZXNzYWdlUGF0aCkge1xuICAgICAgbXNnID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGEsIHRhYi5mbG9hdEJveC5tZXNzYWdlUGF0aCk7XG4gICAgfVxuICAgIGNvbnN0IGhhc01lc3NhZ2UgPSBtc2cgfHwgKGRhdGEubWVzc2FnZSAmJiBkYXRhLm1lc3NhZ2UudmFsdWUpO1xuXG4gICAgLy8gVmVyaWZpY2FyIHNpIGhheSBlcnJvcmVzXG4gICAgY29uc3QgaGFzRXJyb3JzID0gZGF0YS5lcnJvcnMgJiYgZGF0YS5lcnJvcnMubGVuZ3RoID4gMDtcblxuICAgIC8vIFZlcmlmaWNhciBzaSBoYXkgY29udGVuaWRvIHZpc2libGUgZW4gZmxvYXRCb3hcbiAgICBsZXQgaGFzVmlzaWJsZUNvbnRlbnQgPSBmYWxzZTtcblxuICAgIGlmIChoYXNNZXNzYWdlIHx8IGhhc0Vycm9ycykge1xuICAgICAgaGFzVmlzaWJsZUNvbnRlbnQgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAoZGF0YS52YWx1ZXMgJiYgdGFiICYmIHRhYi5mbG9hdEJveCkge1xuICAgICAgLy8gVmVyaWZpY2FyIHNpIGhheSBjb250ZW5pZG8gdmlzaWJsZSBlbiBudW1zLCBkb3RzLCBwbG90cywgaWNvbnNcbiAgICAgIGlmICh0YWIuZmxvYXRCb3gubnVtcykge1xuICAgICAgICBoYXNWaXNpYmxlQ29udGVudCA9IHRhYi5mbG9hdEJveC5udW1zLnNvbWUoKG4pID0+IHtcbiAgICAgICAgICBsZXQgdmFsdWUgPSB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YS52YWx1ZXMsIG4udmFyTmFtZSk7XG4gICAgICAgICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybiBmYWxzZTtcbiAgICAgICAgICBcbiAgICAgICAgICBsZXQgc2hvd0lmID0gdHJ1ZTtcbiAgICAgICAgICBsZXQgaGlkZUlmID0gZmFsc2U7XG4gICAgICAgICAgXG4gICAgICAgICAgaWYgKG4udmFyU2hvdykge1xuICAgICAgICAgICAgc2hvd0lmID0gQm9vbGVhbih1dGlscy5nZXRWYXJCeVBhdGgoZGF0YS52YWx1ZXMsIG4udmFyU2hvdykpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAobi52YXJIaWRlKSB7XG4gICAgICAgICAgICBoaWRlSWYgPSBCb29sZWFuKHV0aWxzLmdldFZhckJ5UGF0aChkYXRhLnZhbHVlcywgbi52YXJIaWRlKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChuLmhpZGRlbiA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgaGlkZUlmID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgXG4gICAgICAgICAgcmV0dXJuIHZhbHVlICE9PSBudWxsICYmIHNob3dJZiAmJiAhaGlkZUlmO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFoYXNWaXNpYmxlQ29udGVudCAmJiB0YWIuZmxvYXRCb3guZG90cykge1xuICAgICAgICBoYXNWaXNpYmxlQ29udGVudCA9IHRhYi5mbG9hdEJveC5kb3RzLnNvbWUoKGRvdCkgPT4ge1xuICAgICAgICAgIHJldHVybiB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YS52YWx1ZXMsIGRvdC52YXJOYW1lKSAhPT0gbnVsbDtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghaGFzVmlzaWJsZUNvbnRlbnQgJiYgdGFiLmZsb2F0Qm94LnBsb3RzKSB7XG4gICAgICAgIGhhc1Zpc2libGVDb250ZW50ID0gdGFiLmZsb2F0Qm94LnBsb3RzLnNvbWUoKG4pID0+IHtcbiAgICAgICAgICByZXR1cm4gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGEudmFsdWVzLCBuLnZhck5hbWUpICE9PSBudWxsO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFoYXNWaXNpYmxlQ29udGVudCAmJiB0YWIuZmxvYXRCb3guaWNvbnMpIHtcbiAgICAgICAgaGFzVmlzaWJsZUNvbnRlbnQgPSB0YWIuZmxvYXRCb3guaWNvbnMuc29tZSgoaWNvbkNvbmZpZykgPT4ge1xuICAgICAgICAgIGlmIChpY29uQ29uZmlnLnZhck5hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YS52YWx1ZXMsIGljb25Db25maWcudmFyTmFtZSkgIT09IG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBpY29uQ29uZmlnLmljb24gIT09IG51bGw7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWhhc1Zpc2libGVDb250ZW50ICYmIHRhYi5mbG9hdEJveC5yb3dEb3RzKSB7XG4gICAgICAgIGhhc1Zpc2libGVDb250ZW50ID0gdGFiLmZsb2F0Qm94LnJvd0RvdHMuc29tZSgocm93KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIEFycmF5LmlzQXJyYXkocm93KSAmJiByb3cuc29tZSgoZG90KSA9PiB7XG4gICAgICAgICAgICBsZXQgdmFsdWUgPSB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YS52YWx1ZXMsIGRvdC52YXJOYW1lKTtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGxldCBzaG93SWYgPSB0cnVlO1xuICAgICAgICAgICAgbGV0IGhpZGVJZiA9IGZhbHNlO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiAoZG90LnZhclNob3cpIHtcbiAgICAgICAgICAgICAgc2hvd0lmID0gQm9vbGVhbih1dGlscy5nZXRWYXJCeVBhdGgoZGF0YS52YWx1ZXMsIGRvdC52YXJTaG93KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZG90LnZhckhpZGUpIHtcbiAgICAgICAgICAgICAgaGlkZUlmID0gQm9vbGVhbih1dGlscy5nZXRWYXJCeVBhdGgoZGF0YS52YWx1ZXMsIGRvdC52YXJIaWRlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIHJldHVybiBzaG93SWYgJiYgIWhpZGVJZjtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gU2kgbm8gaGF5IGNvbnRlbmlkbyB2aXNpYmxlLCBubyBjcmVhciBlbCBmbG9hdEJveFxuICAgIGlmICghaGFzVmlzaWJsZUNvbnRlbnQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vY2hpbGRyZW4gRGF0YVxuICAgIGxldCBwb3NpdGlvbiA9IHRoaXMuZ2V0UG9zaXRpb25GbG9hdEJveChjb25maWcsIGRhdGEsIGl0ZW0sIHR5cGVOb2RlKTtcblxuICAgIGxldCBjbGFzc05hbWUgPSBcIlwiO1xuXG4gICAgaWYgKGRhdGEuZXJyb3JzICYmIGRhdGEuZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNsYXNzTmFtZSArPSBcImhhcy1lcnJvcnMgXCI7XG4gICAgICBpZiAoZGF0YS5lcnJvcnNbMF0pIHtcbiAgICAgICAgY2xhc3NOYW1lICs9IGRhdGEuZXJyb3JzWzBdLmNsYXNzTmFtZUljb24gKyBcIiBcIjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNDbG9zZWQpIHtcbiAgICAgIGNsYXNzTmFtZSArPSBcImhpZGUgXCI7XG4gICAgfVxuXG4gICAgaWYgKGhhc01lc3NhZ2UpIHtcbiAgICAgIGNsYXNzTmFtZSArPSBcImhhcy1tZXNzYWdlIFwiO1xuICAgIH1cblxuICAgIGxldCBzdHJNc2cgPSBcIlwiO1xuICAgIGlmIChoYXNNZXNzYWdlKSB7XG4gICAgICBsZXQgdmlld0JveCA9IFwiMCAwIDI0IDI0XCI7XG4gICAgICAvL2VtYWlsIG91dGxpbmUgaWNvblxuICAgICAgbGV0IGljb24gPVxuICAgICAgICBcIk0yMiA2QzIyIDQuOSAyMS4xIDQgMjAgNEg0QzIuOSA0IDIgNC45IDIgNlYxOEMyIDE5LjEgMi45IDIwIDQgMjBIMjBDMjEuMSAyMCAyMiAxOS4xIDIyIDE4VjZNMjAgNkwxMiAxMUw0IDZIMjBNMjAgMThINFY4TDEyIDEzTDIwIDhWMThaXCI7XG5cbiAgICAgIHN0ck1zZyA9IGBcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImljb24tbWVzc2FnZVwiPlxuICAgICAgICAgICAgICAgIDxzdmcgdmlld0JveD1cIiR7dmlld0JveH1cIj5cbiAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCIke2ljb259XCIgLz5cbiAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICBgO1xuICAgIH1cblxuICAgIGxldCBzdHIgPSBgXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsb2F0LWJveCAke2NsYXNzTmFtZX0gXCJcbiAgICAgICAgICAgICAgICAgICAgIHN0eWxlPVwiJHtwb3NpdGlvbiA/IHBvc2l0aW9uIDogXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgaXRlbS1pZD1cIiR7aXRlbS5pZCB8fCAtMX1cIlxuICAgICAgICAgICAgICAgICAgICAgdHlwZS1ub2RlPVwiJHtpdGVtLnR5cGUgfHwgXCJcIn1cIj5cblxuICAgICAgICAgICAgICAgICAgICAgJHtzdHJNc2d9XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxvYXQtYm94LWNvbnRlbnRcIj5gO1xuXG4gICAgbGV0IHN0ckV4dCA9IGBcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxvYXQtYm94LWV4dCAke2lzQ2xvc2VkID8gXCJoaWRlXCIgOiBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCIke3Bvc2l0aW9uID8gcG9zaXRpb24gOiBcIlwifVwiXG4gICAgICAgICAgICAgICAgICAgICAgaXRlbS1pZD1cIiR7aXRlbS5pZCB8fCAtMX0tZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlLW5vZGU9XCIke2l0ZW0udHlwZSB8fCBcIlwifVwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxvbmctYmFyLWNvbnRhaW5lclwiPmA7XG5cbiAgICBpZiAodGFiICYmIHRhYi5mbG9hdEJveCkge1xuICAgICAgaWYgKHRhYi5mbG9hdEJveC5wbG90cykge1xuICAgICAgICBzdHIgKz0gYDxkaXYgY2xhc3M9XCJwbG90LWZsb2F0Ym94LWNvbnRhaW5lclwiPmA7XG4gICAgICAgIHRhYi5mbG9hdEJveC5wbG90cy5mb3JFYWNoKChuKSA9PiB7XG4gICAgICAgICAgbGV0IGNzc1ZhcnMgPSBcIlwiO1xuICAgICAgICAgIGxldCBjbGFzc05hbWUgPSBcIlwiO1xuICAgICAgICAgIGlmICh1dGlscy5nZXRWYXJCeVBhdGgoZGF0YS52YWx1ZXMsIG4udmFyTmFtZSkgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChuLmNvbG9yKSB7XG4gICAgICAgICAgICAgIGNzc1ZhcnMgPSBgLS1sb2NhbC1jb2xvcjoke24uY29sb3J9O2A7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNsYXNzTmFtZSA9IG4uY2xhc3NOYW1lIHx8IFwiXCI7XG5cbiAgICAgICAgICAgIHN0ciArPSBgPGRpdiBjbGFzcz1cInBsb3QtZmxvYXRib3ggJHtjbGFzc05hbWV9ICR7XG4gICAgICAgICAgICAgIG4uc3R5bGUgfHwgXCJcIlxuICAgICAgICAgICAgfVwiIHN0eWxlPVwiJHtjc3NWYXJzfSBcIj48L2Rpdj5gO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHN0ciArPSBgXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgfVxuXG4gICAgICBpZiAodGFiLmZsb2F0Qm94Lmljb25zKSB7XG4gICAgICAgIHRhYi5mbG9hdEJveC5pY29ucy5mb3JFYWNoKChpY29uQ29uZmlnKSA9PiB7XG4gICAgICAgICAgbGV0IGNsYXNzTmFtZSA9IFwiXCI7XG4gICAgICAgICAgbGV0IGNvbG9yQ2xhc3MgPSBcIlwiO1xuICAgICAgICAgIGxldCBjb2xvclN0eWxlID0gXCJcIjtcbiAgICAgICAgICBsZXQgdmlld0JveCA9IFwiMCAwIDI0IDI0XCI7XG4gICAgICAgICAgbGV0IGljb24gPSBpY29uQ29uZmlnLmljb24gfHwgbnVsbDtcblxuICAgICAgICAgIGlmIChpY29uQ29uZmlnLnZhck5hbWUpIHtcbiAgICAgICAgICAgIGxldCBpY29uVmFyID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGEudmFsdWVzLCBpY29uQ29uZmlnLnZhck5hbWUpO1xuICAgICAgICAgICAgaWYgKGljb25WYXIpIHtcbiAgICAgICAgICAgICAgaWNvbiA9IGljb25WYXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGljb25Db25maWcuY2xhc3NOYW1lKSB7XG4gICAgICAgICAgICBjbGFzc05hbWUgPSBpY29uQ29uZmlnLmNsYXNzTmFtZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaWNvbkNvbmZpZy5jb2xvcikge1xuICAgICAgICAgICAgaWYgKHV0aWxzLmlzSGV4Q29sb3IoaWNvbkNvbmZpZy5jb2xvcikpIHtcbiAgICAgICAgICAgICAgY29sb3JTdHlsZSA9IGAtLWxvY2FsLWNvbG9yOiAke2ljb25Db25maWcuY29sb3J9O2A7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb2xvckNsYXNzID0gaWNvbkNvbmZpZy5jb2xvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaWNvbkNvbmZpZy5jb2xvclZhck5hbWUpIHtcbiAgICAgICAgICAgIGxldCBjb2xvclZhciA9IHV0aWxzLmdldFZhckJ5UGF0aChcbiAgICAgICAgICAgICAgZGF0YS52YWx1ZXMsXG4gICAgICAgICAgICAgIGljb25Db25maWcuY29sb3JWYXJOYW1lXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKGNvbG9yVmFyKSB7XG4gICAgICAgICAgICAgIGlmICh1dGlscy5pc0hleENvbG9yKGNvbG9yVmFyKSkge1xuICAgICAgICAgICAgICAgIGNvbG9yU3R5bGUgPSBgLS1sb2NhbC1jb2xvcjogJHtjb2xvclZhcn07YDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb2xvckNsYXNzID0gY29sb3JWYXI7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzdHIgKz0gYFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpY29uLWZsb2F0Ym94ICR7Y2xhc3NOYW1lfSAke1xuICAgICAgICAgICAgICAgICAgY29sb3JDbGFzcyA/IFwiaGFzLWNvbG9yXCIgOiBcIlwiXG4gICAgICAgICAgICAgICAgfVwiIHN0eWxlPVwiJHtjb2xvclN0eWxlfVwiPlxuICAgICAgICAgICAgICAgICAgPHN2ZyB2aWV3Qm94PVwiJHt2aWV3Qm94fVwiPlxuICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiJHtpY29ufVwiIC8+XG4gICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICBgO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy9udW1lcm9zIGVuIGVsIGZsb2F0Qm94XG4gICAgICBpZiAodGFiLmZsb2F0Qm94Lm51bXMpIHtcbiAgICAgICAgdGFiLmZsb2F0Qm94Lm51bXMuZm9yRWFjaCgobikgPT4ge1xuICAgICAgICAgIGlmICh0YWIubGVnZW5kcyAmJiBuLnRhYktleSkge1xuICAgICAgICAgICAgbGV0IGxlZ2VuZCA9IHRhYi5sZWdlbmRzLmZpbmQoKGwpID0+IGwua2V5ID09IG4udGFiS2V5KTtcbiAgICAgICAgICAgIGlmIChsZWdlbmQgJiYgIWxlZ2VuZC5hY3RpdmUpIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBsZXQgZGF0YUZsb2F0Qm94ID0gbnVsbDtcbiAgICAgICAgICBsZXQgY2xhc3NOYW1lID0gXCJcIjtcbiAgICAgICAgICBsZXQgc2hvd0lmID0gdHJ1ZTtcbiAgICAgICAgICBsZXQgaGlkZUlmID0gZmFsc2U7XG4gICAgICAgICAgbGV0IGNvbG9yQ2xhc3MgPSBcIlwiO1xuICAgICAgICAgIGxldCBjb2xvclN0eWxlID0gXCJcIjtcbiAgICAgICAgICBsZXQgY2xhc3NOYW1lc0V4dCA9IFwiXCI7XG4gICAgICAgICAgbGV0IGNvbG9yU3R5bGVFeHQgPSBcIlwiO1xuICAgICAgICAgIGxldCBjc3NWYXJzID0gXCJcIjtcblxuICAgICAgICAgIGlmIChuLnZhck5hbWUpIHtcbiAgICAgICAgICAgIGRhdGFGbG9hdEJveCA9IHV0aWxzLmdldFZhckJ5UGF0aChkYXRhLnZhbHVlcywgbi52YXJOYW1lKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAobi52YXJTaG93KSB7XG4gICAgICAgICAgICBzaG93SWYgPSBCb29sZWFuKHV0aWxzLmdldFZhckJ5UGF0aChkYXRhLnZhbHVlcywgbi52YXJTaG93KSk7XG4gICAgICAgICAgICBkYXRhRmxvYXRCb3ggPSBkYXRhRmxvYXRCb3ggfHwgXCJcIjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAobi52YXJIaWRlKSB7XG4gICAgICAgICAgICBoaWRlSWYgPSBCb29sZWFuKHV0aWxzLmdldFZhckJ5UGF0aChkYXRhLnZhbHVlcywgbi52YXJIaWRlKSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG4uaGlkZGVuID09PSB0cnVlKSB7XG4gICAgICAgICAgICBoaWRlSWYgPSB0cnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChuLnNoYXBlKSB7XG4gICAgICAgICAgICBjbGFzc05hbWUgKz0gXCJzaGFwZS1cIiArIG4uc2hhcGU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG4uY29sb3IpIHtcbiAgICAgICAgICAgIGlmICh1dGlscy5pc0hleENvbG9yKG4uY29sb3IpKSB7XG4gICAgICAgICAgICAgIGNvbG9yU3R5bGUgPSBgLS1sb2NhbC1jb2xvcjogJHtuLmNvbG9yfTtgO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgY29sb3JDbGFzcyA9IG4uY29sb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG4ubG9uZ0Jhcikge1xuICAgICAgICAgICAgbGV0IGxvbmdCYXJDb2xvciA9IFwiXCI7XG4gICAgICAgICAgICBsZXQgbG9uZ0Jhck9wYWNpdHkgPSBcIlwiO1xuXG4gICAgICAgICAgICBpZiAobi5sb25nQmFyQ29sb3IpIHtcbiAgICAgICAgICAgICAgbG9uZ0JhckNvbG9yID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGEudmFsdWVzLCBuLmxvbmdCYXJDb2xvcik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChsb25nQmFyQ29sb3IpIHtcbiAgICAgICAgICAgICAgaWYgKHV0aWxzLmlzSGV4Q29sb3IobG9uZ0JhckNvbG9yKSkge1xuICAgICAgICAgICAgICAgIGNvbG9yU3R5bGVFeHQgPSBgLS1sb2NhbC1jb2xvcjogJHtsb25nQmFyQ29sb3J9O2A7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lc0V4dCArPSBsb25nQmFyQ29sb3IgKyBcIi1saWdodCBcIjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjb2xvckNsYXNzICYmIGNvbG9yQ2xhc3MgIT0gXCJcIikge1xuICAgICAgICAgICAgICBjbGFzc05hbWVzRXh0ICs9IGNvbG9yQ2xhc3M7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNvbG9yU3R5bGUgJiYgY29sb3JTdHlsZSAhPSBcIlwiKSB7XG4gICAgICAgICAgICAgIGNvbG9yU3R5bGVFeHQgPSBjb2xvclN0eWxlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobi5sb25nQmFyT3BhY2l0eSkge1xuICAgICAgICAgICAgICBsb25nQmFyT3BhY2l0eSA9XG4gICAgICAgICAgICAgICAgdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGEudmFsdWVzLCBuLmxvbmdCYXJPcGFjaXR5KSB8fCBudWxsO1xuICAgICAgICAgICAgICBpZiAobG9uZ0Jhck9wYWNpdHkpIHtcbiAgICAgICAgICAgICAgICBjb2xvclN0eWxlRXh0ICs9IFwiLS1sb2NhbC1vcGFjaXR5OiBcIiArIGxvbmdCYXJPcGFjaXR5ICsgXCI7XCI7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG4ubG9uZ0JhckNsYXNzTmFtZSkge1xuICAgICAgICAgICAgICBjbGFzc05hbWVzRXh0ICs9XG4gICAgICAgICAgICAgICAgdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGEudmFsdWVzLCBuLmxvbmdCYXJDbGFzc05hbWUpIHx8IFwiXCI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBsb25nQmFyID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGEudmFsdWVzLCBuLmxvbmdCYXIpO1xuICAgICAgICAgICAgaWYgKGxvbmdCYXIpIHtcbiAgICAgICAgICAgICAgY3NzVmFycyA9IGAtLWxvbmc6JHtsb25nQmFyfTtgO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChkYXRhRmxvYXRCb3ggIT09IG51bGwgJiYgc2hvd0lmICYmICFoaWRlSWYpIHtcbiAgICAgICAgICAgIHN0ciArPSBgPHNwYW4gY2xhc3M9XCJkYXRhICR7Y29sb3JDbGFzc30gJHtjbGFzc05hbWV9XCIgc3R5bGU9XCIke2NvbG9yU3R5bGV9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW9mIGRhdGFGbG9hdEJveCA9PSBcInN0cmluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGRhdGFGbG9hdEJveFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBcIlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlb2YgZGF0YUZsb2F0Qm94ID09IFwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gdXRpbHMucm91bmQoZGF0YUZsb2F0Qm94LCBuLnJvdW5kKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBcIlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5gO1xuXG4gICAgICAgICAgICBpZiAobi5sb25nQmFyICYmIGNzc1ZhcnMpIHtcbiAgICAgICAgICAgICAgc3RyRXh0ICs9IGA8ZGl2IGNsYXNzPVwibG9uZy1iYXIgJHtjbGFzc05hbWVzRXh0fVwiIHN0eWxlPVwiJHtjb2xvclN0eWxlRXh0fSAke2Nzc1ZhcnN9IFwiPjwvZGl2PiBgO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vcHVudG9zIGVuIGVsIGZsb2F0Qm94XG4gICAgICBpZiAodGFiLmZsb2F0Qm94LmRvdHMpIHtcbiAgICAgICAgc3RyICs9IGA8ZGl2IGNsYXNzPVwiZG90LWNvbnRhaW5lci1taWRkbGVcIj5gO1xuICAgICAgICB0YWIuZmxvYXRCb3guZG90cy5mb3JFYWNoKChkb3QpID0+IHtcbiAgICAgICAgICBpZiAodXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGEudmFsdWVzLCBkb3QudmFyTmFtZSkgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGxldCBjbGFzc05hbWUgPSBcIlwiO1xuICAgICAgICAgICAgbGV0IGNvbG9yQ2xhc3MgPSBcIlwiO1xuICAgICAgICAgICAgbGV0IGNvbG9yU3R5bGUgPSBcIlwiO1xuXG4gICAgICAgICAgICBpZiAoZG90LnNoYXBlKSB7XG4gICAgICAgICAgICAgIGNsYXNzTmFtZSArPSBkb3Quc2hhcGU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChkb3QuY29sb3IpIHtcbiAgICAgICAgICAgICAgaWYgKHV0aWxzLmlzSGV4Q29sb3IoZG90LmNvbG9yKSkge1xuICAgICAgICAgICAgICAgIGNvbG9yU3R5bGUgPSBgLS1sb2NhbC1jb2xvcjogJHtkb3QuY29sb3J9YDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb2xvckNsYXNzID0gZG90LmNvbG9yO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN0ciArPSBgXG4gICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkb3QgJHtjb2xvckNsYXNzfSAke2NsYXNzTmFtZX1cIiBzdHlsZT1cIiR7Y29sb3JTdHlsZX1cIiA+PC9kaXY+YDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBzdHIgKz0gYFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgIH1cblxuICAgICAgLy9maWxhIGRlIHB1bnRvcyBlbiBmbG9hdEJveFxuICAgICAgaWYgKHRhYi5mbG9hdEJveC5yb3dEb3RzKSB7XG4gICAgICAgIHRhYi5mbG9hdEJveC5yb3dEb3RzLmZvckVhY2goKHJvdykgPT4ge1xuICAgICAgICAgIGxldCBmcmVlQ29sdW1ucyA9IDQ7XG4gICAgICAgICAgc3RyICs9IGA8c3BhbiBjbGFzcz1cInJvd2RvdC0tcm93IFwiPmA7XG5cbiAgICAgICAgICByb3cuZm9yRWFjaCgoZG90KSA9PiB7XG4gICAgICAgICAgICBpZiAodGFiLmxlZ2VuZHMgJiYgZG90LnRhYktleSkge1xuICAgICAgICAgICAgICBsZXQgbGVnZW5kID0gdGFiLmxlZ2VuZHMuZmluZCgobCkgPT4gbC5rZXkgPT0gZG90LnRhYktleSk7XG4gICAgICAgICAgICAgIGlmIChsZWdlbmQgJiYgIWxlZ2VuZC5hY3RpdmUpIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IGRhdGFGbG9hdEJveCA9IG51bGw7XG4gICAgICAgICAgICBsZXQgY2xhc3NOYW1lID0gXCJcIjtcbiAgICAgICAgICAgIGxldCBzaG93SWYgPSB0cnVlO1xuICAgICAgICAgICAgbGV0IGhpZGVJZiA9IGZhbHNlO1xuICAgICAgICAgICAgbGV0IGNvbG9yQ2xhc3MgPSBcIlwiO1xuICAgICAgICAgICAgbGV0IGNvbG9yU3R5bGUgPSBcIlwiO1xuXG4gICAgICAgICAgICBpZiAoZG90LnZhck5hbWUpIHtcbiAgICAgICAgICAgICAgZGF0YUZsb2F0Qm94ID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGEudmFsdWVzLCBkb3QudmFyTmFtZSk7XG4gICAgICAgICAgICAgIGRhdGFGbG9hdEJveCA9IHBhcnNlSW50KGRhdGFGbG9hdEJveCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChkb3QudmFyU2hvdykge1xuICAgICAgICAgICAgICBzaG93SWYgPSBCb29sZWFuKHV0aWxzLmdldFZhckJ5UGF0aChkYXRhLnZhbHVlcywgZG90LnZhclNob3cpKTtcbiAgICAgICAgICAgICAgZGF0YUZsb2F0Qm94ID0gZGF0YUZsb2F0Qm94IHx8IFwiXCI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChkb3QudmFySGlkZSkge1xuICAgICAgICAgICAgICBoaWRlSWYgPSBCb29sZWFuKHV0aWxzLmdldFZhckJ5UGF0aChkYXRhLnZhbHVlcywgZG90LnZhckhpZGUpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGRvdC5zaGFwZSkge1xuICAgICAgICAgICAgICBjbGFzc05hbWUgKz0gXCIgc2hhcGUtXCIgKyBkb3Quc2hhcGU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChkb3QuY29sb3IpIHtcbiAgICAgICAgICAgICAgaWYgKHV0aWxzLmlzSGV4Q29sb3IoZG90LmNvbG9yKSkge1xuICAgICAgICAgICAgICAgIGNvbG9yU3R5bGUgPSBgLS1sb2NhbC1jb2xvcjogJHtkb3QuY29sb3J9YDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb2xvckNsYXNzID0gZG90LmNvbG9yO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgZGF0YUZsb2F0Qm94ICE9PSBudWxsICYmXG4gICAgICAgICAgICAgIGRhdGFGbG9hdEJveCA+IDAgJiZcbiAgICAgICAgICAgICAgc2hvd0lmICYmXG4gICAgICAgICAgICAgICFoaWRlSWYgJiZcbiAgICAgICAgICAgICAgZnJlZUNvbHVtbnMgPiAwXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgbGV0IG4gPSBkYXRhRmxvYXRCb3ggPiBmcmVlQ29sdW1ucyA/IGZyZWVDb2x1bW5zIDogZGF0YUZsb2F0Qm94O1xuICAgICAgICAgICAgICBmcmVlQ29sdW1ucyAtPSBuO1xuICAgICAgICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgbjsgaW5kZXgrKykge1xuICAgICAgICAgICAgICAgIHN0ciArPSBgPGRpdiBjbGFzcz1cInJvd2RvdC0tZG90ICR7Y29sb3JDbGFzc30gJHtjbGFzc05hbWV9XCIgc3R5bGU9XCIke2NvbG9yU3R5bGV9XCI+PC9kaXY+YDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgc3RyICs9IGA8L3NwYW4+YDtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc3RyICs9IGBcbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgIHN0ckV4dCArPSBgXG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PmA7XG5cbiAgICBsZXQgJGVsZW0gPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKHN0cik7XG5cbiAgICBsZXQgJGVsZW1FeHQgPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKHN0ckV4dCk7XG5cbiAgICAkZWxlbS5hZGRFdmVudExpc3RlbmVyKFwibW91c2VvdmVyXCIsIChlKSA9PiB7XG4gICAgICAkZWxlbS5kaXNwYXRjaEV2ZW50KFxuICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoXCJtb3VzZU92ZXJGbG9hdEJveFwiLCB7XG4gICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIGl0ZW06IGl0ZW0sXG4gICAgICAgICAgICBkYXRhOiBkYXRhLFxuICAgICAgICAgICAgb3JpZ2luYWxFdnQ6IGUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICAkZWxlbS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICRlbGVtLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgIG5ldyBDdXN0b21FdmVudChcImNsaWNrRmxvYXRCb3hcIiwge1xuICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICBpdGVtOiBpdGVtLFxuICAgICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICAgIG9yaWdpbmFsRXZ0OiBlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgY29udGFpbmVyLmFwcGVuZENoaWxkKCRlbGVtKTtcbiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoJGVsZW1FeHQpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhIERldGFpbERheSwgZGV0YWxsZSBkZSB2YWxvcmVzIGRlIGl0ZW0geSBEaWFcbiAgICogc2UgdXNhIHBhcmE6XG4gICAqICAgIC0gTXVlc3RyYSBub21icmUgZGUgaXRlbSB5IGRldGFsbGVzXG4gICAqICAgIC0gTXVlc3RyYSBjYXBzdWxhcyBkZSBkYXRvc1xuICAgKiAgICAtIE11ZXN0cmEgUGlsbHMsIHBpbGRvcmFzIGRlIGRhdG9zIHJlc3VtaWRvc1xuICAgKiAgICAtIE11ZXN0cmEgYWxlcnRhc1xuICAgKiAgICAtIE11ZXN0cmEgTWVuc2FqZVxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gQ29uZmlndXJhY2lvbiBjYXBpYmFyYVxuICAgKiBAcGFyYW0ge09iamVjdH0gaXRlbSAtIEl0ZW0gcmVsYWNpb25hZG9cbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGFEYXkgLSB2YWxvcmVzIGRlIGl0ZW0geSBEaWFcbiAgICogQHBhcmFtIHtCb29sZWFufSBbb25seVN0cmluZ0NvbnRlbnQgPSBmYWxzZV0gLSBwYXJhIGVzY29nZXIgc2kgZGV2dWVsdmUgU3RyaW5nIG8gRG9tRWxlbWVudFxuICAgKiBAcmV0dXJuIHtTdHJpbmd8T2JqZWN0fSBFbGVtZW50byBjb21vIFN0cmluZyBvIERvbUVsZW1lbnRcbiAgICovXG4gIGNyZWF0ZURldGFpbERheShcbiAgICBjb25maWcsXG4gICAgaXRlbSA9IHt9LFxuICAgIGRhdGFEYXksXG4gICAgdGFiU2VsZWN0ZWQsXG4gICAgb25seVN0cmluZ0NvbnRlbnQgPSBmYWxzZVxuICApIHtcbiAgICBsZXQgc3RyID0gYFxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJoZWFkZXItZGV0YWlsXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGl0bGUgdHJ1bmNhdGVcIj5cbiAgICAgICAgICAgICAgJHtpdGVtLmxhYmVsIHx8IFwiXCJ9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdWJ0aXRsZVwiPlxuICAgICAgICAgICAgICAke2RhdGFEYXkgPyBkYXRlVXRpbHMuZm9ybWF0RGF0ZVJlYWRlYWJsZShkYXRhRGF5LmRhdGUpIDogXCJcIn1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImxpc3QtZGV0YWlsIGxpc3QgY29sdW1uLWZsZXhcIj5gO1xuXG4gICAgLy9DQVBTVUxFU1xuICAgIGxldCB2aXNpYmxlSXRlbXNDb3VudCA9IDA7IC8vIENvbnRhZG9yIGRlIGVsZW1lbnRvcyB2aXNpYmxlc1xuXG4gICAgaWYgKGRhdGFEYXkpIHtcbiAgICAgIGNvbmZpZy50aW1lbGluZS5kZXRhaWxEYXkuY2Fwc3VsZXMuZm9yRWFjaCgoY2FwKSA9PiB7XG4gICAgICAgIC8vcGFyYSBjb21wcm9iYXIgc2kgdGllbmUgZGF0b3MsIHNlIG9idGllbmUgZWwgcHJpbWVyIHZhbG9yXG4gICAgICAgIC8vZGUgbGEgbGlzdGEgZGUgdmFsdWVzIGRlIHVuYSBjYXBzdWxhXG4gICAgICAgIGxldCBoYXNWYWx1ZXMgPVxuICAgICAgICAgIGNhcC52YWx1ZXMuZmlsdGVyKCh2KSA9PiB7XG4gICAgICAgICAgICBsZXQgdmFsdWUgPSB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YURheS52YWx1ZXMsIHYudmFyTmFtZSk7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICB2YWx1ZSAhPT0gbnVsbCAmJiAhKEFycmF5LmlzQXJyYXkodmFsdWUpICYmIHZhbHVlLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSkubGVuZ3RoID4gMDtcblxuICAgICAgICBsZXQgaGlkZUlmID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKGNhcC5oaWRlSWYpIHtcbiAgICAgICAgICBoaWRlSWYgPSBCb29sZWFuKHV0aWxzLmdldFZhckJ5UGF0aChkYXRhRGF5LnZhbHVlcywgY2FwLmhpZGVJZikpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNvbG9yQ2xhc3MgPSBcIlwiO1xuICAgICAgICBsZXQgY29sb3JTdHlsZSA9IFwiXCI7XG5cbiAgICAgICAgaWYgKGNhcC5jb2xvcikge1xuICAgICAgICAgIGlmICh1dGlscy5pc0hleENvbG9yKGNhcC5jb2xvcikpIHtcbiAgICAgICAgICAgIGNvbG9yU3R5bGUgPSBgLS1sb2NhbC1jb2xvcjogJHtjYXAuY29sb3J9O2A7XG4gICAgICAgICAgICBjb2xvclN0eWxlICs9IGAtLWxvY2FsLWNvbG9yLWZvbnQ6ICR7Y2FwLmNvbG9yfTtgO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb2xvckNsYXNzID0gY2FwLmNvbG9yO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoaGFzVmFsdWVzICYmICFoaWRlSWYpIHtcbiAgICAgICAgICB2aXNpYmxlSXRlbXNDb3VudCsrOyAvLyBJbmNyZW1lbnRhciBjb250YWRvciBkZSBlbGVtZW50b3MgdmlzaWJsZXNcbiAgICAgICAgICBzdHIgKz0gYFxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbS1kZXRhaWwgJHtjb2xvckNsYXNzfVwiIHN0eWxlPVwiJHtjb2xvclN0eWxlfVwiPlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxlZnQtaWNvbiAke2NhcC5zaGFwZSB8fCBcIlwifSBcIj48L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJuYW1lXCI+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgJHtjYXAudGl0bGUgfHwgXCJcIn1cbiAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuXG4gICAgICAgICAgc3RyICs9IGBcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbS1kZXNjcmlwdGlvblwiPiBgO1xuXG4gICAgICAgICAgY2FwLnZhbHVlcy5mb3JFYWNoKCh2KSA9PiB7XG4gICAgICAgICAgICBsZXQgdmFsdWUgPSB2LnZhck5hbWVcbiAgICAgICAgICAgICAgPyB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YURheS52YWx1ZXMsIHYudmFyTmFtZSlcbiAgICAgICAgICAgICAgOiBudWxsO1xuXG4gICAgICAgICAgICBpZiAoY2FwLmlzTGFiZWxlZEFycmF5KSB7XG4gICAgICAgICAgICAgIHZhbHVlLmZvckVhY2goKHZhbHVlTGFiZWxlZCkgPT4ge1xuICAgICAgICAgICAgICAgIGxldCBvdXRwdXRWYWx1ZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgbGV0IHZhbHVlTmFtZSA9IHYudmFsdWVOYW1lID8gdi52YWx1ZU5hbWUgOiBcInZhbHVlXCI7XG5cbiAgICAgICAgICAgICAgICBsZXQgdGVtcFZhbHVlID0gdXRpbHMuZ2V0VmFyQnlQYXRoKHZhbHVlTGFiZWxlZCwgdmFsdWVOYW1lKTtcblxuICAgICAgICAgICAgICAgIGlmICh0ZW1wVmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgIG91dHB1dFZhbHVlID0gdi5yb3VuZFxuICAgICAgICAgICAgICAgICAgICA/IHV0aWxzLnJvdW5kKHRlbXBWYWx1ZSwgdi5yb3VuZClcbiAgICAgICAgICAgICAgICAgICAgOiB0ZW1wVmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHYuZm9ybWF0dGVyKSB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXRWYWx1ZSA9IHYuZm9ybWF0dGVyKHZhbHVlTGFiZWxlZCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvdXRwdXRWYWx1ZSA9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXRWYWx1ZSA9IHV0aWxzLmZvcm1hdE51bWJlcihvdXRwdXRWYWx1ZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgc3RyICs9XG4gICAgICAgICAgICAgICAgICBvdXRwdXRWYWx1ZSA9PSBudWxsXG4gICAgICAgICAgICAgICAgICAgID8gXCJcIlxuICAgICAgICAgICAgICAgICAgICA6IGBcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGVzYyAke3Yuc2hvd0NvbHVtbiA/IFwiZGVzYy1jb2x1bW5cIiA6IFwiXCJ9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGFiZWxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgJHt2LmhpZGVMYWJlbCA/IFwiXCIgOiB2YWx1ZUxhYmVsZWQubGFiZWx9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2RpdiA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidmFsXCI+YCArXG4gICAgICAgICAgICAgICAgICAgICAgKHYuaGlkZVByZWZmaXggIT09IHRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgID8gYFxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInByZWZpeFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7di5wcmVmaXggfHwgXCJcIn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPmBcbiAgICAgICAgICAgICAgICAgICAgICAgIDogXCJcIikgK1xuICAgICAgICAgICAgICAgICAgICAgIGA8c3BhbiBjbGFzcz1cInZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtvdXRwdXRWYWx1ZX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPmAgK1xuICAgICAgICAgICAgICAgICAgICAgICh2LmhpZGVTdWZmaXggIT09IHRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgID8gYFxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN1ZmZpeFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7dmFsdWVMYWJlbGVkLnN1ZmZpeCB8fCB2LnN1ZmZpeCB8fCBcIlwifVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+YFxuICAgICAgICAgICAgICAgICAgICAgICAgOiBcIlwiKSArXG4gICAgICAgICAgICAgICAgICAgICAgYFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBsZXQgb3V0cHV0VmFsdWUgPSB2LnJvdW5kID8gdXRpbHMucm91bmQodmFsdWUsIHYucm91bmQpIDogdmFsdWU7XG5cbiAgICAgICAgICAgICAgaWYgKHYuZm9ybWF0dGVyKSB7XG4gICAgICAgICAgICAgICAgb3V0cHV0VmFsdWUgPSB2LmZvcm1hdHRlcih7IG9wdGlvbnM6IHYsIGRhdGFEYXksIG91dHB1dFZhbHVlIH0pO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvdXRwdXRWYWx1ZSA9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgb3V0cHV0VmFsdWUgPSB1dGlscy5mb3JtYXROdW1iZXIob3V0cHV0VmFsdWUpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKG91dHB1dFZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc3RyICs9IGBcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRlc2NcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwcmVmaXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke3YucHJlZml4IHx8IFwiXCJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7b3V0cHV0VmFsdWV9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdWZmaXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke3Yuc3VmZml4IHx8IFwiXCJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgc3RyICs9IGBcbiAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuXG4gICAgICAgICAgc3RyICs9IGBcbiAgICAgICAgICAgICAgPC9kaXY+YDsgLy8gZW5kIC5pdGVtLWRldGFpbFxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBBZ3JlZ2FyIGNsYXNlIHNpbmdsZS1pdGVtIHNpIHNvbG8gaGF5IHVuIGVsZW1lbnRvIHZpc2libGVcbiAgICBjb25zdCBjb2x1bW5DbGFzcyA9XG4gICAgICB2aXNpYmxlSXRlbXNDb3VudCA9PT0gMVxuICAgICAgICA/IFwibGlzdCBjb2x1bW4tZmxleCBzaW5nbGUtaXRlbVwiXG4gICAgICAgIDogXCJsaXN0IGNvbHVtbi1mbGV4XCI7XG4gICAgc3RyID0gc3RyLnJlcGxhY2UoXCJsaXN0IGNvbHVtbi1mbGV4XCIsIGNvbHVtbkNsYXNzKTtcblxuICAgIHN0ciArPSBgXG4gICAgICAgIDwvZGl2PmA7IC8vIGxpc3QtZGV0YWlsXG5cbiAgICAvL1BJTExTXG4gICAgaWYgKFxuICAgICAgY29uZmlnLnRpbWVsaW5lLmRldGFpbERheS5waWxsc1Zhck5hbWUgJiZcbiAgICAgIGRhdGFEYXkgJiZcbiAgICAgIGRhdGFEYXkudmFsdWVzW2NvbmZpZy50aW1lbGluZS5kZXRhaWxEYXkucGlsbHNWYXJOYW1lXVxuICAgICkge1xuICAgICAgc3RyICs9IGBcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZWxlbWVudHMtZGV0YWlsXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibmFtZVwiPiAke2NvbmZpZy50aW1lbGluZS5kZXRhaWxEYXkucGlsbHNUaXRsZX0gPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZWxlbWVudHMtbGlzdFwiPmA7XG5cbiAgICAgIGRhdGFEYXkudmFsdWVzW2NvbmZpZy50aW1lbGluZS5kZXRhaWxEYXkucGlsbHNWYXJOYW1lXS5mb3JFYWNoKChlKSA9PiB7XG4gICAgICAgIGxldCB2YWx1ZSA9IGUudmFsdWU7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBvdXRwdXRWYWx1ZSA9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgdmFsdWUgPSB1dGlscy5mb3JtYXROdW1iZXIodmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RyICs9IGBcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJlbGVtZW50LWRldGFpbFwiPlxuICAgICAgICAgICAgICA8Yj4ke2UubGFiZWx9PC9iPlxuICAgICAgICAgICAgICAke3ZhbHVlfVxuICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgIH0pO1xuXG4gICAgICBzdHIgKz0gYFxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5gOyAvL2VuZCAuZWxlbWVudC1kZXRhaWwgPiAuZWxlbWVudC1saXN0XG4gICAgfVxuXG4gICAgLy9zdHIgKz0gYDwvZGl2PmA7XG5cbiAgICBpZiAoZGF0YURheSAmJiBkYXRhRGF5LmVycm9ycyAmJiBkYXRhRGF5LmVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICBkYXRhRGF5LmVycm9ycy5mb3JFYWNoKChlcnIpID0+IHtcbiAgICAgICAgc3RyICs9IGBcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWxlcnRcIj5cbiAgICAgICAgICAgICR7aWNvbnMuYWxlcnR9XG4gICAgICAgICAgICAke2Vyci5sYWJlbH1cbiAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbGV0IG1zZyA9IG51bGw7XG4gICAgbGV0IGF1dGhvciA9IG51bGw7XG4gICAgbGV0IGRhdGVNc2cgPSBudWxsO1xuICAgIGlmIChkYXRhRGF5ICYmIHRhYlNlbGVjdGVkLmZsb2F0Qm94ICYmIHRhYlNlbGVjdGVkLmZsb2F0Qm94Lm1lc3NhZ2VQYXRoKSB7XG4gICAgICBtc2cgPSB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YURheSwgdGFiU2VsZWN0ZWQuZmxvYXRCb3gubWVzc2FnZVBhdGgpO1xuICAgIH1cblxuICAgIGlmICghbXNnICYmIGRhdGFEYXkgJiYgZGF0YURheS5tZXNzYWdlICYmIGRhdGFEYXkubWVzc2FnZS52YWx1ZSkge1xuICAgICAgbXNnID0gZGF0YURheS5tZXNzYWdlLnZhbHVlO1xuICAgICAgYXV0aG9yID0gZGF0YURheS5tZXNzYWdlLmF1dGhvcjtcbiAgICAgIGRhdGVNc2cgPSBkYXRlVXRpbHMuZm9ybWF0RGF0ZVJlYWRlYWJsZShuZXcgRGF0ZShkYXRhRGF5Lm1lc3NhZ2UuZGF0ZSkpO1xuICAgIH1cblxuICAgIGlmIChtc2cpIHtcbiAgICAgIC8vbXNnID0gbXNnLnJlcGxhY2UoLyhcXHJcXG58XFxyfFxcbikvZywgJzxicj4nKTtcbiAgICAgIHN0ciArPSBgXG4gICAgICAgICAgPGRpdiBjbGFzcz1cIm1zai1jb250YWluZXJcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtc2pcIj5cbiAgICAgICAgICAgIDxwcmU+JHttc2cgfHwgXCJcIn08L3ByZT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1zai1kZXRhaWxcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJlbWFpbFwiPiAke2F1dGhvciB8fCBcIlwifSA8L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGF0ZVwiPiAke2RhdGVNc2cgfHwgXCJcIn0gPC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PmA7XG4gICAgfVxuXG4gICAgbGV0IHN0ckNvbnRhaW5lciA9IGA8ZGl2IGNsYXNzPVwiZGV0YWlsLWRheSBkZC1oaWRlXCI+ICR7c3RyfSA8L2Rpdj5gO1xuXG4gICAgaWYgKG9ubHlTdHJpbmdDb250ZW50KSByZXR1cm4gc3RyO1xuXG4gICAgcmV0dXJuIGRvbS5jcmVhdGVFbGVtZW50RnJvbUhUTUwoc3RyQ29udGFpbmVyKTtcbiAgfSxcblxuICAvKipcbiAgICogUmVjcmVhIEhUTUwgZGUgZGV0YWlsRGF5XG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgLSBDb25maWd1cmFjaW9uIGNhcGliYXJhXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBpdGVtIC0gSXRlbSByZWxhY2lvbmFkb1xuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YURheSAtIHZhbG9yZXMgZGUgaXRlbSB5IERpYVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IEVsZW1lbnRvIGNvbW8gU3RyaW5nLCBkZSBkZXRhaWxEYXlcbiAgICovXG4gIHJlZHJhd0RldGFpbERheShjb25maWcsIGl0ZW0sIGRhdGFEYXksIHRhYlNlbGVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlRGV0YWlsRGF5KGNvbmZpZywgaXRlbSwgZGF0YURheSwgdGFiU2VsZWN0ZWQsIHRydWUpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZXBvc2ljaW9uYSBGbG9hdEJveFxuICAgKiB2ZXJpZmljYSBzaSBlbCBwYXJlbnQgZXN0YSBkZXNwbGVnYWRvLCBwYXJhIG9jdWx0YXIgbG9zIGRhdG9zXG4gICAqXG4gICAqIFNvbG8gYWN0dWFsaXphIGxhcyBhbHR1cmFzIGRlIGxvcyBmbG9hdGJveFxuICAgKiBubyByZWNyZWEgbG9zIGZsb2F0Ym94LCBlcyBtYXMgb3B0aW1vXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgLSBDb25maWd1cmFjaW9uIGNhcGliYXJhXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBpdGVtIC0gSXRlbSByZWxhY2lvbmFkb1xuICAgKi9cbiAgcmVwb3NpdGlvbkZsb2F0Qm94KGNvbmZpZywgJGZsb2F0Qm94Q29udGFpbmVyKSB7XG4gICAgJGZsb2F0Qm94Q29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXCIuZmxvYXQtYm94XCIpLmZvckVhY2goKCRmKSA9PiB7XG4gICAgICBsZXQgaXRlbUlkID0gJGYuZ2V0QXR0cmlidXRlKFwiaXRlbS1pZFwiKTtcbiAgICAgIGxldCBpdGVtSGVpZ2h0ID0gcGFyc2VGbG9hdChcbiAgICAgICAgdXRpbHMuZ2V0Q1NTVmFyaWFibGUoY29uZmlnLCBcIi0taXRlbS1oZWlnaHRcIilcbiAgICAgICk7XG4gICAgICBsZXQgaXRlbSwgcGFyZW50O1xuICAgICAgKHsgaXRlbSwgcGFyZW50IH0gPSB1dGlscy5nZXRJdGVtQnlJZChjb25maWcsIGl0ZW1JZCwgXCJjaGlsZFwiLCB0cnVlKSk7XG4gICAgICBpZiAoaXRlbSkge1xuICAgICAgICBsZXQgdG9wID0gdXRpbHMuZ2V0UG9zaXRpb25CeUl0ZW0oY29uZmlnLCBpdGVtKTtcbiAgICAgICAgJGYuc3R5bGUudG9wID0gdG9wICogaXRlbUhlaWdodCArIFwicHhcIjtcbiAgICAgICAgaWYgKHBhcmVudCAmJiBwYXJlbnQuaXNDbG9zZWQpIHtcbiAgICAgICAgICAkZi5jbGFzc0xpc3QuYWRkKFwiaGlkZVwiKTtcbiAgICAgICAgfSBlbHNlIGlmICgkZi5jbGFzc0xpc3QuY29udGFpbnMoXCJoaWRlXCIpKSB7XG4gICAgICAgICAgJGYuY2xhc3NMaXN0LnJlbW92ZShcImhpZGVcIik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfSxcblxuICAvKipcbiAgICogUmVjcmVhIGluZGljYWRvcmVzIGRlIGRpYXMgc2VsZWNjaW9uYWRvc1xuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gJGVsZW0gLSBFbGVtZW50byBEb20gZG9uZGUgY3JlYSBsb3MgZWxlbWVudG9zIHNlbGVjY2lvbmFkb3NcbiAgICogQHBhcmFtIHtPYmplY3RbXX0gc2VsZWN0ZWQgLSBBcnJheSBjb24gbG9zIGRpYXMgc2VsZWNjaW9uYWRvc1xuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBxdWUgY29udGllbmUgbG9zIGluZGljYWRvcmVzIGRlIGRpYXMgc2VsZWNjaW9uYWRvc1xuICAgKi9cbiAgcmVkcmF3U2VsZWN0Qm9hcmQoJGVsZW0sIHNlbGVjdGVkKSB7XG4gICAgJGVsZW0uaW5uZXJIVE1MID0gXCJcIjtcbiAgICBsZXQgaGFzTnVtYmVyID0gdHJ1ZTtcblxuICAgIGlmIChzZWxlY3RlZCkge1xuICAgICAgaWYgKHNlbGVjdGVkLmxlbmd0aCA9PSAxKSBoYXNOdW1iZXIgPSBmYWxzZTtcblxuICAgICAgc2VsZWN0ZWQuZm9yRWFjaCgocykgPT4ge1xuICAgICAgICBsZXQgYXR0cmlidXRlcyA9IFtdO1xuXG4gICAgICAgIGlmIChoYXNOdW1iZXIpIHtcbiAgICAgICAgICBhdHRyaWJ1dGVzLnB1c2goeyBuYW1lOiBcImNhcC1iYWRnZVwiLCB2YWx1ZTogcy5pbmRleCB9KTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgJHMgPSBkb20uY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgICAgICAgY2xhc3NOYW1lOiBcInNlbGVjdGVkLWRheVwiLFxuICAgICAgICAgIGF0dHJpYnV0ZXMsXG4gICAgICAgIH0pO1xuICAgICAgICAkcy5zdHlsZS5sZWZ0ID0gcy5wb3MubGVmdCArIFwicHhcIjtcbiAgICAgICAgJHMuc3R5bGUudG9wID0gcy5wb3MudG9wICsgXCJweFwiO1xuICAgICAgICAkZWxlbS5hcHBlbmQoJHMpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiAkZWxlbTtcbiAgfSxcblxuICAvKipcbiAgICogT2J0aWVuZSBTdHJpbmcgY29uIGVzdGlsb3MgQ1NTIGRlIGxhIHBvc2ljaW9uIGRlIHVuIGZsb2F0Qm94XG4gICAqIGNhbGN1bGFkbyBzZWd1biBpdGVtIHkgZmVjaGEgZGUgbG9zIHZhbG9yZXNcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYWNpb24gY2FwaWJhcmEsIHBhcmEgdmVyIGZlY2hhIGRlIGluaWNpb1xuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YSAtIERhdG9zIGRlbCBkaWEgaW5kaWNhZG9cbiAgICogQHBhcmFtIHtPYmplY3R9IGl0ZW0gLSBJdGVtIHJlbGFjaW9uYWRvXG4gICAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIENTUyB0b3AgeSBsZWZ0ICwgcGFyYSBwb3NpY2lvbmFyIGZsb2F0Qm94IGVuIHRhYmxlXG4gICAqL1xuICBnZXRQb3NpdGlvbkZsb2F0Qm94KGNvbmZpZywgZGF0YSwgaXRlbSwgdHlwZU5vZGUpIHtcbiAgICBsZXQgbGVmdCA9IGRhdGVVdGlscy5kaWZmRGF5cyhjb25maWcudGltZWxpbmUuc3RhcnQsIGRhdGEuZGF0ZSk7XG4gICAgbGV0IHRvcCA9IHV0aWxzLmdldFBvc2l0aW9uQnlJdGVtKGNvbmZpZywgaXRlbSwgdHlwZU5vZGUpO1xuICAgIGxldCBkYXlXaWR0aCA9IHBhcnNlRmxvYXQodXRpbHMuZ2V0Q1NTVmFyaWFibGUoY29uZmlnLCBcIi0tZGF5LXdpZHRoXCIpKTtcbiAgICBsZXQgaXRlbUhlaWdodCA9IHBhcnNlRmxvYXQodXRpbHMuZ2V0Q1NTVmFyaWFibGUoY29uZmlnLCBcIi0taXRlbS1oZWlnaHRcIikpO1xuICAgIGxlZnQgKj0gZGF5V2lkdGg7XG4gICAgdG9wICo9IGl0ZW1IZWlnaHQ7XG4gICAgcmV0dXJuIFwidG9wOiBcIiArIHRvcCArIFwiLjVweDsgbGVmdDpcIiArIGxlZnQgKyBcIi41cHg7XCI7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgQm90b24gY29tbyBlbGVtZW50byBEb21cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHByb3BzIC0gcHJvcGllZGFkZXMgcGFyYSBib3RvblxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcHMuY2xhc3NOYW1lIC0gY2xhc3NlcyBjc3MgcGFyYSBib3RvblxuICAgKiBAcGFyYW0geyp9IHByb3BzLmtleSAtIGtleSBwYXJhIGlkZW50aWZpY2FyIGEgYm90b25cbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BzLmxhYmVsIC0gVGV4dG8gYm90b25cbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gZGVsIGJvdG9uIGNyZWFkb1xuICAgKi9cbiAgY3JlYXRlQnV0dG9uKHByb3BzKSB7XG4gICAgcmV0dXJuIGRvbS5jcmVhdGVFbGVtZW50RnJvbUhUTUwoYFxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cIiR7cHJvcHMuY2xhc3NOYW1lIHx8IFwiXCJ9XCIgaW5wdXQta2V5PVwiJHtcbiAgICAgICAgICAgICAgcHJvcHMua2V5IHx8IFwiXCJcbiAgICAgICAgICAgIH1cIj5cbiAgICAgICAgICAgICAgJHtwcm9wcy5sYWJlbCB8fCBcIlwifVxuICAgICAgICAgICAgPC9idXR0b24+YCk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgQm90b25lcyBkZSBndWFyZGFyIHkgY2FuY2VsYXIgbG9zIGRhdG9zIGRlIGZvcm11bGFyaW8gZGVsIHNpZGViYXIgZGVyZWNob1xuICAgKlxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBkZWwgYm90b25lcyBjcmVhZG9zXG4gICAqL1xuICBjcmVhdGVOYXZSaWdodGJ1dHRvbnMoY29uZmlnKSB7XG4gICAgbGV0IGJ0blNlY3Rpb24gPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKFxuICAgICAgYDxkaXYgY2xhc3M9XCJidXR0b24tc2VjdGlvblwiPjwvZGl2PmBcbiAgICApO1xuICAgIGlmIChcbiAgICAgIGNvbmZpZy50aW1lbGluZS5uYXYucmlnaHQgJiZcbiAgICAgIGNvbmZpZy50aW1lbGluZS5uYXYucmlnaHQuaGlkZVNhdmVCdXR0b24gIT0gdHJ1ZVxuICAgICkge1xuICAgICAgbGV0IHNhdmVCdG4gPSB0aGlzLmNyZWF0ZUJ1dHRvbih7XG4gICAgICAgIGxhYmVsOiBcIkd1YXJkYXJcIixcbiAgICAgICAgY2xhc3NOYW1lOiBcImNhcC1idG4tcmFpc2VkXCIsXG4gICAgICB9KTtcblxuICAgICAgYnRuU2VjdGlvbi5hcHBlbmRDaGlsZChzYXZlQnRuKTtcbiAgICAgIHNhdmVCdG4uYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgIHNhdmVCdG4uZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoXCJzYXZlTXVsdGlJbnB1dFwiLCB7XG4gICAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIGNvbmZpZy50aW1lbGluZS5uYXYucmlnaHQgJiZcbiAgICAgIGNvbmZpZy50aW1lbGluZS5uYXYucmlnaHQuaGlkZUNhbmNlbEJ1dHRvbiAhPSB0cnVlXG4gICAgKSB7XG4gICAgICBjb25zdCBjYW5jZWxMYWJlbEJ1dHRvbiA9XG4gICAgICAgIGNvbmZpZy50aW1lbGluZS5uYXYucmlnaHQuY2FuY2VsTGFiZWxCdXR0b24gfHwgXCJDYW5jZWxhclwiO1xuICAgICAgbGV0IGNhbmNlbEJ0biA9IHRoaXMuY3JlYXRlQnV0dG9uKHtcbiAgICAgICAgbGFiZWw6IGNhbmNlbExhYmVsQnV0dG9uLFxuICAgICAgICBjbGFzc05hbWU6IFwiY2FwLWJ0bi1vdXRsaW5lXCIsXG4gICAgICB9KTtcblxuICAgICAgYnRuU2VjdGlvbi5hcHBlbmRDaGlsZChjYW5jZWxCdG4pO1xuXG4gICAgICBjYW5jZWxCdG4uYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgIGNhbmNlbEJ0bi5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgIG5ldyBDdXN0b21FdmVudChcImNhbmNlbE11bHRpSW5wdXRcIiwge1xuICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgIGNhbmNlbGFibGU6IGZhbHNlLFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gYnRuU2VjdGlvbjtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBJbnB1dCBjb21vIGVsZW1lbnRvIERvbVxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcHMgLSBjb25maWcgcGFyYSBJbnB1dFxuICAgKiBAcGFyYW0ge09iamVjdH0gW2RhdGFEYXkgPSBudWxsXSAtIHZhbG9yZXMgZGUgaXRlbSB5IERpYSwgb3BjaW9uYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IFtkYXlTZWxlY3RlZCA9IG51bGxdIC0gZGF0b3MgZGVsIGRpYSBzZWxlY2Npb25hZG9cbiAgICogQHBhcmFtIHtPYmplY3RbXX0gW3NlbGVjdGVkID0gW11dIC0gYXJyYXkgZGUgb2JqZXRvcywgZGUgZGlhcyBzZWxlY2Npb25hZG9zXG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tIGRlbCBpbnB1dCBjcmVhZG9cbiAgICovXG4gIGNyZWF0ZUlucHV0KFxuICAgIHByb3BzLFxuICAgIGRhdGFEYXkgPSBudWxsLFxuICAgIGRheVNlbGVjdGVkID0gbnVsbCxcbiAgICBzZWxlY3RlZCA9IFtdLFxuICAgIHRhYlNlbGVjdGVkXG4gICkge1xuICAgIGxldCByID0gbnVsbDtcblxuICAgIGlmIChwcm9wcy5pZ25vcmVSZW5kZXIgPT0gdHJ1ZSkgcmV0dXJuIHI7XG5cbiAgICBzd2l0Y2ggKHByb3BzLnR5cGUpIHtcbiAgICAgIGNhc2UgXCJjdXN0b21cIjpcbiAgICAgICAgciA9IHByb3BzLnJlbmRlclxuICAgICAgICAgID8gcHJvcHMucmVuZGVyKHsgcHJvcHMsIGRhdGFEYXksIGRheVNlbGVjdGVkLCBzZWxlY3RlZCB9KVxuICAgICAgICAgIDogbnVsbDtcbiAgICAgICAgci5zZXRBdHRyaWJ1dGUoXCJpbnB1dC1rZXlcIiwgcHJvcHMua2V5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwic2VsZWN0XCI6XG4gICAgICAgIHIgPSB0aGlzLmNyZWF0ZUlucHV0U2VsZWN0KHByb3BzLCBkYXRhRGF5LCBkYXlTZWxlY3RlZCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcImZpbGVcIjpcbiAgICAgICAgciA9IHRoaXMuY3JlYXRlSW5wdXRGaWxlKHByb3BzLCBkYXRhRGF5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiZmlsZUxpbmtcIjpcbiAgICAgICAgciA9IHRoaXMuY3JlYXRlRmlsZUxpbmsocHJvcHMsIGRhdGFEYXkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJ0ZXh0XCI6XG4gICAgICAgIHIgPSB0aGlzLmNyZWF0ZVRleHQocHJvcHMsIHNlbGVjdGVkKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwidGl0bGVcIjpcbiAgICAgICAgciA9IHRoaXMuY3JlYXRlVGl0bGUocHJvcHMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgciA9IHRoaXMuY3JlYXRlSW5wdXROdW1iZXIocHJvcHMsIGRhdGFEYXkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJmbG9hdFwiOlxuICAgICAgICByID0gdGhpcy5jcmVhdGVJbnB1dEZsb2F0KHByb3BzLCBkYXRhRGF5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwibWVzc2FnZVwiOlxuICAgICAgICByID0gdGhpcy5jcmVhdGVJbnB1dE1lc3NhZ2UocHJvcHMsIGRhdGFEYXkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJ0ZXh0YXJlYVwiOlxuICAgICAgICByID0gdGhpcy5jcmVhdGVJbnB1dFRleHRBcmVhKHByb3BzLCBkYXRhRGF5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiY2hlY2tib3hcIjpcbiAgICAgICAgciA9IHRoaXMuY3JlYXRlSW5wdXRDaGVja2JveChwcm9wcywgZGF0YURheSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcImlucHV0TGlzdFwiOlxuICAgICAgICByID0gdGhpcy5jcmVhdGVJbnB1dExpc3QocHJvcHMsIGRhdGFEYXksIGRheVNlbGVjdGVkKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiaW5wdXQtYm94XCI6XG4gICAgICAgIHIgPSB0aGlzLmNyZWF0ZUlucHV0Qm94KHByb3BzLCBkYXRhRGF5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwibGlzdFwiOlxuICAgICAgICByID0gdGhpcy5jcmVhdGVMaXN0KHByb3BzLCBkYXRhRGF5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiZGF0YS1saXN0XCI6XG4gICAgICAgIHIgPSB0aGlzLmNyZWF0ZURhdGFMaXN0KFxuICAgICAgICAgIHByb3BzLFxuICAgICAgICAgIGRhdGFEYXksXG4gICAgICAgICAgZGF5U2VsZWN0ZWQsXG4gICAgICAgICAgc2VsZWN0ZWQsXG4gICAgICAgICAgdGFiU2VsZWN0ZWRcbiAgICAgICAgKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiYnV0dG9uXCI6XG4gICAgICAgIHIgPSB0aGlzLmNyZWF0ZUlucHV0QnV0dG9uKHByb3BzLCBkYXRhRGF5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiYnV0dG9ucy1ncm91cFwiOlxuICAgICAgICByID0gdGhpcy5jcmVhdGVJbnB1dEJ1dHRvbnNHcm91cChwcm9wcywgZGF0YURheSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcInRpbWVcIjpcbiAgICAgICAgciA9IHRoaXMuY3JlYXRlSW5wdXRUaW1lKHByb3BzLCBkYXRhRGF5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiaW5wdXQtdGV4dFwiOlxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgciA9IHRoaXMuY3JlYXRlSW5wdXRUZXh0KHByb3BzLCBkYXRhRGF5KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcjtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBJbnB1dCBjb24gZm9ybWF0byBIb3JhLCBjb21vIGVsZW1lbnRvIERvbVxuICAgKlxuICAgKiBVc2EgMiBpbnB1dHMsIGhvcmEgeSBtaW51dG9zXG4gICAqXG4gICAqIGVsIHZhbHVlIHF1ZSBpbnRlcnByZXRhIGVzIFN0cmluZyBISDpNTVxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcHMgLSBjb25maWcgcGFyYSBJbnB1dFxuICAgKiBAcGFyYW0ge09iamVjdH0gW2RhdGFEYXkgPSBudWxsXSAtIHZhbG9yZXMgZGUgaXRlbSB5IERpYSwgb3BjaW9uYWxcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gZGVsIGlucHV0IGNyZWFkb1xuICAgKi9cbiAgY3JlYXRlSW5wdXRUaW1lKHByb3BzLCBkYXRhRGF5KSB7XG4gICAgbGV0IGhoVmFsdWUgPSBcIlwiO1xuICAgIGxldCBtbVZhbHVlID0gXCJcIjtcblxuICAgIGlmIChkYXRhRGF5ICYmIGRhdGFEYXkudmFsdWVzKSB7XG4gICAgICBsZXQgdmFsdWUgPSB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YURheSwgcHJvcHMudmFyTmFtZSk7XG5cbiAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICB2YWx1ZSA9IHZhbHVlLnNwbGl0KFwiOlwiKTtcbiAgICAgICAgaGhWYWx1ZSA9IHZhbHVlWzBdO1xuICAgICAgICBtbVZhbHVlID0gdmFsdWVbMV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGV0ICRlbGVtID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChgXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXNlY3Rpb24gJHtcbiAgICAgICAgICAgIHByb3BzLmlzSGlkZGVuID8gXCJoaWRlXCIgOiBcIlwiXG4gICAgICAgICAgfSBcIiBpbnB1dC1rZXk9XCIke3Byb3BzLmtleSB8fCBcIlwifVwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXN1YnRpdGxlIGQtYmxvY2tcIj5cbiAgICAgICAgICAgICAgJHtwcm9wcy5sYWJlbCB8fCBcIlwifVxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleFwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGltZVwiPlxuICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImhvdXJcIlxuICAgICAgICAgICAgICAgICAgICAgIGlkPVwidGVzdFwiXG4gICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCIwMFwiXG4gICAgICAgICAgICAgICAgICAgICAgbWluPVwiMFwiXG4gICAgICAgICAgICAgICAgICAgICAgbWF4PVwiOTlcIlxuICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPVwiJHtoaFZhbHVlfVwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3ltYm9sXCI+Ojwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiXG4gICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtaW51dGVzXCJcbiAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIjAwXCJcbiAgICAgICAgICAgICAgICAgICAgICBtaW49XCIwXCJcbiAgICAgICAgICAgICAgICAgICAgICBtYXg9XCI1OVwiXG4gICAgICAgICAgICAgICAgICAgICAgdmFsdWU9XCIke21tVmFsdWV9XCI+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtaGludFwiPlxuICAgICAgICAgICAgICAgICR7cHJvcHMudGV4dEhpbnQgfHwgXCJcIn1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+YCk7XG5cbiAgICBsZXQgJGhoSW5wdXQgPSAkZWxlbS5xdWVyeVNlbGVjdG9yKFwiLmhvdXJcIik7XG4gICAgbGV0ICRtbUlucHV0ID0gJGVsZW0ucXVlcnlTZWxlY3RvcihcIi5taW51dGVzXCIpO1xuXG4gICAgJGhoSW5wdXQuYWRkRXZlbnRMaXN0ZW5lcihcImlucHV0XCIsIChlKSA9PiB7XG4gICAgICAkaGhJbnB1dC5kaXNwYXRjaEV2ZW50KFxuICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoXCJjaGFuZ2VUaW1lSW5wdXRISFwiLCB7XG4gICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIGtleTogcHJvcHMua2V5LFxuICAgICAgICAgICAgdmFsdWU6IGUuc3JjRWxlbWVudC52YWx1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgICRtbUlucHV0LmFkZEV2ZW50TGlzdGVuZXIoXCJpbnB1dFwiLCAoZSkgPT4ge1xuICAgICAgJG1tSW5wdXQuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwiY2hhbmdlVGltZUlucHV0TU1cIiwge1xuICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICBrZXk6IHByb3BzLmtleSxcbiAgICAgICAgICAgIHZhbHVlOiBlLnNyY0VsZW1lbnQudmFsdWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmFkZEtleURvd25JbnB1dEV2ZW50cygkaGhJbnB1dCwgJGVsZW0sIHByb3BzKTtcbiAgICB0aGlzLmFkZEtleURvd25JbnB1dEV2ZW50cygkbW1JbnB1dCwgJGVsZW0sIHByb3BzKTtcblxuICAgIHJldHVybiAkZWxlbTtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBUZXh0IGNvbW8gZWxlbWVudG8gRG9tXG4gICAqIFNlIGNvbmZpZ3VyYSBjb21vIGlucHV0LCBwZXJvIG5vIGRldnVlbHZlIGRhdG9zLCBlcyB1biB0ZXh0b1xuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcHMgLSBjb25maWcgcGFyYSBJbnB1dFxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBkZWwgaW5wdXQgY3JlYWRvXG4gICAqL1xuICBjcmVhdGVUZXh0KHByb3BzLCBzZWxlY3RlZCkge1xuICAgIGxldCBsYWJlbCA9IHByb3BzLmxhYmVsO1xuICAgIGlmIChwcm9wcy5mb3JtYXR0ZXIpIHtcbiAgICAgIGxhYmVsID0gcHJvcHMuZm9ybWF0dGVyKHsgc2VsZWN0ZWQgfSk7XG4gICAgfVxuICAgIGxldCAkZWxlbSA9IGRvbS5jcmVhdGVFbGVtZW50RnJvbUhUTUwoYFxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWN0aW9uICR7cHJvcHMuaXNIaWRkZW4gPyBcImhpZGUgXCIgOiBcIlwifSAke1xuICAgICAgICAgICAgcHJvcHMudG9MZWZ0ID8gXCJ0by1sZWZ0IFwiIDogXCJcIlxuICAgICAgICAgIH0gXCIgaW5wdXQta2V5PVwiJHtwcm9wcy5rZXkgfHwgXCJcIn1cIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiJHtwcm9wcy5jbGFzc05hbWVzIHx8IFwiXCJ9XCI+XG4gICAgICAgICAgICAke2xhYmVsfVxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDwvZGl2PmApO1xuICAgIHJldHVybiAkZWxlbTtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBUaXRsZSBjb21vIGVsZW1lbnRvIERvbVxuICAgKiBTZSBjb25maWd1cmEgY29tbyBpbnB1dCwgcGVybyBubyBkZXZ1ZWx2ZSBkYXRvcywgZXMgdW4gdGV4dG9cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHByb3BzIC0gY29uZmlnIHBhcmEgSW5wdXRcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gZGVsIGlucHV0IGNyZWFkb1xuICAgKi9cbiAgY3JlYXRlVGl0bGUocHJvcHMpIHtcbiAgICBsZXQgY2xhc3NOYW1lcyA9IFwidGV4dC10aXRsZVwiO1xuICAgIGlmIChwcm9wcy5pc1N1YnRpdGxlKSB7XG4gICAgICBjbGFzc05hbWVzID0gXCJ0ZXh0LXN1YnRpdGxlXCI7XG4gICAgfVxuICAgIHJldHVybiBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKGBcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtc2VjdGlvbiAke1xuICAgICAgICAgICAgcHJvcHMuaXNIaWRkZW4gPyBcImhpZGVcIiA6IFwiXCJcbiAgICAgICAgICB9IFwiIGlucHV0LWtleT1cIiR7cHJvcHMua2V5IHx8IFwiXCJ9XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cIiR7Y2xhc3NOYW1lc31cIj5cbiAgICAgICAgICAgICAgJHtwcm9wcy5sYWJlbH1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5gKTtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBJbnB1dCB0aXBvIE51bWVyaWNvIGNvbW8gZWxlbWVudG8gRG9tXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwcm9wcyAtIGNvbmZpZyBwYXJhIElucHV0XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhRGF5IC0gdmFsb3JlcyBkZSBpdGVtIHkgRGlhLCBvcGNpb25hbFxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBkZWwgaW5wdXQgY3JlYWRvXG4gICAqL1xuICBjcmVhdGVJbnB1dE51bWJlcihwcm9wcywgZGF0YURheSkge1xuICAgIGxldCB2YWx1ZSA9IFwiXCI7XG4gICAgaWYgKGRhdGFEYXkgJiYgZGF0YURheS52YWx1ZXMpIHtcbiAgICAgIHZhbHVlID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGFEYXksIHByb3BzLnZhck5hbWUpO1xuICAgIH1cbiAgICB2YWx1ZSA9IHZhbHVlIHx8IFwiXCI7XG5cbiAgICBsZXQgZWxlbSA9IGRvbS5jcmVhdGVFbGVtZW50RnJvbUhUTUwoYFxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWN0aW9uICR7cHJvcHMuY2xhc3NOYW1lcyB8fCBcIlwifSAke1xuICAgICAgICAgICAgcHJvcHMuaXNIaWRkZW4gPyBcImhpZGVcIiA6IFwiXCJcbiAgICAgICAgICB9IFwiIGlucHV0LWtleT1cIiR7cHJvcHMua2V5IHx8IFwiXCJ9XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtc2VjdGlvbi10aXRsZVwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtc3VidGl0bGVcIj5cbiAgICAgICAgICAgICAgICAke3Byb3BzLmxhYmVsfVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1zdWJ0aXRsZS0yIFwiPlxuICAgICAgICAgICAgICAgICR7cHJvcHMuc3VmZml4ID8gXCIoXCIgKyBwcm9wcy5zdWZmaXggKyBcIilcIiA6IFwiXCJ9XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleFwiPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibmF2LWlucHV0XCJcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU9XCIke3ZhbHVlfVwiPlxuXG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1oaW50XCI+XG4gICAgICAgICAgICAgICAgICAke3Byb3BzLnRleHRIaW50IHx8IFwiXCJ9XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PmApO1xuXG4gICAgbGV0IGlucHV0RWxlbSA9IGVsZW0ucXVlcnlTZWxlY3RvcihcImlucHV0XCIpO1xuXG4gICAgdGhpcy5hZGRLZXlEb3duSW5wdXRFdmVudHMoaW5wdXRFbGVtLCBlbGVtLCBwcm9wcyk7XG5cbiAgICByZXR1cm4gZWxlbTtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBJbnB1dCB0aXBvIEZJbGVwaWNrZXIgY29tbyBlbGVtZW50byBEb21cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHByb3BzIC0gY29uZmlnIHBhcmEgSW5wdXRcbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGFEYXkgLSB2YWxvcmVzIGRlIGl0ZW0geSBEaWEsIG9wY2lvbmFsXG4gICAqIEByZXR1cm4ge09iamVjdH0gRWxlbWVudG8gRG9tIGRlbCBpbnB1dCBjcmVhZG9cbiAgICovXG4gIGNyZWF0ZUlucHV0RmlsZShwcm9wcywgZGF0YURheSkge1xuICAgIGxldCB2YWx1ZSA9IFwiXCI7XG4gICAgbGV0IGZpbGVOYW1lID0gXCJcIjtcbiAgICBsZXQgZmlsZVBhdGggPSBcIlwiO1xuXG4gICAgaWYgKGRhdGFEYXkgJiYgZGF0YURheS52YWx1ZXMpIHtcbiAgICAgIHZhbHVlID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGFEYXksIHByb3BzLnZhck5hbWUpO1xuICAgICAgZmlsZU5hbWUgPSB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YURheSwgcHJvcHMuZmlsZU5hbWVWYWx1ZSk7XG4gICAgICBmaWxlUGF0aCA9IHV0aWxzLmdldFZhckJ5UGF0aChkYXRhRGF5LCBwcm9wcy5maWxlUGF0aFZhbHVlKTtcbiAgICB9XG5cbiAgICB2YWx1ZSA9IHZhbHVlIHx8IFwiXCI7XG4gICAgZmlsZU5hbWUgPSBmaWxlTmFtZSB8fCBcIlwiO1xuICAgIGZpbGVQYXRoID0gZmlsZVBhdGggfHwgXCJcIjtcblxuICAgIGxldCBlbGVtID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChgXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXNlY3Rpb24gJHtwcm9wcy5jbGFzc05hbWVzIHx8IFwiXCJ9ICR7XG4gICAgICAgICAgICBwcm9wcy5pc0hpZGRlbiA/IFwiaGlkZVwiIDogXCJcIlxuICAgICAgICAgIH0gXCIgaW5wdXQta2V5PVwiJHtwcm9wcy5rZXkgfHwgXCJcIn1cIj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXNlY3Rpb24tdGl0bGVcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXN1YnRpdGxlXCI+XG4gICAgICAgICAgICAgICAgJHtwcm9wcy5sYWJlbH1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJuYXYtaW5wdXQtZmlsZVwiID5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInNtYWxsLWNsb3NlIGNsZWFyLWZpbGUtaW5wdXRcIj54PC9idXR0b24+XG4gICAgICAgICAgICAgIDxsYWJlbCA+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJuYXYtaW5wdXQtZmlsZS1sYWJlbFwiPlxuICAgICAgICAgICAgICAgICAgJHtwcm9wcy5waWNrZXJMYWJlbCB8fCBcIlNlbGVjY2lvbmFyIEFyY2hpdm9cIn1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJmaWxlXCIgdmFsdWU9XCIke3ZhbHVlfVwiPlxuICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWN0aW9uLWxpbmtcIj5cbiAgICAgICAgICAgICAgPGEgaHJlZj1cIiR7ZmlsZVBhdGh9XCIgdGFyZ2V0PVwiX2JsYW5rXCIgPlxuICAgICAgICAgICAgICAgICR7ZmlsZU5hbWV9XG4gICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPC9kaXY+YCk7XG5cbiAgICBsZXQgJGlucHV0RWxlbSA9IGVsZW0ucXVlcnlTZWxlY3RvcihcImlucHV0XCIpO1xuICAgIGxldCAkY2xlYXJCdG4gPSBlbGVtLnF1ZXJ5U2VsZWN0b3IoXCIuY2xlYXItZmlsZS1pbnB1dFwiKTtcbiAgICBsZXQgJGZpbGVJbnB1dExhYmVsID0gZWxlbS5xdWVyeVNlbGVjdG9yKFwiLm5hdi1pbnB1dC1maWxlLWxhYmVsXCIpO1xuXG4gICAgJGlucHV0RWxlbS5hZGRFdmVudExpc3RlbmVyKFwiY2hhbmdlXCIsIChldnQpID0+IHtcbiAgICAgIGxldCBmaWxlTmFtZSA9ICRpbnB1dEVsZW0uZmlsZXNbMF0ubmFtZTtcbiAgICAgICRmaWxlSW5wdXRMYWJlbC50ZXh0Q29udGVudCA9IGZpbGVOYW1lO1xuICAgIH0pO1xuXG4gICAgJGNsZWFyQnRuLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZXZ0KSA9PiB7XG4gICAgICAkaW5wdXRFbGVtLnZhbHVlID0gXCJcIjtcbiAgICAgICRmaWxlSW5wdXRMYWJlbC50ZXh0Q29udGVudCA9IHByb3BzLnBpY2tlckxhYmVsIHx8IFwiU2VsZWNjaW9uYXIgQXJjaGl2b1wiO1xuICAgICAgZXZ0LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGVsZW07XG4gIH0sXG5cbiAgY3JlYXRlRmlsZUxpbmsocHJvcHMsIGRhdGFEYXkpIHtcbiAgICBsZXQgZmlsZU5hbWUgPSBcIlwiO1xuICAgIGxldCBmaWxlUGF0aCA9IFwiXCI7XG5cbiAgICBpZiAoZGF0YURheSAmJiBkYXRhRGF5LnZhbHVlcykge1xuICAgICAgLy92YWx1ZSA9IHV0aWxzLmdldFZhckJ5UGF0aChkYXRhRGF5LCBwcm9wcy52YXJOYW1lKTtcbiAgICAgIGZpbGVOYW1lID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGFEYXksIHByb3BzLmZpbGVOYW1lVmFsdWUpO1xuICAgICAgZmlsZVBhdGggPSB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YURheSwgcHJvcHMuZmlsZVBhdGhWYWx1ZSk7XG4gICAgfVxuXG4gICAgaWYgKGZpbGVOYW1lID09IFwiXCIpIHJldHVybiBudWxsO1xuXG4gICAgZmlsZU5hbWUgPSBmaWxlTmFtZSB8fCBcIlwiO1xuICAgIGZpbGVQYXRoID0gZmlsZVBhdGggfHwgXCJcIjtcblxuICAgIGxldCBlbGVtID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChgXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXNlY3Rpb24gJHtwcm9wcy5jbGFzc05hbWVzIHx8IFwiXCJ9ICR7XG4gICAgICAgICAgICBwcm9wcy5pc0hpZGRlbiA/IFwiaGlkZVwiIDogXCJcIlxuICAgICAgICAgIH0gXCIgaW5wdXQta2V5PVwiJHtwcm9wcy5rZXkgfHwgXCJcIn1cIj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXNlY3Rpb24tdGl0bGVcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXN1YnRpdGxlXCI+XG4gICAgICAgICAgICAgICAgJHtwcm9wcy5sYWJlbH1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWN0aW9uLWxpbmtcIj5cbiAgICAgICAgICAgICAgPGEgaHJlZj1cIiR7ZmlsZVBhdGh9XCIgdGFyZ2V0PVwiX2JsYW5rXCIgPlxuICAgICAgICAgICAgICAgICR7ZmlsZU5hbWV9XG4gICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPC9kaXY+YCk7XG5cbiAgICByZXR1cm4gZWxlbTtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBsaXN0YSBkZSBJbnB1dHMsIGNvbiBhcnJheSBkZSB2YWxvcmVzLCBjb21vIGVsZW1lbnRvIERvbVxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcHMgLSBjb25maWcgcGFyYSBJbnB1dFxuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YURheSAtIHZhbG9yZXMgZGUgaXRlbSB5IERpYSwgb3BjaW9uYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IFtkYXlTZWxlY3RlZCA9IG51bGxdIC0gZGF0b3MgZGVsIGRpYSBzZWxlY2Npb25hZG9cbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gZGVsIGlucHV0IGNyZWFkb1xuICAgKi9cbiAgY3JlYXRlSW5wdXRMaXN0KHByb3BzLCBkYXRhRGF5LCBkYXlTZWxlY3RlZCA9IG51bGwpIHtcbiAgICBsZXQgaW5wdXRMaXN0ID0gW107XG5cbiAgICAvL29idGllbmUgaW5wdXRzIGRlZmF1bHQsIHBhcmEgY3JlYXJsb3MsIHNpbiB2YWxvcmVzXG4gICAgaWYgKFxuICAgICAgZGF5U2VsZWN0ZWQgJiZcbiAgICAgIEFycmF5LmlzQXJyYXkoZGF5U2VsZWN0ZWQuaXRlbS52YWx1ZXNbcHJvcHMuaW5wdXRMaXN0XSlcbiAgICApIHtcbiAgICAgIGlucHV0TGlzdCA9IGRheVNlbGVjdGVkLml0ZW0udmFsdWVzW3Byb3BzLmlucHV0TGlzdF0ubWFwKChpbnB1dFJvdykgPT4ge1xuICAgICAgICAvL2xpbXBpYSBpbnB1dExpc3QgaW5wdXRzXG4gICAgICAgIGlucHV0Um93LmlucHV0cy5tYXAoKGlucHV0KSA9PiB7XG4gICAgICAgICAgaW5wdXQudmFsdWUgPSBudWxsO1xuICAgICAgICAgIHJldHVybiBpbnB1dDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy9vYnRpZW5lIHZhbG9yZXMgZGVsIGRpYVxuICAgICAgICBpZiAoZGF0YURheSAmJiBkYXRhRGF5LnZhbHVlcykge1xuICAgICAgICAgIGxldCBpbnB1dFZhbHVlcyA9IHV0aWxzLmdldFZhckJ5UGF0aChkYXRhRGF5LCBwcm9wcy52YWx1ZXNQYXRoKTtcblxuICAgICAgICAgIC8vYXV0b3JyZWxsZW5hXG4gICAgICAgICAgaWYgKGlucHV0VmFsdWVzKSB7XG4gICAgICAgICAgICBpbnB1dFJvdy5pbnB1dHMuZm9yRWFjaCgoaW5wdXQpID0+IHtcbiAgICAgICAgICAgICAgbGV0IHZhbHVlcyA9IGlucHV0VmFsdWVzLmZpbmQoKHYpID0+IHYuaWQgPT0gaW5wdXRSb3cuaWQpO1xuICAgICAgICAgICAgICBpbnB1dC52YWx1ZSA9IHZhbHVlcyA/IHZhbHVlc1tpbnB1dC52YXJOYW1lXSA6IG51bGw7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaW5wdXRSb3c7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBsZXQgc3RyID0gYDxkaXYgaW5wdXQta2V5PVwiJHtwcm9wcy5rZXkgfHwgXCJcIn1cIiBjbGFzcz1cImlucHV0LXNlY3Rpb24tbGlzdCAke1xuICAgICAgcHJvcHMuaXNIaWRkZW4gPyBcImhpZGVcIiA6IFwiXCJcbiAgICB9IFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXNlY3Rpb24tdGl0bGVcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXRpdGxlXCI+XG4gICAgICAgICAgICAgICAgJHtwcm9wcy5sYWJlbH1cbiAgICAgICAgICAgICAgPC9zcGFuPiBcbiAgICAgICAgICAgIDwvZGl2PmA7XG4gICAgaW5wdXRMaXN0LmZvckVhY2goKGlucHV0Um93KSA9PiB7XG4gICAgICBzdHIgKz0gYFxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXNlY3Rpb24gJHtcbiAgICAgICAgICAgICAgICAgICAgcHJvcHMudG9SaWdodCA/IFwidG8tcmlnaHRcIiA6IFwiXCJcbiAgICAgICAgICAgICAgICAgIH1cIiA+XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXN1YnRpdGxlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAke2lucHV0Um93LmxhYmVsfVxuICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5gO1xuXG4gICAgICBpbnB1dFJvdy5pbnB1dHMuZm9yRWFjaCgoaW5wdXQpID0+IHtcbiAgICAgICAgc3RyICs9IGAgXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWN0aW9uLWNvbFwiID5cbiAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtc3VidGl0bGUgXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAke2lucHV0LmxhYmVsfVxuICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtaWQ9XCIke2lucHV0Um93LmlkfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtbGFiZWw9XCIke2lucHV0LmxhYmVsfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJuYXYtaW5wdXQgc21hbGxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPVwiJHtpbnB1dC52YWx1ZX1cIj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgIH0pO1xuICAgICAgc3RyICs9IGBcbiAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG4gICAgfSk7XG4gICAgc3RyICs9IGA8L2Rpdj5gO1xuXG4gICAgbGV0IGVsZW0gPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKHN0cik7XG5cbiAgICBsZXQgaW5wdXRzRWxlbSA9IGVsZW0ucXVlcnlTZWxlY3RvckFsbChcImlucHV0XCIpO1xuICAgIGlucHV0c0VsZW0uZm9yRWFjaCgoaW5wdXRFbGVtKSA9PlxuICAgICAgdGhpcy5hZGRLZXlEb3duSW5wdXRFdmVudHMoaW5wdXRFbGVtLCBlbGVtLCBwcm9wcylcbiAgICApO1xuICAgIHJldHVybiBlbGVtO1xuICB9LFxuXG4gIGNyZWF0ZUlucHV0U2VsZWN0KHByb3BzLCBkYXRhRGF5LCBkYXlTZWxlY3RlZCA9IG51bGwpIHtcbiAgICBsZXQgdmFsdWUgPSBudWxsO1xuICAgIGxldCBvcHRpb25zID0gcHJvcHMub3B0aW9ucztcblxuICAgIGlmIChkYXRhRGF5ICYmIGRhdGFEYXkudmFsdWVzKSB7XG4gICAgICBsZXQgdmFsID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGFEYXksIHByb3BzLnZhck5hbWUpO1xuICAgICAgdmFsdWUgPSB2YWwgPyB2YWwudmFsdWUgOiBudWxsO1xuICAgIH1cblxuICAgIGxldCBzdHIgPSBgPGRpdiBpbnB1dC1rZXk9XCIke3Byb3BzLmtleSB8fCBcIlwifVwiIGNsYXNzPVwiJHtcbiAgICAgIHByb3BzLmlzSGlkZGVuID8gXCJoaWRlXCIgOiBcIlwiXG4gICAgfVwiID5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWN0aW9uIFwiID5cbiAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtc3VidGl0bGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICR7cHJvcHMubGFiZWx9XG4gICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuXG4gICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cImlucHV0LXNlbGVjdFwiPlxuXG4gICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIiAke3ZhbHVlID09IG51bGwgPyBcInNlbGVjdGVkXCIgOiBcIlwifT5cbiAgICAgICAgICAgICAgICAgICR7cHJvcHMubm9EYXRhTGFiZWwgfHwgXCItLSBzaW4gYXNpZ25hciAtLVwifVxuICAgICAgICAgICAgICAgICA8L29wdGlvbj5cblxuICAgICAgICBgO1xuXG4gICAgb3B0aW9ucy5mb3JFYWNoKChvcHRpb24pID0+IHtcbiAgICAgIHN0ciArPSBgXG4gICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCIke29wdGlvbi5pZH1cIiAke1xuICAgICAgICAgICAgICAgICAgIG9wdGlvbi5pZCA9PSB2YWx1ZSA/IFwic2VsZWN0ZWRcIiA6IFwiXCJcbiAgICAgICAgICAgICAgICAgfT5cbiAgICAgICAgICAgICAgICAgJHtvcHRpb24ubGFiZWx9XG4gICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIGA7XG4gICAgfSk7XG4gICAgc3RyICs9IGBcblxuICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgIDwvZGl2PmA7XG5cbiAgICBsZXQgZWxlbSA9IGRvbS5jcmVhdGVFbGVtZW50RnJvbUhUTUwoc3RyKTtcblxuICAgIHJldHVybiBlbGVtO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhIElucHV0IGRlIHRleHRvIFRleHRBcmVhIGNvbW8gZWxlbWVudG8gRG9tXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwcm9wcyAtIGNvbmZpZyBwYXJhIElucHV0XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhRGF5IC0gdmFsb3JlcyBkZSBpdGVtIHkgRGlhLCBvcGNpb25hbFxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBkZWwgaW5wdXQgY3JlYWRvXG4gICAqL1xuICBjcmVhdGVJbnB1dFRleHRBcmVhKHByb3BzLCBkYXRhRGF5KSB7XG4gICAgbGV0IHZhbHVlID0gXCJcIjtcbiAgICBpZiAoZGF0YURheSAmJiBkYXRhRGF5LnZhbHVlcykge1xuICAgICAgdmFsdWUgPSB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YURheSwgcHJvcHMudmFyTmFtZSk7XG4gICAgfVxuICAgIGxldCBlbGVtID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChgXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXNlY3Rpb24gJHtcbiAgICAgICAgICAgIHByb3BzLmlzSGlkZGVuID8gXCJoaWRlXCIgOiBcIlwiXG4gICAgICAgICAgfSBcIiBpbnB1dC1rZXk9XCIke3Byb3BzLmtleSB8fCBcIlwifVwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXN1YnRpdGxlIGQtYmxvY2tcIj5cbiAgICAgICAgICAgICAgJHtwcm9wcy5sYWJlbH1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDx0ZXh0YXJlYSBjbGFzcz1cIlwiIHZhbHVlPVwiJHt2YWx1ZX1cIj48L3RleHRhcmVhPlxuICAgICAgICAgIDwvZGl2PmApO1xuXG4gICAgbGV0IGlucHV0RWxlbSA9IGVsZW0ucXVlcnlTZWxlY3RvcihcInRleHRhcmVhXCIpO1xuICAgIHRoaXMuYWRkS2V5RG93bklucHV0RXZlbnRzKGlucHV0RWxlbSwgZWxlbSwgcHJvcHMpO1xuICAgIHJldHVybiBlbGVtO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhIElucHV0IGRlIE1lbnNhamUgY29tbyBlbGVtZW50byBEb21cbiAgICogdXRpbGl6YSBUZXh0QXJlYVxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcHMgLSBjb25maWcgcGFyYSBJbnB1dFxuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YURheSAtIHZhbG9yZXMgZGUgaXRlbSB5IERpYSwgb3BjaW9uYWxcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gZGVsIGlucHV0IGNyZWFkb1xuICAgKi9cbiAgY3JlYXRlSW5wdXRNZXNzYWdlKHByb3BzLCBkYXRhRGF5KSB7XG4gICAgbGV0IHZhbHVlID0gZGF0YURheSA/IHV0aWxzLmdldFZhckJ5UGF0aChkYXRhRGF5LCBwcm9wcy52YXJOYW1lKSA6IG51bGw7XG4gICAgbGV0IGVsZW0gPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKGBcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtc2VjdGlvbiB0by1sZWZ0IG1zai1pbnB1dC1jb250YWluZXIgJHtcbiAgICAgICAgICAgIHByb3BzLmlzSGlkZGVuID8gXCJoaWRlXCIgOiBcIlwiXG4gICAgICAgICAgfSBcIlxuICAgICAgICAgICAgICBpbnB1dC1rZXk9XCIke3Byb3BzLmtleSB8fCBcIlwifVwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXN1YnRpdGxlIGQtYmxvY2tcIj5cbiAgICAgICAgICAgICAgTWVuc2FqZVxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPHRleHRhcmVhIGNsYXNzPVwibXNqXCI+JHt2YWx1ZSB8fCBcIlwifTwvdGV4dGFyZWE+XG4gICAgICAgICAgPC9kaXY+YCk7XG5cbiAgICBsZXQgaW5wdXRFbGVtID0gZWxlbS5xdWVyeVNlbGVjdG9yKFwidGV4dGFyZWFcIik7XG4gICAgLy90aGlzLmFkZEtleURvd25JbnB1dEV2ZW50cyhpbnB1dEVsZW0pO1xuICAgIHJldHVybiBlbGVtO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhIElucHV0IGRlIHRleHRvIGNvbW8gZWxlbWVudG8gRG9tXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwcm9wcyAtIGNvbmZpZyBwYXJhIElucHV0XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhRGF5IC0gdmFsb3JlcyBkZSBpdGVtIHkgRGlhLCBvcGNpb25hbFxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBkZWwgaW5wdXQgY3JlYWRvXG4gICAqL1xuICBjcmVhdGVJbnB1dFRleHQocHJvcHMsIGRhdGFEYXkpIHtcbiAgICBsZXQgdmFsdWUgPSBcIlwiO1xuICAgIGlmIChkYXRhRGF5ICYmIGRhdGFEYXkudmFsdWVzKSB7XG4gICAgICB2YWx1ZSA9IHV0aWxzLmdldFZhckJ5UGF0aChkYXRhRGF5LCBwcm9wcy52YXJOYW1lKTtcbiAgICB9XG4gICAgbGV0IGVsZW0gPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKGBcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtc2VjdGlvbiAke1xuICAgICAgICAgICAgcHJvcHMuaXNIaWRkZW4gPyBcImhpZGVcIiA6IFwiXCJcbiAgICAgICAgICB9IFwiIGlucHV0LWtleT1cIiR7cHJvcHMua2V5IHx8IFwiXCJ9XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtc3VidGl0bGUgZC1ibG9ja1wiPlxuICAgICAgICAgICAgICAke3Byb3BzLmxhYmVsfVxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJuYXYtaW5wdXRcIiB2YWx1ZT1cIiR7dmFsdWV9XCI+XG4gICAgICAgICAgPC9kaXY+YCk7XG5cbiAgICBsZXQgaW5wdXRFbGVtID0gZWxlbS5xdWVyeVNlbGVjdG9yKFwiaW5wdXRcIik7XG4gICAgdGhpcy5hZGRLZXlEb3duSW5wdXRFdmVudHMoaW5wdXRFbGVtLCBlbGVtLCBwcm9wcyk7XG4gICAgcmV0dXJuIGVsZW07XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgSW5wdXQgTnVtZXJvIEZsb3RhbnRlLCBjb21vIGVsZW1lbnRvIERvbVxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcHMgLSBjb25maWcgcGFyYSBJbnB1dFxuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YURheSAtIHZhbG9yZXMgZGUgaXRlbSB5IERpYSwgb3BjaW9uYWxcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gZGVsIGlucHV0IGNyZWFkb1xuICAgKi9cbiAgY3JlYXRlSW5wdXRGbG9hdChwcm9wcywgZGF0YURheSkge1xuICAgIGxldCB2YWx1ZSA9IFwiXCI7XG4gICAgaWYgKGRhdGFEYXkgJiYgZGF0YURheS52YWx1ZXMpIHtcbiAgICAgIHZhbHVlID0gdXRpbHMuZ2V0VmFyQnlQYXRoKGRhdGFEYXksIHByb3BzLnZhck5hbWUpO1xuICAgIH1cbiAgICBsZXQgZWxlbSA9IGRvbS5jcmVhdGVFbGVtZW50RnJvbUhUTUwoYFxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWN0aW9uICR7XG4gICAgICAgICAgICBwcm9wcy5pc0hpZGRlbiA/IFwiaGlkZVwiIDogXCJcIlxuICAgICAgICAgIH0gXCIgaW5wdXQta2V5PVwiJHtwcm9wcy5rZXkgfHwgXCJcIn1cIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1zdWJ0aXRsZSBkLWJsb2NrXCI+XG4gICAgICAgICAgICAgICR7cHJvcHMubGFiZWx9XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIGNsYXNzPVwibmF2LWlucHV0XCIgdmFsdWU9XCIke3ZhbHVlfVwiPlxuICAgICAgICAgIDwvZGl2PmApO1xuXG4gICAgbGV0IGlucHV0RWxlbSA9IGVsZW0ucXVlcnlTZWxlY3RvcihcImlucHV0XCIpO1xuICAgIHRoaXMuYWRkS2V5RG93bklucHV0RXZlbnRzKGlucHV0RWxlbSwgZWxlbSwgcHJvcHMpO1xuICAgIHJldHVybiBlbGVtO1xuICB9LFxuXG4gIGNyZWF0ZURhdGFMaXN0KHByb3BzLCBkYXRhRGF5LCBkYXlTZWxlY3RlZCwgc2VsZWN0ZWQsIHRhYlNlbGVjdGVkKSB7XG4gICAgbGV0IGxpc3QgPSBbXTtcbiAgICBpZiAoZGF0YURheSAmJiBkYXRhRGF5LnZhbHVlcykge1xuICAgICAgbGlzdCA9IHV0aWxzLmdldFZhckJ5UGF0aChkYXRhRGF5LCBwcm9wcy52YXJOYW1lKSB8fCBbXTtcbiAgICB9XG5cbiAgICBsZXQgc2VhcmNoSW5wdXQgPSBwcm9wcy5oaWRlU2VhcmNoXG4gICAgICA/IFwiXCJcbiAgICAgIDogYCA8ZGl2IGNsYXNzPVwic2VhcmNoLWlucHV0LWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgaWQ9XCJcIiB0eXBlPVwidGV4dFwiIG5hbWU9XCJcIiBjbGFzcz1cInNlYXJjaC1pbnB1dFwiIHBsYWNlaG9sZGVyPVwiYnVzY2FyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJzZWFyY2gtaW5wdXQtY2xlYXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgJHtpY29ucy5jbG9zZUljb259XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcblxuICAgIGxldCBlZGl0QnRuID0gXCJcIjtcblxuICAgIGlmIChwcm9wcy5lZGl0QnV0dG9uKSB7XG4gICAgICBlZGl0QnRuID0gYDxidXR0b24gY2xhc3M9XCJjYXAtYnRuLXJhaXNlZCBjYXAtYnRuLXNtIGVkaXQtYnRuXCIgaW5wdXQta2V5PVwiJHtwcm9wcy5lZGl0QnV0dG9uLmtleX1cIj5cbiAgICAgICAgICAgICAgICAgICAgJHtwcm9wcy5lZGl0QnV0dG9uLmxhYmVsfSBcbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPiBgO1xuICAgIH1cblxuICAgIGxldCBzdHIgPSBgXG4gICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtc2VjdGlvbiAke3Byb3BzLmlzSGlkZGVuID8gXCJoaWRlXCIgOiBcIlwifSBcIiBpbnB1dC1rZXk9XCIke1xuICAgICAgICBwcm9wcy5rZXkgfHwgXCJcIlxuICAgICAgfVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtc2VjdGlvbi10aXRsZVwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXN1YnRpdGxlIGQtYmxvY2tcIj5cbiAgICAgICAgICAgICAgICAke3Byb3BzLmxhYmVsfVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICR7ZWRpdEJ0bn1cdFxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWJveCBcIiBpbnB1dC1rZXk9XCIke3Byb3BzLmtleSB8fCBcIlwifVwiPlxuICAgICAgICAgICAgJHtzZWFyY2hJbnB1dH1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj4gYDtcblxuICAgIGxldCAkZWwgPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKHN0cik7XG4gICAgbGV0ICRzZWFyY2hJbnB1dCA9ICRlbC5xdWVyeVNlbGVjdG9yKFwiLnNlYXJjaC1pbnB1dFwiKTtcbiAgICBsZXQgJHNlYXJjaElucHV0Q2xlYXIgPSAkZWwucXVlcnlTZWxlY3RvcihcIi5zZWFyY2gtaW5wdXQtY2xlYXJcIik7XG4gICAgbGV0ICRpbnB1dEJveCA9ICRlbC5xdWVyeVNlbGVjdG9yKFwiLmlucHV0LWJveFwiKTtcblxuICAgIGxldCAkaXRlbXMgPSBsaXN0Lm1hcCgoaXRlbSwgaikgPT4ge1xuICAgICAgbGV0IGxhYmVsID1cbiAgICAgICAgdXRpbHMuZ2V0VmFyQnlQYXRoKGl0ZW0sIHByb3BzLnZhck5hbWVMYWJlbCkgfHwgZGF0YURheS5sYWJlbCB8fCBcIl9fXCI7XG5cbiAgICAgIGxldCAkZWxJdGVtID0gdGhpcy5jcmVhdGVEYXRhTGlzdEl0ZW0oe1xuICAgICAgICBsYWJlbCxcbiAgICAgICAgdmFsdWVUZXh0OiB1dGlscy5nZXRWYXJCeVBhdGgoaXRlbSwgcHJvcHMudmFyTmFtZVZhbHVlVGV4dCkgfHwgXCJcIixcbiAgICAgICAgc3ViVGV4dDogdXRpbHMuZ2V0VmFyQnlQYXRoKGl0ZW0sIHByb3BzLnZhck5hbWVTdWJUZXh0KSB8fCBcIlwiLFxuICAgICAgICBpZDogXCJsaXN0LWl0ZW0tXCIgKyAoZGF0YURheS5pZCB8fCBqKSxcbiAgICAgICAga2V5OiBcImxpc3QtaXRlbS1cIiArIChkYXRhRGF5LmlkIHx8IGopLFxuICAgICAgICB0b29sdGlwOiB1dGlscy5nZXRWYXJCeVBhdGgoaXRlbSwgcHJvcHMudmFyTmFtZVRvb2x0aXApIHx8IGxhYmVsLFxuICAgICAgICAvL2NvbG9ySWNvbjogXCJjLXJlZFwiLFxuICAgICAgICBsaW5rOiB1dGlscy5nZXRWYXJCeVBhdGgoaXRlbSwgcHJvcHMudmFyTmFtZUxpbmspIHx8IG51bGwsXG4gICAgICAgIHN1ZmZpeDogdXRpbHMuZ2V0VmFyQnlQYXRoKGl0ZW0sIHByb3BzLnZhck5hbWVTdWZmaXgpIHx8IFwiXCIsXG4gICAgICAgIC8vdmFsdWU6IEpTT04uc3RyaW5naWZ5KHV0aWxzLmdldFZhckJ5UGF0aChpdGVtLCBwcm9wcy52YXJOYW1lSW5wdXQpKSB8fCB7fVxuICAgICAgfSk7XG4gICAgICAkaW5wdXRCb3guYXBwZW5kQ2hpbGQoJGVsSXRlbSk7XG4gICAgfSk7XG5cbiAgICBpZiAoJHNlYXJjaElucHV0KSB7XG4gICAgICAkc2VhcmNoSW5wdXRDbGVhci5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgJHNlYXJjaElucHV0LnZhbHVlID0gXCJcIjtcbiAgICAgICAgJHNlYXJjaElucHV0LmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwiaW5wdXRcIiwgeyBidWJibGVzOiB0cnVlIH0pKTtcbiAgICAgIH0pO1xuXG4gICAgICAkc2VhcmNoSW5wdXQuYWRkRXZlbnRMaXN0ZW5lcihcImtleWRvd25cIiwgKGUpID0+IHtcbiAgICAgICAgaWYgKGUua2V5ID09PSBcIkVzY2FwZVwiKSB7XG4gICAgICAgICAgJHNlYXJjaElucHV0LnZhbHVlID0gXCJcIjtcbiAgICAgICAgICAkc2VhcmNoSW5wdXQuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJpbnB1dFwiLCB7IGJ1YmJsZXM6IHRydWUgfSkpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgJHNlYXJjaElucHV0LmFkZEV2ZW50TGlzdGVuZXIoXCJpbnB1dFwiLCAoZSkgPT4ge1xuICAgICAgICBsZXQgJGlucHV0cyA9IFtdO1xuICAgICAgICAkaW5wdXRzID0gJGVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCIubWluaS1pbnB1dC1zZWN0aW9uXCIpIHx8IFtdO1xuICAgICAgICAkaW5wdXRzLmZvckVhY2goKCRpKSA9PiB7XG4gICAgICAgICAgbGV0IGxhYmVsID0gJGkuZ2V0QXR0cmlidXRlKFwibGFiZWxcIik7XG4gICAgICAgICAgbGV0IHNlYXJjaCA9ICRzZWFyY2hJbnB1dC52YWx1ZTtcbiAgICAgICAgICBpZiAobGFiZWwudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhzZWFyY2gudG9Mb3dlckNhc2UoKSkpIHtcbiAgICAgICAgICAgICRpLmNsYXNzTGlzdC5yZW1vdmUoXCJoaWRlXCIpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAkaS5jbGFzc0xpc3QuYWRkKFwiaGlkZVwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLmVkaXRCdXR0b24ub25DbGljaykge1xuICAgICAgbGV0IGJ1dHRvbiA9ICRlbC5xdWVyeVNlbGVjdG9yKFwiYnV0dG9uLmVkaXQtYnRuXCIpO1xuICAgICAgaWYgKGJ1dHRvbiAmJiBwcm9wcy5lZGl0QnV0dG9uKSB7XG4gICAgICAgIGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+XG4gICAgICAgICAgcHJvcHMuZWRpdEJ1dHRvbi5vbkNsaWNrKHtcbiAgICAgICAgICAgIGV2ZW50OiBlLFxuICAgICAgICAgICAgcHJvcHMsXG4gICAgICAgICAgICBkYXRhRGF5LFxuICAgICAgICAgICAgZGF5U2VsZWN0ZWQsXG4gICAgICAgICAgICBzZWxlY3RlZCxcbiAgICAgICAgICAgICRlbGVtZW50OiAkZWwsXG4gICAgICAgICAgICB0YWJTZWxlY3RlZCxcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgJGl0ZW1zLmZvckVhY2goKCRpKSA9PiB7XG4gICAgICAgICRlbC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgICBwcm9wcy5lZGl0QnV0dG9uLm9uQ2xpY2soe1xuICAgICAgICAgICAgZXZlbnQ6IGUsXG4gICAgICAgICAgICBwcm9wcyxcbiAgICAgICAgICAgIGRhdGFEYXksXG4gICAgICAgICAgICBkYXlTZWxlY3RlZCxcbiAgICAgICAgICAgIHNlbGVjdGVkLFxuICAgICAgICAgICAgJGVsZW1lbnQ6ICRlbCxcbiAgICAgICAgICAgIHRhYlNlbGVjdGVkLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiAkZWw7XG4gIH0sXG5cbiAgY3JlYXRlRGF0YUxpc3RJdGVtKHtcbiAgICBsYWJlbCA9IFwiXCIsXG4gICAgdmFsdWVUZXh0ID0gXCJcIixcbiAgICBzdWJUZXh0ID0gXCJcIixcbiAgICBpZCA9IFwiXCIsXG4gICAga2V5ID0gXCJcIixcbiAgICB0b29sdGlwID0gXCJcIixcbiAgICBjb2xvckljb24gPSBcIlwiLFxuICAgIGxpbmsgPSBudWxsLFxuICAgIHN1ZmZpeCA9IG51bGwsXG4gICAgdmFsdWUgPSBcIlwiLFxuICB9KSB7XG4gICAgbGV0IHRvb2x0aXBTdHIgPSBcIlwiO1xuICAgIGxldCBpY29uU3RyID0gbnVsbDtcbiAgICBsZXQgbGlua1N0ciA9IFwiXCI7XG4gICAgbGV0IHN0ciA9IFwiXCI7XG5cbiAgICBpZiAodG9vbHRpcCkge1xuICAgICAgdG9vbHRpcFN0ciA9IGBcbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLXRvb2x0aXBcIj5cbiAgICAgICAgICAgICAgICAgICAgJHt0b29sdGlwfVxuICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICB9XG5cbiAgICBpZiAoY29sb3JJY29uKSB7XG4gICAgICBpZiAodXRpbHMuaXNIZXhDb2xvcihpdGVtRm9ybWF0ZWQuY29sb3JJY29uKSkge1xuICAgICAgICBpY29uU3RyID0gYDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLWljb25cIiBzdHlsZT1cImJhY2tncm91bmQ6JHtjb2xvckljb259XCI+IDwvZGl2PmA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpY29uU3RyID0gYDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLWljb24gJHtjb2xvckljb259XCI+IDwvZGl2PmA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGxpbmspIHtcbiAgICAgIGxpbmtTdHIgPSBgPGEgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLWxpbmtcIiB0YXJnZXQ9XCJfYmxhbmtcIiBocmVmPVwiJHtsaW5rfVwiPiR7aWNvbnMubGlua0ljb259PC9hPiBgO1xuICAgIH1cblxuICAgIHN0ciArPSBgXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uIGNsaWNrZWFibGUgJHtcbiAgICAgICAgICAgICAgaWNvblN0ciA/IFwiaGFzLWljb25cIiA6IFwiXCJcbiAgICAgICAgICAgIH0gXCIgXG4gICAgICAgICAgICAgICAgbGFiZWw9XCIke2xhYmVsfVwiIFxuICAgICAgICAgICAgICAgIGRhdGEtaWQ9XCIke2lkfVwiXG4gICAgICAgICAgICAgICAgZGF0YS1rZXk9XCIke2tleX1cIlxuICAgICAgICAgICAgICAgIGRhdGEtdmFsdWU9XCIke3ZhbHVlIHx8IFwiXCJ9XCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxsYWJlbD5cbiAgICAgICAgICAgICAgICAke2ljb25TdHIgfHwgXCJcIn1cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLXRpdGxlc1wiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbi0tdGl0bGUgdHJ1bmNhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgJHtsYWJlbH1cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbi0tc3VidGl0bGUgdHJ1bmNhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgJHtzdWJUZXh0fVxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS1jb250ZW50XCIgPlxuICAgICAgICAgICAgICAgICAgJHt2YWx1ZVRleHR9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbi0tc3VmZml4XCIgPlxuICAgICAgICAgICAgICAgICAgJHtzdWZmaXh9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAke2xpbmtTdHJ9XG5cbiAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgJHt0b29sdGlwU3RyfVxuICAgICAgICAgICAgPC9kaXY+YDtcbiAgICByZXR1cm4gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChzdHIpO1xuICB9LFxuXG4gIGNyZWF0ZUxpc3QocHJvcHMsIGRhdGFEYXkpIHtcbiAgICBsZXQgdGFic0NvbnRhaW5lciA9IFwiXCI7XG5cbiAgICBpZiAocHJvcHMudGFicykge1xuICAgICAgbGV0IHRhYnMgPSBcIlwiO1xuICAgICAgcHJvcHMudGFicy5mb3JFYWNoKCh0YWIpID0+IHtcbiAgICAgICAgdGFicyArPSBgXG4gICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ib3gtdGFiXCIgdGFiLWtleT1cIiR7dGFiLmtleX1cIj5cbiAgICAgICAgICAke3RhYi5uYW1lfVxuICAgICAgICA8L2Rpdj5gO1xuICAgICAgfSk7XG5cbiAgICAgIHRhYnNDb250YWluZXIgPSBgXG4gICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ib3gtdGFiLWNvbnRhaW5lclwiPlxuICAgICAgICAke3RhYnN9XG4gICAgICAgIDwvZGl2PlxuICAgICAgYDtcbiAgICB9XG5cbiAgICBsZXQgc2VhcmNoSW5wdXQgPSBgXG4gICAgICA8ZGl2IGNsYXNzPVwic2VhcmNoLWlucHV0LWNvbnRhaW5lclwiPlxuICAgICAgICA8aW5wdXQgaWQ9XCJcIiB0eXBlPVwidGV4dFwiIG5hbWU9XCJcIiBjbGFzcz1cInNlYXJjaC1pbnB1dFwiIHBsYWNlaG9sZGVyPVwiYnVzY2FyXCI+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJzZWFyY2gtaW5wdXQtY2xlYXJcIj5cbiAgICAgICAgICR7aWNvbnMuY2xvc2VJY29ufVxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIGA7XG5cbiAgICBsZXQgc3RyID0gYFxuICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXNlY3Rpb24gJHtwcm9wcy5pc0hpZGRlbiA/IFwiaGlkZVwiIDogXCJcIn0gXCIgaW5wdXQta2V5PVwiJHtcbiAgICAgICAgcHJvcHMua2V5IHx8IFwiXCJcbiAgICAgIH1cIj5cbiAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXN1YnRpdGxlIGQtYmxvY2tcIj5cbiAgICAgICAgICAgICAgJHtwcm9wcy5sYWJlbH1cbiAgICAgICAgICAgIDwvc3Bhbj5cblxuICAgICAgICAgICAgJHt0YWJzQ29udGFpbmVyfVxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtYm94IFwiIGlucHV0LWtleT1cIiR7cHJvcHMua2V5IHx8IFwiXCJ9XCI+XG5cbiAgICAgICAgICAgICR7c2VhcmNoSW5wdXR9XG4gICAgICBgO1xuXG4gICAgLy9UT0RPIG9idGVuZXIgaW5wdXQgc2VndW4gZmlsYVxuICAgIGlmIChwcm9wcy5pbnB1dHMpIHtcbiAgICAgIHByb3BzLmlucHV0cy5mb3JFYWNoKChpKSA9PiB7XG4gICAgICAgIGlmIChpLmlzVGl0bGUpIHtcbiAgICAgICAgICBsZXQgdG9vbHRpcCA9IFwiXCI7XG4gICAgICAgICAgbGV0IGljb24gPSBudWxsO1xuXG4gICAgICAgICAgaWYgKGkudG9vbHRpcCkge1xuICAgICAgICAgICAgdG9vbHRpcCA9IGBcbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLXRvb2x0aXBcIj5cbiAgICAgICAgICAgICAgICAgICAgJHtpLnRvb2x0aXB9XG4gICAgICAgICAgICAgICAgICAgICR7aS5zdWZmaXggPyBcIihcIiArIGkuc3VmZml4ICsgXCIpXCIgOiBcIlwifVxuICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaS5jb2xvckljb24pIHtcbiAgICAgICAgICAgIGlmICh1dGlscy5pc0hleENvbG9yKGkuY29sb3JJY29uKSkge1xuICAgICAgICAgICAgICBpY29uID0gYDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLWljb25cIiBzdHlsZT1cImJhY2tncm91bmQ6JHtpLmNvbG9ySWNvbn1cIj4gPC9kaXY+YDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGljb24gPSBgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbi0taWNvbiAke2kuY29sb3JJY29ufVwiPiA8L2Rpdj5gO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHN0ciArPSBgXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uIGlzLXRpdGxlICAke1xuICAgICAgICAgICAgICBpY29uID8gXCJoYXMtaWNvblwiIDogXCJcIlxuICAgICAgICAgICAgfVwiIGlucHV0LXRhYi1rZXk9XCIke2kudGFiS2V5IHx8IFwiXCJ9XCIgbGFiZWw9XCIke2kubGFiZWx9XCI+XG4gICAgICAgICAgICAgIDxsYWJlbD5cbiAgICAgICAgICAgICAgICAke2ljb24gfHwgXCJcIn1cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS10aXRsZSB0cnVuY2F0ZVwiPlxuICAgICAgICAgICAgICAgICAgJHtpLmxhYmVsfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAke3Rvb2x0aXB9XG4gICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxldCB0b29sdGlwID0gXCJcIjtcbiAgICAgICAgICBsZXQgaWNvbiA9IG51bGw7XG4gICAgICAgICAgbGV0IGxpbmsgPSBcIlwiO1xuXG4gICAgICAgICAgaWYgKGkudG9vbHRpcCkge1xuICAgICAgICAgICAgdG9vbHRpcCA9IGBcbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLXRvb2x0aXBcIj5cbiAgICAgICAgICAgICAgICAgICAgJHtpLnRvb2x0aXB9XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChpLmNvbG9ySWNvbikge1xuICAgICAgICAgICAgaWYgKHV0aWxzLmlzSGV4Q29sb3IoaS5jb2xvckljb24pKSB7XG4gICAgICAgICAgICAgIGljb24gPSBgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbi0taWNvblwiIHN0eWxlPVwiYmFja2dyb3VuZDoke2kuY29sb3JJY29ufVwiPiA8L2Rpdj5gO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaWNvbiA9IGA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS1pY29uICR7aS5jb2xvckljb259XCI+IDwvZGl2PmA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGkubGluaykge1xuICAgICAgICAgICAgbGluayA9IGA8YSBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbi0tbGlua1wiIHRhcmdldD1cIl9ibGFua1wiIGhyZWY9XCIke2kubGlua31cIj5cbiAgICAgICAgICAgICAgICAke2ljb25zLmxpbmtJY29ufVxuICAgICAgICAgICAgICAgIDwvYT4gYDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzdHIgKz0gYFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbiAgJHtcbiAgICAgICAgICAgICAgaWNvbiA/IFwiaGFzLWljb25cIiA6IFwiXCJcbiAgICAgICAgICAgIH1cIiBpbnB1dC10YWIta2V5PVwiJHtpLnRhYktleSB8fCBcIlwifVwiIGxhYmVsPVwiJHtpLmxhYmVsfVwiPlxuICAgICAgICAgICAgICA8bGFiZWw+XG5cbiAgICAgICAgICAgICAgICAke2ljb259XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS10aXRsZSB0cnVuY2F0ZVwiPlxuICAgICAgICAgICAgICAgICAgJHtpLmxhYmVsfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbi0tc3VmZml4XCIgPiR7XG4gICAgICAgICAgICAgICAgICBpLnN1ZmZpeCA/IFwiKFwiICsgaS5zdWZmaXggKyBcIilcIiA6IFwiXCJcbiAgICAgICAgICAgICAgICB9PC9kaXY+XG5cbiAgICAgICAgICAgICAgICAke2xpbmt9XG5cbiAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbi0tZm9vdGVyXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGFydFwiPiBzdGFydDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImVuZFwiPiBlbmQgPC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgJHt0b29sdGlwfVxuICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgc3RyICs9IGBcbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj4gYDtcblxuICAgIGxldCAkZWwgPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKHN0cik7XG4gICAgbGV0ICR0YWJzID0gJGVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCIuaW5wdXQtYm94LXRhYlt0YWIta2V5XVwiKSB8fCBbXTtcbiAgICBsZXQgJHNlYXJjaElucHV0ID0gJGVsLnF1ZXJ5U2VsZWN0b3IoXCIuc2VhcmNoLWlucHV0XCIpIHx8IG51bGw7XG4gICAgbGV0ICRzZWFyY2hJbnB1dENsZWFyID0gJGVsLnF1ZXJ5U2VsZWN0b3IoXCIuc2VhcmNoLWlucHV0LWNsZWFyXCIpIHx8IG51bGw7XG5cbiAgICAkdGFicy5mb3JFYWNoKCh0KSA9PiB7XG4gICAgICB0LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZSkgPT4ge1xuICAgICAgICB0aGlzLnNlbGVjdElucHV0Qm94VGFiKHQsICRlbCk7XG4gICAgICAgICRzZWFyY2hJbnB1dC52YWx1ZSA9IFwiXCI7XG4gICAgICAgICRzZWFyY2hJbnB1dC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcImlucHV0XCIsIHsgYnViYmxlczogdHJ1ZSB9KSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGlmICgkc2VhcmNoSW5wdXRDbGVhcikge1xuICAgICAgJHNlYXJjaElucHV0Q2xlYXIuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgICRzZWFyY2hJbnB1dC52YWx1ZSA9IFwiXCI7XG4gICAgICAgICRzZWFyY2hJbnB1dC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcImlucHV0XCIsIHsgYnViYmxlczogdHJ1ZSB9KSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoJHNlYXJjaElucHV0KSB7XG4gICAgICAkc2VhcmNoSW5wdXQuYWRkRXZlbnRMaXN0ZW5lcihcImtleWRvd25cIiwgKGUpID0+IHtcbiAgICAgICAgaWYgKGUua2V5ID09PSBcIkVzY2FwZVwiKSB7XG4gICAgICAgICAgJHNlYXJjaElucHV0LnZhbHVlID0gXCJcIjtcbiAgICAgICAgICAkc2VhcmNoSW5wdXQuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJpbnB1dFwiLCB7IGJ1YmJsZXM6IHRydWUgfSkpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgJHNlYXJjaElucHV0LmFkZEV2ZW50TGlzdGVuZXIoXCJpbnB1dFwiLCAoZSkgPT4ge1xuICAgICAgICBsZXQgJHRhYlNlbGVjdGVkID1cbiAgICAgICAgICAkZWwucXVlcnlTZWxlY3RvcihcIi5pbnB1dC1ib3gtdGFiW3RhYi1rZXldLmFjdGl2ZVwiKSB8fCBudWxsO1xuICAgICAgICBsZXQgJGlucHV0cyA9IFtdO1xuICAgICAgICBpZiAoJHRhYlNlbGVjdGVkKSB7XG4gICAgICAgICAgbGV0IHRhYktleSA9ICR0YWJTZWxlY3RlZC5nZXRBdHRyaWJ1dGUoXCJ0YWIta2V5XCIpO1xuICAgICAgICAgICRpbnB1dHMgPVxuICAgICAgICAgICAgJGVsLnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgICAgICAgIFwiLm1pbmktaW5wdXQtc2VjdGlvbltpbnB1dC10YWIta2V5PSdcIiArIHRhYktleSArIFwiJ11cIlxuICAgICAgICAgICAgKSB8fCBbXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAkaW5wdXRzID0gJGVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCIubWluaS1pbnB1dC1zZWN0aW9uXCIpIHx8IFtdO1xuICAgICAgICB9XG4gICAgICAgICRpbnB1dHMuZm9yRWFjaCgoJGkpID0+IHtcbiAgICAgICAgICBsZXQgbGFiZWwgPSAkaS5nZXRBdHRyaWJ1dGUoXCJsYWJlbFwiKTtcbiAgICAgICAgICBsZXQgc2VhcmNoID0gJHNlYXJjaElucHV0LnZhbHVlO1xuICAgICAgICAgIGlmIChsYWJlbC50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHNlYXJjaC50b0xvd2VyQ2FzZSgpKSkge1xuICAgICAgICAgICAgJGkuY2xhc3NMaXN0LnJlbW92ZShcImhpZGVcIik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICRpLmNsYXNzTGlzdC5hZGQoXCJoaWRlXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLnNlbGVjdElucHV0Qm94VGFiKF8uZmlyc3QoJHRhYnMpLCAkZWwpO1xuXG4gICAgcmV0dXJuICRlbDtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYSBJbnB1dEJveCwgY29tbyBlbGVtZW50byBEb21cbiAgICogdW4gSW5wdXRCb3ggZXMgdW4gY29udGVuZWRvciBjb24gdW5hIGxpc3RhIGRlIGlucHV0c1xuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcHMgLSBjb25maWcgcGFyYSBJbnB1dFxuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YURheSAtIHZhbG9yZXMgZGUgaXRlbSB5IERpYSwgb3BjaW9uYWxcbiAgICogQHJldHVybiB7T2JqZWN0fSBFbGVtZW50byBEb20gZGVsIGlucHV0IGNyZWFkb1xuICAgKi9cbiAgY3JlYXRlSW5wdXRCb3gocHJvcHMsIGRhdGFEYXkpIHtcbiAgICBsZXQgdmFsdWUgPSBbXTtcbiAgICBpZiAoZGF0YURheSAmJiBkYXRhRGF5LnZhbHVlcykge1xuICAgICAgdmFsdWUgPSB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YURheSwgcHJvcHMudmFyTmFtZSk7XG4gICAgfVxuXG4gICAgbGV0IHRhYnNDb250YWluZXIgPSBcIlwiO1xuXG4gICAgaWYgKHByb3BzLnRhYnMpIHtcbiAgICAgIGxldCB0YWJzID0gXCJcIjtcbiAgICAgIHByb3BzLnRhYnMuZm9yRWFjaCgodGFiKSA9PiB7XG4gICAgICAgIHRhYnMgKz0gYFxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtYm94LXRhYlwiIHRhYi1rZXk9XCIke3RhYi5rZXl9XCI+XG4gICAgICAgICAgJHt0YWIubmFtZX1cbiAgICAgICAgPC9kaXY+YDtcbiAgICAgIH0pO1xuXG4gICAgICB0YWJzQ29udGFpbmVyID0gYFxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtYm94LXRhYi1jb250YWluZXJcIj5cbiAgICAgICAgJHt0YWJzfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIGA7XG4gICAgfVxuXG4gICAgbGV0IHNlYXJjaElucHV0ID0gYFxuICAgICAgPGRpdiBjbGFzcz1cInNlYXJjaC1pbnB1dC1jb250YWluZXJcIj5cbiAgICAgICAgPGlucHV0IGlkPVwiXCIgdHlwZT1cInRleHRcIiBuYW1lPVwiXCIgY2xhc3M9XCJzZWFyY2gtaW5wdXRcIiBwbGFjZWhvbGRlcj1cImJ1c2NhclwiPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwic2VhcmNoLWlucHV0LWNsZWFyXCI+XG4gICAgICAgICAke2ljb25zLmNsb3NlSWNvbn1cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICBgO1xuXG4gICAgbGV0IHN0ciA9IGBcbiAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWN0aW9uICR7cHJvcHMuaXNIaWRkZW4gPyBcImhpZGVcIiA6IFwiXCJ9IFwiIGlucHV0LWtleT1cIiR7XG4gICAgICAgIHByb3BzLmtleSB8fCBcIlwiXG4gICAgICB9XCI+XG4gICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1zdWJ0aXRsZSBkLWJsb2NrXCI+XG4gICAgICAgICAgICAgICR7cHJvcHMubGFiZWx9XG4gICAgICAgICAgICA8L3NwYW4+XG5cbiAgICAgICAgICAgICR7dGFic0NvbnRhaW5lcn1cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWJveCBcIiBpbnB1dC1rZXk9XCIke3Byb3BzLmtleSB8fCBcIlwifVwiPlxuXG4gICAgICAgICAgICAke3NlYXJjaElucHV0fVxuICAgICAgYDtcblxuICAgIGlmIChwcm9wcy5pbnB1dHMpIHtcbiAgICAgIHByb3BzLmlucHV0cy5mb3JFYWNoKChpKSA9PiB7XG4gICAgICAgIGlmIChpLmlzVGl0bGUpIHtcbiAgICAgICAgICBsZXQgdG9vbHRpcCA9IFwiXCI7XG4gICAgICAgICAgbGV0IGljb24gPSBcIlwiO1xuXG4gICAgICAgICAgaWYgKGkudG9vbHRpcCkge1xuICAgICAgICAgICAgdG9vbHRpcCA9IGBcbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLXRvb2x0aXBcIj5cbiAgICAgICAgICAgICAgICAgICAgJHtpLnRvb2x0aXB9XG4gICAgICAgICAgICAgICAgICAgICR7aS5zdWZmaXggPyBcIihcIiArIGkuc3VmZml4ICsgXCIpXCIgOiBcIlwifVxuICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaS5jb2xvckljb24pIHtcbiAgICAgICAgICAgIGlmICh1dGlscy5pc0hleENvbG9yKGkuY29sb3JJY29uKSkge1xuICAgICAgICAgICAgICBpY29uID0gYDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLWljb25cIiBzdHlsZT1cImJhY2tncm91bmQ6JHtpLmNvbG9ySWNvbn1cIj4gPC9kaXY+YDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGljb24gPSBgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbi0taWNvbiAke2kuY29sb3JJY29ufVwiPiA8L2Rpdj5gO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHN0ciArPSBgXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uIGlzLXRpdGxlXCIgaW5wdXQtdGFiLWtleT1cIiR7XG4gICAgICAgICAgICAgIGkudGFiS2V5IHx8IFwiXCJcbiAgICAgICAgICAgIH1cIiBsYWJlbD1cIiR7aS5sYWJlbH1cIj5cbiAgICAgICAgICAgICAgPGxhYmVsPlxuICAgICAgICAgICAgICAgICR7aWNvbn1cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS10aXRsZSB0cnVuY2F0ZVwiPlxuICAgICAgICAgICAgICAgICAgJHtpLmxhYmVsfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAke3Rvb2x0aXB9XG4gICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxldCB2YWx1ZV9mb3VuZCA9IHZhbHVlID8gdmFsdWUuZmluZCgodmFsKSA9PiB2YWwuaWQgPT0gaS5pZCkgOiBudWxsO1xuICAgICAgICAgIGxldCB2ID0gdmFsdWVfZm91bmQgfHwgXCJcIjtcbiAgICAgICAgICBsZXQgaW5wdXRWYWx1ZSA9XG4gICAgICAgICAgICBwcm9wcy52YXJOYW1lSW5wdXQgJiYgdltwcm9wcy52YXJOYW1lSW5wdXRdXG4gICAgICAgICAgICAgID8gdltwcm9wcy52YXJOYW1lSW5wdXRdXG4gICAgICAgICAgICAgIDogdi52YWx1ZTtcbiAgICAgICAgICBsZXQgdG9vbHRpcCA9IFwiXCI7XG4gICAgICAgICAgbGV0IGljb24gPSBcIlwiO1xuICAgICAgICAgIGxldCBsaW5rID0gXCJcIjtcblxuICAgICAgICAgIGlmIChpLnRvb2x0aXApIHtcbiAgICAgICAgICAgIHRvb2x0aXAgPSBgXG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS10b29sdGlwXCI+XG4gICAgICAgICAgICAgICAgICAgICR7aS50b29sdGlwfVxuICAgICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaS5jb2xvckljb24pIHtcbiAgICAgICAgICAgIGlmICh1dGlscy5pc0hleENvbG9yKGkuY29sb3JJY29uKSkge1xuICAgICAgICAgICAgICBpY29uID0gYDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLWljb25cIiBzdHlsZT1cImJhY2tncm91bmQ6JHtpLmNvbG9ySWNvbn1cIj4gPC9kaXY+YDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGljb24gPSBgPGRpdiBjbGFzcz1cIm1pbmktaW5wdXQtc2VjdGlvbi0taWNvbiAke2kuY29sb3JJY29ufVwiPiA8L2Rpdj5gO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChpLmxpbmspIHtcbiAgICAgICAgICAgIGxpbmsgPSBgPGEgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLWxpbmtcIiB0YXJnZXQ9XCJfYmxhbmtcIiBocmVmPVwiJHtpLmxpbmt9XCI+XG4gICAgICAgICAgICAgICAgJHtpY29ucy5saW5rSWNvbn1cbiAgICAgICAgICAgICAgICA8L2E+IGA7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3RyICs9IGBcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24gJHtcbiAgICAgICAgICAgICAgaWNvbiA/IFwiaGFzLWljb25cIiA6IFwiXCJcbiAgICAgICAgICAgIH1cIiBpbnB1dC10YWIta2V5PVwiJHtpLnRhYktleSB8fCBcIlwifVwiIGxhYmVsPVwiJHtpLmxhYmVsfVwiPlxuICAgICAgICAgICAgICA8bGFiZWw+XG4gICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibWluaS1pbnB1dFwiXG4gICAgICAgICAgICAgICAgICAgICAgaW5wdXQtaWQ9XCIke2kuaWQgfHwgXCJcIn1cIlxuICAgICAgICAgICAgICAgICAgICAgIGlucHV0LWtleT1cIiR7aS5rZXkgfHwgaS5sYWJlbH1cIlxuICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPVwiJHtpbnB1dFZhbHVlIHx8IFwiXCJ9XCI+XG5cbiAgICAgICAgICAgICAgICAke2ljb24gfHwgXCJcIn1cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtaW5pLWlucHV0LXNlY3Rpb24tLXRpdGxlIHRydW5jYXRlXCI+XG4gICAgICAgICAgICAgICAgICAke2kubGFiZWx9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluaS1pbnB1dC1zZWN0aW9uLS1zdWZmaXhcIiA+JHtcbiAgICAgICAgICAgICAgICAgIGkuc3VmZml4ID8gXCIoXCIgKyBpLnN1ZmZpeCArIFwiKVwiIDogXCJcIlxuICAgICAgICAgICAgICAgIH08L2Rpdj5cblxuICAgICAgICAgICAgICAgICR7bGlua31cblxuICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAke3Rvb2x0aXB9XG4gICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBzdHIgKz0gYFxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PiBgO1xuXG4gICAgbGV0ICRlbCA9IGRvbS5jcmVhdGVFbGVtZW50RnJvbUhUTUwoc3RyKTtcbiAgICBsZXQgJHRhYnMgPSAkZWwucXVlcnlTZWxlY3RvckFsbChcIi5pbnB1dC1ib3gtdGFiW3RhYi1rZXldXCIpIHx8IFtdO1xuICAgIGxldCAkaW5wdXRzID0gJGVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCJpbnB1dC5taW5pLWlucHV0XCIpIHx8IFtdO1xuICAgIGxldCAkc2VhcmNoSW5wdXQgPSAkZWwucXVlcnlTZWxlY3RvcihcIi5zZWFyY2gtaW5wdXRcIikgfHwgbnVsbDtcbiAgICBsZXQgJHNlYXJjaElucHV0Q2xlYXIgPSAkZWwucXVlcnlTZWxlY3RvcihcIi5zZWFyY2gtaW5wdXQtY2xlYXJcIikgfHwgbnVsbDtcblxuICAgICR0YWJzLmZvckVhY2goKHQpID0+IHtcbiAgICAgIHQuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgIHRoaXMuc2VsZWN0SW5wdXRCb3hUYWIodCwgJGVsKTtcbiAgICAgICAgJHNlYXJjaElucHV0LnZhbHVlID0gXCJcIjtcbiAgICAgICAgJHNlYXJjaElucHV0LmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwiaW5wdXRcIiwgeyBidWJibGVzOiB0cnVlIH0pKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaWYgKCRzZWFyY2hJbnB1dENsZWFyKSB7XG4gICAgICAkc2VhcmNoSW5wdXRDbGVhci5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgJHNlYXJjaElucHV0LnZhbHVlID0gXCJcIjtcbiAgICAgICAgJHNlYXJjaElucHV0LmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwiaW5wdXRcIiwgeyBidWJibGVzOiB0cnVlIH0pKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICgkc2VhcmNoSW5wdXQpIHtcbiAgICAgICRzZWFyY2hJbnB1dC5hZGRFdmVudExpc3RlbmVyKFwia2V5ZG93blwiLCAoZSkgPT4ge1xuICAgICAgICBpZiAoZS5rZXkgPT09IFwiRXNjYXBlXCIpIHtcbiAgICAgICAgICAkc2VhcmNoSW5wdXQudmFsdWUgPSBcIlwiO1xuICAgICAgICAgICRzZWFyY2hJbnB1dC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcImlucHV0XCIsIHsgYnViYmxlczogdHJ1ZSB9KSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAkc2VhcmNoSW5wdXQuYWRkRXZlbnRMaXN0ZW5lcihcImlucHV0XCIsIChlKSA9PiB7XG4gICAgICAgIGxldCAkdGFiU2VsZWN0ZWQgPVxuICAgICAgICAgICRlbC5xdWVyeVNlbGVjdG9yKFwiLmlucHV0LWJveC10YWJbdGFiLWtleV0uYWN0aXZlXCIpIHx8IG51bGw7XG4gICAgICAgIGxldCAkaW5wdXRzID0gW107XG4gICAgICAgIGlmICgkdGFiU2VsZWN0ZWQpIHtcbiAgICAgICAgICBsZXQgdGFiS2V5ID0gJHRhYlNlbGVjdGVkLmdldEF0dHJpYnV0ZShcInRhYi1rZXlcIik7XG4gICAgICAgICAgJGlucHV0cyA9XG4gICAgICAgICAgICAkZWwucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgICAgICAgXCIubWluaS1pbnB1dC1zZWN0aW9uW2lucHV0LXRhYi1rZXk9J1wiICsgdGFiS2V5ICsgXCInXVwiXG4gICAgICAgICAgICApIHx8IFtdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICRpbnB1dHMgPSAkZWwucXVlcnlTZWxlY3RvckFsbChcIi5taW5pLWlucHV0LXNlY3Rpb25cIikgfHwgW107XG4gICAgICAgIH1cbiAgICAgICAgJGlucHV0cy5mb3JFYWNoKCgkaSkgPT4ge1xuICAgICAgICAgIGxldCBsYWJlbCA9ICRpLmdldEF0dHJpYnV0ZShcImxhYmVsXCIpO1xuICAgICAgICAgIGxldCBzZWFyY2ggPSAkc2VhcmNoSW5wdXQudmFsdWU7XG4gICAgICAgICAgaWYgKGxhYmVsLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoc2VhcmNoLnRvTG93ZXJDYXNlKCkpKSB7XG4gICAgICAgICAgICAkaS5jbGFzc0xpc3QucmVtb3ZlKFwiaGlkZVwiKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgJGkuY2xhc3NMaXN0LmFkZChcImhpZGVcIik7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuc2VsZWN0SW5wdXRCb3hUYWIoXy5maXJzdCgkdGFicyksICRlbCk7XG5cbiAgICAkaW5wdXRzLmZvckVhY2goKGkpID0+IHRoaXMuYWRkS2V5RG93bklucHV0RXZlbnRzKGksICRlbCwgcHJvcHMpKTtcblxuICAgIHJldHVybiAkZWw7XG4gIH0sXG5cbiAgc2VsZWN0SW5wdXRCb3hUYWIoJHRhYiwgJGVsKSB7XG4gICAgbGV0ICR0YWJzID0gJGVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCIuaW5wdXQtYm94LXRhYlt0YWIta2V5XVwiKSB8fCBbXTtcbiAgICBsZXQgJGlucHV0U2VjdGlvbnMgPSAkZWwucXVlcnlTZWxlY3RvckFsbChcIi5taW5pLWlucHV0LXNlY3Rpb25cIikgfHwgW107XG5cbiAgICAkdGFicy5mb3JFYWNoKCh0KSA9PiB7XG4gICAgICB0LmNsYXNzTGlzdC5yZW1vdmUoXCJhY3RpdmVcIik7XG4gICAgfSk7XG5cbiAgICBpZiAoJHRhYikge1xuICAgICAgJHRhYi5jbGFzc0xpc3QuYWRkKFwiYWN0aXZlXCIpO1xuXG4gICAgICAkaW5wdXRTZWN0aW9ucy5mb3JFYWNoKChpKSA9PiB7XG4gICAgICAgIGxldCBrZXkgPSBpLmdldEF0dHJpYnV0ZShcImlucHV0LXRhYi1rZXlcIik7XG4gICAgICAgIGlmIChrZXkgPT0gJHRhYi5nZXRBdHRyaWJ1dGUoXCJ0YWIta2V5XCIpKSB7XG4gICAgICAgICAgaS5jbGFzc0xpc3QucmVtb3ZlKFwiaGlkZVwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpLmNsYXNzTGlzdC5hZGQoXCJoaWRlXCIpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWEgQ2hlY2tib3gsIGNvbW8gZWxlbWVudG8gRG9tXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwcm9wcyAtIGNvbmZpZyBwYXJhIElucHV0XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhRGF5IC0gdmFsb3JlcyBkZSBpdGVtIHkgRGlhLCBvcGNpb25hbFxuICAgKiBAcmV0dXJuIHtPYmplY3R9IEVsZW1lbnRvIERvbSBkZWwgaW5wdXQgY3JlYWRvXG4gICAqL1xuICBjcmVhdGVJbnB1dENoZWNrYm94KHByb3BzLCBkYXRhRGF5KSB7XG4gICAgbGV0IHZhbHVlID0gXCJcIjtcbiAgICBpZiAoZGF0YURheSAmJiBkYXRhRGF5LnZhbHVlcykge1xuICAgICAgdmFsdWUgPSB1dGlscy5nZXRWYXJCeVBhdGgoZGF0YURheSwgcHJvcHMudmFyTmFtZSk7XG4gICAgfVxuICAgIGxldCByID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChgXG4gICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtc2VjdGlvbiAke3Byb3BzLmlzSGlkZGVuID8gXCJoaWRlXCIgOiBcIlwifSBcIiBpbnB1dC1rZXk9XCIke1xuICAgICAgICBwcm9wcy5rZXkgfHwgXCJcIlxuICAgICAgfVwiPlxuICAgICAgICA8bGFiZWw+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIG5hbWU9XCIke3Byb3BzLmtleSB8fCBcIlwifVwiIGlucHV0LWtleT1cIiR7XG4gICAgICAgICAgICBwcm9wcy5rZXkgfHwgXCJcIlxuICAgICAgICAgIH1cIiAke3ZhbHVlID8gXCJjaGVja2VkXCIgOiBcIlwifT5cbiAgICAgICAgICAke3Byb3BzLmxhYmVsfVxuICAgICAgICA8L2xhYmVsPlxuICAgICAgPC9kaXY+YCk7XG5cbiAgICByZXR1cm4gcjtcbiAgfSxcblxuICBjcmVhdGVJbnB1dEJ1dHRvbnNHcm91cChwcm9wcykge1xuICAgIGxldCAkY29udGFpbmVyID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChgXG4gICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtc2VjdGlvbiAke3Byb3BzLmlzSGlkZGVuID8gXCJoaWRlXCIgOiBcIlwifSBcIiBpbnB1dC1rZXk9XCIke1xuICAgICAgICBwcm9wcy5rZXkgfHwgXCJcIlxuICAgICAgfVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYnV0dG9ucy1ncm91cFwiPiA8L2Rpdj5cbiAgICAgIDwvZGl2PmApO1xuXG4gICAgbGV0ICRjb250YWluZXJCdXR0b25Hcm91cCA9ICRjb250YWluZXIucXVlcnlTZWxlY3RvcihcIi5idXR0b25zLWdyb3VwXCIpO1xuXG4gICAgbGV0ICRidXR0b25zID0gW107XG4gICAgJGJ1dHRvbnMgPSBwcm9wcy5idXR0b25zLm1hcCgoYnV0dG9uUHJvcCkgPT4ge1xuICAgICAgbGV0IGJ1dHRvblN0ciA9IGBcbiAgICAgICAgPGJ1dHRvbiBcbiAgICAgICAgICBuYW1lPVwiJHtidXR0b25Qcm9wLmtleSB8fCBcIlwifVwiIFxuICAgICAgICAgIGlucHV0LWtleT1cIiR7YnV0dG9uUHJvcC5rZXkgfHwgXCJcIn1cIlxuICAgICAgICAgIGNsYXNzPVwiY2FwLWJ0bi1vdXRsaW5lIGNhcC1idG4tc20gJHtcbiAgICAgICAgICAgIGJ1dHRvblByb3AuaXNTZWxlY3RlZCA/IFwic2VsZWN0ZWRcIiA6IFwiXCJcbiAgICAgICAgICB9IFwiPlxuICAgICAgICAgICR7YnV0dG9uUHJvcC5sYWJlbH1cbiAgICAgICAgPC9idXR0b24+YDtcblxuICAgICAgbGV0ICRidXR0b24gPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKGJ1dHRvblN0cik7XG4gICAgICAkY29udGFpbmVyQnV0dG9uR3JvdXAuYXBwZW5kKCRidXR0b24pO1xuXG4gICAgICAkYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZSkgPT4ge1xuICAgICAgICBpZiAocHJvcHMuaXNTZWxlY3RhYmxlKSB7XG4gICAgICAgICAgJGJ1dHRvbnMuZm9yRWFjaCgoJGIpID0+ICRiLmNsYXNzTGlzdC5yZW1vdmUoXCJzZWxlY3RlZFwiKSk7XG4gICAgICAgICAgJGJ1dHRvbi5jbGFzc0xpc3QuYWRkKFwic2VsZWN0ZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgYnV0dG9uUHJvcC5vbkNsaWNrKHsgcHJvcHMsIGV2ZW50OiBlLCBidXR0b25zRWxlbWVudHM6ICRidXR0b25zIH0pO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gJGJ1dHRvbjtcbiAgICB9KTtcblxuICAgIHJldHVybiAkY29udGFpbmVyO1xuICB9LFxuXG4gIGNyZWF0ZUlucHV0QnV0dG9uKHByb3BzLCBkYXRhRGF5KSB7XG4gICAgbGV0IHIgPSBkb20uY3JlYXRlRWxlbWVudEZyb21IVE1MKGBcbiAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWN0aW9uICR7cHJvcHMuaXNIaWRkZW4gPyBcImhpZGVcIiA6IFwiXCJ9IFwiIGlucHV0LWtleT1cIiR7XG4gICAgICAgIHByb3BzLmtleSB8fCBcIlwiXG4gICAgICB9XCI+XG4gICAgICAgICAgPGJ1dHRvbiBcbiAgICAgICAgICAgIG5hbWU9XCIke3Byb3BzLmtleSB8fCBcIlwifVwiXG4gICAgICAgICAgICBpbnB1dC1rZXk9XCIke3Byb3BzLmtleSB8fCBcIlwifVwiXG4gICAgICAgICAgICBjbGFzcz1cImNhcC1idG4tb3V0bGluZVwiPlxuICAgICAgICAgICAgJHtwcm9wcy5sYWJlbH1cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PmApO1xuXG4gICAgbGV0IGJ1dHRvbiA9IHIucXVlcnlTZWxlY3RvcihcImJ1dHRvblwiKTtcbiAgICBidXR0b24uYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PlxuICAgICAgcHJvcHMub25DbGljayh7IHByb3BzLCBldmVudDogZSwgZGF0YURheSB9KVxuICAgICk7XG5cbiAgICByZXR1cm4gcjtcbiAgfSxcblxuICBhZGRLZXlEb3duSW5wdXRFdmVudHMoJGlucHV0LCAkaW5wdXRDb250YWluZXIsIHByb3BzKSB7XG4gICAgJGlucHV0LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXlkb3duXCIsIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgaWYgKGV2ZW50LmtleUNvZGUgPT09IDEzKSB7XG4gICAgICAgIC8vRU5URVJcbiAgICAgICAgJGlucHV0LmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwic2F2ZU11bHRpSW5wdXRcIiwge1xuICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgIGNhbmNlbGFibGU6IGZhbHNlLFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoZXZlbnQua2V5Q29kZSA9PT0gMjcpIHtcbiAgICAgICAgLy9FU0NcbiAgICAgICAgJGlucHV0LmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwiY2FuY2VsTXVsdGlJbnB1dFwiLCB7XG4gICAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICAkaW5wdXQuYWRkRXZlbnRMaXN0ZW5lcihcImlucHV0XCIsIChlKSA9PiB7XG4gICAgICBpZiAocHJvcHMub25JbnB1dCkge1xuICAgICAgICBwcm9wcy5vbklucHV0KHtcbiAgICAgICAgICBldmVudDogZSxcbiAgICAgICAgICB2YWx1ZTogZS5zcmNFbGVtZW50LnZhbHVlLFxuICAgICAgICAgIHByb3BzLFxuICAgICAgICAgICRlbGVtZW50OiAkaW5wdXRDb250YWluZXIsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9LFxuXG4gIGNyZWF0ZUNvbnRleHRNZW51KHtcbiAgICBjb25maWcsXG4gICAgdGFyZ2V0LFxuICAgICRjYXBpYmFyYUVsZW0gPSBudWxsLFxuICAgIGV2dCA9IG51bGwsXG4gICAgZGF0ZSA9IG51bGwsXG4gICAgaXRlbSA9IG51bGwsXG4gICAgc2VsZWN0ZWQgPSBbXSxcbiAgICB0YWJTZWxlY3RlZCA9IG51bGwsXG4gICAgbGVmdCA9IG51bGwsXG4gICAgdG9wID0gbnVsbCxcbiAgICBuYW1lID0gXCJcIixcbiAgfSkge1xuICAgIGlmIChcbiAgICAgIGNvbmZpZy50aW1lbGluZS5jb250ZXh0TWVudSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICBjb25maWcudGltZWxpbmUuY29udGV4dE1lbnUub3B0aW9ucyA9PSB1bmRlZmluZWRcbiAgICApXG4gICAgICByZXR1cm4geyBlbGVtOiBudWxsLCBpc1Zpc2libGU6IGZhbHNlIH07XG5cbiAgICBsZXQgY2xhc3NOYW1lID0gXCJcIjtcbiAgICBsZXQgc3R5bGUgPSBcIlwiO1xuICAgIGxldCBzdHJIdG1sID0gXCJcIjtcbiAgICBsZXQgbGVmdFBvc2l0aW9uID0gbnVsbDtcbiAgICBsZXQgdG9wUG9zaXRpb24gPSBudWxsO1xuICAgIGxldCBpc1Zpc2libGUgPSB0cnVlO1xuICAgIGxldCBib3VuZFJlY3RDYXBpYmFyYSA9IG51bGw7XG4gICAgbGV0IGdhcCA9IDE1OyAvL3B4XG5cbiAgICBpZiAoJGNhcGliYXJhRWxlbSkge1xuICAgICAgYm91bmRSZWN0Q2FwaWJhcmEgPSAkY2FwaWJhcmFFbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIH1cblxuICAgIGlmIChldnQgJiYgYm91bmRSZWN0Q2FwaWJhcmEpIHtcbiAgICAgIGxlZnQgPSBldnQuY2xpZW50WDtcbiAgICAgIHRvcCA9IGV2dC5jbGllbnRZIC0gYm91bmRSZWN0Q2FwaWJhcmEudG9wO1xuICAgIH1cblxuICAgIGlmIChsZWZ0KSB7XG4gICAgICBsZWZ0UG9zaXRpb24gPSBsZWZ0O1xuICAgIH1cblxuICAgIGlmICh0b3ApIHtcbiAgICAgIHRvcFBvc2l0aW9uID0gdG9wO1xuICAgIH1cblxuICAgIGlmICgobGVmdFBvc2l0aW9uICE9PSBudWxsKSAmICh0b3BQb3NpdGlvbiAhPT0gbnVsbCkpIHtcbiAgICAgIGlmIChib3VuZFJlY3RDYXBpYmFyYSkge1xuICAgICAgICBsZXQgdHJhbnNmb3JtU3R5bGUgPSBcIlwiO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgdG9wUG9zaXRpb24gPiAoYm91bmRSZWN0Q2FwaWJhcmEuaGVpZ2h0ICogMikgLyA2ICYmXG4gICAgICAgICAgdG9wUG9zaXRpb24gPD0gKGJvdW5kUmVjdENhcGliYXJhLmhlaWdodCAqIDQpIC8gNlxuICAgICAgICApIHtcbiAgICAgICAgICB0cmFuc2Zvcm1TdHlsZSArPSBgdHJhbnNsYXRlWSgtNTAlKWA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRvcFBvc2l0aW9uID4gKGJvdW5kUmVjdENhcGliYXJhLmhlaWdodCAqIDQpIC8gNikge1xuICAgICAgICAgIHRyYW5zZm9ybVN0eWxlICs9IGB0cmFuc2xhdGVZKC0xMDAlKWA7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobGVmdFBvc2l0aW9uID4gKGJvdW5kUmVjdENhcGliYXJhLndpZHRoICogNCkgLyA2KSB7XG4gICAgICAgICAgdHJhbnNmb3JtU3R5bGUgKz0gYHRyYW5zbGF0ZVgoLTEwMCUpYDtcbiAgICAgICAgICBsZWZ0UG9zaXRpb24gLT0gZ2FwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxlZnRQb3NpdGlvbiArPSBnYXA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRyYW5zZm9ybVN0eWxlICE9IFwiXCIpIHtcbiAgICAgICAgICBzdHlsZSArPSBgIHRyYW5zZm9ybTogJHt0cmFuc2Zvcm1TdHlsZX07YDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBzdHlsZSArPSBgdG9wOiAke3RvcFBvc2l0aW9ufXB4OyBsZWZ0OiAke2xlZnRQb3NpdGlvbn1weDtgO1xuICAgIH0gZWxzZSB7XG4gICAgICBjbGFzc05hbWUgKz0gXCJjbS1oaWRlXCI7XG4gICAgICBpc1Zpc2libGUgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBzdHJIdG1sICs9IGAgPGRpdiBjbGFzcz1cImNhcC1jb250ZXh0LW1lbnUtY29udGFpbmVyICR7Y2xhc3NOYW1lfVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FwLWNvbnRleHQtbWVudVwiIHN0eWxlPVwiJHtzdHlsZX1cIj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgIDwvZGl2PmA7XG5cbiAgICBsZXQgJGNvbnRleHRNZW51Q29udGFpbmVyID0gZG9tLmNyZWF0ZUVsZW1lbnRGcm9tSFRNTChzdHJIdG1sKTtcbiAgICBsZXQgJGNvbnRleHRNZW51ID0gJGNvbnRleHRNZW51Q29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoXCIuY2FwLWNvbnRleHQtbWVudVwiKTtcbiAgICBsZXQgaGFzU29tZW9wdGlvbiA9IGZhbHNlO1xuXG4gICAgY29uZmlnLnRpbWVsaW5lLmNvbnRleHRNZW51Lm9wdGlvbnMuZm9yRWFjaCgob3B0aW9uKSA9PiB7XG4gICAgICBpZiAob3B0aW9uLnNob3dJZikge1xuICAgICAgICBsZXQgc2hvdyA9IG9wdGlvbi5zaG93SWYoeyBpdGVtLCBkYXRlLCBzZWxlY3RlZCwgbmFtZSwgdGFiU2VsZWN0ZWQgfSk7XG4gICAgICAgIGlmICghc2hvdykgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBsZXQgaXNFbmFibGVkID0gdHJ1ZTtcbiAgICAgIGxldCBpc0NsaWNrZWFibGUgPSB0cnVlO1xuICAgICAgaWYgKG9wdGlvbi5lbmFibGVJZikge1xuICAgICAgICBpc0VuYWJsZWQgPSBvcHRpb24uZW5hYmxlSWYoe1xuICAgICAgICAgIGl0ZW0sXG4gICAgICAgICAgZGF0ZSxcbiAgICAgICAgICBzZWxlY3RlZCxcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIHRhYlNlbGVjdGVkLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgbGV0IG9wdGlvbkNsYXNzTmFtZSA9IFwiXCI7XG4gICAgICBsZXQgc3RySWNvbiA9IFwiXCI7XG4gICAgICBsZXQgbGFiZWwgPSBcIlwiO1xuXG4gICAgICBpZiAoIWlzRW5hYmxlZCkge1xuICAgICAgICBvcHRpb25DbGFzc05hbWUgKz0gXCJpcy1kaXNhYmxlZCBcIjtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wdGlvbi5pc0RpdmlkZXIpIHtcbiAgICAgICAgaXNDbGlja2VhYmxlID0gZmFsc2U7XG4gICAgICAgIG9wdGlvbkNsYXNzTmFtZSArPSBcImlzLWRpdmlkZXIgXCI7XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb24ubGFiZWwpIHtcbiAgICAgICAgbGFiZWwgPSBgPHNwYW4+JHtvcHRpb24ubGFiZWx9PC9zcGFuPmA7XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb24uaWNvbikge1xuICAgICAgICBzdHJJY29uID0gYDxkaXYgY2xhc3M9XCJjYXAtY29udGV4dC1tZW51X2l0ZW1faWNvblwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxzdmcgdmlld0JveD1cIjAgMCAyNCAyNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIiR7b3B0aW9uLmljb259XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PmA7XG4gICAgICB9XG5cbiAgICAgIGxldCBvcHRpb25TdHJIdG1sID0gYFxuICAgICAgICA8ZGl2IGNsYXNzPVwiY2FwLWNvbnRleHQtbWVudV9pdGVtICR7b3B0aW9uQ2xhc3NOYW1lfVwiPlxuICAgICAgICAgICR7c3RySWNvbn1cbiAgICAgICAgICAke2xhYmVsfVxuICAgICAgICA8L2Rpdj5gO1xuXG4gICAgICBsZXQgJG9wdGlvbiA9IGRvbS5jcmVhdGVFbGVtZW50RnJvbUhUTUwob3B0aW9uU3RySHRtbCk7XG5cbiAgICAgIGlmIChpc0VuYWJsZWQgJiYgaXNDbGlja2VhYmxlKSB7XG4gICAgICAgICRvcHRpb24uYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChldnRDbGljaykgPT5cbiAgICAgICAgICBvcHRpb24ub25DbGljayh7XG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBldnQ6IGV2dENsaWNrLFxuICAgICAgICAgICAgZGF0ZSxcbiAgICAgICAgICAgIGl0ZW0sXG4gICAgICAgICAgICBzZWxlY3RlZCxcbiAgICAgICAgICAgIHRhYlNlbGVjdGVkLFxuICAgICAgICAgICAgdGFyZ2V0LFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAkb3B0aW9uLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZXZ0Q2xpY2spID0+IHtcbiAgICAgICAgICBldnRDbGljay5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIGV2dENsaWNrLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgJGNvbnRleHRNZW51LmFwcGVuZCgkb3B0aW9uKTtcbiAgICAgIGhhc1NvbWVvcHRpb24gPSB0cnVlO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGVsZW06ICRjb250ZXh0TWVudUNvbnRhaW5lcixcbiAgICAgIGlzVmlzaWJsZSxcbiAgICB9O1xuICB9LFxufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFFQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBREE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUZBO0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBRkE7QUFPQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFRQTtBQVFBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUZBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFLQTtBQVBBO0FBQ0E7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUdBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRkE7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUhBO0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBSEE7QUFRQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBSEE7QUFRQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBSEE7QUFRQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUhBO0FBU0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBSEE7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBREE7QUFIQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUtBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUpBO0FBSEE7QUFXQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFIQTtBQVNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSkE7QUFNQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUpBO0FBTUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUlBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFJQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBSEE7QUFVQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBSUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFJQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQTdDQTtBQStDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBN0NBO0FBK0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBN0NBO0FBK0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUE3Q0E7QUErQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBR0E7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUpBO0FBSEE7QUFXQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRkE7QUFLQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRkE7QUFLQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFIQTtBQVVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTEE7QUFIQTtBQVlBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFOQTtBQUhBO0FBYUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBSEE7QUFVQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFMQTtBQU9BO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSEE7QUFXQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVFBO0FBQ0E7QUFBQTtBQUNBO0FBREE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUpBO0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFNQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBREE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVBBO0FBU0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBUEE7QUFTQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBUEE7QUFTQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUtBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU9BO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUhBO0FBVUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFIQTtBQVVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUdBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUlBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFJQTtBQUNBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBSUE7QUFFQTtBQUNBO0FBQ0E7QUFGQTtBQUtBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBT0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQU9BO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFsRUE7QUFDQTtBQW9FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSEE7QUFTQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFIQTtBQVNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFWQTtBQVlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBUEE7QUFVQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFQQTtBQVNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVZBO0FBWUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFHQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRkE7QUFLQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUZBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSkE7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVhBO0FBYUE7QUFJQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUlBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUxBO0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFQQTtBQVVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBcDdJQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./src/util/tableElements.js\n");
|
|
259
259
|
|
|
260
260
|
/***/ }),
|
|
261
261
|
|