1(()=>{var __webpack_modules__={17:(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__)=>{"use strict";eval('\n;// CONCATENATED MODULE: ./js/basicos.js\nfunction medidas() {\n var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n var h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;\n h > w ? document.body.classList.add("portrait") : document.body.classList.remove("portrait");\n h < w ? document.body.classList.add("landscape") : document.body.classList.remove("landscape");\n}\n;\nvar body = document.body,\n html = document.documentElement;\nvar height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);\nfunction basicos_visible(el) {\n if (el) {\n const antelacion = 250;\n const elem = el.getBoundingClientRect();\n var altura = document.documentElement.clientHeight;\n var isVisible = elem.top >= 0 && elem.top <= altura || elem.bottom >= 0 && elem.top <= altura || elem.top < altura + antelacion && elem.bottom > 0;\n return isVisible;\n } else {\n return false;\n }\n}\nfunction basicos_mostrar(clases) {\n var mostrar = document.querySelectorAll(clases);\n for (var i = 0; i < mostrar.length; i++) {\n mostrar[i].style.opacity = 1;\n mostrar[i].style.visibility = "visible";\n mostrar[i].style.display = "block";\n }\n}\nfunction basicos_ocultar(clases) {\n var ocultar = document.querySelectorAll(clases);\n for (var i = 0; i < ocultar.length; i++) {\n ocultar[i].style.opacity = 0;\n ocultar[i].style.visibility = "hidden";\n ocultar[i].style.visibility = "none";\n }\n}\n// EXTERNAL MODULE: ../deps/phoenix_html/priv/static/phoenix_html.js\nvar phoenix_html = __webpack_require__(458);\n// EXTERNAL MODULE: ./vendor/jquery.slugger.js\nvar jquery_slugger = __webpack_require__(70);\n;// CONCATENATED MODULE: ./js/publi.js\njQuery("document").ready(function ($) {\n cambio_apanhos();\n apanhos_swip();\n});\nfunction apanhos_swip() {\n if ($(\'.swiper-socias\').length) {\n var width = $(window).width();\n if (width > 767) {\n $(\'.swiper-socias .swiper-wrapper\').css("height", width / 2.1);\n }\n }\n}\n$(function () {\n var $window = $(window);\n var width = $window.width();\n var height = $window.height();\n setInterval(function () {\n if (width != $window.width() || height != $window.height()) {\n width = $window.width();\n height = $window.height();\n cambio_apanhos();\n }\n }, 300);\n});\nfunction cambio_apanhos() {\n $(\'.videos .carousel-inner\').height($(\'.videos .carousel-item.active\').outerHeight());\n var width = $(window).width();\n if ($(window).width() > 769) {\n $(".contenido .contenido .real .todo-el-ancho").each(function () {\n console.log("cambio_apanhos");\n var prop = $(this).attr("data-proporcion");\n var width = $(this).width();\n $(this).css("padding-bottom", function () {\n return prop * width / 100;\n });\n });\n var fijo_compartir = $(".fijo .compartir");\n if (false) { var left; }\n var left = (width - $("#menu-arriba .container").width()) / 2;\n var video_texto = $(".video-texto");\n if (video_texto) {\n video_texto.css("padding-left", left);\n }\n $(".destacada1 .elem1.noencalada .resumen:first-of-type .responsively-lazy").css("overflow", "hidden").css("padding-bottom", "40%");\n $(".destacada1 .elem1.noencalada .resumen:first-of-type .responsively-lazy img").css("top", "-20%").css("height", "140%");\n } else {\n $(".contenido .contenido img").css("width", "100%");\n }\n\n //var fotos = html.match(/{{([A-z.jpg]*)}}/);\n //$(\'video,audio\').not(\'.no-mep,.fullscreen-bg__video\').mediaelementplayer({\n //var player = new MediaElement("video-principal", {\n // var mediaE = document.getElementById("video-principal");\n // console.log("xxx")\n // console.log(mediaE);\n // var player = new MediaElement(mediaE, {\n // iconSprite: \'/js/mediaelement/mejs-controls.svg\',\n // stretching: \'responsive\' ,\n // });\n\n var iframes = document.querySelectorAll(\'.articulo-contenido iframe\');
1\n if (iframes && iframes.legth) {\n for (var i = 0; i < iframes.length; i++) {\n var medidas = iframes[i].Element.getBoundingClientRect();\n var iframe_w = medidas.width;\n var h = iframes[i].getAttribute("height");\n var w = iframes[i].getAttribute("width");\n var altura = iframe_w / w * h;\n iframes[i].style.height = altura;\n }\n }\n}\n;\n$(\'.modal\').on(\'shown.bs.modal\', function (e) {\n var modal_box = $(this).find(\'.modal\');\n modal_box.css("display", "flex !important ");\n var modal = $(this).find(\'.modal-dialog\');\n var modalc = $(this).find(\'.modal-content\');\n var modalo = $(this).find(\'.mejs__container iframe\');\n var rw = modal.width();\n var h = $(this).find(\'.mejs__container iframe\').attr("height");\n var w = $(this).find(\'.mejs__container iframe\').attr("width");\n var altura = rw / w * h;\n $(this).find(\'.mejs__layer\').css("height", altura).css("width", rw);\n $(this).find(\'.mejs__container\').css("height", altura).css("width", rw);\n modalo.css("width", rw).css("height", altura);\n //modalmodal.css(\'margin-top\', (($(window).height() - (parseInt(modalc.height() )))/2));\n});\n$(\'iframe-off\').each(function () {\n function injectCSS() {\n $iframe.contents().find(\'head\').append($("<style type=\'text/css\'>" + ".player .vp-cards, .player .vp-controls { display: none !important; } " + "</style>"));\n }\n var $iframe = $(this);\n $iframe.on(\'load\', injectCSS);\n injectCSS();\n});\nfunction eliminarID(elementId) {\n var element = document.getElementById(elementId);\n element.parentNode.removeChild(element);\n}\nif (document.getElementById("close-faldon")) {\n document.getElementById("close-faldon").addEventListener("click", function () {\n eliminarID("faldon-container");\n });\n}\n// EXTERNAL MODULE: ./js/formularios.js\nvar formularios = __webpack_require__(587);\n// EXTERNAL MODULE: ./vendor/postscribe.min.js\nvar postscribe_min = __webpack_require__(782);\nvar postscribe_min_default = /*#__PURE__*/__webpack_require__.n(postscribe_min);\n;// CONCATENATED MODULE: ../deps/phoenix/priv/static/phoenix.mjs\n// js/phoenix/utils.js\nvar closure = (value) => {\n if (typeof value === "function") {\n return value;\n } else {\n let closure2 = function() {\n return value;\n };\n return closure2;\n }\n};\n\n// js/phoenix/constants.js\nvar globalSelf = typeof self !== "undefined" ? self : null;\nvar phxWindow = typeof window !== "undefined" ? window : null;\nvar global = globalSelf || phxWindow || globalThis;\nvar DEFAULT_VSN = "2.0.0";\nvar SOCKET_STATES = { connecting: 0, open: 1, closing: 2, closed: 3 };\nvar MAX_LONGPOLL_BATCH_SIZE = 100;\nvar DEFAULT_TIMEOUT = 1e4;\nvar WS_CLOSE_NORMAL = 1e3;\nvar CHANNEL_STATES = {\n closed: "closed",\n errored: "errored",\n joined: "joined",\n joining: "joining",\n leav
1ing: "leaving"\n};\nvar CHANNEL_EVENTS = {\n close: "phx_close",\n error: "phx_error",\n join: "phx_join",\n reply: "phx_reply",\n leave: "phx_leave"\n};\nvar TRANSPORTS = {\n longpoll: "longpoll",\n websocket: "websocket"\n};\nvar XHR_STATES = {\n complete: 4\n};\nvar AUTH_TOKEN_PREFIX = "base64url.bearer.phx.";\n\n// js/phoenix/push.js\nvar Push = class {\n constructor(channel, event, payload, timeout) {\n this.channel = channel;\n this.event = event;\n this.payload = payload || function() {\n return {};\n };\n this.receivedResp = null;\n this.timeout = timeout;\n this.timeoutTimer = null;\n this.recHooks = [];\n this.sent = false;\n }\n /**\n *\n * @param {number} timeout\n */\n resend(timeout) {\n this.timeout = timeout;\n this.reset();\n this.send();\n }\n /**\n *\n */\n send() {\n if (this.hasReceived("timeout")) {\n return;\n }\n this.startTimeout();\n this.sent = true;\n this.channel.socket.push({\n topic: this.channel.topic,\n event: this.event,\n payload: this.payload(),\n ref: this.ref,\n join_ref: this.channel.joinRef()\n });\n }\n /**\n *\n * @param {*} status\n * @param {*} callback\n */\n receive(status, callback) {\n if (this.hasReceived(status)) {\n callback(this.receivedResp.response);\n }\n this.recHooks.push({ status, callback });\n return this;\n }\n /**\n * @private\n */\n reset() {\n this.cancelRefEvent();\n this.ref = null;\n this.refEvent = null;\n this.receivedResp = null;\n this.sent = false;\n }\n /**\n * @private\n */\n matchReceive({ status, response, _ref }) {\n this.recHooks.filter((h) => h.status === status).forEach((h) => h.callback(response));\n }\n /**\n * @private\n */\n cancelRefEvent() {\n if (!this.refEvent) {\n return;\n }\n this.channel.off(this.refEvent);\n }\n /**\n * @private\n */\n cancelTimeout() {\n clearTimeout(this.timeoutTimer);\n this.timeoutTimer = null;\n }\n /**\n * @private\n */\n startTimeout() {\n if (this.timeoutTimer) {\n this.cancelTimeout();\n }\n this.ref = this.channel.socket.makeRef();\n this.refEvent = this.channel.replyEventName(this.ref);\n this.channel.on(this.refEvent, (payload) => {\n this.cancelRefEvent();\n this.cancelTimeout();\n this.receivedResp = payload;\n this.matchReceive(payload);\n });\n this.timeoutTimer = setTimeout(() => {\n this.trigger("timeout", {});\n }, this.timeout);\n }\n /**\n * @private\n */\n hasReceived(status) {\n return this.receivedResp && this.receivedResp.status === status;\n }\n /**\n * @private\n */\n trigger(status, response) {\n this.channel.trigger(this.refEvent, { status, response });\n }\n};\n\n// js/phoenix/timer.js\nvar Timer = class {\n constructor(callback, timerCalc) {\n this.callback = callback;\n this.timerCalc = timerCalc;\n this.timer = null;\n this.tries = 0;\n }\n reset() {\n this.tries = 0;\n clearTimeout(this.timer);\n }\n /**\n * Cancels any previous scheduleTimeout and schedules callback\n */\n scheduleTimeout() {\n clearTimeout(this.timer);\n this.timer = setTimeout(() => {\n this.tries = this.tries + 1;\n this.callback();\n }, this.timerCalc(this.tries + 1));\n }\n};\n\n// js/phoenix/channel.js\nvar Channel = class {\n constructor(topic, params, socket) {\n this.state = CHANNEL_STATES.closed;\n this.topic = topic;\n this.params = closure(params || {});\n this.socket = socket;\n this.bindings = [];\n this.bindingRef = 0;\n this.timeout = this.socket.timeout;\n this.joinedOnce = false;\n this.joinPush = new Push(this, CHANNEL_EVENTS.join, this.params, this.timeout);\n this.pushBuffer = [];\n this.stateChangeRefs = [];\n this.rejoinTimer = new Timer(() => {\n if (this.socket.isConnected()) {\n this.rejoin();\n }\n }, this.socket.rejoinAfterMs);\n this.stateChangeRefs.push(this.socket.onError(() => this.rejoinTimer.reset()));\n this.stateChangeRefs.push(\n this.socket.onOpen(() =>
1 {\n this.rejoinTimer.reset();\n if (this.isErrored()) {\n this.rejoin();\n }\n })\n );\n this.joinPush.receive("ok", () => {\n this.state = CHANNEL_STATES.joined;\n this.rejoinTimer.reset();\n this.pushBuffer.forEach((pushEvent) => pushEvent.send());\n this.pushBuffer = [];\n });\n this.joinPush.receive("error", () => {\n this.state = CHANNEL_STATES.errored;\n if (this.socket.isConnected()) {\n this.rejoinTimer.scheduleTimeout();\n }\n });\n this.onClose(() => {\n this.rejoinTimer.reset();\n if (this.socket.hasLogger()) this.socket.log("channel", `close ${this.topic} ${this.joinRef()}`);\n this.state = CHANNEL_STATES.closed;\n this.socket.remove(this);\n });\n this.onError((reason) => {\n if (this.socket.hasLogger()) this.socket.log("channel", `error ${this.topic}`, reason);\n if (this.isJoining()) {\n this.joinPush.reset();\n }\n this.state = CHANNEL_STATES.errored;\n if (this.socket.isConnected()) {\n this.rejoinTimer.scheduleTimeout();\n }\n });\n this.joinPush.receive("timeout", () => {\n if (this.socket.hasLogger()) this.socket.log("channel", `timeout ${this.topic} (${this.joinRef()})`, this.joinPush.timeout);\n let leavePush = new Push(this, CHANNEL_EVENTS.leave, closure({}), this.timeout);\n leavePush.send();\n this.state = CHANNEL_STATES.errored;\n this.joinPush.reset();\n if (this.socket.isConnected()) {\n this.rejoinTimer.scheduleTimeout();\n }\n });\n this.on(CHANNEL_EVENTS.reply, (payload, ref) => {\n this.trigger(this.replyEventName(ref), payload);\n });\n }\n /**\n * Join the channel\n * @param {integer} timeout\n * @returns {Push}\n */\n join(timeout = this.timeout) {\n if (this.joinedOnce) {\n throw new Error("tried to join multiple times. \'join\' can only be called a single time per channel instance");\n } else {\n this.timeout = timeout;\n this.joinedOnce = true;\n this.rejoin();\n return this.joinPush;\n }\n }\n /**\n * Hook into channel close\n * @param {Function} callback\n */\n onClose(callback) {\n this.on(CHANNEL_EVENTS.close, callback);\n }\n /**\n * Hook into channel errors\n * @param {Function} callback\n */\n onError(callback) {\n return this.on(CHANNEL_EVENTS.error, (reason) => callback(reason));\n }\n /**\n * Subscribes on channel events\n *\n * Subscription returns a ref counter, which can be used later to\n * unsubscribe the exact event listener\n *\n * @example\n * const ref1 = channel.on("event", do_stuff)\n * const ref2 = channel.on("event", do_other_stuff)\n * channel.off("event", ref1)\n * // Since unsubscription, do_stuff won\'t fire,\n * // while do_other_stuff will keep firing on the "event"\n *\n * @param {string} event\n * @param {Function} callback\n * @returns {integer} ref\n */\n on(event, callback) {\n let ref = this.bindingRef++;\n this.bindings.push({ event, ref, callback });\n return ref;\n }\n /**\n * Unsubscribes off of channel events\n *\n * Use the ref returned from a channel.on() to unsubscribe one\n * handler, or pass nothing for the ref to unsubscribe all\n * handlers for the given event.\n *\n * @example\n * // Unsubscribe the do_stuff handler\n * const ref1 = channel.on("event", do_stuff)\n * channel.off("event", ref1)\n *\n * // Unsubscribe all handlers from event\n * channel.off("event")\n *\n * @param {string} event\n * @param {integer} ref\n */\n off(event, ref) {\n this.bindings = this.bindings.filter((bind) => {\n return !(bind.event === event && (typeof ref === "undefined" || ref === bind.ref));\n });\n }\n /**\n * @private\n */\n canPush() {\n return this.socket.isConnected() && this.isJoined();\n }\n /**\n * Sends a message `event` to phoenix with the payload `payload`.\n * Phoenix receives this in the `handle_in(event, payload, socket)`\n * function. if phoenix replies or it times out (default 10000ms),\n * then optionally the reply can be received.\n *\n * @example\n * channel.push("event")\n * .receive("ok", payload => console.log("phoenix replied:", payload))\n * .receive("error", err => console.log("phoenix errored", err))\n * .receive("timeout", () => console.log("timed out pushing"))\n * @param {string} event\n * @param {Object} payload\n * @param {number} [timeout]\n * @returns {Push}\n */\n push(event, payload, timeout = this.timeout) {\n payload = payload || {};\n if (!this.joinedOnce) {\n throw new Error(`tried to push \'${event}\' to \'${this.topic}\' before joining. Use channel.join() before pushing events`);\n }
1\n let pushEvent = new Push(this, event, function() {\n return payload;\n }, timeout);\n if (this.canPush()) {\n pushEvent.send();\n } else {\n pushEvent.startTimeout();\n this.pushBuffer.push(pushEvent);\n }\n return pushEvent;\n }\n /** Leaves the channel\n *\n * Unsubscribes from server events, and\n * instructs channel to terminate on server\n *\n * Triggers onClose() hooks\n *\n * To receive leave acknowledgements, use the `receive`\n * hook to bind to the server ack, ie:\n *\n * @example\n * channel.leave().receive("ok", () => alert("left!") )\n *\n * @param {integer} timeout\n * @returns {Push}\n */\n leave(timeout = this.timeout) {\n this.rejoinTimer.reset();\n this.joinPush.cancelTimeout();\n this.state = CHANNEL_STATES.leaving;\n let onClose = () => {\n if (this.socket.hasLogger()) this.socket.log("channel", `leave ${this.topic}`);\n this.trigger(CHANNEL_EVENTS.close, "leave");\n };\n let leavePush = new Push(this, CHANNEL_EVENTS.leave, closure({}), timeout);\n leavePush.receive("ok", () => onClose()).receive("timeout", () => onClose());\n leavePush.send();\n if (!this.canPush()) {\n leavePush.trigger("ok", {});\n }\n return leavePush;\n }\n /**\n * Overridable message hook\n *\n * Receives all events for specialized message handling\n * before dispatching to the channel callbacks.\n *\n * Must return the payload, modified or unmodified\n * @param {string} event\n * @param {Object} payload\n * @param {integer} ref\n * @returns {Object}\n */\n onMessage(_event, payload, _ref) {\n return payload;\n }\n /**\n * @private\n */\n isMember(topic, event, payload, joinRef) {\n if (this.topic !== topic) {\n return false;\n }\n if (joinRef && joinRef !== this.joinRef()) {\n if (this.socket.hasLogger()) this.socket.log("channel", "dropping outdated message", { topic, event, payload, joinRef });\n return false;\n } else {\n return true;\n }\n }\n /**\n * @private\n */\n joinRef() {\n return this.joinPush.ref;\n }\n /**\n * @private\n */\n rejoin(timeout = this.timeout) {\n if (this.isLeaving()) {\n return;\n }\n this.socket.leaveOpenTopic(this.topic);\n this.state = CHANNEL_STATES.joining;\n this.joinPush.resend(timeout);\n }\n /**\n * @private\n */\n trigger(event, payload, ref, joinRef) {\n let handledPayload = this.onMessage(event, payload, ref, joinRef);\n if (payload && !handledPayload) {\n throw new Error("channel onMessage callbacks must return the payload, modified or unmodified");\n }\n let eventBindings = this.bindings.filter((bind) => bind.event === event);\n for (let i = 0; i < eventBindings.length; i++) {\n let bind = eventBindings[i];\n bind.callback(handledPayload, ref, joinRef || this.joinRef());\n }\n }\n /**\n * @private\n */\n replyEventName(ref) {\n return `chan_reply_${ref}`;\n }\n /**\n * @private\n */\n isClosed() {\n return this.state === CHANNEL_STATES.closed;\n }\n /**\n * @private\n */\n isErrored() {\n return this.state === CHANNEL_STATES.errored;\n }\n /**\n * @private\n */\n isJoined() {\n return this.state === CHANNEL_STATES.joined;\n }\n /**\n * @private\n */\n isJoining() {\n return this.state === CHANNEL_STATES.joining;\n }\n /**\n * @private\n */\n isLeaving() {\n return this.state === CHANNEL_STATES.leaving;\n }\n};\n\n// js/phoenix/ajax.js\nvar Ajax = class {\n static request(method, endPoint, headers, body, timeout, ontimeout, callback) {\n if (global.XDomainRequest) {\n let req = new global.XDomainRequest();\n return this.xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback);\n } else if (global.XMLHttpRequest) {\n let req = new global.XMLHttpRequest();\n return this.xhrRequest(req, method, endPoint, headers, body, timeout, ontimeout, callback);\n } else if (global.fetch && global.AbortController) {\n return this.fetchRequest(method, endPoint, headers, body, timeout, ontimeout, callback);\n } else {\n throw new Error("No suitable XMLHttpRequest implementation found");\n }\n }\n static fetchRequest(method, endPoint, headers, body, timeout, ontimeout, callback) {\n let options = {\n method,\n headers,\n body\n };
1\n let controller = null;\n if (timeout) {\n controller = new AbortController();\n const _timeoutId = setTimeout(() => controller.abort(), timeout);\n options.signal = controller.signal;\n }\n global.fetch(endPoint, options).then((response) => response.text()).then((data) => this.parseJSON(data)).then((data) => callback && callback(data)).catch((err) => {\n if (err.name === "AbortError" && ontimeout) {\n ontimeout();\n } else {\n callback && callback(null);\n }\n });\n return controller;\n }\n static xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback) {\n req.timeout = timeout;\n req.open(method, endPoint);\n req.onload = () => {\n let response = this.parseJSON(req.responseText);\n callback && callback(response);\n };\n if (ontimeout) {\n req.ontimeout = ontimeout;\n }\n req.onprogress = () => {\n };\n req.send(body);\n return req;\n }\n static xhrRequest(req, method, endPoint, headers, body, timeout, ontimeout, callback) {\n req.open(method, endPoint, true);\n req.timeout = timeout;\n for (let [key, value] of Object.entries(headers)) {\n req.setRequestHeader(key, value);\n }\n req.onerror = () => callback && callback(null);\n req.onreadystatechange = () => {\n if (req.readyState === XHR_STATES.complete && callback) {\n let response = this.parseJSON(req.responseText);\n callback(response);\n }\n };\n if (ontimeout) {\n req.ontimeout = ontimeout;\n }\n req.send(body);\n return req;\n }\n static parseJSON(resp) {\n if (!resp || resp === "") {\n return null;\n }\n try {\n return JSON.parse(resp);\n } catch {\n console && console.log("failed to parse JSON response", resp);\n return null;\n }\n }\n static serialize(obj, parentKey) {\n let queryStr = [];\n for (var key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) {\n continue;\n }\n let paramKey = parentKey ? `${parentKey}[${key}]` : key;\n let paramVal = obj[key];\n if (typeof paramVal === "object") {\n queryStr.push(this.serialize(paramVal, paramKey));\n } else {\n queryStr.push(encodeURIComponent(paramKey) + "=" + encodeURIComponent(paramVal));\n }\n }\n return queryStr.join("&");\n }\n static appendParams(url, params) {\n if (Object.keys(params).length === 0) {\n return url;\n }\n let prefix = url.match(/\\?/) ? "&" : "?";\n return `${url}${prefix}${this.serialize(params)}`;\n }\n};\n\n// js/phoenix/longpoll.js\nvar arrayBufferToBase64 = (buffer) => {\n let binary = "";\n let bytes = new Uint8Array(buffer);\n let len = bytes.byteLength;\n for (let i = 0; i < len; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n};\nvar LongPoll = class {\n constructor(endPoint, protocols) {\n if (protocols && protocols.length === 2 && protocols[1].startsWith(AUTH_TOKEN_PREFIX)) {\n this.authToken = atob(protocols[1].slice(AUTH_TOKEN_PREFIX.length));\n }\n this.endPoint = null;\n this.token = null;\n this.skipHeartbeat = true;\n this.reqs = /* @__PURE__ */ new Set();\n this.awaitingBatchAck = false;\n this.currentBatch = null;\n this.currentBatchTimer = null;\n this.batchBuffer = [];\n this.onopen = function() {\n };\n this.onerror = function() {\n };\n this.onmessage = function() {\n };\n this.onclose = function() {\n };\n this.pollEndpoint = this.normalizeEndpoint(endPoint);\n this.readyState = SOCKET_STATES.connecting;\n setTimeout(() => this.poll(), 0);\n }\n normalizeEndpoint(endPoint) {\n return endPoint.replace("ws://", "http://").replace("wss://", "https://").replace(new RegExp("(.*)/" + TRANSPORTS.websocket), "$1/" + TRANSPORTS.longpoll);\n }\n endpointURL() {\n return Ajax.appendParams(this.pollEndpoint, { token: this.token });\n }\n closeAndRetry(code, reason, wasClean) {\n this.close(code, reason, wasClean);\n this.readyState = SOCKET_STATES.connecting;\n }
1\n ontimeout() {\n this.onerror("timeout");\n this.closeAndRetry(1005, "timeout", false);\n }\n isActive() {\n return this.readyState === SOCKET_STATES.open || this.readyState === SOCKET_STATES.connecting;\n }\n poll() {\n const headers = { "Accept": "application/json" };\n if (this.authToken) {\n headers["X-Phoenix-AuthToken"] = this.authToken;\n }\n this.ajax("GET", headers, null, () => this.ontimeout(), (resp) => {\n if (resp) {\n var { status, token, messages } = resp;\n if (status === 410 && this.token !== null) {\n this.onerror(410);\n this.closeAndRetry(3410, "session_gone", false);\n return;\n }\n this.token = token;\n } else {\n status = 0;\n }\n switch (status) {\n case 200:\n messages.forEach((msg) => {\n setTimeout(() => this.onmessage({ data: msg }), 0);\n });\n this.poll();\n break;\n case 204:\n this.poll();\n break;\n case 410:\n this.readyState = SOCKET_STATES.open;\n this.onopen({});\n this.poll();\n break;\n case 403:\n this.onerror(403);\n this.close(1008, "forbidden", false);\n break;\n case 0:\n case 500:\n this.onerror(500);\n this.closeAndRetry(1011, "internal server error", 500);\n break;\n default:\n throw new Error(`unhandled poll status ${status}`);\n }\n });\n }\n // we collect all pushes within the current event loop by\n // setTimeout 0, which optimizes back-to-back procedural\n // pushes against an empty buffer\n send(body) {\n if (typeof body !== "string") {\n body = arrayBufferToBase64(body);\n }\n if (this.currentBatch) {\n this.currentBatch.push(body);\n } else if (this.awaitingBatchAck) {\n this.batchBuffer.push(body);\n } else {\n this.currentBatch = [body];\n this.currentBatchTimer = setTimeout(() => {\n this.batchSend(this.currentBatch);\n this.currentBatch = null;\n }, 0);\n }\n }\n batchSend(messages, offset = 0) {\n this.awaitingBatchAck = true;\n const next = offset + MAX_LONGPOLL_BATCH_SIZE;\n const batch = messages.slice(offset, next);\n this.ajax("POST", { "Content-Type": "application/x-ndjson" }, batch.join("\\n"), () => this.onerror("timeout"), (resp) => {\n if (!resp || resp.status !== 200) {\n this.awaitingBatchAck = false;\n this.onerror(resp && resp.status);\n this.closeAndRetry(1011, "internal server error", false);\n } else if (next < messages.length) {\n this.batchSend(messages, next);\n } else if (this.batchBuffer.length > 0) {\n this.batchSend(this.batchBuffer);\n this.batchBuffer = [];\n } else {\n this.awaitingBatchAck = false;\n }\n });\n }\n close(code, reason, wasClean) {\n for (let req of this.reqs) {\n req.abort();\n }\n this.readyState = SOCKET_STATES.closed;\n let opts = Object.assign({ code: 1e3, reason: void 0, wasClean: true }, { code, reason, wasClean });\n this.batchBuffer = [];\n clearTimeout(this.currentBatchTimer);\n this.currentBatchTimer = null;\n if (typeof CloseEvent !== "undefined") {\n this.onclose(new CloseEvent("close", opts));\n } else {\n this.onclose(opts);\n }\n }\n ajax(method, headers, body, onCallerTimeout, callback) {\n let req;\n let ontimeout = () => {\n this.reqs.delete(req);\n onCallerTimeout();\n };\n req = Ajax.request(method, this.endpointURL(), headers, body, this.timeout, ontimeout, (resp) => {\n this.reqs.delete(req);\n if (this.isActive()) {\n callback(resp);\n }\n });\n this.reqs.add(req);\n }\n};\n\n// js/phoenix/presence.js\nvar Presence = class _Presence {\n constructor(channel, opts = {}) {\n let events = opts.events || { state: "presence_state", diff: "presence_diff" };\n this.state = /* @__PURE__ */ Object.create(null);\n this.pendingDiffs = [];\n this.channel = channel;\n this.joinRef = null;
1\n this.caller = {\n onJoin: function() {\n },\n onLeave: function() {\n },\n onSync: function() {\n }\n };\n this.channel.on(events.state, (newState) => {\n let { onJoin, onLeave, onSync } = this.caller;\n this.joinRef = this.channel.joinRef();\n this.state = _Presence.syncState(this.state, newState, onJoin, onLeave);\n this.pendingDiffs.forEach((diff) => {\n this.state = _Presence.syncDiff(this.state, diff, onJoin, onLeave);\n });\n this.pendingDiffs = [];\n onSync();\n });\n this.channel.on(events.diff, (diff) => {\n let { onJoin, onLeave, onSync } = this.caller;\n if (this.inPendingSyncState()) {\n this.pendingDiffs.push(diff);\n } else {\n this.state = _Presence.syncDiff(this.state, diff, onJoin, onLeave);\n onSync();\n }\n });\n }\n onJoin(callback) {\n this.caller.onJoin = callback;\n }\n onLeave(callback) {\n this.caller.onLeave = callback;\n }\n onSync(callback) {\n this.caller.onSync = callback;\n }\n list(by) {\n return _Presence.list(this.state, by);\n }\n inPendingSyncState() {\n return !this.joinRef || this.joinRef !== this.channel.joinRef();\n }\n // lower-level public static API\n /**\n * Used to sync the list of presences on the server\n * with the client\'s state. An optional `onJoin` and `onLeave` callback can\n * be provided to react to changes in the client\'s local presences across\n * disconnects and reconnects with the server.\n *\n * @returns {Presence}\n */\n static syncState(currentState, newState, onJoin, onLeave) {\n let state = this.toNullProtoObj(this.clone(currentState));\n newState = this.toNullProtoObj(newState);\n let joins = /* @__PURE__ */ Object.create(null);\n let leaves = /* @__PURE__ */ Object.create(null);\n this.map(state, (key, presence) => {\n if (!newState[key]) {\n leaves[key] = presence;\n }\n });\n this.map(newState, (key, newPresence) => {\n let currentPresence = state[key];\n if (currentPresence) {\n let newRefs = newPresence.metas.map((m) => m.phx_ref);\n let curRefs = currentPresence.metas.map((m) => m.phx_ref);\n let joinedMetas = newPresence.metas.filter((m) => curRefs.indexOf(m.phx_ref) < 0);\n let leftMetas = currentPresence.metas.filter((m) => newRefs.indexOf(m.phx_ref) < 0);\n if (joinedMetas.length > 0) {\n joins[key] = newPresence;\n joins[key].metas = joinedMetas;\n }\n if (leftMetas.length > 0) {\n leaves[key] = this.clone(currentPresence);\n leaves[key].metas = leftMetas;\n }\n } else {\n joins[key] = newPresence;\n }\n });\n return this.syncDiff(state, { joins, leaves }, onJoin, onLeave);\n }\n /**\n *\n * Used to sync a diff of presence join and leave\n * events from the server, as they happen. Like `syncState`, `syncDiff`\n * accepts optional `onJoin` and `onLeave` callbacks to react to a user\n * joining or leaving from a device.\n *\n * @returns {Presence}\n */\n static syncDiff(state, diff, onJoin, onLeave) {\n state = this.toNullProtoObj(state);\n let { joins, leaves } = this.clone(diff);\n if (!onJoin) {\n onJoin = function() {\n };\n }\n if (!onLeave) {\n onLeave = function() {\n };\n }\n this.map(joins, (key, newPresence) => {\n let currentPresence = state[key];\n state[key] = this.clone(newPresence);\n if (currentPresence) {\n let joinedRefs = state[key].metas.map((m) => m.phx_ref);\n let curMetas = currentPresence.metas.filter((m) => joinedRefs.indexOf(m.phx_ref) < 0);\n state[key].metas.unshift(...curMetas);\n }\n onJoin(key, currentPresence, newPresence);\n });\n this.map(leaves, (key, leftPresence) => {\n let currentPresence = state[key];\n if (!currentPresence) {\n return;\n }\n let refsToRemove = leftPresence.metas.map((m) => m.phx_ref);\n currentPresence.metas = currentPresence.metas.filter((p) => {\n return refsToRemove.indexOf(p.phx_ref) < 0;\n });\n onLeave(key, currentPresence, leftPresence);\n if (currentPresence.metas.length === 0) {\n delete state[key];\n }\n });\n return state;\n }\n /**\n * Returns the array of presences, with selected metadata.\n *\n * @param {Object} presences\n * @param {Function} chooser\n *\n * @returns {Presence}
1\n */\n static list(presences, chooser) {\n if (!chooser) {\n chooser = function(key, pres) {\n return pres;\n };\n }\n return this.map(presences, (key, presence) => {\n return chooser(key, presence);\n });\n }\n // private\n static map(obj, func) {\n return Object.getOwnPropertyNames(obj).map((key) => func(key, obj[key]));\n }\n // Presence keys are chosen on the server and may collide with\n // Object.prototype properties ("__proto__", "constructor", ...), so any\n // object indexed by presence key must not have a prototype chain\n //\n // TODO: replace the null-prototype objects with Maps in Phoenix 2.0\n // (breaking change for the lower-level static API)\n static toNullProtoObj(obj) {\n if (Object.getPrototypeOf(obj) === null) {\n return obj;\n }\n let cleaned = /* @__PURE__ */ Object.create(null);\n Object.getOwnPropertyNames(obj).forEach((key) => {\n cleaned[key] = obj[key];\n });\n return cleaned;\n }\n static clone(obj) {\n return JSON.parse(JSON.stringify(obj));\n }\n};\n\n// js/phoenix/serializer.js\nvar serializer_default = {\n HEADER_LENGTH: 1,\n META_LENGTH: 4,\n KINDS: { push: 0, reply: 1, broadcast: 2 },\n encode(msg, callback) {\n if (msg.payload.constructor === ArrayBuffer) {\n return callback(this.binaryEncode(msg));\n } else {\n let payload = [msg.join_ref, msg.ref, msg.topic, msg.event, msg.payload];\n return callback(JSON.stringify(payload));\n }\n },\n decode(rawPayload, callback) {\n if (rawPayload.constructor === ArrayBuffer) {\n return callback(this.binaryDecode(rawPayload));\n } else {\n let [join_ref, ref, topic, event, payload] = JSON.parse(rawPayload);\n return callback({ join_ref, ref, topic, event, payload });\n }\n },\n // private\n binaryEncode(message) {\n let { join_ref, ref, event, topic, payload } = message;\n let encoder = new TextEncoder();\n let joinRefBytes = encoder.encode(join_ref);\n let refBytes = encoder.encode(ref);\n let topicBytes = encoder.encode(topic);\n let eventBytes = encoder.encode(event);\n this.assertFieldSize(joinRefBytes.byteLength, "join_ref");\n this.assertFieldSize(refBytes.byteLength, "ref");\n this.assertFieldSize(topicBytes.byteLength, "topic");\n this.assertFieldSize(eventBytes.byteLength, "event");\n let metaLength = this.META_LENGTH + joinRefBytes.byteLength + refBytes.byteLength + topicBytes.byteLength + eventBytes.byteLength;\n let header = new ArrayBuffer(this.HEADER_LENGTH + metaLength);\n let headerBytes = new Uint8Array(header);\n let view = new DataView(header);\n let offset = 0;\n view.setUint8(offset++, this.KINDS.push);\n view.setUint8(offset++, joinRefBytes.byteLength);\n view.setUint8(offset++, refBytes.byteLength);\n view.setUint8(offset++, topicBytes.byteLength);\n view.setUint8(offset++, eventBytes.byteLength);\n headerBytes.set(joinRefBytes, offset);\n offset += joinRefBytes.byteLength;\n headerBytes.set(refBytes, offset);\n offset += refBytes.byteLength;\n headerBytes.set(topicBytes, offset);\n offset += topicBytes.byteLength;\n headerBytes.set(eventBytes, offset);\n offset += eventBytes.byteLength;\n var combined = new Uint8Array(header.byteLength + payload.byteLength);\n combined.set(headerBytes, 0);\n combined.set(new Uint8Array(payload), header.byteLength);\n return combined.buffer;\n },\n assertFieldSize(size, name) {\n if (size > 255) {\n throw new Error(`unable to convert ${name} to binary: must be less than or equal to 255 bytes, but is ${size} bytes`);\n }\n },\n binaryDecode(buffer) {\n let view = new DataView(buffer);\n let kind = view.getUint8(0);\n let decoder = new TextDecoder();\n switch (kind) {\n case this.KINDS.push:\n return this.decodePush(buffer, view, decoder);\n case this.KINDS.reply:\n return this.decodeReply(buffer, view, decoder);\n case this.KINDS.broadcast:\n return this.decodeBroadcast(buffer, view, decoder);\n }\n },\n decodePush(buffer, view, decoder) {\n let joinRefSize = view.getUint8(1);\n let topicSize = view.getUint8(2);\n let eventSize = view.getUint8(3);\n let offset = this.HEADER_LENGTH + this.META_LENGTH - 1;\n let joinRef = decoder.decode(buffer.slice(offset, offset + joinRefSize));\n offset = offset + joinRefSize;\n let topic = decoder.decode(buffer.slice(offset, offset + topicSize));\n offset = offset + topicSize;\n let event = decoder.decode(buffer.slice(offset, offset + eventSize));\n offset = offset + eventSize;\n let data = buffer.slice(offset, buffer.byteLength);\n return { join_ref: joinRef, ref: null, topic, event, payload: data };\n },\n decodeReply(buffer, view, decoder) {\n let joinRefSize = view.getUint8(1);\n let refSize = view.getUint8(2);\n let topicSize = view.getUint8(3);\n let eventSize = view.getUint8(4);\n let offset = this.HEADER_LENGTH + this.META_LENGTH;\n let joinRef = decoder.decode(buffer.slice(offset, offset + joinRefSize));\n offset = offset + joinRefSize;\n let ref = decoder.decode(buffer.slice(offset, offset + refSize));\n offset = offset + refSize;\n let topic = decoder.decode(buffer.slice(offset, offset + topicSize));\n offset = offset + topicSize;\n let event = decoder.decode(buffer.slice(offset, offset + eventSize));\n offset = offset + eventSize;\n let data = buffer.slice(offset, buffer.byteLength);\n let payload = { status: event, response: data };\n return { join_ref: joinRef, ref, topic, event: CHANNEL_EVENTS.reply, payload };\n },\n decodeBroadcast(buffer, view, decoder) {\n let topicSize = view.getUint8(1);\n let eventSize = view.getUint8(2);\n let offset = this.HEADER_LENGTH + 2;\n let topic = decoder.decode(buffer.slice(offset, offset + topicSize));\n offset = offset + topicSize;\n let event = decoder.decode(buffer.slice(offset, offset + eventSize));\n offset = offset + eventSize;\n let data = buffer.slice(offset, buffer.byteLength);\n return { join_ref: null, ref: null, topic, event, payload: data };\n }\n};\n\n// js/phoenix/socket.js\nvar Socket = class {\n constructor(endPoint, opts = {}) {\n this.stateChangeCallbacks = { open: [], close: [], error: [], message: [] };\n this.channels = [];\n this.sendBuffer = [];\n this.ref = 0;\n this.fallbackRef = null;\n this.timeout = opts.timeout || DEFAULT_TIMEOUT;\n this.transport = opts.transport || global.WebSocket || LongPoll;\n this.primaryPassedHealthCheck = false;\n this.longPollFallbackMs = opts.longPollFallbackMs;\n this.fallbackTimer = null;\n this.sessionStore = opts.sessionStorage || global && global.sessionStorage;\n this.establishedConnections = 0;\n this.defaultEncoder = serializer_default.encode.bind(serializer_default);\n this.defaultDecoder = serializer_default.decode.bind(serializer_default);\n this.closeWasClean = true;\n this.disconnecting = false;\n this.binaryType = opts.binaryType || "arraybuffer";\n this.connectClock = 1;\n this.pageHidden = false;\n if (this.transport !== LongPoll) {\n this.encode = opts.encode || this.defaultEncoder;\n this.decode = opts.decode || this.defaultDecoder;\n } else {\n this.encode = this.defaultEncoder;\n this.decode = this.defaultDecoder;\n }\n let awaitingConnectionOnPageShow = null;\n if (phxWindow && phxWindow.addEventListener) {\n phxWindow.addEventListener("pagehide", (_e) => {\n if (this.conn) {\n this.disconnect();\n awaitingConnectionOnPageShow = this.connectClock;\n }\n });\n phxWindow.addEventListener("pageshow", (_e) => {\n if (awaitingConnectionOnPageShow === this.connectClock) {\n awaitingConnectionOnPageShow = null;\n this.connect();\n }\n });\n phxWindow.addEventListener("visibilitychange", () => {\n if (document.visibilityState === "hidden") {\n this.pageHidden = true;\n } else {\n this.pageHidden = false;\n if (!this.isConnected() && !this.closeWasClean) {\n this.teardown(() => this.connect());\n }\n }\n });\n }\n this.heartbeatIntervalMs = opts.heartbeatIntervalMs || 3e4;
1\n this.rejoinAfterMs = (tries) => {\n if (opts.rejoinAfterMs) {\n return opts.rejoinAfterMs(tries);\n } else {\n return [1e3, 2e3, 5e3][tries - 1] || 1e4;\n }\n };\n this.reconnectAfterMs = (tries) => {\n if (opts.reconnectAfterMs) {\n return opts.reconnectAfterMs(tries);\n } else {\n return [10, 50, 100, 150, 200, 250, 500, 1e3, 2e3][tries - 1] || 5e3;\n }\n };\n this.logger = opts.logger || null;\n if (!this.logger && opts.debug) {\n this.logger = (kind, msg, data) => {\n console.log(`${kind}: ${msg}`, data);\n };\n }\n this.longpollerTimeout = opts.longpollerTimeout || 2e4;\n this.params = closure(opts.params || {});\n this.endPoint = `${endPoint}/${TRANSPORTS.websocket}`;\n this.vsn = opts.vsn || DEFAULT_VSN;\n this.heartbeatTimeoutTimer = null;\n this.heartbeatTimer = null;\n this.pendingHeartbeatRef = null;\n this.reconnectTimer = new Timer(() => {\n if (this.pageHidden) {\n this.log("Not reconnecting as page is hidden!");\n this.teardown();\n return;\n }\n this.teardown(() => this.connect());\n }, this.reconnectAfterMs);\n this.authToken = opts.authToken && closure(opts.authToken);\n }\n /**\n * Returns the LongPoll transport reference\n */\n getLongPollTransport() {\n return LongPoll;\n }\n /**\n * Disconnects and replaces the active transport\n *\n * @param {Function} newTransport - The new transport class to instantiate\n *\n */\n replaceTransport(newTransport) {\n this.connectClock++;\n this.closeWasClean = true;\n clearTimeout(this.fallbackTimer);\n this.reconnectTimer.reset();\n if (this.conn) {\n this.conn.close();\n this.conn = null;\n }\n this.transport = newTransport;\n }\n /**\n * Returns the socket protocol\n *\n * @returns {string}\n */\n protocol() {\n return location.protocol.match(/^https/) ? "wss" : "ws";\n }\n /**\n * The fully qualified socket url\n *\n * @returns {string}\n */\n endPointURL() {\n let uri = Ajax.appendParams(\n Ajax.appendParams(this.endPoint, this.params()),\n { vsn: this.vsn }\n );\n if (uri.charAt(0) !== "/") {\n return uri;\n }\n if (uri.charAt(1) === "/") {\n return `${this.protocol()}:${uri}`;\n }\n return `${this.protocol()}://${location.host}${uri}`;\n }\n /**\n * Disconnects the socket\n *\n * See https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes for valid status codes.\n *\n * @param {Function} callback - Optional callback which is called after socket is disconnected.\n * @param {integer} code - A status code for disconnection (Optional).\n * @param {string} reason - A textual description of the reason to disconnect. (Optional)\n */\n disconnect(callback, code, reason) {\n this.connectClock++;\n this.disconnecting = true;\n this.closeWasClean = true;\n clearTimeout(this.fallbackTimer);\n this.reconnectTimer.reset();\n this.teardown(() => {\n this.disconnecting = false;\n callback && callback();\n }, code, reason);\n }\n /**\n *\n * @param {Object} params - The params to send when connecting, for example `{user_id: userToken}`\n *\n * Passing params to connect is deprecated; pass them in the Socket constructor instead:\n * `new Socket("/socket", {params: {user_id: userToken}})`.\n */\n connect(params) {\n if (params) {\n console && console.log("passing params to connect is deprecated. Instead pass :params to the Socket constructor");\n this.params = closure(params);\n }\n if (this.conn && !this.disconnecting) {\n return;\n }\n if (this.longPollFallbackMs && this.transport !== LongPoll) {\n this.connectWithF
1allback(LongPoll, this.longPollFallbackMs);\n } else {\n this.transportConnect();\n }\n }\n /**\n * Logs the message. Override `this.logger` for specialized logging. noops by default\n * @param {string} kind\n * @param {string} msg\n * @param {Object} data\n */\n log(kind, msg, data) {\n this.logger && this.logger(kind, msg, data);\n }\n /**\n * Returns true if a logger has been set on this socket.\n */\n hasLogger() {\n return this.logger !== null;\n }\n /**\n * Registers callbacks for connection open events\n *\n * @example socket.onOpen(function(){ console.info("the socket was opened") })\n *\n * @param {Function} callback\n */\n onOpen(callback) {\n let ref = this.makeRef();\n this.stateChangeCallbacks.open.push([ref, callback]);\n return ref;\n }\n /**\n * Registers callbacks for connection close events\n * @param {Function} callback\n */\n onClose(callback) {\n let ref = this.makeRef();\n this.stateChangeCallbacks.close.push([ref, callback]);\n return ref;\n }\n /**\n * Registers callbacks for connection error events\n *\n * @example socket.onError(function(error){ alert("An error occurred") })\n *\n * @param {Function} callback\n */\n onError(callback) {\n let ref = this.makeRef();\n this.stateChangeCallbacks.error.push([ref, callback]);\n return ref;\n }\n /**\n * Registers callbacks for connection message events\n * @param {Function} callback\n */\n onMessage(callback) {\n let ref = this.makeRef();\n this.stateChangeCallbacks.message.push([ref, callback]);\n return ref;\n }\n /**\n * Pings the server and invokes the callback with the RTT in milliseconds\n * @param {Function} callback\n *\n * Returns true if the ping was pushed or false if unable to be pushed.\n */\n ping(callback) {\n if (!this.isConnected()) {\n return false;\n }\n let ref = this.makeRef();\n let startTime = Date.now();\n this.push({ topic: "phoenix", event: "heartbeat", payload: {}, ref });\n let onMsgRef = this.onMessage((msg) => {\n if (msg.ref === ref) {\n this.off([onMsgRef]);\n callback(Date.now() - startTime);\n }\n });\n return true;\n }\n /**\n * @private\n *\n * @param {Function}\n */\n transportName(transport) {\n switch (transport) {\n case LongPoll:\n return "LongPoll";\n default:\n return transport.name;\n }\n }\n /**\n * @private\n */\n transportConnect() {\n this.connectClock++;\n this.closeWasClean = false;\n let protocols = void 0;\n if (this.authToken) {\n protocols = ["phoenix", `${AUTH_TOKEN_PREFIX}${btoa(this.authToken()).replace(/=/g, "")}`];\n }\n this.conn = new this.transport(this.endPointURL(), protocols);\n this.conn.binaryType = this.binaryType;\n this.conn.timeout = this.longpollerTimeout;\n this.conn.onopen = () => this.onConnOpen();\n this.conn.onerror = (error) => this.onConnError(error);\n this.conn.onmessage = (event) => this.onConnMessage(event);\n this.conn.onclose = (event) => this.onConnClose(event);\n }\n getSession(key) {\n return this.sessionStore && this.sessionStore.getItem(key);\n }\n storeSession(key, val) {\n this.sessionStore && this.sessionStore.setItem(key, val);\n }
1\n connectWithFallback(fallbackTransport, fallbackThreshold = 2500) {\n clearTimeout(this.fallbackTimer);\n let established = false;\n let primaryTransport = true;\n let openRef, errorRef;\n let fallbackTransportName = this.transportName(fallbackTransport);\n let fallback = (reason) => {\n this.log("transport", `falling back to ${fallbackTransportName}...`, reason);\n this.off([openRef, errorRef]);\n primaryTransport = false;\n this.replaceTransport(fallbackTransport);\n this.transportConnect();\n };\n if (this.getSession(`phx:fallback:${fallbackTransportName}`)) {\n return fallback("memorized");\n }\n this.fallbackTimer = setTimeout(fallback, fallbackThreshold);\n errorRef = this.onError((reason) => {\n this.log("transport", "error", reason);\n if (primaryTransport && !established) {\n clearTimeout(this.fallbackTimer);\n fallback(reason);\n }\n });\n if (this.fallbackRef) {\n this.off([this.fallbackRef]);\n }\n this.fallbackRef = this.onOpen(() => {\n established = true;\n if (!primaryTransport) {\n let fallbackTransportName2 = this.transportName(fallbackTransport);\n if (!this.primaryPassedHealthCheck) {\n this.storeSession(`phx:fallback:${fallbackTransportName2}`, "true");\n }\n return this.log("transport", `established ${fallbackTransportName2} fallback`);\n }\n clearTimeout(this.fallbackTimer);\n this.fallbackTimer = setTimeout(fallback, fallbackThreshold);\n this.ping((rtt) => {\n this.log("transport", "connected to primary after", rtt);\n this.primaryPassedHealthCheck = true;\n clearTimeout(this.fallbackTimer);\n });\n });\n this.transportConnect();\n }\n clearHeartbeats() {\n clearTimeout(this.heartbeatTimer);\n clearTimeout(this.heartbeatTimeoutTimer);\n }\n onConnOpen() {\n if (this.hasLogger()) this.log("transport", `${this.transportName(this.transport)} connected to ${this.endPointURL()}`);\n this.closeWasClean = false;\n this.disconnecting = false;\n this.establishedConnections++;\n this.flushSendBuffer();\n this.reconnectTimer.reset();\n this.resetHeartbeat();\n this.stateChangeCallbacks.open.forEach(([, callback]) => callback());\n }\n /**\n * @private\n */\n heartbeatTimeout() {\n if (this.pendingHeartbeatRef) {\n this.pendingHeartbeatRef = null;\n if (this.hasLogger()) {\n this.log("transport", "heartbeat timeout. Attempting to re-establish connection");\n }\n this.triggerChanError();\n this.closeWasClean = false;\n this.teardown(() => this.reconnectTimer.scheduleTimeout(), WS_CLOSE_NORMAL, "heartbeat timeout");\n }\n }\n resetHeartbeat() {\n if (this.conn && this.conn.skipHeartbeat) {\n return;\n }\n this.pendingHeartbeatRef = null;\n this.clearHeartbeats();\n this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs);\n }\n teardown(callback, code, reason) {\n if (!this.conn) {\n return callback && callback();\n }\n const connToClose = this.conn;\n this.waitForBufferDone(connToClose, () => {\n if (code) {\n connToClose.close(code, reason || "");\n } else {\n connToClose.close();\n }\n this.waitForSocketClosed(connToClose, () => {\n if (this.conn === connToClose) {\n this.conn.onopen = function() {\n };\n this.conn.onerror = function() {\n };\n this.conn.onmessage = function() {\n };\n this.conn.onclose = function() {\n };\n this.conn = null;\n }\n callback && callback();\n });\n });\n }\n waitForBufferDone(conn, callback, tries = 1) {\n if (tries === 5 || !conn.bufferedAmount) {\n callback();\n return;\n }\n setTimeout(() => {\n this.waitForBufferDone(conn, callback, tries + 1);\n }, 150 * tries);\n }\n waitForSocketClosed(conn, callback, tries = 1) {\n if (tries === 5 || conn.readyState === SOCKET_STATES.closed) {\n callback();\n return;\n }\n setTimeout(() =>
1 {\n this.waitForSocketClosed(conn, callback, tries + 1);\n }, 150 * tries);\n }\n onConnClose(event) {\n if (this.conn) this.conn.onclose = () => {\n };\n let closeCode = event && event.code;\n if (this.hasLogger()) this.log("transport", "close", event);\n this.triggerChanError();\n this.clearHeartbeats();\n if (!this.closeWasClean && closeCode !== 1e3) {\n this.reconnectTimer.scheduleTimeout();\n }\n this.stateChangeCallbacks.close.forEach(([, callback]) => callback(event));\n }\n /**\n * @private\n */\n onConnError(error) {\n if (this.hasLogger()) this.log("transport", "error", error);\n let transportBefore = this.transport;\n let establishedBefore = this.establishedConnections;\n this.stateChangeCallbacks.error.forEach(([, callback]) => {\n callback(error, transportBefore, establishedBefore);\n });\n if (transportBefore === this.transport || establishedBefore > 0) {\n this.triggerChanError();\n }\n }\n /**\n * @private\n */\n triggerChanError() {\n this.channels.forEach((channel) => {\n if (!(channel.isErrored() || channel.isLeaving() || channel.isClosed())) {\n channel.trigger(CHANNEL_EVENTS.error);\n }\n });\n }\n /**\n * @returns {string}\n */\n connectionState() {\n switch (this.conn && this.conn.readyState) {\n case SOCKET_STATES.connecting:\n return "connecting";\n case SOCKET_STATES.open:\n return "open";\n case SOCKET_STATES.closing:\n return "closing";\n default:\n return "closed";\n }\n }\n /**\n * @returns {boolean}\n */\n isConnected() {\n return this.connectionState() === "open";\n }\n /**\n * @private\n *\n * @param {Channel}\n */\n remove(channel) {\n this.off(channel.stateChangeRefs);\n this.channels = this.channels.filter((c) => c !== channel);\n }\n /**\n * Removes `onOpen`, `onClose`, `onError,` and `onMessage` registrations.\n *\n * @param {refs} - list of refs returned by calls to\n * `onOpen`, `onClose`, `onError,` and `onMessage`\n */\n off(refs) {\n for (let key in this.stateChangeCallbacks) {\n this.stateChangeCallbacks[key] = this.stateChangeCallbacks[key].filter(([ref]) => {\n return refs.indexOf(ref) === -1;\n });\n }\n }\n /**\n * Initiates a new channel for the given topic\n *\n * @param {string} topic\n * @param {Object} chanParams - Parameters for the channel\n * @returns {Channel}\n */\n channel(topic, chanParams = {}) {\n let chan = new Channel(topic, chanParams, this);\n this.channels.push(chan);\n return chan;\n }\n /**\n * @param {Object} data\n */\n push(data) {\n if (this.hasLogger()) {\n let { topic, event, payload, ref, join_ref } = data;\n this.log("push", `${topic} ${event} (${join_ref}, ${ref})`, payload);\n }\n if (this.isConnected()) {\n this.encode(data, (result) => this.conn.send(result));\n } else {\n this.sendBuffer.push(() => this.encode(data, (result) => this.conn.send(result)));\n }\n }\n /**\n * Return the next message ref, accounting for overflows\n * @returns {string}\n */\n makeRef() {\n let newRef = this.ref + 1;\n if (newRef === this.ref) {\n this.ref = 0;\n } else {\n this.ref = newRef;\n }\n return this.ref.toString();\n }\n sendHeartbeat() {\n if (this.pendingHeartbeatRef && !this.isConnected()) {\n return;\n }\n this.pendingHeartbeatRef = this.makeRef();\n this.push({ topic: "phoenix", event: "heartbeat", payload: {}, ref: this.pendingHeartbeatRef });\n this.heartbeatTimeoutTimer = setTimeout(() => this.heartbeatTimeout(), this.heartbeatIntervalMs);\n }\n flushSendBuffer() {\n if (this.isConnected() && this.sendBuffer.length > 0) {\n this.sendBuffer.forEach((callback) => callback());\n this.sendBuffer = [];\n }\n }\n onConnMessage(rawMessage) {\n this.decode(rawMessage.data, (msg) => {\n let { topic, event, payload, ref, join_ref } = msg;\n if (ref && ref === this.pendingHeartbeatRef) {\n this.clearHeartbeats();\n this.pendingHeartbeatRef = null;\n this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs);\n }\n if (this.hasLogger()) this.log("receive", `${payload.status || ""} ${topic} ${event} ${ref && "(" + ref + ")" || ""}`, payload);\n for (let i = 0; i < this.channels.length;
1 i++) {\n const channel = this.channels[i];\n if (!channel.isMember(topic, event, payload, join_ref)) {\n continue;\n }\n channel.trigger(event, payload, ref, join_ref);\n }\n for (let i = 0; i < this.stateChangeCallbacks.message.length; i++) {\n let [, callback] = this.stateChangeCallbacks.message[i];\n callback(msg);\n }\n });\n }\n leaveOpenTopic(topic) {\n let dupChannel = this.channels.find((c) => c.topic === topic && (c.isJoined() || c.isJoining()));\n if (dupChannel) {\n if (this.hasLogger()) this.log("transport", `leaving duplicate topic "${topic}"`);\n dupChannel.leave();\n }\n }\n};\n\n//# sourceMappingURL=phoenix.mjs.map\n\n// EXTERNAL MODULE: ./node_modules/nprogress/nprogress.js\nvar nprogress = __webpack_require__(865);\nvar nprogress_default = /*#__PURE__*/__webpack_require__.n(nprogress);\n;// CONCATENATED MODULE: ./node_modules/phoenix_live_view/priv/static/phoenix_live_view.esm.js\n// js/phoenix_live_view/constants.ts\nvar CONSECUTIVE_RELOADS = "consecutive-reloads";\nvar MAX_RELOADS = 10;\nvar RELOAD_JITTER_MIN = 5e3;\nvar RELOAD_JITTER_MAX = 1e4;\nvar FAILSAFE_JITTER = 3e4;\nvar PHX_EVENT_CLASSES = [\n "phx-click-loading",\n "phx-change-loading",\n "phx-submit-loading",\n "phx-keydown-loading",\n "phx-keyup-loading",\n "phx-blur-loading",\n "phx-focus-loading",\n "phx-hook-loading"\n];\nvar PHX_DROP_TARGET_ACTIVE_CLASS = "phx-drop-target-active";\nvar PHX_COMPONENT = "data-phx-component";\nvar PHX_VIEW_REF = "data-phx-view";\nvar PHX_LIVE_LINK = "data-phx-link";\nvar PHX_TRACK_STATIC = "track-static";\nvar PHX_LINK_STATE = "data-phx-link-state";\nvar PHX_REF_LOADING = "data-phx-ref-loading";\nvar PHX_REF_SRC = "data-phx-ref-src";\nvar PHX_REF_LOCK = "data-phx-ref-lock";\nvar PHX_PENDING_REFS = "phx-pending-refs";\nvar PHX_TRACK_UPLOADS = "track-uploads";\nvar PHX_UPLOAD_REF = "data-phx-upload-ref";\nvar PHX_PREFLIGHTED_REFS = "data-phx-preflighted-refs";\nvar PHX_DONE_REFS = "data-phx-done-refs";\nvar PHX_DROP_TARGET = "drop-target";\nvar PHX_ACTIVE_ENTRY_REFS = "data-phx-active-refs";\nvar PHX_LIVE_FILE_UPDATED = "phx:live-file:updated";\nvar PHX_SKIP = "data-phx-skip";\nvar PHX_MAGIC_ID = "data-phx-id";\nvar PHX_PRUNE = "data-phx-prune";\nvar PHX_CONNECTED_CLASS = "phx-connected";\nvar PHX_LOADING_CLASS = "phx-loading";\nvar PHX_ERROR_CLASS = "phx-error";\nvar PHX_CLIENT_ERROR_CLASS = "phx-client-error";\nvar PHX_SERVER_ERROR_CLASS = "phx-server-error";\nvar PHX_PARENT_ID = "data-phx-parent-id";\nvar PHX_MAIN = "data-phx-main";\nvar PHX_ROOT_ID = "data-phx-root-id";\nvar PHX_VIEWPORT_TOP = "viewport-top";\nvar PHX_VIEWPORT_BOTTOM = "viewport-bottom";\nvar PHX_VIEWPORT_OVERRUN_TARGET = "viewport-overrun-target";\nvar PHX_TRIGGER_ACTION = "trigger-action";\nvar PHX_HAS_FOCUSED = "phx-has-focused";\nvar FOCUSABLE_INPUTS = [\n "text",\n "textarea",\n "number",\n "email",\n "password",\n "search",\n "tel",\n "url",\n "date",\n "time",\n "datetime-local",\n "color",\n "range"\n];\nvar CHECKABLE_INPUTS = ["checkbox", "radio"];\nvar PHX_HAS_SUBMITTED = "phx-has-submitted";\nvar PHX_SESSION = "data-phx-session";\nvar PHX_VIEW_SELECTOR = `[${PHX_SESSION}]`;\nvar PHX_STICKY = "data-phx-sticky";\nvar PHX_STATIC = "data-phx-static";\nvar PHX_READONLY = "data-phx-readonly";\nvar PHX_DISABLED = "data-phx-disabled";\nvar PHX_DISABLE_WITH = "disable-with";\nvar PHX_DISABLE_WITH_RESTORE = "data-phx-disable-with-restore";\nvar PHX_HOOK = "hook";\nvar PHX_DEBOUNCE = "debounce";\nvar PHX_THROTTLE = "throttle";\nvar PHX_UPDATE = "update";\nvar PHX_STREAM = "stream";\nvar PHX_STREAM_REF = "data-phx-stream";\nvar PHX_PORTAL = "data-phx-portal";\nvar PHX_TELEPORTED_REF = "data-phx-teleported";\nvar PHX_TELEPORTED_SRC = "data-phx-teleported-src";\nvar PHX_RUNTIME_HOOK = "data-phx-runtime-hook";\nvar PHX_LV_PID = "data-phx-pid";\nvar PHX_KEY = "key";\nvar PHX_PRIVATE = "phxPrivate";\nvar PHX_AUTO_RECOVER = "auto-recover";\nvar PHX_NO_UNUSED_FIELD = "no-unused-field";\nvar PHX_LV_DEBUG = "phx:live-socket:debug";\nvar PHX_LV_PROFILE = "phx:live-socket:profiling";
1\nvar PHX_LV_LATENCY_SIM = "phx:live-socket:latency-sim";\nvar PHX_LV_HISTORY_POSITION = "phx:nav-history-position";\nvar PHX_PROGRESS = "progress";\nvar PHX_MOUNTED = "mounted";\nvar PHX_RELOAD_STATUS = "__phoenix_reload_status__";\nvar LOADER_TIMEOUT = 1;\nvar MAX_CHILD_JOIN_ATTEMPTS = 3;\nvar BEFORE_UNLOAD_LOADER_TIMEOUT = 200;\nvar DISCONNECTED_TIMEOUT = 500;\nvar BINDING_PREFIX = "phx-";\nvar PUSH_TIMEOUT = 3e4;\nvar DEBOUNCE_TRIGGER = "debounce-trigger";\nvar THROTTLED = "throttled";\nvar DEBOUNCE_PREV_KEY = "debounce-prev-key";\nvar DEFAULTS = {\n debounce: 300,\n throttle: 300\n};\nvar PHX_PENDING_ATTRS = [PHX_REF_LOADING, PHX_REF_SRC, PHX_REF_LOCK];\nvar STATIC = "s";\nvar ROOT = "r";\nvar COMPONENTS = "c";\nvar KEYED = "k";\nvar KEYED_COUNT = "kc";\nvar EVENTS = "e";\nvar REPLY = "r";\nvar TITLE = "t";\nvar TEMPLATES = "p";\nvar STREAM = "stream";\n\n// js/phoenix_live_view/entry_uploader.js\nvar EntryUploader = class {\n constructor(entry, config, liveSocket) {\n const { chunk_size, chunk_timeout } = config;\n this.liveSocket = liveSocket;\n this.entry = entry;\n this.offset = 0;\n this.chunkSize = chunk_size;\n this.chunkTimeout = chunk_timeout;\n this.chunkTimer = null;\n this.errored = false;\n this.uploadChannel = liveSocket.channel(`lvu:${entry.ref}`, {\n token: entry.metadata()\n });\n }\n error(reason) {\n if (this.errored) {\n return;\n }\n this.uploadChannel.leave();\n this.errored = true;\n this.chunkTimer != null && clearTimeout(this.chunkTimer);\n this.entry.error(reason);\n }\n upload() {\n this.uploadChannel.onError((reason) => this.error(reason));\n this.uploadChannel.join().receive("ok", (_data) => this.readNextChunk()).receive("error", ({ reason }) => this.error(reason));\n }\n isDone() {\n return this.offset >= this.entry.file.size;\n }\n readNextChunk() {\n const reader = new window.FileReader();\n const blob = this.entry.file.slice(\n this.offset,\n this.chunkSize + this.offset\n );\n reader.onload = (e) => {\n if (e.target?.error === null) {\n this.offset += /** @type {ArrayBuffer} */\n e.target.result.byteLength;\n this.pushChunk(\n /** @type {ArrayBuffer} */\n e.target.result\n );\n } else {\n return logError("Read error: " + e.target?.error);\n }\n };\n reader.readAsArrayBuffer(blob);\n }\n pushChunk(chunk) {\n if (!this.uploadChannel.isJoined()) {\n return;\n }\n this.uploadChannel.push("chunk", chunk, this.chunkTimeout).receive("ok", () => {\n this.entry.progress(this.offset / this.entry.file.size * 100);\n if (!this.isDone()) {\n this.chunkTimer = setTimeout(\n () => this.readNextChunk(),\n this.liveSocket.getLatencySim() || 0\n );\n }\n }).receive("error", ({ reason }) => this.error(reason));\n }\n};\n\n// js/phoenix_live_view/utils.ts\nvar logError = (msg, obj) => console.error && console.error(msg, obj);\nvar ensureSameOrigin = (href, kind) => {\n let url;\n try {\n url = new URL(href, window.location.href);\n } catch {\n throw new Error(\n `expected ${kind} destination to be a valid URL, got: ${href}`\n );\n }\n if (url.origin !== window.location.origin) {\n throw new Error(\n `cannot ${kind} to "${href}" because its origin does not match the current origin "${window.location.origin}". Use window.location directly for cross-origin navigation.`\n );\n }\n};\nvar isCid = (cid) => {\n const type = typeof cid;\n return type === "number" || type === "string" && /^(0|[1-9]\\d*)$/.test(cid);\n};\nfunction detectDuplicateIds() {\n const ids = /* @__PURE__ */ new Set();\n const elems = document.querySelectorAll("*[id]");\n for (let i = 0, len = elems.length; i < len; i++) {\n if (ids.has(elems[i].id)) {\n console.error(\n `Multiple IDs detected: ${elems[i].id}. Ensure unique element ids.`\n );\n } else {\n ids.add(elems[i].id);\n }\n }\n}\nfunction detectInvalidStreamInserts(inserts) {\n const errors = /* @__PURE__ */ new Set();
1\n Object.keys(inserts).forEach((id) => {\n const streamEl = document.getElementById(id);\n if (streamEl && streamEl.parentElement && streamEl.parentElement.getAttribute("phx-update") !== "stream") {\n errors.add(\n `The stream container with id "${streamEl.parentElement.id}" is missing the phx-update="stream" attribute. Ensure it is set for streams to work properly.`\n );\n }\n });\n errors.forEach((error) => console.error(error));\n}\nvar debug = (view, kind, msg, obj) => {\n if (view.liveSocket.isDebugEnabled()) {\n console.log(`${view.id} ${kind}: ${msg} - `, obj);\n }\n};\nvar phoenix_live_view_esm_closure = (val) => typeof val === "function" ? val : function() {\n return val;\n};\nvar clone = (obj) => {\n return JSON.parse(JSON.stringify(obj));\n};\nvar closestPhxBinding = (startEl, binding, borderEl) => {\n let el = startEl;\n do {\n if (el.matches(`[${binding}]`) && !("disabled" in el && el.disabled)) {\n return el;\n }\n el = el.parentElement;\n } while (el !== null && el.nodeType === 1 && !(borderEl && borderEl.isSameNode(el) || el.matches(PHX_VIEW_SELECTOR)));\n return null;\n};\nvar isObject = (obj) => {\n return obj !== null && typeof obj === "object" && !(obj instanceof Array);\n};\nvar isEqualObj = (obj1, obj2) => JSON.stringify(obj1) === JSON.stringify(obj2);\nvar isEmpty = (obj) => {\n for (const x in obj) {\n return false;\n }\n return true;\n};\nvar maybe = (el, callback) => el && callback(el);\nvar channelUploader = function(entries, onError, resp, liveSocket) {\n entries.forEach((entry) => {\n const entryUploader = new EntryUploader(entry, resp.config, liveSocket);\n entryUploader.upload();\n });\n};\nvar eventContainsFiles = (e) => {\n if (e.dataTransfer.types) {\n for (let i = 0; i < e.dataTransfer.types.length; i++) {\n if (e.dataTransfer.types[i] === "Files") {\n return true;\n }\n }\n }\n return false;\n};\n\n// js/phoenix_live_view/browser.ts\nvar Browser = {\n canPushState() {\n return typeof history.pushState !== "undefined";\n },\n dropLocal(localStorage, namespace, subkey) {\n return localStorage.removeItem(this.localKey(namespace, subkey));\n },\n updateLocal(localStorage, namespace, subkey, initial, func) {\n const current = this.getLocal(localStorage, namespace, subkey);\n const key = this.localKey(namespace, subkey);\n const newVal = current === null ? initial : func(current);\n localStorage.setItem(key, JSON.stringify(newVal));\n return newVal;\n },\n getLocal(localStorage, namespace, subkey) {\n return JSON.parse(localStorage.getItem(this.localKey(namespace, subkey)));\n },\n updateCurrentState(callback) {\n if (!this.canPushState()) {\n return;\n }\n history.replaceState(\n callback(history.state || {}),\n "",\n window.location.href\n );\n },\n pushState(kind, meta, to) {\n if (this.canPushState()) {\n if (to !== window.location.href) {\n if (meta.type == "redirect" && meta.scroll) {\n const currentState = history.state || {};\n currentState.scroll = meta.scroll;\n history.replaceState(currentState, "", window.location.href);\n }\n delete meta.scroll;\n history[kind + "State"](meta, "", to || null);\n window.requestAnimationFrame(() => {\n const hashEl = this.getHashTargetEl(window.location.hash);\n if (hashEl) {\n hashEl.scrollIntoView();\n } else if (meta.type === "redirect") {\n window.scroll(0, 0);\n }\n });\n }\n } else if (to) {\n this.redirect(to);\n }\n },\n setCookie(name, value, maxAgeSeconds) {\n const expires = typeof maxAgeSeconds === "number" ? ` max-age=${maxAgeSeconds};` : "";\n document.cookie = `${name}=${value};${expires} path=/`;\n },\n getCookie(name) {\n return document.cookie.replace(\n new RegExp(`(?:(?:^|.*;s*)${name}s*=s*([^;]*).*$)|^.*$`),\n "$1"\n );\n },\n deleteCookie(name) {\n document.cookie = `${name}=; max-age=-1; path=/`;\n },\n redirect(toURL, flash = null, navigate = (url) => {\n window.location.href = url;\n }) {\n if (flash) {\n this.setCookie("__phoenix_flash__", flash, 60);\n }\n navigate(toURL);\n },\n localKey(namespace, subkey) {\n return `${namespace}-${subkey}`;\n },\n getHashTargetEl(maybeHash) {\n const hash = maybeHash.toString().substring(1);\n if (hash === "") {\n return;\n }\n return document.getElementById(hash) || document.querySelector(`a[name="${hash}"]`);\n }\n};\nvar browser_default = Browser;\n\n// js/phoenix_live_view/dom.ts\nvar DOM = {\n byId(id) {\n return document.getElementById(id) || logError(`no id found for ${id}`);\n },\n elementFromTarget(target) {\n if (!(target instanceof Node)) {\n return null;\n }\n if (target.nodeType === Node.ELEMENT_NODE) {\n return target;\n } else {\n return target.parentElement;\n }\n },\n removeClass(el, className) {\n el.classList.remove(className);\n if (el.classList.length === 0) {\n el.removeAttribute("class");\n }\n },\n all(node, query, callback) {\n if (!node) {\n return [];\n }\n const array = Array.from(node.querySelectorAll(query));\n if (callback) {\n array.forEach(callback);\n }\n return array;\n },\n childNodeLength(html) {\n const template = document.createElement("template");\n template.innerHTML = html;\n return template.content.childElementCount;\n },\n isUploadInput(el) {\n return el.type === "file" && el.getAttribute(PHX_UPLOAD_REF) !== null;\n },\n isAutoUpload(inputEl) {\n return inputEl.hasAttribute("data-phx-auto-upload");\n }
1,\n findUploadInputs(node) {\n const formId = node.id;\n const inputsOutsideForm = this.all(\n document,\n `input[type="file"][${PHX_UPLOAD_REF}][form="${formId}"]`\n );\n return this.all(node, `input[type="file"][${PHX_UPLOAD_REF}]`).concat(\n inputsOutsideForm\n );\n },\n findComponent(viewId, cid, doc2 = document) {\n return doc2.querySelector(\n `[${PHX_VIEW_REF}="${viewId}"][${PHX_COMPONENT}="${cid}"]`\n );\n },\n getComponent(viewId, cid, doc2 = document) {\n const el = this.findComponent(viewId, cid, doc2);\n if (!el) {\n throw new Error(\n `no component found matching viewId ${viewId} and cid ${cid}`\n );\n }\n return el;\n },\n isPhxDestroyed(node) {\n return node.id && DOM.private(node, "destroyed") ? true : false;\n },\n wantsNewTab(e) {\n const wantsNewTab = e.ctrlKey || e.shiftKey || e.metaKey || e.button && e.button === 1;\n const isDownload = e.target instanceof HTMLAnchorElement && e.target.hasAttribute("download");\n const isTargetBlank = e.target.hasAttribute("target") && e.target.getAttribute("target").toLowerCase() === "_blank";\n const isTargetNamedTab = e.target.hasAttribute("target") && !e.target.getAttribute("target").startsWith("_");\n return wantsNewTab || isTargetBlank || isDownload || isTargetNamedTab;\n },\n isUnloadableFormSubmit(e) {\n const isDialogSubmit = e.target && e.target.getAttribute("method") === "dialog" || e.submitter && e.submitter.getAttribute("formmethod") === "dialog";\n if (isDialogSubmit) {\n return false;\n } else {\n return !e.defaultPrevented && !this.wantsNewTab(e);\n }\n },\n isNewPageClick(e, currentLocation) {\n const href = e.target instanceof HTMLAnchorElement ? e.target.getAttribute("href") : null;\n let url;\n if (e.defaultPrevented || href === null || this.wantsNewTab(e)) {\n return false;\n }\n if (href.startsWith("mailto:") || href.startsWith("tel:")) {\n return false;\n }\n if (e.target.isContentEditable) {\n return false;\n }\n try {\n url = new URL(href);\n } catch {\n try {\n url = new URL(href, currentLocation);\n } catch {\n return true;\n }\n }\n if (url.host === currentLocation.host && url.protocol === currentLocation.protocol) {\n if (url.pathname === currentLocation.pathname && url.search === currentLocation.search) {\n return url.hash === "" && !url.href.endsWith("#");\n }\n }\n return url.protocol.startsWith("http");\n },\n markPhxChildDestroyed(el) {\n if (this.isPhxChild(el)) {\n el.setAttribute(PHX_SESSION, "");\n }\n this.putPrivate(el, "destroyed", true);\n },\n findPhxChildrenInFragment(html, parentId) {\n const template = document.createElement("template");\n template.innerHTML = html;\n return this.findPhxChildren(template.content, parentId);\n },\n isIgnored(el, phxUpdate) {\n return (el.getAttribute(phxUpdate) || el.getAttribute("data-phx-update")) === "ignore";\n },\n isPhxUpdate(el, phxUpdate, updateTypes) {\n return el.getAttribute && updateTypes.indexOf(el.getAttribute(phxUpdate)) >= 0;\n },\n findPhxSticky(el) {\n return this.all(el, `[${PHX_STICKY}]`);\n },\n findPhxChildren(el, parentId) {\n return this.all(el, `${PHX_VIEW_SELECTOR}[${PHX_PARENT_ID}="${parentId}"]`);\n },\n findExistingParentCIDs(viewId, cids) {\n const parentCids = /* @__PURE__ */ new Set();\n const childrenCids = /* @__PURE__ */ new Set();\n cids.forEach((cid) => {\n this.all(\n document,\n `[${PHX_VIEW_REF}="${viewId}"][${PHX_COMPONENT}="${cid}"]`\n ).forEach((parent) => {\n parentCids.add(cid);\n this.all(parent, `[${PHX_VIEW_REF}="${viewId}"][${PHX_COMPONENT}]`).map((el) => parseInt(el.getAttribute(PHX_COMPONENT))).forEach((childCID) => childrenCids.add(childCID));\n });\n });\n childrenCids.forEach((childCid) => parentCids.delete(childCid));\n return parentCids;\n },\n private(el, key) {\n return el[PHX_PRIVATE] && el[PHX_PRIVATE][key];\n },\n deletePrivate(el, key) {\n el[PHX_PRIVATE] && delete el[PHX_PRIVATE][key];\n },\n putPrivate(el, key, value) {\n if (!el[PHX_PRIVATE]) {\n el[PHX_PRIVATE] = {};\n }\n el[PHX_PRIVATE][key] = value;\n },\n updatePrivate(el, key, defaultVal, updateFunc) {\n const existing = this.private(el, key);\n if (existing === void 0) {\n this.putPrivate(el, key, updateFunc(defaultVal));\n } else {\n this.putPrivate(el, key, updateFunc(existing));\n }\n },\n syncPendingAttrs(fromEl, toEl) {\n if (!fromEl.hasAttribute(PHX_REF_SRC)) {\n return;\n }\n PHX_EVENT_CLASSES.forEach((className) => {\n fromEl.classList.contains(className) && toEl.classList.add(className);\n });\n PHX_PENDING_ATTRS.filter((attr) =>
1 fromEl.hasAttribute(attr)).forEach(\n (attr) => {\n toEl.setAttribute(attr, fromEl.getAttribute(attr));\n }\n );\n },\n copyPrivates(target, source) {\n if (source[PHX_PRIVATE]) {\n target[PHX_PRIVATE] = source[PHX_PRIVATE];\n }\n },\n putTitle(str) {\n const titleEl = document.querySelector("title");\n if (titleEl) {\n const { prefix, suffix, default: defaultTitle } = titleEl.dataset;\n const isEmpty2 = typeof str !== "string" || str.trim() === "";\n if (isEmpty2 && typeof defaultTitle !== "string") {\n return;\n }\n const inner = isEmpty2 ? defaultTitle : str;\n document.title = `${prefix || ""}${inner || ""}${suffix || ""}`;\n } else {\n document.title = str;\n }\n },\n debounce(el, event, phxDebounce, defaultDebounce, phxThrottle, defaultThrottle, asyncFilter, callback) {\n let debounce = el.getAttribute(phxDebounce);\n let throttle = el.getAttribute(phxThrottle);\n if (debounce === "") {\n debounce = defaultDebounce;\n }\n if (throttle === "") {\n throttle = defaultThrottle;\n }\n const value = debounce || throttle;\n switch (value) {\n case null:\n return callback();\n case "blur":\n this.incCycle(el, "debounce-blur-cycle", () => {\n if (asyncFilter()) {\n callback();\n }\n });\n if (this.once(el, "debounce-blur")) {\n el.addEventListener(\n "blur",\n () => this.triggerCycle(el, "debounce-blur-cycle")\n );\n }\n return;\n default:\n const timeout = parseInt(value);\n const trigger = () => throttle ? this.deletePrivate(el, THROTTLED) : callback();\n const currentCycle = this.incCycle(el, DEBOUNCE_TRIGGER, trigger);\n if (isNaN(timeout)) {\n return logError(`invalid throttle/debounce value: ${value}`);\n }\n if (throttle) {\n let newKeyDown = false;\n if (event.type === "keydown") {\n const prevKey = this.private(el, DEBOUNCE_PREV_KEY);\n this.putPrivate(el, DEBOUNCE_PREV_KEY, event.key);\n newKeyDown = prevKey !== event.key;\n }\n if (!newKeyDown && this.private(el, THROTTLED)) {\n return false;\n } else {\n callback();\n const t = setTimeout(() => {\n if (asyncFilter()) {\n this.triggerCycle(el, DEBOUNCE_TRIGGER);\n }\n }, timeout);\n this.putPrivate(el, THROTTLED, t);\n }\n } else {\n setTimeout(() => {\n if (asyncFilter()) {\n this.triggerCycle(el, DEBOUNCE_TRIGGER, currentCycle);\n }\n }, timeout);\n }\n const form = el.form;\n if (form && this.once(form, "bind-debounce")) {\n form.addEventListener("submit", () => {\n Array.from(new FormData(form).entries(), ([name]) => {\n const namedItem = form.elements.namedItem(name);\n const input = namedItem instanceof RadioNodeList ? namedItem[0] : namedItem;\n if (input) {\n this.incCycle(input, DEBOUNCE_TRIGGER);\n this.deletePrivate(input, THROTTLED);\n }\n });\n });\n }\n if (this.once(el, "bind-debounce")) {\n el.addEventListener("blur", () => {\n clearTimeout(this.private(el, THROTTLED));\n if (asyncFilter()) {\n this.triggerCycle(el, DEBOUNCE_TRIGGER);\n }\n });\n }\n }\n },\n triggerCycle(el, key, currentCycle) {\n const [cycle, trigger] = this.private(el, key);\n if (!currentCycle) {\n currentCycle = cycle;\n }\n if (currentCycle === cycle) {\n this.incCycle(el, key);\n trigger();\n }\n },\n once(el, key) {\n if (this.private(el, key) === true) {\n return false;\n }\n this.putPrivate(el, key, true);\n return true;\n }
1,\n incCycle(el, key, trigger = function() {\n }) {\n let [currentCycle] = this.private(el, key) || [0, trigger];\n currentCycle++;\n this.putPrivate(el, key, [currentCycle, trigger]);\n return currentCycle;\n },\n // maintains or adds privately used hook information\n // fromEl and toEl can be the same element in the case of a newly added node\n // fromEl and toEl can be any HTML node type, so we need to check if it\'s an element node\n maintainPrivateHooks(fromEl, toEl, phxViewportTop, phxViewportBottom) {\n if (fromEl.hasAttribute && fromEl.hasAttribute("data-phx-hook") && !toEl.hasAttribute("data-phx-hook")) {\n toEl.setAttribute("data-phx-hook", fromEl.getAttribute("data-phx-hook"));\n }\n if (toEl.hasAttribute && (toEl.hasAttribute(phxViewportTop) || toEl.hasAttribute(phxViewportBottom))) {\n toEl.setAttribute("data-phx-hook", "Phoenix.InfiniteScroll");\n }\n },\n putCustomElHook(el, hook) {\n if (el.isConnected) {\n el.setAttribute("data-phx-hook", "");\n } else {\n console.error(`\n hook attached to non-connected DOM element\n ensure you are calling createHook within your connectedCallback. ${el.outerHTML}\n `);\n }\n this.putPrivate(el, "custom-el-hook", hook);\n },\n getCustomElHook(el) {\n return this.private(el, "custom-el-hook");\n },\n isUsedInput(el) {\n return el.nodeType === Node.ELEMENT_NODE && (this.private(el, PHX_HAS_FOCUSED) || this.private(el, PHX_HAS_SUBMITTED));\n },\n resetForm(form) {\n Array.from(form.elements).forEach((input) => {\n this.deletePrivate(input, PHX_HAS_FOCUSED);\n this.deletePrivate(input, PHX_HAS_SUBMITTED);\n });\n },\n isPhxChild(node) {\n return node.getAttribute && node.getAttribute(PHX_PARENT_ID);\n },\n isPhxSticky(node) {\n return node.getAttribute && node.getAttribute(PHX_STICKY) !== null;\n },\n isChildOfAny(el, parents) {\n return !!parents.find((parent) => parent.contains(el));\n },\n firstPhxChild(el) {\n return this.isPhxChild(el) ? el : this.all(el, `[${PHX_PARENT_ID}]`)[0];\n },\n isPortalTemplate(el) {\n return el.tagName === "TEMPLATE" && el.hasAttribute(PHX_PORTAL);\n },\n closestViewEl(el) {\n const portalOrViewEl = el.closest(\n `[${PHX_TELEPORTED_REF}],${PHX_VIEW_SELECTOR}`\n );\n if (!portalOrViewEl) {\n return null;\n }\n if (portalOrViewEl.hasAttribute(PHX_TELEPORTED_REF)) {\n return this.byId(portalOrViewEl.getAttribute(PHX_TELEPORTED_REF));\n } else if (portalOrViewEl.hasAttribute(PHX_SESSION)) {\n return portalOrViewEl;\n }\n return null;\n },\n dispatchEvent(target, name, opts = {}) {\n let defaultBubble = true;\n const isUploadTarget = target.nodeName === "INPUT" && target.type === "file";\n if (isUploadTarget && name === "click") {\n defaultBubble = false;\n }\n const bubbles = opts.bubbles === void 0 ? defaultBubble : !!opts.bubbles;\n const eventOpts = {\n bubbles,\n cancelable: true,\n detail: opts.detail || {}\n };\n const event = name === "click" ? new MouseEvent("click", eventOpts) : new CustomEvent(name, eventOpts);\n target.dispatchEvent(event);\n },\n cloneNode(node, html) {\n if (typeof html === "undefined") {\n return node.cloneNode(true);\n } else {\n const cloned = node.cloneNode(false);\n cloned.innerHTML = html;\n return cloned;\n }\n },\n // merge attributes from source to target\n // if an element is ignored, we only merge data attributes\n // including removing data attributes that are no longer in the source\n mergeAttrs(target, source, opts = {}) {\n const exclude = new Set(opts.exclude || []);\n const isIgnored = opts.isIgnored;\n const sourceAttrs = source.attributes;\n for (let i = sourceAttrs.length - 1; i >= 0; i--) {\n const name = sourceAttrs[i].name;\n if (!exclude.has(name)) {\n const sourceValue = source.getAttribute(name);\n if (target.getAttribute(name) !== sourceValue && (!isIgnored || isIgnored && name.startsWith("data-"))) {\n target.setAttribute(name, sourceValue);\n }\n } else {\n if (name === "value") {\n const sourceValue = source.value ?? source.getAttribute(name);\n if (target.value === sourceValue) {\n target.setAttribute("value", source.getAttribute(name));\n }\n }\n }\n }\n const targetAttrs = target.attributes;\n for (let i = targetAttrs.length - 1; i >= 0; i--) {\n const name = targetAttrs[i].name;\n if (isIgnored) {\n if (name.startsWith("data-") && !source.hasAttribute(name) && !PHX_PENDING_ATTRS.includes(name)) {\
1n target.removeAttribute(name);\n }\n } else {\n if (!source.hasAttribute(name)) {\n target.removeAttribute(name);\n }\n }\n }\n },\n mergeFocusedInput(target, source) {\n if (!(target instanceof HTMLSelectElement)) {\n DOM.mergeAttrs(target, source, { exclude: ["value"] });\n }\n if (source.readOnly) {\n target.setAttribute("readonly", true);\n } else {\n target.removeAttribute("readonly");\n }\n },\n hasSelectionRange(el) {\n return el.setSelectionRange && (el.type === "text" || el.type === "textarea");\n },\n restoreFocus(focused, selectionStart, selectionEnd) {\n if (focused instanceof HTMLSelectElement) {\n focused.focus();\n }\n if (!DOM.isTextualInput(focused)) {\n return;\n }\n const wasFocused = focused.matches(":focus");\n if (!wasFocused) {\n focused.focus();\n }\n if (this.hasSelectionRange(focused)) {\n focused.setSelectionRange(selectionStart, selectionEnd);\n }\n },\n /**\n * Returns true if the element is an input that can be focused and edited by the user,\n * so we can skip patching it if it has focus.\n */\n isEditableInput(el) {\n return this.isFormAssociated(el) && !(el instanceof HTMLButtonElement) && !(el instanceof HTMLInputElement && el.type === "button");\n },\n isFormAssociated(el) {\n if (!(el instanceof HTMLElement))\n return false;\n if (el.localName) {\n const customEl = customElements.get(el.localName);\n if (customEl) {\n return customEl.formAssociated === true;\n }\n }\n return el instanceof HTMLInputElement || el instanceof HTMLSelectElement || el instanceof HTMLTextAreaElement || el instanceof HTMLButtonElement;\n },\n syncAttrsToProps(el) {\n if (el instanceof HTMLInputElement && CHECKABLE_INPUTS.indexOf(el.type.toLocaleLowerCase()) >= 0) {\n el.checked = el.getAttribute("checked") !== null;\n }\n },\n isTextualInput(el) {\n return FOCUSABLE_INPUTS.indexOf(el.type) >= 0;\n },\n isNowTriggerFormExternal(el, phxTriggerExternal) {\n return el.getAttribute && el.getAttribute(phxTriggerExternal) !== null && document.body.contains(el);\n },\n cleanChildNodes(container, phxUpdate) {\n if (DOM.isPhxUpdate(container, phxUpdate, ["append", "prepend", PHX_STREAM])) {\n const toRemove = [];\n container.childNodes.forEach((childNode) => {\n if (!("id" in childNode) || !childNode.id) {\n const isEmptyTextNode = childNode.nodeType === Node.TEXT_NODE && childNode.nodeValue && childNode.nodeValue.trim() === "";\n if (!isEmptyTextNode && childNode.nodeType !== Node.COMMENT_NODE) {\n logError(\n `only HTML element tags with an id are allowed inside containers with phx-update.\n\nremoving illegal node: "${("outerHTML" in childNode && childNode.outerHTML || childNode.nodeValue || "").trim()}"\n\n`\n );\n }\n toRemove.push(childNode);\n }\n });\n toRemove.forEach((childNode) => childNode.remove());\n }\n },\n replaceRootContainer(container, tagName, attrs) {\n const retainedAttrs = /* @__PURE__ */ new Set([\n "id",\n PHX_SESSION,\n PHX_STATIC,\n PHX_MAIN,\n PHX_ROOT_ID\n ]);\n if (container.tagName.toLowerCase() === tagName.toLowerCase()) {\n Array.from(container.attributes).filter((attr) => !retainedAttrs.has(attr.name.toLowerCase())).forEach((attr) => container.removeAttribute(attr.name));\n Object.keys(attrs).filter((name) => !retainedAttrs.has(name.toLowerCase())).forEach((attr) => container.setAttribute(attr, attrs[attr]));\n return container;\n } else {\n const newContainer = document.createElement(tagName);\n Object.keys(attrs).forEach(\n (attr) => newContainer.setAttribute(attr, attrs[attr])\n );\n retainedAttrs.forEach((attr) => {\n const value = container.getAttribute(attr);\n if (value !== null) {\n newContainer.setAttribute(attr, value);\n }\n });\n newContainer.innerHTML = container.innerHTML;\n container.replaceWith(newContainer);\n return newContainer;\n }\n },\n getSticky(el, name, defaultVal) {\n const op = (DOM.private(el, "sticky") || []).find(\n ([existingName]) => name === existingName\n );\n if (op) {\n const [_name, _op, stashedResult] = op;\n return stashedResult;\n } else {\n return typeof defaultVal === "function" ? defaultVal() : defaultVal;\n }\n },\n deleteSticky(el, name) {\n this.updatePrivate(el, "sticky", [], (ops) =>
1 {\n return ops.filter(([existingName, _]) => existingName !== name);\n });\n },\n putSticky(el, name, op) {\n const stashedResult = op(el);\n this.updatePrivate(el, "sticky", [], (ops) => {\n const existingIndex = ops.findIndex(\n ([existingName]) => name === existingName\n );\n if (existingIndex >= 0) {\n ops[existingIndex] = [name, op, stashedResult];\n } else {\n ops.push([name, op, stashedResult]);\n }\n return ops;\n });\n },\n applyStickyOperations(el) {\n const ops = DOM.private(el, "sticky");\n if (!ops) {\n return;\n }\n ops.forEach(([name, op, _stashed]) => this.putSticky(el, name, op));\n },\n isLocked(el) {\n return el.hasAttribute && el.hasAttribute(PHX_REF_LOCK);\n },\n attributeIgnored(attribute, ignoredAttributes) {\n return ignoredAttributes.some(\n (toIgnore) => attribute.name == toIgnore || toIgnore === "*" || toIgnore.includes("*") && attribute.name.match(toIgnore) != null\n );\n }\n};\nvar dom_default = DOM;\n\n// js/phoenix_live_view/upload_entry.js\nvar UploadEntry = class {\n static isActive(fileEl, file) {\n const isNew = file._phxRef === void 0;\n const activeRefs = fileEl.getAttribute(PHX_ACTIVE_ENTRY_REFS).split(",");\n const isActive = activeRefs.indexOf(LiveUploader.genFileRef(file)) >= 0;\n return file.size > 0 && (isNew || isActive);\n }\n static isPreflighted(fileEl, file) {\n const preflightedRefs = fileEl.getAttribute(PHX_PREFLIGHTED_REFS).split(",");\n const isPreflighted = preflightedRefs.indexOf(LiveUploader.genFileRef(file)) >= 0;\n return isPreflighted && this.isActive(fileEl, file);\n }\n static isPreflightInProgress(file) {\n return file._preflightInProgress === true;\n }\n static markPreflightInProgress(file) {\n file._preflightInProgress = true;\n }\n constructor(fileEl, file, view, autoUpload) {\n this.ref = LiveUploader.genFileRef(file);\n this.fileEl = fileEl;\n this.file = file;\n this.view = view;\n this.meta = null;\n this._isCancelled = false;\n this._isDone = false;\n this._progress = 0;\n this._lastProgressSent = -1;\n this._onDone = function() {\n };\n this._onElUpdated = this.onElUpdated.bind(this);\n this.fileEl.addEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);\n this.autoUpload = autoUpload;\n }\n metadata() {\n return this.meta;\n }\n progress(progress) {\n this._progress = Math.floor(progress);\n if (this._progress > this._lastProgressSent) {\n if (this._progress >= 100) {\n this._progress = 100;\n this._lastProgressSent = 100;\n this._isDone = true;\n this.view.pushFileProgress(this.fileEl, this.ref, 100, () => {\n LiveUploader.untrackFile(this.fileEl, this.file);\n this._onDone();\n });\n } else {\n this._lastProgressSent = this._progress;\n this.view.pushFileProgress(this.fileEl, this.ref, this._progress);\n }\n }\n }\n isCancelled() {\n return this._isCancelled;\n }\n cancel() {\n this.file._preflightInProgress = false;\n this._isCancelled = true;\n this._isDone = true;\n this._onDone();\n }\n isDone() {\n return this._isDone;\n }\n error(reason = "failed") {\n this.fileEl.removeEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);\n this.view.pushFileProgress(this.fileEl, this.ref, { error: reason });\n if (!this.isAutoUpload()) {\n LiveUploader.clearFiles(this.fileEl);\n }\n }\n isAutoUpload() {\n return this.autoUpload;\n }\n //private\n onDone(callback) {\n this._onDone = () => {\n this.fileEl.removeEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);\n callback();\n };\n }\n onElUpdated() {\n const activeRefs = this.fileEl.getAttribute(PHX_ACTIVE_ENTRY_REFS).split(",");\n if (activeRefs.indexOf(this.ref) === -1) {\n LiveUploader.untrackFile(this.fileEl, this.file);\n this.cancel();\n }\n }\n toPreflightPayload() {\n return {\n last_modified: this.file.lastModified,\n name: this.file.name,\n relative_path: this.file.webkitRelativePath,\n size: this.file.size,\n type: this.file.type,\n ref: this.ref,\n meta: typeof this.file.meta === "function" ? this.file.meta() : void 0\n };\n }\n uploader(uploaders) {\n if (this.meta.uploader) {\n const callback = uploaders[this.meta.uploader] || logError(`no uploader configured for ${this.meta.uploader}`);\n return { name: this.meta.uploader, callback };\n } else {\n return { name: "channel", callback: channelUploader };\n }\n }\n zipPostFlight(resp) {\n this.meta = resp.entries[this.ref];\n if (!this.meta) {\n logError(`no preflight upload response returned with ref ${this.ref}`, {\n input: this.fileEl,\n response: resp\n });\n }\n }\n};\n\n// js/phoenix_live_view/live_uploader.js\nvar liveUploaderFileRef = 0;\nvar LiveUploader = class _LiveUploader {\n static genFileRef(file) {\n const ref = file._phxRef;\n if (ref !== void 0) {\n return ref;\n } else {\n file._phxRef = (liveUploaderFileRef++).toString();\n return file._phxRef;\n }\n }\n static getEntryDataURL(inputEl, ref) {\n const file = this.activeFiles(inputEl).find(\n (file2) => this.genFileRef(file2) === ref\n );\n if (!file)\n return null;\n return URL.createObjectURL(file);\n }\n static hasUploadsInProgress(formEl) {\n let active = 0;
1\n dom_default.findUploadInputs(formEl).forEach((input) => {\n if (input.getAttribute(PHX_PREFLIGHTED_REFS) !== input.getAttribute(PHX_DONE_REFS)) {\n active++;\n }\n });\n return active > 0;\n }\n static serializeUploads(inputEl) {\n const files = this.activeFiles(inputEl);\n const fileData = {};\n files.forEach((file) => {\n const entry = { path: inputEl.name };\n const uploadRef = inputEl.getAttribute(PHX_UPLOAD_REF);\n fileData[uploadRef] = fileData[uploadRef] || [];\n entry.ref = this.genFileRef(file);\n entry.last_modified = file.lastModified;\n entry.name = file.name || entry.ref;\n entry.relative_path = file.webkitRelativePath;\n entry.type = file.type;\n entry.size = file.size;\n if (typeof file.meta === "function") {\n entry.meta = file.meta();\n }\n fileData[uploadRef].push(entry);\n });\n return fileData;\n }\n static clearFiles(inputEl) {\n inputEl.value = null;\n inputEl.removeAttribute(PHX_UPLOAD_REF);\n dom_default.putPrivate(inputEl, "files", []);\n }\n static untrackFile(inputEl, file) {\n dom_default.putPrivate(\n inputEl,\n "files",\n dom_default.private(inputEl, "files").filter((f) => !Object.is(f, file))\n );\n }\n /**\n * @param {HTMLInputElement} inputEl\n * @param {Array<File|Blob>} files\n * @param {DataTransfer} [dataTransfer]\n */\n static trackFiles(inputEl, files, dataTransfer) {\n if (inputEl.getAttribute("multiple") !== null) {\n const newFiles = files.filter(\n (file) => !this.activeFiles(inputEl).find((f) => Object.is(f, file))\n );\n dom_default.updatePrivate(\n inputEl,\n "files",\n [],\n (existing) => existing.concat(newFiles)\n );\n inputEl.value = "";\n } else {\n if (dataTransfer && dataTransfer.files.length > 0) {\n inputEl.files = dataTransfer.files;\n }\n dom_default.putPrivate(inputEl, "files", files);\n }\n }\n static activeFileInputs(formEl) {\n const fileInputs = dom_default.findUploadInputs(formEl);\n return Array.from(fileInputs).filter(\n (el) => el.files && this.activeFiles(el).length > 0\n );\n }\n static activeFiles(input) {\n return (dom_default.private(input, "files") || []).filter(\n (f) => UploadEntry.isActive(input, f)\n );\n }\n static inputsAwaitingPreflight(formEl) {\n const fileInputs = dom_default.findUploadInputs(formEl);\n return Array.from(fileInputs).filter(\n (input) => this.filesAwaitingPreflight(input).length > 0\n );\n }\n static filesAwaitingPreflight(input) {\n return this.activeFiles(input).filter(\n (f) => !UploadEntry.isPreflighted(input, f) && !UploadEntry.isPreflightInProgress(f)\n );\n }\n static markPreflightInProgress(entries) {\n entries.forEach((entry) => UploadEntry.markPreflightInProgress(entry.file));\n }\n constructor(inputEl, view, onComplete) {\n this.autoUpload = dom_default.isAutoUpload(inputEl);\n this.view = view;\n this.onComplete = onComplete;\n this._entries = Array.from(\n _LiveUploader.filesAwaitingPreflight(inputEl) || []\n ).map((file) => new UploadEntry(inputEl, file, view, this.autoUpload));\n _LiveUploader.markPreflightInProgress(this._entries);\n this.numEntriesInProgress = this._entries.length;\n }\n isAutoUpload() {\n return this.autoUpload;\n }\n entries() {\n return this._entries;\n }\n initAdapterUpload(resp, onError, liveSocket) {\n this._entries = this._entries.map((entry) => {\n if (entry.isCancelled()) {\n this.numEntriesInProgress--;\n if (this.numEntriesInProgress === 0) {\n this.onComplete();\n }\n } else {\n entry.zipPostFlight(resp);\n entry.onDone(() => {\n this.numEntriesInProgress--;\n if (this.numEntriesInProgress === 0) {\n this.onComplete();\n }\n });\n }\n return entry;\n });\n const groupedEntries = this._entries.reduce((acc, entry) => {\n if (!entry.meta) {\n return acc;\n }\n const { name, callback } = entry.uploader(liveSocket.uploaders);\n acc[name] = acc[name] || { callback, entries: [] };\n acc[name].entries.push(entry);\n return acc;\n }, {});\n for (const name in groupedEntries) {\n const { callback, entries } = groupedEntries[name];\n callback(entries, onError, resp, liveSocket);\n }\n }\n};\n\n// js/phoenix_live_view/aria.ts\nvar ARIA = {\n anyOf(instance, classes) {\n return classes.some((name) => instance instanceof name);\n },\n isFocusable(el, interactiveOnly = false) {\n return el instanceof HTMLAnchorElement && el.rel !== "ignore" || el instanceof HTMLAreaElement && el.href !== void 0 || !("disabled" in el && el.disabled) && this.anyOf(el, [\n HTMLInputElement,\n HTMLSelectElement,\n HTMLTextAreaElement,\n HTMLButtonElement\n ]) || el instanceof HTMLIFrameElement || el instanceof HTMLElement && el.tabIndex >= 0 && el.getAttribute("aria-hidden") !== "true" || !interactiveOnly && el.getAttribute("tabindex") !== null && el.getAttribute("aria-hidden") !== "true";\n },\n attemptFocus(el, interactiveOnly = false) {\n if (this.isFocusable(el, interactiveOnly)) {\n tr
1y {\n el.focus();\n } catch {\n }\n }\n return !!document.activeElement && document.activeElement.isSameNode(el);\n },\n focusFirstInteractive(el) {\n let child = el.firstElementChild;\n while (child) {\n if (this.attemptFocus(child, true) || this.focusFirstInteractive(child)) {\n return true;\n }\n child = child.nextElementSibling;\n }\n return false;\n },\n focusFirst(el) {\n let child = el.firstElementChild;\n while (child) {\n if (this.attemptFocus(child) || this.focusFirst(child)) {\n return true;\n }\n child = child.nextElementSibling;\n }\n return false;\n },\n focusLast(el) {\n let child = el.lastElementChild;\n while (child) {\n if (this.attemptFocus(child) || this.focusLast(child)) {\n return true;\n }\n child = child.previousElementSibling;\n }\n return false;\n }\n};\nvar aria_default = ARIA;\n\n// js/phoenix_live_view/hooks.ts\nvar findScrollContainer = (el) => {\n if (["HTML", "BODY"].indexOf(el.nodeName.toUpperCase()) >= 0)\n return null;\n if (["scroll", "auto"].indexOf(getComputedStyle(el).overflowY) >= 0)\n return el;\n return findScrollContainer(el.parentElement);\n};\nvar scrollTop = (scrollContainer) => {\n if (scrollContainer) {\n return scrollContainer.scrollTop;\n } else {\n return document.documentElement.scrollTop || document.body.scrollTop;\n }\n};\nvar bottom = (scrollContainer) => {\n if (scrollContainer) {\n return scrollContainer.getBoundingClientRect().bottom;\n } else {\n return window.innerHeight || document.documentElement.clientHeight;\n }\n};\nvar phoenix_live_view_esm_top = (scrollContainer) => {\n if (scrollContainer) {\n return scrollContainer.getBoundingClientRect().top;\n } else {\n return 0;\n }\n};\nvar isAtViewportTop = (el, scrollContainer) => {\n const rect = el.getBoundingClientRect();\n return Math.ceil(rect.top) >= phoenix_live_view_esm_top(scrollContainer) && Math.floor(rect.top) <= bottom(scrollContainer);\n};\nvar isAtViewportBottom = (el, scrollContainer) => {\n const rect = el.getBoundingClientRect();\n return Math.ceil(rect.bottom) >= phoenix_live_view_esm_top(scrollContainer) && Math.floor(rect.bottom) <= bottom(scrollContainer);\n};\nvar isWithinViewport = (el, scrollContainer) => {\n const rect = el.getBoundingClientRect();\n return Math.ceil(rect.top) >= phoenix_live_view_esm_top(scrollContainer) && Math.floor(rect.top) <= bottom(scrollContainer);\n};\nvar InfiniteScroll = {\n mounted() {\n this.scrollContainer = findScrollContainer(this.el);\n let scrollBefore = scrollTop(this.scrollContainer);\n let topOverran = false;\n const throttleInterval = 500;\n let pendingOp = null;\n const onTopOverrun = this.throttle(\n throttleInterval,\n (topEvent, firstChild) => {\n pendingOp = () => true;\n this.liveSocket.js().push(this.el, topEvent, {\n value: { id: firstChild.id, _overran: true },\n callback: () => {\n pendingOp = null;\n }\n });\n }\n );\n const onFirstChildAtTop = this.throttle(\n throttleInterval,\n (topEvent, firstChild) => {\n pendingOp = () => firstChild.scrollIntoView({ block: "start" });\n this.liveSocket.js().push(this.el, topEvent, {\n value: { id: firstChild.id },\n callback: () => {\n pendingOp = null;\n window.requestAnimationFrame(() => {\n if (!isWithinViewport(firstChild, this.scrollContainer)) {\n firstChild.scrollIntoView({ block: "start" });\n }\n });\n }\n });\n }\n );\n const onLastChildAtBottom = this.throttle(\n throttleInterval,\n (bottomEvent, lastChild) => {\n pendingOp = () => lastChild.scrollIntoView({ block: "end" });\n this.liveSocket.js().push(this.el, bottomEvent, {\n value: { id: lastChild.id },\n callback: () => {\n pendingOp = null;\n window.requestAnimationFrame(() =>
1 {\n if (!isWithinViewport(lastChild, this.scrollContainer)) {\n lastChild.scrollIntoView({ block: "end" });\n }\n });\n }\n });\n }\n );\n this.onScroll = (_e) => {\n const scrollNow = scrollTop(this.scrollContainer);\n if (pendingOp) {\n scrollBefore = scrollNow;\n return pendingOp();\n }\n const rect = this.findOverrunTarget();\n const topEvent = this.el.getAttribute(\n this.liveSocket.binding("viewport-top")\n );\n const bottomEvent = this.el.getAttribute(\n this.liveSocket.binding("viewport-bottom")\n );\n const lastChild = this.el.lastElementChild;\n const firstChild = this.el.firstElementChild;\n const isScrollingUp = scrollNow < scrollBefore;\n const isScrollingDown = scrollNow > scrollBefore;\n if (isScrollingUp && topEvent && !topOverran && rect.top >= 0) {\n topOverran = true;\n onTopOverrun(topEvent, firstChild);\n } else if (isScrollingDown && topOverran && rect.top <= 0) {\n topOverran = false;\n }\n if (topEvent && isScrollingUp && firstChild && isAtViewportTop(firstChild, this.scrollContainer)) {\n onFirstChildAtTop(topEvent, firstChild);\n } else if (bottomEvent && isScrollingDown && lastChild && isAtViewportBottom(lastChild, this.scrollContainer)) {\n onLastChildAtBottom(bottomEvent, lastChild);\n }\n scrollBefore = scrollNow;\n };\n if (this.scrollContainer) {\n this.scrollContainer.addEventListener("scroll", this.onScroll);\n } else {\n window.addEventListener("scroll", this.onScroll);\n }\n },\n updated() {\n if (this.scrollContainer && !this.scrollContainer.isConnected) {\n this.destroyed();\n this.mounted();\n }\n },\n destroyed() {\n if (this.scrollContainer) {\n this.scrollContainer.removeEventListener("scroll", this.onScroll);\n } else {\n window.removeEventListener("scroll", this.onScroll);\n }\n },\n throttle(interval, callback) {\n let lastCallAt = 0;\n let timer;\n return (...args) => {\n const now = Date.now();\n const remainingTime = interval - (now - lastCallAt);\n if (remainingTime <= 0 || remainingTime > interval) {\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n lastCallAt = now;\n callback(...args);\n } else if (!timer) {\n timer = setTimeout(() => {\n lastCallAt = Date.now();\n timer = null;\n callback(...args);\n }, remainingTime);\n }\n };\n },\n findOverrunTarget() {\n let rect;\n const overrunTarget = this.el.getAttribute(\n this.liveSocket.binding(PHX_VIEWPORT_OVERRUN_TARGET)\n );\n if (overrunTarget) {\n const overrunEl = document.getElementById(overrunTarget);\n if (overrunEl) {\n rect = overrunEl.getBoundingClientRect();\n } else {\n throw new Error("did not find element with id " + overrunTarget);\n }\n } else {\n rect = this.el.getBoundingClientRect();\n }\n return rect;\n }\n};\nvar LiveFileUpload = {\n activeRefs() {\n return this.el.getAttribute(PHX_ACTIVE_ENTRY_REFS);\n },\n preflightedRefs() {\n return this.el.getAttribute(PHX_PREFLIGHTED_REFS);\n },\n mounted() {\n this.js().ignoreAttributes(this.el, ["value"]);\n this.preflightedWas = this.preflightedRefs();\n },\n updated() {\n const newPreflights = this.preflightedRefs();\n if (this.preflightedWas !== newPreflights) {\n this.preflightedWas = newPreflights;\n if (newPreflights === "") {\n this.__view().cancelSubmit(this.el.form);\n }\n }\n if (this.activeRefs() === "") {\n this.el.value = "";\n }\n this.el.dispatchEvent(new CustomEvent(PHX_LIVE_FILE_UPDATED));\n }\n};\nvar LiveImgPreview = {\n mounted() {\n this.ref = this.el.getAttribute("data-phx-entry-ref");\n this.inputEl = document.getElementById(\n this.el.getAttribute(PHX_UPLOAD_REF)\n );\n this.url = LiveUploader.getEntryDataURL(this.inputEl, this.ref);\n this.el.src = this.url;\n },\n destroyed() {\n URL.revokeObjectURL(this.url);\n }\n};\nvar Hooks = {\n LiveFileUpload,\n LiveImgPreview,\n FocusWrap: {\n mounted() {\n this.focusStart = this.el.firstElementChild;\n this.focusEnd = this.el.lastElementChild;\n this.focusStart.addEventListener("focus", (e) => {\n if (!e.relatedTarget || !this.el.contains(e.relatedTarget)) {\n const nextFocus = e.target.nextElementSibling;\n aria_default.attemptFocus(nextFocus) || aria_default.focu
1sFirst(nextFocus);\n } else {\n aria_default.focusLast(this.el);\n }\n });\n this.focusEnd.addEventListener("focus", (e) => {\n if (!e.relatedTarget || !this.el.contains(e.relatedTarget)) {\n const nextFocus = e.target.previousElementSibling;\n aria_default.attemptFocus(nextFocus) || aria_default.focusLast(nextFocus);\n } else {\n aria_default.focusFirst(this.el);\n }\n });\n if (!this.el.contains(document.activeElement)) {\n this.el.addEventListener("phx:show-end", () => this.el.focus());\n if (window.getComputedStyle(this.el).display !== "none") {\n aria_default.focusFirst(this.el);\n }\n }\n }\n },\n InfiniteScroll\n};\nvar hooks_default = Hooks;\n\n// js/phoenix_live_view/element_ref.ts\nvar ElementRef = class {\n static onUnlock(el, callback) {\n if (!dom_default.isLocked(el) && !el.closest(`[${PHX_REF_LOCK}]`)) {\n return callback();\n }\n const closestLock = el.closest(`[${PHX_REF_LOCK}]`);\n const ref = closestLock.closest(`[${PHX_REF_LOCK}]`).getAttribute(PHX_REF_LOCK);\n closestLock.addEventListener(\n `phx:undo-lock:${ref}`,\n () => {\n callback();\n },\n { once: true }\n );\n }\n constructor(el) {\n this.el = el;\n this.loadingRef = el.hasAttribute(PHX_REF_LOADING) ? parseInt(el.getAttribute(PHX_REF_LOADING), 10) : null;\n this.lockRef = el.hasAttribute(PHX_REF_LOCK) ? parseInt(el.getAttribute(PHX_REF_LOCK), 10) : null;\n }\n // public\n maybeUndo(ref, phxEvent, eachCloneCallback) {\n if (!this.isWithin(ref)) {\n dom_default.updatePrivate(this.el, PHX_PENDING_REFS, [], (pendingRefs) => {\n pendingRefs.push(ref);\n return pendingRefs;\n });\n return;\n }\n this.undoLocks(ref, phxEvent, eachCloneCallback);\n this.undoLoading(ref, phxEvent);\n dom_default.updatePrivate(this.el, PHX_PENDING_REFS, [], (pendingRefs) => {\n return pendingRefs.filter((pendingRef) => {\n let opts = {\n detail: { ref: pendingRef, event: phxEvent },\n bubbles: true,\n cancelable: false\n };\n if (this.loadingRef && this.loadingRef > pendingRef) {\n this.el.dispatchEvent(\n new CustomEvent(`phx:undo-loading:${pendingRef}`, opts)\n );\n }\n if (this.lockRef && this.lockRef > pendingRef) {\n this.el.dispatchEvent(\n new CustomEvent(`phx:undo-lock:${pendingRef}`, opts)\n );\n }\n return pendingRef > ref;\n });\n });\n if (this.isFullyResolvedBy(ref)) {\n this.el.removeAttribute(PHX_REF_SRC);\n }\n }\n // private\n isWithin(ref) {\n return !(this.loadingRef !== null && this.loadingRef > ref && this.lockRef !== null && this.lockRef > ref);\n }\n // Check for cloned PHX_REF_LOCK element that has been morphed behind\n // the scenes while this element was locked in the DOM.\n // When we apply the cloned tree to the active DOM element, we must\n //\n // 1. execute pending mounted hooks for nodes now in the DOM\n // 2. undo any ref inside the cloned tree that has since been ack\'d\n undoLocks(ref, phxEvent, eachCloneCallback) {\n if (!this.isLockUndoneBy(ref)) {\n return;\n }\n const clonedTree = dom_default.private(this.el, PHX_REF_LOCK);\n if (clonedTree) {\n eachCloneCallback(clonedTree);\n dom_default.deletePrivate(this.el, PHX_REF_LOCK);\n }\n this.el.removeAttribute(PHX_REF_LOCK);\n const opts = {\n detail: { ref, event: phxEvent },\n bubbles: true,\n cancelable: false\n };\n this.el.dispatchEvent(\n new CustomEvent(`phx:undo-lock:${this.lockRef}`, opts)\n );\n }\n undoLoading(ref, phxEvent) {\n if (!this.isLoadingUndoneBy(ref)) {\n if (this.canUndoLoading(ref) && this.el.classList.contains("phx-submit-loading")) {\n this.el.classList.remove("phx-change-loading");\n }\n return;\n }\n if (this.canUndoLoading(ref)) {\n this.el.removeAttribute(PHX_REF_LOADING);\n const disabledVal = this.el.getAttribute(PHX_DISABLED);\n const readOnlyVal = this.el.getAttribute(PHX_READONLY);\n if (readOnlyVal !== null && "readOnly" in this.el) {\n this.el.readOnly = readOnlyVal === "true" ? true : false;\n this.el.removeAttribute(PHX_READONLY);\n }\n if (disabledVal !== null && "disabled" in this.el) {\n this.el.disabled = disabledVal === "true" ? true : false;\n this.el.removeAttribute(PHX_DISABLED);\n }\n const disableRestore = this.el.getAttribute(PHX_DISABLE_WITH_RESTORE);\n if (disableRestore !== null) {\n this.el.textContent = disableRestore;\n this.el.removeAttribute(PHX_DISABLE_WITH_RESTORE);\n }\n const opts = {\n detail: { ref, event: phxEvent },\n bubbles: true,\n cancelable: false\n };\n this.el.dispatchEvent(\n new CustomEvent(`phx:undo-loading:${this.loadingRef}`, opts)\n );\n }\n PHX_EVENT_CLASSES.forEach((name) => {\n if (name !== "phx-submit-loading" || this.canUndoLoading(ref)) {\n dom_default.removeClass(this.el, name);\n }\n });\n }\n isLoadingUndoneBy(ref) {\n return this.loadingRef === null ? false : this.loadingRef <= ref;\n }\n /** @internal */\n isLockUndoneBy(ref) {\n return this.lockRef === null ? false : this.lockRef <= ref;\n }\n isFullyResolvedBy(ref) {\n return (this.loadingRef === null || this.loadingRef <= ref) && (this.lockRef === null || this.lockRef <= ref);\n }\n // only remove the phx-submit-loading class if we are not locked\n canUndoLoading(ref) {\n return this.lockRef === null || this.lockRef <= ref;\n }\n};\n\n// js/phoenix_live_view/dom_post_morph_restorer.ts\nvar DOMPostMorphRestorer = class {\n constructor(containerBefore, containerAfter, updateType) {\n const idsBefore = /* @__PURE__ */ new Set();\n const idsAfter = new Set(\n [...containerAfter.children].map((child) => child.id)\n );\n const elementsToModify = [];
1\n Array.from(containerBefore.children).forEach((child) => {\n if (child.id) {\n idsBefore.add(child.id);\n if (idsAfter.has(child.id)) {\n const previousElementId = child.previousElementSibling && child.previousElementSibling.id;\n elementsToModify.push({\n elementId: child.id,\n previousElementId\n });\n }\n }\n });\n this.containerId = containerAfter.id;\n this.updateType = updateType;\n this.elementsToModify = elementsToModify;\n this.elementIdsToAdd = [...idsAfter].filter((id) => !idsBefore.has(id));\n }\n // We do the following to optimize append/prepend operations:\n // 1) Track ids of modified elements & of new elements\n // 2) All the modified elements are put back in the correct position in the DOM tree\n // by storing the id of their previous sibling\n // 3) New elements are going to be put in the right place by morphdom during append.\n // For prepend, we move them to the first position in the container\n perform() {\n const container = dom_default.byId(this.containerId);\n if (!container) {\n return;\n }\n this.elementsToModify.forEach((elementToModify) => {\n if (elementToModify.previousElementId) {\n maybe(\n document.getElementById(elementToModify.previousElementId),\n (previousElem) => {\n maybe(\n document.getElementById(elementToModify.elementId),\n (elem) => {\n const isInRightPlace = elem.previousElementSibling && elem.previousElementSibling.id == previousElem.id;\n if (!isInRightPlace) {\n previousElem.insertAdjacentElement("afterend", elem);\n }\n }\n );\n }\n );\n } else {\n maybe(document.getElementById(elementToModify.elementId), (elem) => {\n const isInRightPlace = elem.previousElementSibling == null;\n if (!isInRightPlace) {\n container.insertAdjacentElement("afterbegin", elem);\n }\n });\n }\n });\n if (this.updateType == "prepend") {\n this.elementIdsToAdd.reverse().forEach((elemId) => {\n maybe(\n document.getElementById(elemId),\n (elem) => container.insertAdjacentElement("afterbegin", elem)\n );\n });\n }\n }\n};\n\n// ../node_modules/morphdom/dist/morphdom-esm.js\nvar DOCUMENT_FRAGMENT_NODE = 11;\nfunction morphAttrs(fromNode, toNode) {\n var toNodeAttrs = toNode.attributes;\n var attr;\n var attrName;\n var attrNamespaceURI;\n var attrValue;\n var fromValue;\n if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE || fromNode.nodeType === DOCUMENT_FRAGMENT_NODE) {\n return;\n }\n for (var i = toNodeAttrs.length - 1; i >= 0; i--) {\n attr = toNodeAttrs[i];\n attrName = attr.name;\n attrNamespaceURI = attr.namespaceURI;\n attrValue = attr.value;\n if (attrNamespaceURI) {\n attrName = attr.localName || attrName;\n fromValue = fromNode.getAttributeNS(attrNamespaceURI, attrName);\n if (fromValue !== attrValue) {\n if (attr.prefix === "xmlns") {\n attrName = attr.name;\n }\n fromNode.setAttributeNS(attrNamespaceURI, attrName, attrValue);\n }\n } else {\n fromValue = fromNode.getAttribute(attrName);\n if (fromValue !== attrValue) {\n fromNode.setAttribute(attrName, attrValue);\n }\n }\n }\n var fromNodeAttrs = fromNode.attributes;\n for (var d = fromNodeAttrs.length - 1; d >= 0; d--) {\n attr = fromNodeAttrs[d];\n attrName = attr.name;\n attrNamespaceURI = attr.namespaceURI;\n if (attrNamespaceURI) {\n attrName = attr.localName || attrName;\n if (!toNode.hasAttributeNS(attrNamespaceURI, attrName)) {\n fromNode.removeAttributeNS(attrNamespaceURI, attrName);\n }\n } else {\n if (!toNode.hasAttribute(attrName)) {\n fromNode.removeAttribute(attrName);\n }\n }\n }\n}\nvar range;\nvar NS_XHTML = "http://www.w3.org/1999/xhtml";\nvar doc = typeof document === "undefined" ? void 0 : document;
1\nvar HAS_TEMPLATE_SUPPORT = !!doc && "content" in doc.createElement("template");\nvar HAS_RANGE_SUPPORT = !!doc && doc.createRange && "createContextualFragment" in doc.createRange();\nfunction createFragmentFromTemplate(str) {\n var template = doc.createElement("template");\n template.innerHTML = str;\n return template.content.childNodes[0];\n}\nfunction createFragmentFromRange(str) {\n if (!range) {\n range = doc.createRange();\n range.selectNode(doc.body);\n }\n var fragment = range.createContextualFragment(str);\n return fragment.childNodes[0];\n}\nfunction createFragmentFromWrap(str) {\n var fragment = doc.createElement("body");\n fragment.innerHTML = str;\n return fragment.childNodes[0];\n}\nfunction toElement(str) {\n str = str.trim();\n if (HAS_TEMPLATE_SUPPORT) {\n return createFragmentFromTemplate(str);\n } else if (HAS_RANGE_SUPPORT) {\n return createFragmentFromRange(str);\n }\n return createFragmentFromWrap(str);\n}\nfunction compareNodeNames(fromEl, toEl) {\n var fromNodeName = fromEl.nodeName;\n var toNodeName = toEl.nodeName;\n var fromCodeStart, toCodeStart;\n if (fromNodeName === toNodeName) {\n return true;\n }\n fromCodeStart = fromNodeName.charCodeAt(0);\n toCodeStart = toNodeName.charCodeAt(0);\n if (fromCodeStart <= 90 && toCodeStart >= 97) {\n return fromNodeName === toNodeName.toUpperCase();\n } else if (toCodeStart <= 90 && fromCodeStart >= 97) {\n return toNodeName === fromNodeName.toUpperCase();\n } else {\n return false;\n }\n}\nfunction createElementNS(name, namespaceURI) {\n return !namespaceURI || namespaceURI === NS_XHTML ? doc.createElement(name) : doc.createElementNS(namespaceURI, name);\n}\nfunction moveChildren(fromEl, toEl) {\n var curChild = fromEl.firstChild;\n while (curChild) {\n var nextChild = curChild.nextSibling;\n toEl.appendChild(curChild);\n curChild = nextChild;\n }\n return toEl;\n}\nfunction syncBooleanAttrProp(fromEl, toEl, name) {\n if (fromEl[name] !== toEl[name]) {\n fromEl[name] = toEl[name];\n if (fromEl[name]) {\n fromEl.setAttribute(name, "");\n } else {\n fromEl.removeAttribute(name);\n }\n }\n}\nvar specialElHandlers = {\n OPTION: function(fromEl, toEl) {\n var parentNode = fromEl.parentNode;\n if (parentNode) {\n var parentName = parentNode.nodeName.toUpperCase();\n if (parentName === "OPTGROUP") {\n parentNode = parentNode.parentNode;\n parentName = parentNode && parentNode.nodeName.toUpperCase();\n }\n if (parentName === "SELECT" && !parentNode.hasAttribute("multiple")) {\n if (fromEl.hasAttribute("selected") && !toEl.selected) {\n fromEl.setAttribute("selected", "selected");\n fromEl.removeAttribute("selected");\n }\n parentNode.selectedIndex = -1;\n }\n }\n syncBooleanAttrProp(fromEl, toEl, "selected");\n },\n /**\n * The "value" attribute is special for the <input> element since it sets\n * the initial value. Changing the "value" attribute without changing the\n * "value" property will have no effect since it is only used to the set the\n * initial value. Similar for the "checked" attribute, and "disabled".\n */\n INPUT: function(fromEl, toEl) {\n syncBooleanAttrProp(fromEl, toEl, "checked");\n syncBooleanAttrProp(fromEl, toEl, "disabled");\n if (fromEl.value !== toEl.value) {\n fromEl.value = toEl.value;\n }\n if (!toEl.hasAttribute("value")) {\n fromEl.removeAttribute("value");\n }\n },\n TEXTAREA: function(fromEl, toEl) {\n var newValue = toEl.value;\n if (fromEl.value !== newValue) {\n fromEl.value = newValue;\n }\n var firstChild = fromEl.firstChild;\n if (firstChild) {\n var oldValue = firstChild.nodeValue;\n if (oldValue == newValue || !newValue && oldValue == fromEl.placeholder) {\n return;\n }\n firstChild.nodeValue = newValue;\n }\n },\n SELECT: function(fromEl, toEl) {\n if (!toEl.hasAttribute("multiple")) {\n var selectedIndex = -1;\n var i = 0;\n var curChild = fromEl.firstChild;\n var optgroup;\n var nodeName;\n while (curChild) {\n nodeName = curChild.nodeName && curChild.nodeName.toUpperCase();\n if (nodeName === "OPTGROUP") {\n optgroup = curChild;\n curChild = optgroup.firstChild;\n if (!curChild) {\n curChild = optgroup.nextSibling;\n optgroup = null;\n }\n } else {\n if (nodeName === "OPTION") {\n if (curChild.hasAttribute("selected")) {\n selectedIndex = i;\n break;\n }\n i++;\n }\n curChild = curChild.nextSibling;\n if (!curChild && optgroup) {\n curChild = optgroup.nextSibling;\n optgroup = null;\n }\n }\n }\n fromEl.selectedIndex = selectedIndex;\n }\n }\n};\nvar ELEMENT_NODE = 1;\nvar DOCUMENT_FRAGMENT_NODE$1 = 11;\nvar TEXT_NODE = 3;\nvar COMMENT_NODE = 8;\nfunction noop() {\n}\nfunction defaultGetNodeKey(node) {\n if (node) {\n return node.getAttribute && node.getAttribute("id") || node.id;\n }\n}\nfunction morphdomFactory(morphAttrs2) {\n return function morphdom2(fromNode, toNode, options) {\n if (!options) {\n options = {};\n }\n if (typeof toNode === "string") {\n if (fromNode.nodeName === "#document" || fromNode.nodeName === "HTML") {\n var toNodeHtml = toNode;\n toNode = doc.createElement("html");\n toNode.innerHTML = toNodeHtml;\n } else if (fromNode.nodeName === "BODY") {\n var toNodeBody = toNode;\n toNode = doc.createElement("html");\n toNode.innerHTML = toNodeBody;\n var bodyElement = toNode.querySelector("body");\n if (bodyElement) {\n toNode = bodyElement;\n }\n } else {\n toNode = toElement(toNode);\n }\n } else if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE$1) {\n toNode = toNode.firstElementChild;\n }\n var getNodeKey = options.getNodeKey || defaultGetNodeKey;\n var onBeforeNodeAdded = options.onBeforeNodeAdded || noop;\n var onNodeAdded = options.onNodeAdded || noop;\n var onBeforeElUpdated = options.onBeforeElUpdated || noop;\n var onElUpdated = options.onElUpdated || noop;\n var onBeforeNodeDiscarded = options.onBeforeNodeDiscarded || noop;\n var onNodeDiscarded = options.onNodeDiscarded || noop;\n var onBeforeElChildrenUpdated = options.onBeforeElChildrenUpdated || noop;\n var skipFromChildren = options.skipFromChildren || noop;\n var addChild = options.addChild || function(parent, child) {\n return parent.appendChild(child);\n };\n var childrenOnly = options.childrenOnly === true;\n var fromNodesLookup = /* @__PURE__ */ Object.create(null);\n var keyedRemovalList = [];\n function addKeyedRemoval(key) {\n keyedRemovalList.push(key);\n }\n function walkDiscardedChildNodes(node, skipKeyedNodes) {\n if (node.nodeType === ELEMENT_NODE) {\n var curChild = node.firstChild;\n while (curChild) {\n var key = void 0;\n if (skipKeyedNodes && (key = getNodeKey(curChild))) {\n addKeyedRemoval(key);\n } else {\n onNodeDiscarded(curChild);\n if (curChild.firstChild) {\n walkDiscardedChildNodes(curChild, skipKeyedNodes);\n }\n }\n curChild = curChild.nextSibling;\n }\n }\n }\n function removeNode(node, parentNode, skipKeyedNodes) {\n if (onBeforeNodeDiscarded(node) === false) {\n return;\n }\n if (parentNode) {\n parentNode.removeChild(node);\n }\n onNodeDiscarded(node);\n walkDiscardedChildNodes(node, skipKeyedNodes);\n }\n function indexTree(node) {\n if (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE$1) {\n var curChild = node.firstChild;\n while (curChild) {\n var key = getNodeKey(curChild);\n if (key) {\n fromNodesLookup[key] = curChild;\n }\n indexTree(curChild);\n curChild = curChild.nextSibling;\n }\n }\n }\n indexTree(fromNode);\n function handleNodeAdded(el) {\n onNodeAdded(el);\n var curChild = el.firstChild;\n while (curChild) {\n var nextSibling = curChild.nextSibling;\n var key = getNodeKey(curChild);\n if (key) {\n var unmatchedFromEl = fromNodesLookup[key];\n if (unmatchedFromEl && compareNodeNames(curChild, unmatchedFromEl)) {\n curChild.parentNode.replaceChild(unmatchedFromEl, curChild);\n morphEl(unmatchedFromEl, curChild);\n } else {\n handleNodeAdded(curChild);\n }\n } else {\n handleNodeAdded(curChild);\n }\n curChild = nextSibling;\n }\n }\n function cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey) {\n while (curFromNodeChild) {\n var fromNextSibling = curFromNodeChild.nextSibling;\n if (curFromNodeKey = getNodeKey(curFromNodeChild)) {\n addKeyedRemoval(curFromNodeKey);\n } else {\n removeNode(\n curFromNodeChild,\n fromEl,\n true\n /* skip keyed nodes */\n );\n }\n curFromNodeChild = fromNextSibling;\n }\n }\n function morphEl(fromEl, toEl, childrenOnly2) {\n var toElKey = getNodeKey(toEl);\n if (toElKey) {\n delete fromNodesLookup[toElKey];\n }\n if (!childrenOnly2) {\n var beforeUpdateResult = onBeforeElUpdated(fromEl, toEl);\n if (beforeUpdateResult === false) {\n return;\n } else if (beforeUpdateResult instanceof HTMLElement) {\n fromEl = beforeUpdateResult;\n indexTree(fromEl);\n }\n morphAttrs2(fromEl, toEl);\n onElUpdated(fromEl);\n if (onBeforeElChildrenUpdated(fromEl, toEl) === false) {\n return;\n }\n }\n if (fromEl.nodeName !== "TEXTAREA") {\n morphChildren(fromEl, toEl);\n } else {\n specialElHandlers.TEXTAREA(fromEl, toEl);\n }\n }\n function morphChildren(fromEl, toEl) {\n var skipFrom = ski
1pFromChildren(fromEl, toEl);\n var curToNodeChild = toEl.firstChild;\n var curFromNodeChild = fromEl.firstChild;\n var curToNodeKey;\n var curFromNodeKey;\n var fromNextSibling;\n var toNextSibling;\n var matchingFromEl;\n outer:\n while (curToNodeChild) {\n toNextSibling = curToNodeChild.nextSibling;\n curToNodeKey = getNodeKey(curToNodeChild);\n while (!skipFrom && curFromNodeChild) {\n fromNextSibling = curFromNodeChild.nextSibling;\n if (curToNodeChild.isSameNode && curToNodeChild.isSameNode(curFromNodeChild)) {\n curToNodeChild = toNextSibling;\n curFromNodeChild = fromNextSibling;\n continue outer;\n }\n curFromNodeKey = getNodeKey(curFromNodeChild);\n var curFromNodeType = curFromNodeChild.nodeType;\n var isCompatible = void 0;\n if (curFromNodeType === curToNodeChild.nodeType) {\n if (curFromNodeType === ELEMENT_NODE) {\n if (curToNodeKey) {\n if (curToNodeKey !== curFromNodeKey) {\n if (matchingFromEl = fromNodesLookup[curToNodeKey]) {\n if (fromNextSibling === matchingFromEl) {\n isCompatible = false;\n } else {\n fromEl.insertBefore(matchingFromEl, curFromNodeChild);\n if (curFromNodeKey) {\n addKeyedRemoval(curFromNodeKey);\n } else {\n removeNode(\n curFromNodeChild,\n fromEl,\n true\n /* skip keyed nodes */\n );\n }\n curFromNodeChild = matchingFromEl;\n curFromNodeKey = getNodeKey(curFromNodeChild);\n }\n } else {\n isCompatible = false;\n }\n }\n } else if (curFromNodeKey) {\n isCompatible = false;\n }\n isCompatible = isCompatible !== false && compareNodeNames(curFromNodeChild, curToNodeChild);\n if (isCompatible) {\n morphEl(curFromNodeChild, curToNodeChild);\n }\n } else if (curFromNodeType === TEXT_NODE || curFromNodeType == COMMENT_NODE) {\n isCompatible = true;\n if (curFromNodeChild.nodeValue !== curToNodeChild.nodeValue) {\n curFromNodeChild.nodeValue = curToNodeChild.nodeValue;\n }\n }\n }\n if (isCompatible) {\n curToNodeChild = toNextSibling;\n curFromNodeChild = fromNextSibling;\n continue outer;\n }\n if (curFromNodeKey) {\n addKeyedRemoval(curFromNodeKey);\n } else {\n removeNode(\n curFromNodeChild,\n fromEl,\n true\n /* skip keyed nodes */\n );\n }\n curFromNodeChild = fromNextSibling;\n }\n if (curToNodeKey && (matchingFromEl = fromNodesLookup[curToNodeKey]) && compareNodeNames(matchingFromEl, curToNodeChild)) {\n if (!skipFrom) {\n addChild(fromEl, matchingFromEl);\n }\n morphEl(matchingFromEl, curToNodeChild);\n } else {\n var onBeforeNodeAddedResult = onBeforeNodeAdded(curToNodeChild);\n if (onBeforeNodeAddedResult !== false) {\n if (onBeforeNodeAddedResult) {\n curToNodeChild = onBeforeNodeAddedResult;\n }\n if (curToNodeChild.actualize) {\n curToNodeChild = curToNodeChild.actualize(fromEl.ownerDocument || doc);\n }\n addChild(fromEl, curToNodeChild);\n handleNodeAdded(curToNodeChild);\n }\n }\n curToNodeChild = toNextSibling;\n curFromNodeChild = fromNextSibling;\n }\n cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey);\n var specialElHandler = specialElHandlers[fromEl.nodeName];\n if (specialElHandler) {\n specialElHandler(fromEl, toEl);\n }\n }\n var morphedNode = fromNode;\n var morphedNodeType = morphedNode.nodeType;\n var toNodeType = toNode.nodeType;\n if (!childrenOnly) {\n if (morphedNodeType === ELEMENT_NODE) {\n if (toNodeType === ELEMENT_NODE) {\n if (!compareNodeNames(fromNode, toNode)) {\n onNodeDiscarded(fromNode);\n morphedNode = moveChildren(fromNode, createElementNS(toNode.nodeName, toNode.namespaceURI));\n }\n } else {\n morphedNode = toNode;\n }\n } else if (morphedNodeType === TEXT_NODE || morphedNodeType === COMMENT_NODE) {\n if (toNodeType === morphedNodeType) {\n if (morphedNode.nodeValue !== toNode.nodeValue) {\n morphedNode.nodeValue = toNode.nodeValue;\n }\n return morphedNode;\n } else {\n morphedNode = toNode;\n }\n }\n }\n if (morphedNode === toNode) {\n onNodeDiscarded(fromNode);\n } else {\n if (toNode.isSameNode && toNode.isSameNode(morphedNode)) {\n return;\n }\n morphEl(morphedNode, toNode, childrenOnly);\n if (keyedRemovalList) {\n for (var i = 0, len = keyedRemovalList.length; i < len;
1 i++) {\n var elToRemove = fromNodesLookup[keyedRemovalList[i]];\n if (elToRemove) {\n removeNode(elToRemove, elToRemove.parentNode, false);\n }\n }\n }\n }\n if (!childrenOnly && morphedNode !== fromNode && fromNode.parentNode) {\n if (morphedNode.actualize) {\n morphedNode = morphedNode.actualize(fromNode.ownerDocument || doc);\n }\n fromNode.parentNode.replaceChild(morphedNode, fromNode);\n }\n return morphedNode;\n };\n}\nvar morphdom = morphdomFactory(morphAttrs);\nvar morphdom_esm_default = morphdom;\n\n// js/phoenix_live_view/dom_patch.ts\nvar DOMPatch = class {\n constructor(view, container, html, streams, targetCID, opts = {}) {\n this.view = view;\n this.liveSocket = view.liveSocket;\n this.container = container;\n this.rootID = view.root.id;\n this.html = html;\n this.streams = streams;\n this.streamInserts = {};\n this.streamComponentRestore = {};\n this.targetCID = targetCID;\n this.pendingRemoves = [];\n this.phxRemove = this.liveSocket.binding("remove");\n this.targetContainer = targetCID ? dom_default.getComponent(this.view.id, targetCID) : container;\n this.beforeUpdatedCallbacks = [];\n this.afterAddedCallbacks = [];\n this.afterUpdatedCallbacks = [];\n this.afterPhxChildAddedCallbacks = [];\n this.afterDiscardedCallbacks = [];\n this.afterTransitionsDiscardedCallbacks = [];\n this.withChildren = opts.withChildren || opts.undoRef !== void 0 || false;\n this.undoRef = opts.undoRef ?? null;\n }\n beforeUpdated(callback) {\n this.beforeUpdatedCallbacks.push(callback);\n }\n afterAdded(callback) {\n this.afterAddedCallbacks.push(callback);\n }\n afterUpdated(callback) {\n this.afterUpdatedCallbacks.push(callback);\n }\n afterPhxChildAdded(callback) {\n this.afterPhxChildAddedCallbacks.push(callback);\n }\n afterDiscarded(callback) {\n this.afterDiscardedCallbacks.push(callback);\n }\n afterTransitionsDiscarded(callback) {\n this.afterTransitionsDiscardedCallbacks.push(callback);\n }\n markPrunableContentForRemoval() {\n const phxUpdate = this.liveSocket.binding(PHX_UPDATE);\n dom_default.all(\n this.container,\n `[${phxUpdate}=append] > *, [${phxUpdate}=prepend] > *`,\n (el) => {\n el.setAttribute(PHX_PRUNE, "");\n }\n );\n }\n perform(isJoinPatch) {\n const { view, liveSocket, html, container } = this;\n let targetContainer = this.targetContainer;\n if (this.targetCID) {\n const closestLock = targetContainer.closest(`[${PHX_REF_LOCK}]`);\n if (closestLock && !closestLock.isSameNode(targetContainer)) {\n const clonedTree = dom_default.private(closestLock, PHX_REF_LOCK);\n if (clonedTree) {\n targetContainer = clonedTree.querySelector(\n `[data-phx-component="${this.targetCID}"]`\n );\n if (!targetContainer)\n return;\n }\n }\n }\n const focused = liveSocket.getActiveElement();\n const { selectionStart, selectionEnd } = focused && dom_default.hasSelectionRange(focused) ? focused : {};\n const phxUpdate = liveSocket.binding(PHX_UPDATE);\n const phxViewportTop = liveSocket.binding(PHX_VIEWPORT_TOP);\n const phxViewportBottom = liveSocket.binding(PHX_VIEWPORT_BOTTOM);\n const phxTriggerExternal = liveSocket.binding(PHX_TRIGGER_ACTION);\n const added = [];\n const updates = [];\n const appendPrependUpdates = [];\n let portalCallbacks = [];\n let externalFormTriggered = null;\n const morph = (targetContainer2, source, withChildren = this.withChildren) => {\n const morphCallbacks = {\n // normally, we are running with childrenOnly, as the patch HTML for a LV\n // does not include the LV attrs (data-phx-session, etc.)\n // when we are patching a live component, we do want to patch the root element as well;\n // another case is the recursive patch of a stream item that was kept on reset (-> onBeforeNodeAdded)\n childrenOnly: targetContainer2.getAttribute(PHX_COMPONENT) === null && !withChildren,\n getNodeKey: (node) => {\n if (!(node instanceof Element))\n return null;\n if (dom_default.isPhxDestroyed(node)) {\n return null;\n }\n if (isJoinPatch) {\n return node.id;\n }\n if (dom_default.private(node, "clientsideIdAttribute")) {\n return node.getAttribute(PHX_MAGIC_ID);\n }\n return node.id || node.getAttribute(PHX_MAGIC_ID);\n },\n // skip indexing from children when container is stream\n skipFromChildren: (from) => {\n return from.getAttribute(phxUpdate) === PHX_STREAM;\n },\n // tell morphdom how to add a child\n addChild: (parent, child) =>
1 {\n const { ref, streamAt } = this.getStreamInsert(child);\n if (ref === void 0) {\n return parent.appendChild(child);\n }\n this.setStreamRef(child, ref);\n if (streamAt === 0) {\n parent.insertAdjacentElement("afterbegin", child);\n } else if (streamAt === -1) {\n const lastChild = parent.lastElementChild;\n if (lastChild && !lastChild.hasAttribute(PHX_STREAM_REF)) {\n const nonStreamChild = Array.from(parent.children).find(\n (c) => !c.hasAttribute(PHX_STREAM_REF)\n );\n parent.insertBefore(child, nonStreamChild ?? null);\n } else {\n parent.appendChild(child);\n }\n } else if (streamAt > 0) {\n const sibling = Array.from(parent.children)[streamAt];\n parent.insertBefore(child, sibling);\n }\n },\n onBeforeNodeAdded: (el) => {\n if (!(el instanceof Element)) {\n return el;\n }\n if (this.getStreamInsert(el)?.updateOnly && !this.streamComponentRestore[el.id]) {\n return false;\n }\n dom_default.maintainPrivateHooks(el, el, phxViewportTop, phxViewportBottom);\n let morphedEl = el;\n if (this.streamComponentRestore[el.id]) {\n morphedEl = this.streamComponentRestore[el.id];\n delete this.streamComponentRestore[el.id];\n morph(morphedEl, el, true);\n }\n return morphedEl;\n },\n onNodeAdded: (el) => {\n if (!(el instanceof Element)) {\n added.push(el);\n return;\n }\n this.maybeReOrderStream(el, true);\n if (dom_default.isPortalTemplate(el)) {\n portalCallbacks.push(() => this.teleport(el, morph));\n }\n if (el instanceof HTMLImageElement && el.srcset) {\n el.srcset = el.srcset;\n } else if (el instanceof HTMLVideoElement && el.autoplay) {\n el.play();\n }\n if (dom_default.isNowTriggerFormExternal(el, phxTriggerExternal)) {\n externalFormTriggered = el;\n }\n if (dom_default.isPhxChild(el) && view.ownsElement(el) || dom_default.isPhxSticky(el) && view.ownsElement(el.parentNode)) {\n this.trackAfterPhxChildAdded(el);\n }\n if (el.nodeName === "SCRIPT" && el.hasAttribute(PHX_RUNTIME_HOOK)) {\n this.handleRuntimeHook(el, source);\n }\n added.push(el);\n },\n onNodeDiscarded: (el) => this.onNodeDiscarded(el),\n onBeforeNodeDiscarded: (el) => {\n if (!(el instanceof Element)) {\n return true;\n }\n if (el.getAttribute(PHX_PRUNE) !== null) {\n return true;\n }\n if (el.parentElement !== null && el.id && dom_default.isPhxUpdate(el.parentElement, phxUpdate, [\n PHX_STREAM,\n "append",\n "prepend"\n ])) {\n return false;\n }\n if (el.getAttribute(PHX_TELEPORTED_REF)) {\n return false;\n }\n if (this.maybePendingRemove(el)) {\n return false;\n }\n if (this.skipCIDSibling(el)) {\n return false;\n }\n if (dom_default.isPortalTemplate(el)) {\n const teleportedEl = document.getElementById(\n el.content.firstElementChild?.id || ""\n );\n if (teleportedEl) {\n teleportedEl.remove();\n morphCallbacks.onNodeDiscarded(teleportedEl);\n this.view.dropPortalElementId(teleportedEl.id);\n }\n }\n return true;\n },\n onElUpdated: (el) => {\n if (dom_default.isNowTriggerFormExternal(el, phxTriggerExternal)) {\n externalFormTriggered = el;\n }\n updates.push(el);\n this.maybeReOrderStream(el, false);\n },\n onBeforeElUpdated: (fromEl, toEl) => {\n if (fromEl.id && fromEl.isSameNode(targetContainer2) && fromEl.id !== toEl.id) {\n morphCallbacks.onNodeDiscarded(fromEl);\n fromEl.replaceWith(toEl);\n return morphCallbacks.onNodeAdded(toEl);\n }\n dom_default.syncPendingAttrs(fromEl, toEl);\n dom_default.maintainPrivateHooks(\n fromEl,\n toEl,\n phxViewportTop,\n phxViewportBottom\n );\n dom_default.cleanChildNodes(toEl, phxUpdate);\n const isFocusedFormEl = focused && fromEl.isSameNode(focused) && dom_default.isEditableInput(fromEl);\n const focusedSelectChanged = isFocusedFormEl && this.isChangedSelect(fromEl, toEl);\n if (this.skipCIDSibling(toEl)) {\n this.maybeCloneLockedElement(fromEl, isFocusedFormEl);\n this.copyNestedPrivateLock(fromEl, toEl);\n this.maybeReOrderStream(fromEl);\n return false;\n }\n if (dom_default.isPhxSticky(fromEl)) {\n [PHX_SESSION, PHX_STATIC, PHX_ROOT_ID].map((attr) => [\n attr,\n fromEl.getAttribute(attr),\n toEl.getAttribute(attr)\n ]).forEac
1h(([attr, fromVal, toVal]) => {\n if (toVal && fromVal !== toVal) {\n fromEl.setAttribute(attr, toVal);\n }\n });\n return false;\n }\n if (dom_default.isIgnored(fromEl, phxUpdate) || fromEl.form && fromEl.form.isSameNode(externalFormTriggered)) {\n this.trackBeforeUpdated(fromEl, toEl);\n dom_default.mergeAttrs(fromEl, toEl, {\n isIgnored: dom_default.isIgnored(fromEl, phxUpdate)\n });\n updates.push(fromEl);\n dom_default.applyStickyOperations(fromEl);\n return false;\n }\n if (fromEl.type === "number" && fromEl.validity && fromEl.validity.badInput) {\n return false;\n }\n fromEl = this.maybeCloneLockedElement(fromEl, isFocusedFormEl);\n if (dom_default.isPhxChild(toEl)) {\n const prevSession = fromEl.getAttribute(PHX_SESSION);\n dom_default.mergeAttrs(fromEl, toEl, { exclude: [PHX_STATIC] });\n if (prevSession !== "") {\n fromEl.setAttribute(PHX_SESSION, prevSession);\n }\n fromEl.setAttribute(PHX_ROOT_ID, this.rootID);\n dom_default.applyStickyOperations(fromEl);\n return false;\n }\n this.copyNestedPrivateLock(fromEl, toEl);\n dom_default.copyPrivates(toEl, fromEl);\n if (dom_default.isPortalTemplate(toEl)) {\n portalCallbacks.push(() => this.teleport(toEl, morph));\n fromEl.content.replaceChildren(toEl.content.cloneNode(true));\n return false;\n }\n if (isFocusedFormEl && fromEl.type !== "hidden" && !focusedSelectChanged) {\n this.trackBeforeUpdated(fromEl, toEl);\n dom_default.mergeFocusedInput(fromEl, toEl);\n dom_default.syncAttrsToProps(fromEl);\n updates.push(fromEl);\n dom_default.applyStickyOperations(fromEl);\n return false;\n } else {\n if (focusedSelectChanged) {\n fromEl.blur();\n }\n if (dom_default.isPhxUpdate(toEl, phxUpdate, ["append", "prepend"])) {\n appendPrependUpdates.push(\n new DOMPostMorphRestorer(\n fromEl,\n toEl,\n toEl.getAttribute(phxUpdate)\n )\n );\n }\n dom_default.syncAttrsToProps(toEl);\n dom_default.applyStickyOperations(toEl);\n this.trackBeforeUpdated(fromEl, toEl);\n return fromEl;\n }\n }\n };\n morphdom_esm_default(targetContainer2, source, morphCallbacks);\n };\n this.trackBeforeUpdated(container, container);\n liveSocket.time("morphdom", () => {\n this.streams.forEach(([ref, inserts, deleteIds, reset]) => {\n inserts.forEach(([key, streamAt, limit, updateOnly]) => {\n this.streamInserts[key] = { ref, streamAt, limit, reset, updateOnly };\n });\n if (reset !== void 0) {\n dom_default.all(document, `[${PHX_STREAM_REF}="${ref}"]`, (child) =>
1 {\n this.removeStreamChildElement(child);\n });\n }\n deleteIds.forEach((id) => {\n const child = document.getElementById(id);\n if (child) {\n this.removeStreamChildElement(child);\n }\n });\n });\n if (isJoinPatch) {\n dom_default.all(this.container, `[${phxUpdate}=${PHX_STREAM}]`).filter((el) => this.view.ownsElement(el)).forEach((el) => {\n Array.from(el.children).forEach((child) => {\n this.removeStreamChildElement(child, true);\n });\n });\n }\n morph(targetContainer, html);\n let teleportCount = 0;\n while (portalCallbacks.length > 0 && teleportCount < 5) {\n const copy = portalCallbacks.slice();\n portalCallbacks = [];\n copy.forEach((callback) => callback());\n teleportCount++;\n }\n this.view.portalElementIds.forEach((id) => {\n const el = document.getElementById(id);\n if (el) {\n const srcId = el.getAttribute(PHX_TELEPORTED_SRC);\n if (srcId) {\n const source = document.getElementById(srcId);\n if (!source) {\n el.remove();\n this.onNodeDiscarded(el);\n this.view.dropPortalElementId(id);\n }\n }\n }\n });\n });\n if (liveSocket.isDebugEnabled()) {\n detectDuplicateIds();\n detectInvalidStreamInserts(this.streamInserts);\n Array.from(document.querySelectorAll("input[name=id]")).forEach(\n (node) => {\n if (node instanceof HTMLInputElement && node.form) {\n console.error(\n \'Detected an input with name="id" inside a form! This will cause problems when patching the DOM.\\n\',\n node\n );\n }\n }\n );\n }\n if (appendPrependUpdates.length > 0) {\n liveSocket.time("post-morph append/prepend restoration", () => {\n appendPrependUpdates.forEach((update) => update.perform());\n });\n }\n liveSocket.silenceEvents(\n () => dom_default.restoreFocus(focused, selectionStart, selectionEnd)\n );\n dom_default.dispatchEvent(document, "phx:update");\n added.forEach((el) => this.trackAfterAdded(el));\n updates.forEach((el) => this.trackAfterUpdated(el));\n this.transitionPendingRemoves();\n if (externalFormTriggered) {\n liveSocket.unload();\n const submitter = dom_default.private(externalFormTriggered, "submitter");\n if (submitter && submitter.name && targetContainer.contains(submitter)) {\n const input = document.createElement("input");\n input.type = "hidden";\n const formId = submitter.getAttribute("form");\n if (formId) {\n input.setAttribute("form", formId);\n }\n input.name = submitter.name;\n input.value = submitter.value;\n submitter.parentElement.insertBefore(input, submitter);\n }\n Object.getPrototypeOf(externalFormTriggered).submit.call(\n externalFormTriggered\n );\n }\n return true;\n }\n trackBeforeUpdated(fromEl, toEl) {\n this.beforeUpdatedCallbacks.forEach((cb) => cb(fromEl, toEl));\n }\n trackAfterAdded(el) {\n this.afterAddedCallbacks.forEach((cb) => cb(el));\n }\n trackAfterUpdated(el) {\n this.afterUpdatedCallbacks.forEach((cb) => cb(el));\n }\n trackAfterPhxChildAdded(el) {\n this.afterPhxChildAddedCallbacks.forEach((cb) => cb(el));\n }\n trackAfterDiscarded(el) {\n this.afterDiscardedCallbacks.forEach((cb) => cb(el));\n }\n trackAfterTransitionsDiscarded(els) {\n this.afterTransitionsDiscardedCallbacks.forEach((cb) => cb(els));\n }\n onNodeDiscarded(el) {\n if (dom_default.isPhxChild(el) || dom_default.isPhxSticky(el)) {\n this.liveSocket.destroyViewByEl(el);\n }\n this.trackAfterDiscarded(el);\n }\n maybePendingRemove(node) {\n if (node.getAttribute && node.getAttribute(this.phxRemove) !== null) {\n this.pendingRemoves.push(node);\n return true;\n } else {\n return false;\n }\n }\n removeStreamChildElement(child, force = false) {\n if (!force && !this.view.ownsElement(child)) {\n return;\n }\n if (this.streamInserts[child.id]) {\n this.streamComponentRestore[child.id] = child;\n child.remove();\n } else {\n if (!this.maybePendingRemove(child)) {\n child.remove();\n this.onNodeDiscarded(child);\n }\n }\n }
1\n getStreamInsert(el) {\n const insert = el.id ? this.streamInserts[el.id] : {};\n return insert || {};\n }\n setStreamRef(el, ref) {\n dom_default.putSticky(\n el,\n PHX_STREAM_REF,\n (el2) => el2.setAttribute(PHX_STREAM_REF, ref)\n );\n }\n maybeReOrderStream(el, isNew = false) {\n const { ref, streamAt, reset } = this.getStreamInsert(el);\n if (streamAt === void 0) {\n return;\n }\n this.setStreamRef(el, ref);\n if (!reset && !isNew) {\n return;\n }\n if (!el.parentElement) {\n return;\n }\n if (streamAt === 0) {\n this.moveOrInsertBefore(\n el.parentElement,\n el,\n el.parentElement.firstElementChild\n );\n } else if (streamAt > 0) {\n const children = Array.from(el.parentElement.children);\n const oldIndex = children.indexOf(el);\n if (streamAt >= children.length - 1) {\n this.moveOrInsertBefore(el.parentElement, el, null);\n } else {\n const sibling = children[streamAt];\n if (oldIndex > streamAt) {\n this.moveOrInsertBefore(el.parentElement, el, sibling);\n } else {\n this.moveOrInsertBefore(\n el.parentElement,\n el,\n sibling.nextElementSibling\n );\n }\n }\n }\n this.maybeLimitStream(el);\n }\n // Reorder a child within its parent. When supported, use the atomic\n // moveBefore (https://developer.mozilla.org/en-US/docs/Web/API/Node/moveBefore)\n // so connected custom elements (and other state-bearing nodes like iframes)\n // are not disconnected and reconnected by the move. Falls back to\n // insertBefore otherwise. Passing `ref === null` moves to the end.\n // See also https://github.com/phoenixframework/phoenix_live_view/issues/4212.\n moveOrInsertBefore(parent, child, ref) {\n if (typeof parent.moveBefore === "function") {\n try {\n parent.moveBefore(child, ref);\n return;\n } catch {\n }\n }\n parent.insertBefore(child, ref);\n }\n maybeLimitStream(el) {\n const { limit } = this.getStreamInsert(el);\n if (limit !== null) {\n const children = Array.from(el.parentElement.children);\n if (limit < 0 && children.length > limit * -1) {\n children.slice(0, children.length + limit).forEach((child) => this.removeStreamChildElement(child));\n } else if (limit >= 0 && children.length > limit) {\n children.slice(limit).forEach((child) => this.removeStreamChildElement(child));\n }\n }\n }\n transitionPendingRemoves() {\n const { pendingRemoves, liveSocket } = this;\n if (pendingRemoves.length > 0) {\n liveSocket.transitionRemoves(pendingRemoves, this.view, () => {\n pendingRemoves.forEach((el) => {\n const child = dom_default.firstPhxChild(el);\n if (child) {\n liveSocket.destroyViewByEl(child);\n }\n el.remove();\n });\n this.trackAfterTransitionsDiscarded(pendingRemoves);\n });\n }\n }\n isChangedSelect(fromEl, toEl) {\n if (!(fromEl instanceof HTMLSelectElement) || fromEl.multiple) {\n return false;\n }\n if (fromEl.options.length !== toEl.options.length) {\n return true;\n }\n toEl.value = fromEl.value;\n return !fromEl.isEqualNode(toEl);\n }\n skipCIDSibling(el) {\n return el.nodeType === Node.ELEMENT_NODE && el.hasAttribute(PHX_SKIP);\n }\n maybeCloneLockedElement(fromEl, isFocusedFormEl) {\n if (!fromEl.hasAttribute(PHX_REF_SRC))\n return fromEl;\n const ref = new ElementRef(fromEl);\n if (!fromEl.hasAttribute(PHX_REF_LOCK) || this.undoRef !== null && ref.isLockUndoneBy(this.undoRef)) {\n return fromEl;\n }\n dom_default.applyStickyOperations(fromEl);\n const clone2 = fromEl.hasAttribute(PHX_REF_LOCK) ? dom_default.private(fromEl, PHX_REF_LOCK) || fromEl.cloneNode(true) : null;\n if (!clone2)\n return fromEl;\n dom_default.putPrivate(fromEl, PHX_REF_LOCK, clone2);\n return isFocusedFormEl ? fromEl : clone2;\n }\n copyNestedPrivateLock(fromEl, toEl) {\n if (this.undoRef === null || !dom_default.private(toEl, PHX_REF_LO
1CK))\n return;\n dom_default.putPrivate(fromEl, PHX_REF_LOCK, dom_default.private(toEl, PHX_REF_LOCK));\n }\n indexOf(parent, child) {\n return Array.from(parent.children).indexOf(child);\n }\n teleport(el, morph) {\n const targetSelector = el.getAttribute(PHX_PORTAL);\n const portalContainer = document.querySelector(targetSelector);\n if (!portalContainer) {\n throw new Error(\n "portal target with selector " + targetSelector + " not found"\n );\n }\n const toTeleport = el.content.firstElementChild;\n if (this.skipCIDSibling(toTeleport)) {\n return;\n }\n if (!toTeleport?.id) {\n throw new Error(\n "phx-portal template must have a single root element with ID!"\n );\n }\n const existing = document.getElementById(toTeleport.id);\n let portalTarget;\n if (existing) {\n if (!portalContainer.contains(existing)) {\n portalContainer.appendChild(existing);\n }\n portalTarget = existing;\n } else {\n portalTarget = document.createElement(toTeleport.tagName);\n portalContainer.appendChild(portalTarget);\n }\n toTeleport.setAttribute(PHX_TELEPORTED_REF, this.view.id);\n toTeleport.setAttribute(PHX_TELEPORTED_SRC, el.id);\n morph(portalTarget, toTeleport, true);\n toTeleport.removeAttribute(PHX_TELEPORTED_REF);\n toTeleport.removeAttribute(PHX_TELEPORTED_SRC);\n this.view.pushPortalElementId(toTeleport.id);\n }\n handleRuntimeHook(el, source) {\n const name = el.getAttribute(PHX_RUNTIME_HOOK);\n let nonce = el.hasAttribute("nonce") ? el.getAttribute("nonce") : null;\n if (el.hasAttribute("nonce")) {\n const template = document.createElement("template");\n template.innerHTML = source;\n nonce = template.content.querySelector(`script[${PHX_RUNTIME_HOOK}="${CSS.escape(name)}"]`)?.getAttribute("nonce") ?? null;\n }\n const script = document.createElement("script");\n script.textContent = el.textContent;\n dom_default.mergeAttrs(script, el, { isIgnored: false });\n if (nonce) {\n script.nonce = nonce;\n }\n el.replaceWith(script);\n el = script;\n }\n};\n\n// js/phoenix_live_view/rendered.js\nvar VOID_TAGS = /* @__PURE__ */ new Set([\n "area",\n "base",\n "br",\n "col",\n "command",\n "embed",\n "hr",\n "img",\n "input",\n "keygen",\n "link",\n "meta",\n "param",\n "source",\n "track",\n "wbr"\n]);\nvar quoteChars = /* @__PURE__ */ new Set(["\'", \'"\']);\nvar modifyRoot = (html, attrs, clearInnerHTML) => {\n let i = 0;\n let insideComment = false;\n let beforeTag, afterTag, tag, tagNameEndsAt, id, newHTML;\n const lookahead = html.match(/^(\\s*(?:\x3c!--.*?--\x3e\\s*)*)<([^\\s\\/>]+)/);\n if (lookahead === null) {\n throw new Error(`malformed html ${html}`);\n }\n i = lookahead[0].length;\n beforeTag = lookahead[1];\n tag = lookahead[2];\n tagNameEndsAt = i;\n for (i; i < html.length; i++) {\n if (html.charAt(i) === ">") {\n break;\n }\n if (html.charAt(i) === "=") {\n const isId = html.slice(i - 3, i) === " id";\n i++;\n const char = html.charAt(i);\n if (quoteChars.has(char)) {\n const attrStartsAt = i;\n i++;\n for (i; i < html.length; i++) {\n if (html.charAt(i) === char) {\n break;\n }\n }\n if (isId) {\n id = html.slice(attrStartsAt + 1, i);\n break;\n }\n }\n }\n }\n let closeAt = html.length - 1;\n insideComment = false;\n while (closeAt >= beforeTag.length + tag.length) {\n const char = html.charAt(closeAt);\n if (insideComment) {\n if (char === "-" && html.slice(closeAt - 3, closeAt) === "<!-") {\n insideComment = false;\n closeAt -= 4;\n } else {\n closeAt -= 1;\n }\n } else if (char === ">" && html.slice(closeAt - 2, closeAt) === "--") {\n insideComment = true;\n closeAt -= 3;\n } else if (char === ">") {\n break;\n } else {\n closeAt -= 1;\n }\n }\n afterTag = html.slice(closeAt + 1, html.length);\n const attrsStr = Object.keys(attrs).map((attr) => attrs[attr] === true ? attr : `${attr}="${attrs[attr]}"`).join(" ");\n if (clearInnerHTML) {\n const idAttrStr = id ? ` id="${id}"` : "";\n if (VOID_TAGS.has(tag)) {\n newHTML = `<${tag}${idAttrStr}${attrsStr === "" ? "" : " "}${attrsStr}/>`;\n } else {\n newHTML = `<${tag}${idAttrStr}${attrsStr === "" ? "" : " "}${attrsStr}></${tag}>`;\n }\n } else {\n const rest = html.slice(tagNameEndsAt, closeAt + 1);\n newHTML = `<${tag}${attrsStr === "" ? "" : " "}${attrsStr}${rest}`;\n }\n return [newHTML, beforeTag, afterTag];\n};\nvar Rendered = class {\n static extract(diff) {\n const { [REPLY]: reply, [EVENTS]: events, [TITLE]: title } = diff;\n delete diff[REPLY];\n delete diff[EVENTS];\n delete diff[TITLE];\n return { diff, title, reply: reply || null, events: events || [] };\n }\n constructor(viewId, rendered) {\n this.viewId = viewId;\n this.rendered = {};\n this.magicId = 0;\n this.mergeDiff(rendered);\n }\n parentViewId() {\n return this.viewId;\n }\n toString(onlyCids) {\n const { buffer: str, streams } = this.recursiveToString(\n this.rendered,\n this.rendered[COMPONENTS],\n onlyCids,\n true,\n {}\n );\n return { buffer: str, streams };\n }\n recursiveToString(rendered, components = rendered[COMPONENTS], onlyCids, changeTracking, rootAttrs) {\n onlyCids = onlyCids ? new Set(onlyCids) : null;\n const output = {\n buffer: "",\n components,\n onlyCids,\n streams: /* @__PURE__ */ new Set()\n };\n this.toOutputBuffer(rendered, null, output, changeTracking, rootAttrs);\n return { buffer: output.buffer, streams: output.streams };\n }\n componentCIDs(diff) {\n return Object.keys(diff[COMPONENTS] || {}).map((i) => parseInt(i));\n }\n isComponentOnlyDiff(diff) {\n if (!diff[COMPONENTS]) {\n return false;\n }\n return Object.keys(diff).length === 1;\n }\n getComponent(diff, cid) {\n return diff[COMPONENTS][cid];\n }\n resetRender(cid) {\n if (this.rendered[COMPONENTS][cid]) {\n this.rendered[COMPONENTS][cid].reset = true;\n }\n }\n mergeDiff(diff) {\n const newc = diff[COMPONENTS];\n const cache = {};\n delete diff[COMPONENTS];\n this.rendered = this.mutableMerge(this.rendered, diff);\n this.rendered[COMPONENTS] = this.rendered[COMPONENTS] || {};\n if (newc) {\n const oldc = this.rendered[COMPONENTS];\n for (const cid in newc) {\n newc[cid] = this.cachedFindComponent(cid, newc[cid], oldc, newc, cache);\n }\n for (const cid in newc) {\n oldc[cid] = newc[cid];\n }\n diff[COMPONENTS] = newc;\n }\n }\n cachedFindComponent(cid, cdiff, oldc, newc, cache) {\n if (cache[cid]) {\n return cache[cid];\n } else {\n let ndiff, stat, scid = cdiff[STATIC];\n if (isCid(scid)) {\n let tdiff;\n if (scid > 0) {\n tdiff = this.cachedFindComponent(scid, newc[scid], oldc, newc, cache);\n } else {\n tdiff = oldc[-scid];\n }\n stat = tdiff[STATIC];\n ndiff = this.cloneMerge(tdiff, cdiff, true);\n ndiff[STATIC] = stat;\n } else {\n ndiff = cdiff[STATIC] !== void 0 || oldc[cid] === void 0 ? cdiff : this.cloneMerge(oldc[cid], cdiff, false);\n }\n cache[cid] = ndiff;\n return ndiff;\n }\n }\n mutableMerge(target, source) {\n if (source[STATIC] !== void 0) {\n return source;\n } else {\n this.doMutableMerge(target, source);\n return target;\n }\n }\n doMutableMerge(target, source) {\n if (source[KEYED]) {\n this.mergeKe
1yed(target, source);\n } else {\n for (const key in source) {\n const val = source[key];\n const targetVal = target[key];\n const isObjVal = isObject(val);\n if (isObjVal && val[STATIC] === void 0 && isObject(targetVal)) {\n this.doMutableMerge(targetVal, val);\n } else {\n target[key] = val;\n }\n }\n }\n if (target[ROOT]) {\n target.newRender = true;\n }\n }\n clone(diff) {\n if ("structuredClone" in window) {\n return structuredClone(diff);\n } else {\n return JSON.parse(JSON.stringify(diff));\n }\n }\n // keyed comprehensions\n mergeKeyed(target, source) {\n const clonedTarget = this.clone(target);\n Object.entries(source[KEYED]).forEach(([i, entry]) => {\n if (i === KEYED_COUNT) {\n return;\n }\n if (Array.isArray(entry)) {\n const [old_idx, diff] = entry;\n target[KEYED][i] = clonedTarget[KEYED][old_idx];\n this.doMutableMerge(target[KEYED][i], diff);\n } else if (typeof entry === "number") {\n const old_idx = entry;\n target[KEYED][i] = clonedTarget[KEYED][old_idx];\n } else if (typeof entry === "object") {\n if (!target[KEYED][i]) {\n target[KEYED][i] = {};\n }\n this.doMutableMerge(target[KEYED][i], entry);\n }\n });\n if (source[KEYED][KEYED_COUNT] < target[KEYED][KEYED_COUNT]) {\n for (let i = source[KEYED][KEYED_COUNT]; i < target[KEYED][KEYED_COUNT]; i++) {\n delete target[KEYED][i];\n }\n }\n target[KEYED][KEYED_COUNT] = source[KEYED][KEYED_COUNT];\n if (source[STREAM]) {\n target[STREAM] = source[STREAM];\n }\n if (source[TEMPLATES]) {\n target[TEMPLATES] = source[TEMPLATES];\n }\n }\n // Merges cid trees together, copying statics from source tree.\n //\n // The `pruneMagicId` is passed to control pruning the magicId of the\n // target. We must always prune the magicId when we are sharing statics\n // from another component. If not pruning, we replicate the logic from\n // mutableMerge, where we set newRender to true if there is a root\n // (effectively forcing the new version to be rendered instead of skipped)\n //\n cloneMerge(target, source, pruneMagicId) {\n let merged;\n if (source[KEYED]) {\n merged = this.clone(target);\n this.mergeKeyed(merged, source);\n } else {\n merged = { ...target, ...source };\n for (const key in merged) {\n const val = source[key];\n const targetVal = target[key];\n if (isObject(val) && val[STATIC] === void 0 && isObject(targetVal)) {\n merged[key] = this.cloneMerge(targetVal, val, pruneMagicId);\n } else if (val === void 0 && isObject(targetVal)) {\n merged[key] = this.cloneMerge(targetVal, {}, pruneMagicId);\n }\n }\n }\n if (pruneMagicId) {\n delete merged.magicId;\n delete merged.newRender;\n } else if (target[ROOT]) {\n merged.newRender = true;\n }\n return merged;\n }\n componentToString(cid) {\n const { buffer: str, streams } = this.recursiveCIDToString(\n this.rendered[COMPONENTS],\n cid,\n null\n );\n const [strippedHTML, _before, _after] = modifyRoot(str, {});\n return { buffer: strippedHTML, streams };\n }\n pruneCIDs(cids) {\n cids.forEach((cid) => delete this.rendered[COMPONENTS][cid]);\n }\n // private\n get() {\n return this.rendered;\n }\n isNewFingerprint(diff = {}) {\n return !!diff[STATIC];\n }\n templateStatic(part, templates) {\n if (typeof part === "number") {\n return templates[part];\n } else {\n return part;\n }\n }\n nextMagicID() {\n this.magicId++;\n return `m${this.magicId}-${this.parentViewId()}`;\n }\n // Converts rendered tree to output buffer.\n //\n // changeTracking controls if we can apply the PHX_SKIP optimization.\n toOutputBuffer(rendered, templates, output, changeTracking, rootAttrs = {}) {\n if (rendered[KEYED]) {\n return this.comprehensionToBuffer(\n rendered,\n templates,\n output,\n changeTracking\n );\n }\n if (rendered[TEMPLATES]) {\n templates = rendered[TEMPLATES];\n delete rendered[TEMPLATES];\n }\n let { [STATIC]: statics } = rendered;\n statics = this.templateStatic(statics, templates);\n rendered[STATIC] = statics;\n const isRoot = rendered[ROOT];\n const prevBuffer = output.buffer;\n if (isRoot) {\n output.buffer = "";\n }\n if (changeTracking && isRoot && !rendered.magicId) {\n rendered.newRender = true;\n rendered.magicId = this.nextMagicID();\n }\n output.buffer += statics[0];\n for (let i = 1; i < statics.length;
1 i++) {\n this.dynamicToBuffer(rendered[i - 1], templates, output, changeTracking);\n output.buffer += statics[i];\n }\n if (isRoot) {\n let skip = false;\n let attrs;\n if (changeTracking || rendered.magicId) {\n skip = changeTracking && !rendered.newRender;\n attrs = { [PHX_MAGIC_ID]: rendered.magicId, ...rootAttrs };\n } else {\n attrs = rootAttrs;\n }\n if (skip) {\n attrs[PHX_SKIP] = true;\n }\n const [newRoot, commentBefore, commentAfter] = modifyRoot(\n output.buffer,\n attrs,\n skip\n );\n rendered.newRender = false;\n output.buffer = prevBuffer + commentBefore + newRoot + commentAfter;\n }\n }\n comprehensionToBuffer(rendered, templates, output, changeTracking) {\n const keyedTemplates = templates || rendered[TEMPLATES];\n const statics = this.templateStatic(rendered[STATIC], templates);\n rendered[STATIC] = statics;\n delete rendered[TEMPLATES];\n for (let i = 0; i < rendered[KEYED][KEYED_COUNT]; i++) {\n output.buffer += statics[0];\n for (let j = 1; j < statics.length; j++) {\n this.dynamicToBuffer(\n rendered[KEYED][i][j - 1],\n keyedTemplates,\n output,\n changeTracking\n );\n output.buffer += statics[j];\n }\n }\n if (rendered[STREAM]) {\n const stream = rendered[STREAM];\n const [_ref, _inserts, deleteIds, reset] = stream || [null, {}, [], null];\n if (stream !== void 0 && (rendered[KEYED][KEYED_COUNT] > 0 || deleteIds.length > 0 || reset)) {\n delete rendered[STREAM];\n rendered[KEYED] = {\n [KEYED_COUNT]: 0\n };\n output.streams.add(stream);\n }\n }\n }\n dynamicToBuffer(rendered, templates, output, changeTracking) {\n if (typeof rendered === "number") {\n const { buffer: str, streams } = this.recursiveCIDToString(\n output.components,\n rendered,\n output.onlyCids\n );\n output.buffer += str;\n output.streams = /* @__PURE__ */ new Set([...output.streams, ...streams]);\n } else if (isObject(rendered)) {\n this.toOutputBuffer(rendered, templates, output, changeTracking, {});\n } else {\n output.buffer += rendered;\n }\n }\n recursiveCIDToString(components, cid, onlyCids) {\n const component = components[cid] || logError(`no component for CID ${cid}`, components);\n const attrs = { [PHX_COMPONENT]: cid, [PHX_VIEW_REF]: this.viewId };\n const skip = onlyCids && !onlyCids.has(cid);\n component.newRender = !skip;\n component.magicId = `c${cid}-${this.parentViewId()}`;\n const changeTracking = !component.reset;\n const { buffer: html, streams } = this.recursiveToString(\n component,\n components,\n onlyCids,\n changeTracking,\n attrs\n );\n delete component.reset;\n return { buffer: html, streams };\n }\n};\n\n// js/phoenix_live_view/js.js\nvar focusStack = [];\nvar default_transition_time = 200;\nvar JS = {\n // private\n exec(e, eventType, phxEvent, view, sourceEl, defaults) {\n const [defaultKind, defaultArgs] = defaults || [\n null,\n { callback: defaults && defaults.callback }\n ];\n const commands = Array.isArray(phxEvent) ? phxEvent : typeof phxEvent === "string" && phxEvent.startsWith("[") ? JSON.parse(phxEvent) : [[defaultKind, defaultArgs]];\n commands.forEach(([kind, args]) => {\n if (kind === defaultKind) {\n args = { ...defaultArgs, ...args };\n args.callback = args.callback || defaultArgs.callback;\n }\n this.filterToEls(view.liveSocket, sourceEl, args).forEach((el) => {\n this[`exec_${kind}`](e, eventType, phxEvent, view, sourceEl, el, args);\n });\n });\n },\n isVisible(el) {\n return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length > 0);\n },\n // returns true if any part of the element is inside the viewport\n isInViewport(el) {\n const rect = el.getBoundingClientRect();\n const windowHeight = window.innerHeight || document.documentElement.clientHeight;\n const windowWidth = window.innerWidth || document.documentElement.clientWidth;\n return rect.right > 0 && rect.bottom > 0 && rect.left < windowWidth && rect.top < windowHeight;\n },\n // private\n // commands\n exec_exec(e, eventType, phxEvent, view, sourceEl, el, { attr, to }) {\n const encodedJS = el.getAttribute(attr);\n if (!encodedJS) {\n throw new Error(`expected ${attr} to contain JS command on "${to}"`);\n }\n view.liveSocket.execJS(el, encodedJS, eventType);\n },\n exec_dispatch(e, eventType, phxEvent, view, sourceEl, el, { event, detail, bubbles, blocking }) {\n detail = detail || {};\n detail.dispatcher = sourceEl;\n if (blocking) {\n const promise = new Promise((resolve, _reject) => {\n detail.done = resolve;\n });\n view.liveSocket.asyncTransition(promise);\n }\n dom_default.dispatchEvent(el, event, { detail, bubbles });\n }
1,\n exec_push(e, eventType, phxEvent, view, sourceEl, el, args) {\n const {\n event,\n data,\n target,\n page_loading,\n loading,\n value,\n dispatcher,\n callback\n } = args;\n const pushOpts = {\n loading,\n value,\n target,\n page_loading: !!page_loading,\n originalEvent: e\n };\n const targetSrc = eventType === "change" && dispatcher ? dispatcher : sourceEl;\n const phxTarget = target || targetSrc.getAttribute(view.binding("target")) || targetSrc;\n const handler = (targetView, targetCtx) => {\n if (!targetView.isConnected()) {\n return;\n }\n if (eventType === "change") {\n let { newCid, _target } = args;\n _target = _target || (dom_default.isFormAssociated(sourceEl) ? sourceEl.name : void 0);\n if (_target) {\n pushOpts._target = _target;\n }\n targetView.pushInput(\n sourceEl,\n targetCtx,\n newCid,\n event || phxEvent,\n pushOpts,\n callback\n );\n } else if (eventType === "submit") {\n const { submitter } = args;\n targetView.submitForm(\n sourceEl,\n targetCtx,\n event || phxEvent,\n submitter,\n pushOpts,\n callback\n );\n } else {\n targetView.pushEvent(\n eventType,\n sourceEl,\n targetCtx,\n event || phxEvent,\n data,\n pushOpts,\n callback\n );\n }\n };\n if (args.targetView && args.targetCtx) {\n handler(args.targetView, args.targetCtx);\n } else {\n view.withinTargets(phxTarget, handler);\n }\n },\n exec_navigate(e, eventType, phxEvent, view, sourceEl, el, { href, replace }) {\n view.liveSocket.historyRedirect(\n e,\n href,\n replace ? "replace" : "push",\n null,\n sourceEl\n );\n },\n exec_patch(e, eventType, phxEvent, view, sourceEl, el, { href, replace }) {\n view.liveSocket.pushHistoryPatch(\n e,\n href,\n replace ? "replace" : "push",\n sourceEl\n );\n },\n exec_focus(e, eventType, phxEvent, view, sourceEl, el) {\n aria_default.attemptFocus(el);\n window.requestAnimationFrame(() => {\n window.requestAnimationFrame(() => aria_default.attemptFocus(el));\n });\n },\n exec_focus_first(e, eventType, phxEvent, view, sourceEl, el) {\n aria_default.focusFirstInteractive(el) || aria_default.focusFirst(el);\n window.requestAnimationFrame(() => {\n window.requestAnimationFrame(\n () => aria_default.focusFirstInteractive(el) || aria_default.focusFirst(el)\n );\n });\n },\n exec_push_focus(e, eventType, phxEvent, view, sourceEl, el) {\n focusStack.push(el || sourceEl);\n },\n exec_pop_focus(_e, _eventType, _phxEvent, _view, _sourceEl, _el) {\n const el = focusStack.pop();\n if (el) {\n el.focus();\n window.requestAnimationFrame(() => {\n window.requestAnimationFrame(() => el.focus());\n });\n }\n },\n exec_add_class(e, eventType, phxEvent, view, sourceEl, el, { names, transition, time, blocking }) {\n this.addOrRemoveClasses(el, names, [], transition, time, view, blocking);\n },\n exec_remove_class(e, eventType, phxEvent, view, sourceEl, el, { names, transition, time, blocking }) {\n this.addOrRemoveClasses(el, [], names, transition, time, view, blocking);\n },\n exec_toggle_class(e, eventType, phxEvent, view, sourceEl, el, { names, transition, time, blocking }) {\n this.toggleClasses(el, names, transition, time, view, blocking);\n },\n exec_toggle_attr(e, eventType, phxEvent, view, sourceEl, el, { attr: [attr, val1, val2] }) {\n this.toggleAttr(el, attr, val1, val2);\n },\n exec_ignore_attrs(e, eventType, phxEvent, view, sourceEl, el, { attrs }) {\n this.ignoreAttrs(el, attrs);\n },\n exec_transition(e, eventType, phxEvent, view, sourceEl, el, { time, transition, blocking }) {\n this.addOrRemoveClasses(el, [], [], transition, time, view, blocking);\n },\n exec_toggle(e, eventType, phxEvent, view, sourceEl, el, { display, ins, outs, time, blocking }) {\n this.toggle(eventType, view, el, display, ins, outs, time, blocking);\n },\n exec_show(e, eventType, phxEvent, view, sourceEl, el, { display, transition, time, blocking }) {\n this.show(eventType, view, el, display, transition, time, blocking);\n },\n exec_hide(e, eventType, phxEvent, view, sourceEl, el, { display, transition, time, blocking }) {\n this.hide(eventType, view, el, display, transition, time, blocking);\n },\n exec_set_attr(e, eventType, phxEvent, view, sourceEl, el, { attr: [attr, val] }) {\n this.setOrRemoveAttrs(el, [[attr, val]], []);\n },\n exec_remove_attr(e, eventType, phxEvent, view, sourceEl, el, { attr }) {\n this.setOrRemoveAttrs(el, [], [attr]);\n },\n ignoreAttrs(el, attrs) {\n dom_default.putPrivate(el, "JS:ignore_attrs", {\n apply: (fromEl, toEl) => {\n let fromAttributes = Array.from(fromEl.attributes);\n let fromAttributeNames = fromAttributes.map((attr) => attr.name);\n Array.from(toEl.attributes).filter((attr) => {\n return !fromAttributeNames.includes(attr.name);\n }
1).forEach((attr) => {\n if (dom_default.attributeIgnored(attr, attrs)) {\n toEl.removeAttribute(attr.name);\n }\n });\n fromAttributes.forEach((attr) => {\n if (dom_default.attributeIgnored(attr, attrs)) {\n toEl.setAttribute(attr.name, attr.value);\n }\n });\n }\n });\n },\n onBeforeElUpdated(fromEl, toEl) {\n const ignoreAttrs = dom_default.private(fromEl, "JS:ignore_attrs");\n if (ignoreAttrs) {\n ignoreAttrs.apply(fromEl, toEl);\n }\n },\n // utils for commands\n show(eventType, view, el, display, transition, time, blocking) {\n if (!this.isVisible(el)) {\n this.toggle(\n eventType,\n view,\n el,\n display,\n transition,\n null,\n time,\n blocking\n );\n }\n },\n hide(eventType, view, el, display, transition, time, blocking) {\n if (this.isVisible(el)) {\n this.toggle(\n eventType,\n view,\n el,\n display,\n null,\n transition,\n time,\n blocking\n );\n }\n },\n toggle(eventType, view, el, display, ins, outs, time, blocking) {\n time = time || default_transition_time;\n const [inClasses, inStartClasses, inEndClasses] = ins || [[], [], []];\n const [outClasses, outStartClasses, outEndClasses] = outs || [[], [], []];\n if (inClasses.length > 0 || outClasses.length >
1 0) {\n if (this.isVisible(el)) {\n const onStart = () => {\n this.addOrRemoveClasses(\n el,\n outStartClasses,\n inClasses.concat(inStartClasses).concat(inEndClasses)\n );\n window.requestAnimationFrame(() => {\n this.addOrRemoveClasses(el, outClasses, []);\n window.requestAnimationFrame(\n () => this.addOrRemoveClasses(el, outEndClasses, outStartClasses)\n );\n });\n };\n const onEnd = () => {\n this.addOrRemoveClasses(el, [], outClasses.concat(outEndClasses));\n dom_default.putSticky(\n el,\n "toggle",\n (currentEl) => currentEl.style.display = "none"\n );\n el.dispatchEvent(new Event("phx:hide-end"));\n };\n el.dispatchEvent(new Event("phx:hide-start"));\n if (blocking === false) {\n onStart();\n setTimeout(onEnd, time);\n } else {\n view.transition(time, onStart, onEnd);\n }\n } else {\n if (eventType === "remove") {\n return;\n }\n const onStart = () => {\n this.addOrRemoveClasses(\n el,\n inStartClasses,\n outClasses.concat(outStartClasses).concat(outEndClasses)\n );\n const stickyDisplay = display || this.defaultDisplay(el);\n window.requestAnimationFrame(() => {\n this.addOrRemoveClasses(el, inClasses, []);\n window.requestAnimationFrame(() => {\n dom_default.putSticky(\n el,\n "toggle",\n (currentEl) => currentEl.style.display = stickyDisplay\n );\n this.addOrRemoveClasses(el, inEndClasses, inStartClasses);\n });\n });\n };\n const onEnd = () => {\n this.addOrRemoveClasses(el, [], inClasses.concat(inEndClasses));\n el.dispatchEvent(new Event("phx:show-end"));\n };\n el.dispatchEvent(new Event("phx:show-start"));\n if (blocking === false) {\n onStart();\n setTimeout(onEnd, time);\n } else {\n view.transition(time, onStart, onEnd);\n }\n }\n }
1 else {\n if (this.isVisible(el)) {\n window.requestAnimationFrame(() => {\n el.dispatchEvent(new Event("phx:hide-start"));\n dom_default.putSticky(\n el,\n "toggle",\n (currentEl) => currentEl.style.display = "none"\n );\n el.dispatchEvent(new Event("phx:hide-end"));\n });\n } else {\n window.requestAnimationFrame(() => {\n el.dispatchEvent(new Event("phx:show-start"));\n const stickyDisplay = display || this.defaultDisplay(el);\n dom_default.putSticky(\n el,\n "toggle",\n (currentEl) => currentEl.style.display = stickyDisplay\n );\n el.dispatchEvent(new Event("phx:show-end"));\n });\n }\n }\n },\n toggleClasses(el, classes, transition, time, view, blocking) {\n window.requestAnimationFrame(() => {\n const [prevAdds, prevRemoves] = dom_default.getSticky(el, "classes", [[], []]);\n const newAdds = classes.filter(\n (name) => prevAdds.indexOf(name) < 0 && !el.classList.contains(name)\n );\n const newRemoves = classes.filter(\n (name) => prevRemoves.indexOf(name) < 0 && el.classList.contains(name)\n );\n this.addOrRemoveClasses(\n el,\n newAdds,\n newRemoves,\n transition,\n time,\n view,\n blocking\n );\n });\n },\n toggleAttr(el, attr, val1, val2) {\n if (el.hasAttribute(attr)) {\n if (val2 !== void 0) {\n if (el.getAttribute(attr) === val1) {\n this.setOrRemoveAttrs(el, [[attr, val2]], []);\n } else {\n this.setOrRemoveAttrs(el, [[attr, val1]], []);\n }\n } else {\n this.setOrRemoveAttrs(el, [], [attr]);\n }\n } else {\n this.setOrRemoveAttrs(el, [[attr, val1]], []);\n }\n },\n addOrRemoveClasses(el, adds, removes, transition, time, view, blocking) {\n time = time || default_transition_time;\n const [transitionRun, transitionStart, transitionEnd] = transition || [\n [],\n [],\n []\n ];\n if (transitionRun.length > 0) {\n const onStart = () => {\n this.addOrRemoveClasses(\n el,\n transitionStart,\n [].concat(transitionRun).concat(transitionEnd)\n );\n window.requestAnimationFrame(() => {\n this.addOrRemoveClasses(el, transitionRun, []);\n window.requestAnimationFrame(\n () => this.addOrRemoveClasses(el, transitionEnd, transitionStart)\n );\n });\n };\n const onDone = () => this.addOrRemoveClasses(\n el,\n adds.concat(transitionEnd),\n removes.concat(transitionRun).concat(transitionStart)\n );\n if (blocking === false) {\n onStart();\n setTimeout(onDone, time);\n } else {\n view.transition(time, onStart, onDone);\n }\n return;\n }\n window.requestAnimationFrame(() => {\n const [prevAdds, prevRemoves] = dom_default.getSticky(el, "classes", [[], []]);\n const keepAdds = adds.filter(\n (name) => prevAdds.indexOf(name) < 0 && !el.classList.contains(name)\n );\n const keepRemoves = removes.filter(\n (name) => prevRemoves.indexOf(name) < 0 && el.classList.contains(name)\n );\n const newAdds = prevAdds.filter((name) => removes.indexOf(name) < 0).concat(keepAdds);\n const newRemoves = prevRemoves.filter((name) => adds.indexOf(name) < 0).concat(keepRemoves);\n dom_default.putSticky(el, "classes", (currentEl) => {\n currentEl.classList.remove(...newRemoves);\n currentEl.classList.add(...newAdds);\n return [newAdds, newRemoves];\n });\n });\n },\n setOrRemoveAttrs(el, sets, removes) {\n const [prevSets, prevRemoves] = dom_default.getSticky(el, "attrs", [[], []]);\n const alteredAttrs = sets.map(([attr, _val]) => attr).concat(removes);\n const newSets = prevSets.filter(([attr, _val]) => !alteredAttrs.includes(attr)).concat(sets);\n const newRemoves = prevRemoves.filter((attr) => !alteredAttrs.includes(attr)).concat(removes);\n if (sets.some(([attr, _val]) => attr === "id")) {\n dom_default.putPrivate(el, "clientsideIdAttribute", true);\n }\n dom_default.putSticky(el, "attrs", (currentEl) =>
1 {\n newRemoves.forEach((attr) => currentEl.removeAttribute(attr));\n newSets.forEach(([attr, val]) => currentEl.setAttribute(attr, val));\n return [newSets, newRemoves];\n });\n },\n hasAllClasses(el, classes) {\n return classes.every((name) => el.classList.contains(name));\n },\n isToggledOut(el, outClasses) {\n return !this.isVisible(el) || this.hasAllClasses(el, outClasses);\n },\n filterToEls(liveSocket, sourceEl, { to }) {\n const defaultQuery = () => {\n if (typeof to === "string") {\n return document.querySelectorAll(to);\n } else if (to.closest) {\n const toEl = sourceEl.closest(to.closest);\n return toEl ? [toEl] : [];\n } else if (to.inner) {\n return sourceEl.querySelectorAll(to.inner);\n }\n };\n return to ? liveSocket.jsQuerySelectorAll(sourceEl, to, defaultQuery) : [sourceEl];\n },\n defaultDisplay(el) {\n return { tr: "table-row", td: "table-cell" }[el.tagName.toLowerCase()] || "block";\n },\n transitionClasses(val) {\n if (!val) {\n return null;\n }\n let [trans, tStart, tEnd] = Array.isArray(val) ? val : [val.split(" "), [], []];\n trans = Array.isArray(trans) ? trans : trans.split(" ");\n tStart = Array.isArray(tStart) ? tStart : tStart.split(" ");\n tEnd = Array.isArray(tEnd) ? tEnd : tEnd.split(" ");\n return [trans, tStart, tEnd];\n }\n};\nvar js_default = JS;\n\n// js/phoenix_live_view/js_commands.ts\nvar js_commands_default = (liveSocket, eventType) => {\n return {\n exec(el, encodedJS) {\n liveSocket.execJS(el, encodedJS, eventType);\n },\n show(el, opts = {}) {\n const owner = liveSocket.owner(el);\n js_default.show(\n eventType,\n owner,\n el,\n opts.display,\n js_default.transitionClasses(opts.transition),\n opts.time,\n opts.blocking\n );\n },\n hide(el, opts = {}) {\n const owner = liveSocket.owner(el);\n js_default.hide(\n eventType,\n owner,\n el,\n null,\n js_default.transitionClasses(opts.transition),\n opts.time,\n opts.blocking\n );\n },\n toggle(el, opts = {}) {\n const owner = liveSocket.owner(el);\n const inTransition = js_default.transitionClasses(opts.in);\n const outTransition = js_default.transitionClasses(opts.out);\n js_default.toggle(\n eventType,\n owner,\n el,\n opts.display,\n inTransition,\n outTransition,\n opts.time,\n opts.blocking\n );\n },\n addClass(el, names, opts = {}) {\n const classNames = Array.isArray(names) ? names : names.split(" ");\n const owner = liveSocket.owner(el);\n js_default.addOrRemoveClasses(\n el,\n classNames,\n [],\n js_default.transitionClasses(opts.transition),\n opts.time,\n owner,\n opts.blocking\n );\n },\n removeClass(el, names, opts = {}) {\n const classNames = Array.isArray(names) ? names : names.split(" ");\n const owner = liveSocket.owner(el);\n js_default.addOrRemoveClasses(\n el,\n [],\n classNames,\n js_default.transitionClasses(opts.transition),\n opts.time,\n owner,\n opts.blocking\n );\n },\n toggleClass(el, names, opts = {}) {\n const classNames = Array.isArray(names) ? names : names.split(" ");\n const owner = liveSocket.owner(el);\n js_default.toggleClasses(\n el,\n classNames,\n js_default.transitionClasses(opts.transition),\n opts.time,\n owner,\n opts.blocking\n );\n },\n transition(el, transition, opts = {}) {\n const owner = liveSocket.owner(el);\n js_default.addOrRemoveClasses(\n el,\n [],\n [],\n js_default.transitionClasses(transition),\n opts.time,\n owner,\n opts.blocking\n );\n },\n setAttribute(el, attr, val) {\n js_default.setOrRemoveAttrs(el, [[attr, val]], []);\n },\n removeAttribute(el, attr) {\n js_default.setOrRemoveAttrs(el, [], [attr]);\n },\n toggleAttribute(el, attr, val1, val2) {\n js_default.toggleAttr(el, attr, val1, val2);\n },\n push(el, type, opts = {}) {\n liveSocket.withinOwners(el, (view) => {\n const data = opts.value || {};\n delete opts.value;\n let e = new CustomEvent("phx:exec", { detail: { sourceElement: el } });\n js_default.exec(e, eventType, type, view, el, ["push", { data, ...opts }]);\n });\n },\n navigate(href, opts = {}
1) {\n ensureSameOrigin(href, "navigate");\n const customEvent = new CustomEvent("phx:exec");\n liveSocket.historyRedirect(\n customEvent,\n href,\n opts.replace ? "replace" : "push",\n null,\n null\n );\n },\n patch(href, opts = {}) {\n ensureSameOrigin(href, "patch");\n const customEvent = new CustomEvent("phx:exec");\n liveSocket.pushHistoryPatch(\n customEvent,\n href,\n opts.replace ? "replace" : "push",\n null\n );\n },\n ignoreAttributes(el, attrs) {\n js_default.ignoreAttrs(el, Array.isArray(attrs) ? attrs : [attrs]);\n }\n };\n};\n\n// js/phoenix_live_view/view_hook.ts\nvar HOOK_ID = "hookId";\nvar DEAD_HOOK = "deadHook";\nvar viewHookID = 1;\nvar ViewHook = class _ViewHook {\n get liveSocket() {\n return this.__liveSocket();\n }\n /** @internal */\n static makeID() {\n return viewHookID++;\n }\n /** @internal */\n static elementID(el) {\n return dom_default.private(el, HOOK_ID);\n }\n /** @internal */\n static deadHook(el) {\n return dom_default.private(el, DEAD_HOOK) === true;\n }\n /** @internal */\n constructor(view, el, callbacks) {\n this.el = el;\n this.__attachView(view);\n this.__listeners = /* @__PURE__ */ new Set();\n this.__isDisconnected = false;\n dom_default.putPrivate(this.el, HOOK_ID, _ViewHook.makeID());\n if (view && view.isDead) {\n dom_default.putPrivate(this.el, DEAD_HOOK, true);\n }\n if (callbacks) {\n const protectedProps = /* @__PURE__ */ new Set([\n "el",\n "liveSocket",\n "__view",\n "__listeners",\n "__isDisconnected",\n "constructor",\n // Standard object properties\n // Core ViewHook API methods\n "js",\n "pushEvent",\n "pushEventTo",\n "handleEvent",\n "removeHandleEvent",\n "upload",\n "uploadTo",\n // Internal lifecycle callers\n "__mounted",\n "__updated",\n "__beforeUpdate",\n "__destroyed",\n "__reconnected",\n "__disconnected",\n "__cleanup__"\n ]);\n for (const key in callbacks) {\n if (Object.prototype.hasOwnProperty.call(callbacks, key)) {\n this[key] = callbacks[key];\n if (protectedProps.has(key)) {\n console.warn(\n `Hook object for element #${el.id} overwrites core property \'${key}\'!`\n );\n }\n }\n }\n const lifecycleMethods = [\n "mounted",\n "beforeUpdate",\n "updated",\n "destroyed",\n "disconnected",\n "reconnected"\n ];\n lifecycleMethods.forEach((methodName) => {\n if (callbacks[methodName] && typeof callbacks[methodName] === "function") {\n this[methodName] = callbacks[methodName];\n }\n });\n }\n }\n /** @internal */\n __attachView(view) {\n if (view) {\n this.__view = () => view;\n this.__liveSocket = () => view.liveSocket;\n } else {\n this.__view = () => {\n throw new Error(\n `hook not yet attached to a live view: ${this.el.outerHTML}`\n );\n };\n this.__liveSocket = () => {\n throw new Error(\n `hook not yet attached to a live view: ${this.el.outerHTML}`\n );\n };\n }\n }\n // Default lifecycle methods\n mounted() {\n }\n beforeUpdate() {\n }\n updated() {\n }\n destroyed() {\n }\n disconnected() {\n }\n reconnected() {\n }\n // Internal lifecycle callers - called by the View\n /** @internal */\n __mounted() {\n this.mounted();\n }\n /** @internal */\n __updated() {\n this.updated();\n }\n /** @internal */\n __beforeUpdate() {\n this.beforeUpdate();\n }\n /** @internal */\n __destroyed() {\n this.destroyed();\n dom_default.deletePrivate(this.el, HOOK_ID);\n }\n /** @internal */\n __reconnected() {\n if (this.__isDisconnected) {\n this.__isDisconnected = false;\n this.reconnected();\n }\n }\n /** @internal */\n __disconnected() {\n this.__isDisconnected = true;\n this.disconnected();\n }\n js() {\n return {\n ...js_commands_default(this.__view().liveSocket, "hook"),\n exec: (encodedJS) => {\n this.__view().liveSocket.execJS(this.el, encodedJS, "hook");\n }\n };\n }\n pushEvent(event, payload, onReply) {\n const promise = this.__view().pushHookEvent(\n this.el,\n null,\n event,\n payload || {}\n );\n if (onReply === void 0) {\n return promise.then(({ reply }) => reply);\n }\n promise.then(\n ({ reply, ref }) => onReply(reply, ref)\n ).catch(() =>
1 {\n });\n }\n pushEventTo(selectorOrTarget, event, payload, onReply) {\n if (onReply === void 0) {\n const targetPair = [];\n this.__view().withinTargets(\n selectorOrTarget,\n (view, targetCtx) => {\n targetPair.push({ view, targetCtx });\n }\n );\n const promises = targetPair.map(({ view, targetCtx }) => {\n return view.pushHookEvent(\n this.el,\n targetCtx,\n event,\n payload || {}\n );\n });\n return Promise.allSettled(promises);\n }\n this.__view().withinTargets(\n selectorOrTarget,\n (view, targetCtx) => {\n view.pushHookEvent(this.el, targetCtx, event, payload || {}).then(\n ({ reply, ref }) => onReply(reply, ref)\n ).catch(() => {\n });\n }\n );\n }\n handleEvent(event, callback) {\n const callbackRef = {\n event,\n callback: (customEvent) => callback(customEvent.detail)\n };\n window.addEventListener(\n `phx:${event}`,\n callbackRef.callback\n );\n this.__listeners.add(callbackRef);\n return callbackRef;\n }\n removeHandleEvent(ref) {\n window.removeEventListener(\n `phx:${ref.event}`,\n ref.callback\n );\n this.__listeners.delete(ref);\n }\n upload(name, files) {\n return this.__view().dispatchUploads(null, name, files);\n }\n uploadTo(selectorOrTarget, name, files) {\n return this.__view().withinTargets(\n selectorOrTarget,\n (view, targetCtx) => {\n view.dispatchUploads(targetCtx, name, files);\n }\n );\n }\n /** @internal */\n __cleanup__() {\n this.__listeners.forEach(\n (callbackRef) => this.removeHandleEvent(callbackRef)\n );\n }\n};\n\n// js/phoenix_live_view/view.ts\nvar prependFormDataKey = (key, prefix) => {\n const isArray = key.endsWith("[]");\n let baseKey = isArray ? key.slice(0, -2) : key;\n baseKey = baseKey.replace(/([^\\[\\]]+)(\\]?$)/, `${prefix}$1$2`);\n if (isArray) {\n baseKey += "[]";\n }\n return baseKey;\n};\nvar View = class _View {\n static closestView(el) {\n const liveViewEl = el.closest(PHX_VIEW_SELECTOR);\n return liveViewEl ? dom_default.private(liveViewEl, "view") : null;\n }\n constructor(el, liveSocket, parentView, flash = null, liveReferer = null) {\n this.rendered = null;\n this.isDead = false;\n this.liveSocket = liveSocket;\n this.flash = flash;\n this.parent = parentView;\n this.root = parentView ? parentView.root : this;\n this.el = el;\n const boundView = dom_default.private(this.el, "view");\n if (boundView !== void 0 && boundView.isDead !== true) {\n logError(\n `The DOM element for this view has already been bound to a view.\n\n An element can only ever be associated with a single view!\n Please ensure that you are not trying to initialize multiple LiveSockets on the same page.\n This could happen if you\'re accidentally trying to render your root layout more than once.\n Ensure that the template set on the LiveView is different than the root layout.\n `,\n { view: boundView }\n );\n throw new Error("Cannot bind multiple views to the same DOM element.");\n }\n dom_default.putPrivate(this.el, "view", this);\n this.id = this.el.id;\n this.el.setAttribute(PHX_ROOT_ID, this.root.id);\n this.ref = 0;\n this.lastAckRef = null;\n this.childJoins = 0;\n this.loaderTimer = null;\n this.disconnectedTimer = null;\n this.pendingDiffs = [];\n this.pendingForms = /* @__PURE__ */ new Set();\n this.redirect = false;\n this.href = null;\n this.joinCount = this.parent ? this.parent.joinCount - 1 : 0;\n this.joinAttempts = 0;\n this.joinPending = true;\n this.destroyed = false;\n this.joinCallback = function(onDone) {\n onDone && onDone();\n };\n this.stopCallback = function() {\n };\n this.pendingJoinOps = [];\n this.viewHooks = {};\n this.formSubmits = [];\n this.children = this.parent ? null : {};\n this.root.children[this.id] = {};\n this.formsForRecovery = {};\n this.channel = this.liveSocket.channel(`lv:${this.id}`, () => {\n const url = this.href && this.expandURL(this.href);\n return {\n redirect: this.redirect ? url : void 0,\n url: this.redirect ? void 0 : url || void 0,\n params: this.connectParam
1s(liveReferer),\n session: this.getSession(),\n static: this.getStatic(),\n flash: this.flash ?? void 0,\n sticky: this.el.hasAttribute(PHX_STICKY)\n };\n });\n this.portalElementIds = /* @__PURE__ */ new Set();\n }\n setHref(href) {\n this.href = href;\n }\n setRedirect(href) {\n this.redirect = true;\n this.href = href;\n }\n isMain() {\n return this.el.hasAttribute(PHX_MAIN);\n }\n connectParams(liveReferer) {\n const params = this.liveSocket.params(this.el);\n const manifest = dom_default.all(document, `[${this.binding(PHX_TRACK_STATIC)}]`).map(\n (node) => "src" in node && node.src || "href" in node && node.href\n ).filter((url) => typeof url === "string");\n if (manifest.length > 0) {\n params["_track_static"] = manifest;\n }\n params["_mounts"] = this.joinCount;\n params["_mount_attempts"] = this.joinAttempts;\n params["_live_referer"] = liveReferer ?? void 0;\n this.joinAttempts++;\n return params;\n }\n isConnected() {\n return this.channel.canPush();\n }\n getSession() {\n return this.el.getAttribute(PHX_SESSION);\n }\n getStatic() {\n const val = this.el.getAttribute(PHX_STATIC);\n return val === "" ? null : val;\n }\n destroy(callback = function() {\n }) {\n this.destroyAllChildren();\n this.destroyPortalElements();\n this.destroyed = true;\n dom_default.deletePrivate(this.el, "view");\n delete this.root.children[this.id];\n if (this.parent) {\n delete this.root.children[this.parent.id][this.id];\n }\n this.loaderTimer != null && clearTimeout(this.loaderTimer);\n const onFinished = () => {\n callback();\n for (const id in this.viewHooks) {\n this.destroyHook(this.viewHooks[id]);\n }\n };\n dom_default.markPhxChildDestroyed(this.el);\n this.log("destroyed", () => ["the child has been removed from the parent"]);\n this.channel.leave().receive("ok", onFinished).receive("error", onFinished).receive("timeout", onFinished);\n }\n setContainerClasses(...classes) {\n this.el.classList.remove(\n PHX_CONNECTED_CLASS,\n PHX_LOADING_CLASS,\n PHX_ERROR_CLASS,\n PHX_CLIENT_ERROR_CLASS,\n PHX_SERVER_ERROR_CLASS\n );\n this.el.classList.add(...classes);\n }\n showLoader(timeout) {\n this.loaderTimer != null && clearTimeout(this.loaderTimer);\n if (timeout) {\n this.loaderTimer = setTimeout(() => this.showLoader(), timeout);\n } else {\n for (const id in this.viewHooks) {\n this.viewHooks[id].__disconnected();\n }\n this.setContainerClasses(PHX_LOADING_CLASS);\n }\n }\n execAll(binding) {\n dom_default.all(\n this.el,\n `[${binding}]`,\n (el) => this.liveSocket.execJS(el, el.getAttribute(binding))\n );\n }\n hideLoader() {\n this.loaderTimer != null && clearTimeout(this.loaderTimer);\n this.disconnectedTimer != null && clearTimeout(this.disconnectedTimer);\n this.setContainerClasses(PHX_CONNECTED_CLASS);\n this.execAll(this.binding("connected"));\n }\n triggerReconnected() {\n for (const id in this.viewHooks) {\n this.viewHooks[id].__reconnected();\n }\n }\n log(kind, msgCallback) {\n this.liveSocket.log(this, kind, msgCallback);\n }\n transition(time, onStart, onDone = function() {\n }) {\n this.liveSocket.transition(time, onStart, onDone);\n }\n // calls the callback with the view and target element for the given phxTarget\n // targets can be:\n // * an element itself, then it is simply passed to liveSocket.owner;\n // * a CID (Component ID), then we first search the component\'s element in the DOM\n // * a selector, then we search the selector in the DOM and call the callback\n // for each element found with the corresponding owner view\n withinTargets(phxTarget, callback, dom = document) {\n if (phxTarget instanceof HTMLElement || phxTarget instanceof SVGElement) {\n return this.liveSocket.owner(\n phxTarget,\n (view) => callback(view, phxTarget)\n );\n }\n if (isCid(phxTarget)) {\n const target = dom_default.findComponent(this.id, phxTarget, dom);\n if (!target) {\n logError(`no component found matching phx-target of ${phxTarget}`);\n } else {\n callback(\n this,\n typeof phxTarget === "number" ? phxTarget : parseInt(phxTarget)\n );\n }\n } else {\n const targets = Array.from(dom.querySelectorAll(phxTarget));\n if (targets.length === 0) {\n logError(\n `nothing found matching the phx-target selector "${phxTarget}"`\n );\n }
1\n targets.forEach(\n (target) => this.liveSocket.owner(target, (view) => callback(view, target))\n );\n }\n }\n applyDiff(type, rawDiff, callback) {\n this.log(type, () => ["", clone(rawDiff)]);\n const { diff, reply, events, title } = Rendered.extract(rawDiff);\n const ev = events.reduce(\n (acc, args) => {\n if (args.length === 3 && args[2] == true) {\n acc.pre.push(args.slice(0, -1));\n } else {\n acc.post.push(args);\n }\n return acc;\n },\n { pre: [], post: [] }\n );\n this.liveSocket.dispatchEvents(ev.pre);\n const update = () => {\n callback({ diff, reply, events: ev.post });\n if (typeof title === "string" || type == "mount" && this.isMain()) {\n window.requestAnimationFrame(() => dom_default.putTitle(title));\n }\n };\n if ("onDocumentPatch" in this.liveSocket.domCallbacks) {\n this.liveSocket.triggerDOM("onDocumentPatch", [update]);\n } else {\n update();\n }\n }\n onJoin(resp) {\n const { rendered, container, liveview_version, pid } = resp;\n if (container) {\n const [tag, attrs] = container;\n this.el = dom_default.replaceRootContainer(this.el, tag, attrs);\n dom_default.putPrivate(this.el, "view", this);\n }\n this.childJoins = 0;\n this.joinPending = true;\n this.flash = null;\n if (this.root === this) {\n this.formsForRecovery = this.getFormsForRecovery();\n }\n if (this.isMain() && window.history.state === null) {\n browser_default.pushState("replace", {\n type: "patch",\n id: this.id,\n position: this.liveSocket.currentHistoryPosition\n });\n }\n if (liveview_version !== this.liveSocket.version()) {\n console.warn(\n `LiveView asset version mismatch. JavaScript version ${this.liveSocket.version()} vs. server ${liveview_version}. To avoid issues, please ensure that your assets use the same version as the server.`\n );\n }\n if (pid) {\n this.el.setAttribute(PHX_LV_PID, pid);\n }\n browser_default.dropLocal(\n this.liveSocket.localStorage,\n window.location.pathname,\n CONSECUTIVE_RELOADS\n );\n this.applyDiff("mount", rendered, ({ diff, events }) => {\n this.rendered = new Rendered(this.id, diff);\n const [html, streams] = this.renderContainer(null, "join");\n this.dropPendingRefs();\n this.joinCount++;\n this.joinAttempts = 0;\n this.maybeRecoverForms(html, () => {\n this.onJoinComplete(resp, html, streams, events);\n });\n });\n }\n dropPendingRefs() {\n dom_default.all(document, `[${PHX_REF_SRC}="${this.refSrc()}"]`, (el) => {\n el.removeAttribute(PHX_REF_LOADING);\n el.removeAttribute(PHX_REF_SRC);\n el.removeAttribute(PHX_REF_LOCK);\n });\n }\n onJoinComplete({ live_patch }, html, streams, events) {\n if (this.joinCount > 1 || this.parent && !this.parent.isJoinPending()) {\n return this.applyJoinPatch(live_patch, html, streams, events);\n }\n const newChildren = dom_default.findPhxChildrenInFragment(html, this.id).filter(\n (toEl) => {\n const fromEl = toEl.id && this.el.querySelector(`[id="${toEl.id}"]`);\n const phxStatic = fromEl && fromEl.getAttribute(PHX_STATIC);\n if (phxStatic) {\n toEl.setAttribute(PHX_STATIC, phxStatic);\n }\n if (fromEl) {\n fromEl.setAttribute(PHX_ROOT_ID, this.root.id);\n }\n return this.joinChild(toEl);\n }\n );\n if (newChildren.length === 0) {\n if (this.parent) {\n this.root.pendingJoinOps.push([\n this,\n () => this.applyJoinPatch(live_patch, html, streams, events)\n ]);\n this.parent.ackJoin(this);\n } else {\n this.onAllChildJoinsComplete();\n this.applyJoinPatch(live_patch, html, streams, events);\n }\n } else {\n this.root.pendingJoinOps.push([\n this,\n () => this.applyJoinPatch(live_patch, html, streams, events)\n ]);\n }\n }\n attachTrueDocEl() {\n const el = dom_default.byId(this.id);\n if (!el) {\n throw new Error("unable to find root element for view");\n }\n this.el = el;\n dom_default.putPrivate(this.el, "view", this);\n this.el.setAttribute(PHX_ROOT_ID, this.root.id);\n }\n // this is invoked for dead and live views, so we must filter by\n // by owner to ensure we aren\'t duplicating hooks across disconnect\n // and connected states. This also handles cases where hooks exist\n // in a root layout with a
1LV in the body\n execNewMounted(parent = document) {\n let phxViewportTop = this.binding(PHX_VIEWPORT_TOP);\n let phxViewportBottom = this.binding(PHX_VIEWPORT_BOTTOM);\n this.all(\n parent,\n `[${phxViewportTop}], [${phxViewportBottom}]`,\n (hookEl) => {\n dom_default.maintainPrivateHooks(\n hookEl,\n hookEl,\n phxViewportTop,\n phxViewportBottom\n );\n this.maybeAddNewHook(hookEl);\n }\n );\n this.all(\n parent,\n `[${this.binding(PHX_HOOK)}], [data-phx-${PHX_HOOK}]`,\n (hookEl) => {\n this.maybeAddNewHook(hookEl);\n }\n );\n this.all(parent, `[${this.binding(PHX_MOUNTED)}]`, (el) => {\n this.maybeMounted(el);\n });\n }\n all(parent, selector, callback) {\n dom_default.all(parent, selector, (el) => {\n if (this.ownsElement(el)) {\n callback(el);\n }\n });\n }\n applyJoinPatch(live_patch, html, streams, events) {\n if (this.joinCount > 1) {\n if (this.pendingJoinOps.length) {\n this.pendingJoinOps.forEach((cb) => typeof cb === "function" && cb());\n this.pendingJoinOps = [];\n }\n }\n this.attachTrueDocEl();\n const patch = new DOMPatch(this, this.el, html, streams, null);\n patch.markPrunableContentForRemoval();
1\n this.performPatch(patch, false, true);\n this.joinNewChildren();\n this.execNewMounted();\n this.joinPending = false;\n this.liveSocket.dispatchEvents(events);\n this.applyPendingUpdates();\n if (live_patch) {\n const { kind, to } = live_patch;\n this.liveSocket.historyPatch(to, kind);\n }\n this.hideLoader();\n if (this.joinCount > 1) {\n this.triggerReconnected();\n }\n this.stopCallback();\n }\n triggerBeforeUpdateHook(fromEl, toEl) {\n this.liveSocket.triggerDOM("onBeforeElUpdated", [fromEl, toEl]);\n const hook = this.getHook(fromEl);\n const isIgnored = hook && dom_default.isIgnored(fromEl, this.binding(PHX_UPDATE));\n if (hook && !fromEl.isEqualNode(toEl) && !(isIgnored && isEqualObj(fromEl.dataset, toEl.dataset))) {\n hook.__beforeUpdate();\n return hook;\n }\n }\n maybeMounted(el) {\n const phxMounted = el.getAttribute(this.binding(PHX_MOUNTED));\n const hasBeenInvoked = phxMounted && dom_default.private(el, "mounted");\n if (phxMounted && !hasBeenInvoked) {\n this.liveSocket.execJS(el, phxMounted);\n dom_default.putPrivate(el, "mounted", true);\n }\n }\n maybeAddNewHook(el) {\n const newHook = this.addHook(el);\n if (newHook) {\n newHook.__mounted();\n }\n }
1\n performPatch(patch, pruneCids, isJoinPatch = false) {\n const removedEls = [];\n let phxChildrenAdded = false;\n const updatedHookIds = /* @__PURE__ */ new Set();\n this.liveSocket.triggerDOM("onPatchStart", [patch.targetContainer]);\n patch.afterAdded((el) => {\n this.liveSocket.triggerDOM("onNodeAdded", [el]);\n const phxViewportTop = this.binding(PHX_VIEWPORT_TOP);\n const phxViewportBottom = this.binding(PHX_VIEWPORT_BOTTOM);\n dom_default.maintainPrivateHooks(el, el, phxViewportTop, phxViewportBottom);\n this.maybeAddNewHook(el);\n if (el.getAttribute) {\n this.maybeMounted(el);\n }\n });\n patch.afterPhxChildAdded((el) => {\n if (dom_default.isPhxSticky(el)) {\n this.liveSocket.joinRootViews();\n } else {\n phxChildrenAdded = true;\n }\n });\n patch.beforeUpdated((fromEl, toEl) => {\n const hook = this.triggerBeforeUpdateHook(fromEl, toEl);\n if (hook) {\n updatedHookIds.add(fromEl.id);\n }\n js_default.onBeforeElUpdated(fromEl, toEl);\n });\n patch.afterUpdated((el) => {\n if (updatedHookIds.has(el.id)) {\n const hook = this.getHook(el);\n hook && hook.__updated();\n }\n });\n patch.afterDiscarded((el) => {\n if (el.nodeType === Node.ELEMENT_NODE) {\n removedEls.push(el);\n }\n });\n patch.afterTransitionsDiscarded(\n (els) => this.afterElementsRemoved(els, pruneCids)\n );\n patch.perform(isJoinPatch);\n this.afterElementsRemoved(removedEls, pruneCids);\n this.liveSocket.triggerDOM("onPatchEnd", [patch.targetContainer]);\n return phxChildrenAdded;\n }
1\n afterElementsRemoved(elements, pruneCids) {\n const destroyedCIDs = [];\n elements.forEach((parent) => {\n const components = dom_default.all(\n parent,\n `[${PHX_VIEW_REF}="${this.id}"][${PHX_COMPONENT}]`\n );\n const hooks = dom_default.all(\n parent,\n `[${this.binding(PHX_HOOK)}], [data-phx-hook]`\n );\n components.concat(parent).forEach((el) => {\n const cid = this.componentID(el);\n if (isCid(cid) && destroyedCIDs.indexOf(cid) === -1 && el.getAttribute(PHX_VIEW_REF) === this.id) {\n destroyedCIDs.push(cid);\n }\n });\n hooks.concat(parent).forEach((hookEl) => {\n const hook = this.getHook(hookEl);\n hook && this.destroyHook(hook);\n });\n });\n if (pruneCids) {\n this.maybePushComponentsDestroyed(destroyedCIDs);\n }\n }\n joinNewChildren() {\n dom_default.findPhxChildren(document, this.id).forEach((el) => this.joinChild(el));\n }\n maybeRecoverForms(html, callback) {\n const phxChange = this.binding("change");\n const oldForms = this.root.formsForRecovery;\n const template = document.createElement("template");\n template.innerHTML = html;\n if (!template.content.firstElementChild) {\n return;\n }\n dom_default.all(template.content, `[${PHX_PORTAL}]`).forEach((portalTemplate) => {\n if (!(portalTemplate instanceof HTMLTemplateElement)) {\n return;\n }\n template.content.firstElementChild?.appendChild(\n portalTemplate.content.firstElementChild\n );\n });\n const rootEl = template.content.firstElementChild;\n rootEl.id = this.id;\n rootEl.setAttribute(PHX_ROOT_ID, this.root.id);
1\n rootEl.setAttribute(PHX_SESSION, this.getSession());\n rootEl.setAttribute(PHX_STATIC, this.getStatic() ?? "");\n this.parent && rootEl.setAttribute(PHX_PARENT_ID, this.parent.id);\n dom_default.putPrivate(rootEl, "view", this);\n const formsToRecover = (\n // we go over all forms in the new DOM; because this is only the HTML for the current\n // view, we can be sure that all forms are owned by this view:\n dom_default.all(template.content, "form").filter((newForm) => newForm.id && oldForms[newForm.id]).filter((newForm) => !this.pendingForms.has(newForm.id)).filter(\n (newForm) => oldForms[newForm.id].getAttribute(phxChange) === newForm.getAttribute(phxChange)\n ).map((newForm) => {\n return [oldForms[newForm.id], newForm];\n })\n );\n if (formsToRecover.length === 0) {\n return callback();\n }\n formsToRecover.forEach(([oldForm, newForm], i) => {\n this.pendingForms.add(newForm.id);\n this.pushFormRecovery(\n oldForm,\n newForm,\n template.content.firstElementChild,\n () => {\n this.pendingForms.delete(newForm.id);\n if (i === formsToRecover.length - 1) {\n callback();\n }\n }\n );\n });\n }\n getChildById(id) {\n return this.root.children[this.id][id];\n }\n getDescendentByEl(el) {\n if (el.id === this.id) {\n return this;\n } else {\n return this.children && this.children[el.getAttribute(PHX_PARENT_ID)]?.[el.id];\n }\n }\n destroyDescendent(id) {\n for (const parentId in this.root.children) {\n for (const childId in this.root.children[parentId]) {\n if (childId === id) {\n return this.root.children[parentId][childId].destroy();\n }\n }\n }\n }\n joinChild(el) {\n const child = this.getChildById(el.id);\n if (!child) {\n const view = new _View(el, this.liveSocket, this);\n this.root.children[this.id][view.id] = view;\n view.join();\n this.childJoins++;\n return true;\n }\n }\n isJoinPending() {\n return this.joinPending;\n }\n ackJoin(_child) {\n this.childJoins--;\n if (this.childJoins === 0) {\n if (this.parent) {\n this.parent.ackJoin(this);\n } else {\n this.onAllChildJoinsComplete();\n }\n }\n }\n onAllChildJoinsComplete() {\n this.pendingForms.clear();\n this.formsForRecovery = {};\n this.joinCallback(() => {\n this.pendingJoinOps.forEach(([view, op]) => {\n if (!view.isDestroyed()) {\n op();\n }\n });\n this.pendingJoinOps = [];\n });\n }\n update(diff, events, isPending = false) {\n if (this.isJoinPending() || this.liveSocket.hasPendingLink() && this.root.isMain()) {\n if (!isPending) {\n this.pendingDiffs.push({ diff, events });\n }\n return false;\n }\n this.rendered.mergeDiff(diff);\n let phxChildrenAdded = false;\n if (this.rendered.isComponentOnlyDiff(diff)) {\n this.liveSocket.time("component patch complete", () => {\n const parentCids = dom_default.findExistingParentCIDs(\n this.id,\n this.rendered.componentCIDs(diff)\n );\n parentCids.forEach((parentCID) => {\n if (this.componentPatch(\n this.rendered.getComponent(diff, parentCID),\n parentCID\n )) {\n phxChildrenAdded = true;\n }\n });\n });\n } else if (!isEmpty(diff)) {\n this.liveSocket.time("full patch complete", () => {\n const [html, streams] = this.renderContainer(diff, "update");\n const patch = new DOMPatch(this, this.el, html, streams, null);
1\n phxChildrenAdded = this.performPatch(patch, true);\n });\n }\n this.liveSocket.dispatchEvents(events);\n if (phxChildrenAdded) {\n this.joinNewChildren();\n }\n return true;\n }\n renderContainer(diff, kind) {\n return this.liveSocket.time(`toString diff (${kind})`, () => {\n const tag = this.el.tagName;\n const cids = diff ? this.rendered.componentCIDs(diff) : null;\n const { buffer: html, streams } = this.rendered.toString(cids);\n return [`<${tag}>${html}</${tag}>`, streams];\n });\n }\n componentPatch(diff, cid) {\n if (isEmpty(diff))\n return false;\n const { buffer: html, streams } = this.rendered.componentToString(cid);\n const patch = new DOMPatch(this, this.el, html, streams, cid);\n const childrenAdded = this.performPatch(patch, true);\n return childrenAdded;\n }\n getHook(el) {\n return this.viewHooks[ViewHook.elementID(el)];\n }\n addHook(el) {\n const hookElId = ViewHook.elementID(el);\n if (el.getAttribute && !this.ownsElement(el)) {\n return;\n }\n if (hookElId && !this.viewHooks[hookElId]) {\n if (ViewHook.deadHook(el)) {\n return;\n }\n const hook = dom_default.getCustomElHook(el) || logError(`no hook found for custom element: ${el.id}`);\n this.viewHooks[hookElId] = hook;\n hook.__attachView(this);\n return hook;\n } else if (hookElId || !el.getAttribute) {\n return;\n } else {\n const hookName = el.getAttribute(`data-phx-${PHX_HOOK}`) || el.getAttribute(this.binding(PHX_HOOK));\n if (!hookName) {\n return;\n }\n const hookDefinition = this.liveSocket.getHookDefinition(hookName);\n if (hookDefinition) {\n if (!el.id) {\n logError(\n `no DOM ID for hook "${hookName}". Hooks require a unique ID on each element.`,\n el\n );\n return;\n }\n let hookInstance;\n try {\n if (typeof hookDefinition === "function" && hookDefinition.prototype instanceof ViewHook) {\n hookInstance = new hookDefinition(this, el);\n } else if (typeof hookDefinition === "object" && hookDefinition !== null) {\n hookInstance = new ViewHook(this, el, hookDefinition);\n } else {\n logError(\n `Invalid hook definition for "${hookName}". Expected a class extending ViewHook or an object definition.`,\n el\n );\n return;\n }\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : String(e);\n logError(`Failed to create hook "${hookName}": ${errorMessage}`, el);\n return;\n }\n this.viewHooks[ViewHook.elementID(hookInstance.el)] = hookInstance;\n return hookInstance;\n } else if (hookName !== null) {\n logError(`unknown hook foun
1d for "${hookName}"`, el);\n }\n }\n }\n destroyHook(hook) {\n const hookId = ViewHook.elementID(hook.el);\n hook.__destroyed();\n hook.__cleanup__();\n delete this.viewHooks[hookId];\n }\n applyPendingUpdates() {\n this.pendingDiffs = this.pendingDiffs.filter(\n ({ diff, events }) => !this.update(diff, events, true)\n );\n this.eachChild((child) => child.applyPendingUpdates());\n }\n eachChild(callback) {\n const children = this.root.children[this.id] || {};\n for (const id in children) {\n callback(this.getChildById(id));\n }\n }\n onChannel(event, cb) {\n this.liveSocket.onChannel(this.channel, event, (resp) => {\n if (this.isJoinPending()) {\n if (this.joinCount > 1) {\n this.pendingJoinOps.push(() => cb(resp));\n } else {\n this.root.pendingJoinOps.push([this, () => cb(resp)]);\n }\n } else {\n this.liveSocket.requestDOMUpdate(() => cb(resp));\n }\n });\n }\n bindChannel() {\n this.liveSocket.onChannel(this.channel, "diff", (rawDiff) => {\n this.liveSocket.requestDOMUpdate(() => {\n this.applyDiff(\n "update",\n rawDiff,\n ({ diff, events }) => this.update(diff, events)\n );\n });\n });\n this.onChannel(\n "redirect",\n ({ to, flash }) => this.onRedirect({ to, flash })\n );\n this.onChannel("live_patch", (redir) => this.onLivePatch(redir));\n this.onChannel("live_redirect", (redir) => this.onLiveRedirect(redir));\n this.channel.onError((reason) => this.onError(reason));\n this.channel.onClose((reason) => this.onClose(reason));\n }\n destroyAllChildren() {\n this.eachChild((child) => child.destroy());\n }\n onLiveRedirect(redir) {\n const { to, kind, flash } = redir;\n const url = this.expandURL(to);\n const e = new CustomEvent("phx:server-navigate", {\n detail: { to, kind, flash }\n });\n this.liveSocket.historyRedirect(e, url, kind, flash);\n }\n onLivePatch(redir) {\n const { to, kind } = redir;\n this.href = this.expandURL(to);\n this.liveSocket.historyPatch(to, kind);\n }\n expandURL(to) {\n return to.startsWith("/") ? `${window.location.protocol}//${window.location.host}${to}` : to;\n }\n onRedirect({\n to,\n flash,\n reloadToken\n }) {\n this.liveSocket.redirect(to, flash ?? null, reloadToken ?? null);\n }\n isDestroyed() {\n return this.destroyed;\n }\n joinDead() {\n this.isDead = true;\n }\n join(callback) {\n this.showLoader(this.liveSocket.loaderTimeout);\n this.bindChannel();\n if (this.isMain()) {\n this.stopCallback = this.liveSocket.withPageLoading({\n to: this.href,\n kind: "initial"\n });\n }\n this.joinCallback = (onDone) => {\n onDone = onDone || function() {\n };\n callback ? callback(this.joinCount, onDone) : onDone();\n };\n this.wrapPush(() => this.channel.join(), {\n ok: (resp) => this.liveSocket.requestDOMUpdate(() => this.onJoin(resp)),\n error: (error) => this.onJoinError(error),\n timeout: () => this.onJoinError({ reason: "timeout" })\n });\n }\n onJoinError(resp) {\n if (resp.events) {\n this.liveSocket.dispatchEvents(resp.events);\n }\n if (resp.reason === "reload") {\n this.log("error", () => [\n `failed mount with ${resp.status}. Falling back to page reload`,\n resp\n ]);\n this.onRedirect({\n to: this.liveSocket.main.href,\n reloadToken: resp.token\n });\n return;\n } else if (resp.reason === "unauthorized" || resp.reason === "stale") {\n this.log("error", () => [\n "unauthorized live_redirect. Falling back to page request",\n resp\n ]);\n this.onRedirect({ to: this.liveSocket.main.href, flash: this.flash });\n return;\n }\n if (resp.redirect || resp.live_redirect) {\n this.joinPending = false;\n this.channel.leave();\n }\n if (resp.redirect) {\n return this.onRedirect(resp.redirect);\n }\n if (resp.live_redirect) {\n return this.onLiveRedirect(resp.live_redirect);\n }\n this.log("error", () => ["unable to join", resp]);\n if (this.isMain()) {\n this.displayError(\n [PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS],\n { unstructuredError: resp, errorKind: "server" }\n );\n if (this.liveSocket.isConnected()) {\n this.liveSocket.reloadWithJitter(this);\n }\n } else {\n if (this.joinAttempts >= MAX_CHILD_JOIN_ATTEMPTS) {\n this.root.displayError(\n [PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS],\n { unstructuredError: resp, errorKind: "server" }\n );\n this.log("error", () => [\n `giving up trying to mount after ${MAX_CHILD_JOIN_ATTEMPTS} tries`,\n resp\n ]);\n this.destroy();\n }
1\n const trueChildEl = dom_default.byId(this.el.id);\n if (trueChildEl) {\n dom_default.mergeAttrs(trueChildEl, this.el);\n this.displayError(\n [PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS],\n { unstructuredError: resp, errorKind: "server" }\n );\n this.el = trueChildEl;\n } else {\n this.destroy();\n }\n }\n }\n onClose(reason) {\n if (this.isDestroyed()) {\n return;\n }\n if (this.isMain() && this.liveSocket.hasPendingLink() && reason !== "leave") {\n return this.liveSocket.reloadWithJitter(this);\n }\n this.destroyAllChildren();\n this.liveSocket.dropActiveElement(this);\n if (this.liveSocket.isUnloaded()) {\n this.showLoader(BEFORE_UNLOAD_LOADER_TIMEOUT);\n }\n }\n onError(reason) {\n this.onClose(reason);\n if (this.liveSocket.isConnected()) {\n this.log("error", () => ["view crashed", reason]);\n }\n if (!this.liveSocket.isUnloaded()) {\n if (this.liveSocket.isConnected()) {\n this.displayError(\n [PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS],\n { unstructuredError: reason, errorKind: "server" }\n );\n } else {\n this.displayError(\n [PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_CLIENT_ERROR_CLASS],\n { unstructuredError: reason, errorKind: "client" }\n );\n }\n }\n }\n displayError(classes, details = {}) {\n if (this.isMain()) {\n dom_default.dispatchEvent(window, "phx:page-loading-start", {\n detail: { to: this.href, kind: "error", ...details }\n });\n }\n this.showLoader();\n this.setContainerClasses(...classes);\n this.delayedDisconnected();\n }\n delayedDisconnected() {\n this.disconnectedTimer = setTimeout(() => {\n this.execAll(this.binding("disconnected"));\n }, this.liveSocket.disconnectedTimeout);\n }\n wrapPush(callerPush, receives) {\n const latency = this.liveSocket.getLatencySim();\n const withLatency = latency ? (cb) => setTimeout(() => !this.isDestroyed() && cb(), latency) : (cb) => !this.isDestroyed() && cb();\n withLatency(() => {\n callerPush().receive(\n "ok",\n (resp) => withLatency(() => receives.ok && receives.ok(resp))\n ).receive(\n "error",\n (reason) => withLatency(() => receives.error && receives.error(reason))\n ).receive(\n "timeout",\n () => withLatency(() => receives.timeout && receives.timeout())\n );\n });\n }\n pushWithReply(refGenerator, event, payload) {\n if (!this.isConnected()) {\n return Promise.reject(new Error("no connection"));\n }\n const [ref, [el], opts] = refGenerator ? refGenerator({ payload }) : [null, [], {}];\n const oldJoinCount = this.joinCount;\n let onLoadingDone = function() {\n };\n if (opts.page_loading) {\n onLoadingDone = this.liveSocket.withPageLoading({\n kind: "element",\n target: el\n });\n }\n if (typeof payload.cid !== "number") {\n delete payload.cid;\n }\n return new Promise((resolve, reject) => {\n this.wrapPush(() => this.channel.push(event, payload, PUSH_TIMEOUT), {\n ok: (resp) => {\n if (ref !== null) {\n this.lastAckRef = ref;\n }\n const finish = (hookReply) => {\n if (resp.redirect) {\n this.onRedirect(resp.redirect);\n }\n if (resp.live_patch) {\n this.onLivePatch(resp.live_patch);\n }\n if (resp.live_redirect) {\n this.onLiveRedirect(resp.live_redirect);\n }\n onLoadingDone();\n resolve({ resp, reply: hookReply, ref });\n };\n if (resp.diff) {\n this.liveSocket.requestDOMUpdate(() => {\n this.applyDiff("update", resp.diff, ({ diff, reply, events }) => {\n if (ref !== null) {\n this.undoRefs(ref, payload.event);\n }\n this.update(diff, events);\n finish(reply);\n });\n });\n } else {\n if (ref !== null) {\n this.undoRefs(ref, payload.event);\n }\n finish(null);\n }\n },\n error: (reason) => reject(new Error(`failed with reason: ${JSON.stringify(reason)}`)),\n timeout: () => {\n reject(new Error("timeout"));\n if (this.joinCount === oldJoinCount) {\n this.liveSocket.reloadWithJitter(this, () => {\n this.log("timeout", () => [\n "received timeout while communicating with server. Falling back to hard refresh for recovery"\n ]);\n });\n }\n }\n });\n });\n }\n undoRefs(ref, phxEvent, onlyEls) {\n if (!this.isConnected()) {\n return;\n }\n const selector = `[${PHX_REF_SRC}="${this.refSrc()}"]`;\n if (onlyEls) {\n onlyEls = new Set(onlyEls);\n dom_default.all(document, selector, (parent) => {\n if (onlyEls && !onlyEls.has(parent)) {\n return;\n }\n dom_default.all(\n parent,\n selector,\n (child) => this.undoElRef(child, ref, phxEvent)\n );\n this.undoElRef(parent, ref, phxEvent);\n });\n } else {\n dom_default.all(document, selector, (el) => this.undoElRef(el, ref, phxEvent));\n }\n }\n undoElRef(el, ref, phxEvent) {\n const elRef = new ElementRef(el);\n elRef.maybeUndo(ref, phxEvent, (clonedTree) => {\n const patch = new DOMPatch(this, el, clonedTree, /* @__P
1URE__ */ new Set(), null, {\n undoRef: ref\n });\n const phxChildrenAdded = this.performPatch(patch, true);\n dom_default.all(\n el,\n `[${PHX_REF_SRC}="${this.refSrc()}"]`,\n (child) => this.undoElRef(child, ref, phxEvent)\n );\n if (phxChildrenAdded) {\n this.joinNewChildren();\n }\n });\n }\n refSrc() {\n return this.el.id;\n }\n putRef(elements, phxEvent, eventType, opts = {}) {\n const newRef = this.ref++;\n const disableWith = this.binding(PHX_DISABLE_WITH);\n if (opts.loading) {\n const loadingEls = dom_default.all(document, opts.loading).map((el) => {\n return { el, lock: true, loading: true };\n });\n elements = elements.concat(loadingEls);\n }\n for (const { el, lock, loading } of elements) {\n if (!lock && !loading) {\n throw new Error("putRef requires lock or loading");\n }\n el.setAttribute(PHX_REF_SRC, this.refSrc());\n if (loading) {\n el.setAttribute(PHX_REF_LOADING, newRef.toString());\n }\n if (lock) {\n el.setAttribute(PHX_REF_LOCK, newRef.toString());\n }\n if (!loading || opts.submitter && !(el === opts.submitter || el === opts.form)) {\n continue;\n }\n const lockCompletePromise = new Promise((resolve) => {\n el.addEventListener(`phx:undo-lock:${newRef}`, () => resolve(detail), {\n once: true\n });\n });\n const loadingCompletePromise = new Promise((resolve) => {\n el.addEventListener(\n `phx:undo-loading:${newRef}`,\n () => resolve(detail),\n { once: true }\n );\n });\n el.classList.add(`phx-${eventType}-loading`);\n const disableText = el.getAttribute(disableWith);\n if (disableText !== null) {\n if (!el.getAttribute(PHX_DISABLE_WITH_RESTORE)) {\n el.setAttribute(PHX_DISABLE_WITH_RESTORE, el.textContent || "");\n }\n if (disableText !== "") {\n el.textContent = disableText;\n }\n el.setAttribute(\n PHX_DISABLED,\n el.getAttribute(PHX_DISABLED) || ("disabled" in el ? String(el.disabled) : "")\n );\n el.setAttribute("disabled", "");\n }\n const detail = {\n event: phxEvent,\n eventType,\n ref: newRef,\n isLoading: loading,\n isLocked: lock,\n lockElements: elements.filter(({ lock: lock2 }) => lock2).map(({ el: el2 }) => el2),\n loadingElements: elements.filter(({ loading: loading2 }) => loading2).map(({ el: el2 }) => el2),\n unlock: (els) => {\n els = Array.isArray(els) ? els : [els];\n this.undoRefs(newRef, phxEvent, els);\n },\n lockComplete: lockCompletePromise,\n loadingComplete: loadingCompletePromise,\n lock: (lockEl) => {\n return new Promise((resolve) => {\n if (this.isAcked(newRef)) {\n return resolve(detail);\n }\n lockEl.setAttribute(PHX_REF_LOCK, newRef);\n lockEl.setAttribute(PHX_REF_SRC, this.refSrc());\n lockEl.addEventListener(\n `phx:lock-stop:${newRef}`,\n () => resolve(detail),\n { once: true }\n );\n });\n }\n };\n if (opts.payload) {\n detail["payload"] = opts.payload;\n }\n if (opts.target) {\n detail["target"] = opts.target;\n }\n if (opts.originalEvent) {\n detail["originalEvent"] = opts.originalEvent;\n }\n el.dispatchEvent(\n new CustomEvent("phx:push", {\n detail,\n bubbles: true,\n cancelable: false\n })\n );\n if (phxEvent) {\n el.dispatchEvent(\n new CustomEvent(`phx:push:${phxEvent}`, {\n detail,\n bubbles: true,\n cancelable: false\n })\n );\n }\n }\n return [newRef, elements.map(({ el }) => el), opts];\n }\n isAcked(ref) {\n return this.lastAckRef !== null && this.lastAckRef >= ref;\n }\n componentID(el) {\n const cid = el.getAttribute && el.getAttribute(PHX_COMPONENT);\n return cid ? parseInt(cid) : null;\n }\n targetComponentID(target, targetCtx, opts = {}) {\n if (isCid(targetCtx)) {\n return targetCtx;\n }\n const cidOrSelector = opts.target || target.getAttribute(this.binding("target"));
1\n if (isCid(cidOrSelector)) {\n return typeof cidOrSelector === "number" ? cidOrSelector : parseInt(cidOrSelector);\n } else if (targetCtx && (cidOrSelector !== null || opts.target)) {\n return this.closestComponentID(targetCtx);\n } else {\n return null;\n }\n }\n closestComponentID(targetCtx) {\n if (isCid(targetCtx)) {\n return targetCtx;\n } else if (targetCtx) {\n return maybe(\n // We either use the closest data-phx-component binding, or -\n // in case of portals - continue with the portal source.\n // This is necessary if teleporting an element outside of its LiveComponent.\n targetCtx.closest(`[${PHX_COMPONENT}],[${PHX_TELEPORTED_SRC}]`),\n (el) => {\n if (el.hasAttribute(PHX_COMPONENT)) {\n return this.ownsElement(el) && this.componentID(el);\n }\n if (el.hasAttribute(PHX_TELEPORTED_SRC)) {\n const portalParent = dom_default.byId(el.getAttribute(PHX_TELEPORTED_SRC));\n return this.closestComponentID(portalParent);\n }\n }\n );\n } else {\n return null;\n }\n }\n pushHookEvent(el, targetCtx, event, payload) {\n if (!this.isConnected()) {\n this.log("hook", () => [\n "unable to push hook event. LiveView not connected",\n event,\n payload\n ]);\n return Promise.reject(\n new Error("unable to push hook event. LiveView not connected")\n );\n }\n const refGenerator = () => this.putRef([{ el, loading: true, lock: true }], event, "hook", {\n payload,\n target: targetCtx\n });\n return this.pushWithReply(refGenerator, "event", {\n type: "hook",\n event,\n value: payload,\n cid: this.closestComponentID(targetCtx)\n }).then(\n ({ resp: _resp, reply, ref }) => ({ reply, ref })\n );\n }\n extractMeta(el, meta, value) {\n const prefix = this.binding("value-");\n for (let i = 0; i < el.attributes.length; i++) {\n if (!meta) {\n meta = {};\n }\n const name = el.attributes[i].name;\n if (name.startsWith(prefix)) {\n meta[name.replace(prefix, "")] = el.getAttribute(name);\n }\n }\n if (el.value !== void 0 && !(el instanceof HTMLFormElement)) {\n if (!meta) {\n meta = {};\n }\n meta.value = el.value;\n if (el.tagName === "INPUT" && CHECKABLE_INPUTS.indexOf(el.type) >= 0 && !el.checked) {\n delete meta.value;\n }\n }\n if (value) {\n if (!meta) {\n meta = {};\n }\n for (const key in value) {\n meta[key] = value[key];\n }\n }\n return meta;\n }\n serializeForm(form, opts = {}, onlyNames = []) {\n const { submitter } = opts;\n let injectedElement;\n if (submitter && submitter.name) {\n const input = document.createElement("input");\n input.type = "hidden";\n const formId = submitter.getAttribute("form");\n if (formId) {\n input.setAttribute("form", formId);\n }\n input.name = submitter.name;\n input.value = submitter.value;\n submitter.parentElement.insertBefore(input, submitter);\n injectedElement = input;\n }\n const formData = new FormData(form);\n const toRemove = [];\n formData.forEach((val, key, _index) => {\n if (val instanceof File) {\n toRemove.push(key);\n }\n });\n toRemove.forEach((key) => formData.delete(key));\n const params = new URLSearchParams();\n const { inputsUnused, onlyHiddenInputs } = Array.from(form.elements).reduce(\n (acc, input) => {\n if (!dom_default.isFormAssociated(input)) {\n return acc;\n }\n const { inputsUnused: inputsUnused2, onlyHiddenInputs: onlyHiddenInputs2 } = acc;\n const key = input.name;\n if (!key) {\n return acc;\n }\n if (inputsUnused2[key] === void 0) {\n inputsUnused2[key] = true;\n }\n if (onlyHiddenInputs2[key] === void 0) {\n onlyHiddenInputs2[key] = true;\n }\n const inputSkipUnusedField = input.hasAttribute(\n this.binding(PHX_NO_UNUSED_FIELD)\n );\n const isUsed = dom_default.private(input, PHX_HAS_FOCUSED) || dom_default.private(input, PHX_HAS_SUBMITTED) || inputSkipUnusedField;\n const isHidden = input.type === "hidden";
1\n inputsUnused2[key] = inputsUnused2[key] && !isUsed;\n onlyHiddenInputs2[key] = onlyHiddenInputs2[key] && isHidden;\n return acc;\n },\n { inputsUnused: {}, onlyHiddenInputs: {} }\n );\n const formSkipUnusedFields = form.hasAttribute(\n this.binding(PHX_NO_UNUSED_FIELD)\n );\n for (const [key, val] of formData.entries()) {\n if (onlyNames.length === 0 || onlyNames.indexOf(key) >= 0) {\n const isUnused = inputsUnused[key];\n const hidden = onlyHiddenInputs[key];\n const skipUnusedCheck = formSkipUnusedFields;\n if (!skipUnusedCheck && isUnused && !(submitter && submitter.name == key) && !hidden) {\n params.append(prependFormDataKey(key, "_unused_"), "");\n }\n if (typeof val === "string") {\n params.append(key, val);\n }\n }\n }\n if (submitter && injectedElement) {\n submitter.parentElement.removeChild(injectedElement);\n }\n return params.toString();\n }\n pushEvent(type, el, targetCtx, phxEvent, meta, opts = {}, onReply) {\n this.pushWithReply(\n (maybePayload) => this.putRef([{ el, loading: true, lock: true }], phxEvent, type, {\n ...opts,\n payload: maybePayload?.payload\n }),\n "event",\n {\n type,\n event: phxEvent,\n value: this.extractMeta(el, meta, opts.value),\n cid: this.targetComponentID(el, targetCtx, opts)\n }\n ).then(({ reply }) => onReply && onReply(reply)).catch((error) => logError("Failed to push event", error));\n }\n pushFileProgress(fileEl, entryRef, progress, onReply = function() {\n }) {\n this.liveSocket.withinOwners(fileEl.form, (view, targetCtx) => {\n view.pushWithReply(null, "progress", {\n event: fileEl.getAttribute(view.binding(PHX_PROGRESS)),\n ref: fileEl.getAttribute(PHX_UPLOAD_REF),\n entry_ref: entryRef,\n progress,\n cid: view.targetComponentID(fileEl.form, targetCtx)\n }).then(() => onReply()).catch((error) => logError("Failed to push file progress", error));\n });\n }\n pushInput(inputEl, targetCtx, forceCid, phxEvent, opts, callback) {\n if (!inputEl.form) {\n throw new Error("form events require the input to be inside a form");\n }\n let uploads;\n const cid = isCid(forceCid) ? forceCid : this.targetComponentID(inputEl.form, targetCtx, opts);\n const refGenerator = (maybePayload) => {\n return this.putRef(\n [\n { el: inputEl, loading: true, lock: true },\n { el: inputEl.form, loading: true, lock: true }\n ],\n phxEvent,\n "change",\n { ...opts, payload: maybePayload?.payload }\n );\n };\n let formData;\n const meta = this.extractMeta(inputEl.form, {}, opts.value);\n const serializeOpts = {};\n if (inputEl instanceof HTMLButtonElement) {\n serializeOpts.submitter = inputEl;\n }\n if (inputEl.getAttribute(this.binding("change"))) {\n formData = this.serializeForm(inputEl.form, serializeOpts, [\n inputEl.name\n ]);\n } else {\n formData = this.serializeForm(inputEl.form, serializeOpts);\n }\n if (dom_default.isUploadInput(inputEl) && inputEl.files && inputEl.files.length > 0) {\n LiveUploader.trackFiles(inputEl, Array.from(inputEl.files));\n }\n uploads = LiveUploader.serializeUploads(inputEl);\n const event = {\n type: "form",\n event: phxEvent,\n value: formData,\n meta: {\n // no target was implicitly sent as "undefined" in LV <= 1.0.5, therefore\n // we have to keep it. In 1.0.6 we switched from passing meta as URL encoded data\n // to passing it directly in the event, but the JSON encode would drop keys with\n // undefined values.\n _target: opts._target || "undefined",\n ...meta\n },\n uploads,\n cid\n };\n this.pushWithReply(refGenerator, "event", event).then(({ resp }) => {\n if (dom_default.isUploadInput(inputEl) && dom_default.isAutoUpload(inputEl)) {\n ElementRef.onUnlock(inputEl, () => {\n if (LiveUploader.filesAwaitingPreflight(inputEl).length > 0) {\n const [ref, _els] = refGenerator();\n this.undoRefs(ref, phxEvent, [inputEl.form]);\n this.uploadFiles(\n inputEl.form,\n phxEvent,\n targetCtx,\n ref,\n cid,\n (_uploads) =>
1 {\n callback && callback(resp);\n this.triggerAwaitingSubmit(inputEl.form, phxEvent);\n this.undoRefs(ref, phxEvent);\n }\n );\n }\n });\n } else {\n callback && callback(resp);\n }\n }).catch((error) => logError("Failed to push input event", error));\n }\n triggerAwaitingSubmit(formEl, phxEvent) {\n const awaitingSubmit = this.getScheduledSubmit(formEl);\n if (awaitingSubmit) {\n const [_el, _ref, _opts, callback] = awaitingSubmit;\n this.cancelSubmit(formEl, phxEvent);\n callback();\n }\n }\n getScheduledSubmit(formEl) {\n return this.formSubmits.find(\n ([el, _ref, _opts, _callback]) => el.isSameNode(formEl)\n );\n }\n scheduleSubmit(formEl, ref, opts, callback) {\n if (this.getScheduledSubmit(formEl)) {\n return true;\n }\n this.formSubmits.push([formEl, ref, opts, callback]);\n }\n cancelSubmit(formEl, phxEvent) {\n this.formSubmits = this.formSubmits.filter(\n ([el, ref, _opts, _callback]) => {\n if (el.isSameNode(formEl)) {\n this.undoRefs(ref, phxEvent);\n return false;\n } else {\n return true;\n }\n }\n );\n }\n disableForm(formEl, phxEvent, opts = {}) {\n const filterIgnored = (el) => {\n const userIgnored = closestPhxBinding(\n el,\n `${this.binding(PHX_UPDATE)}=ignore`,\n el.form\n );\n return !(userIgnored || closestPhxBinding(el, "data-phx-update=ignore", el.form));\n };\n const filterDisables = (el) => {\n return el.hasAttribute(this.binding(PHX_DISABLE_WITH));\n };\n const filterButton = (el) => el.tagName == "BUTTON";\n const filterInput = (el) => ["INPUT", "TEXTAREA"].includes(el.tagName);\n const formElements = Array.from(formEl.elements);\n const disables = formElements.filter(filterDisables);\n const buttons = formElements.filter(filterButton).filter(filterIgnored);\n const inputs = formElements.filter(filterInput).filter(filterIgnored);\n buttons.forEach((button) => {\n button.setAttribute(PHX_DISABLED, button.disabled.toString());\n button.disabled = true;\n });\n inputs.forEach((input) => {\n input.setAttribute(PHX_READONLY, input.readOnly.toString());\n input.readOnly = true;\n if (input instanceof HTMLInputElement && input.files) {\n input.setAttribute(PHX_DISABLED, input.disabled.toString());\n input.disabled = true;\n }\n });\n const formEls = disables.concat(buttons).concat(inputs).map((el) => {\n return { el, loading: true, lock: true };\n });\n const els = [\n { el: formEl, loading: true, lock: false },\n ...formEls\n ].reverse();\n return this.putRef(els, phxEvent, "submit", opts);\n }\n pushFormSubmit(formEl, targetCtx, phxEvent, submitter, opts, onReply) {\n const refGenerator = (maybePayload) => this.disableForm(formEl, phxEvent, {\n ...opts,\n form: formEl,\n payload: maybePayload?.payload,\n submitter\n });\n dom_default.putPrivate(formEl, "submitter", submitter);\n const cid = this.targetComponentID(formEl, targetCtx);\n if (LiveUploader.hasUploadsInProgress(formEl)) {\n const [ref, _els] = refGenerator();\n const push = () => this.pushFormSubmit(\n formEl,\n targetCtx,\n phxEvent,\n submitter,\n opts,\n onReply\n );\n return this.scheduleSubmit(formEl, ref, opts, push);\n } else if (LiveUploader.inputsAwaitingPreflight(formEl).length > 0) {\n const [ref, els] = refGenerator();\n const proxyRefGen = () => [ref, els, opts];\n this.uploadFiles(formEl, phxEvent, targetCtx, ref, cid, (_uploads) => {\n if (LiveUploader.inputsAwaitingPreflight(formEl).length > 0) {\n return this.undoRefs(ref, phxEvent);\n }\n const meta = this.extractMeta(formEl, {}, opts.value);\n const formData = this.serializeForm(formEl, { submitter });\n this.pushWithReply(proxyRefGen, "event", {\n type: "form",\n event: phxEvent,\n value: formData,\n meta,\n cid\n }).then(({ resp }) => onReply(resp)).catch((error) => logError("Failed to push form submit", error));\n });\n } else if (!(formEl.hasAttribute(PHX_REF_SRC) && formEl.classList.contains("phx-submit-loading"))) {\n const meta = this.extractMeta(formEl, {}, opts.value);\n const formData = this.serializeForm(formEl, { submitter });\n this.pushWithReply(refGenerator, "event", {\n type: "form",\n event: phxEvent,\n value: formData,\n meta,\n cid\n }).then(({ resp }) => onReply(resp)).catch((error) => logError("Failed to push form submit", error));\n }\n }\n uploadFiles(formEl, phxEvent, targetCtx, ref, cid, onComplete) {\n const joinCountAtUpload = this.joinCount;\n const inputEls = LiveUploader.activeFileInputs(formEl);\n let numFileInputsInProgress = inputEls.length;
1\n inputEls.forEach((inputEl) => {\n const uploader = new LiveUploader(inputEl, this, () => {\n numFileInputsInProgress--;\n if (numFileInputsInProgress === 0) {\n onComplete();\n }\n });\n const entries = uploader.entries().map((entry) => entry.toPreflightPayload());\n if (entries.length === 0) {\n numFileInputsInProgress--;\n return;\n }\n const payload = {\n ref: inputEl.getAttribute(PHX_UPLOAD_REF),\n entries,\n cid: this.targetComponentID(inputEl.form, targetCtx)\n };\n this.log("upload", () => ["sending preflight request", payload]);\n this.pushWithReply(null, "allow_upload", payload).then(({ resp }) => {\n this.log("upload", () => ["got preflight response", resp]);\n uploader.entries().forEach((entry) => {\n if (resp.entries && !resp.entries[entry.ref]) {\n this.handleFailedEntryPreflight(\n entry.ref,\n "failed preflight",\n uploader\n );\n }\n });\n if (resp.error || Object.keys(resp.entries).length === 0) {\n this.undoRefs(ref, phxEvent);\n const errors = resp.error || [];\n errors.map(([entry_ref, reason]) => {\n this.handleFailedEntryPreflight(entry_ref, reason, uploader);\n });\n } else {\n const onError = (callback) => {\n this.channel.onError(() => {\n if (this.joinCount === joinCountAtUpload) {\n callback();\n }\n });\n };\n uploader.initAdapterUpload(resp, onError, this.liveSocket);\n }\n }).catch((error) => logError("Failed to push upload", error));\n });\n }\n handleFailedEntryPreflight(uploadRef, reason, uploader) {\n if (uploader.isAutoUpload()) {\n const entry = uploader.entries().find((entry2) => entry2.ref === uploadRef.toString());\n if (entry) {\n entry.cancel();\n }\n } else {\n uploader.entries().map((entry) => entry.cancel());\n }\n this.log("upload", () => [`error for entry ${uploadRef}`, reason]);\n }\n dispatchUploads(targetCtx, name, filesOrBlobs) {\n const targetElement = this.targetCtxElement(targetCtx) || this.el;\n const inputs = dom_default.findUploadInputs(targetElement).filter(\n (el) => el.name === name\n );\n if (inputs.length === 0) {\n logError(`no live file inputs found matching the name "${name}"`);\n } else if (inputs.length > 1) {\n logError(`duplicate live file inputs found matching the name "${name}"`);\n } else {\n dom_default.dispatchEvent(inputs[0], PHX_TRACK_UPLOADS, {\n detail: { files: filesOrBlobs }\n });\n }\n }\n targetCtxElement(targetCtx) {\n if (isCid(targetCtx)) {\n const target = dom_default.findComponent(this.id, targetCtx);\n return target;\n } else if (targetCtx) {\n return targetCtx;\n } else {\n return null;\n }\n }\n pushFormRecovery(oldForm, newForm, templateDom, callback) {\n const phxChange = this.binding("change");\n const phxTarget = newForm.getAttribute(this.binding("target")) || newForm;\n const phxEvent = newForm.getAttribute(this.binding(PHX_AUTO_RECOVER)) || newForm.getAttribute(this.binding("change"));\n const inputs = Array.from(oldForm.elements).filter(\n (el) => dom_default.isFormAssociated(el) && el.name && !el.hasAttribute(phxChange)\n );\n if (inputs.length === 0) {\n callback();\n return;\n }\n inputs.forEach(\n (input2) => input2.hasAttribute(PHX_UPLOAD_REF) && LiveUploader.clearFiles(input2)\n );\n const input = inputs.find((el) => el.type !== "hidden") || inputs[0];\n let pending = 0;\n this.withinTargets(\n phxTarget,\n (targetView, targetCtx) => {\n const cid = this.targetComponentID(newForm, targetCtx);\n pending++;\n let e = new CustomEvent("phx:form-recovery", {\n detail: { sourceElement: oldForm }\n });\n js_default.exec(e, "change", phxEvent, this, input, [\n "push",\n {\n _target: input.name,\n targetView,\n targetCtx,\n newCid: cid,\n callback: () => {\n pending--;\n if (pending === 0) {\n callback();\n }\n }\n }\n ]);\n },\n templateDom\n );\n }\n pushLinkPatch(e, href, targetEl, callback) {\n const linkRef = this.liveSocket.setPendingLink(href);\n const loading = e.isTrusted && e.type !== "popstate";\n const refGen = targetEl ? () => this.putRef(\n [{ el: targetEl, loading, lock: true }],\n null,\n "click"\n ) : null;\n const fallback = () => this.liveSocket.redirect(window.location.href, null, null);\n const url = href.startsWith("/") ? `${location.protocol}//${location.host}${href}` : href;\n this.pushWithReply(refGen, "live_patch", { url }).then(\n ({ resp }) =>
1 {\n this.liveSocket.requestDOMUpdate(() => {\n if (resp.link_redirect) {\n this.liveSocket.replaceMain(href, null, callback, linkRef);\n } else if (resp.redirect) {\n return;\n } else {\n if (this.liveSocket.commitPendingLink(linkRef)) {\n this.href = href;\n }\n this.applyPendingUpdates();\n callback && callback(linkRef);\n }\n });\n },\n ({ error: _error, timeout: _timeout }) => fallback()\n );\n }\n getFormsForRecovery() {\n if (this.joinCount === 0) {\n return {};\n }\n const phxChange = this.binding("change");\n return dom_default.all(\n document,\n `#${CSS.escape(this.id)} form[${phxChange}], [${PHX_TELEPORTED_REF}="${CSS.escape(this.id)}"] form[${phxChange}]`\n ).filter((form) => form instanceof HTMLFormElement).filter((form) => form.id).filter((form) => form.elements.length > 0).filter(\n (form) => form.getAttribute(this.binding(PHX_AUTO_RECOVER)) !== "ignore"\n ).map((form) => {\n const clonedForm = form.cloneNode(true);\n morphdom_esm_default(clonedForm, form, {\n onBeforeElUpdated: (fromEl, toEl) => {\n dom_default.copyPrivates(fromEl, toEl);\n if (fromEl.getAttribute("form") === form.id && fromEl.parentNode) {\n fromEl.parentNode.removeChild(fromEl);\n return false;\n }\n return true;\n }\n });\n const externalElements = document.querySelectorAll(\n `[form="${CSS.escape(form.id)}"]`\n );\n Array.from(externalElements).forEach((el) => {\n const clonedEl = el.cloneNode(true);\n morphdom_esm_default(clonedEl, el);\n dom_default.copyPrivates(clonedEl, el);\n clonedEl.removeAttribute("form");\n clonedForm.appendChild(clonedEl);\n });\n return clonedForm;\n }).reduce((acc, form) => {\n acc[form.id] = form;\n return acc;\n }, {});\n }\n maybePushComponentsDestroyed(destroyedCIDs) {\n let willDestroyCIDs = destroyedCIDs.filter((cid) => {\n return dom_default.findComponent(this.id, cid) === null;\n });\n const onError = (error) => {\n if (!this.isDestroyed()) {\n logError("Failed to push components destroyed", error);\n }\n };\n if (willDestroyCIDs.length > 0) {\n willDestroyCIDs.forEach((cid) => this.rendered.resetRender(cid));\n this.pushWithReply(null, "cids_will_destroy", { cids: willDestroyCIDs }).then(() => {\n this.liveSocket.requestDOMUpdate(() => {\n let completelyDestroyCIDs = willDestroyCIDs.filter((cid) => {\n return dom_default.findComponent(this.id, cid) === null;\n });\n if (completelyDestroyCIDs.length > 0) {\n this.pushWithReply(null, "cids_destroyed", {\n cids: completelyDestroyCIDs\n }).then(({ resp }) => {\n this.rendered.pruneCIDs(resp.cids);\n }).catch(onError);\n }\n });\n }).catch(onError);\n }\n }\n ownsElement(el) {\n let parentViewEl = dom_default.closestViewEl(el);\n return el.getAttribute(PHX_PARENT_ID) === this.id || parentViewEl && parentViewEl.id === this.id || !parentViewEl && this.isDead;\n }\n submitForm(form, targetCtx, phxEvent, submitter, opts = {}) {\n dom_default.putPrivate(form, PHX_HAS_SUBMITTED, true);\n const inputs = Array.from(form.elements);\n inputs.forEach((input) => dom_default.putPrivate(input, PHX_HAS_SUBMITTED, true));\n this.liveSocket.blurActiveElement();\n this.pushFormSubmit(form, targetCtx, phxEvent, submitter, opts, () => {\n this.liveSocket.restorePreviouslyActiveFocus();\n });\n }\n binding(kind) {\n return this.liveSocket.binding(kind);\n }\n // phx-portal\n pushPortalElementId(id) {\n this.portalElementIds.add(id);\n }\n dropPortalElementId(id) {\n this.portalElementIds.delete(id);\n }\n destroyPortalElements() {\n if (!this.liveSocket.unloaded) {\n this.portalElementIds.forEach((id) => {\n const el = document.getElementById(id);\n if (el) {\n el.remove();\n }\n });\n }\n }\n};\n\n// js/phoenix_live_view/live_socket.ts\nvar isUsedInput = (el) => dom_default.isUsedInput(el);\nvar LiveSocket = class {\n /**\n * Creates a new LiveSocket instance.\n */\n constructor(url, phxSocket, opts = {}) {\n /** @internal */\n this.unloaded = false;\n if (!phxSocket || phxSocket.constructor.name === "Object") {\n throw new Error(`\n a phoenix Socket must be provided as the second argument to the LiveSocket constructor. For example:\n\n import {Socket} from "phoenix"\n import {LiveSocket} from "phoenix_live_view"\n let liveSocket = new LiveSocket("/live", Socket, {...})\n `);\n }\n this.socket = new phxSocket(url, opts);\n this.bindingPrefix = opts.bindingPrefix || BINDING_PREFIX;\n this.params = phoenix_live_view_esm_closure(opts.params || {});\n this.viewLogger = opts.viewLogger;\n this.metadataCallbacks = opts.metadata || {};\n this.defaults = Object.assign(clone(DEFAULTS), opts.defaults || {});\n this.prevActive = null;\n this.silenced = false;\n this.main = null;\n this.outgoingMainEl = null;\n this.clickStartedAtTarget = null;\n this.linkRef = 1;\n this.roots = {};\n this.href = window.location.href;\n this.pendingLink = null;\n this.currentLocation = clone(window.location);\n this.hooks = opts.hooks || {};\n this.uploaders = opts.uploaders || {};\n this.loaderTimeout = opts.loaderTimeout || LOADER_TIMEOUT;\n this.disconnectedTimeout = opts.disconnectedTimeout || DISCONNECTED_TIMEOUT;\n this.reloadWithJitterTimer = null;\n this.maxReloads = opts.maxReloads || MAX_RELOADS;\n this.reloadJitterMin = opts.reloadJitterMin || RELOAD_JITTER_MIN;\n this.reloadJitterMax = opts.reloadJitterMax || RELOAD_JITTER_MAX;\n this.failsafeJitter = opts.failsafeJitter || FAILSAFE_JITTER;\n this.localStorage = opts.localStorage || window.localStorage;\n this.sessionStorage = opts.sessionStorage || window.sessionStorage;\n this.boundTopLevelEvents = false;\n this.boundEventNames = /* @__PURE__ */ new Set();\n this.blockPhxChangeWhileComposing = opts.blockPhxChangeWhileComposing || false;\n this.serverCloseRef = null;\n this.domCallbacks = Object.assign(\n {\n jsQuerySelectorAll: null,\n onPatchStart: phoenix_live_view_esm_closure(),\n onPatchEnd: phoenix_live_view_esm_closure(),\n onNodeAdded: phoenix_live_view_esm_closure(),\n onBeforeElUpdated: phoenix_live_view_esm_closure()\n },\n opts.dom || {}\n );\n this.transitions = new TransitionSet();\n this.currentHistoryPosition = parseInt(this.sessionStorage.getItem(PHX_LV_HISTORY_POSITION) || "0") || 0;\n window.addEventListener("pagehide", (_e) => {\n this.unloaded = true;\n });\n this.socket.onOpen(() =>
1 {\n if (this.isUnloaded()) {\n window.location.reload();\n }\n });\n }\n // public\n /**\n * Returns the version of the LiveView client.\n */\n version() {\n return "1.2.6";\n }\n /**\n * Returns true if profiling is enabled. See {@link enableProfiling} and {@link disableProfiling}.\n */\n isProfileEnabled() {\n return this.sessionStorage.getItem(PHX_LV_PROFILE) === "true";\n }\n /**\n * Returns true if debugging is enabled. See {@link enableDebug} and {@link disableDebug}.\n */\n isDebugEnabled() {\n return this.sessionStorage.getItem(PHX_LV_DEBUG) === "true";\n }\n /**\n * Returns true if debugging is disabled. See {@link enableDebug} and {@link disableDebug}.\n */\n isDebugDisabled() {\n return this.sessionStorage.getItem(PHX_LV_DEBUG) === "false";\n }\n /**\n * Enables debugging.\n *\n * When debugging is enabled, the LiveView client will log debug information to the console.\n * See [Debugging client events](https://phoenix-live-view.hexdocs.pm/js-interop.html#debugging-client-events) for more information.\n */\n enableDebug() {\n this.sessionStorage.setItem(PHX_LV_DEBUG, "true");\n }\n /**\n * Enables profiling.\n *\n * When profiling is enabled, the LiveView client will log profiling information to the console.\n */\n enableProfiling() {\n this.sessionStorage.setItem(PHX_LV_PROFILE, "true");\n }\n /**\n * Disables debugging.\n */\n disableDebug() {\n this.sessionStorage.setItem(PHX_LV_DEBUG, "false");\n }\n /**\n * Disables profiling.\n */\n disableProfiling() {\n this.sessionStorage.removeItem(PHX_LV_PROFILE);\n }\n /**\n * Enables latency simulation.\n *\n * When latency simulation is enabled, the LiveView client will add a delay to requests and responses from the server.\n * See [Simulating Latency](https://phoenix-live-view.hexdocs.pm/js-interop.html#simulating-latency) for more information.\n */\n enableLatencySim(upperBoundMs) {\n this.enableDebug();\n console.log(\n "latency simulator enabled for the duration of this browser session. Call disableLatencySim() to disable"\n );\n this.sessionStorage.setItem(PHX_LV_LATENCY_SIM, upperBoundMs.toString());\n }\n /**\n * Disables latency simulation.\n */\n disableLatencySim() {\n this.sessionStorage.removeItem(PHX_LV_LATENCY_SIM);\n }\n /**\n * Returns the current latency simulation upper bound.\n */\n getLatencySim() {\n const str = this.sessionStorage.getItem(PHX_LV_LATENCY_SIM);\n return str ? parseInt(str) : null;\n }\n /**\n * Returns the Phoenix Socket instance.\n */\n getSocket() {\n return this.socket;\n }\n /**\n * Connects to the LiveView server.\n */\n connect() {\n if (window.location.hostname === "localhost" && !this.isDebugDisabled()) {\n this.enableDebug();\n }\n const doConnect = () => {\n this.resetReloadStatus();\n if (this.joinRootViews()) {\n this.bindTopLevelEvents();\n this.socket.connect();\n } else if (this.main) {\n this.socket.connect();\n } else {\n this.bindTopLevelEvents({ dead: true });\n }\n this.joinDeadView();\n };\n if (["complete", "loaded", "interactive"].indexOf(document.readyState) >= 0) {\n doConnect();\n } else {\n document.addEventListener("DOMContentLoaded", () => doConnect());\n }\n }\n /**\n * Disconnects from the LiveView server.\n */\n disconnect(callback) {\n this.reloadWithJitterTimer != null && clearTimeout(this.reloadWithJitterTimer);\n if (this.serverCloseRef) {\n this.socket.off([this.serverCloseRef]);\n this.serverCloseRef = null;\n }\n this.socket.disconnect(callback);\n }\n /**\n * Can be used to replace the transport used by the underlying Phoenix Socket.\n */\n replaceTransport(transport) {\n this.reloadWithJitterTimer != null && clearTimeout(this.reloadWithJitterTimer);\n this.socket.replaceTransport(transport);\n this.connect();\n }\n /**\n * Executes an encoded JS command, targeting the given element.\n *\n * See [`Phoenix.LiveView.JS`](https://phoenix-live-view.hexdocs.pm/Phoenix.LiveView.JS.html) for more information.\n */\n execJS(el, encodedJS, eventType = null) {\n const e = new CustomEvent("phx:exec", { detail: { sourceElement: el } });\n this.owner(el, (view) => js_default.exec(e, eventType, encodedJS, view, el));\n }\n /**\n * Returns an object with methods to manipulate the DOM and execute JavaScript.\n * The applied changes integrate with server DOM patching.\n *\n * See [JavaScript interoperability](https://phoenix-live-view.hexdocs.pm/js-interop.html) for more information.\n */\n js() {\n return js_commands_default(this, "js");\n }\n // private\n /** @internal */\n unload() {\n if (this.unloaded) {\n return;\n }\n if (this.main && this.isConnected()) {\n this.log(this.main, "socket", () => ["disconnect for page nav"]);\n }\n this.unloaded = true;\n this.destroyAllViews();\n this.disconnect();\n }\n /** @internal */\n triggerDOM(kind, args) {\n this.domCallbacks[kind](...args);\n }\n /** @internal */\n time(name, func) {\n if (!this.isProfileEnabled() || !console.time) {\n return func();\n }\n console.time(name);\n const result = func();\n console.timeEnd(name);\n return result;\n }\n /** @internal */\n log(view, kind, msgCallback) {\n if (this.viewLogger) {\n const [msg, obj] = msgCallback();\n this.viewLogger(view, kind, msg, obj);\n } else if (this.isDebugEnabled()) {\n const [msg, obj] = msgCallback();\n debug(view, kind, msg, obj);\n }\n }\n /** @internal */\n requestDOMUpdate(callback) {\n this.transitions.after(callback);\n }\n /** @internal */\n asyncTransition(promise) {\n this.transitions.addAsyncTransition(promise);\n }\n /** @internal */\n transition(time, onStart, onDone = function() {\
1n }) {\n this.transitions.addTransition(time, onStart, onDone);\n }\n /** @internal */\n onChannel(channel, event, cb) {\n channel.on(event, (data) => {\n const latency = this.getLatencySim();\n if (!latency) {\n cb(data);\n } else {\n setTimeout(() => cb(data), latency);\n }\n });\n }\n /** @internal */\n reloadWithJitter(view, log) {\n this.reloadWithJitterTimer != null && clearTimeout(this.reloadWithJitterTimer);\n this.disconnect();\n const minMs = this.reloadJitterMin;\n const maxMs = this.reloadJitterMax;\n let afterMs = Math.floor(Math.random() * (maxMs - minMs + 1)) + minMs;\n const tries = browser_default.updateLocal(\n this.localStorage,\n window.location.pathname,\n CONSECUTIVE_RELOADS,\n 0,\n (count) => count + 1\n );\n if (tries >= this.maxReloads) {\n afterMs = this.failsafeJitter;\n }\n this.reloadWithJitterTimer = setTimeout(() => {\n if (view.isDestroyed() || view.isConnected()) {\n return;\n }\n view.destroy();\n log ? log() : this.log(view, "join", () => [\n `encountered ${tries} consecutive reloads`\n ]);\n if (tries >= this.maxReloads) {\n this.log(view, "join", () => [\n `exceeded ${this.maxReloads} consecutive reloads. Entering failsafe mode`\n ]);\n }\n if (this.pendingLink !== null) {\n window.location.href = this.pendingLink;\n } else {\n window.location.reload();\n }\n }, afterMs);\n }\n /** @internal */\n getHookDefinition(name) {\n if (!name) {\n return;\n }\n return this.maybeInternalHook(name) || this.hooks[name] || this.maybeRuntimeHook(name);\n }\n /** @internal */\n maybeInternalHook(name) {\n return name && name.startsWith("Phoenix.") && hooks_default[name.split(".")[1]];\n }\n /** @internal */\n maybeRuntimeHook(name) {\n const runtimeHook = document.querySelector(\n `script[${PHX_RUNTIME_HOOK}="${CSS.escape(name)}"]`\n );\n if (!runtimeHook) {\n return;\n }\n let callbacks = window[`phx_hook_${name}`];\n if (!callbacks || typeof callbacks !== "function") {\n logError("a runtime hook must be a function", runtimeHook);\n return;\n }\n const hookDefiniton = callbacks();\n if (hookDefiniton && (typeof hookDefiniton === "object" || typeof hookDefiniton === "function")) {\n return hookDefiniton;\n }\n logError(\n "runtime hook must return an object with hook callbacks or an instance of ViewHook",\n runtimeHook\n );\n }\n /** @internal */\n isUnloaded() {\n return this.unloaded;\n }\n /** @internal */\n isConnected() {\n return this.socket.isConnected();\n }\n /** @internal */\n getBindingPrefix() {\n return this.bindingPrefix;\n }\n /** @internal */\n binding(kind) {\n return `${this.getBindingPrefix()}${kind}`;\n }\n /** @internal */\n channel(topic, params) {\n return this.socket.channel(topic, params);\n }\n /** @internal */\n joinDeadView() {\n const body = document.body;\n if (body && !this.isPhxView(body) && !this.isPhxView(document.firstElementChild)) {\n const view = this.newRootView(body);\n view.setHref(this.getHref());\n view.joinDead();\n if (!this.main) {\n this.main = view;\n }\n window.requestAnimationFrame(() => {\n view.execNewMounted();\n this.maybeScroll(history.state?.scroll);\n });\n }\n }\n /** @internal */\n joinRootViews() {\n let rootsFound = false;\n dom_default.all(\n document,\n `${PHX_VIEW_SELECTOR}:not([${PHX_PARENT_ID}])`,\n (rootEl) => {\n if (!this.getRootById(rootEl.id)) {\n const view = this.newRootView(rootEl);\n if (!dom_default.isPhxSticky(rootEl)) {\n view.setHref(this.getHref());\n }\n view.join();\n if (rootEl.hasAttribute(PHX_MAIN)) {\n this.main = view;\n }\n }\n rootsFound = true;\n }\n );\n return rootsFound;\n }\n /** @internal */\n redirect(to, flash, reloadToken) {\n if (reloadToken) {\n browser_default.setCookie(PHX_RELOAD_STATUS, reloadToken, 60);\n }\n this.unload();\n browser_default.redirect(to, flash);\n }\n /** @internal */\n replaceMain(href, flash, callback = null, linkRef = this.setPendingLink(href)) {\n if (!this.main) {\n return;\n }\n const liveReferer = this.currentLocation.href;\n this.outgoingMainEl = this.outgoingMainEl || this.main.el;\n const stickies = dom_default.findPhxSticky(document) || [];\n const removeEls = dom_default.all(\n this.outgoingMainEl,\n `[${this.binding("remove")}]`\n ).filter((el) => !dom_default.isChildOfAny(el, stickies));\n const newMainEl = dom_default.cloneNode(this.outgoingMainEl, "");\n const oldMainView = this.main;\n oldMainView.showLoader(this.loaderTimeout);\n oldMainView.destroy();\n this.main = this.newRootView(newMainEl, flash, liveReferer);\n this.main.setRedirect(href);\n this.transitionRemoves(removeEls, oldMainView);\n this.main.join((joinCount, onDone) => {\n if (joinCount === 1 && this.commitPendingLink(linkRef)) {\n this.requestDOMUpdate(() =>
1 {\n removeEls.forEach((el) => el.remove());\n stickies.forEach((el) => newMainEl.appendChild(el));\n this.outgoingMainEl.replaceWith(newMainEl);\n this.outgoingMainEl = null;\n callback && callback(linkRef);\n onDone();\n });\n }\n });\n }\n /** @internal */\n transitionRemoves(elements, view, callback) {\n const removeAttr = this.binding("remove");\n const silenceEvents = (e) => {\n e.preventDefault();\n e.stopImmediatePropagation();\n };\n elements.forEach((el) => {\n for (const event of this.boundEventNames) {\n el.addEventListener(event, silenceEvents, true);\n }\n const e = new CustomEvent("phx:exec", { detail: { sourceElement: el } });\n js_default.exec(e, "remove", el.getAttribute(removeAttr), view, el);\n });\n this.requestDOMUpdate(() => {\n elements.forEach((el) => {\n for (const event of this.boundEventNames) {\n el.removeEventListener(event, silenceEvents, true);\n }\n });\n callback && callback();\n });\n }\n /** @internal */\n isPhxView(el) {\n return el.getAttribute && el.getAttribute(PHX_SESSION) !== null;\n }\n /** @internal */\n newRootView(el, flash, liveReferer) {\n const view = new View(el, this, null, flash, liveReferer);\n this.roots[view.id] = view;\n return view;\n }\n /** @internal */\n owner(childEl, callback) {\n let view;\n const viewEl = dom_default.closestViewEl(childEl);\n if (viewEl) {\n view = dom_default.private(viewEl, "view");\n } else {\n if (!childEl.isConnected) {\n return null;\n }\n view = this.main;\n }\n return view && callback ? callback(view) : view;\n }\n /** @internal */\n withinOwners(childEl, callback) {\n this.owner(childEl, (view) => callback(view, childEl));\n }\n /** @internal */\n getViewByEl(el) {\n const rootId = el.getAttribute(PHX_ROOT_ID);\n return maybe(\n this.getRootById(rootId),\n (root) => root.getDescendentByEl(el)\n );\n }\n /** @internal */\n getRootById(id) {\n return this.roots[id];\n }\n /** @internal */\n destroyAllViews() {\n for (const id in this.roots) {\n this.roots[id].destroy();\n delete this.roots[id];\n }\n this.main = null;\n }\n /** @internal */\n destroyViewByEl(el) {\n const root = this.getRootById(el.getAttribute(PHX_ROOT_ID));\n if (root && root.id === el.id) {\n root.destroy();\n delete this.roots[root.id];\n } else if (root) {\n root.destroyDescendent(el.id);\n }\n }\n /** @internal */\n getActiveElement() {\n return document.activeElement;\n }\n /** @internal */\n dropActiveElement(view) {\n if (this.prevActive && view.ownsElement(this.prevActive)) {\n this.prevActive = null;\n }\n }\n /** @internal */\n restorePreviouslyActiveFocus() {\n if (this.prevActive && this.prevActive !== document.body && this.prevActive instanceof HTMLElement) {\n this.prevActive.focus();\n }\n }\n /** @internal */\n blurActiveElement() {\n this.prevActive = this.getActiveElement();\n if (this.prevActive !== document.body && this.prevActive instanceof HTMLElement) {\n this.prevActive.blur();\n }\n }\n /** @internal */\n bindTopLevelEvents({ dead } = {}) {\n if (this.boundTopLevelEvents) {\n return;\n }\n this.boundTopLevelEvents = true;\n this.serverCloseRef = this.socket.onClose((event) => {\n if (event && event.code === 1e3 && this.main) {\n return this.reloadWithJitter(this.main);\n }\n });\n document.body.addEventListener("click", function() {\n });\n window.addEventListener(\n "pageshow",\n (e) =>
1 {\n if (e.persisted) {\n this.getSocket().disconnect();\n this.withPageLoading({ to: window.location.href, kind: "redirect" });\n window.location.reload();\n }\n },\n true\n );\n if (!dead) {\n this.bindNav();\n }\n this.bindClicks();\n if (!dead) {\n this.bindForms();\n }\n this.bind(\n { keyup: "keyup", keydown: "keydown" },\n (e, type, view, targetEl, phxEvent, _phxTarget) => {\n const matchKey = targetEl.getAttribute(this.binding(PHX_KEY));\n const pressedKey = e.key && e.key.toLowerCase();\n if (matchKey && matchKey.toLowerCase() !== pressedKey) {\n return;\n }\n const data = { key: e.key, ...this.eventMeta(type, e, targetEl) };\n js_default.exec(e, type, phxEvent, view, targetEl, ["push", { data }]);\n }\n );\n this.bind(\n { blur: "focusout", focus: "focusin" },\n (e, type, view, targetEl, phxEvent, phxTarget) => {\n if (!phxTarget) {\n const data = { ...this.eventMeta(type, e, targetEl) };\n js_default.exec(e, type, phxEvent, view, targetEl, ["push", { data }]);\n }\n }\n );\n this.bind(\n { blur: "blur", focus: "focus" },\n (e, type, view, targetEl, phxEvent, phxTarget) => {\n if (phxTarget === "window") {\n const data = this.eventMeta(type, e, targetEl);\n js_default.exec(e, type, phxEvent, view, targetEl, ["push", { data }]);\n }\n }\n );\n this.on("dragover", (e) => e.preventDefault());\n this.on("dragenter", (e) => {\n let target = e.target && dom_default.elementFromTarget(e.target);\n if (!target) {\n return;\n }\n const dropzone = closestPhxBinding(target, this.binding(PHX_DROP_TARGET));\n if (!dropzone || !(dropzone instanceof HTMLElement)) {\n return;\n }\n if (eventContainsFiles(e)) {\n this.js().addClass(dropzone, PHX_DROP_TARGET_ACTIVE_CLASS);\n }\n });\n this.on("dragleave", (e) => {\n let target = e.target && dom_default.elementFromTarget(e.target);\n if (!target) {\n return;\n }\n const dropzone = closestPhxBinding(target, this.binding(PHX_DROP_TARGET));\n if (!dropzone || !(dropzone instanceof HTMLElement)) {\n return;\n }\n const rect = dropzone.getBoundingClientRect();\n if (e.clientX <= rect.left || e.clientX >= rect.right || e.clientY <= rect.top || e.clientY >= rect.bottom) {\n this.js().removeClass(dropzone, PHX_DROP_TARGET_ACTIVE_CLASS);\n }\n });\n this.on("drop", (e) => {\n let target = e.target && dom_default.elementFromTarget(e.target);\n if (!target) {\n return;\n }\n e.preventDefault();\n const dropzone = closestPhxBinding(target, this.binding(PHX_DROP_TARGET));\n if (!dropzone || !(dropzone instanceof HTMLElement)) {\n return;\n }\n this.js().removeClass(dropzone, PHX_DROP_TARGET_ACTIVE_CLASS);\n if (!e.dataTransfer) {\n return;\n }\n const dropTargetId = dropzone.getAttribute(this.binding(PHX_DROP_TARGET));\n const dropTarget = dropTargetId && document.getElementById(dropTargetId);\n const files = Array.from(e.dataTransfer.files || []);\n if (!dropTarget || !(dropTarget instanceof HTMLInputElement) || dropTarget.disabled || files.length === 0 || !(dropTarget.files instanceof FileList)) {\n return;\n }\n LiveUploader.trackFiles(dropTarget, files, e.dataTransfer);\n dropTarget.dispatchEvent(new Event("input", { bubbles: true }));\n });\n this.on(PHX_TRACK_UPLOADS, (e) => {\n const uploadTarget = e.target && dom_default.elementFromTarget(e.target);\n if (!dom_default.isUploadInput(uploadTarget)) {\n return;\n }\n const files = Array.from(e.detail.files || []).filter(\n (f) => f instanceof File || f instanceof Blob\n );\n LiveUploader.trackFiles(uploadTarget, files);\n uploadTarget.dispatchEvent(new Event("input", { bubbles: true }));\n });\n }\n /** @internal */\n eventMeta(eventName, e, targetEl) {\n const callback = this.metadataCallbacks[eventName];\n return callback ? callback(e, targetEl) : {};\n }\n /** @internal */\n setPendingLink(href) {\n this.linkRef++;\n this.pendingLink = href;\n this.resetReloadStatus();\n return this.linkRef;\n }\n /**\n * @internal\n * anytime we are navigating or connecting, drop reload cookie in case\n * we issue the cookie but the next request was interrupted and the server never dropped it\n */\n resetReloadStatus() {\n browser_default.deleteCookie(PHX_RELOAD_STATUS);\n }\n /** @internal */\n commitPendingLink(linkRef) {\n if (this.linkRef !== linkRef) {\n return false;\n }\n if (this.pendingLink !== null) {\n this.href = this.pendingLink;\n this.pendingLink = null;\n }\n return true;\n }\n /** @internal */\n getHref() {\n return this.href;\n }
1\n /** @internal */\n hasPendingLink() {\n return !!this.pendingLink;\n }\n /** @internal */\n bind(events, callback) {\n for (const event in events) {\n const browserEventName = events[event];\n this.on(browserEventName, (e) => {\n const binding = this.binding(event);\n const windowBinding = this.binding(`window-${event}`);\n const targetPhxEvent = e.target instanceof Element && e.target.getAttribute(binding);\n if (!(e.target instanceof Element)) {\n return;\n }\n if (targetPhxEvent) {\n this.debounce(e.target, e, browserEventName, () => {\n this.withinOwners(e.target, (view) => {\n callback(\n e,\n event,\n view,\n e.target,\n targetPhxEvent,\n null\n );\n });\n });\n } else {\n dom_default.all(document, `[${windowBinding}]`, (el) => {\n const phxEvent = el.getAttribute(windowBinding);\n this.debounce(el, e, browserEventName, () => {\n this.withinOwners(el, (view) => {\n callback(\n e,\n event,\n view,\n el,\n phxEvent,\n "window"\n );\n });\n });\n });\n }\n });\n }\n }\n /** @internal */\n bindClicks() {\n this.on("mousedown", (e) => this.clickStartedAtTarget = e.target);\n this.bindClick();\n }\n /** @internal */\n bindClick() {\n const click = this.binding("click");\n window.addEventListener(\n "click",\n (e) => {\n let target = e.target && dom_default.elementFromTarget(e.target);\n if (!target) {\n return;\n }\n if (e.detail === 0)\n this.clickStartedAtTarget = target;\n const clickStartedAtTarget = this.clickStartedAtTarget || target;\n target = closestPhxBinding(target, click);\n this.dispatchClickAway(e, clickStartedAtTarget);\n this.clickStartedAtTarget = null;\n if (!target) {\n return;\n }\n const phxEvent = target.getAttribute(click);\n if (!phxEvent) {\n if (dom_default.isNewPageClick(e, window.location)) {\n this.unload();\n }\n return;\n }\n if (target.getAttribute("href") === "#") {\n e.preventDefault();\n }\n if (target.hasAttribute(PHX_REF_SRC)) {\n return;\n }\n this.debounce(target, e, "click", () => {\n this.withinOwners(target, (view) => {\n js_default.exec(e, "click", phxEvent, view, target, [\n "push",\n { data: this.eventMeta("click", e, target) }\n ]);\n });\n });\n },\n false\n );\n }\n /** @internal */\n dispatchClickAway(e, clickStartedAt) {\n const phxClickAway = this.binding("click-away");\n const portal = clickStartedAt.closest(`[${PHX_TELEPORTED_SRC}]`);\n const portalStartedAt = portal && dom_default.byId(portal.getAttribute(PHX_TELEPORTED_SRC));\n dom_default.all(document, `[${phxClickAway}]`, (el) => {\n let startedAt = clickStartedAt;\n if (portal && !portal.contains(el)) {\n startedAt = portalStartedAt;\n }\n if (!(el.isSameNode(startedAt) || el.contains(startedAt) || // When clicking a link with custom method,\n // phoenix_html triggers a click on a submit button\n // of a hidden form appended to the body. For such cases\n // where the clicked target is hidden, we skip click-away.\n //\n // Also, when we have a portal, we don\'t want to check the visibility\n // of the portal source, as it\'s a <template> that is always not visible.\n // Instead, check the visibility of the original click target.\n !js_default.isVisible(clickStartedAt))) {\n this.withinOwners(el, (view) => {\n const phxEvent = el.getAttribute(phxClickAway);\n if (js_default.isVisible(el) && js_default.isInViewport(el)) {\
1n js_default.exec(e, "click", phxEvent, view, el, [\n "push",\n { data: this.eventMeta("click", e, e.target) }\n ]);\n }\n });\n }\n });\n }\n /** @internal */\n bindNav() {\n if (!browser_default.canPushState()) {\n return;\n }\n if (history.scrollRestoration) {\n history.scrollRestoration = "manual";\n }\n let scrollTimer = null;\n window.addEventListener("scroll", (_e) => {\n scrollTimer != null && clearTimeout(scrollTimer);\n scrollTimer = setTimeout(() => {\n browser_default.updateCurrentState(\n (state) => Object.assign(state, { scroll: window.scrollY })\n );\n }, 100);\n });\n window.addEventListener(\n "popstate",\n (event) => {\n if (!this.registerNewLocation(window.location)) {\n return;\n }\n const { type, backType, id, scroll, position } = event.state || {};\n const href = window.location.href;\n const isForward = position > this.currentHistoryPosition;\n const navType = isForward ? type : backType || type;\n this.currentHistoryPosition = position || 0;\n this.sessionStorage.setItem(\n PHX_LV_HISTORY_POSITION,\n this.currentHistoryPosition.toString()\n );\n dom_default.dispatchEvent(window, "phx:navigate", {\n detail: {\n href,\n patch: navType === "patch",\n pop: true,\n direction: isForward ? "forward" : "backward"\n }\n });\n this.requestDOMUpdate(() => {\n const callback = () => {\n this.maybeScroll(scroll);\n };\n if (this.main && this.main.isConnected() && navType === "patch" && id === this.main.id) {\n this.main.pushLinkPatch(event, href, null, callback);\n } else {\n this.replaceMain(href, null, callback);\n }\n });\n },\n false\n );\n window.addEventListener(\n "click",\n (e) => {\n let el = e.target && dom_default.elementFromTarget(e.target);\n if (!el) {\n return;\n }\n const target = closestPhxBinding(\n el,\n PHX_LIVE_LINK\n );\n const type = target && target.getAttribute(PHX_LIVE_LINK);\n if (!type || !this.isConnected() || !this.main || dom_default.wantsNewTab(e)) {\n return;\n }\n const href = target.href instanceof SVGAnimatedString ? target.href.baseVal : target.href;\n const linkState = target.getAttribute(PHX_LINK_STATE);\n if (linkState !== "replace" && linkState !== "push") {\n throw new Error(\n `expected ${PHX_LINK_STATE} to be "replace" or "push", got: ${linkState}`\n );\n }\n e.preventDefault();\n e.stopImmediatePropagation();\n if (this.pendingLink === href) {\n return;\n }\n this.requestDOMUpdate(() => {\n if (type === "patch") {\n this.pushHistoryPatch(e, href, linkState, target);\n } else if (type === "redirect") {\n this.historyRedirect(e, href, linkState, null, target);\n } else {\n throw new Error(\n `expected ${PHX_LIVE_LINK} to be "patch" or "redirect", got: ${type}`\n );\n }\n const phxClick = target.getAttribute(this.binding("click"));\n if (phxClick) {\n this.requestDOMUpdate(() => this.execJS(target, phxClick, "click"));\n }\n });\n },\n false\n );\n }\n /** @internal */\n maybeScroll(scroll) {\n if (typeof scroll === "number") {\n requestAnimationFrame(() => {\n window.scrollTo(0, scroll);\n });\n }\n }\n /** @internal */\n dispatchEvent(event, payload = {}) {\n dom_default.dispatchEvent(window, `phx:${event}`, { detail: payload });\n }\n /** @internal */\n dispatchEvents(events) {\n events.forEach(([event, payload]) => this.dispatchEvent(event, payload));\n }\n /** @internal */\n withPageLoading(info, callback) {\n dom_default.dispatchEvent(window, "phx:page-loading-start", { detail: info });\n const done = () => dom_default.dispatchEvent(window, "phx:page-loading-stop", { detail: info });\n return callback ? callback(done) : done;\n }\n /** @internal */\n pushHistoryPatch(e, href, linkState, targetEl) {\n if (!this.isConnected() || !(this.main && this.main.isMain())) {\n return browser_default.redirect(href);\n }\n this.withPageLoading({ to: href, kind: "patch" }, (done) => {\n this.main.pushLinkPatch(e, href, targetEl, (linkRef) => {\n this.historyPatch(href, linkState, linkRef);\n done();\n });\n });\n }\n /** @internal */\n historyPatch(href, linkState, linkRef = this.setPendingLink(href)) {\n if (!this.commitPendingLink(linkRef)) {\n return;\n }\n this.currentHistoryPosition++;\n this.sessionStorage.setItem(\n PHX_LV_HISTORY_POSITION,\n this.currentHistoryPosition.toString()\n );\n browser_default.updateCurrentState((state) => ({ ...state, backType: "patch" }));\n browser_default.pushState(\n linkState,\n {\n type: "patch",\n id: this.main.id,\n position: this.currentHistoryPosition\n },\n href\n );\n dom_default.dispatchEvent(window, "phx:navigate", {\n detail: { patch: true, href, pop: false, direction: "forward" }\n });\n this.registerNewLocation(window.location);\n }\n /** @internal */\n historyRedirect(e, href, linkState, flash, targetEl) {\n const clickLoading = targetEl && e.isTrusted && e.type !== "popstate";\n if (clickLoading) {\n targetEl.classList.add("phx-click-loading");\n }\n if (!this.isConnected() || !(this.main && this.main.isMain())) {\n return browser_default.redirect(href, flash);\n }\n if (/^\\/$|^\\/[^\\/]+.*$/.test(href)) {\n const { protocol, host } = window.location;\n href = `${protocol}//${host}${href}`;\n }\n const scroll = window.scrollY;\n this.withPageLoading({ to: href, kind: "redirect" }, (done) => {\n this.replaceMain(href, flash, (linkRef) => {\n if (linkRef === this.linkRef) {\n this.currentHistoryPosition++;\n this.sessionStorage.setItem(\n PHX_LV_HISTORY_POSITION,\n this.currentHistoryPosition.toString()\n );\n browser_default.updateCurrentState((state) => ({\n ...state,\n backType: "redirect"\n }));\n browser_default.pushState(\n linkState,\n {\n type: "redirect",\n id: this.main.id,\n scroll,\n position: this.currentHistoryPosition\n },\n href\n );\n dom_default.dispatchEvent(window, "phx:navigate", {\n detail: { href, patch: false, pop: false, direction: "forward" }\n });\n this.registerNewLocation(window.location);\n }\n if (clickLoading) {\n targetEl.classList.remove("phx-click-loading");\n }\n done();\n });\n });\n }\n /** @internal */\n registerNewLocation(newLocation) {\n const { pathname, search } = this.currentLocation;\n if (pathname + search === newLocation.pathname + newLocation.search) {\n return false;\n } else {\n this.currentLocation = clone(newLocation);\n return true;\n }\n }\n /** @internal */\n bindForms() {\n let iterations = 0;\n let externalFormSubmitted = false;\n this.on("submit", (e) => {\n if (!(e.target instanceof HTMLFormElement))\n return;\n const phxSubmit = e.target.getAttribute(this.binding("submit"));\n const phxChange = e.target.getAttribute(this.binding("change"));\n if (!externalFormSubmitted && phxChange && !phxSubmit) {\n externalFormSubmitted = true;\n e.preventDefault();\n this.withinOwners(e.target, (view) => {\n view.disableForm(e.target);\n window.requestAnimationFrame(() =>
1 {\n if (dom_default.isUnloadableFormSubmit(e)) {\n this.unload();\n }\n e.target.submit();\n });\n });\n }\n });\n this.on("submit", (e) => {\n if (!(e.target instanceof HTMLFormElement))\n return;\n const phxEvent = e.target.getAttribute(this.binding("submit"));\n if (!phxEvent) {\n if (dom_default.isUnloadableFormSubmit(e)) {\n this.unload();\n }\n return;\n }\n e.preventDefault();\n e.target.disabled = true;\n this.withinOwners(e.target, (view) => {\n js_default.exec(e, "submit", phxEvent, view, e.target, [\n "push",\n { submitter: e.submitter }\n ]);\n });\n });\n for (const type of ["change", "input"]) {\n this.on(type, (e) => {\n if (!dom_default.isFormAssociated(e.target)) {\n return;\n }\n if (e instanceof CustomEvent && e.target.form === void 0) {\n if (e.detail && e.detail.dispatcher) {\n throw new Error(\n `dispatching a custom ${type} event is only supported on input elements inside a form`\n );\n }\n return;\n }\n const input = e.target;\n const phxChange = this.binding("change");\n if (this.blockPhxChangeWhileComposing && e instanceof InputEvent && e.isComposing) {\n const key = `composition-listener-${type}`;\n if (!dom_default.private(input, key)) {\n dom_default.putPrivate(input, key, true);\n input.addEventListener(\n "compositionend",\n () => {\n input.dispatchEvent(new Event(type, { bubbles: true }));\n dom_default.deletePrivate(input, key);\n },\n { once: true }\n );\n }\n return;\n }\n const inputEvent = input.getAttribute(phxChange);\n const formEvent = input.form && input.form.getAttribute(phxChange);\n const phxEvent = inputEvent || formEvent;\n if (!phxEvent) {\n return;\n }\n if (input.type === "number" && input.validity && input.validity.badInput) {\n return;\n }\n const dispatcher = inputEvent ? input : input.form;\n const currentIterations = iterations;\n iterations++;\n const { at, type: lastType } = dom_default.private(input, "prev-iteration") || {};\n if (at === currentIterations - 1 && type === "change" && lastType === "input") {\n return;\n }\n dom_default.putPrivate(input, "prev-iteration", {\n at: currentIterations,\n type\n });\n this.debounce(input, e, type, () => {\n this.withinOwners(dispatcher, (view) => {\n dom_default.putPrivate(input, PHX_HAS_FOCUSED, true);\n js_default.exec(e, "change", phxEvent, view, input, [\n "push",\n { _target: input.name, dispatcher }\n ]);\n });\n });\n });\n }\n this.on("reset", (e) => {\n const form = e.target;\n dom_default.resetForm(form);\n const input = Array.from(form.elements).find(\n (el) => "type" in el && el.type === "reset"\n );\n if (input) {\n window.requestAnimationFrame(() => {\n input.dispatchEvent(\n new Event("input", { bubbles: true, cancelable: false })\n );\n });\n }\n });\n }\n /** @internal */\n debounce(el, event, eventType, callback) {\n if (eventType === "blur" || eventType === "focusout") {\n return callback();\n }\n const phxDebounce = this.binding(PHX_DEBOUNCE);\n const phxThrottle = this.binding(PHX_THROTTLE);\n const defaultDebounce = this.defaults.debounce.toString();\n const defaultThrottle = this.defaults.throttle.toString();\n this.withinOwners(el, (view) => {\n const asyncFilter = () => !view.isDestroyed() && document.body.contains(el);\n dom_default.debounce(\n el,\n event,\n phxDebounce,\n defaultDebounce,\n phxThrottle,\n defaultThrottle,\n asyncFilter,\n () => {\n callback();\n }\n );\n });\n }\n /** @internal */\n silenceEvents(callback) {\n this.silenced = true;\n callback();\n this.silenced = false;\n }\n /** @internal */\n on(event, callback) {\n this.boundEventNames.add(event);\n window.addEventListener(event, (e) => {\n if (!this.silenced) {\n callback(e);\n }\n });\n }\n /** @internal */\n jsQuerySelectorAll(sourceEl, query, defaultQuery) {\n const all = this.domCallbacks.jsQuerySelectorAll;\n return all ? all(sourceEl, query, defaultQuery) : defaultQuery();\n }\n};\nvar TransitionSet = class {\n constructor() {\n this.transitions = /* @__PURE__ */ new Set();\n this.promises = /* @__PURE__ */ new Set();\n this.pendingOps = [];\n }\n reset() {\n this.transitions.forEach((timer) => {\n clearTimeout(timer);\n this.transitions.delete(timer);\n });\n this.promises.clear();\n this.flushPendingOps();\n }\n after(callback) {\n if (this.size() === 0) {\n callback();\n } else {\n this.pushPendingOp(callback);\n }\n }\n addTransition(time, onStart, onDone) {\n onStart();\n const timer = setTimeout(() =>
1 {\n this.transitions.delete(timer);\n onDone();\n this.flushPendingOps();\n }, time);\n this.transitions.add(timer);\n }\n addAsyncTransition(promise) {\n this.promises.add(promise);\n promise.then(() => {\n this.promises.delete(promise);\n this.flushPendingOps();\n });\n }\n pushPendingOp(op) {\n this.pendingOps.push(op);\n }\n size() {\n return this.transitions.size + this.promises.size;\n }\n flushPendingOps() {\n if (this.size() > 0) {\n return;\n }\n const op = this.pendingOps.shift();\n if (op) {\n op();\n this.flushPendingOps();\n }\n }\n};\n\n// js/phoenix_live_view/index.ts\nfunction createHook(el, callbacks) {\n let existingHook = dom_default.getCustomElHook(el);\n if (existingHook) {\n return existingHook;\n }\n if (!el.hasAttribute("id")) {\n logError(\n "Elements passed to createHook need to have a unique id attribute",\n el\n );\n }\n let hook = new ViewHook(View.closestView(el), el, callbacks);\n dom_default.putCustomElHook(el, hook);\n return hook;\n}\nfunction getFileURLForUpload(input, uploadRef) {\n return LiveUploader.getEntryDataURL(input, uploadRef);\n}\n\n//# sourceMappingURL=phoenix_live_view.esm.js.map\n\n;// CONCATENATED MODULE: ../deps/live_select/priv/static/live_select.min.js\nfunction o(e, t) {\n let i;\n return (...s) => {\n clearTimeout(i), i = setTimeout(() => {\n e.apply(this, s);\n }, t);\n };\n}\n/* harmony default export */ const live_select_min = ({\n LiveSelect: {\n textInput() {\n return this.el.querySelector("input[type=text]");\n },\n debounceMsec() {\n return parseInt(this.el.dataset.debounce);\n },\n updateMinLen() {\n return parseInt(this.el.dataset.updateMinLen);\n },\n maybeStyleClearButtons() {\n const e = this.el.querySelector("button.ls-clear-button");\n e && (this.textInput().parentElement.style.position = "relative", this.textInput().parentElement.style.display = "flex", this.textInput().parentElement.style.alignItems = "center", e.style.minHeight = "20px", e.style.minWidth = "20px", e.style.position = "absolute", e.style.right = "5px", e.style.display = "block"), this.el.querySelectorAll("button.ls-clear-tag-button").forEach(t => {\n t.style.minHeight = "20px", t.style.minWidth = "20px";\n });\n },\n pushEventToParent(e, t) {\n const i = this.el.dataset.phxTarget;\n i ? this.pushEventTo(i, e, t) : this.pushEvent(e, t);\n },\n attachDomEventHandlers() {\n this.textInput().onkeydown = t => {\n t.code === "Enter" && t.preventDefault(), this.pushEventTo(this.el, "keydown", {\n key: t.code\n });\n }, this.changeEvents = o((t, i, s) => {\n this.pushEventTo(this.el, "change", {\n text: s\n }), this.pushEventToParent("live_select_change", {\n id: this.el.id,\n field: i,\n text: s\n });\n }, this.debounceMsec()), this.textInput().oninput = t => {\n const i = t.target.value.trim(),\n s = this.el.dataset.field;\n i.length >
1= this.updateMinLen() ? this.changeEvents(this.el.id, s, i) : this.pushEventTo(this.el, "options_clear", {});\n };\n const e = this.el.querySelector("ul");\n e && (e.onmousedown = t => {\n const i = t.target.closest("div[data-idx]");\n i && (this.pushEventTo(this.el, "option_click", {\n idx: i.dataset.idx\n }), t.preventDefault());\n }), this.el.querySelectorAll("button[data-idx]").forEach(t => {\n t.onclick = i => {\n this.pushEventTo(this.el, "option_remove", {\n idx: t.dataset.idx\n });\n };\n });\n },\n setInputValue(e) {\n this.textInput().value = e;\n },\n inputEvent(e, t) {\n const i = t === "single" ? "input.single-mode" : e.length === 0 ? "input[data-live-select-empty]" : "input[type=hidden]";\n this.el.querySelector(i).dispatchEvent(new Event("input", {\n bubbles: !0\n }));\n },\n mounted() {\n this.maybeStyleClearButtons(), this.handleEvent("select", ({\n id: e,\n selection: t,\n mode: i,\n current_text: s,\n input_event: l,\n parent_event: n\n }) => {\n this.el.id === e && (this.selection = t, s != null && this.setInputValue(s), l && this.inputEvent(t, i), n && this.pushEventToParent(n, {\n id: e\n }));\n }), this.handleEvent("scroll_to_option", ({\n id: e,\n idx: t\n }) => {\n if (this.el.id === e) {\n const i = this.el.querySelector(`div[data-idx="${t}"]`);\n i && i.scrollIntoView({\n block: "nearest",\n behavior: "instant",\n container: "nearest"\n });\n }\n }), this.attachDomEventHandlers();\n },\n updated() {\n this.maybeStyleClearButtons(), this.attachDomEventHandlers();\n },\n reconnected() {\n this.selection && this.selection.length > 0 && this.pushEventTo(this.el, "selection_recovery", this.selection);\n }\n }\n});\n;// CONCATENATED MODULE: ./node_modules/alpinejs/dist/module.esm.js\n// packages/alpinejs/src/scheduler.js\nvar flushPending = false;\nvar flushing = false;\nvar queue = [];\nvar lastFlushedIndex = -1;\nfunction scheduler(callback) {\n queueJob(callback);\n}\nfunction queueJob(job) {\n if (!queue.includes(job))\n queue.push(job);\n queueFlush();\n}\nfunction dequeueJob(job) {\n let index = queue.indexOf(job);\n if (index !== -1 && index > lastFlushedIndex)\n queue.splice(index, 1);\n}\nfunction queueFlush() {\n if (!flushing && !flushPending) {\n flushPending = true;\n queueMicrotask(flushJobs);\n }\n}\nfunction flushJobs() {\n flushPending = false;\n flushing = true;\n for (let i = 0; i < queue.length; i++) {\n queue[i]();\n lastFlushedIndex = i;\n }\n queue.length = 0;\n lastFlushedIndex = -1;\n flushing = false;\n}\n\n// packages/alpinejs/src/reactivity.js\nvar reactive;\nvar effect;\nvar release;\nvar raw;\nvar shouldSchedule = true;\nfunction disableEffectScheduling(callback) {\n shouldSchedule = false;\n callback();\n shouldSchedule = true;\n}\nfunction setReactivityEngine(engine) {\n reactive = engine.reactive;\n release = engine.release;\n effect = (callback) => engine.effect(callback, {scheduler: (task) => {\n if (shouldSchedule) {\n scheduler(task);\n } else {\n task();\n }\n }});\n raw = engine.raw;\n}\nfunction overrideEffect(override) {\n effect = override;\n}\nfunction elementBoundEffect(el) {\n let cleanup2 = () => {\n };\n let wrappedEffect = (callback) => {\n let effectReference = effect(callback);\n if (!el._x_effects) {\n el._x_effects = new Set();\n el._x_runEffects = () => {\n el._x_effects.forEach((i) => i());\n };\n }\n el._x_effects.add(effectReference);\n cleanup2 = () => {\n if (effectReference === void 0)\n return;\n el._x_effects.delete(effectReference);\n release(effectReference);\n };\n return effectReference;\n };\n return [wrappedEffect, () => {\n cleanup2();\n }];\n}\n\n// packages/alpinejs/src/mutation.js\nvar onAttributeAddeds = [];\nvar onElRemoveds = [];\nvar onElAddeds = [];\nfunction onElAdded(callback) {\n onElAddeds.push(callback);\n}\nfunction onElRemoved(el, callback) {\n if (typeof callback === "function") {\n if (!el._x_cleanups)\n el._x_cleanups = [];\n el._x_cleanups.push(callback);\n } else {\n callback = el;\n onElRemoveds.push(callback);\n }\n}\nfunction onAttributesAdded(callback) {\n onAttributeAddeds.push(callback);\n}\nfunction onAttributeRemoved(el, name, callback) {\n if (!el._x_attributeCleanups)\n el._x_attributeCleanups = {};\n if (!el._x_attributeCleanups[name])\n el._x_attributeCleanups[name] = [];\n el._x_attributeCleanups[name].push(callback);\n}\nfunction cleanupAttributes(el, names) {\n if (!el._x_attributeCleanups)\n return;
1\n Object.entries(el._x_attributeCleanups).forEach(([name, value]) => {\n if (names === void 0 || names.includes(name)) {\n value.forEach((i) => i());\n delete el._x_attributeCleanups[name];\n }\n });\n}\nvar observer = new MutationObserver(onMutate);\nvar currentlyObserving = false;\nfunction startObservingMutations() {\n observer.observe(document, {subtree: true, childList: true, attributes: true, attributeOldValue: true});\n currentlyObserving = true;\n}\nfunction stopObservingMutations() {\n flushObserver();\n observer.disconnect();\n currentlyObserving = false;\n}\nvar recordQueue = [];\nvar willProcessRecordQueue = false;\nfunction flushObserver() {\n recordQueue = recordQueue.concat(observer.takeRecords());\n if (recordQueue.length && !willProcessRecordQueue) {\n willProcessRecordQueue = true;\n queueMicrotask(() => {\n processRecordQueue();\n willProcessRecordQueue = false;\n });\n }\n}\nfunction processRecordQueue() {\n onMutate(recordQueue);\n recordQueue.length = 0;\n}\nfunction mutateDom(callback) {\n if (!currentlyObserving)\n return callback();\n stopObservingMutations();\n let result = callback();\n startObservingMutations();\n return result;\n}\nvar isCollecting = false;\nvar deferredMutations = [];\nfunction deferMutations() {\n isCollecting = true;\n}\nfunction flushAndStopDeferringMutations() {\n isCollecting = false;\n onMutate(deferredMutations);\n deferredMutations = [];\n}\nfunction onMutate(mutations) {\n if (isCollecting) {\n deferredMutations = deferredMutations.concat(mutations);\n return;\n }\n let addedNodes = [];\n let removedNodes = [];\n let addedAttributes = new Map();\n let removedAttributes = new Map();\n for (let i = 0; i < mutations.length; i++) {\n if (mutations[i].target._x_ignoreMutationObserver)\n continue;\n if (mutations[i].type === "childList") {\n mutations[i].addedNodes.forEach((node) => node.nodeType === 1 && addedNodes.push(node));\n mutations[i].removedNodes.forEach((node) => node.nodeType === 1 && removedNodes.push(node));\n }\n if (mutations[i].type === "attributes") {\n let el = mutations[i].target;\n let name = mutations[i].attributeName;\n let oldValue = mutations[i].oldValue;\n let add2 = () => {\n if (!addedAttributes.has(el))\n addedAttributes.set(el, []);\n addedAttributes.get(el).push({name, value: el.getAttribute(name)});\n };\n let remove = () => {\n if (!removedAttributes.has(el))\n removedAttributes.set(el, []);\n removedAttributes.get(el).push(name);\n };\n if (el.hasAttribute(name) && oldValue === null) {\n add2();\n }
1 else if (el.hasAttribute(name)) {\n remove();\n add2();\n } else {\n remove();\n }\n }\n }\n removedAttributes.forEach((attrs, el) => {\n cleanupAttributes(el, attrs);\n });\n addedAttributes.forEach((attrs, el) => {\n onAttributeAddeds.forEach((i) => i(el, attrs));\n });\n for (let node of removedNodes) {\n if (addedNodes.includes(node))\n continue;\n onElRemoveds.forEach((i) => i(node));\n if (node._x_cleanups) {\n while (node._x_cleanups.length)\n node._x_cleanups.pop()();\n }\n }\n addedNodes.forEach((node) => {\n node._x_ignoreSelf = true;\n node._x_ignore = true;\n });\n for (let node of addedNodes) {\n if (removedNodes.includes(node))\n continue;\n if (!node.isConnected)\n continue;\n delete node._x_ignoreSelf;\n delete node._x_ignore;\n onElAddeds.forEach((i) => i(node));\n node._x_ignore = true;\n node._x_ignoreSelf = true;\n }\n addedNodes.forEach((node) => {\n delete node._x_ignoreSelf;\n delete node._x_ignore;\n });\n addedNodes = null;\n removedNodes = null;\n addedAttributes = null;\n removedAttributes = null;\n}\n\n// packages/alpinejs/src/scope.js\nfunction scope(node) {\n return mergeProxies(closestDataStack(node));\n}\nfunction addScopeToNode(node, data2, referenceNode) {\n node._x_dataStack = [data2, ...closestDataStack(referenceNode || node)];\n return () => {\n node._x_dataStack = node._x_dataStack.filter((i) => i !== data2);\n };\n}\nfunction closestDataStack(node) {\n if (node._x_dataStack)\n return node._x_dataStack;\n if (typeof ShadowRoot === "function" && node instanceof ShadowRoot) {\n return closestDataStack(node.host);\n }\n if (!node.parentNode) {\n return [];\n }\n return closestDataStack(node.parentNode);\n}\nfunction mergeProxies(objects) {\n let thisProxy = new Proxy({}, {\n ownKeys: () => {\n return Array.from(new Set(objects.flatMap((i) => Object.keys(i))));\n },\n has: (target, name) => {\n return objects.some((obj) => obj.hasOwnProperty(name));\n },\n get: (target, name) => {\n return (objects.find((obj) => {\n if (obj.hasOwnProperty(name)) {\n let descriptor = Object.getOwnPropertyDescriptor(obj, name);\n if (descriptor.get && descriptor.get._x_alreadyBound || descriptor.set && descriptor.set._x_alreadyBound) {\n return true;\n }\n if ((descriptor.get || descriptor.set) && descriptor.enumerable) {\n let getter = descriptor.get;\n let setter = descriptor.set;\n let property = descriptor;\n getter = getter && getter.bind(thisProxy);\n setter = setter && setter.bind(thisProxy);\n if (getter)\n getter._x_alreadyBound = true;\n if (setter)\n setter._x_alreadyBound = true;\n Object.defineProperty(obj, name, {\n ...property,\n get: getter,\n set: setter\n });\n }\n return true;\n }\n return false;\n }) || {})[name];\n },\n set: (target, name, value) => {\n let closestObjectWithKey = objects.find((obj) => obj.hasOwnProperty(name));\n if (closestObjectWithKey) {\n closestObjectWithKey[name] = value;\n } else {\n objects[objects.length - 1][name] = value;\n }\n return true;\n }\n });\n return thisProxy;\n}\n\n// packages/alpinejs/src/interceptor.js\nfunction initInterceptors(data2) {\n let isObject2 = (val) => typeof val === "object" && !Array.isArray(val) && val !== null;\n let recurse = (obj, basePath = "") => {\n Object.entries(Object.getOwnPropertyDescriptors(obj)).forEach(([key, {value, enumerable}]) => {\n if (enumerable === false || value === void 0)\n return;\n let path = basePath === "" ? key : `${basePath}.${key}`;\n if (typeof value === "object" && value !== null && value._x_interceptor) {\n obj[key] = value.initialize(data2, path, key);\n } else {\n if (isObject2(value) && value !== obj && !(value instanceof Element)) {\n recurse(value, path);\n }\n }\n });\n };
1\n return recurse(data2);\n}\nfunction interceptor(callback, mutateObj = () => {\n}) {\n let obj = {\n initialValue: void 0,\n _x_interceptor: true,\n initialize(data2, path, key) {\n return callback(this.initialValue, () => get(data2, path), (value) => set(data2, path, value), path, key);\n }\n };\n mutateObj(obj);\n return (initialValue) => {\n if (typeof initialValue === "object" && initialValue !== null && initialValue._x_interceptor) {\n let initialize = obj.initialize.bind(obj);\n obj.initialize = (data2, path, key) => {\n let innerValue = initialValue.initialize(data2, path, key);\n obj.initialValue = innerValue;\n return initialize(data2, path, key);\n };\n } else {\n obj.initialValue = initialValue;\n }\n return obj;\n };\n}\nfunction get(obj, path) {\n return path.split(".").reduce((carry, segment) => carry[segment], obj);\n}\nfunction set(obj, path, value) {\n if (typeof path === "string")\n path = path.split(".");\n if (path.length === 1)\n obj[path[0]] = value;\n else if (path.length === 0)\n throw error;\n else {\n if (obj[path[0]])\n return set(obj[path[0]], path.slice(1), value);\n else {\n obj[path[0]] = {};\n return set(obj[path[0]], path.slice(1), value);\n }\n }\n}\n\n// packages/alpinejs/src/magics.js\nvar magics = {};\nfunction magic(name, callback) {\n magics[name] = callback;\n}\nfunction injectMagics(obj, el) {\n Object.entries(magics).forEach(([name, callback]) => {\n let memoizedUtilities = null;\n function getUtilities() {\n if (memoizedUtilities) {\n return memoizedUtilities;\n } else {\n let [utilities, cleanup2] = getElementBoundUtilities(el);\n memoizedUtilities = {interceptor, ...utilities};\n onElRemoved(el, cleanup2);\n return memoizedUtilities;\n }\n }\n Object.defineProperty(obj, `$${name}`, {\n get() {\n return callback(el, getUtilities());\n },\n enumerable: false\n });\n });\n return obj;\n}\n\n// packages/alpinejs/src/utils/error.js\nfunction tryCatch(el, expression, callback, ...args) {\n try {\n return callback(...args);\n } catch (e) {\n handleError(e, el, expression);\n }\n}\nfunction handleError(error2, el, expression = void 0) {\n Object.assign(error2, {el, expression});\n console.warn(`Alpine Expression Error: ${error2.message}\n\n${expression ? \'Expression: "\' + expression + \'"\\n\\n\' : ""}`, el);\n setTimeout(() => {\n throw error2;\n }, 0);\n}\n\n// packages/alpinejs/src/evaluator.js\nvar shouldAutoEvaluateFunctions = true;\nfunction dontAutoEvaluateFunctions(callback) {\n let cache = shouldAutoEvaluateFunctions;\n shouldAutoEvaluateFunctions = false;\n let result = callback();\n shouldAutoEvaluateFunctions = cache;\n return result;\n}\nfunction evaluate(el, expression, extras = {}) {\n let result;\n evaluateLater(el, expression)((value) => result = value, extras);\n return result;\n}\nfunction evaluateLater(...args) {\n return theEvaluatorFunction(...args);\n}\nvar theEvaluatorFunction = normalEvaluator;\nfunction setEvaluator(newEvaluator) {\n theEvaluatorFunction = newEvaluator;\n}\nfunction normalEvaluator(el, expression) {\n let overriddenMagics = {};\n injectMagics(overriddenMagics, el);\n let dataStack = [overriddenMagics, ...closestDataStack(el)];\n let evaluator = typeof expression === "function" ? generateEvaluatorFromFunction(dataStack, expression) : generateEvaluatorFromString(dataStack, expression, el);\n return tryCatch.bind(null, el, expression, evaluator);\n}\nfunction generateEvaluatorFromFunction(dataStack, func) {\n return (receiver = () => {\n }, {scope: scope2 = {}, params = []} = {}) => {\n let result = func.apply(mergeProxies([scope2, ...dataStack]), params);\n runIfTypeOfFunction(receiver, result);\n };\n}\nvar evaluatorMemo = {};\nfunction generateFunctionFromString(expression, el) {\n if (evaluatorMemo[expression]) {\n return evaluatorMemo[expression];\n }\n let AsyncFunction = Object.getPrototypeOf(async function() {\
1n }).constructor;\n let rightSideSafeExpression = /^[\\n\\s]*if.*\\(.*\\)/.test(expression) || /^(let|const)\\s/.test(expression) ? `(async()=>{ ${expression} })()` : expression;\n const safeAsyncFunction = () => {\n try {\n return new AsyncFunction(["__self", "scope"], `with (scope) { __self.result = ${rightSideSafeExpression} }; __self.finished = true; return __self.result;`);\n } catch (error2) {\n handleError(error2, el, expression);\n return Promise.resolve();\n }\n };\n let func = safeAsyncFunction();\n evaluatorMemo[expression] = func;\n return func;\n}\nfunction generateEvaluatorFromString(dataStack, expression, el) {\n let func = generateFunctionFromString(expression, el);\n return (receiver = () => {\n }, {scope: scope2 = {}, params = []} = {}) => {\n func.result = void 0;\n func.finished = false;\n let completeScope = mergeProxies([scope2, ...dataStack]);\n if (typeof func === "function") {\n let promise = func(func, completeScope).catch((error2) => handleError(error2, el, expression));\n if (func.finished) {\n runIfTypeOfFunction(receiver, func.result, completeScope, params, el);\n func.result = void 0;\n } else {\n promise.then((result) => {\n runIfTypeOfFunction(receiver, result, completeScope, params, el);\n }).catch((error2) => handleError(error2, el, expression)).finally(() => func.result = void 0);\n }\n }\n };\n}\nfunction runIfTypeOfFunction(receiver, value, scope2, params, el) {\n if (shouldAutoEvaluateFunctions && typeof value === "function") {\n let result = value.apply(scope2, params);\n if (result instanceof Promise) {\n result.then((i) => runIfTypeOfFunction(receiver, i, scope2, params)).catch((error2) => handleError(error2, el, value));\n } else {\n receiver(result);\n }\n } else if (typeof value === "object" && value instanceof Promise) {\n value.then((i) => receiver(i));\n } else {\n receiver(value);\n }\n}\n\n// packages/alpinejs/src/directives.js\nvar prefixAsString = "x-";\nfunction prefix(subject = "") {\n return prefixAsString + subject;\n}\nfunction setPrefix(newPrefix) {\n prefixAsString = newPrefix;\n}\nvar directiveHandlers = {};\nfunction directive(name, callback) {\n directiveHandlers[name] = callback;\n return {\n before(directive2) {\n if (!directiveHandlers[directive2]) {\n console.warn("Cannot find directive `${directive}`. `${name}` will use the default order of execution");\n return;\n }\n const pos = directiveOrder.indexOf(directive2);\n directiveOrder.splice(pos >= 0 ? pos : directiveOrder.indexOf("DEFAULT"), 0, name);\n }\n };\n}\nfunction directives(el, attributes, originalAttributeOverride) {\n attributes = Array.from(attributes);\n if (el._x_virtualDirectives) {\n let vAttributes = Object.entries(el._x_virtualDirectives).map(([name, value]) => ({name, value}));\n let staticAttributes = attributesOnly(vAttributes);\n vAttributes = vAttributes.map((attribute) => {\n if (staticAttributes.find((attr) => attr.name === attribute.name)) {\n return {\n name: `x-bind:${attribute.name}`,\n value: `"${attribute.value}"`\n };\n }\n return attribute;\n });\n attributes = attributes.concat(vAttributes);\n }\n let transformedAttributeMap = {};\n let directives2 = attributes.map(toTransformedAttributes((newName, oldName) => transformedAttributeMap[newName] = oldName)).filter(outNonAlpineAttributes).map(toParsedDirectives(transformedAttributeMap, originalAttributeOverride)).sort(byPriority);\n return directives2.map((directive2) => {\n return getDirectiveHandler(el, directive2);\n });\n}\nfunction attributesOnly(attributes) {\n return Array.from(attributes).map(toTransformedAttributes()).filter((attr) => !outNonAlpineAttributes(attr));\n}\nvar isDeferringHandlers = false;\nvar directiveHandlerStacks = new Map();\nvar currentHandlerStackKey = Symbol();\nfunction deferHandlingDirectives(callback) {\n isDeferringHandlers = true;\n let key = Symbol();\n currentHandlerStackKey = key;\n directiveHandlerStacks.set(key, []);\n let flushHandlers = () => {\n while (directiveHandlerStacks.get(key).length)\n directiveHandlerStacks.get(key).shift()();\n directiveHandlerStacks.delete(key);\n };\n let stopDeferring = () => {\n isDeferringHandlers = false;\n flushHandlers();\n };\n callback(flushHandlers);\n stopDeferring();\n}\nfunction getElementBoundUtilities(el) {\n let cleanups = [];\n let cleanup2 = (callback) => cleanups.push(callback);\n let [effect3, cleanupEffect] = elementBoundEffect(el);\n cleanups.push(cleanupEffect);\n let utilities = {\n Alpine: alpine_default,\n effect: effect3,\n cleanup: cleanup2,\n evaluateLater: evaluateLater.bind(evaluateLater, el),\n evaluate: evaluate.bind(evaluate, el)\n };\n let doCleanup = () => cleanups.forEach((i) => i());\n return [utilities, doCleanup];\n}\nfunction getDirectiveHandler(el, directive2) {\n let noop = () => {\n };\n let handler4 = directiveHandlers[directive2.type] || noop;\n let [utilities, cleanup2] = getElementBoundUtilities(el);\n onAttributeRemoved(el, directive2.original, cleanup2);\n let fullHandler = () => {\n if (el._x_ignore || el._x_ignoreSelf)\n return;\n handler4.inline && handler4.inline(el, directive2, utilities);\n handler4 = handler4.bind(handler4, el, directive2, utilities);\n isDeferringHandlers ? directiveHandlerStacks.get(currentHandlerStackKey).push(handler4) : handler4();\n };\n fullHandler.runCleanups = cleanup2;\n return fullHandler;\n}\nvar startingWith = (subject, replacement) => ({name, value}) =>
1 {\n if (name.startsWith(subject))\n name = name.replace(subject, replacement);\n return {name, value};\n};\nvar into = (i) => i;\nfunction toTransformedAttributes(callback = () => {\n}) {\n return ({name, value}) => {\n let {name: newName, value: newValue} = attributeTransformers.reduce((carry, transform) => {\n return transform(carry);\n }, {name, value});\n if (newName !== name)\n callback(newName, name);\n return {name: newName, value: newValue};\n };\n}\nvar attributeTransformers = [];\nfunction mapAttributes(callback) {\n attributeTransformers.push(callback);\n}\nfunction outNonAlpineAttributes({name}) {\n return alpineAttributeRegex().test(name);\n}\nvar alpineAttributeRegex = () => new RegExp(`^${prefixAsString}([^:^.]+)\\\\b`);\nfunction toParsedDirectives(transformedAttributeMap, originalAttributeOverride) {\n return ({name, value}) => {\n let typeMatch = name.match(alpineAttributeRegex());\n let valueMatch = name.match(/:([a-zA-Z0-9\\-:]+)/);\n let modifiers = name.match(/\\.[^.\\]]+(?=[^\\]]*$)/g) || [];\n let original = originalAttributeOverride || transformedAttributeMap[name] || name;\n return {\n type: typeMatch ? typeMatch[1] : null,\n value: valueMatch ? valueMatch[1] : null,\n modifiers: modifiers.map((i) => i.replace(".", "")),\n expression: value,\n original\n };\n };\n}\nvar DEFAULT = "DEFAULT";\nvar directiveOrder = [\n "ignore",\n "ref",\n "data",\n "id",\n "bind",\n "init",\n "for",\n "model",\n "modelable",\n "transition",\n "show",\n "if",\n DEFAULT,\n "teleport"\n];\nfunction byPriority(a, b) {\n let typeA = directiveOrder.indexOf(a.type) === -1 ? DEFAULT : a.type;\n let typeB = directiveOrder.indexOf(b.type) === -1 ? DEFAULT : b.type;\n return directiveOrder.indexOf(typeA) - directiveOrder.indexOf(typeB);\n}\n\n// packages/alpinejs/src/utils/dispatch.js\nfunction dispatch(el, name, detail = {}) {\n el.dispatchEvent(new CustomEvent(name, {\n detail,\n bubbles: true,\n composed: true,\n cancelable: true\n }));\n}\n\n// packages/alpinejs/src/utils/walk.js\nfunction walk(el, callback) {\n if (typeof ShadowRoot === "function" && el instanceof ShadowRoot) {\n Array.from(el.children).forEach((el2) => walk(el2, callback));\n return;\n }\n let skip = false;\n callback(el, () => skip = true);\n if (skip)\n return;\n let node = el.firstElementChild;\n while (node) {\n walk(node, callback, false);\n node = node.nextElementSibling;\n }\n}\n\n// packages/alpinejs/src/utils/warn.js\nfunction warn(message, ...args) {\n console.warn(`Alpine Warning: ${message}`, ...args);\n}\n\n// packages/alpinejs/src/lifecycle.js\nvar started = false;\nfunction start() {\n if (started)\n warn("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems.");\n started = true;\n if (!document.body)\n warn("Unable to initialize. Trying to load Alpine before `<body>` is available. Did you forget to add `defer` in Alpine\'s `<script>` tag?");\n dispatch(document, "alpine:init");\n dispatch(document, "alpine:initializing");\n startObservingMutations();\n onElAdded((el) => initTree(el, walk));\n onElRemoved((el) => destroyTree(el));\n onAttributesAdded((el, attrs) => {\n directives(el, attrs).forEach((handle) => handle());\n });\n let outNestedComponents = (el) => !closestRoot(el.parentElement, true);\n Array.from(document.querySelectorAll(allSelectors())).filter(outNestedComponents).forEach((el) => {\n initTree(el);\n });\n dispatch(document, "alpine:initialized");\n}\nvar rootSelectorCallbacks = [];\nvar initSelectorCallbacks = [];\nfunction rootSelectors() {\n return rootSelectorCallbacks.map((fn) => fn());\n}\nfunction allSelectors() {\n return rootSelectorCallbacks.concat(initSelectorCallbacks).map((fn) => fn());\n}\nfunction addRootSelector(selectorCallback) {\n rootSelectorCallbacks.push(selectorCallback);\n}\nfunction addInitSelector(selectorCallback) {\n initSelectorCallbacks.push(selectorCallback);\n}\nfunction closestRoot(el, includeInitSelectors = false) {\n return findClosest(el, (element) => {\n const selectors = includeInitSelectors ? allSelectors() : rootSelectors();\n if (selectors.some((selector) => element.matches(selector)))\n return true;\n });\n}\nfunction findClosest(el, callback) {\n if (!el)\n return;\n if (callback(el))\n return el;\n if (el._x_teleportBack)\n el = el._x_teleportBack;\n if (!el.parentElement)\n return;\n return findClosest(el.parentElement, callback);\n}\nfunction isRoot(el) {\n return rootSelectors().some((selector) => el.matches(selector));\n}\nvar initInterceptors2 = [];\nfunction interceptInit(callback) {\n initInterceptors2.push(callback);\n}\nfunction initTree(el, walker = walk, intercept = () => {\n}) {\n deferHandlingDirectives(() =>
1 {\n walker(el, (el2, skip) => {\n intercept(el2, skip);\n initInterceptors2.forEach((i) => i(el2, skip));\n directives(el2, el2.attributes).forEach((handle) => handle());\n el2._x_ignore && skip();\n });\n });\n}\nfunction destroyTree(root) {\n walk(root, (el) => cleanupAttributes(el));\n}\n\n// packages/alpinejs/src/nextTick.js\nvar tickStack = [];\nvar isHolding = false;\nfunction nextTick(callback = () => {\n}) {\n queueMicrotask(() => {\n isHolding || setTimeout(() => {\n releaseNextTicks();\n });\n });\n return new Promise((res) => {\n tickStack.push(() => {\n callback();\n res();\n });\n });\n}\nfunction releaseNextTicks() {\n isHolding = false;\n while (tickStack.length)\n tickStack.shift()();\n}\nfunction holdNextTicks() {\n isHolding = true;\n}\n\n// packages/alpinejs/src/utils/classes.js\nfunction setClasses(el, value) {\n if (Array.isArray(value)) {\n return setClassesFromString(el, value.join(" "));\n } else if (typeof value === "object" && value !== null) {\n return setClassesFromObject(el, value);\n } else if (typeof value === "function") {\n return setClasses(el, value());\n }\n return setClassesFromString(el, value);\n}\nfunction setClassesFromString(el, classString) {\n let split = (classString2) => classString2.split(" ").filter(Boolean);\n let missingClasses = (classString2) => classString2.split(" ").filter((i) => !el.classList.contains(i)).filter(Boolean);\n let addClassesAndReturnUndo = (classes) => {\n el.classList.add(...classes);\n return () => {\n el.classList.remove(...classes);\n };\n };\n classString = classString === true ? classString = "" : classString || "";\n return addClassesAndReturnUndo(missingClasses(classString));\n}\nfunction setClassesFromObject(el, classObject) {\n let split = (classString) => classString.split(" ").filter(Boolean);\n let forAdd = Object.entries(classObject).flatMap(([classString, bool]) =>
1 bool ? split(classString) : false).filter(Boolean);\n let forRemove = Object.entries(classObject).flatMap(([classString, bool]) => !bool ? split(classString) : false).filter(Boolean);\n let added = [];\n let removed = [];\n forRemove.forEach((i) => {\n if (el.classList.contains(i)) {\n el.classList.remove(i);\n removed.push(i);\n }\n });\n forAdd.forEach((i) => {\n if (!el.classList.contains(i)) {\n el.classList.add(i);\n added.push(i);\n }\n });\n return () => {\n removed.forEach((i) => el.classList.add(i));\n added.forEach((i) => el.classList.remove(i));\n };\n}\n\n// packages/alpinejs/src/utils/styles.js\nfunction setStyles(el, value) {\n if (typeof value === "object" && value !== null) {\n return setStylesFromObject(el, value);\n }\n return setStylesFromString(el, value);\n}\nfunction setStylesFromObject(el, value) {\n let previousStyles = {};\n Object.entries(value).forEach(([key, value2]) => {\n previousStyles[key] = el.style[key];\n if (!key.startsWith("--")) {\n key = kebabCase(key);\n }\n el.style.setProperty(key, value2);\n });\n setTimeout(() => {\n if (el.style.length === 0) {\n el.removeAttribute("style");\n }\n });\n return () => {\n setStyles(el, previousStyles);\n };\n}\nfunction setStylesFromString(el, value) {\n let cache = el.getAttribute("style", value);\n el.setAttribute("style", value);\n return () => {\n el.setAttribute("style", cache || "");\n };\n}\nfunction kebabCase(subject) {\n return subject.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();\n}\n\n// packages/alpinejs/src/utils/once.js\nfunction once(callback, fallback = () => {\n}) {\n let called = false;\n return function() {\n if (!called) {\n called = true;\n callback.apply(this, arguments);\n } else {\n fallback.apply(this, arguments);\n }\n };\n}\n\n// packages/alpinejs/src/directives/x-transition.js\ndirective("transition", (el, {value, modifiers, expression}, {evaluate: evaluate2}) => {\n if (typeof expression === "function")\n expression = evaluate2(expression);\n if (expression === false)\n return;\n if (!expression || typeof expression === "boolean") {\n registerTransitionsFromHelper(el, modifiers, value);\n } else {\n registerTransitionsFromClassString(el, expression, value);\n }\n});\nfunction registerTransitionsFromClassString(el, classString, stage) {\n registerTransitionObject(el, setClasses, "");\n let directiveStorageMap = {\n enter: (classes) => {\n el._x_transition.enter.during = classes;\n },\n "enter-start": (classes) => {\n el._x_transition.enter.start = classes;\n },\n "enter-end": (classes) => {\n el._x_transition.enter.end = classes;\n },\n leave: (classes) => {\n el._x_transition.leave.during = classes;\n },\n "leave-start": (classes) => {\n el._x_transition.leave.start = classes;\n },\n "leave-end": (classes) => {\n el._x_transition.leave.end = classes;\n }\n };\n directiveStorageMap[stage](classString);\n}\nfunction registerTransitionsFromHelper(el, modifiers, stage) {\n registerTransitionObject(el, setStyles);\n let doesntSpecify = !modifiers.includes("in") && !modifiers.includes("out") && !stage;\n let transitioningIn = doesntSpecify || modifiers.includes("in") || ["enter"].includes(stage);\n let transitioningOut = doesntSpecify || modifiers.includes("out") || ["leave"].includes(stage);\n if (modifiers.includes("in") && !doesntSpecify) {\n modifiers = modifiers.filter((i, index) => index < modifiers.indexOf("out"));\n }\n if (modifiers.includes("out") && !doesntSpecify) {\n modifiers = modifiers.filter((i, index) => index > modifiers.indexOf("out"));\n }\n let wantsAll = !modifiers.includes("opacity") && !modifiers.includes("scale");\n let wantsOpacity = wantsAll || modifiers.includes("opacity");\n let wantsScale = wantsAll || modifiers.includes("scale");\n let opacityValue = wantsOpacity ? 0 : 1;\n let scaleValue = wantsScale ? modifierValue(modifiers, "scale", 95) / 100 : 1;\n let delay = modifierValue(modifiers, "delay", 0) / 1e3;\n let origin = modifierValue(modifiers, "origin", "center");\n let property = "opacity, transform";\n let durationIn = modifierValue(modifiers, "duration", 150) / 1e3;\n let durationOut = modifierValue(modifiers, "duration", 75) / 1e3;\n let easing = `cubic-bezier(0.4, 0.0, 0.2, 1)`;\n if (transitioningIn) {\n el._x_transition.enter.during = {\n transformOrigin: origin,\n transitionDelay: `${delay}s`,\n transitionProperty: property,\n transitionDuration: `${durationIn}s`,\n transitionTimingFunction: easing\n };
1\n el._x_transition.enter.start = {\n opacity: opacityValue,\n transform: `scale(${scaleValue})`\n };\n el._x_transition.enter.end = {\n opacity: 1,\n transform: `scale(1)`\n };\n }\n if (transitioningOut) {\n el._x_transition.leave.during = {\n transformOrigin: origin,\n transitionDelay: `${delay}s`,\n transitionProperty: property,\n transitionDuration: `${durationOut}s`,\n transitionTimingFunction: easing\n };\n el._x_transition.leave.start = {\n opacity: 1,\n transform: `scale(1)`\n };\n el._x_transition.leave.end = {\n opacity: opacityValue,\n transform: `scale(${scaleValue})`\n };\n }\n}\nfunction registerTransitionObject(el, setFunction, defaultValue = {}) {\n if (!el._x_transition)\n el._x_transition = {\n enter: {during: defaultValue, start: defaultValue, end: defaultValue},\n leave: {during: defaultValue, start: defaultValue, end: defaultValue},\n in(before = () => {\n }, after = () => {\n }) {\n transition(el, setFunction, {\n during: this.enter.during,\n start: this.enter.start,\n end: this.enter.end\n }, before, after);\n },\n out(before = () => {\n }, after = () => {\n }) {\n transition(el, setFunction, {\n during: this.leave.during,\n start: this.leave.start,\n end: this.leave.end\n }, before, after);\n }\n };\n}\nwindow.Element.prototype._x_toggleAndCascadeWithTransitions = function(el, value, show, hide) {\n const nextTick2 = document.visibilityState === "visible" ? requestAnimationFrame : setTimeout;\n let clickAwayCompatibleShow = () => nextTick2(show);\n if (value) {\n if (el._x_transition && (el._x_transition.enter || el._x_transition.leave)) {\n el._x_transition.enter && (Object.entries(el._x_transition.enter.during).length || Object.entries(el._x_transition.enter.start).length || Object.entries(el._x_transition.enter.end).length) ? el._x_transition.in(show) : clickAwayCompatibleShow();\n } else {\n el._x_transition ? el._x_transition.in(show) : clickAwayCompatibleShow();\n }\n return;\n }\n el._x_hidePromise = el._x_transition ? new Promise((resolve, reject) => {\n el._x_transition.out(() => {\n }, () => resolve(hide));\n el._x_transitioning.beforeCancel(() => reject({isFromCancelledTransition: true}));\n }) : Promise.resolve(hide);\n queueMicrotask(() => {\n let closest = closestHide(el);\n if (closest) {\n if (!closest._x_hideChildren)\n closest._x_hideChildren = [];\n closest._x_hideChildren.push(el);\n } else {\n nextTick2(() =>
1 {\n let hideAfterChildren = (el2) => {\n let carry = Promise.all([\n el2._x_hidePromise,\n ...(el2._x_hideChildren || []).map(hideAfterChildren)\n ]).then(([i]) => i());\n delete el2._x_hidePromise;\n delete el2._x_hideChildren;\n return carry;\n };\n hideAfterChildren(el).catch((e) => {\n if (!e.isFromCancelledTransition)\n throw e;\n });\n });\n }\n });\n};\nfunction closestHide(el) {\n let parent = el.parentNode;\n if (!parent)\n return;\n return parent._x_hidePromise ? parent : closestHide(parent);\n}\nfunction transition(el, setFunction, {during, start: start2, end} = {}, before = () => {\n}, after = () => {\n}) {\n if (el._x_transitioning)\n el._x_transitioning.cancel();\n if (Object.keys(during).length === 0 && Object.keys(start2).length === 0 && Object.keys(end).length === 0) {\n before();\n after();\n return;\n }\n let undoStart, undoDuring, undoEnd;\n performTransition(el, {\n start() {\n undoStart = setFunction(el, start2);\n },\n during() {\n undoDuring = setFunction(el, during);\n },\n before,\n end() {\n undoStart();\n undoEnd = setFunction(el, end);\n },\n after,\n cleanup() {\n undoDuring();\n undoEnd();\n }\n });\n}\nfunction performTransition(el, stages) {\n let interrupted, reachedBefore, reachedEnd;\n let finish = once(() => {\n mutateDom(() => {\n interrupted = true;\n if (!reachedBefore)\n stages.before();\n if (!reachedEnd) {\n stages.end();\n releaseNextTicks();\n }\n stages.after();\n if (el.isConnected)\n stages.cleanup();\n delete el._x_transitioning;\n });\n });\n el._x_transitioning = {\n beforeCancels: [],\n beforeCancel(callback) {\n this.beforeCancels.push(callback);\n },\n cancel: once(function() {\n while (this.beforeCancels.length) {\n this.beforeCancels.shift()();\n }\n ;\n finish();\n }),\n finish\n };\n mutateDom(() => {\n stages.start();\n stages.during();\n });\n holdNextTicks();\n requestAnimationFrame(() => {\n if (interrupted)\n return;\n let duration = Number(getComputedStyle(el).transitionDuration.replace(/,.*/, "").replace("s", "")) * 1e3;\n let delay = Number(getComputedStyle(el).transitionDelay.replace(/,.*/, "").replace("s", "")) * 1e3;\n if (duration === 0)\n duration = Number(getComputedStyle(el).animationDuration.replace("s", "")) * 1e3;\n mutateDom(() => {\n stages.before();\n });\n reachedBefore = true;\n requestAnimationFrame(() => {\n if (interrupted)\n return;\n mutateDom(() => {\n stages.end();\n });\n releaseNextTicks();\n setTimeout(el._x_transitioning.finish, duration + delay);\n reachedEnd = true;\n });\n });\n}\nfunction modifierValue(modifiers, key, fallback) {\n if (modifiers.indexOf(key) === -1)\n return fallback;\n const rawValue = modifiers[modifiers.indexOf(key) + 1];\n if (!rawValue)\n return fallback;\n if (key === "scale") {\n if (isNaN(rawValue))\n return fallback;\n }\n if (key === "duration" || key === "delay") {\n let match = rawValue.match(/([0-9]+)ms/);\n if (match)\n return match[1];\n }\n if (key === "origin") {\n if (["top", "right", "left", "center", "bottom"].includes(modifiers[modifiers.indexOf(key) + 2])) {\n return [rawValue, modifiers[modifiers.indexOf(key) + 2]].join(" ");\n }\n }\n return rawValue;\n}\n\n// packages/alpinejs/src/clone.js\nvar isCloning = false;\nfunction skipDuringClone(callback, fallback = () => {\n}) {\n return (...args) => isCloning ? fallback(...args) : callback(...args);\n}\nfunction onlyDuringClone(callback) {\n return (...args) => isCloning && callback(...args);\n}\nfunction module_esm_clone(oldEl, newEl) {\n if (!newEl._x_dataStack)\n newEl._x_dataStack = oldEl._x_dataStack;\n isCloning = true;\n dontRegisterReactiveSideEffects(() =>
1 {\n cloneTree(newEl);\n });\n isCloning = false;\n}\nfunction cloneTree(el) {\n let hasRunThroughFirstEl = false;\n let shallowWalker = (el2, callback) => {\n walk(el2, (el3, skip) => {\n if (hasRunThroughFirstEl && isRoot(el3))\n return skip();\n hasRunThroughFirstEl = true;\n callback(el3, skip);\n });\n };\n initTree(el, shallowWalker);\n}\nfunction dontRegisterReactiveSideEffects(callback) {\n let cache = effect;\n overrideEffect((callback2, el) => {\n let storedEffect = cache(callback2);\n release(storedEffect);\n return () => {\n };\n });\n callback();\n overrideEffect(cache);\n}\n\n// packages/alpinejs/src/utils/bind.js\nfunction bind(el, name, value, modifiers = []) {\n if (!el._x_bindings)\n el._x_bindings = reactive({});\n el._x_bindings[name] = value;\n name = modifiers.includes("camel") ? camelCase(name) : name;\n switch (name) {\n case "value":\n bindInputValue(el, value);\n break;\n case "style":\n bindStyles(el, value);\n break;\n case "class":\n bindClasses(el, value);\n break;\n case "selected":\n case "checked":\n bindAttributeAndProperty(el, name, value);\n break;\n default:\n bindAttribute(el, name, value);\n break;\n }\n}\nfunction bindInputValue(el, value) {\n if (el.type === "radio") {\n if (el.attributes.value === void 0) {\n el.value = value;\n }\n if (window.fromModel) {\n el.checked = checkedAttrLooseCompare(el.value, value);\n }\n } else if (el.type === "checkbox") {\n if (Number.isInteger(value)) {\n el.value = value;\n } else if (!Number.isInteger(value) && !Array.isArray(value) && typeof value !== "boolean" && ![null, void 0].includes(value)) {\n el.value =
1String(value);\n } else {\n if (Array.isArray(value)) {\n el.checked = value.some((val) => checkedAttrLooseCompare(val, el.value));\n } else {\n el.checked = !!value;\n }\n }\n } else if (el.tagName === "SELECT") {\n updateSelect(el, value);\n } else {\n if (el.value === value)\n return;\n el.value = value;\n }\n}\nfunction bindClasses(el, value) {\n if (el._x_undoAddedClasses)\n el._x_undoAddedClasses();\n el._x_undoAddedClasses = setClasses(el, value);\n}\nfunction bindStyles(el, value) {\n if (el._x_undoAddedStyles)\n el._x_undoAddedStyles();\n el._x_undoAddedStyles = setStyles(el, value);\n}\nfunction bindAttributeAndProperty(el, name, value) {\n bindAttribute(el, name, value);\n setPropertyIfChanged(el, name, value);\n}\nfunction bindAttribute(el, name, value) {\n if ([null, void 0, false].includes(value) && attributeShouldntBePreservedIfFalsy(name)) {\n el.removeAttribute(name);\n } else {\n if (isBooleanAttr(name))\n value = name;\n setIfChanged(el, name, value);\n }\n}\nfunction setIfChanged(el, attrName, value) {\n if (el.getAttribute(attrName) != value) {\n el.setAttribute(attrName, value);\n }\n}\nfunction setPropertyIfChanged(el, propName, value) {\n if (el[propName] !== value) {\n el[propName] = value;\n }\n}\nfunction updateSelect(el, value) {\n const arrayWrappedValue = [].concat(value).map((value2) => {\n return value2 + "";\n });\n Array.from(el.options).forEach((option) => {\n option.selected = arrayWrappedValue.includes(option.value);\n });\n}\nfunction camelCase(subject) {\n return subject.toLowerCase().replace(/-(\\w)/g, (match, char) => char.toUpperCase());\n}\nfunction checkedAttrLooseCompare(valueA, valueB) {\n return valueA == valueB;\n}\nfunction isBooleanAttr(attrName) {\n const booleanAttributes = [\n "disabled",\n "checked",\n "required",\n "readonly",\n "hidden",\n "open",\n "selected",\n "autofocus",\n "itemscope",\n "multiple",\n "novalidate",\n "allowfullscreen",\n "allowpaymentrequest",\n "formnovalidate",\n "autoplay",\n "controls",\n "loop",\n "muted",\n "playsinline",\n "default",\n "ismap",\n "reversed",\n "async",\n "defer",\n "nomodule"\n ];\n return booleanAttributes.includes(attrName);\n}\nfunction attributeShouldntBePreservedIfFalsy(name) {\n return !["aria-pressed", "aria-checked", "aria-expanded", "aria-selected"].includes(name);\n}\nfunction getBinding(el, name, fallback) {\n if (el._x_bindings && el._x_bindings[name] !== void 0)\n return el._x_bindings[name];\n return getAttributeBinding(el, name, fallback);\n}\nfunction extractProp(el, name, fallback, extract = true) {\n if (el._x_bindings && el._x_bindings[name] !== void 0)\n return el._x_bindings[name];\n if (el._x_inlineBindings && el._x_inlineBindings[name] !== void 0) {\n let binding = el._x_inlineBindings[name];\n binding.extract = extract;\n return dontAutoEvaluateFunctions(() => {\n return evaluate(el, binding.expression);\n });\n }\n return getAttributeBinding(el, name, fallback);\n}\nfunction getAttributeBinding(el, name, fallback) {\n let attr = el.getAttribute(name);\n if (attr === null)\n return typeof fallback === "function" ? fallback() : fallback;\n if (attr === "")\n return true;\n if (isBooleanAttr(name)) {\n return !![name, "true"].includes(attr);\n }\n return attr;\n}\n\n// packages/alpinejs/src/utils/debounce.js\nfunction debounce(func, wait) {\n var timeout;\n return function() {\n var context = this, args = arguments;\n var later = function() {\n timeout = null;\n func.apply(context, args);\n };\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n };\n}\n\n// packages/alpinejs/src/utils/throttle.js\nfunction throttle(func, limit) {\n let inThrottle;\n return function() {\n let context = this, args = arguments;\n if (!inThrottle) {\n func.apply(context, args);\n inThrottle = true;\n setTimeout(() => inThrottle = false, limit);\n }\n };\n}\n\n// packages/alpinejs/src/plugin.js\nfunction module_esm_plugin(callback) {\n let callbacks = Array.isArray(callback) ? callback : [callback];\n callbacks.forEach((i) => i(alpine_default));\n}\n\n// packages/alpinejs/src/store.js\nvar stores = {};\nvar isReactive = false;\nfunction store(name, value) {\n if (!isReactive) {\n stores = reactive(stores);\n isReactive = true;\n }\n if (value === void 0) {\n return stores[name];\n }\n stores[name] = value;\n if (typeof value === "object" && value !== null && value.hasOwnProperty("init") && typeof value.init === "function") {\n stores[name].init();\n }\n initInterceptors(stores[name]);\n}\nfunction getStores() {\n return stores;\n}\n\n// packages/alpinejs/src/binds.js\nvar binds = {};\nfunction bind2(name, bindings) {\n let getBindings = typeof bindings !== "function" ? () => bindings : bindings;\n if (name instanceof Element) {\n applyBindingsObject(name, getBindings());\n } else {\n binds[name] = getBindings;\n }\n}\nfunction injectBindingProviders(obj) {\n Object.entries(binds).forEac
1h(([name, callback]) => {\n Object.defineProperty(obj, name, {\n get() {\n return (...args) => {\n return callback(...args);\n };\n }\n });\n });\n return obj;\n}\nfunction applyBindingsObject(el, obj, original) {\n let cleanupRunners = [];\n while (cleanupRunners.length)\n cleanupRunners.pop()();\n let attributes = Object.entries(obj).map(([name, value]) => ({name, value}));\n let staticAttributes = attributesOnly(attributes);\n attributes = attributes.map((attribute) => {\n if (staticAttributes.find((attr) => attr.name === attribute.name)) {\n return {\n name: `x-bind:${attribute.name}`,\n value: `"${attribute.value}"`\n };\n }\n return attribute;\n });\n directives(el, attributes, original).map((handle) => {\n cleanupRunners.push(handle.runCleanups);\n handle();\n });\n}\n\n// packages/alpinejs/src/datas.js\nvar datas = {};\nfunction data(name, callback) {\n datas[name] = callback;\n}\nfunction injectDataProviders(obj, context) {\n Object.entries(datas).forEach(([name, callback]) => {\n Object.defineProperty(obj, name, {\n get() {\n return (...args) => {\n return callback.bind(context)(...args);\n };\n },\n enumerable: false\n });\n });\n return obj;\n}\n\n// packages/alpinejs/src/alpine.js\nvar Alpine = {\n get reactive() {\n return reactive;\n },\n get release() {\n return release;\n },\n get effect() {\n return effect;\n },\n get raw() {\n return raw;\n },\n version: "3.12.3",\n flushAndStopDeferringMutations,\n dontAutoEvaluateFunctions,\n disableEffectScheduling,\n startObservingMutations,\n stopObservingMutations,\n setReactivityEngine,\n closestDataStack,\n skipDuringClone,\n onlyDuringClone,\n addRootSelector,\n addInitSelector,\n addScopeToNode,\n deferMutations,\n mapAttributes,\n evaluateLater,\n interceptInit,\n setEvaluator,\n mergeProxies,\n extractProp,\n findClosest,\n closestRoot,\n destroyTree,\n interceptor,\n transition,\n setStyles,\n mutateDom,\n directive,\n throttle,\n debounce,\n evaluate,\n initTree,\n nextTick,\n prefixed: prefix,\n prefix: setPrefix,\n plugin: module_esm_plugin,\n magic,\n store,\n start,\n clone: module_esm_clone,\n bound: getBinding,\n $data: scope,\n walk,\n data,\n bind: bind2\n};\nvar alpine_default = Alpine;\n\n// node_modules/@vue/shared/dist/shared.esm-bundler.js\nfunction makeMap(str, expectsLowerCase) {\n const map = Object.create(null);\n const list = str.split(",");\n for (let i = 0; i < list.length; i++) {\n map[list[i]] = true;\n }\n return expectsLowerCase ? (val) => !!map[val.toLowerCase()] : (val) => !!map[val];\n}\nvar PatchFlagNames = {\n [1]: `TEXT`,\n [2]: `CLASS`,\n [4]: `STYLE`,\n [8]: `PROPS`,\n [16]: `FULL_PROPS`,\n [32]: `HYDRATE_EVENTS`,\n [64]: `STABLE_FRAGMENT`,\n [128]: `KEYED_FRAGMENT`,\n [256]: `UNKEYED_FRAGMENT`,\n [512]: `NEED_PATCH`,\n [1024]: `DYNAMIC_SLOTS`,\n [2048]: `DEV_ROOT_FRAGMENT`,\n [-1]: `HOISTED`,\n [-2]: `BAIL`\n};\nvar slotFlagsText = {\n [1]: "STABLE",\n [2]: "DYNAMIC",\n [3]: "FORWARDED"\n};\nvar specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;\nvar isBooleanAttr2 = /* @__PURE__ */ makeMap(specialBooleanAttrs + `,async,autofocus,autoplay,controls,default,defer,disabled,hidden,loop,open,required,reversed,scoped,seamless,checked,muted,multiple,selected`);\nvar EMPTY_OBJ = true ? Object.freeze({}) : 0;\nvar EMPTY_ARR = true ? Object.freeze([]) : 0;\nvar extend = Object.assign;\nvar module_esm_hasOwnProperty = Object.prototype.hasOwnProperty;\nvar hasOwn = (val, key) => module_esm_hasOwnProperty.call(val, key);\nvar isArray = Array.isArray;\nvar isMap = (val) => toTypeString(val) === "[object Map]";\nvar isString = (val) => typeof val === "string";\nvar isSymbol = (val) => typeof val === "symbol";\nvar module_esm_isObject = (val) => val !== null && typeof val === "object";\nvar objectToString = Object.prototype.toString;\nvar toTypeString = (value) => objectToString.call(value);\nvar toRawType = (value) => {\n return toTypeString(value).slice(8, -1);\n};\nvar isIntegerKey = (key) =>
1 isString(key) && key !== "NaN" && key[0] !== "-" && "" + parseInt(key, 10) === key;\nvar cacheStringFunction = (fn) => {\n const cache = Object.create(null);\n return (str) => {\n const hit = cache[str];\n return hit || (cache[str] = fn(str));\n };\n};\nvar camelizeRE = /-(\\w)/g;\nvar camelize = cacheStringFunction((str) => {\n return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : "");\n});\nvar hyphenateRE = /\\B([A-Z])/g;\nvar hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, "-$1").toLowerCase());\nvar capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + str.slice(1));\nvar toHandlerKey = cacheStringFunction((str) => str ? `on${capitalize(str)}` : ``);\nvar hasChanged = (value, oldValue) => value !== oldValue && (value === value || oldValue === oldValue);\n\n// node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js\nvar targetMap = new WeakMap();\nvar effectStack = [];\nvar activeEffect;\nvar ITERATE_KEY = Symbol( true ? "iterate" : 0);\nvar MAP_KEY_ITERATE_KEY = Symbol( true ? "Map key iterate" : 0);\nfunction isEffect(fn) {\n return fn && fn._isEffect === true;\n}\nfunction effect2(fn, options = EMPTY_OBJ) {\n if (isEffect(fn)) {\n fn = fn.raw;\n }\n const effect3 = createReactiveEffect(fn, options);\n if (!options.lazy) {\n effect3();\n }\n return effect3;\n}\nfunction stop(effect3) {\n if (effect3.active) {\n cleanup(effect3);\n if (effect3.options.onStop) {\n effect3.options.onStop();\n }\n effect3.active = false;\n }\n}\nvar uid = 0;\nfunction createReactiveEffect(fn, options) {\n const effect3 = function reactiveEffect() {\n if (!effect3.active) {\n return fn();\n }\n if (!effectStack.includes(effect3)) {\n cleanup(effect3);\n try {\n enableTracking();\n effectStack.push(effect3);\n activeEffect = effect3;\n return fn();\n } finally {\n effectStack.pop();\n resetTracking();\n activeEffect = effectStack[effectStack.length - 1];\n }\n }\n };\n effect3.id = uid++;\n effect3.allowRecurse = !!options.allowRecurse;\n effect3._isEffect = true;\n effect3.active = true;\n effect3.raw = fn;\n effect3.deps = [];\n effect3.options = options;\n return effect3;\n}\nfunction cleanup(effect3) {\n const {deps} = effect3;\n if (deps.length) {\n for (let i = 0; i < deps.length; i++) {\n deps[i].delete(effect3);\n }\n deps.length = 0;\n }\n}\nvar shouldTrack = true;\nvar trackStack = [];\nfunction pauseTracking() {\n trackStack.push(shouldTrack);\n shouldTrack = false;\n}\nfunction enableTracking() {\n trackStack.push(shouldTrack);\n shouldTrack = true;\n}\nfunction resetTracking() {\n const last = trackStack.pop();\n shouldTrack = last === void 0 ? true : last;\n}\nfunction track(target, type, key) {\n if (!shouldTrack || activeEffect === void 0) {\n return;\n }\n let depsMap = targetMap.get(target);\n if (!depsMap) {\n targetMap.set(target, depsMap = new Map());\n }\n let dep = depsMap.get(key);\n if (!dep) {\n depsMap.set(key, dep = new Set());\n }
1\n if (!dep.has(activeEffect)) {\n dep.add(activeEffect);\n activeEffect.deps.push(dep);\n if (activeEffect.options.onTrack) {\n activeEffect.options.onTrack({\n effect: activeEffect,\n target,\n type,\n key\n });\n }\n }\n}\nfunction trigger(target, type, key, newValue, oldValue, oldTarget) {\n const depsMap = targetMap.get(target);\n if (!depsMap) {\n return;\n }\n const effects = new Set();\n const add2 = (effectsToAdd) => {\n if (effectsToAdd) {\n effectsToAdd.forEach((effect3) => {\n if (effect3 !== activeEffect || effect3.allowRecurse) {\n effects.add(effect3);\n }\n });\n }\n };\n if (type === "clear") {\n depsMap.forEach(add2);\n } else if (key === "length" && isArray(target)) {\n depsMap.forEach((dep, key2) => {\n if (key2 === "length" || key2 >= newValue) {\n add2(dep);\n }\n });\n } else {\n if (key !== void 0) {\n add2(depsMap.get(key));\n }\n switch (type) {\n case "add":\n if (!isArray(target)) {\n add2(depsMap.get(ITERATE_KEY));\n if (isMap(target)) {\n add2(depsMap.get(MAP_KEY_ITERATE_KEY));\n }\n } else if (isIntegerKey(key)) {\n add2(depsMap.get("length"));\n }\n break;\n case "delete":\n if (!isArray(target)) {\n add2(depsMap.get(ITERATE_KEY));\n if (isMap(target)) {\n add2(depsMap.get(MAP_KEY_ITERATE_KEY));\n }\n }\n break;\n case "set":\n if (isMap(target)) {\n add2(depsMap.get(ITERATE_KEY));\n }\n break;\n }\n }\n const run = (effect3) => {\n if (effect3.options.onTrigger) {\n effect3.options.onTrigger({\n effect: effect3,\n target,\n key,\n type,\n newValue,\n oldValue,\n oldTarget\n });\n }\n if (effect3.options.scheduler) {\n effect3.options.scheduler(effect3);\n } else {\n effect3();\n }\n };\n effects.forEach(run);\n}\nvar isNonTrackableKeys = /* @__PURE__ */ makeMap(`__proto__,__v_isRef,__isVue`);\nvar builtInSymbols = new Set(Object.getOwnPropertyNames(Symbol).map((key) => Symbol[key]).filter(isSymbol));\nvar get2 = /* @__PURE__ */ createGetter();\nvar shallowGet = /* @__PURE__ */ createGetter(false, true);\nvar readonlyGet = /* @__PURE__ */ createGetter(true);\nvar shallowReadonlyGet = /* @__PURE__ */ createGetter(true, true);\nvar arrayInstrumentations = {};\n["includes", "indexOf", "lastIndexOf"].forEach((key) => {\n const method = Array.prototype[key];\n arrayInstrumentations[key] = function(...args) {\n const arr = toRaw(this);\n for (let i = 0, l = this.length; i < l; i++) {\n track(arr, "get", i + "");\n }\n const res = method.apply(arr, args);\n if (res === -1 || res === false) {\n return method.apply(arr, args.map(toRaw));\n } else {\n return res;\n }\n };\n});\n["push", "pop", "shift", "unshift", "splice"].forEach((key) => {\n const method = Array.prototype[key];\n arrayInstrumentations[key] = function(...args) {\n pauseTracking();\n const res = method.apply(this, args);\n resetTracking();\n return res;\n };\n});\nfunction createGetter(isReadonly = false, shallow = false) {\n return function get3(target, key, receiver) {\n if (key === "__v_isReactive") {\n return !isReadonly;\n } else if (key === "__v_isReadonly") {\n return isReadonly;\n } else if (key === "__v_raw" && receiver === (isReadonly ? shallow ? shallowReadonlyMap : readonlyMap : shallow ? shallowReactiveMap : reactiveMap).get(target)) {\n return target;\n }\n const targetIsArray = isArray(target);\n if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {\n return Reflect.get(arrayInstrumentations, key, receiver);\n }\n const res = Reflect.get(target, key, receiver);\n if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {\n return res;\n }\n if (!isReadonly) {\n track(target, "get", key);\n }\n if (shallow) {\n return res;\n }\n if (isRef(res)) {\n const shouldUnwrap = !targetIsArray || !isIntegerKey(key);\n return shouldUnwrap ? res.value : res;\n }
1\n if (module_esm_isObject(res)) {\n return isReadonly ? readonly(res) : reactive2(res);\n }\n return res;\n };\n}\nvar set2 = /* @__PURE__ */ createSetter();\nvar shallowSet = /* @__PURE__ */ createSetter(true);\nfunction createSetter(shallow = false) {\n return function set3(target, key, value, receiver) {\n let oldValue = target[key];\n if (!shallow) {\n value = toRaw(value);\n oldValue = toRaw(oldValue);\n if (!isArray(target) && isRef(oldValue) && !isRef(value)) {\n oldValue.value = value;\n return true;\n }\n }\n const hadKey = isArray(target) && isIntegerKey(key) ? Number(key) < target.length : hasOwn(target, key);\n const result = Reflect.set(target, key, value, receiver);\n if (target === toRaw(receiver)) {\n if (!hadKey) {\n trigger(target, "add", key, value);\n } else if (hasChanged(value, oldValue)) {\n trigger(target, "set", key, value, oldValue);\n }\n }\n return result;\n };\n}\nfunction deleteProperty(target, key) {\n const hadKey = hasOwn(target, key);\n const oldValue = target[key];\n const result = Reflect.deleteProperty(target, key);\n if (result && hadKey) {\n trigger(target, "delete", key, void 0, oldValue);\n }\n return result;\n}\nfunction has(target, key) {\n const result = Reflect.has(target, key);\n if (!isSymbol(key) || !builtInSymbols.has(key)) {\n track(target, "has", key);\n }\n return result;\n}\nfunction ownKeys(target) {\n track(target, "iterate", isArray(target) ? "length" : ITERATE_KEY);\n return Reflect.ownKeys(target);\n}\nvar mutableHandlers = {\n get: get2,\n set: set2,\n deleteProperty,\n has,\n ownKeys\n};\nvar readonlyHandlers = {\n get: readonlyGet,\n set(target, key) {\n if (true) {\n console.warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target);\n }\n return true;\n },\n deleteProperty(target, key) {\n if (true) {\n console.warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target);\n }\n return true;\n }\n};\nvar shallowReactiveHandlers = extend({}, mutableHandlers, {\n get: shallowGet,\n set: shallowSet\n});\nvar shallowReadonlyHandlers = extend({}, readonlyHandlers, {\n get: shallowReadonlyGet\n});\nvar toReactive = (value) => module_esm_isObject(value) ? reactive2(value) : value;\nvar toReadonly = (value) => module_esm_isObject(value) ? readonly(value) : value;\nvar toShallow = (value) => value;\nvar getProto = (v) => Reflect.getPrototypeOf(v);\nfunction get$1(target, key, isReadonly = false, isShallow = false) {\n target = target["__v_raw"];\n const rawTarget = toRaw(target);\n const rawKey = toRaw(key);\n if (key !== rawKey) {\n !isReadonly && track(rawTarget, "get", key);\n }\n !isReadonly && track(rawTarget, "get", rawKey);\n const {has: has2} = getProto(rawTarget);\n const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;\n if (has2.call(rawTarget, key)) {\n return wrap(target.get(key));\n } else if (has2.call(rawTarget, rawKey)) {\n return wrap(target.get(rawKey));\n } else if (target !== rawTarget) {\n target.get(key);\n }\n}\nfunction has$1(key, isReadonly = false) {\n const target = this["__v_raw"];\n const rawTarget = toRaw(target);\n const rawKey = toRaw(key);\n if (key !== rawKey) {\n !isReadonly && track(rawTarget, "has", key);\n }\n !isReadonly && track(rawTarget, "has", rawKey);\n return key === rawKey ? target.has(key) : target.has(key) || target.has(rawKey);\n}\nfunction size(target, isReadonly = false) {\n target = target["__v_raw"];\n !isReadonly && track(toRaw(target), "iterate", ITERATE_KEY);\n return Reflect.get(target, "size", target);\n}\nfunction add(value) {\n value = toRaw(value);\n const target = toRaw(this);\n const proto = getProto(target);\n const hadKey = proto.has.call(target, value);\n if (!hadKey) {\n target.add(value);\n trigger(target, "add", value, value);\n }\n return this;\n}\nfunction set$1(key, value) {\n value = toRaw(value);\n const target = toRaw(this);\n const {has: has2, get: get3} = getProto(target);\n let hadKey = has2.call(target, key);\n if (!hadKey) {\n key = toRaw(key);\n hadKey = has2.call(target, key);\n } else if (true) {\n checkIdentityKeys(target, has2, key);\n }\n const oldValue = get3.call(target, key);\n target.set(key, value);\n if (!hadKey) {\n trigger(target, "add", key, value);\n } else if (hasChanged(value, oldValue)) {\n trigger(target, "set", key, value, oldValue);\n }\n return this;\n}\nfunction deleteEntry(key) {\n const target = toRaw(this);\n const {has: has2, get: get3} = getProto(target);\n let hadKey = has2.call(target, key);\n if (!hadKey) {\n key = toRaw(key);\n hadKey = has2.call(target, key);\n } else if (true) {\n checkIdentityKeys(target, has2, key);\n }\n const oldValue = get3 ? get3.call(target, key) : void 0;\n const result = target.delete(key);\n if (hadKey) {\n trigger(target, "delete", key, void 0, oldValue);\n }\n return result;\n}\nfunction clear() {\n const target = toRaw(this);\n const hadItems = target.size !== 0;\n const oldTarget = true ? isMap(target) ? new Map(target) : new Set(target) : 0;\n const result = target.clear();\n if (hadItems) {\n trigger(target, "clear", void 0, void 0, oldTarget);\n }\n return result;\n}\nfunction createForEach(isReadonly, isShallow) {\n return function forEach(callback, thisArg) {\n const observed = this;\n const target = observed["__v_raw"];\n const rawTarget = toRaw(target);\n const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;\n !isReadonly && track(rawTarget, "iterate", ITERATE_KEY);\n return target.forEach((value, key) => {\n return callback.call(thisArg, wrap(value), wrap(key), observed);\n });\n };\n}\nfunction createIterableMethod(method, isReadonly, isShallow) {\n return function(...args) {\n const target = this["__v_raw"];\n const rawTarget = toRaw(target);\n const targetIsMap = isMap(rawTarget);\n const isPair = method === "entries" || method === Symbol.iterator && targetIsMap;\n const isKeyOnly = method === "keys" && targetIsMap;\n const innerIterator = target[method](...args);\n const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;\n !isReadonly && track(rawTarget, "iterate", isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY);\n return {\n next() {\n const {value, done} = innerIterator.next();\n return done ? {value, done} : {\n value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),\n done\n };\n },\n [Symbol.iterator]() {\n return this;\n }\n };\n };\n}\nfunction createReadonlyMethod(type) {\n return function(...args) {\n if (true) {\n const
1key = args[0] ? `on key "${args[0]}" ` : ``;\n console.warn(`${capitalize(type)} operation ${key}failed: target is readonly.`, toRaw(this));\n }\n return type === "delete" ? false : this;\n };\n}\nvar mutableInstrumentations = {\n get(key) {\n return get$1(this, key);\n },\n get size() {\n return size(this);\n },\n has: has$1,\n add,\n set: set$1,\n delete: deleteEntry,\n clear,\n forEach: createForEach(false, false)\n};\nvar shallowInstrumentations = {\n get(key) {\n return get$1(this, key, false, true);\n },\n get size() {\n return size(this);\n },\n has: has$1,\n add,\n set: set$1,\n delete: deleteEntry,\n clear,\n forEach: createForEach(false, true)\n};\nvar readonlyInstrumentations = {\n get(key) {\n return get$1(this, key, true);\n },\n get size() {\n return size(this, true);\n },\n has(key) {\n return has$1.call(this, key, true);\n },\n add: createReadonlyMethod("add"),\n set: createReadonlyMethod("set"),\n delete: createReadonlyMethod("delete"),\n clear: createReadonlyMethod("clear"),\n forEach: createForEach(true, false)\n};\nvar shallowReadonlyInstrumentations = {\n get(key) {\n return get$1(this, key, true, true);\n },\n get size() {\n return size(this, true);\n },\n has(key) {\n return has$1.call(this, key, true);\n },\n add: createReadonlyMethod("add"),\n set: createReadonlyMethod("set"),\n delete: createReadonlyMethod("delete"),\n clear: createReadonlyMethod("clear"),\n forEach: createForEach(true, true)\n};\nvar iteratorMethods = ["keys", "values", "entries", Symbol.iterator];\niteratorMethods.forEach((method) => {\n mutableInstrumentations[method] = createIterableMethod(method, false, false);\n readonlyInstrumentations[method] = createIterableMethod(method, true, false);\n shallowInstrumentations[method] = createIterableMethod(method, false, true);\n shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true);\n});\nfunction createInstrumentationGetter(isReadonly, shallow) {\n const instrumentations = shallow ? isReadonly ? shallowReadonlyInstrumentations : shallowInstrumentations : isReadonly ? readonlyInstrumentations : mutableInstrumentations;\n return (target, key, receiver) => {\n if (key === "__v_isReactive") {\n return !isReadonly;\n } else if (key === "__v_isReadonly") {\n return isReadonly;\n } else if (key === "__v_raw") {\n return target;\n }\n return Reflect.get(hasOwn(instrumentations, key) && key in target ? instrumentations : target, key, receiver);\n };\n}\nvar mutableCollectionHandlers = {\n get: createInstrumentationGetter(false, false)\n};\nvar shallowCollectionHandlers = {\n get: createInstrumentationGetter(false, true)\n};\nvar readonlyCollectionHandlers = {\n get: createInstrumentationGetter(true, false)\n};\nvar shallowReadonlyCollectionHandlers = {\n get: createInstrumentationGetter(true, true)\n};\nfunction checkIdentityKeys(target, has2, key) {\n const rawKey = toRaw(key);\n if (rawKey !== key && has2.call(target, rawKey)) {\n const type = toRawType(target);\n console.warn(`Reactive ${type} contains both the raw and reactive versions of the same object${type === `Map` ? ` as keys` : ``}, which can lead to inconsistencies. Avoid differentiating between the raw and reactive versions of an object and only use the reactive version if possible.`);\n }\n}\nvar reactiveMap = new WeakMap();\nvar shallowReactiveMap = new WeakMap();\nvar readonlyMap = new WeakMap();\nvar shallowReadonlyMap = new WeakMap();\nfunction targetTypeMap(rawType) {\n switch (rawType) {\n case "Object":\n case "Array":\n return 1;\n case "Map":\n case "Set":\n case "WeakMap":\n case "WeakSet":\n return 2;\n default:\n return 0;\n }\n}\nfunction getTargetType(value) {\n return value["__v_skip"] || !Object.isExtensible(value) ? 0 : targetTypeMap(toRawType(value));\n}\nfunction reactive2(target) {\n if (target && target["__v_isReadonly"]) {\n return target;\n }\n return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);\n}\nfunction readonly(target) {\n return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap);\n}\nfunction createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) {\n if (!module_esm_isObject(target)) {\n if (true) {\n console.warn(`value cannot be made reactive: ${String(target)}`);\n }\n return target;\n }\n if (target["__v_raw"] && !(isReadonly && target["__v_isReactive"])) {\n return target;\n }\n const existingProxy = proxyMap.get(target);\n if (existingProxy) {\n return existingProxy;\n }\n const targetType = getTargetType(target);\n if (targetType === 0) {\n return target;\n }\n const proxy = new Proxy(target, targetType === 2 ? collectionHandlers : baseHandlers);\n proxyMap.set(target, proxy);\n return proxy;\n}\nfunction toRaw(observed) {\n return observed && toRaw(observed["__v_raw"]) || observed;\n}\nfunction isRef(r) {\n return Boolean(r && r.__v_isRef === true);\n}\n\n// packages/alpinejs/src/magics/$nextTick.js\nmagic("nextTick", () => nextTick);\n\n// packages/alpinejs/src/magics/$dispatch.js\nmagic("dispatch", (el) => dispatch.bind(dispatch, el));\n\n// packages/alpinejs/src/magics/$watch.js\nmagic("watch", (el, {evaluateLater: evaluateLater2, effect: effect3}) => (key, callback) =>
1 {\n let evaluate2 = evaluateLater2(key);\n let firstTime = true;\n let oldValue;\n let effectReference = effect3(() => evaluate2((value) => {\n JSON.stringify(value);\n if (!firstTime) {\n queueMicrotask(() => {\n callback(value, oldValue);\n oldValue = value;\n });\n } else {\n oldValue = value;\n }\n firstTime = false;\n }));\n el._x_effects.delete(effectReference);\n});\n\n// packages/alpinejs/src/magics/$store.js\nmagic("store", getStores);\n\n// packages/alpinejs/src/magics/$data.js\nmagic("data", (el) => scope(el));\n\n// packages/alpinejs/src/magics/$root.js\nmagic("root", (el) => closestRoot(el));\n\n// packages/alpinejs/src/magics/$refs.js\nmagic("refs", (el) => {\n if (el._x_refs_proxy)\n return el._x_refs_proxy;\n el._x_refs_proxy = mergeProxies(getArrayOfRefObject(el));\n return el._x_refs_proxy;\n});\nfunction getArrayOfRefObject(el) {\n let refObjects = [];\n let currentEl = el;\n while (currentEl) {\n if (currentEl._x_refs)\n refObjects.push(currentEl._x_refs);\n currentEl = currentEl.parentNode;\n }\n return refObjects;\n}\n\n// packages/alpinejs/src/ids.js\nvar globalIdMemo = {};\nfunction findAndIncrementId(name) {\n if (!globalIdMemo[name])\n globalIdMemo[name] = 0;\n return ++globalIdMemo[name];\n}\nfunction closestIdRoot(el, name) {\n return findClosest(el, (element) => {\n if (element._x_ids && element._x_ids[name])\n return true;\n });\n}\nfunction setIdRoot(el, name) {\n if (!el._x_ids)\n el._x_ids = {};\n if (!el._x_ids[name])\n el._x_ids[name] = findAndIncrementId(name);\n}\n\n// packages/alpinejs/src/magics/$id.js\nmagic("id", (el) => (name, key = null) => {\n let root = closestIdRoot(el, name);\n let id = root ? root._x_ids[name] : findAndIncrementId(name);\n return key ? `${name}-${id}-${key}` : `${name}-${id}`;\n});\n\n// packages/alpinejs/src/magics/$el.js\nmagic("el", (el) => el);\n\n// packages/alpinejs/src/magics/index.js\nwarnMissingPluginMagic("Focus", "focus", "focus");\nwarnMissingPluginMagic("Persist", "persist", "persist");\nfunction warnMissingPluginMagic(name, magicName, slug) {\n magic(magicName, (el) => warn(`You can\'t use [$${directiveName}] without first installing the "${name}" plugin here: https://alpinejs.dev/plugins/${slug}`, el));\n}\n\n// packages/alpinejs/src/entangle.js\nfunction entangle({get: outerGet, set: outerSet}, {get: innerGet, set: innerSet}) {\n let firstRun = true;\n let outerHash, innerHash, outerHashLatest, innerHashLatest;\n let reference = effect(() => {\n let outer, inner;\n if (firstRun) {\n outer = outerGet();\n innerSet(outer);\n inner = innerGet();\n firstRun = false;\n } else {\n outer = outerGet();\n inner = innerGet();\n outerHashLatest = JSON.stringify(outer);\n innerHashLatest = JSON.stringify(inner);\n if (outerHashLatest !== outerHash) {\n inner = innerGet();\n innerSet(outer);\n inner = outer;\n } else {\n outerSet(inner);\n outer = inner;\n }\n }\n outerHash = JSON.stringify(outer);\n innerHash = JSON.stringify(inner);\n });\n return () => {\n release(reference);\n };\n}\n\n// packages/alpinejs/src/directives/x-modelable.js\ndirective("modelable", (el, {expression}, {effect: effect3, evaluateLater: evaluateLater2, cleanup: cleanup2}) => {\n let func = evaluateLater2(expression);\n let innerGet = () => {\n let result;\n func((i) => result = i);\n return result;\n };\n let evaluateInnerSet = evaluateLater2(`${expression} = __placeholder`);\n let innerSet = (val) => evaluateInnerSet(() => {\n }, {scope: {__placeholder: val}});\n let initialValue = innerGet();\n innerSet(initialValue);\n queueMicrotask(() => {\n if (!el._x_model)\n return;\n el._x_removeModelListeners["default"]();\n let outerGet = el._x_model.get;\n let outerSet = el._x_model.set;\n let releaseEntanglement = entangle({\n get() {\n return outerGet();\n },\n set(value) {\n outerSet(value);\n }\n }, {\n get() {\n return innerGet();\n },\n set(value) {\n innerSet(value);\n }\n });\n cleanup2(releaseEntanglement);\n });\n});\n\n// packages/alpinejs/src/directives/x-teleport.js\nvar teleportContainerDuringClone = document.createElement("div");\ndirective("teleport", (el, {modifiers, expression}, {cleanup: cleanup2}) =>
1 {\n if (el.tagName.toLowerCase() !== "template")\n warn("x-teleport can only be used on a <template> tag", el);\n let target = skipDuringClone(() => {\n return document.querySelector(expression);\n }, () => {\n return teleportContainerDuringClone;\n })();\n if (!target)\n warn(`Cannot find x-teleport element for selector: "${expression}"`);\n let clone2 = el.content.cloneNode(true).firstElementChild;\n el._x_teleport = clone2;\n clone2._x_teleportBack = el;\n if (el._x_forwardEvents) {\n el._x_forwardEvents.forEach((eventName) => {\n clone2.addEventListener(eventName, (e) => {\n e.stopPropagation();\n el.dispatchEvent(new e.constructor(e.type, e));\n });\n });\n }\n addScopeToNode(clone2, {}, el);\n mutateDom(() => {\n if (modifiers.includes("prepend")) {\n target.parentNode.insertBefore(clone2, target);\n } else if (modifiers.includes("append")) {\n target.parentNode.insertBefore(clone2, target.nextSibling);\n } else {\n target.appendChild(clone2);\n }\n initTree(clone2);\n clone2._x_ignore = true;\n });\n cleanup2(() => clone2.remove());\n});\n\n// packages/alpinejs/src/directives/x-ignore.js\nvar handler = () => {\n};\nhandler.inline = (el, {modifiers}, {cleanup: cleanup2}) => {\n modifiers.includes("self") ? el._x_ignoreSelf = true : el._x_ignore = true;\n cleanup2(() =>
1 {\n modifiers.includes("self") ? delete el._x_ignoreSelf : delete el._x_ignore;\n });\n};\ndirective("ignore", handler);\n\n// packages/alpinejs/src/directives/x-effect.js\ndirective("effect", (el, {expression}, {effect: effect3}) => effect3(evaluateLater(el, expression)));\n\n// packages/alpinejs/src/utils/on.js\nfunction on(el, event, modifiers, callback) {\n let listenerTarget = el;\n let handler4 = (e) => callback(e);\n let options = {};\n let wrapHandler = (callback2, wrapper) => (e) => wrapper(callback2, e);\n if (modifiers.includes("dot"))\n event = dotSyntax(event);\n if (modifiers.includes("camel"))\n event = camelCase2(event);\n if (modifiers.includes("passive"))\n options.passive = true;\n if (modifiers.includes("capture"))\n options.capture = true;\n if (modifiers.includes("window"))\n listenerTarget = window;\n if (modifiers.includes("document"))\n listenerTarget = document;\n if (modifiers.includes("debounce")) {\n let nextModifier = modifiers[modifiers.indexOf("debounce") + 1] || "invalid-wait";\n let wait = isNumeric(nextModifier.split("ms")[0]) ? Number(nextModifier.split("ms")[0]) : 250;\n handler4 = debounce(handler4, wait);\n }\n if (modifiers.includes("throttle")) {\n let nextModifier = modifiers[modifiers.indexOf("throttle") + 1] || "invalid-wait";\n let wait = isNumeric(nextModifier.split("ms")[0]) ? Number(nextModifier.split("ms")[0]) : 250;\n handler4 = throttle(handler4, wait);\n }\n if (modifiers.includes("prevent"))\n handler4 = wrapHandler(handler4, (next, e) => {\n e.preventDefault();\n next(e);\n });\n if (modifiers.includes("stop"))\n handler4 = wrapHandler(handler4, (next, e) => {\n e.stopPropagation();\n next(e);\n });\n if (modifiers.includes("self"))\n handler4 = wrapHandler(handler4, (next, e) => {\n e.target === el && next(e);\n });\n if (modifiers.includes("away") || modifiers.includes("outside")) {\n listenerTarget = document;\n handler4 = wrapHandler(handler4, (next, e) => {\n if (el.contains(e.target))\n return;\n if (e.target.isConnected === false)\n return;\n if (el.offsetWidth < 1 && el.offsetHeight < 1)\n return;\n if (el._x_isShown === false)\n return;\n next(e);\n });\n }\n if (modifiers.includes("once")) {\n handler4 = wrapHandler(handler4, (next, e) => {\n next(e);\n listenerTarget.removeEventListener(event, handler4, options);\n });\n }\n handler4 = wrapHandler(handler4, (next, e) => {\n if (isKeyEvent(event)) {\n if (isListeningForASpecificKeyThatHasntBeenPressed(e, modifiers)) {\n return;\n }\n }\n next(e);\n });\n listenerTarget.addEventListener(event, handler4, options);\n return () => {\n listenerTarget.removeEventListener(event, handler4, options);\n };\n}\nfunction dotSyntax(subject) {\n return subject.replace(/-/g, ".");\n}\nfunction camelCase2(subject) {\n return subject.toLowerCase().replace(/-(\\w)/g, (match, char) => char.toUpperCase());\n}\nfunction isNumeric(subject) {\n return !Array.isArray(subject) && !isNaN(subject);\n}\nfunction kebabCase2(subject) {\n if ([" ", "_"].includes(subject))\n return subject;\n return subject.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[_\\s]/, "-").toLowerCase();\n}\nfunction isKeyEvent(event) {\n return ["keydown", "keyup"].includes(event);\n}\nfunction isListeningForASpecificKeyThatHasntBeenPressed(e, modifiers) {\n let keyModifiers = modifiers.filter((i) => {\n return !["window", "document", "prevent", "stop", "once", "capture"].includes(i);\n });\n if (keyModifiers.includes("debounce")) {\n let debounceIndex = keyModifiers.indexOf("debounce");\n keyModifiers.splice(debounceIndex, isNumeric((keyModifiers[debounceIndex + 1] || "invalid-wait").split("ms")[0]) ? 2 : 1);\n }\n if (keyModifiers.includes("throttle")) {\n let debounceIndex = keyModifiers.indexOf("throttle");\n keyModifiers.splice(debounceIndex, isNumeric((keyModifiers[debounceIndex + 1] || "invalid-wait").split("ms")[0]) ? 2 : 1);\n }\n if (keyModifiers.length === 0)\n return false;\n if (keyModifiers.length === 1 && keyToModifiers(e.key).includes(keyModifiers[0]))\n return false;\n const systemKeyModifiers = ["ctrl", "shift", "alt", "meta", "cmd", "super"];\n const selectedSystemKeyModifiers = systemKeyModifiers.filter((modifier) => keyModifiers.includes(modifier));\n keyModifiers = keyModifiers.filter((i) => !selectedSystemKeyModifiers.includes(i));\n if (selectedSystemKeyModifiers.length > 0) {\n const activelyPressedKeyModifiers = selectedSystemKeyModifiers.filter((modifier) => {\n if (modifier === "cmd" || modifier === "super")\n modifier = "meta";\n return e[`${modifier}Key`];\n });\n if (activelyPressedKeyModifiers.length === selectedSystemKeyModifiers.length) {\n if (keyToModifiers(e.key).includes(keyModifiers[0]))\n return false;\n }\n }\n return true;\n}\nfunction keyToModifiers(key) {\n if (!key)\n return [];\n key = kebabCase2(key);\n let modifierToKeyMap = {\n ctrl: "control",\n slash: "/",\n space: " ",\n spacebar: " ",\n cmd: "meta",\n esc: "escape",\n up: "arrow-up",\n down: "arrow-down",\n left: "arrow-left",\n right: "arrow-right",\n period: ".",\n equal: "=",\n minus: "-",\n underscore: "_"\n };\n modifierToKeyMap[key] = key;\n return Object.keys(modifierToKeyMap).map((modifier) => {\n if (modifierToKeyMap[modifier] === key)\n return modifier;\n }).filter((modifier) => modifier);\n}\n\n// packages/alpinejs/src/directives/x-model.js\ndirective("model", (el, {modifiers, expression}, {effect: effect3, cleanup: cleanup2}) =>
1 {\n let scopeTarget = el;\n if (modifiers.includes("parent")) {\n scopeTarget = el.parentNode;\n }\n let evaluateGet = evaluateLater(scopeTarget, expression);\n let evaluateSet;\n if (typeof expression === "string") {\n evaluateSet = evaluateLater(scopeTarget, `${expression} = __placeholder`);\n } else if (typeof expression === "function" && typeof expression() === "string") {\n evaluateSet = evaluateLater(scopeTarget, `${expression()} = __placeholder`);\n } else {\n evaluateSet = () => {\n };\n }\n let getValue = () => {\n let result;\n evaluateGet((value) => result = value);\n return isGetterSetter(result) ? result.get() : result;\n };\n let setValue = (value) => {\n let result;\n evaluateGet((value2) => result = value2);\n if (isGetterSetter(result)) {\n result.set(value);\n } else {\n evaluateSet(() => {\n }, {\n scope: {__placeholder: value}\n });\n }\n };\n if (typeof expression === "string" && el.type === "radio") {\n mutateDom(() => {\n if (!el.hasAttribute("name"))\n el.setAttribute("name", expression);\n });\n }\n var event = el.tagName.toLowerCase() === "select" || ["checkbox", "radio"].includes(el.type) || modifiers.includes("lazy") ? "change" : "input";\n let removeListener = isCloning ? () => {\n } : on(el, event, modifiers, (e) => {\n setValue(getInputValue(el, modifiers, e, getValue()));\n });\n if (modifiers.includes("fill") && [null, ""].includes(getValue())) {\n el.dispatchEvent(new Event(event, {}));\n }\n if (!el._x_removeModelListeners)\n el._x_removeModelListeners = {};\n el._x_removeModelListeners["default"] = removeListener;\n cleanup2(() => el._x_removeModelListeners["default"]());\n if (el.form) {\n let removeResetListener = on(el.form, "reset", [], (e) => {\n nextTick(() => el._x_model && el._x_model.set(el.value));\n });\n cleanup2(() => removeResetListener());\n }\n el._x_model = {\n get() {\n return getValue();\n },\n set(value) {\n setValue(value);\n }\n };\n el._x_forceModelUpdate = (value) => {\n value = value === void 0 ? getValue() : value;\n if (value === void 0 && typeof expression === "string" && expression.match(/\\./))\n value = "";\n window.fromModel = true;\n mutateDom(() => bind(el, "value", value));\n delete window.fromModel;\n };\n effect3(() => {\n let value = getValue();\n if (modifiers.includes("unintrusive") && document.activeElement.isSameNode(el))\n return;\n el._x_forceModelUpdate(value);\n });\n});\nfunction getInputValue(el, modifiers, event, currentValue) {\n return mutateDom(() => {\n if (event instanceof CustomEvent && event.detail !== void 0)\n return event.detail ?? event.target.value;\n else if (el.type === "checkbox") {\n if (Array.isArray(currentValue)) {\n let newValue = modifiers.includes("number") ? safeParseNumber(event.target.value) : event.target.value;\n return event.target.checked ? currentValue.concat([newValue]) : currentValue.filter((el2) => !checkedAttrLooseCompare2(el2, newValue));\n } else {\n return event.target.checked;\n }\n } else if (el.tagName.toLowerCase() === "select" && el.multiple) {\n return modifiers.includes("number") ? Array.from(event.target.selectedOptions).map((option) => {\n let rawValue = option.value || option.text;\n return safeParseNumber(rawValue);\n }) : Array.from(event.target.selectedOptions).map((option) => {\n return option.value || option.text;\n });\n } else {\n let rawValue = event.target.value;\n return modifiers.includes("number") ? safeParseNumber(rawValue) : modifiers.includes("trim") ? rawValue.trim() : rawValue;\n }\n });\n}\nfunction safeParseNumber(rawValue) {\n let number = rawValue ? parseFloat(rawValue) : null;\n return isNumeric2(number) ? number : rawValue;\n}\nfunction checkedAttrLooseCompare2(valueA, valueB) {\n return valueA == valueB;\n}\nfunction isNumeric2(subject) {\n return !Array.isArray(subject) && !isNaN(subject);\n}\nfunction isGetterSetter(value) {\n return value !== null && typeof value === "object" && typeof value.get === "function" && typeof value.set === "function";\n}\n\n// packages/alpinejs/src/directives/x-cloak.js\ndirective("cloak", (el) => queueMicrotask(() => mutateDom(() => el.removeAttribute(prefix("cloak")))));\n\n// packages/alpinejs/src/directives/x-init.js\naddInitSelector(() => `[${prefix("init")}]`);\ndirective("init", skipDuringClone((el, {expression}, {evaluate: evaluate2}) =>
1 {\n if (typeof expression === "string") {\n return !!expression.trim() && evaluate2(expression, {}, false);\n }\n return evaluate2(expression, {}, false);\n}));\n\n// packages/alpinejs/src/directives/x-text.js\ndirective("text", (el, {expression}, {effect: effect3, evaluateLater: evaluateLater2}) => {\n let evaluate2 = evaluateLater2(expression);\n effect3(() => {\n evaluate2((value) => {\n mutateDom(() => {\n el.textContent = value;\n });\n });\n });\n});\n\n// packages/alpinejs/src/directives/x-html.js\ndirective("html", (el, {expression}, {effect: effect3, evaluateLater: evaluateLater2}) => {\n let evaluate2 = evaluateLater2(expression);\n effect3(() => {\n evaluate2((value) => {\n mutateDom(() => {\n el.innerHTML = value;\n el._x_ignoreSelf = true;\n initTree(el);\n delete el._x_ignoreSelf;\n });\n });\n });\n});\n\n// packages/alpinejs/src/directives/x-bind.js\nmapAttributes(startingWith(":", into(prefix("bind:"))));\nvar handler2 = (el, {value, modifiers, expression, original}, {effect: effect3}) => {\n if (!value) {\n let bindingProviders = {};\n injectBindingProviders(bindingProviders);\n let getBindings = evaluateLater(el, expression);\n getBindings((bindings) => {\n applyBindingsObject(el, bindings, original);\n }, {scope: bindingProviders});\n return;\n }\n if (value === "key")\n return storeKeyForXFor(el, expression);\n if (el._x_inlineBindings && el._x_inlineBindings[value] && el._x_inlineBindings[value].extract) {\n return;\n }\n let evaluate2 = evaluateLater(el, expression);\n effect3(() => evaluate2((result) => {\n if (result === void 0 && typeof expression === "string" && expression.match(/\\./)) {\n result = "";\n }\n mutateDom(() => bind(el, value, result, modifiers));\n }));\n};\nhandler2.inline = (el, {value, modifiers, expression}) => {\n if (!value)\n return;\n if (!el._x_inlineBindings)\n el._x_inlineBindings = {};\n el._x_inlineBindings[value] = {expression, extract: false};\n};\ndirective("bind", handler2);\nfunction storeKeyForXFor(el, expression) {\n el._x_keyExpression = expression;\n}\n\n// packages/alpinejs/src/directives/x-data.js\naddRootSelector(() => `[${prefix("data")}]`);\ndirective("data", skipDuringClone((el, {expression}, {cleanup: cleanup2}) => {\n expression = expression === "" ? "{}" : expression;\n let magicContext = {};\n injectMagics(magicContext, el);\n let dataProviderContext = {};\n injectDataProviders(dataProviderContext, magicContext);\n let data2 = evaluate(el, expression, {scope: dataProviderContext});\n if (data2 === void 0 || data2 === true)\n data2 = {};\n injectMagics(data2, el);\n let reactiveData = reactive(data2);\n initInterceptors(reactiveData);\n let undo = addScopeToNode(el, reactiveData);\n reactiveData["init"] && evaluate(el, reactiveData["init"]);\n cleanup2(() =>
1 {\n reactiveData["destroy"] && evaluate(el, reactiveData["destroy"]);\n undo();\n });\n}));\n\n// packages/alpinejs/src/directives/x-show.js\ndirective("show", (el, {modifiers, expression}, {effect: effect3}) => {\n let evaluate2 = evaluateLater(el, expression);\n if (!el._x_doHide)\n el._x_doHide = () => {\n mutateDom(() => {\n el.style.setProperty("display", "none", modifiers.includes("important") ? "important" : void 0);\n });\n };\n if (!el._x_doShow)\n el._x_doShow = () => {\n mutateDom(() => {\n if (el.style.length === 1 && el.style.display === "none") {\n el.removeAttribute("style");\n } else {\n el.style.removeProperty("display");\n }\n });\n };\n let hide = () => {\n el._x_doHide();\n el._x_isShown = false;\n };\n let show = () => {\n el._x_doShow();\n el._x_isShown = true;\n };\n let clickAwayCompatibleShow = () => setTimeout(show);\n let toggle = once((value) => value ? show() : hide(), (value) => {\n if (typeof el._x_toggleAndCascadeWithTransitions === "function") {\n el._x_toggleAndCascadeWithTransitions(el, value, show, hide);\n } else {\n value ? clickAwayCompatibleShow() : hide();\n }\n });\n let oldValue;\n let firstTime = true;\n effect3(() => evaluate2((value) => {\n if (!firstTime && value === oldValue)\n return;\n if (modifiers.includes("immediate"))\n value ? clickAwayCompatibleShow() : hide();\n toggle(value);\n oldValue = value;\n firstTime = false;\n }));\n});\n\n// packages/alpinejs/src/directives/x-for.js\ndirective("for", (el, {expression}, {effect: effect3, cleanup: cleanup2}) => {\n let iteratorNames = parseForExpression(expression);\n let evaluateItems = evaluateLater(el, iteratorNames.items);\n let evaluateKey = evaluateLater(el, el._x_keyExpression || "index");\n el._x_prevKeys = [];\n el._x_lookup = {};\n effect3(() => loop(el, iteratorNames, evaluateItems, evaluateKey));\n cleanup2(() =>
1 {\n Object.values(el._x_lookup).forEach((el2) => el2.remove());\n delete el._x_prevKeys;\n delete el._x_lookup;\n });\n});\nfunction loop(el, iteratorNames, evaluateItems, evaluateKey) {\n let isObject2 = (i) => typeof i === "object" && !Array.isArray(i);\n let templateEl = el;\n evaluateItems((items) => {\n if (isNumeric3(items) && items >= 0) {\n items = Array.from(Array(items).keys(), (i) => i + 1);\n }\n if (items === void 0)\n items = [];\n let lookup = el._x_lookup;\n let prevKeys = el._x_prevKeys;\n let scopes = [];\n let keys = [];\n if (isObject2(items)) {\n items = Object.entries(items).map(([key, value]) => {\n let scope2 = getIterationScopeVariables(iteratorNames, value, key, items);\n evaluateKey((value2) => keys.push(value2), {scope: {index: key, ...scope2}});\n scopes.push(scope2);\n });\n } else {\n for (let i = 0; i < items.length; i++) {\n let scope2 = getIterationScopeVariables(iteratorNames, items[i], i, items);\n evaluateKey((value) => keys.push(value), {scope: {index: i, ...scope2}});\n scopes.push(scope2);\n }\n }\n let adds = [];\n let moves = [];\n let removes = [];\n let sames = [];\n for (let i = 0; i < prevKeys.length; i++) {\n let key = prevKeys[i];\n if (keys.indexOf(key) === -1)\n removes.push(key);\n }\n prevKeys = prevKeys.filter((key) => !removes.includes(key));\n let lastKey = "template";\n for (let i = 0; i < keys.length; i++) {\n let key = keys[i];\n let prevIndex = prevKeys.indexOf(key);\n if (prevIndex === -1) {\n prevKeys.splice(i, 0, key);\n adds.push([lastKey, i]);\n } else if (prevIndex !== i) {\n let keyInSpot = prevKeys.splice(i, 1)[0];\n let keyForSpot = prevKeys.splice(prevIndex - 1, 1)[0];\n prevKeys.splice(i, 0, keyForSpot);\n prevKeys.splice(prevIndex, 0, keyInSpot);\n moves.push([keyInSpot, keyForSpot]);\n } else {\n sames.push(key);\n }\n lastKey = key;\n }\n for (let i = 0; i < removes.length; i++) {\n let key = removes[i];\n if (!!lookup[key]._x_effects) {\n lookup[key]._x_effects.forEach(dequeueJob);\n }\n lookup[key].remove();\n lookup[key] = null;\n delete lookup[key];\n }\n for (let i = 0; i < moves.length; i++) {\n let [keyInSpot, keyForSpot] = moves[i];\n let elInSpot = lookup[keyInSpot];\n let elForSpot = lookup[keyForSpot];\n let marker = document.createElement("div");\n mutateDom(() => {\n if (!elForSpot)\n warn(`x-for ":key" is undefined or invalid`, templateEl);\n elForSpot.after(marker);\n elInSpot.after(elForSpot);\n elForSpot._x_currentIfEl && elForSpot.after(elForSpot._x_currentIfEl);\n marker.before(elInSpot);\n elInSpot._x_currentIfEl && elInSpot.after(elInSpot._x_currentIfEl);\n marker.remove();\n });\n elForSpot._x_refreshXForScope(scopes[keys.indexOf(keyForSpot)]);\n }\n for (let i = 0; i < adds.length; i++) {\n let [lastKey2, index] = adds[i];\n let lastEl = lastKey2 === "template" ? templateEl : lookup[lastKey2];\n if (lastEl._x_currentIfEl)\n lastEl = lastEl._x_currentIfEl;\n let scope2 = scopes[index];\n let key = keys[index];\n let clone2 = document.importNode(templateEl.content, true).firstElementChild;\n let reactiveScope = reactive(scope2);\n addScopeToNode(clone2, reactiveScope, templateEl);\n clone2._x_refreshXForScope = (newScope) => {\n Object.entries(newScope).forEach(([key2, value]) => {\n reactiveScope[key2] = value;\n });\n };\n mutateDom(() => {\n lastEl.after(clone2);\n initTree(clone2);\n });\n if (typeof key === "object") {\n warn("x-for key cannot be an object, it must be a string or an integer", templateEl);\n }\n lookup[key] = clone2;\n }\n for (let i = 0; i < sames.length; i++) {\n lookup[sames[i]]._x_refreshXForScope(scopes[keys.indexOf(sames[i])]);\n }\n templateEl._x_prevKeys = keys;\n });\n}\nfunction parseForExpression(expression) {\n let forIteratorRE = /,([^,\\}
1\\]]*)(?:,([^,\\}\\]]*))?$/;\n let stripParensRE = /^\\s*\\(|\\)\\s*$/g;\n let forAliasRE = /([\\s\\S]*?)\\s+(?:in|of)\\s+([\\s\\S]*)/;\n let inMatch = expression.match(forAliasRE);\n if (!inMatch)\n return;\n let res = {};\n res.items = inMatch[2].trim();\n let item = inMatch[1].replace(stripParensRE, "").trim();\n let iteratorMatch = item.match(forIteratorRE);\n if (iteratorMatch) {\n res.item = item.replace(forIteratorRE, "").trim();\n res.index = iteratorMatch[1].trim();\n if (iteratorMatch[2]) {\n res.collection = iteratorMatch[2].trim();\n }\n } else {\n res.item = item;\n }\n return res;\n}\nfunction getIterationScopeVariables(iteratorNames, item, index, items) {\n let scopeVariables = {};\n if (/^\\[.*\\]$/.test(iteratorNames.item) && Array.isArray(item)) {\n let names = iteratorNames.item.replace("[", "").replace("]", "").split(",").map((i) => i.trim());\n names.forEach((name, i) => {\n scopeVariables[name] = item[i];\n });\n } else if (/^\\{.*\\}$/.test(iteratorNames.item) && !Array.isArray(item) && typeof item === "object") {\n let names = iteratorNames.item.replace("{", "").replace("}", "").split(",").map((i) => i.trim());\n names.forEach((name) => {\n scopeVariables[name] = item[name];\n });\n } else {\n scopeVariables[iteratorNames.item] = item;\n }\n if (iteratorNames.index)\n scopeVariables[iteratorNames.index] = index;\n if (iteratorNames.collection)\n scopeVariables[iteratorNames.collection] = items;\n return scopeVariables;\n}\nfunction isNumeric3(subject) {\n return !Array.isArray(subject) && !isNaN(subject);\n}\n\n// packages/alpinejs/src/directives/x-ref.js\nfunction handler3() {\n}\nhandler3.inline = (el, {expression}, {cleanup: cleanup2}) => {\n let root = closestRoot(el);\n if (!root._x_refs)\n root._x_refs = {};\n root._x_refs[expression] = el;\n cleanup2(() => delete root._x_refs[expression]);\n};\ndirective("ref", handler3);\n\n// packages/alpinejs/src/directives/x-if.js\ndirective("if", (el, {expression}, {effect: effect3, cleanup: cleanup2}) => {\n let evaluate2 = evaluateLater(el, expression);\n let show = () => {\n if (el._x_currentIfEl)\n return el._x_currentIfEl;\n let clone2 = el.content.cloneNode(true).firstElementChild;\n addScopeToNode(clone2, {}, el);\n mutateDom(() => {\n el.after(clone2);\n initTree(clone2);\n });\n el._x_currentIfEl = clone2;\n el._x_undoIf = () => {\n walk(clone2, (node) => {\n if (!!node._x_effects) {\n node._x_effects.forEach(dequeueJob);\n }\n });\n clone2.remove();\n delete el._x_currentIfEl;\n };\n return clone2;\n };\n let hide = () => {\n if (!el._x_undoIf)\n return;\n el._x_undoIf();\n delete el._x_undoIf;\n };\n effect3(() => evaluate2((value) => {\n value ? show() : hide();\n }));\n cleanup2(() => el._x_undoIf && el._x_undoIf());\n});\n\n// packages/alpinejs/src/directives/x-id.js\ndirective("id", (el, {expression}, {evaluate: evaluate2}) => {\n let names = evaluate2(expression);\n names.forEach((name) => setIdRoot(el, name));\n});\n\n// packages/alpinejs/src/directives/x-on.js\nmapAttributes(startingWith("@", into(prefix("on:"))));\ndirective("on", skipDuringClone((el, {value, modifiers, expression}, {cleanup: cleanup2}) => {\n let evaluate2 = expression ? evaluateLater(el, expression) : () => {\n };\n if (el.tagName.toLowerCase() === "template") {\n if (!el._x_forwardEvents)\n el._x_forwardEvents = [];\n if (!el._x_forwardEvents.includes(value))\n el._x_forwardEvents.push(value);\n }\n let removeListener = on(el, value, modifiers, (e) => {\n evaluate2(() => {\n }, {scope: {$event: e}, params: [e]});\n });\n cleanup2(() => removeListener());\n}));\n\n// packages/alpinejs/src/directives/index.js\nwarnMissingPluginDirective("Collapse", "collapse", "collapse");\nwarnMissingPluginDirective("Intersect", "intersect", "intersect");\nwarnMissingPluginDirective("Focus", "trap", "focus");\nwarnMissingPluginDirective("Mask", "mask", "mask");\nfunction warnMissingPluginDirective(name, directiveName2, slug) {\n directive(directiveName2, (el) => warn(`You can\'t use [x-${directiveName2}] without first installing the "${name}" plugin here: https://alpinejs.dev/plugins/${slug}`, el));\n}\n\n// packages/alpinejs/src/index.js\nalpine_default.setEvaluator(normalEvaluator);\nalpine_default.setReactivityEngine({reactive: reactive2, effect: effect2, release: stop, raw: toRaw});\nvar src_default = alpine_default;\n\n// packages/alpinejs/builds/module.js\nvar module_default = src_default;\n\n\n;// CONCATENATED MODULE: ./js/app.js\n// Import dependencies\n//\n// If you no longer want to use a dependency, remember\n// to also remove its path from "config.paths.watched".\n\n\n\n\n\n\n\n//import postscribe from \'postscribe\'\n\n//import postcribe from \'../vendor/postscribe\'\n//import socket from "./socket"\n\n\n\n\nconst userAgent = navigator.userAgent.toLowerCase();\nconst human = userAgent.includes("bot") ? false : true;
1\n\n//import \'alpinejs\';\n\nwindow.Alpine = module_default;\nmodule_default.start();\nlet csrfToken = document.querySelector("meta[name=\'csrf-token\']").getAttribute("content");\n\n// NOTIFICACIONES //\n\nconst applicationServerPublicKey = "BG2FvaWurlCXXeyEN6R0muQuhrBgimi7QvNjcFIOoCN9wyeQJNxSkFlunAv62WsW72JpeDgbLlFyV8P6ZogvEAU";\nlet pushButton = null;\nlet canalesDiv = null;\nlet isSubscribed = false;\nlet swRegistration = null;\nfunction urlB64ToUint8Array(base64String) {\n const padding = \'=\'.repeat((4 - base64String.length % 4) % 4);\n const base64 = (base64String + padding).replace(/\\-/g, \'+\').replace(/_/g, \'/\');\n const rawData = window.atob(base64);\n const outputArray = new Uint8Array(rawData.length);\n for (let i = 0; i < rawData.length; ++i) {\n outputArray[i] = rawData.charCodeAt(i);\n }\n return outputArray;\n}\nfunction updateBtn() {\n if (Notification.permission === \'denied\') {\n pushButton.textContent = \'Notificaciones Push Bloqueadas.\';\n pushButton.disabled = true;\n updateSubscriptionOnServer(null);\n return;\n }\n if (isSubscribed) {\n pushButton.textContent = \'Desactivar Notificaciones Push\';\n } else {\n pushButton.textContent = \'Activar Notificaciones Push\';\n }\n pushButton.disabled = false;\n}\nfunction updateSubscriptionOnServer(subscription, inicial) {\n var canales = radioCanales();\n if (inicial) {\n canales = ["peticion_inicial"];\n }\n if (subscription) {\n sendSubscriptionToBackEnd(subscription, canales);\n }\n const subscriptionJson = document.querySelector(\'.js-subscription-json\');\n const subscriptionDetails = document.querySelector(\'.js-subscription-details\');\n if (subscription) {\n subscriptionJson.textContent = JSON.stringify(subscription);\n subscriptionDetails.classList.remove(\'is-invisible\');\n } else {\n subscriptionDetails.classList.add(\'is-invisible\');\n }\n}\nfunction subscribeUser() {\n const applicationServerKey = urlB64ToUint8Array(applicationServerublicKey);\n swRegistration.pushManager.subscribe({\n userVisibleOnly: true,\n applicationServerKey: applicationServerKey\n }).then(function (subscription) {\n updateSubscriptionOnServer(subscription);\n isSubscribed = true;\n updateBtn();\n }).catch(function (err) {\n updateBtn();\n });\n}\nfunction unsubscribeUser() {\n swRegistration.pushManager.getSubscription().then(function (subscription) {\n if (subscription) {\n deleteSubscriptionBackEnd(subscription);\n return subscription.unsubscribe();\n }\n }).catch(function (error) {\n console.log(\'Error unsubscribing\', error);\n }).then(function (subscription) {\n updateSubscriptionOnServer(null);\n console.log(\'User is unsubscribed.\');\n isSubscribed = false;\n updateBtn();\n //updateCanales([]);\n });\n}\nfunction initializeNotificationsUI(hook) {\n pushButton.addEventListener(\'click\', function () {\n pushButton.disabled = true;\n if (isSubscribed) {\n hook.pushEvent("suscrito", {\n "suscrito": "suscrito"\n });\n unsubscribeUser();\n } else {\n hook.pushEvent("suscrito", {\n "suscrito": "no_suscrito"\n });\n subscribeUser();\n }\n });\n\n // Set the initial subscription value\n swRegistration.pushManager.getSubscription().then(function (subscription) {\n isSubscribed = !(subscription === null);\n updateSubscriptionOnServer(subscription, "inicial");\n updateBtn();\n });\n}\nfunction sendSubscriptionToBackEnd(subscription, canales) {\n subscription = {\n "suscripcion_push": subscription,\n "canales": canales\n };\n return fetch(\'/api/suscripcionespush/\', {\n method: \'POST\',\n headers: {\n \'Content-Type\': \'application/json\'\n },\n body: JSON.stringify(subscription)\n }).then(function (response) {\n if (!response.ok) {\n throw new Error(\'Bad status code from server.\');\n }\n return response.json();\n }).then(function (responseData) {\n if (!(responseData.data && responseData.data.success)) {\n throw new Error(\'Bad response from server.\');\n } else {\n console.log(responseData.data);\n updateCanales(responseData.data["canales"], responseData.data["suscripciones"]);\n }\n });\n}\nfunction deleteSubscriptionBackEnd(subscription) {\n const endpoint = encodeURIComponent(subscription.endpoint);\n return fetch(\'/api/suscripcionespush/\' + endpoint, {\n method: \'DELETE\',\n headers: {\n \'Content-Type\': \'application/json\'\n }\n }).then(function (response) {\n if (!response.ok) {\n throw new Error(\'Bad status code from server.\');\n }\n return response.json();\n }).then(function (responseData) {\n if (!(responseData.data && responseData.data.success)) {\n throw new Error(\'Bad response from server.\');\n } else {\n updateCanales([]);\n }\n });\n}\nfunction updateCanales(canales, canales_activos) {\n canalesDiv.innerHTML = "";\n for (const canal of canales) {\n createCanal(canal, canales_activos);\n }\n}\nfunction createCanal(canal, canales_activos) {\n var activo = false;\n for (const canal_activo of canales_activos) {\n if (canal_activo == canal.id) {\n var activo = true;\n }\n }\n var checked = "";\n if (activo) {\n checked = "checked";\n }\n var div = document.createElement("div");\n var label_l = document.createElement(\'label\');\n label_l.htmlFor = canal.id;\n label_l.innerHTML = canal.nombre;\n div.appendChild(label_l);\n var span = document.createElement("span");\n span.classList.add(\'ckbx-style-1\');\n var button = document.createElement("input");\n button.type = "checkbox";\n button.value = canal.id;\n button.id = canal.id;\n button.checked = checked;\n span.appendChild(button);\n var label_c = document.createElement(\'label\');\n label_c.htmlFor = canal.id;\n span.appendChild(label_c);\n div.appendChild(span);\n canalesDiv.appendChild(div);\n button.addEventListener(\'change\', event => {\n subscribeUser();\n });\n}\nfunction radioCanales() {\n let activados = [];\n let checkboxes = document.querySelectorAll(\'input:checked\');
1\n checkboxes.forEach(checkbox => {\n activados.push(checkbox.value);\n });\n return activados;\n}\nfunction handleConnection() {\n if (navigator.onLine) {\n isReachable(getServerUrl()).then(function (online) {\n if (online) {\n console.log(\'online\');\n } else {\n console.log(\'no connectivity\');\n }\n });\n } else {\n console.log(\'offline\');\n }\n}\nfunction isReachable(url) {\n return fetch(url, {\n method: \'HEAD\',\n mode: \'no-cors\'\n }).then(function (resp) {\n return resp && (resp.ok || resp.type === \'opaque\');\n }).catch(function (err) {\n console.warn(\'[conn test failure]:\', err);\n });\n}\nfunction getServerUrl() {\n return window.location.origin;\n}\n\n// FIN NOTIFICACIONES\n\nconst summerNoteMin = {\n styleWithSpan: false,\n lang: \'es-ES\',\n height: 400,\n dialogsFade: true,\n toolbar: [[\'style\', [\'italic\', \'underline\', \'clear\']], [\'insert\', [\'link\', \'unlink\']]],\n cleaner: {\n notTime: 500,\n // Time to display Notifications.\n action: \'both\',\n // both|button|paste \'button\' only cleans via toolbar button, \'paste\' only clean when pasting content, both does both options.\n newline: \'<br>\',\n // Summernote\'s default is to use \'<p><br></p>\'\n notStyle: \'position:absolute;top:0;left:0;right:0\',\n // Position of Notification\n icon: \'<i class="note-icon">[x]</i>\',\n keepHtml: true,\n // Remove all Html formats\n keepClasses: false,\n // Remove Classes\n keepOnlyTags: [\'<br>\', \'<a>\', \'<p>\'],\n // If keepHtml is true, remove all tags except these\n badTags: [\'style\', \'script\', \'applet\', \'embed\', \'noframes\', \'noscript\', \'html\'],\n // Remove full tags with contents\n keepTagContents: [\'span\', \'font\', \'strong\'],\n // Remove full tags with contents\n badAttributes: [\'dir\', \'id\', \'style\', \'start\', \'name\', \'class\', \'align\', \'ontouchstart\', \'size\', \'face\', \'lang\'] // Remove attributes from remaining tags\n }\n};\nconst summerNoteConf = {\n styleWithSpan: false,\n lang: \'es-ES\',\n height: 400,\n dialogsFade: true,\n toolbar: [[\'style\', [\'bold\', \'italic\', \'underline\', \'clear\']], [\'font\', [\'strikethrough\', \'superscript\', \'subscript\']], [\'para\', [\'ul\', \'ol\', \'paragraph\']], [\'link\', [\'style\']], [\'insert\', [\'link\', \'unlink\']], [\'salto\', [\'articulo\', \'foto\', \'codigo\', \'documento\', \'borrar\']], [\'view\', [\'codeview\']], [\'insert\', [\'template\']]],\n popover: {\n image: [[\'custom\', [\'imageAttributes\', \'captionIt\']], [\'imagesize\', [\'imageSize100\', \'imageSize50\', \'imageSize25\']], [\'float\', [\'floatLeft\', \'floatRight\', \'floatNone\']], [\'remove\', [\'removeMedia\']]]\n },\n imageAttributes: {\n imageDialogLayout: \'default\',\n // default|horizontal\n icon: \'<i class="note-icon-pencil"/>\',\n removeEmpty: false // true = remove attributes | false = leave empty if present\n },\n displayFields: {\n imageBasic: true,\n // show/hide Title, Source, Alt fields\n imageExtra: true,\n // show/hide Alt, Class, Style, Role fields\n linkBasic: true,\n // show/hide URL and Target fields for link\n linkExtra: false // show/hide Class, Rel, Role fields for link\n },\n captionIt: {\n icon: \'<i class="note-icon-pencil"}/>\',\n // Leave empty or don\'t set for default Icon.\n figureClass: \'figure-interna\',\n figcaptionClass: \'pie\'\n },\n cleaner: {\n notTime: 500,\n // Time to display Notifications.\n action: \'both\',\n // both|button|paste \'button\' only cleans via toolbar button, \'paste\' only clean when pasting content, both does both options.\n newline: \'<br>\',\n // Summernote\'s default is to use \'<p><br></p>\'\n notStyle: \'position:absolute;top:0;left:0;right:0\',\n // Position of Notification\n icon: \'<i class="note-icon">[x]</i>\',\n keepHtml: true,\n // Remove all Html formats\n keepClasses: false,\n // Remove Classes\n keepOnlyTags: [\'<br>\', \'<a>\', \'<p>\'],\n // If keepHtml is true, remove all tags except these\n badTags: [\'style\', \'script\', \'applet\', \'embed\', \'noframes\', \'noscript\', \'html\'],\n // Remove full tags with contents\n keepTagContents: [\'span\', \'font\', \'strong\'],\n // Remove full tags with contents\n badAttributes: [\'dir\', \'id\', \'style\', \'start\', \'name\', \'class\', \'align\', \'ontouchstart\', \'size\', \'face\', \'lang\'] // Remove attributes from remaining tags\n },\n template: {\n path: \'/js/summernote/tpls\',\n list: {\n \'recuadro_generico\': \'Recuadro genérico\',\n \'recuadro_dcha\': \'Recuadro derecho\',\n \'recuadro_izq\': \'Recuadro izquierdo\',\n \'recuadro\': \'Recuadro "antiguo"\'\n }\n }\n};\nwindow.addEventListener("phx:quitar-body-overflows", e => {\n document.querySelector("body").classList.remove("overflow");\n});\nwindow.addEventListener("articulista:limpiar_url", e => {\n history.replaceState(\'\', document.title, window.location.href.split(\'#\')[0]);\n});\nwindow.addEventListener("articulista:menu", e => {\n var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n if (w > 768 && document.querySelector(\'#menu-bur-contenedor\')) {\n var menu_admin = 0;\n if (document.querySelector(\'#menu-admin\')) {\n menu_admin = document.querySelector(\'#menu-admin\').offsetHeight;\n }\n var publi = 0;\n if (basicos_visible(document.querySelector(\'#publi-cabecera\'))) {\n var {\n bottom\n } = document.querySelector(\'#publi-cabecera\').getBoundingClientRect();\n if (bottom > 1) {\n publi = bottom;\n }\n }\n var menu_arriba = document.querySelector(\'#menu-arriba\').offsetHeight - 1;\n var abajo = menu_arriba + menu_admin + publi;
1\n const menu_1 = document.querySelector(\'#menu-bur-contenedor\');\n menu_1.style.top = `${menu_arriba}px`;\n menu_1.style.height = `calc(100vh - ${abajo}px)`;\n const menu_secciones = document.querySelector(\'.menu-secciones\');\n const menu_secciones_container = document.getElementById("menu-secciones-escritorio");\n menu_secciones_container.appendChild(menu_secciones);\n const menu_secciones_h = menu_secciones.offsetHeight / 2;\n var {\n top\n } = document.querySelector(\'.secciones\').getBoundingClientRect();\n menu_secciones_container.style.top = `${top - menu_secciones_h}px`;\n if (document.querySelector(\'#menu-personal-contenedor\')) {\n const menu_2 = document.querySelector(\'#menu-personal-contenedor\');\n menu_2.style.top = `${menu_arriba}px`;\n menu_2.style.height = `calc(100vh - ${abajo}px)`;\n }\n }\n if (w < 768 && document.querySelector(\'#menu-bur-contenedor\')) {\n const menu_secciones = document.querySelector(\'.menu-secciones\');\n document.getElementById("menu-secciones-movil").appendChild(menu_secciones);\n }\n});\n\n// Base AUDIOS \n\nwindow.addEventListener("phx:cambiar-seleccion", e => {\n if (audio.paused) {\n liveSocket.hooks.AudioPlayer.datos_audio();\n }\n ;\n});\nwindow.addEventListener("phx:play-seleccion", e => {\n if (document.getElementById("seleccionar")) {\n liveSocket.hooks.AudioSeleccionar.mounted();\n }\n audio_origen = "recomendacion";\n liveSocket.hooks.AudioPlayer.audio_reproducir();\n});\nfunction segundos_a_string(s) {\n if (s === "undefined" || s == 0 || isNaN(s)) return "00:00";\n const h = Math.floor(s / 3600);\n const m = Math.floor(s % 3600 / 60);\n s = s % 60;\n s = parseInt(s);\n return [h, m > 9 ? m : h ? \'0\' + m : m || \'0\', s > 9 ? s : \'0\' + s].filter(a => a).join(\':\');\n}\nvar radiobot_api = "wss://radio.radiobot.org/api/live/nowplaying/websocket";\nvar socket_radio_bot = false;\nlet audio = false;\nlet audio_origen = "recomendacion";\nvar audio_progreso = document.querySelector(\'#progreso-audio\');\nvar audio_momento = 0;\nvar audio_position = document.querySelector("#audio-position");\nconst hooks = {\n TrackEvent: {\n mounted() {\n document.addEventListener("click", e => {\n if (this.liveSocket.isConnected()) {\n console.log(e.target);\n const el = e.target.closest("[id]");\n console.log(el);\n this.pushEvent("track_event", {\n tag: e.target.tagName,\n id: el.id,\n path: location.pathname\n }).catch(() => {});\n }\n });\n },\n destroyed() {\n document.removeEventListener("click", this.clickHandler);\n }\n },\n ScrollToInicio: {\n updated() {\n const el = document.getElementById("lista-inicio");\n if (el) {\n //el.scrollIntoView({ behavior: "smooth" })\n const y = el.getBoundingClientRect().top + window.scrollY - 100;\n window.scrollTo({\n top: y,\n behavior: "smooth"\n });\n }\n }\n },\n MantenerScroll: {\n mounted() {\n this.scrollX = window.scrollX;\n this.scrollY = window.scrollY;\n },\n updated() {\n if (this.scrollX !== undefined) {\n requestAnimationFrame(() => {\n window.scrollTo(this.scrollX, this.scrollY);\n });\n }\n this.scrollX = window.scrollX;\n this.scrollY = window.scrollY;\n }\n },\n EleccionesChart: {\n mounted() {\n this.cargarD3();\n },\n cargarD3() {\n if (typeof d3 !== \'undefined\') {\n this.inicializar();\n return;\n }\n const script = document.createElement(\'script\');\n script.src = \'https://cdnjs.cloudflare.com/ajax/libs/d3/6.0.0/d3.min.js\';\n script.integrity = \'sha512-9uJB6ZmL2UhBkQH2X1B+lbEFIDtlauO0fPUp0Rdo6Tz21a1awgSD+FfSykvd+gD3c8WQrwWeaEgMkPsDep3P8w==\';\n script.crossOrigin = \'anonymous\';\n script.referrerPolicy = \'no-referrer\';\n script.onload = () => {\n // Fallback: asegurar que D3 esté disponible\n setTimeout(() => this.inicializar(), 50);\n };\n\n // Fallback si onload no funciona\n script.onerror = () => {\n setTimeout(() => this.inicializar(), 500);\n };\n document.head.appendChild(script);\n },\n inicializar() {\n this.state = {\n data: JSON.parse(this.el.dataset.datos || \'{}\'),\n anho: this.el.dataset.anho,\n territorio: this.el.dataset.territorio,\n datosConsulta: JSON.parse(this.el.dataset.datosConsulta || \'{}\')\n };\n this.draw_all();\n },\n updated() {\n this.state.anho = this.el.dataset.anho;\n this.state.territorio = this.el.dataset.territorio;\n this.draw_all();\n },\n getSize(id) {\n const el = document.getElementById(id);\n if (!el || !el.clientWidth) return null;\n return {\n width: el.clientWidth,\n height: el.clientWidth / 950 * 250\n };\n },\n responsivefy(svg) {\n const c = d3.select(svg.node().parentNode);\n const w = parseInt(svg.style("width"));\n const h = parseInt(svg.style("height"));\n svg.attr("viewBox", `0 0 ${w} ${h}`).attr("preserveAspectRatio", "xMinYMid meet");\n window.addEventListener("resize", () => {\n const nw = parseInt(c.style("width"));\n svg.attr("width", nw).attr("height", Math.round(nw * h / w));\n });\n },\n createSvg(id, w, h) {\n const c = d3.select(\'#\' + id);\n c.selectAll(\'*\').remove();\n return c.append(\'svg\').attr(\'width\', w).attr(\'height\', h).call(this.responsivefy).append(\'g\');\n },\n createDatosSvg(width, height) {\n var size = 16;\n if (width < 600) {\n size = 13;\n }\n if (width < 550) {\n size = 12;\n }\n if (width < 500) {\n size = 12;\n }\n if (width < 450) {\n size = 11;\n }\n if (width < 400) {\n size = 10;\n }\n const c = d3.select(\'#datos\');\n c.selectAll(\'*\').remove();\n return c.append(\'svg\').attr(\'width\', width).attr(\'height\', height).call(this.responsivefy).append(\'g\').attr(\'font-family\', \'sans-serif\').attr(\'font-size\', size).attr(\'text-anchor\', \'middle\');\n },\n createScales(data, w, h) {\n return {\n x: d3.scaleBand().domain(data.map(d => d.siglas)).range([0, w]).padding(0.05),\n y: d3.scaleLinear().domain([0, d3.max(data, d => d.percent / 100)]).nice().range([h, 0])\n };\n },\n createYScaleGlobal(data, height) {\n return d3.scaleLinear().domain([0, d3.max(data, d => d.percent / 100)]).range([height, 0]).nice();\n },\n drawBars(svg, data, size, frac, yScaleGlobal, id) {\n let d = data;\n if (frac === 1) d = data.slice(0, 5);\n if (frac === 2) d = data.slice(5);\n const s = this.createScales(d, size.width, size.height);\n const anho_actual = this.state.datosConsulta.anho_actual || \'2026\';\n const anho_anterior = this.state.datosConsulta.anho_anterior || \'2022\';\n if (id !== \'grafica_2\') {\n svg.append(\'text\').attr(\'x\', size.width - 10).attr(\'y\', 40).attr(\'text-anchor\', \'end\').attr(\'font-size\', 32).attr(\'font-weight\', \'bold\').text(this.state.anho === \'elecciones_actuales\' ? anho_actual : anho_anterior);\n }\n const g = svg.selectAll(\'.bar\').data(d).enter().append(\'g\');\n g.append(\'rect\').attr(\'class\', \'bar\').attr(\'x\', x => s.x(x.siglas)).attr(\'y\', yScaleGlobal(0)).attr(\'width\', s.x.bandwidth()).attr(\'height\', size.height - yScaleGlobal(0)).attr(\'fill\', x => this.color(this.sigla(x.siglas))).on(\'mouseover\', this.showTooltip).on(\'mouseout\', this.hideTooltip).transition().duration(800).attr(\'y\', x => yScaleGlobal(x.percent / 100)).attr(\'height\', x => size.height - yScaleGlobal(x.percent / 100));\n g.append(\'text\').attr(\'x\', x => s.x(x.siglas) + s.x.bandwidth() / 2).attr(\'y\', x => yScaleGlobal(4)).attr(\'text-anchor\', \'middle\').attr(\'font-weight\', \'bold\').attr(\'font-size\', 26).attr(\'fill\', d => d.percent > 650 ? "#fff" : "#000").text(x => x.escanhos);\n }
1,\n drawPie(id, data, frac) {\n const size = this.getSize(id);\n if (!size) return;\n let d = data;\n const totalVotes = d3.sum(d, x => x.votos);\n if (frac === 1) d = data.slice(0, 5);\n if (frac === 2) d = data.slice(5);\n const svg = this.createSvg(id, size.width, 100);\n const s = this.createScales(d, size.width, 100);\n const g = svg.selectAll(\'g.partido\').data(d).enter().append(\'g\').attr(\'class\', \'partido\').attr(\'transform\', x => `translate(${s.x(x.siglas) + s.x.bandwidth() / 2},0)`);\n g.append(\'text\').attr(\'y\', 20).attr(\'font-size\', 14).attr(\'text-anchor\', \'middle\').attr(\'font-weight\', \'bold\').text(x => this.sigla(x.siglas));\n g.append(\'text\').attr(\'y\', 40).attr(\'font-size\', 13).attr(\'font-weight\', \'bold\').attr(\'text-anchor\', \'middle\').text(x => (x.votos / totalVotes * 100).toFixed(1) + \'%\');\n g.append(\'text\').attr(\'y\', 58).attr(\'font-size\', 11).attr(\'fill\', \'#555\').attr(\'text-anchor\', \'middle\').text(x => x.votos.toLocaleString(\'es-ES\'));\n },\n draw_datos() {\n if (!this.state.data?.[this.state.anho]?.[this.state.territorio] || !this.state.data?.elecciones_anteriores?.[this.state.territorio]) return;\n const size = this.getSize(\'datos\');\n if (!size) return;\n const svg = this.createDatosSvg(size.width, 120);\n const d26 = this.state.data.elecciones_actuales[this.state.territorio].general;\n const d23 = this.state.data.elecciones_anteriores[this.state.territorio].general;\n const cols = 6;\n const colW = size.width / cols;\n const x = i => colW * i + colW / 2;\n const y1 = 30,\n y2 = 65,\n y3 = 95;\n const anho_actual = this.state.datosConsulta.anho_actual;\n const anho_anterior = this.state.datosConsulta.anho_anterior;\n svg.append(\'rect\').attr(\'x\', 0).attr(\'y\', y2 - 18).attr(\'width\', size.width).attr(\'height\', 28).attr(\'fill\', \'#eee\');\n svg.append(\'rect\').attr(\'x\', 0).attr(\'y\', y3 - 18).attr(\'width\', size.width).attr(\'height\', 28).attr(\'fill\', \'#eee\');\n svg.append(\'text\').attr(\'x\', x(0)).attr(\'y\', y1).attr(\'font-weight\', \'bold\').text(\'\');\n svg.append(\'text\').attr(\'x\', x(1)).attr(\'y\', y1).text(\'Escrutado\');\n svg.append(\'text\').attr(\'x\', x(2)).attr(\'y\', y1).text(\'Abstención\');\n svg.append(\'text\').attr(\'x\', x(3)).attr(\'y\', y1).text(\'Blanco\');\n svg.append(\'text\').attr(\'x\', x(4)).attr(\'y\', y1).text(\'Nulos\');\n svg.append(\'text\').attr(\'x\', x(5)).attr(\'y\', y1).text(\'Escaños\');\n svg.append(\'text\').attr(\'x\', x(0)).attr(\'y\', y2).attr(\'font-weight\', \'bold\').text(anho_actual);\n svg.append(\'text\').attr(\'x\', x(1)).attr(\'y\', y2).text(d26.percent_escrutado.toFixed(2) + \' %\');\n svg.append(\'text\').attr(\'x\', x(2)).attr(\'y\', y2).text(d26.percent_abstencion.toFixed(2) + \' %\');\n svg.append(\'text\').attr(\'x\', x(3)).attr(\'y\', y2).text(d26.percent_blanco.toFixed(2) + \' %\');\n svg.append(\'text\').attr(\'x\', x(4)).attr(\'y\', y2).text(d26.percent_nulos.toFixed(2) + \' %\');\n svg.append(\'text\').attr(\'x\', x(5)).attr(\'y\', y2).text(d26.escanhos);\n svg.append(\'text\').attr(\'x\', x(0)).attr(\'y\', y3).attr(\'font-weight\', \'bold\').text(anho_anterior);\n svg.append(\'text\').attr(\'x\', x(1)).attr(\'y\', y3).text(\'100.00 %\');\n svg.append(\'text\').attr(\'x\', x(2)).attr(\'y\', y3).text(d23.percent_abstencion.toFixed(2) + \' %\');\n svg.append(\'text\').attr(\'x\', x(3)).attr(\'y\', y3).text(d23.percent_blanco.toFixed(2) + \' %\');\n svg.append(\'text\').attr(\'x\', x(4)).attr(\'y\', y3).text(d23.percent_nulos.toFixed(2) + \' %\');\n svg.append(\'text\').attr(\'x\', x(5)).attr(\'y\', y3).text(d23.escanhos);\n },\n showTooltip(e, d) {\n const t = document.getElementById(\'tooltip\');\n const r = e.target.getBoundingClientRect();\n t.textContent = d.siglas;\n t.style.left = r.left + r.width / 2 + \'px\';\n t.style.top = r.top - 30 + \'px\';\n t.classList.add(\'show\');\n },\n hideTooltip() {\n document.getElementById(\'tooltip\').classList.remove(\'show\');\n },\n draw_all() {\n const data = this.state.data?.[this.state.anho]?.[this.state.territorio]?.recuento_partidos;\n this.draw_datos();\n if (!data || !data.length || data[0].codigo == "0000") {\n const anho_actual = this.state.datosConsulta.anho_actual || \'2026\';\n const anho_anterior = this.state.datosConsulta.anho_anterior || \'2022\';\n const anho = this.state.anho === \'elecciones_actuales\' ? anho_actual : anho_anterior;\n [\'grafica\', \'grafica_1\', \'grafica_2\'].forEach(id =>
1 {\n const s = this.getSize(id);\n if (!s) return;\n const svg = this.createSvg(id, s.width, s.height);\n svg.append(\'text\').attr(\'x\', s.width / 2).attr(\'y\', s.height / 2).attr(\'text-anchor\', \'middle\').attr(\'font-size\', 24).attr(\'font-weight\', \'bold\').attr(\'fill\', \'#666\').text(`SIN DATOS ${anho}`);\n });\n [\'pie\', \'pie_1\', \'pie_2\'].forEach(id => {\n const s = this.getSize(id);\n if (!s) return;\n const svg = this.createSvg(id, s.width, 100);\n });\n return;\n }\n [\'grafica\', \'grafica_1\', \'grafica_2\'].forEach((id, i) => {\n const s = this.getSize(id);\n if (!s) return;\n const yScaleGlobal = this.createYScaleGlobal(data, s.height);\n this.drawBars(this.createSvg(id, s.width, s.height), data, s, i, yScaleGlobal, id);\n });\n this.drawPie(\'pie\', data, 0);\n this.drawPie(\'pie_1\', data, 1);\n this.drawPie(\'pie_2\', data, 2);\n },\
1n color(partido) {\n const colores = {\n "PSOE": "#dc0612",\n "PSOE-A": "#dc0612",\n "PP": "#01549f",\n "VOX": "#53d403",\n "AHORA REPÃBLICAS": "#f7b93f",\n "AHORA REPÃBLICAS (ERC-EH BILDU-BNG-ARA MÃS)": "#f7b93f",\n "JUNTS": "#00B4C4",\n "JUNTS-UE": "#00B4C4",\n "CEUS": "#297f41",\n "PODEMOS": "#72156e",\n "PODEMOS-IU": "#72156e",\n "PODEMOS ALIAZA VERDE": "#72156e",\n "PODEMOS -AV": "#72156e",\n "P-IU-AV": "#72156e",\n "SUMAR": "#BB2649",\n "Cs": "#ff6419",\n "S.A.L.F": "#9FA2B2",\n "SALF": "#9FA2B2",\n "PACMA": "#00d084",\n "PorA": "#f8c565",\n "ADELANTE ANDALUCÃA": "#009076",\n "AA": "#009076"\n };\n return colores[partido] || \'#\' + Math.floor(Math.random() * Math.pow(2, 32) ^ 0xffffff).toString(16).substr(-6);\n },\n sigla(partido) {\n const siglas = {\n "P.S.O.E.": "PSOE",\n "PARTIDO AUTÃNOMOS": "PA",\n "RECORTES CERO": "RC",\n "ADELANTE ANDALUCÃA-ANDALUCISTAS": "AA-A",\n "ADELANTE ANDALUCÃA-ANDALUCISTAS": "AA-A",\n "ANDALUCISTAS-PA": "A-PA",\n "ANDALUCISTAS - PA": "A-PA",\n "ADELANTE ANDALUCÃA": "AA",\n "AHORA REPÃBLICAS": "A.R.",\n "AGRUPACIÃN DE ELECTORES SE ACABà LA FIESTA": "A.E.S.A.F",\n "AHORA REPÃBLICAS (ERC-EH BILDU-BNG-ARA MÃS)": "A.R.",\n "PODEMOS ALIANZA VERDE": "P-AV",\n "PODEMOS -AV": "P-AV",\n "PODEMOS-IU-AV": "P-IU-AV",\n "COALICIÃN ARAGONESA": "CA",\n "IU- MOVIMIENTO SUMAR": "IU-MS",\n "ESCAÃOS EN BLANCO": "EB",\n "MUNDO+JUSTO": "M+J",\n "ESPAÃA VACIADA": "E.V.",\n "CS-Tà ARAGÃN": "CS-TU",\n "FE de las JONS": "FE Jons",\n "PCAS-TC-Recortes Cero": "PCAS-TC-RC"\n };\n return siglas[partido] || partido;\n }\n },\n FlowCurrent: {\n mounted() {\n this.el.style.transition = "transform 1.2s ease-in-out, fill 0.8s";\n },\n updated() {\n let x = parseFloat(this.el.dataset.x);\n let y = parseFloat(this.el.dataset.y);\n\n // efecto Bezier-like: ligera curva en movimiento\n let cx = x + (Math.random() - 0.5) * 20;\n let cy = y + (Math.random() - 0.5) * 10;\n this.el.setAttribute("x", cx);\n this.el.setAttribute("y", cy);\n }\n },\n HorizontalScroll: {\n mounted() {\n if (window.innerWidth > 768) return; // â No hacer nada en escritorio\n const id = `#${this.el.dataset.id}`;\n const el = this.el;\n let atEnd = false;\n el.addEventListener("scroll", () => {\n const scrollLeft = el.scrollLeft;\n const scrollWidth = el.scrollWidth;\n const clientWidth = el.clientWidth;\n if (scrollLeft + clientWidth >= scrollWidth - 0) {\n if (!atEnd) {\n this.pushEventTo(id, "scroll_end");\n atEnd = true;\n }\n } else {\n atEnd = false;\n }\n });\n }\n },\n CarruselTrack: {\n mounted() {\n this.page = parseInt(this.el.dataset.page);\n },\n updated() {\n const page = parseInt(this.el.dataset.page);\n const perPage = parseInt(this.el.dataset.perPage);\n const elemento = document.getElementById(\'track-socias-opinion\') || document.getElementById(\'track-relacionadas-live\').parentNode;\n const ancho_total_visible = elemento.offsetWidth;\n\n //const offset = -page * perPage * itemWidth\n const offset = -page * ancho_total_visible;\n const track = this.el.querySelector(".items-track");\n this.page = page;\n if (track) {\n if (window.innerWidth <= 768) return; // â No hacer nada en movil \n track.style.transform = `translateX(${offset}px)`;\n }\n }\n },\n LazyLoadAd: {\n mounted() {\n var modulo_publi = this.el.dataset.name;\n let alreadyTriggered = false;\n const handleVisible = () => {\n //if (alreadyTriggered) return\n alreadyTriggered = true;\n\n // Verificar locks y estado de actualización de contenido\n if (publi_lock || contenidoupdating) {\n if (!publi_pendientes.includes(modulo_publi)) {\n publi_pendientes.push(modulo_publi);\n }\n return;\n }\n var slug1 = "";\n var slug2 = "";\n var loc = location.pathname.split(\'/\').slice(1);\n if (loc[0]) {\n slug1 = loc[0];\n }\n if (loc[1]) {\n slug2 = loc[1];\n }\n if (loc[0] == "sin-publicar") {\n slug1 = loc[1];\n slug2 = loc[2];\n }\n var nodo = document.getElementById("nodo-contenido");\n if (nodo) {\n nodo = nodo.getAttribute(\'data-nodo\');\n }\n this.pushEventTo(this.el, "ad_visible", {\n modulo: modulo_publi,\n slug1: slug1,\n slug2: slug2,\n mobil: window.innerWidth > 767 ? false : true,\n nodo: nodo,\n ip: document.body.getAttribute(\'data-ip\')\n });\n observer.disconnect();\n };\n const observer = new IntersectionObserver(([entry]) => {\n if (entry.isIntersecting || entry.intersectionRatio > 0) {\n handleVisible();\n }\n }, {\n rootMargin: "200px"\n });\n observer.observe(this.el);\n\n // comprobación inicial\n const rect = this.el.getBoundingClientRect();\n const inView = rect.top < window.innerHeight && rect.bottom > 0;\n if (inView) {\n handleVisible();\n }\n this.handleEvent(`update_ad_${modulo_publi}`, anuncio =>
1 {\n if (this.el.dataset.name == anuncio.modulo) {\n var mobil = window.innerWidth > 767 ? false : true;\n let modulo = this.el;\n if (!modulo) return;\n\n // 1. Añadir clase según el tipo de anuncio\n if (anuncio.maquetacion && anuncio.maquetacion.no_publicidad === "no_publicidad") {\n modulo.classList.add(\'bloque-activo\');\n } else {\n modulo.classList.add(\'anuncio-activo\');\n }\n\n // 2. Vaciar el contenido del módulo\n modulo.innerHTML = "";\n\n // 3. Atributo "phx-update"\n modulo.setAttribute(\'phx-update\', \'ignore\');\n\n // 4. Si hay script, usar postscribe (si está disponible)\n if (anuncio.script && anuncio.script.length > 10) {\n if (typeof (postscribe_min_default()) !== "undefined") {\n try {\n postscribe_min_default()(modulo, anuncio.script, {\n error: function (e) {\n console.warn(\'Ad failed to load:\', e);\n }\n });\n } catch (err) {\n console.log("Error al insertar script");\n }\n } else {\n console.warn("postscribe no está definido");\n }\n } else {\n // 5. Si hay HTML personalizado\n if (anuncio.html && anuncio.html.length > 1) {\n const div = document.createElement(\'div\');\n div.classList.add(\'html-anun\');\n div.innerHTML = anuncio.html;\n modulo.appendChild(div);\n } else {\n // 6. Si no hay HTML ni script, construir enlace de anuncio\n const redireccion = anuncio.url_redireccion || "false";\n const a = document.createElement(\'a\');\n a.dataset.anun = anuncio.id;\n a.dataset.click = redireccion;\n a.href = `/ir_anuncio/${anuncio.id}/${mobil}`;\n a.target = "_blank";\n a.setAttribute(\'aria-label\', \'publicidad\');\n a.classList.add(\'anuncio-link\');\n modulo.appendChild(a);\n\n // 7. Imagen o video\n if (anuncio.imagen) {\n const ext = anuncio.imagen.split(\'.\').pop().split(\'?\').shift();\n if (ext === "mp4") {\n const video = document.createElement(\'video\');\n video.classList.add(\'no-mep\');\n video.autoplay = true;\n video.muted = true;\n video.loop = true;\n video.src = anuncio.imagen;\n video.alt = a.titulo;\n a.appendChild(video);\n } else {\n const img = document.createElement(\'img\');\n img.src = anuncio.imagen;\n img.alt = anuncio.titulo;\n a.appendChild(img);\n }\n }\n\n // 8. PÃxel de impresión\n if (anuncio.url_impresion) {\n const pixel = document.createElement(\'img\');\n pixel.classList.add(\'transparent\');\n pixel.src = anuncio.url_impresion.replace("[timestamp]", +new Date());\n pixel.alt = "Advertisment";\n pixel.border = "0";\n pixel.height = 1;\n pixel.width = 1;\n a.appendChild(pixel);\n }\n }\n }\n //this.el.innerHTML = data.content;\n }\n popup();\n });\n }\n },\n MapLibreFormMap: {\n mounted() {\n if (!window.maplibregl) {\n Promise.all([this.loadCSS("https://unpkg.com/[email protected]/dist/maplibre-gl.css"), this.loadJS("https://unpkg.com/[email protected]/dist/maplibre-gl.js")]).then(() => this.initMap()).catch(err => console.error("Error loading MapLibre:", err));\n } else {\n this.initMap();\n }\n },\n updated() {\n this.initMap();\n },\n loadCSS(url) {\n return new Promise((resolve, reject) => {\n if (document.querySelector(`link[href="${url}"]`)) return resolve();\n const link = document.createElement("link");\n link.rel = "stylesheet";\n link.href = url;\n link.onload = resolve;\n link.onerror = reject;\n document.head.appendChild(link);\n });\n },\n loadJS(url) {\n return new Promise((resolve, reject) => {\n if (document.querySelector(`script[src="${url}"]`)) return resolve();\n const script = document.createElement("script");\n script.src = url;\n script.id = "ID_map_script";\n script.async = true;\n script.onload = resolve;\n script.onerror = reject;\n document.body.appendChild(script);\n });\n },\n initMap() {\n const lat = parseFloat(this.el.dataset.lat) || 0;\n const lng = parseFloat(this.el.dataset.lng) || 0;\n const zoom = parseFloat(this.el.dataset.zoom) || 2;\n this.map = new maplibregl.Map({\n container: this.el,\n style: "https://demotiles.maplibre.org/style.json",\n style: "https://demotiles.maplibre.org/styles/osm-bright-gl-style/tyle.json",\n style: "https://tiles.stadiamaps.com/styles/osm_bright.json",\n center: [lng, lat],\n zoom: zoom\n });\n this.map.addControl(new maplibregl.NavigationControl());\n\n // ð§· Crear marcador inicial\n this.marker = new maplibregl.Marker({\n draggable: true\n }).setLngLat([lng, lat]).addTo(this.map);\n\n // ð°ï¸ Actualizar marcador y enviar evento cuando se mueve o hace zoom\n this.map.on("moveend", () => this.handleMapMove());\n this.map.on("zoomend", () => this.handleMapMove());\n this.map.on("click", e => {\n const {\n lng,\n lat\n } = e.lngLat;\n this.marker.setLngLat([lng, lat]);\n\n // Emitir evento a LiveView si lo deseas\n this.pushEvent("map_moved", {\n lat,\n lng,\n zoom: Math.round(this.map.getZoom())\n });\n });\n },\n handleMapMove() {\n const center = this.map.getCenter();\n const zoom = this.map.getZoom();\n\n // Mover el marcador al nuevo centro\n this.marker.setLngLat(center);\n\n // Emitir evento a LiveView\n this.pushEvent("map_moved", {\n lat: center.lat,\n lng: center.lng,\n zoom: Math.round(zoom)\n });\n }\n },\n TabHighlight: {\n mounted() {\n this.startBlinking();\n },\n updated() {\n this.startBlinking();\n },\n destroyed() {\n // Limpieza de seguridad\n if (this.blinkInterval) {\n clearInterval(this.blinkInterval);\n }\n },\n startBlinking() {\n if (document.hasFocus()) {\n return;\n }\n let originalTitle = document.title;\n let newTitle = this.el.dataset.title || "Nueva actualización";\n\n // Limpia cualquier intervalo anterior\n if (this.blinkInterval) {\n clearInterval(this.blinkInterval);\n }\n const blink = () => {\n document.title = document.title === originalTitle ? newTitle : originalTitle;\n };\n this.blinkInterval = setInterval(blink, 1000);\n\n // Detener cuando se vuelve a enfocar la pestaña\n window.addEventListener("focus", () => {\n clearInterval(this.blinkInterval);\n document.title = originalTitle;\n }, {\n once: true\n });\n }\n },\n CoordinaContenido: {\n mounted() {\n window.addEventListener(\'contenido-actualizando\', () => {\n contenidoupdating = true;\n });\n window.addEventListener(\'contenido-estabilizado\', () => {\n contenidoupdating = false;\n // Reanudar procesamiento de publicidad después de breve delay\n setTimeout(() =>
1 {\n if (!publi_lock) {\n reubicar_publis(true);\n }\n }, 200);\n });\n }\n },\n LazyRelacionadas: {\n mounted() {\n const observer = new IntersectionObserver((entries, observer) => {\n entries.forEach(entry => {\n if (entry.isIntersecting || entry.intersectionRatio > 0) {\n //console.log("RELACIONADAS");\n // Notificar inicio de actualización de contenido\n window.dispatchEvent(new CustomEvent(\'contenido-actualizando\'));\n this.pushEvent("cargar-relacionadas");\n this.pushEvent("cargar-portadilla");\n\n // Notificar fin de actualización después de procesamiento\n setTimeout(() => {\n window.dispatchEvent(new CustomEvent(\'contenido-estabilizado\'));\n }, 300);\n observer.unobserve(entry.target); // Solo una vez\n }\n });\n }, {\n root: null,\n rootMargin: "150px",\n // 100px antes de entrar en vista\n threshold: 0.01\n });\n observer.observe(this.el);\n },\n updated() {\n apanhos_publi_bloque_tema();\n }\n },\n LazyPortadilla: {\n mounted() {\n const observer = new IntersectionObserver((entries, observer) => {\n entries.forEach(entry => {\n if (entry.isIntersecting || entry.intersectionRatio > 0) {\n //console.log("PORTADILLA");\n observer.unobserve(entry.target); // Solo una vez\n }\n });\n }, {\n root: null,\n rootMargin: "150px",\n // 100px antes de entrar en vista\n threshold: 0.01\n });\n observer.observe(this.el);\n }\n },\n MenuPosicion: {\n mounted() {\n ajuste_menu_movil();\n },\n updated() {\n ajuste_menu_movil();\n }\n },\n AutoClearFlash: {\n mounted() {\n let ignoredIDs = ["client-error", "server-error"];\n if (ignoredIDs.includes(this.el.id)) return;\n let hideElementAfter = 3000; // ms\n let clearFlashAfter = hideElementAfter + 500; // ms\n\n // first hide the element\n setTimeout(() => {\n this.el.style.opacity = 0;\n }, hideElementAfter);\n\n // then clear the flash\n setTimeout(() => {\n this.pushEvent("lv:clear-flash");\n }, clearFlashAfter);\n }\n },\n ApanhoCrop: {\n mounted() {\n apanho_crop();\n console.log("CROP");\n },\n updated() {\n apanho_crop();\n console.log("CROP");\n },\n beforeUpdate() {},\n destroyed() {},\n disconnected() {},\n reconnected() {}\n },\n ApanhosArticulo: {\n mounted() {\n ejecutados_embebidos = false;\n reubicar_resumenes_articulo();\n lanzar_codigos_embebidos();\n apanhos_imagenes_articulos();\n //reubicar_publis();\n esperarHastaQueExistaAlturaLimitados(() => {\n ejecutados_limitados = false;\n limitados();\n });\n copiar_acortados();\n lanzar_scripts();\n scroll_into_id();\n document.addEventListener("scroll", processScroll);\n },\n updated() {\n //console.log("Articulo UPDATED")\n ejecutados_embebidos = false;\n apanhos_imagenes_articulos();\n //lanzar_codigos_embebidos();\n reubicar_resumenes_articulo();\n //reubicar_publis(true);\n lanzar_scripts();\n ejecutados_embebidos = true;\n document.addEventListener("scroll", processScroll);\n esperarHastaQueExistaAlturaLimitados(() => {\n ejecutados_limitados = false;\n limitados();\n });\n apanhos_publi_bloque_tema();\n }\n },\n ApanhosComentarios: {\n mounted() {},\n updated() {\n recortar_comentarios();\n scroll_into_id(true);\n }\n },\n SwiperGalerias: {\n updated() {\n swiper_galeria();\n swiper_galeria_modal();\n },\n mounted() {\n swiper_galeria();\n swiper_galeria_modal();\n }\n },\n BorrarTooltips: {\n updated() {\n setTimeout(() => {\n document.querySelector(\'.temptooltip\').style.display = \'none\';\n }, 1500);\n },\n mounted() {\n setTimeout(() =>
1 {\n document.querySelector(\'.temptooltip\').style.display = \'none\';\n }, 1500);\n }\n },\n EditorSocias: {\n updated() {\n $(\'.summernote\').summernote(\'destroy\');\n $(\'.summernote\').summernote(summerNoteMin);\n },\n mounted() {\n $(\'.summernote\').summernote(\'destroy\');\n $(\'.summernote\').summernote(summerNoteMin);\n }\n },\n Editor: {\n updated() {\n $(\'.summernote\').summernote(\'destroy\');\n $(\'.summernote\').summernote(summerNoteConf);\n },\n mounted() {\n $(\'.summernote\').summernote(\'destroy\');\n $(\'.summernote\').summernote(summerNoteConf);\n }\n },\n EditorMinimo: {\n mounted() {\n this.initSummerNote();\n },\n updated() {\n this.initSummerNote();\n },\n destroyed() {\n this.destroySummerNote();\n },\n initSummerNote() {\n const element = this.el.querySelector(\'.summernote\');\n if (element) {\n let contenido = \'\';\n if ($(element).data(\'summernote\')) {\n contenido = $(element).summernote(\'code\');\n }\n $(element).summernote(\'destroy\');\n $(element).summernote(summerNoteMin);\n if (contenido) {\n $(element).summernote(\'code\', contenido);\n }\n }\n },\n destroySummerNote() {\n const element = this.el.querySelector(\'.summernote\');\n if (element && $(element).data(\'summernote\')) {\n $(element).summernote(\'destroy\');\n }\n }\n },\n Notificaciones: {\n mounted() {\n const hook = this;\n pushButton = document.querySelector(\'.js-push-btn\');\n canalesDiv = document.querySelector(\'.canales\');\n if (\'serviceWorker\' in navigator && \'PushManager\' in window) {\n navigator.serviceWorker.register(\'/sw.js\').then(function (swReg) {\n console.log(\'Service Worker registrado\');\n swRegistration = swReg;\n initializeNotificationsUI(hook);\n swRegistration.pushManager.getSubscription().then(function (subscription) {\n hook.pushEvent("suscrito", subscription);\n });\n }).catch(function (error) {\n //console.error(\'Service Worker Error\', error);\n console.error(\'Service Worker Error\');\n console.log(error.message);\n console.log(error.name);\n console.log(error.stack);\n });\n } else {\n console.log("NO soportado");\n }\n window.addEventListener(\'online\', handleConnection);\n window.addEventListener(\'offline\', handleConnection);\n /*\n console.log(Notification);\n if(Notification.permission === "default") {\n console.log("permiso???");\n Notification.requestPermission();\n //swRegistration.pushManager.getSubscription()\n } else {\n console.log("permiso si.....???");\n }\n */\n }\n },\n CookieHook: {\n mounted() {\n this.handleEvent(\'cookie_portada\', async params => {\n try {\n await fetch(\'api/cookie_portada\', {\n method: \'post\',\n body: JSON.stringify(params),\n headers: {\n \'Content-Type\': \'application/json\'\n }\n });\n } catch (err) {\n alert(err.message ?? "An error occurred");\n }\n });\n }\n },\n AudioRadioSeleccionar: {\n destroyed() {},\n mounted() {\n //document.querySelector(\'#reproductor_radio\').classList.remove("activo")\n audio_origen = "directo";\n if (audio.paused) {\n liveSocket.hooks.AudioPlayer.datos_audio();\n }\n ;\n this.anhadir_eventos();\n },\n anhadir_eventos() {\n var viewportWidth = window.innerWidth || document.documentElement.clientWidth;\n if (viewportWidth < 769) {\n var hoy = new Date().getDay();\n this.toggleDay(hoy);\n }\n },\n toggleDay(day) {\n var days = document.getElementById("days");\n var grid = document.getElementById("grid");\n var labels = document.getElementsByClassName("day");\n switch (day) {\n case 1:\n grid.style.setProperty("grid-template-columns", "3em 10px calc(100% - 3em - 10px) repeat(6, 0)");\n days.style.setProperty("grid-template-columns", "3em 10px calc(100% - 3em - 10px) repeat(6, 0)");\n break;\n case 2:\n days.style.setProperty("grid-template-columns", "3em 10px 0 calc(100% - 3em - 10px) 0 0 0 0 0");\n grid.style.setProperty("grid-template-columns", "3em 10px 0 calc(100% - 3em - 10px) 0 0 0 0 0");\n break;\n case 3:\n days.style.setProperty("grid-template-columns", "3em 10px 0 0 calc(100% - 3em - 10px) 0 0 0 0");\n grid.style.setProperty("grid-template-columns", "3em 10px 0 0 calc(100% - 3em - 10px) 0 0 0 0");\n break;\n case 4:\n days.style.setProperty("grid-template-columns", "3em 10px 0 0 0 calc(100% - 3em - 10px) 0 0 0");\n grid.style.setProperty("grid-template-columns", "3em 10px 0 0 0 calc(100% - 3em - 10px) 0 0 0");\n break;\n case 5:\n days.style.setProperty("grid-template-columns", "3em 10px 0 0 0 0 calc(100% - 3em - 10px) 0 0");\n grid.style.setProperty("grid-template-columns", "3em 10px 0 0 0 0 calc(100% - 3em - 10px) 0 0");\n break;\n case 6:\n days.style.setProperty("grid-template-columns", "3em 10px 0 0 0 0 0 calc(100% - 3em - 10px) 0");\n grid.style.setProperty("grid-template-columns", "3em 10px 0 0 0 0 0 calc(100% - 3em - 10px) 0");\n break;\n default:\n days.style.setProperty("grid-template-columns", "3em 10px repeat(6, 0) calc(100% - 3em - 10px)");\n grid.style.setProperty("grid-template-columns", "3em 10px repeat(6, 0) calc(100% - 3em - 10px)");\n break;\n }\n for (let i = 0; i < labels.length;
1 i++) {\n labels[i].style.setProperty("height", "0px");\n labels[i].style.setProperty("visibility", "hidden");\n }\n labels[day - 1].style.setProperty("height", "auto");\n labels[day - 1].style.setProperty("visibility", "visible");\n }\n },\n ListadoRadio: {\n mounted() {\n var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n if (w > 768) {\n document.querySelector(\'#reproductor_radio\').classList.add("activo");\n document.querySelector(\'body\').classList.add("radio");\n document.querySelector(\'body\').classList.add("overflow_m");\n }\n }\n },\n AudioSeleccionar: {\n disconnected() {\n document.querySelector(\'#reproductor_radio\').classList.remove("activo");\n document.querySelector(\'body\').classList.remove("radio");\n document.querySelector(\'body\').classList.remove("overflow_m");\n document.querySelector(\'.play-podcast\').style.display = \'none \';\n document.querySelector(\'body\').classList.remove("overflow");\n if (audio.paused) {\n audio_origen = "recomendacion";\n liveSocket.hooks.AudioPlayer.datos_audio();\n }\n },\n destroyed() {\n document.querySelector(\'#reproductor_radio\').classList.remove("activo");\n document.querySelector(\'body\').classList.remove("radio");\n document.querySelector(\'body\').classList.remove("overflow_m");\n document.querySelector(\'.play-podcast\').style.display = \'none \';\n document.querySelector(\'body\').classList.remove("overflow");\n if (audio.paused) {\n audio_origen = "recomendacion";\n liveSocket.hooks.AudioPlayer.datos_audio();\n }\n },\n updated() {},\n mounted() {\n const ua = navigator.userAgent.toLowerCase();\n const isTelegram = ua.includes(\'telegram\');\n const isMovileSafari = ua.includes(\'mobile safari\');\n audio_origen = "podcast";\n document.querySelector(\'.podcast-titulo\').innerText = document.getElementById(\'audio-titulo\').innerText;\n document.querySelector(\'.play-podcast\').style.display = \'block\';\n document.querySelector(\'.play-podcast\').addEventListener(\'click\', event => {\n this.seleccionar();\n });\n document.getElementById("podcast-radio-bot").src = document.getElementById("seleccionar").src;\n document.querySelector(\'#reproductor_radio\').classList.add("activo");\n document.querySelector(\'body\').classList.add("radio");\n document.querySelector(\'body\').classList.add("overflow_m");\n document.querySelector(\'body\').classList.remove("overflow");\n if (audio.paused) {\n liveSocket.hooks.AudioPlayer.datos_audio();\n }\n document.querySelector(\'#reproductor_radio\').classList.add("activo");\n },\n seleccionar() {\n audio_origen = "podcast";\n liveSocket.hooks.AudioPlayer.audio_reproducir();\n }\n },\n AudioPlayer: {\n mounted() {\n //para que no se cuelque el Telegram...\n document.addEventListener("visibilitychange", () => {\n if (document.hidden) {\n window.audioPlayingOnHide = audio && !audio.paused;\n } else if (window.audioPlayingOnHide && audio && audio.paused) {\n audio.play().catch(() => {});\n }\n });\n document.querySelector(\'.play-button.play\').addEventListener(\'click\', event => {\n if (this.isRestrictedEnv()) {\n this.mostrarAvisoSalida();\n return;\n }\n if (audio_origen == "podcast" || audio_origen == "recomendacion") {\n this.audio_reproducir();\n } else {\n this.play_directo();\n }\n });\n document.querySelector(\'.play-directo\').addEventListener(\'click\', event => {\n this.play_directo();\n });\n document.querySelector(\'.play-button.pause\').addEventListener(\'click\', event => {\n this.pausar();\n });\n document.querySelector(\'.mute-button.mute\').addEventListener(\'click\', event => {\n this.mutear();\n });\n document.querySelector(\'.mute-button.unmute\').addEventListener(\'click\', event => {\n this.unmutear();\n });\n document.querySelector(\'.hacia-atras\').addEventListener(\'click\', event => {\n this.posicion(-10);\n });\n document.querySelector(\'.hacia-delante\').addEventListener(\'click\', event => {\n this.posicion(10);\n });\n audio_position.addEventListener("change", event => {\n audio.currentTime = audio_position.value;\n document.querySelector(\'.momento\').innerText = segundos_a_string(audio.currentTime);\n });\n this.datos_audio();\n },\n isTelegram() {\n const ua = navigator.userAgent || "";\n return /Telegram/i.test(ua);\n },\n isWebView() {\n const ua = navigator.userAgent || "";\n\n // Android WebView tÃpico\n const isAndroidWebView = /wv|WebView/i.test(ua);\n\n // iOS WebView (no Safari)\n const isIOSWebView = /iPhone|iPad/.test(ua) && !/Safari/i.test(ua);\n return isAndroidWebView || isIOSWebView;\n },\n isRestrictedEnv() {\n //return true;\n return this.isTelegram() || this.isWebView();\n },\n mostrarAvisoSalida() {\n const modal = document.getElementById("aviso-telegram");\n const link = document.getElementById("abrir-navegador");\n\n // URL actual\n link.href = window.location.href;\n modal.classList.remove("hidden");\n document.getElementById("seguir-aqui").onclick = () => {\n modal.classList.add("hidden");\n if (audio_origen == "podcast" || audio_origen == "recomendacion") {\n this.audio_reproducir();\n } else {\n this.play_directo();\n }\n };\n },\n audio_reproducir() {\n // estado actual antes de cualquier cambio\n let isResume = audio && audio.src && audio.paused && audio.currentTime > 0;\n audio.pause();\n if (audio_origen == "podcast" || audio_origen == "recomendacion") {\n this.cerrar_datos_directo();\n }\n\n // Solo llamar a datos_audio() para nuevas selecciones\n if (!isResume) {\n this.datos_audio();\n }\n\n // asegurarnos que la duración esté disponible\n if (audio.duration) {\n document.querySelector(\'.tiempo\').innerText = segundos_a_string(audio.duration);\n audio_position.setAttribute("max", audio.duration);\n }\n audio.play();\n document.querySelector(\'.con_sonido\').style.display = \'block\';\n document.querySelector(\'.play-button.play\').style.display = \'none\';\n document.querySelector(\'.play-button.pause\').style.display = \'inline-block\';\n }
1,\n play_directo() {\n audio_origen = "directo";\n this.audio_reproducir();\n },\n pausar() {\n audio.pause();\n document.querySelector(\'.play-button.play\').style.display = \'inline-block\';\n document.querySelector(\'.play-button.pause\').style.display = \'none\';\n document.querySelector(\'.con_sonido\').style.display = \'none\';\n },\n mutear() {\n audio.volume = 0;\n document.querySelector(\'.mute-button.unmute\').style.display = \'inline-block\';\n document.querySelector(\'.mute-button.mute\').style.display = \'none\';\n document.querySelector(\'.con_sonido\').style.display = \'none\';\n },\n unmutear() {\n //audio.volume = this.range.value/100;\n audio.volume = 50 / 100;\n document.querySelector(\'.mute-button.mute\').style.display = \'inline-block\';\n document.querySelector(\'.mute-button.unmute\').style.display = \'none\';\n document.querySelector(\'.con_sonido\').style.display = \'block\';\n },\n datos_audio() {\n document.querySelector(\'#reproductor_radio\').classList.add(audio_origen);\n switch (audio_origen) {\n case "recomendacion":\n audio = document.getElementById("seleccion-radio");\n document.querySelector(\'.modo\').innerText = "Recomendación";\n document.querySelector(\'.sonando1\').innerText = document.querySelector(\'.seleccion-titulo\').innerText;\n document.querySelector(\'.sonando2\').innerText = document.querySelector(\'.seleccion-tema\').innerText;\n this.control_tiempo();\n break;\n case "podcast":\n audio = document.getElementById("podcast-radio-bot");\n document.querySelector(\'.modo\').innerText = "Podcast";\n document.querySelector(\'.sonando1\').innerText = document.getElementById(\'audio-titulo\').innerText;\n document.querySelector(\'.sonando2\').innerText = document.querySelector(\'#audio-tema\').innerText;\n document.querySelector(\'#RadioBot .imagen\').innerHTML = "";\n document.querySelector(\'#RadioBot .imagen\').appendChild(document.querySelector(\'#articulo-contenido .cabecera .responsively-lazy\').cloneNode(true));\n this.control_tiempo();\n document.querySelector(\'.podcast-titulo\').innerText = document.getElementById(\'audio-titulo\').innerText;\n document.querySelector(\'.play-podcast\').style.display = \'block\';\n document.querySelector(\'.play-podcast\').addEventListener(\'click\', event => {\n this.seleccionar();\n });\n document.getElementById("podcast-radio-bot").src = document.getElementById("seleccionar").src;\n document.querySelector(\'#reproductor_radio\').classList.add("activo");\n document.querySelector(\'body\').classList.add("radio");\n document.querySelector(\'body\').classList.add("overflow_m");\n document.querySelector(\'body\').classList.remove("overflow");\n document.querySelector(\'#reproductor_radio\').classList.add("activo");\n break;\n default:\n //audio = document.getElementById("directo-radio-bot");\n //document.querySelector(\'.modo\').innerText = "Radio 24h";\n //document.querySelector(\'.sonando1\').innerText = "";\n //document.querySelector(\'.sonando2\').innerText = "";\n //\n audio = document.getElementById("seleccion-radio");\n document.querySelector(\'.modo\').innerText = "Recomendación";\n document.querySelector(\'.sonando1\').innerText = document.querySelector(\'.seleccion-titulo\').innerText;\n document.querySelector(\'.sonando2\').innerText = document.querySelector(\'.seleccion-tema\').innerText;\n this.control_tiempo();\n }\n },\n datos_directo() {\n socket_radio_bot = new WebSocket(radiobot_api);\n socket_radio_bot.onopen = function (e) {\n socket_radio_bot.send(JSON.stringify({\n "subs": {\n "station:salto": {}\n }\n }));\n };\n socket_radio_bot.onmessage = function (event) {\n const data = JSON.parse(event.data);\n const np = data?.pub?.data?.np || null;\n if (np) {\n audio_momento = np.now_playing.elapsed / np.now_playing.duration * 100 + "%";\n document.querySelector(\'.sonando1\').innerText = np.now_playing.playlist.split(" - ")[1] || "Continuidad";\n document.querySelector(\'.sonando2\').innerText = np.now_playing.song.text + " | ";\n audio_progreso.style.setProperty("--progreso", audio_momento);\n audio_position.value = np.now_playing.elapsed;\n audio_position.setAttribute("max", np.now_playing.duration);\n document.querySelector(\'.tiempo\').innerText = segundos_a_string(np.now_playing.duration);\n document.querySelector(\'.momento\').innerText = segundos_a_string(np.now_playing.elapsed);\n }\n };\n }
1,\n cerrar_datos_directo() {\n if (socket_radio_bot.readyState == WebSocket.OPEN) socket_radio_bot.close();\n },\n control_tiempo() {\n /*\n audio.onloadedmetadata = function(e) {\n document.querySelector(\'.tiempo\').innerText =\n segundos_a_string(audio.duration);\n audio_position.setAttribute("max", audio.duration)\n };\n audio_momento = 0;\n audio.addEventListener(\'timeupdate\', () => {\n // actualizar progreso UI\n audio_position.value = audio.currentTime;\n audio_momento = audio.currentTime / audio.duration * 100 + "%";\n audio_progreso.style.setProperty("--progreso", audio_momento);\n });\n */\n if (audio.duration) {\n document.querySelector(\'.tiempo\').innerText = segundos_a_string(audio.duration);\n audio_position.setAttribute("max", audio.duration);\n }\n setInterval(() => {\n if (!audio.paused && audio.duration) {\n document.querySelector(\'.momento\').innerText = segundos_a_string(audio.currentTime);\n audio_momento = audio.currentTime / audio.duration * 100 + "%";\n } else {\n //document.querySelector(\'.momento\').innerText = "00:00"\n //audio_momento = 0\n }\n audio_position.value = audio.currentTime;\n audio_progreso.style.setProperty("--progreso", audio_momento);\n }, 1000);\n },\n posicion(t) {\n audio.currentTime = audio.currentTime + t;\n }\n },\n VidstackHook: {\n mounted() {\n let currentEl = this.el;\n //console.log("VidstackHook mounted");\n var player = document.querySelector(\'media-player\');\n //console.log(player); \n },\n beforeUpdate() {},\n updated() {\n //console.log("VidstackHook updated");\n },\n destroyed() {},\n disconnected() {},\n reconnected() {}\n },\n ...live_select_min\n};\nlet liveSocket = new LiveSocket(\'/live\', Socket, {\n hooks,\n dom: {\n // make LiveView work nicely with alpinejs\n onBeforeElUpdated(from, to) {\n //if (from.__x) {\n if (from._x_dataStack) {\n //window.Alpine.clone(from.__x, to);\n window.Alpine.clone(from, to);\n }\n }\n },\n params: {\n _csrf_token: csrfToken\n }\n});\nfunction esperarHastaQueExistaAlturaLimitados(callback) {\n const check = () => {\n const elems = document.querySelectorAll(".limitado");\n if (!elems.length) {\n return requestAnimationFrame(check);\n }\n\n // Esperar a que scrollHeight y clientHeight sean > 0\n const listo = [...elems].every(el => el.scrollHeight > 0 && el.clientHeight > 0);\n if (listo) {\n callback();\n } else {\n requestAnimationFrame(check);\n }\n };\n check();\n}\nwindow.addEventListener("phx:page-loading-start", function (info) {\n nprogress_default().start();\n document.querySelector("body").classList.remove("overflow");\n if (document.querySelector("#menu-bur-contenedor")) {\n document.querySelector("#menu-bur-contenedor").classList.remove("activo");\n document.querySelector("#menu-bur-contenedor").classList.remove("scroll-off");\n }\n if (document.querySelector("#menu-personal-contenedor")) {\n document.querySelector("#menu-personal-contenedor").classList.remove("activo");\n }\n if (document.querySelector("#menu-admin")) {\n document.querySelector("#menu-admin").classList.remove("activo");\n }\n});\nwindow.addEventListener("phx:page-loading-stop", function (info) {\n //document.querySelector("body").classList.remove("overflow_m");\n //document.querySelector("body").classList.remove("radio");\n\n modulos_publi = modulos_publi_iniciales;\n cambio();\n cambio_apanhos();\n apanhos_imagenes_articulos();\n apanho_crop();\n reubicar_publis(true);\n nprogress_default().done();\n responsivelyLazy.run();\n ubicacion_banda_inferior();\n scrollHandler();\n if ($(\'.twitter-tweet\').length) {\n //$.getScript(\'//platform.twitter.com/widgets.js\',function(){});\n }\n ;\n scroll_into = true;\n //scroll_into_id()\n});\nvar scroll_into = true;\nfunction scroll_into_id(parar = false) {\n if (parar) {\n if (true) {\n var id = window.location.hash.substring(1);\n if (document.getElementById(id)) {\n if (id.includes("comentario")) {\n document.querySelector(\'body\').classList.add("overflow");\n document.querySelector(\'#comentarios\').classList.add("activo");\n }\n document.getElementById(id).scrollIntoView({\n behavior: \'smooth\'\n });\n }\n document.querySelector(\'body\').classList.remove("overflow-hidden");\n //history.replaceState(null, null, \' \');\n //history.replaceState(\'\', document.title, window.location.href.split(\'#\')[0]); \n scroll_into = false;\n }\n }\n}
1\n// connect if there are any LiveViews on the page\nliveSocket.connect();\n\n// expose liveSocket on window for web console debug logs and latency simulation:\n// >> liveSocket.enableDebug()\n//liveSocket.enableDebug()\n// >> liveSocket.enableLatencySim(1000) // enabled for duration of browser session\n// >> liveSocket.disableLatencySim()\nwindow.liveSocket = liveSocket;\n//console.log(liveSocket)\n\ndocument.addEventListener(\'DOMContentLoaded\', function () {\n //apanhos_imagenes_articulos();\n //reubicar_publis(); //evitamos pedir laterales al principio\n cambio_apanhos();\n //social();\n apanhos_menus();\n //triggers_menus_mob();\n scrollHandler();\n //lecturas_cuenteo();\n //setInterval(function() {responsivelyLazy.run(); apanhos_imagenes_articulos()}, 300);\n setInterval(function () {\n responsivelyLazy.run();\n }, 300);\n setInterval(function () {\n scrollHandler();\n }, 500);\n var sw = true;\n window.addEventListener("scroll", function () {\n if (sw) {\n sw = false;\n setTimeout(function () {\n scrollHandler();\n sw = true;\n }, 300);\n }\n });\n if (typeof $(\'.linkpdf\').fancybox === "function") {\n $(".linkpdf").fancybox({\n type: "iframe"\n });\n }\n if ($(\'.articulo.show .twitter-tweet\').length || $(\'.articulo.search .twitter-tweet\').length) {\n //$.getScript(\'//platform.twitter.com/widgets.js\',function(){});\n }\n}, false);\nconst onScrollStop = callback => {\n let isScrolling;\n window.addEventListener(\'scroll\', e => {\n clearTimeout(isScrolling);\n isScrolling = setTimeout(() => {\n callback();\n }, 750);\n }, false);\n};\nonScrollStop(() => {\n if (document.querySelector(".banda-portada")) {\n document.querySelector(".banda-portada").style.display = "block";\n }\n});\nfunction scrollHandler() {\n subir_o_bajar();\n //social();\n header_en_sticky();\n ver_barra_progreso();\n apanhos_menus();\n if (document.querySelector("body:not(.formulario):not(.edit)")) {\n comprobar_publi_visible();\n }\n}\nfunction ajuste_menu_movil() {\n var posicion = document.querySelector("#MenuPosicion");\n posicion = ".menu_zona_socias_mobil .m_" + posicion.dataset.posicion;\n var m = document.querySelector(posicion);\n if (m && !m.classList.contains("activo")) {\n m.classList.add("activo");\n m.scrollLeft = 20;\n var x = m.getBoundingClientRect().x;\n if (x > 1) {\n document.querySelector(".menu_zona_socias_mobil .menu_container").scrollLeft = x;\n }\n }\n}\n\n// PUBLI\nvar extra_1 = document.querySelector(\'#articulo-contenido .col-extra .publicidades\');\nvar extra_2 = document.querySelector(\'.portada-portadilla .col-extra\');\nvar lateral_1 = document.querySelector(\'#lateral-1-container\');\nvar lateral_2 = document.querySelector(\'#lateral-2-container\');\nvar lateral_3 = document.querySelector(\'#lateral-3-container\');\nvar lateral_4 = document.querySelector(\'#lateral-4-container\');\nvar lateral_5 = document.querySelector(\'#lateral-5-container\');\nfunction actualizar_bloques_anuncios() {\n extra_1 = document.querySelector(\'#articulo-contenido .col-extra .publicidades\');\n extra_2 = document.querySelector(\'.portada-portadilla .col-extra\');\n lateral_1 = document.querySelector(\'#lateral-1-container\');\n lateral_2 = document.querySelector(\'#lateral-2-container\');\n lateral_3 = document.querySelector(\'#lateral-3-container\');\n lateral_4 = document.querySelector(\'#lateral-4-container\');\n lateral_5 = document.querySelector(\'#lateral-5-container\');\n lateral_5 = document.querySelector(\'#lateral-5-container\');\n}\nvar anuncios_reubicar = ["lateral-1", "lateral-2", "central-grande", "opinion-1", "opinion-2", "opinion-3", "lateral-3", "lateral-4", "central-grande-2", "bajo-1", "bajo-2", "bajo-3", "lateral-5"];\nfunction reubicar_publis_escritorio() {\n var lateral_1_p = document.getElementById("lateral-1");\n var lateral_2_p = document.getElementById("lateral-2");\n var lateral_3_p = document.getElementById("lateral-3");\n var lateral_4_p = document.getElementById("lateral-4");\n var lateral_5_p = document.getElementById("lateral-5");\n lateral_1 != null && lateral_1_p != null ? lateral_1.appendChild(lateral_1_p) : false;\n lateral_2 != null && lateral_2_p != null ? lateral_2.appendChild(lateral_2_p) : false;\n lateral_3 != null && lateral_3_p != null ? lateral_3.appendChild(lateral_3_p) : false;\n lateral_4 != null && lateral_4_p != null ? lateral_4.appendChild(lateral_4_p) : false;\n lateral_5 != null && lateral_5_p != null ? lateral_5.appendChild(lateral_5_p) : false;\n if (document.getElementById("anuncios-opinion")) {\n document.getElementById("anuncios-opinion").appendChild(document.getElementById("opinion-1"));\n document.getElementById("anuncios-opinion").appendChild(document.getElementById("opinion-2"));\n document.getElementById("anuncios-opinion").appendChild(document.getElementById("opinion-3"));\n }\n if (document.getElementById("anuncios-footer")) {\n document.getElementById("anuncios-footer").appendChild(document.getElementById("bajo-1"));\n document.getElementById("anuncios-footer").appendChild(document.getElementById("bajo-2"));\n document.getElementById("anuncios-footer").appendChild(document.getElementById("bajo-3"));\n }\n if (document.getElementById("central-grande-container")) {\n document.getElementById("central-grande-container").appendChild(document.getElementById("central-grande"));\n }\n if (document.getElementById("central-grande-2-container")) {\n document.getElementById("central-grande-2-container").appendChild(document.getElementById("central-grande-2"));\n }\n}\nfunction reubicar_publis_mobil() {\n var bloques = false;\n var contenido = document.querySelector("#articulo-contenido .col
1-contenido .articulo-texto-contenido");\n var cobertura = document.querySelectorAll(".cobertura");\n //var portada = document.querySelector("main .portada:not(.portada-portadilla)");\n var portada = document.querySelector("main .portada");\n if (contenido && portada) {\n if (cobertura.length > 0) {\n bloques = [...contenido.querySelectorAll(".cobertura")].concat([...portada.querySelectorAll(".resumen")]);\n } else {\n bloques = [...contenido.querySelectorAll("div:not(.resumen):not(blockquote) p")].concat([...portada.querySelectorAll(".resumen")]);\n }\n }\n if (!bloques && portada) {\n //bloques = portada.querySelectorAll(".grid .columna");\n if (!bloques) {\n bloques = portada.querySelectorAll(".resumen");\n }\n }\n if (bloques) {\n //console.log(bloques)\n anuncios_reubicar.forEach(function (elem, indice, array) {\n if (bloques && bloques[1 + 2 * indice] && document.getElementById(elem)) {\n //console.log(indice)\n //console.log(bloques[indice])\n //console.log(elem)\n bloques[1 + 2 * indice].insertAdjacentElement("afterend", document.getElementById(elem));\n } else {\n //console.log("DND???????????????????????\'\'\'\'")\n //console.log(elem)\n }\n });\n }\n}\n// Variables de coordinación entre publicidad y contenido\nvar publi_lock = false; // Evita manipulación simultánea\nvar publi_pendientes = []; // Anuncios pendientes de procesar\nvar contenidoupdating = false; // Indica actualización de contenido LiveView\n\nvar reubicar_las_publis = true;\nfunction reubicar_publis(forzar = false) {\n reubicar_las_publis = forzar ? true : reubicar_las_publis;\n\n // Si hay contenido actualizándose y no es forzado, pausar ejecución\n if (contenidoupdating && !forzar) return;\n if (reubicar_las_publis === true) {\n // Establecer lock para evitar conflicto con LazyLoadAd\n if (!publi_lock) {\n publi_lock = true;\n }\n actualizar_bloques_anuncios();\n if (document.querySelector(".articulo-contenido")) {\n var anuncio_grande = document.getElementById("central-grande");\n var contenido = document.querySelector("#articulo-contenido .col-contenido .articulo-texto-contenido");\n var cobertura = document.querySelectorAll(".cobertura");\n var bloques = [];\n if (contenido) {\n if (cobertura.length > 0) {\n bloques = contenido.querySelectorAll(".cobertura");\n } else {\n bloques = contenido.querySelectorAll("div:not(.resumen):not(blockquote):not(.twitter-tweet) p");\n }\n var bloque = Math.ceil(bloques.length / 2);\n if (bloques.length > 1 && bloque > 3 && anuncio_grande) {\n bloques[bloque].insertAdjacentElement("afterend", anuncio_grande);\n }\n }\n }\n if ($(window).width() < 767) {\n reubicar_publis_mobil();\n } else {\n reubicar_publis_escritorio();\n }\n if ($(window).width() > 1024 && !document.querySelector(".galeria_todo_ancho")) {\n if (document.getElementById(\'articulo-contenido\')) {\n var articulo_textos = document.querySelector(\'#articulo-textos .contenido\');\n var altura_articulo = 0;\n if (articulo_textos) {\n altura_articulo = articulo_textos.scrollHeight;\n }\n var altura_info = 0;\n if (document.querySelector(\'.info-blog\')) {\n altura_info = document.querySelector(\'.info-blog\').scrollHeight;\n }\n if (document.querySelector(\'.info-tema\')) {\n altura_info = altura_info + document.querySelector(\'.info-tema\').scrollHeight;\n }\n var altura = altura_articulo - altura_info;\n //var style = "height: "+altura+"px; max-height: "+altura+"px; min-height: "+altura+"px"\n //var style = "";\n\n if (extra_1) {\n //extra_1.setAttribute("style", style);\n extra_1.setAttribute("phx-update", "ignore");\n if (extra_2) {\n extra_2.setAttribute("phx-update", "ignore");\n }\n ;\n if (altura <= 300) {\n //console.log("lat-0");\n // 0 en articulo / 0 + 2\n //extra_1.remove();\n //extra_1.innerHTML = "";\n //if(lateral_4){ lateral_4.replaceWith(lateral_1)}\n //if(lateral_5){ lateral_5.replaceWith(lateral_2)}\n if (lateral_4 && lateral_1) {\n lateral_4.appendChild(lateral_1.children[0].cloneNode(true));\n }\n if (lateral_5 && lateral_2) {\n lateral_5.appendChild(lateral_2.children[0].cloneNode(true));\n }\n if (lateral_1) {\n lateral_1.classList.add("hidden");\n lateral_2.classList.add("hidden");\n lateral_3.classList.add("hidden");\n lateral_4.classList.add("h50");\n lateral_5.classList.add("h50");\n }\n } else if (altura >
1 300 && altura < 1000) {\n // console.log("lat-1");\n // 1 en articulo / 1 + 2\n //extra_2.replaceChild(lateral_2,lateral_4)\n //extra_2.replaceChild(lateral_3,lateral_5)\n if (lateral_4 && lateral_2) {\n lateral_4.appendChild(lateral_2.children[0].cloneNode(true));\n }\n if (lateral_5 && lateral_3) {\n lateral_5.appendChild(lateral_3.children[0].cloneNode(true));\n }\n if (lateral_1) {\n lateral_1.classList.add("h100");\n lateral_2.classList.add("hidden");\n lateral_3.classList.add("hidden");\n if (lateral_4) {\n lateral_4.classList.add("h50");\n }\n ;\n if (lateral_5) {\n lateral_5.classList.add("h50");\n }\n ;\n }\n } else if (altura >= 1000 && altura < 2500) {\n //console.log("lat-2");\n // 2 en articulo / 2 + 2\n //if(lateral_4 && lateral_3){ lateral_4.replaceWith(lateral_3)}\n if (lateral_5 && lateral_4) {\n lateral_5.appendChild(lateral_4.children[0].cloneNode(true));\n }\n if (lateral_4 && lateral_3) {\n lateral_4.appendChild(lateral_3.children[0].cloneNode(true));\n }\n //if(lateral_5){lateral_5.remove()}\n lateral_1.classList.add("h50");\n lateral_2.classList.add("h50");\n if (lateral_3) {\n lateral_3.classList.add("hidden");\n }\n ;\n if (lateral_4 && lateral_5) {\n lateral_4.classList.add("h50");\n }\n ;\n if (lateral_5) {\n lateral_5.classList.add("h50");\n }\n ;\n } else if (altura >= 2500) {\n //console.log("lat-3");\n // 3 en articulo todo / 3 + 2\n lateral_1.classList.add("h33");\n lateral_2.classList.add("h33");\n lateral_3.classList.add("h33");\n if (lateral_4) {\n lateral_4.classList.add("h50");\n }\n ;\n if (lateral_5) {\n lateral_5.classList.add("h50");\n }\n ;\n }\n }\n }\n } else {\n if (document.getElementById(\'articulo-contenido\')) {\n //var style = ""\n if (extra_1) {\n //extra_1.setAttribute("style", style);\n //extra_1.setAttribute("phx-update", "ignore");\n //extra_2.setAttribute("phx-update", "ignore");\n if (lateral_1) {\n lateral_1.classList.remove("h33");\n lateral_1.classList.remove("h50");\n lateral_1.classList.remove("h100");\n lateral_5.classList.remove("hidden");\n }\n if (lateral_2) {\n lateral_2.classList.remove("h33");\n lateral_2.classList.remove("h50");\n lateral_5.classList.remove("hidden");\n }\n if (lateral_3) {\n lateral_3.classList.remove("h33");\n lateral_3.classList.remove("h50");\n lateral_5.classList.remove("hidden");\n }\n if (lateral_4) {\n lateral_4.classList.remove("h50");\n lateral_5.classList.remove("hidden");\n }\n if (lateral_5) {\n lateral_5.classList.remove("h50");\n lateral_5.classList.remove("hidden");\n }\n }\n }\n }\n //console.log("Reubicadas publis")\n reubicar_las_publis = false;\n\n // Liberar lock y procesar anuncios pendientes\n setTimeout(() => {\n publi_lock = false;\n procesar_publi_pendientes();\n }, 100);\n }\n}\nfunction apanhos_publi_bloque_tema() {\n if ($(window).width() > 767 && document.querySelector(".info-tema")) {\n let h = document.querySelector(".info-tema").offsetHeight;\n let h2 = document.querySelector(".relacionadas").offsetHeight;\n document.querySelectorAll(".h100").forEach(el =>
1 {\n el.style.height = `calc(100% - ${h}px + ${h2}px)`;\n el.style.minHeight = `calc(100% - ${h}px + ${h2}px)`;\n el.style.maxHeight = `calc(100% - ${h}px + ${h2}px)`;\n });\n }\n}\n\n// Función para procesar anuncios pendientes después de liberar locks\nfunction procesar_publi_pendientes() {\n if (publi_pendientes.length === 0) return;\n\n //console.log("Procesando publicidad pendiente:", publi_pendientes);\n\n while (publi_pendientes.length > 0) {\n const modulo = publi_pendientes.shift();\n const elemento = document.querySelector(`[data-name="${modulo}"]`);\n if (elemento && !elemento.classList.contains(\'anuncio-activo\')) {\n // Simular evento de intersección para procesar el anuncio\n const event = new Event(\'intersect\');\n Object.defineProperty(event, \'isIntersecting\', {\n get: () => true\n });\n Object.defineProperty(event, \'intersectionRatio\', {\n get: () => 1\n });\n\n // Disparar manualmente el procesamiento\n const observer = new IntersectionObserver(([entry]) => {\n if (entry.isIntersecting) {\n elemento.dispatchEvent(new CustomEvent(\'ad-visible-trigger\', {\n detail: {\n modulo: modulo\n }\n }));\n }\n });\n observer.observe(elemento);\n observer.disconnect();\n }\n }\n}\nvar modulos_publi_iniciales = ["popup", "faldon"];\nvar modulos_publi = modulos_publi_iniciales;\nfunction comprobar_publi_visible() {\n var publis = [];\n var modulos = modulos_publi.slice(0);\n for (var i = 0; i < modulos_publi.length; i++) {\n if (document.getElementById(modulos_publi[i]) && basicos_visible(document.getElementById(modulos_publi[i]))) {\n //console.log("VISIBLE: "+ modulos_publi[i]);\n publis.push(modulos_publi[i]);\n modulos = modulos.filter(item => item !== modulos_publi[i]);\n }\n }\n if (publis.length > 0) {\n pedir_anuncios(publis);\n modulos_publi = modulos;\n }\n}\nfunction social() {\n if (document.getElementById(\'compartirPrincipal\')) {\n if (visible(document.getElementById(\'compartirPrincipal\')) || visible(document.querySelector(".banner-blogs"))) {\n ocultar(\'.fijo .compartir\');\n } else {\n mostrar(\'.fijo .compartir\');\n }\n if (!visible(document.getElementById(\'articulo-contenido\'))) {\n ocultar(\'.fijo .compartir\');\n }\n }\n}\nfunction ver_barra_progreso() {\n if (document.getElementById(\'articulo-contenido\')) {\n if (basicos_visible(document.getElementById(\'header\'))) {\n document.querySelector(\'.header\').classList.remove(\'header-out\');\n } else {\n document.querySelector(\'.header\').classList.add(\'header-out\');\n }\n }\n}\nvar rem = function (count) {\n var unit = $(\'html\').css(\'font-size\');\n if (typeof count !== \'undefined\' && count > 0) {\n return parseInt(unit) * count;\n } else {\n return parseInt(unit);\n }\n};\nvar scrollPos = 0;\nvar parar = 0;\nfunction subir_o_bajar() {\n var actual = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;\n var sticky_activo = document.querySelector(".sticky-header") ? document.querySelector(".sticky-header").offsetHeight : 0;
1\n var h = sticky_activo + rem(1.25);\n //console.log(actual +" "+ scrollPos + " " + (actual - scrollPos))\n var dif = actual - scrollPos;\n //console.log(dif)\n if (dif < -40) {\n //if (dif < -40 && sticky_activo) {\n //console.log("UP")\n document.querySelector(\'body\').classList.add(\'up\');\n document.querySelector(\'body\').classList.remove(\'down\');\n parar = 0;\n } else if (dif > 40) {\n //} else if (dif > 40 || sticky_activo == 0){\n //console.log("DOWN")\n document.querySelector(\'body\').classList.add(\'down\');\n document.querySelector(\'body\').classList.remove(\'up\');\n parar = 0;\n } else {\n if (parar == 2) {\n //document.querySelector(\'body\').classList.add(\'up\')\n //document.querySelector(\'body\').classList.remove(\'down\')\n }\n parar = parar + 1;\n //console.log("PARA")\n }\n var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n if (document.querySelector(".up-down") && dif < -40 && sticky_activo) {\n document.querySelector(".up-down").style.display = "block";\n } else if (document.querySelector(".up-down") && (dif > 40 || sticky_activo == 0)) {\n document.querySelector(".up-down").style.display = "none";\n }\n if (document.querySelector(".banda-portada")) {\n if (sticky_activo == 0) {\n document.querySelector(".banda-portada").style.display = "block";\n }\n if (dif > 50) {\n document.querySelector(".banda-portada").style.display = "none";\n } else if (dif < -40 && sticky_activo) {\n document.querySelector(".banda-portada").style.display = "block";\n }\n }\n if (document.querySelector("#menu-arriba .cabeceradoble")) {\n var cabecera_1 = document.querySelector(".cabecera_portada .cabeceradoble");\n var cabecera_2 = document.querySelector("#menu-arriba .cabeceradoble");\n var escondida = cabecera_1.getBoundingClientRect().bottom < -100;\n if (cabecera_1 && escondida) {\n cabecera_2.classList.add("visible-logo");\n } else {\n cabecera_2.classList.remove("visible-logo");\n }\n }\n if (w < 769) {\n if (document.querySelector(".up-down-articulo")) {\n if (basicos_visible(document.getElementById(\'articulo-textos\')) && !basicos_visible(document.querySelector("#compartirPrincipal .compartir"))) {\n document.querySelector(".header").classList.add("up-down-activo");\n } else {\n document.querySelector(".header").classList.remove("up-down-activo");\n }\n }\n }\n if (document.querySelector(".publi-lateral")) {\n document.querySelectorAll(".publi-lateral").forEach(lateral => {\n lateral.style.top = h + "px";\n });\n }\n scrollPos = actual <= 0 ? 0 : actual;\n}\n;\nfunction ubicacion_banda_inferior() {\n var width = $(window).width();\n const portada_bi = document.querySelector(\'.portada_bi\');\n if (portada_bi && width < 768) {\n var loc = location.pathname.split(\'/\');\n loc = loc.join("/");\n const boletines_bi = document.querySelector(\'.boletines_bi\');\n const misalto_bi = document.querySelector(\'.misalto_bi\');\n const guardados_bi = document.querySelector(\'.guardados_bi\');\n switch (loc) {\n case "/":\n portada_bi.classList.add(\'activa\');\n boletines_bi && boletines_bi.classList.remove(\'activa\');\n misalto_bi && misalto_bi.classList.remove(\'activa\');\n guardados_bi && guardados_bi.classList.remove(\'activa\');\n break;\n case "/zona-socias/boletines":\n portada_bi.classList.remove(\'activa\');\n boletines_bi && boletines_bi.classList.add(\'activa\');\n misalto_bi && misalto_bi.classList.remove(\'activa\');\n guardados_bi && guardados_bi.classList.remove(\'activa\');\n break;\n case "/mi-salto":\n portada_bi.classList.remove(\'activa\');\n boletines_bi && boletines_bi.classList.remove(\'activa\');\n misalto_bi && misalto_bi.classList.add(\'activa\');\n guardados_bi && guardados_bi.classList.remove(\'activa\');\n break;\n case "/zona-socias/articulos-guardados":\n portada_bi.classList.remove(\'activa\');\n boletines_bi && boletines_bi.classList.remove(\'activa\');\n misalto_bi && misalto_bi.classList.remove(\'activa\');\n guardados_bi && guardados_bi.classList.add(\'activa\');\n break;\n default:\n portada_bi.classList.remove(\'activa\');\n boletines_bi && boletines_bi.classList.remove(\'activa\');\n misalto_bi && misalto_bi.classList.remove(\'activa\');\n guardados_bi && guardados_bi.classList.remove(\'activa\');\n break;\n }\n }\n}\n;\nfunction pedir_anuncios(modulos) {\n //console.log("pedir anuncios")\n var width = $(window).width();\n if (width > 767) {\n var mobil = false;\n } else {\n var mobil = true;\n }\n var loc = location.pathname.split(\'/\').slice(1);\n const ubicaciones_sin_publi = ["info", "mi-salto", "zona-socias", "suscribirse", "formulario", "cuenta", "area-personal", "admin"];\n if (ubicaciones_sin_publi.includes(loc[0]) && document.querySelector("#css_zona_s
1ocias") == null) {\n var style = document.createElement(\'style\');\n style.setAttribute("id", "css_zona_socias");\n style.textContent = `\n #publi-cabecera,\n .anuncio {\n display: none !important;\n }\n `;\n document.head.appendChild(style);\n return true;\n } else {\n if (!ubicaciones_sin_publi.includes(loc[0]) && document.querySelector("#css_zona_socias")) {\n var css = document.querySelector("#css_zona_socias");\n css.remove();\n }\n }\n var slug = "";\n if (loc[0]) {\n slug = loc[0] + \'/\';\n }\n if (loc[1]) {\n slug = slug + loc[1] + \'/\';\n } else {\n slug;\n }\n ;\n if (loc[0] == "sin-publicar") {\n slug = loc[1] + \'/\' + loc[2];\n }\n var nodo = $(\'body\').attr(\'id\');\n if (!ubicaciones_sin_publi.includes(loc[0])) {\n $(\'body\').addClass(\'wait\');\n $.ajax({\n url: \'/api/\' + slug + \'anuncio/\' + modulos + \'/\' + nodo + \'/\' + mobil,\n type: \'GET\',\n dataType: \'json\',\n success: function (data) {\
1n $(\'body\').removeClass(\'wait\');\n modulos = data.data;\n $.each(modulos, function (row) {\n var modulo_publi = modulos[row].modulo;\n var modulo = $("#" + modulo_publi);\n if (modulos[row].maquetacion && modulos[row].maquetacion.no_publicidad == "no_publicidad") {\n modulo.addClass(\'bloque-activo\');\n } else {\n modulo.addClass(\'anuncio-activo\');\n }\n modulo.empty();\n modulo.attr(\'phx-update\', "ignore");\n if (modulos[row].script && modulos[row].script.length > 10) {\n //$(modulos[row].script).appendTo(modulo);\n //\n $(function () {\n // console.log(modulos[row].script);\n postscribe_min_default()(modulo, modulos[row].script);\n try {\n postscribe_min_default()(modulo, modulos[row].script);\n } catch (err) {\n console.log("Error al insertar script");\n }\n });\n //eval(modulos[row].script);\n } else {\n //modulo.addClass(\'anuncio-activo\');\n if (modulos[row].html && modulos[row].html.length > 1) {\n var div = $(\'<div/>\').addClass(\'html-anun\').appendTo(modulo);\n div.append(modulos[row].html);\n } else {\n if (modulos[row].url_redireccion) {\n var redireccion = modulos[row].url_redireccion;\n } else {\n var redireccion = "false";\n }\n var a = $(\'<a/>\').attr(\'data-anun\', modulos[row].id).attr(\'data-click\', redireccion).attr(\'href\', "/ir_anuncio/" + modulos[row].id + \'/\' + mobil).attr(\'target\', \'_blank\').attr(\'aria-label\', \'publicidad\').addClass(\'anuncio-link\').appendTo(modulo);\n if (modulos[row].imagen) {\n if (modulos[row].imagen.split(\'.\').pop().split(\'?\').shift() == "mp4") {\n var video = $(\'<video/>\').addClass(\'no-mep\').prop({\n autoplay: true,\n muted: true,\n loop: true\n }).attr(\'src\', modulos[row].imagen).attr(\'alt\', data.texto).appendTo(a);\n } else {\n var img = $(\'<img/>\').addClass(\'\').attr(\'src\', modulos[row].imagen).attr(\'alt\', data.texto).attr(\'fetchpriority\', \'hight\').appendTo(a);\n }\n }\n if (modulos[row].url_impresion) {\n var pixel = $(\'<img/>\').addClass(\'transparent\').attr(\'src\', modulos[row].url_impresion.replace("[timestamp]", +new Date())).attr(\'alt\', "Advertisment").attr(\'border\', "0").attr(\'height\', "1").attr(\'width\', "1").appendTo(a);\n }\n }\n }\n });\n popup();\n },\n error: function (request, error) {\n $(\'body\').removeClass(\'wait\');\n }\n });\n }\n $(document).on(\'click\', \'.anuncio-link\', function () {\n var url = $(this).attr("data-click");\n if (url != "false") {\n $.get(url);\n }\n });\n}\nfunction popup() {\n const popup = document.getElementById("popup");\n if (popup && popup.children.length !== 0) {\n setTimeout(function () {\n //const modal = document.getElementById("modal-popup");\n //if (modal) {\n // Mostrar el modal manualmente (sin Bootstrap)\n // modal.style.display = "block"; // o usa "flex" si tu CSS lo requiere\n // modal.classList.add("visible"); // opcional, por si tienes animaciones CSS\n // }\n $(\'#modal-popup\').modal(\'show\');\n const days = 1;\n const date = new Date();\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n const expires = "; expires=" + date.toUTCString();\n const name = "hab";\n const value = "saltarines";\n document.cookie = name + "=" + (value || "") + expires + "; path=/";\n }, 10000);\n popup.id = "popupOFF";\n }\n}\nfunction pedir_articulos(nodo, tipo) {\n $(\'body\').addClass(\'w
1ait\');\n $.ajax({\n url: \'/api/listar/\' + nodo + \'/\' + tipo,\n type: \'GET\',\n dataType: \'json\',\n success: function (data) {\n $(\'body\').removeClass(\'wait\');\n fabricar_menu_secciones(data.data, tipo);\n },\n error: function (request, error) {\n $(\'body\').removeClass(\'wait\');\n }\n });\n}\nfunction apanhos_menus() {\n var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n if (document.getElementById("menu-admin") && w > 768) {\n let h = document.querySelector("#menu-admin .container").getBoundingClientRect().height;\n if (document.getElementById("anuncio-cabecera")) {\n document.getElementById("anuncio-cabecera").style.marginTop = h;\n }\n if (document.querySelector("publi-lateral")) {\n h = document.getElementByClassName("seguimiento").getBoundingClientRect().height + h;\n document.querySelectorAll(".publi-lateral").forEach(lateral => {\n lateral.style.top = h;\n });\n }\n }\n}\n$(document).on(\'click\', \'.compartir_link\', function () {});\n$(document).on(\'click\', \'.anuncio a off\', function () {\n var d = $(this).attr("data-anun");\n $.ajax({\n url: \'/api/anuncio/redireccion/\' + d,\n type: \'PUT\',\n success: function (data) {}\n });\n});\nvar swiper_seccion = "";\nvar width = $(window).width();\nfunction cambio() {\n //social();\n apanhos_menus();\n //scrollHandler();\n apanhos_imagenes_articulos();\n}\nfunction apanho_crop() {\n var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n if (w > 768 && (document.querySelector("table.table .crop") || document.querySelector("table.table .crop2"))) {\n var table = document.querySelector("table.table");\n var crop = document.querySelector("table.table .crop");\n var crops = document.querySelectorAll("table.table .crop2");\n var crop1 = crops[0];\n var crop2 = crops[1];\n var ancho_contenedor_0 = table.parentNode.offsetWidth;\n if (crop) {\n crop.style.maxWidth = "100%";\n crop.style.width = "100%";\n }\n if (crop2) {\n crop2.style.maxWidth = "100%";\n crop2.style.width = "100%";\n }\n console.log(ancho_contenedor_0);\n var ancho_contenedor = table.getBoundingClientRect().x;\n console.log(ancho_contenedor);\n var ancho_tabla = table.offsetWidth;\n console.log(ancho_tabla);\n var ancho_crop = 0;\n if (crop) {\n ancho_crop = crop.offsetWidth;\n }\n if (crop2) {\n ancho_crop = crop2.offsetWidth + crop1.offsetWidth;\n }\n console.log(ancho_crop);\n var nuevo_ancho_crop = ancho_contenedor - (ancho_tabla - ancho_crop);\n console.log(nuevo_ancho_crop);\n document.querySelectorAll("table.table .crop").forEach(crop => {\n crop.style.maxWidth = `calc(${nuevo_ancho_crop}px)`;\n crop.style.width = `calc(${nuevo_ancho_crop}px )`;\n });\n document.querySelectorAll("table.table .crop2").forEach(crop => {\n crop.style.maxWidth = `calc(${nuevo_ancho_crop / 2}px)`;\n crop.style.width = `calc(${nuevo_ancho_crop / 2}px )`;\n });\n table.style.maxWidth = `calc(${ancho_contenedor_0}px - 1.5rem)`;\n table.style.width = `calc(${ancho_contenedor_0}px - 1.5rem)`;\n }\n}\nfunction apanhos_imagenes_articulos() {\n if (document.querySelector(".real .todo-el-ancho")) {\n document.querySelectorAll(".real .todo-el-ancho").forEach(imagen => {\n var prop = imagen.getAttribute("data-proporcion");\n var width = imagen.offsetWidth;\n imagen.style.paddingBottom = prop * width / 100 + "px";\n imagen.setAttribute(\'phx-update\', \'ignore\');\n });\n }\n var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n if (w > 768) {\n document.querySelectorAll(".vertical img").forEach(imagen => {\n imagen.parentNode.style.cssText = "cssText", "width: 75% !important; margin-right: 2.5em !important; margin-left: -37% !important; float: left";\n //imagen.nextElementSibling.style.marginLeft = "50%";\n });\n document.querySelectorAll(".real .vertical img").forEach(imagen =>
1 {\n var paddingBottom = imagen.parentNode.style.paddingBottom * .63;\n imagen.parentNode.style.cssText = `padding-bottom: ${paddingBottom}; margin: 0 !important;`;\n imagen.parentNode.parentNode.style.cssText = "margin: 0 0 0 -37% !important; float: left; clear: both; padding: 2.5rem 2.5rem 0 0";\n //imagen.parentNode.parentNode.querySelectorAll(".figure-caption").style.paddingLeft = "50%";\n imagen.style.marginLeft = "0 !important";\n var prop = imagen.parentNode.getAttribute("data-proporcion");\n var width = imagen.parentNode.offsetWidth;\n imagen.parentNode.style.paddingBottom = prop * width / 100 + "px";\n });\n } else {\n document.querySelectorAll(".vertical img").forEach(imagen => {\n imagen.parentNode.style.cssText = "cssText", "";\n });\n document.querySelectorAll(".real .vertical img").forEach(imagen => {\n var width = imagen.parentNode.offsetWidth;\n var prop = imagen.parentNode.getAttribute("data-proporcion");\n var paddingBottom = width * prop;\n imagen.parentNode.style.cssText = `padding-bottom: ${paddingBottom}; margin: 0 !important;`;\n imagen.parentNode.parentNode.style.cssText = "";\n imagen.style.marginLeft = "0 !important";\n imagen.parentNode.style.paddingBottom = prop * width / 100 + "px";\n });\n }\n}\nvar galleryTop = {};\nvar galleryThumbs = {};\nvar galleryThumbsFake = {};\nfunction swiper_galeria() {\n if ($(\'.gallery-top\').length) {\n galleryTop = new Swiper(\'.gallery-top\', {\n slidesPerView: 1,\n slidesPerGroup: 1,\n nextButton: \'.swiper-button-next\',\n prevButton: \'.swiper-button-prev\',\n onSlideChangeStart: function (swip) {\n if (width > 768) {\n var index = swip.activeIndex;\n var activo = swip.slides[index];\n galleryThumbs.slideTo(index);\n galleryThumbsFake.slideTo(index);\n var seccion = activo.getAttribute(\'data-seccion\');\n if (seccion != swiper_seccion) {\n swiper_seccion = seccion;\n var id_link = \'#apartado\' + seccion;\n var id_tab = \'#apartado\' + seccion + \'-tab\';\n $(\'.tablink\').removeClass(\'active\');\n $(\'.tab-pane\').removeClass(\'active\');\n $(\'.tab-pane\').removeClass(\'show\');\n $(id_link).addClass(\'active\');\n $(id_tab).addClass(\'active\');\n $(id_link).addClass(\'show\');\n $(id_tab).addClass(\'show\');\n $(id_tab).tab(\'show\');\n }\n }\n }\n });\n if (width > 768) {\n galleryThumbs = new Swiper(\'.gallery-thumbs\', {\n centeredSlides: true,\n slidesPerView: "auto",\n slidesPerGroup: 1,\n watchSlidesVisibility: true,\n centeredSlides: true,\n //touchRatio: 0.2,\n slideToClickedSlide: true,\n //pagination: ".swiper-pagination",\n //nextButton: \'.swiper-button-next2\',\n //prevButton: \'.swiper-button-prev2\',\n //paginationClickable: true,\n zoom: false,\n grabCursor: true,\n onSlideChangeStart: function (swip) {\n var index = swip.activeIndex;\n galleryTop.slideTo(index);\n }\n });\n galleryThumbsFake = new Swiper(\'.gallery-thumbs-fake\', {\n slidesPerView: 7,\n slidesPerGroup: 7,\n slideToClickedSlide: true,\n pagination: ".swiper-pagination",\n nextButton: \'.swiper-button-next2\',\n prevButton: \'.swiper-button-prev2\',\n paginationClickable: true,\n onSlideChangeStart: function (swip) {\n var index = swip.activeIndex;\n galleryTop.slideTo(index);\n }\n });\n galleryTop.params.control = galleryThumbs;\n galleryThumbs.params.control = galleryTop;\n }\n }\n var acceso = this;\n $(document).on(\'click\', \'.pedir .articulo-resumen\', pedir_articulo);\n $(document).on(\'dblclick\', \'.gallery-thumbs .swiper-slide-active\', pedir_articulo);\n $(\'a[data-toggle="tab"]\').on(\'shown.bs.tab\', function (e) {\n e.target; // newly activated tab;\n var id = e.target.getAttribute(\'aria-controls\');\n var id_art = $(\'#\' + id + \' .swiper-slide\').first().attr(\'data-articulo\');\n e.relatedTarget; // previous active tab\n var item = $(".gallery-top *[data-articulo=" + id_art + "]");\n var index = $(".gallery-top .articulo-resumen").index(item);\n if (index > -1) {\n galleryTop.slideTo(index);\n }\n var id_link = \'#\' + id;\n var id_tab = \'#\' + id + \'-tab\';\n $(\'.tablink\').removeClass(\'active\');\n $(\'.tab-pane\').removeClass(\'active\');\n $(\'.tab-pane\').removeClass(\'show\');\n $(id_link).addClass(\'active\');\n $(id_tab).addClass(\'active\');\n $(id_link).addClass(\'show\');\n $(id_tab).addClass(\'show\');\n $(id_tab).tab(\'show\');\n });\n}\n$(document).ready(function () {\n if ($(\'.swiper-socias\').length) {\n var swiper = new Swiper(\'.swiper-socias\', {\n nextButton: \'.swiper-button-next\',\n prevButton: \'.swiper-button-prev\',\n pagination: ".swiper-pagination",\n spaceBetween: 0,\n speed: 4000,\n loop: true,\n autoplay: {\n delay: 6000\n }\n });\n }\n});\nfunction swiper_galeria_modal() {\n $(".modal").on(\'show.bs.modal\', function (e) {\n setTimeout(function () {\n if ($(\'.swiper-galeria\').length) {\n var img = $(e.relatedTarget).attr("data-img");\n var swiper = new Swiper(\'.swiper-galeria\', {\n initialSlide: img,\n slidesPerView: 1,\n slidesPerGroup: 1,\n nextButton: \'.swiper-buttom-next\',\n prevButton: \'.swiper-buttom-prev\',\n effect: \'fade\',\n pagination: \'.pagination\',\n paginationType: \'custom\',\n paginationCustomRender: function (swiper, current, total) {\n return current + \'/\' + total;\n }\n });\n }\n }, 500);\n });\n $(document).on(\'click\', \'.ocultar-info\', function () {\n var cols = document.querySelectorAll(\'.swiper-galeria .info\');\n for (var c = 0; c < cols.length; ++c) {\n cols[c].classList.toggle(\'oculto\');\n }\n });\n}\n;
1\nfunction pedir_articulo() {\n var id = $(this).attr("data-articulo");\n $(\'body\').addClass(\'wait\');\n $.ajax({\n url: \'/api_secur/articulo/\' + id,\n type: \'GET\',\n dataType: \'json\',\n success: function (data) {\n $(\'body\').removeClass(\'wait\');\n var articulo = $(\'.articulo-completo\');\n articulo.html(\'\');\n articulo.html(data.articulo);\n cambio();\n $(\'html, body\').stop().animate({\n \'scrollTop\': articulo.offset().top - $(".seguimiento").height() - 25\n }, 900, \'swing\');\n },\n error: function (request, error) {\n $(\'body\').removeClass(\'wait\');\n }\n });\n var id_tab = $("#TabContent *[data-articulo=" + id + "]").parent().parent().parent().parent().attr("id");\n var id_link = \'#\' + id_tab;\n id_tab = \'#\' + id_tab + \'-tab\';\n $(\'.tablink\').removeClass(\'active\');\n $(\'.tab-pane\').removeClass(\'active\');\n $(\'.tab-pane\').removeClass(\'show\');\n $(id_link).addClass(\'active\');\n $(id_tab).addClass(\'active\');\n $(id_link).addClass(\'show\');\n $(id_tab).addClass(\'show\');\n $(id_tab).tab(\'show\');\n var item = $(".gallery-top *[data-articulo=" + id + "]");\n var index = $(".gallery-top .articulo-resumen").index(item);\n galleryTop.slideTo(index);\n galleryThumbsFake.slideTo(index);\n}\n$(document).ready(function () {\n if ($(\'.swiper-edicion-impresa\').length) {\n var swiper = new Swiper(\'.swiper-edicion-impresa\', {\n nextButton: \'.swiper-ed-next\',\n prevButton: \'.swiper-ed-prev\',\n spaceBetween: 0,\n slidesPerView: 1,\n slidesPerGroup: 1\n });\n }\n});\n$(document).ready(function () {\n var width = $(window).width();\n if (width < 768) {\n if ($(\'.relacionadas-OFF .resumen\').length > 1) {\n var swiper = new Swiper(\'.relacionadas .col-md-9\', {\n slideClass: "resumen",\n wrapperClass: "card-deck-portada",\n nextButton: \'.swiper-numeros-next\',\n prevButton: \'.swiper-numeros-prev\',\n slidesPerView: 1,\n slidesPerGroup: 1\n });\n }\n if ($(\'.numero .resto\').length || $(\'.swiper-numeros\').length) {\n var swiper = new Swiper(\'.swiper-numeros\', {\n nextButton: \'.swiper-numeros-next\',\n prevButton: \'.swiper-numeros-prev\',\n slidesPerView: 1,\n slidesPerGroup: 1\n });\n }\n }\n if ($(\'.swiper-libros\').length) {\n var swiper = new Swiper(\'.swiper-libros\', {\n nextButton: \'.swiper-libros-next\',\n prevButton: \'.swiper-libros-prev\',\n slidesPerView: 4,\n slidesPerGroup: 4,\n breakpoints: {\n 768: {\n slidesPerView: 1,\n slidesPerGroup: 1\n }\n }\n });\n }\n});\n\n/*\n$(document).ready(function(){\n // to fade in on page load\n // to fade out before redirect\n $(\'a\').click(function(e){\n redirect = $(this).attr(\'href\');\n e.preventDefault();\n $(\'body\').fadeOut(400, function(){\n document.location.href = redirect\n });\n });\n})\n\n\n\nvar tooltips = document.querySelectorAll(\'.resumen\');\nfor(var i = 0; i < tooltips.length; i++) {\n tooltips[i].addEventListener(\'mousemove\', function fn(e) {\n if (e.target.classList.contains("entradilla_hover")) {\n var tooltip = e.target.classList.contains("entradilla_hover") ?\n e.target :\n e.target.querySelector(\':scope .entradilla_hover\');\n tooltip.style.left =\n e.pageX + tooltip.clientWidth + 10 <\n document.body.clientWidth ?\n e.pageX + 10 + \'px\' :\n document.body.clientWidth + 5 - tooltip.clientWidth + \'px\';\n tooltip.style.top =\n e.pageY + tooltip.clientHeight + 10 <\n document.body.clientHeight ?\n e.pageY + 10 + \'px\' : \n document.body.clientHeight + 5 - tooltip.clientHeight + \'px\';\n }\n });\n}\n*/\n//document.addEventListener(\'DOMContentLoaded\', function() {\nfunction recortar_comentarios() {\n var linkClick = function (e) {\n var m = e.currentTarget;\n if (m.classList.contains(\'less\')) {\n m.classList.remove(\'less\');\n m.innerHTML = moretext;\n } else {\n m.classList.add(\'less\');\n m.innerHTML = lesstext;\n }\n m.parentNode.classList.toggle(\'visible\');\n //m.parentNode.nextSlibing.classList.toggle(\'visible\')\n return false;\n };\n var showChar = 300;\n var ellipsestext = "...";\n var moretext = "<svg class=\'icon\' title=\'\' viewBox=\'700 400 100 100\'><use xlink:href=\'#mas\'></use></svg>";\n var lesstext = "<svg class=\'icon\' title=\'\' viewBox=\'400 700 100 100\'><use xlink:href=\'#menos\'></use> </svg>";\n var mores = document.getElementsByClassName(\'cortar_texto\');\n for (var i = 0; i < mores.length;
1 i++) {\n var content = mores[i].innerHTML;\n if (content.length > showChar) {\n var c = content.substr(0, showChar);\n var h = content.substr(showChar, content.length - showChar);\n var html = \'\' + c + \'<span class="moreellipses">\' + ellipsestext + \' </span><span class="morecontent"><span>\' + h + \'</span><a class="morelink">\' + moretext + \'</a></span>\';\n mores[i].innerHTML = html;\n }\n }\n var morelinks = document.getElementsByClassName(\'morelink\');\n for (var i = 0; i < morelinks.length; i++) {\n morelinks[i].onclick = linkClick;\n }\n}\nfunction copiar_acortados() {\n var copiar_txt = function (e) {\n var el = e.currentTarget;\n var text = el.getAttribute("texto");\n var textArea = document.createElement(\'textarea\');\n textArea.setAttribute(\'style\', \'width:1px;border:0;opacity:0;\');\n document.body.appendChild(textArea);\n textArea.value = text;\n textArea.select();\n document.execCommand(\'copy\');\n document.body.removeChild(textArea);\n };\n var copiar = document.getElementsByClassName("copiar");\n for (var i = 0; i < copiar.length; i++) {\n copiar[i].onclick = copiar_txt;\n }\n var copiar_acortado = document.getElementById("copiar_acortado");\n if (copiar_acortado) {\n copiar_acortado.onclick = function () {\n var valor = document.getElementById(\'articulo_acortado\').value ? document.getElementById(\'articulo_acortado\').value : document.getElementById(\'articulo_id\').value;\n var textArea = document.createElement(\'textarea\');\n textArea.setAttribute(\'style\', \'width:1px;border:0;opacity:0;\');\n document.body.appendChild(textArea);\n textArea.value = "https://elsal.to/" + valor;\n textArea.select();\n document.execCommand(\'copy\');\n document.body.removeChild(textArea);\n };\n }\n}\nvar segundos = 0;\nvar relacionadas = false;\nfunction pagina_activa() {\n var repetir = true;\n if (document.visibilityState == "visible") {\n segundos++;\n }\n if (document.getElementsByClassName("relacionadas").length && visible(document.getElementsByClassName("relacionadas")[0])) {\n relacionadas = true;\n }\n if (segundos > 15 && relacionadas) {\n // anotar\n //console.log("anotar")\n //anotar_lectura();\n repetir = false;\n }\n if (repetir) {\n setTimeout(function () {\n pagina_activa();\n }, 1000);\n }\n}\n//pagina_activa()\n\nfunction anotar_lectura() {\n const csrf = document.querySelector(\'meta[name="csrf-token"]\').content;\n const url = "/articulo/anotar/1223";\n fetch(url, {\n method: "PUT",\n headers: {\n \'x-csrf-token\': csrf\n }\n });\n}\nlet processScroll = () => {\n if (document.getElementById("articulo-contenido")) {\n let docElem = document.documentElement,\n docBody = document.body,\n scrollTop = docElem[\'scrollTop\'] || docBody[\'scrollTop\'],\n header = document.getElementsByTagName("header")[0].offsetHeight,\n halfWindowHeight = window.screen.height / 3,\n scrollStop = document.getElementById(\'articulo-contenido\').offsetHeight,\n scrollBottom_old = (docElem[\'scrollHeight\'] || docBody[\'scrollHeight\']) - scrollStop,\n scrollBottom = scrollStop - halfWindowHeight,\n scrollPercent = (scrollTop - header) / scrollBottom;\n scrollPercent = scrollPercent < 0 ? 0 : scrollPercent;\n scrollPercent = scrollPercent * 100 + \'%\';\n if (document.getElementById("progress-bar") && scrollStop > 0) {\n document.getElementById("progress-bar").style.setProperty("--scrollAmount", scrollPercent);\n }\n }\n};\nif (document.getElementById("articulo-contenido")) {\n document.addEventListener("scroll", processScroll);\n}\nwindow.addEventListener("scroll_to", e => {\n e.target.scrollIntoView();\n});\nfunction header_en_sticky() {\n var sensor = document.querySelector(".sticky-sensor");\n var header = document.querySelector("header");\n var contenido = document.querySelector("#contenido-principal");\n var tema = false;\n if (document.querySelector(".nube-tema")) {\n contenido = document.querySelector(".nube-tema");\n tema = true;\n }\n if (document.querySelector(".articulo-contenido")) {\n contenido = false;\n }\n if (header) {\n var observer = new IntersectionObserver(([e]) =>
1 {\n header.classList.toggle("sticky-header", e.intersectionRatio < 1);\n var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n if (w < 768 && contenido && e.intersectionRatio < 1) {\n contenido.style.paddingTop = `${header.clientHeight}px`;\n } else if (contenido && !tema) {\n contenido.style.paddingTop = 0;\n }\n }, {\n threshold: [1]\n });\n observer.observe(sensor);\n }\n}\nvar reubicar_resumenes_articulos = false;\nfunction reubicar_resumenes_articulo() {\n if (reubicar_resumenes_articulos === false) {\n document.querySelectorAll(\'[data-articulo-resumen]\').forEach(resumen => {\n var id = resumen.dataset.articuloResumen;\n var ubicacion = document.getElementById(`ubicacion_articulo_${id}`);\n var articulo = document.getElementById(`mover_ubicacion_${id}`);\n ubicacion.replaceWith(articulo);\n reubicar_resumenes_articulos = false;\n });\n }\n}\nwindow.addEventListener(\'orientationchange\', cambio_medidas);\nwindow.addEventListener(\'DOMContentLoaded\', cambio_medidas);\ndocument.addEventListener(\'DOMContentLoaded\', publi_version);\nwindow.addEventListener(\'resize\', cambio_medidas);\nfunction cambio_medidas() {\n medidas();\n publi_version_cambio();\n apanhos_imagenes_articulos();\n}\nvar publi_version_actual = "";\nfunction publi_version() {\n var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n w <= 768 ? publi_version_actual = "mobil" : publi_version_actual = "escritorio";\n}\nfunction publi_version_cambio() {\n var anterior = publi_version_actual;\n publi_version();\n publi_version_actual == anterior ? true : reubicar_publis(true);\n}\nfunction lanzar_scripts() {\n lanzar_codigos_embebidos();\n //console.log("LANZANDO SCRIPTSSSS")\n var entradilla = document.querySelector("#entradilla2");\n if (entradilla) {\n var infografia = entradilla.innerHTML;\n entradilla.innerHTML = "";\n if (infografia) postscribe_min_default()("#entradilla2", infografia);\n }\n var flourish = document.querySelector(".flourish-embed");\n if (document.querySelector(".flourish-embed iframe")) {\n flourish = false;\n } else {\n flourish = flourish;\n }\n if (flourish) {\n window.FlourishLoaded = null;\n const script_flourish = "<script src=\'https://public.flourish.studio/resources/embed.js\'><\/script>";\n postscribe_min_default()("#UbicacionScripts", script_flourish);\n //console.log("!!!!!!!!!!!!!!!!!!!!")\n }\n}\nvar ejecutados_embebidos = false;
1\nfunction lanzar_codigos_embebidos() {\n if (ejecutados_embebidos === false) {\n ejecutados_embebidos = true;\n var embeds = document.querySelectorAll(".embed_data");\n for (var i = 0; i < embeds.length; i++) {\n var embed = embeds[i].getElementsByTagName("codigo")[0];\n var id = embeds[i].getAttribute("move_to");\n //console.log("aqui "+ id)\n var to = document.getElementById(id);\n //console.log(to)\n //console.log(codigo)\n var codigo = decodeURI(embed.getAttribute("codigo"));\n if (to.innerHTML === "") {\n to.innerHTML = "<span></span>";\n postscribe_min_default()("#" + id, codigo);\n }\n }\n }\n}\nvar ejecutados_limitados = false;\nfunction limitados() {\n if (ejecutados_limitados === false) {\n ejecutados_limitados = true;\n var limitados = document.querySelectorAll(".limitado");\n limitados = Array.from(limitados).filter(el => !el.closest(\'.socias_opinion\'));\n var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n if (w > 768) {\n for (var i = 0; i < limitados.length; i++) {\n var limitado = limitados[i];\n limitado.parentNode.classList.add("limitar");\n if (limitado.scrollHeight > limitado.clientHeight || limitado.scrollWidth > limitado.clientWidth) {\n limitado.parentNode.classList.add("limitar");\n } else {\n limitado.parentNode.classList.remove("limitar");\n }\n if (limitado.scrollHeight >= 30) {\n limitado.parentNode.classList.add("limitar");\n }\n }\n }\n }\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTcuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9qcy9iYXNpY29zLmpzPzM0MjAiLCJ3ZWJwYWNrOi8vLy4vanMvcHVibGkuanM/ZTA5NSIsIndlYnBhY2s6Ly8vLi4vZGVwcy9waG9lbml4L3ByaXYvc3RhdGljL3Bob2VuaXgubWpzPzRlMjAiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL3Bob2VuaXhfbGl2ZV92aWV3L3ByaXYvc3RhdGljL3Bob2VuaXhfbGl2ZV92aWV3LmVzbS5qcz8xMGRiIiwid2VicGFjazovLy8uLi9kZXBzL2xpdmVfc2VsZWN0L3ByaXYvc3RhdGljL2xpdmVfc2VsZWN0Lm1pbi5qcz81YTNiIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9hbHBpbmVqcy9kaXN0L21vZHVsZS5lc20uanM/ZGQ1MiIsIndlYnBhY2s6Ly8vLi9qcy9hcHAuanM/NzQ3MyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZnVuY3Rpb24gbWVkaWRhcygpIHtcbiAgdmFyIHcgPSB3aW5kb3cuaW5uZXJXaWR0aFxuICAgIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aFxuICAgIHx8IGRvY3VtZW50LmJvZHkuY2xpZW50V2lkdGg7XG5cbiAgdmFyIGggPSB3aW5kb3cuaW5uZXJIZWlnaHRcbiAgICB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0XG4gICAgfHwgZG9jdW1lbnQuYm9keS5jbGllbnRIZWlnaHQ7IFxuXG4gIGggPiB3ID8gZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKFwicG9ydHJhaXRcIikgOiBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoXCJwb3J0cmFpdFwiKTtcbiAgaCA8IHcgPyBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoXCJsYW5kc2NhcGVcIikgOiBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoXCJsYW5kc2NhcGVcIik7XG59O1xuXG52YXIgYm9keSA9IGRvY3VtZW50LmJvZHksXG4gICAgaHRtbCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcblxudmFyIGhlaWdodCA9IE1hdGgubWF4KCBib2R5LnNjcm9sbEhlaWdodCwgYm9keS5vZmZzZXRIZWlnaHQsIFxuICAgICAgICAgICAgICAgICAgICAgICBodG1sLmNsaWVudEhlaWdodCwgaHRtbC5zY3JvbGxIZWlnaHQsIGh0bWwub2Zmc2V0SGVpZ2h0ICk7XG5cblxuZXhwb3J0IGZ1bmN0aW9uIHZpc2libGUoZWwpIHtcbiAgaWYgKGVsKSB7XG4gICAgY29uc3QgYW50ZWxhY2lvbiA9IDI1MDtcbiAgICBjb25zdCBlbGVtID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgdmFyIGFsdHVyYSA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQ7XG4gICAgdmFyIGlzVmlzaWJsZSA9IChlbGVtLnRvcCA+PSAwICYmIGVsZW0udG9wPD0gYWx0dXJhKSBcbiAgICAgICAgICAgICAgICAgICAgfHwgKGVsZW0uYm90dG9tID49IDAgJiYgZWxlbS50b3A8PSBhbHR1cmEpXG4gICAgICAgICAgICAgICAgICAgIHx8IChlbGVtLnRvcCA8IGFsdHVyYSArIGFudGVsYWNpb24gJiYgZWxlbS5ib3R0b20gPiAwKTtcbiAgICByZXR1cm4gaXNWaXNpYmxlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gbW9zdHJhcihjbGFzZXMpe1xuICB2YXIgbW9zdHJhciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoY2xhc2VzKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtb3N0cmFyLmxlbmd0aDsgaSsrKSB7XG4gICAgbW9zdHJhcltpXS5zdHlsZS5vcGFjaXR5ID0gMTtcbiAgICBtb3N0cmFyW2ldLnN0eWxlLnZpc2liaWxpdHkgPSBcInZpc2libGVcIjtcbiAgICBtb3N0cmFyW2ldLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG9jdWx0YXIoY2xhc2VzKXtcbiAgdmFyIG9jdWx0YXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKGNsYXNlcyk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgb2N1bHRhci5sZW5ndGg7IGkrKykge1xuICAgIG9jdWx0YXJbaV0uc3R5bGUub3BhY2l0eSA9IDA7XG4gICAgb2N1bHRhcltpXS5zdHlsZS52aXNpYmlsaXR5ID0gXCJoaWRkZW5cIjtcbiAgICBvY3VsdGFyW2ldLnN0eWxlLnZpc2liaWxpdHkgPSBcIm5vbmVcIjtcbiAgfVxufVxuXG4iLCJqUXVlcnkoXCJkb2N1bWVudFwiKS5yZWFkeShmdW5jdGlvbigkKXtcbiAgY2FtYmlvX2FwYW5ob3MoKTtcbiAgYXBhbmhvc19zd2lwKCk7XG59KTtcbmZ1bmN0aW9uIGFwYW5ob3Nfc3dpcCgpe1xuICBpZiAoJCgnLnN3aXBlci1zb2NpYXMnKS5sZW5ndGgpIHtcbiAgICB2YXIgd2lkdGggPSAkKHdpbmRvdykud2lkdGgoKTtcbiAgICBpZiAod2lkdGg+NzY3KXsgXG4gICAgICAkKCcuc3dpcGVyLXNvY2lhcyAuc3dpcGVyLXdyYXBwZXInKS5jc3MoXCJoZWlnaHRcIiwgd2lkdGgvMi4xKTtcbiAgICB9ICAgXG4gI
1H1cbn1cbiQoZnVuY3Rpb24oKSB7XG4gIHZhciAkd2luZG93ID0gJCh3aW5kb3cpO1xuICB2YXIgd2lkdGggPSAkd2luZG93LndpZHRoKCk7XG4gIHZhciBoZWlnaHQgPSAkd2luZG93LmhlaWdodCgpO1xuICBzZXRJbnRlcnZhbChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCh3aWR0aCAhPSAkd2luZG93LndpZHRoKCkpIHx8IChoZWlnaHQgIT0gJHdpbmRvdy5oZWlnaHQoKSkpIHtcbiAgICAgIHdpZHRoID0gJHdpbmRvdy53aWR0aCgpO1xuICAgICAgaGVpZ2h0ID0gJHdpbmRvdy5oZWlnaHQoKTtcbiAgICAgIGNhbWJpb19hcGFuaG9zKCk7XG4gICAgfVxuICB9LCAzMDApO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gY2FtYmlvX2FwYW5ob3MoKXsgXG4gICAgJCgnLnZpZGVvcyAuY2Fyb3VzZWwtaW5uZXInKVxuICAgICAgLmhlaWdodCgkKCcudmlkZW9zIC5jYXJvdXNlbC1pdGVtLmFjdGl2ZScpLm91dGVySGVpZ2h0KCkpO1xuICB2YXIgd2lkdGggPSAkKHdpbmRvdykud2lkdGgoKTtcbiAgaWYgKCQod2luZG93KS53aWR0aCgpPjc2OSl7IFxuICAgICQoXCIuY29udGVuaWRvIC5jb250ZW5pZG8gLnJlYWwgLnRvZG8tZWwtYW5jaG9cIikuZWFjaChmdW5jdGlvbigpe1xuICAgICAgY29uc29sZS5sb2coXCJjYW1iaW9fYXBhbmhvc1wiKVxuICAgICAgdmFyIHByb3AgPSAkKHRoaXMpLmF0dHIoXCJkYXRhLXByb3BvcmNpb25cIik7XG4gICAgICB2YXIgd2lkdGggPSAkKHRoaXMpLndpZHRoKCk7XG4gICAgICAkKHRoaXMpLmNzcyhcInBhZGRpbmctYm90dG9tXCIsIGZ1bmN0aW9uKCl7XG4gICAgICAgIHJldHVybiBwcm9wKndpZHRoLzEwMH0pO1xuICAgIH0pO1xuXG4gICAgdmFyIGZpam9fY29tcGFydGlyID0gJChcIi5maWpvIC5jb21wYXJ0aXJcIik7XG4gICAgaWYgKGZhbHNlICYmIGZpam9fY29tcGFydGlyKSB7XG4gICAgICB2Y
1XIgbGVmdCA9ICgod2lkdGggLSAkKFwiLmFydGljdWxvLWNvbnRlbmlkbyAuY2FiZWNlcmEgLmNvbnRhaW5lclwiKS53aWR0aCgpKS8yKSAtIGZpam9fY29tcGFydGlyLndpZHRoKCk7XG4gICAgICBpZiAobGVmdCA8IDApeyBsZWZ0ID0gMDsgfVxuICAgICAgJChcIi5maWpvIC5jb21wYXJ0aXJcIikgLmNzcyhcImxlZnRcIixsZWZ0KTtcbiAgICB9XG4gICAgdmFyIGxlZnQgPSAoKHdpZHRoIC0gJChcIiNtZW51LWFycmliYSAuY29udGFpbmVyXCIpLndpZHRoKCkpLzIpO1xuICAgIHZhciB2aWRlb190ZXh0byA9ICQoXCIudmlkZW8tdGV4dG9cIik7XG4gICAgaWYgKHZpZGVvX3RleHRvKSB7XG4gICAgICB2aWRlb190ZXh0b1xuICAgICAgICAuY3NzKFwicGFkZGluZy1sZWZ0XCIsbGVmdCk7XG4gICAgfVxuICAgICQoXCIuZGVzdGFjYWRhMSAuZWxlbTEubm9lbmNhbGFkYSAucmVzdW1lbjpmaXJzdC1vZi10eXBlIC5yZXNwb25zaXZlbHktbGF6eVwiKVxuICAgICAgLmNzcyhcIm92ZXJmbG93XCIsXCJoaWRkZW5cIilcbiAgICAgIC5jc3MoXCJwYWRkaW5nLWJvdHRvbVwiLFwiNDAlXCIpO1xuICAgICQoXCIuZGVzdGFjYWRhMSAuZWxlbTEubm9lbmNhbGFkYSAucmVzdW1lbjpmaXJzdC1vZi10eXBlIC5yZXNwb25zaXZlbHktbGF6eSBpbWdcIilcbiAgICAgIC5jc3MoXCJ0b3BcIixcIi0yMCVcIilcbiAgICAgIC5jc3MoXCJoZWlnaHRcIixcIjE0MCVcIik7XG5cbiAgfSBlbHNlIHtcbiAgICAkKFwiLmNvbnRlbmlkbyAuY29udGVuaWRvIGltZ1wiKVxuICAgICAgLmNzcyhcIndpZHRoXCIsXCIxMDAl
1XCIpXG4gIH1cblxuICAvL3ZhciBmb3RvcyA9IGh0bWwubWF0Y2goL3t7KFtBLXouanBnXSopfX0vKTtcbiAgLy8kKCd2aWRlbyxhdWRpbycpLm5vdCgnLm5vLW1lcCwuZnVsbHNjcmVlbi1iZ19fdmlkZW8nKS5tZWRpYWVsZW1lbnRwbGF5ZXIoe1xuICAgIC8vdmFyIHBsYXllciA9IG5ldyBNZWRpYUVsZW1lbnQoXCJ2aWRlby1wcmluY2lwYWxcIiwge1xuLy8gIHZhciBtZWRpYUUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInZpZGVvLXByaW5jaXBhbFwiKTtcbi8vICBjb25zb2xlLmxvZyhcInh4eFwiKVxuLy8gIGNvbnNvbGUubG9nKG1lZGlhRSk7XG4vLyAgdmFyIHBsYXllciA9IG5ldyBNZWRpYUVsZW1lbnQobWVkaWFFLCB7XG4vLyAgICBpY29uU3ByaXRlOiAnL2pzL21lZGlhZWxlbWVudC9tZWpzLWNvbnRyb2xzLnN2ZycsXG4vLyAgICBzdHJldGNoaW5nOiAncmVzcG9uc2l2ZScgLFxuLy8gIH0pO1xuXG4gIHZhciBpZnJhbWVzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmFydGljdWxvLWNvbnRlbmlkbyBpZnJhbWUnKTtcbiAgaWYgKGlmcmFtZXMgJiYgaWZyYW1lcy5sZWd0aCl7IFxuICBmb3IgKHZhciBpID0gMDsgaSA8IGlmcmFtZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgbWVkaWRhcyA9IGlmcmFtZXNbaV0uRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB2YXIgaWZyYW1lX3cgPSBtZWRpZGFzLndpZHRoO1xuICAgIHZhciBoID0gaWZyYW1lc1tpXS5nZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIik7XG4gICAgdmFyIHcgPSBpZnJhbWVzW2ldLmdldEF0dHJpYnV0ZShcIndpZHRoXCIpO1xuICAgIHZhciBhbHR1cmEgPSBpZnJhbWVfdy93Kmg7XG4gICAgaWZyYW1lc1tpXS5zdHlsZS5oZWlnaHQgPSBhbHR1cmE7XG4gIH1cbiAgfVxufTtcblxuJCgnLm1vZGFsJykub24oJ3Nob3duLmJzLm1vZGFsJywgZnVuY3Rpb24gKGUpIHtcbiAgdmFyIG1vZGFsX2JveCA9ICQodGhpcykuZmluZCgnLm1vZGFsJyk7XG4gIG1vZGFsX2JveC5jc3MoXCJkaXNwbGF5XCIsIFwiZmxleCAhaW1wb3J0YW50IFwiKTtcbiAgdmFyIG1vZGFsID0gJCh0aGlzKS5maW5kKCcubW9kYWwtZGlhbG9nJyk7XG4gIHZhciBtb2RhbGMgPSAkKHRoaXMpLmZpbmQoJy5tb2RhbC1jb250ZW50Jyk7XG4gIHZhciBtb2RhbG8gPSAkKHRoaXMpLmZpbmQoJy5tZWpzX19jb250YWluZXIgaWZyYW1lJyk7XG4gIHZhciBydyA9IG1vZGFsLndpZHRoKCk7XG4gIHZhciBoID0gJCh0aGlzKS5maW5kKCcubWVqc19fY29udGFpbmVyIGlmcmFtZScpLmF0dHIoXCJoZWlnaHRcIik7XG4gIHZhciB3ID0gJCh0aGlzKS5maW5kKCcubWVqc19fY29udGFpbmVyIGlmcmFtZScpLmF0dHIoXCJ3aWR0aFwiKTtcbiAgdmFyIGFsdHVyYSA9IHJ3L3cqaDtcbiAgJCh0aGlzKS5maW5kKCcubWVqc19fbGF5ZXInKS5jc3MoXCJoZWlnaHRcIiwgYWx0dXJhKS5jc3MoXCJ3aWR0aFwiLCBydyk7XG4gICQodGhpcykuZmluZCgnLm1lanNfX2NvbnRhaW5lcicpLmNzcyhcImhlaWdodFwiLCBhbHR1cmEpLmNzcyhcIndpZHRoXCIsIHJ3KTtcbiAgbW9kYWxvLmNzcyhcIndpZHRoXCIsIHJ3KS5jc3MoXCJoZWlnaHRcIiwgYWx0dXJhKTtcbiAgLy9tb2RhbG1vZGFsLmNzcygnbWFyZ2luLXRvcCcsICgoJCh3aW5kb3cpLmhlaWdodCgpIC0gKHBhcnNlSW50KG1vZGFsYy5oZWlnaHQoKSApKSkvMikpO1xufSk7XG4kKCdpZnJhbWUtb2ZmJykuZWFjaChmdW5jdGlvbigpe1xuICBmdW5jdGlvbiBpbmplY3RDU1MoKXtcbiAgICAkaWZyYW1lLmNvbnRlbnRzKCkuZmluZCgnaGVhZCcpLmFwcGVuZChcbiAgICAgICQoXCI8c3R5bGUgdHlwZT0ndGV4dC9jc3MnPlwiK1xuICAgICAgICBcIi5wbGF5ZXIgLnZwLWNhcmRzLCAucGxheWVyIC52cC1jb250cm9scyB7IGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDsgfSBcIitcbiAgICAgICAgXCI8L3N0eWxlPlwiKVxuICAgICk7XG4gIH1cbiAgdmFyICRpZnJhbWUgPSAkKHRoaXMpO1xuICAkaWZyYW1lLm9uKCdsb2FkJywgaW5qZWN0Q1NTKTtcbiAgaW5qZWN0Q1NTKCk7XG59KTtcblxuZnVuY3Rpb24gZWxpbWluYXJJRChlbGVtZW50SWQpIHtcbiAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtZW50SWQpO1xuICBlbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWxlbWVudCk7XG59XG5pZihkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImNsb3NlLWZhbGRvblwiKSl7XG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiY2xvc2UtZmFsZG9uXCIpXG4gICAgLmFkZEV2ZW50TGlzdGVuZXIgKFwiY2xpY2tcIiwgZnVuY3Rpb24oKXtcbiAgICAgIGVsaW1pbmFySUQoXCJmYWxkb24tY29udGFpbmVyXCIpXG4gICAgfVxuICApO1xufVxuIiwiLy8ganMvcGhvZW5peC91dGlscy5qc1xudmFyIGNsb3N1cmUgPSAodmFsdWUpID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9IGVsc2Uge1xuICAgIGxldCBjbG9zdXJlMiA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG4gICAgcmV0dXJuIGNsb3N1cmUyO1xuICB9XG59O1xuXG4vLyBqcy9waG9lbml4L2NvbnN0YW50cy5qc1xudmFyIGdsb2JhbFNlbGYgPSB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiBudWxsO1xudmFyIHBoeFdpbmRvdyA9IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiBudWxsO1xudmFyIGdsb2JhbCA9IGdsb2JhbFNlbGYgfHwgcGh4V2luZG93IHx8IGdsb2JhbFRoaXM7XG52YXIgREVGQVVMVF9WU04gPSBcIjIuMC4wXCI7XG52YXIgU09DS0VUX1NUQVRFUyA9IHsgY29ubmVjdGluZzogMCwgb3BlbjogMSwgY2xvc2luZzogMiwgY2xvc2VkOiAzIH07XG52YXIgTUFYX0xPTkdQT0xMX0JBVENIX1NJWkUgPSAxMDA7XG52YXIgREVGQVVMVF9USU1FT1VUID0gMWU0O1xudmFyIFdTX0NMT1NFX05PUk1BTCA9IDFlMztcbnZhciBDSEFOTkVMX1NUQVRFUyA9IHtcbiAgY2xvc2VkOiBcImNsb3NlZFwiLFxuICBlcnJvcmVkOiBcImVycm9yZWRcIixcbiAgam9pbmVkOiBcImpvaW5lZFwiLFxuICBqb2luaW5nOiBcImpvaW5pbmdcIixcbiAgbGVhdmluZzogXCJsZWF2aW5nXCJcbn07XG52YXIgQ0hBTk5FTF9FVkVOVFMgPSB7XG4gIGNsb3NlOiBcInBoeF9jbG9zZVwiLFxuICBlcnJvcjogXCJwaHhfZXJyb3JcIixcbiAgam9pbjogXCJwaHhfam9pblwiLFxuICByZXBseTogXCJwaHhfcmVwbHlcIixcbiAgbGVhdmU6IFwicGh4X2xlYXZlXCJcbn07XG52YXIgVFJBTlNQT1JUUyA9IHtcbiAgbG9uZ3BvbGw6IFwibG9uZ3BvbGxcIixcbiAgd2Vic29ja2V0OiBcIndlYnNvY2tldFwiXG59O1xudmFyIFhIUl9TVEFURVMgPSB7XG4gIGNvbXBsZXRlOiA0XG59O1xudmFyIEFVVEhfVE9LRU5fUFJFRklYID0gXCJiYXNlNjR1cmwuYmVhcmVyLnBoeC5cIjtcblxuLy8ganMvcGhvZW5peC9w
1dXNoLmpzXG52YXIgUHVzaCA9IGNsYXNzIHtcbiAgY29uc3RydWN0b3IoY2hhbm5lbCwgZXZlbnQsIHBheWxvYWQsIHRpbWVvdXQpIHtcbiAgICB0aGlzLmNoYW5uZWwgPSBjaGFubmVsO1xuICAgIHRoaXMuZXZlbnQgPSBldmVudDtcbiAgICB0aGlzLnBheWxvYWQgPSBwYXlsb2FkIHx8IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH07XG4gICAgdGhpcy5yZWNlaXZlZFJlc3AgPSBudWxsO1xuICAgIHRoaXMudGltZW91dCA9IHRpbWVvdXQ7XG4gICAgdGhpcy50aW1lb3V0VGltZXIgPSBudWxsO1xuICAgIHRoaXMucmVjSG9va3MgPSBbXTtcbiAgICB0aGlzLnNlbnQgPSBmYWxzZTtcbiAgfVxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXRcbiAgICovXG4gIHJlc2VuZCh0aW1lb3V0KSB7XG4gICAgdGhpcy50aW1lb3V0ID0gdGltZW91dDtcbiAgICB0aGlzLnJlc2V0KCk7XG4gICAgdGhpcy5zZW5kKCk7XG4gIH1cbiAgLyoqXG4gICAqXG4gICAqL1xuICBzZW5kKCkge1xuICAgIGlmICh0aGlzLmhhc1JlY2VpdmVkKFwidGltZW91dFwiKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnN0YXJ0VGltZW91dCgpO1xuICAgIHRoaXMuc2VudCA9IHRydWU7XG4gICAgdGhpcy5jaGFubmVsLnNvY2tldC5wdXNoKHtcbiAgICAgIHRvcGljOiB0aGlzLmNoYW5uZWwudG9waWMsXG4gICAgICBldmVudDogdGhpcy5ldmVudCxcbiAgICAgIHBheWxvYWQ6IHRoaXMucGF5bG9hZCgpLFxuICAgICAgcmVmOiB0aGlzLnJlZixcbiAgICAgIGpvaW5fcmVmOiB0aGlzLmNoYW5uZWwuam9pblJlZigpXG4gICAgfSk7XG4gIH1cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSB7Kn0gc3RhdHVzXG4gICAqIEBwYXJhbSB7Kn0gY2FsbGJhY2tcbiAgICovXG4gIHJlY2VpdmUoc3RhdHVzLCBjYWxsYmFjaykge1xuICAgIGlmICh0aGlzLmhhc1JlY2VpdmVkKHN0YXR1cykpIHtcbiAgICAgIGNhbGxiYWNrKHRoaXMucmVjZWl2ZWRSZXNwLnJlc3BvbnNlKTtcbiAgICB9XG4gICAgdGhpcy5yZWNIb29rcy5wdXNoKHsgc3RhdHVzLCBjYWxsYmFjayB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHJlc2V0KCkge1xuICAgIHRoaXMuY2FuY2VsUmVmRXZlbnQoKTtcbiAgICB0aGlzLnJlZiA9IG51bGw7XG4gICAgdGhpcy5yZWZFdmVudCA9IG51bGw7XG4gICAgdGhpcy5yZWNlaXZlZFJlc3AgPSBudWxsO1xuICAgIHRoaXMuc2VudCA9IGZhbHNlO1xuICB9XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgbWF0Y2hSZWNlaXZlKHsgc3RhdHVzLCByZXNwb25zZSwgX3JlZiB9KSB7XG4gICAgdGhpcy5yZWNIb29rcy5maWx0ZXIoKGgpID0+IGguc3RhdHVzID09PSBzdGF0dXMpLmZvckVhY2goKGgpID0+IGguY2FsbGJhY2socmVzcG9uc2UpKTtcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGNhbmNlbFJlZkV2ZW50KCkge1xuICAgIGlmICghdGhpcy5yZWZFdmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNoYW5uZWwub2ZmKHRoaXMucmVmRXZlbnQpO1xuICB9XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgY2FuY2VsVGltZW91dCgpIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lb3V0VGltZXIpO1xuICAgIHRoaXMudGltZW91dFRpbWVyID0gbnVsbDtcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHN0YXJ0VGltZW91dCgpIHtcbiAgICBpZiAodGhpcy50aW1lb3V0VGltZXIpIHtcbiAgICAgIHRoaXMuY2FuY2VsVGltZW91dCgpO1xuICAgIH1cbiAgICB0aGlzLnJlZiA9IHRoaXMuY2hhbm5lbC5zb2NrZXQubWFrZVJlZigpO1xuICAgIHRoaXMucmVmRXZlbnQgPSB0aGlzLmNoYW5uZWwucmVwbHlFdmVudE5hbWUodGhpcy5yZWYpO1xuICAgIHRoaXMuY2hhbm5lbC5vbih0aGlzLnJlZkV2ZW50LCAocGF5bG9hZCkgPT4ge1xuICAgICAgdGhpcy5jYW5jZWxSZWZFdmVudCgpO1xuICAgICAgdGhpcy5jYW5jZWxUaW1lb3V0KCk7XG4gICAgICB0aGlzLnJlY2VpdmVkUmVzcCA9IHBheWxvYWQ7XG4gICAgICB0aGlzLm1hdGNoUmVjZWl2ZShwYXlsb2FkKTtcbiAgICB9KTtcbiAgICB0aGlzLnRpbWVvdXRUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy50cmlnZ2VyKFwidGltZW91dFwiLCB7fSk7XG4gICAgfSwgdGhpcy50aW1lb3V0KTtcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGhhc1JlY2VpdmVkKHN0YXR1cykge1xuICAgIHJldHVybiB0aGlzLnJlY2VpdmVkUmVzcCAmJiB0aGlzLnJlY2VpdmVkUmVzcC5zdGF0dXMgPT09IHN0YXR1cztcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHRyaWdnZXIoc3RhdHVzLCByZXNwb25zZSkge1xuICAgIHRoaXMuY2hhbm5lbC50cmlnZ2VyKHRoaXMucmVmRXZlbnQsIHsgc3RhdHVzLCByZXNwb25zZSB9KTtcbiAgfVxufTtcblxuLy8ganMvcGhvZW5peC90aW1lci5qc1xudmFyIFRpbWVyID0gY2xhc3Mge1xuICBjb25zdHJ1Y3RvcihjYWxsYmFjaywgdGltZXJDYWxjKSB7XG4gICAgdGhpcy5jYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHRoaXMudGltZXJDYWxjID0gdGltZXJDYWxjO1xuICAgIHRoaXMudGltZXIgPSBudWxsO1xuICAgIHRoaXMudHJpZXMgPSAwO1xuICB9XG4gIHJlc2V0KCkge1xuICAgIHRoaXMudHJpZXMgPSAwO1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVyKTtcbiAgfVxuICAvKipcbiAgICogQ2FuY2VscyBhbnkgcHJldmlvdXMgc2NoZWR1bGVUaW1lb3V0IGFuZCBzY2hlZHVsZXMgY2FsbGJhY2tcbiAgICovXG4gIHNjaGVkdWxlVGltZW91dCgpIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lcik7XG4gICAgdGhpcy50aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy50cmllcyA9IHRoaXMudHJpZXMgKyAxO1xuICAgICAgdGhpcy5jYWxsYmFjaygpO1xuICAgIH0sIHRoaXMudGltZXJDYWxjKHRoaXMudHJpZXMgKyAxKSk7XG4gIH1cbn07XG5cbi8vIGpzL3Bob2VuaXgvY2hhbm5lbC5qc1xudmFyIENoYW5uZWwgPSBjbGFzcyB7XG4gIGNvbnN0cnVjdG9yKHRvcGljLCBwYXJhbXMsIHNvY2tldCkge1xuICAgIHRoaXMuc3RhdGUgPSBDSEFOTkVMX1NUQVRFUy5jbG9zZWQ7XG4gICAgdGhpcy50b3BpYyA9IHRvcGljO1xuICAgIHRoaXMucGFyYW1zID0gY2xvc3VyZShwYXJhbXMgfHwge30pO1xuICAgIHRoaXMuc29ja2V0ID0gc29ja2V0O1xuICAgIHRoaXMuYmluZGluZ3MgPSBbXTtcbiAgICB0aGlzLmJpbmRpbmdSZWYgPSAwO1xuICAgIHRoaXMudGltZW91dCA9IHRoaXMuc29ja2V0LnRpbWVvdXQ7XG4gICAgdGhpcy5qb2luZWRPbmNlID0gZmFsc2U7XG4gICAgdGhpcy5qb2luUHVzaCA9IG5ldyBQdXNoKHRoaXMsIENIQU5ORUxfRVZFTlRTLmpvaW4sIHRoaXMucGFyYW1zLCB0aGlzLnRpbWVvdXQpO1xuICAgIHRoaXMucHVzaEJ1ZmZlciA9IFtdO1xuICAgIHRoaXMuc3RhdGVDaGFuZ2VSZWZzID0gW107XG4gICAgdGhpcy5yZWpvaW5UaW1lciA9IG5ldyBUaW1lcigoKSA9PiB7XG4gICAgICBpZiAodGhpcy5zb2NrZXQuaXNDb25uZWN0ZWQoKSkge1xuICAgICAgICB0aGlzLnJlam9pbigpO1xuICAgICAgfVxuICAgIH0sIHRoaXMuc29ja2V0LnJlam9pbkFmdGVyTXMpO1xuICAgIHRoaXMuc3RhdGVDaGFuZ2VSZWZzLnB1c2godGhpcy5zb2NrZXQub25FcnJvcigoKSA9PiB0aGlzLnJlam9pblRpbWVyLnJlc2V0KCkpKTtcbiAgICB0aGlzLnN0YXRlQ2hhbmdlUmVmcy5wdXNoKFxuICAgICAgdGhpcy5zb2NrZXQub25PcGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5yZWpvaW5UaW1lci5yZXNldCgpO1xuICAgICAgICBpZiAodGhpcy5pc0Vycm9yZWQoKSkge1xuICAgICAgICAgI
1HRoaXMucmVqb2luKCk7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKTtcbiAgICB0aGlzLmpvaW5QdXNoLnJlY2VpdmUoXCJva1wiLCAoKSA9PiB7XG4gICAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMuam9pbmVkO1xuICAgICAgdGhpcy5yZWpvaW5UaW1lci5yZXNldCgpO1xuICAgICAgdGhpcy5wdXNoQnVmZmVyLmZvckVhY2goKHB1c2hFdmVudCkgPT4gcHVzaEV2ZW50LnNlbmQoKSk7XG4gICAgICB0aGlzLnB1c2hCdWZmZXIgPSBbXTtcbiAgICB9KTtcbiAgICB0aGlzLmpvaW5QdXNoLnJlY2VpdmUoXCJlcnJvclwiLCAoKSA9PiB7XG4gICAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMuZXJyb3JlZDtcbiAgICAgIGlmICh0aGlzLnNvY2tldC5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICAgIHRoaXMucmVqb2luVGltZXIuc2NoZWR1bGVUaW1lb3V0KCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5vbkNsb3NlKCgpID0+IHtcbiAgICAgIHRoaXMucmVqb2luVGltZXIucmVzZXQoKTtcbiAgICAgIGlmICh0aGlzLnNvY2tldC5oYXNMb2dnZXIoKSkgdGhpcy5zb2NrZXQubG9nKFwiY2hhbm5lbFwiLCBgY2xvc2UgJHt0aGlzLnRvcGljfSAke3RoaXMuam9pblJlZigpfWApO1xuICAgICAgdGhpcy5zdGF0ZSA9IENIQU5ORUxfU1RBVEVTLmNsb3NlZDtcbiAgICAgIHRoaXMuc29ja2V0LnJlbW92ZSh0aGlzKTtcbiAgICB9KTtcbiAgICB0aGlzLm9uRXJyb3IoKHJlYXNvbikgPT4ge1xuICAgICAgaWYgKHRoaXMuc29ja2V0Lmhhc0xvZ2dlcigpKSB0aGlzLnNvY2tldC5sb2coXCJjaGFubmVsXCIsIGBlcnJvciAke3RoaXMudG9waWN9YCwgcmVhc29uKTtcbiAgICAgIGlmICh0aGlzLmlzSm9pbmluZygpKSB7XG4gICAgICAgIHRoaXMuam9pblB1c2gucmVzZXQoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc3RhdGUgPSBDSEFOTkVMX1NUQVRFUy5lcnJvcmVkO1xuICAgICAgaWYgKHRoaXMuc29ja2V0LmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgdGhpcy5yZWpvaW5UaW1lci5zY2hlZHVsZVRpbWVvdXQoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLmpvaW5QdXNoLnJlY2VpdmUoXCJ0aW1lb3V0XCIsICgpID0+IHtcbiAgICAgIGlmICh0aGlzLnNvY2tldC5oYXNMb2dnZXIoKSkgdGhpcy5zb2NrZXQubG9nKFwiY2hhbm5lbFwiLCBgdGltZW91dCAke3RoaXMudG9waWN9ICgke3RoaXMuam9pblJlZigpfSlgLCB0aGlzLmpvaW5QdXNoLnRpbWVvdXQpO1xuICAgICAgbGV0IGxlYXZlUHVzaCA9IG5ldyBQdXNoKHRoaXMsIENIQU5ORUxfRVZFTlRTLmxlYXZlLCBjbG9zdXJlKHt9KSwgdGhpcy50aW1lb3V0KTtcbiAgICAgIGxlYXZlUHVzaC5zZW5kKCk7XG4gICAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMuZXJyb3JlZDtcbiAgICAgIHRoaXMuam9pblB1c2gucmVzZXQoKTtcbiAgICAgIGlmICh0aGlzLnNvY2tldC5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICAgIHRoaXMucmVqb2luVGltZXIuc2NoZWR1bGVUaW1lb3V0KCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5vbihDSEFOTkVMX0VWRU5UUy5yZXBseSwgKHBheWxvYWQsIHJlZikgPT4ge1xuICAgICAgdGhpcy50cmlnZ2VyKHRoaXMucmVwbHlFdmVudE5hbWUocmVmKSwgcGF5bG9hZCk7XG4gICAgfSk7XG4gIH1cbiAgLyoqXG4gICAqIEpvaW4gdGhlIGNoYW5uZWxcbiAgICogQHBhcmFtIHtpbnRlZ2VyfSB0aW1lb3V0XG4gICAqIEByZXR1cm5zIHtQdXNofVxuICAgKi9cbiAgam9pbih0aW1lb3V0ID0gdGhpcy50aW1lb3V0KSB7XG4gICAgaWYgKHRoaXMuam9pbmVkT25jZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwidHJpZWQgdG8gam9pbiBtdWx0aXBsZSB0aW1lcy4gJ2pvaW4nIGNhbiBvbmx5IGJlIGNhbGxlZCBhIHNpbmdsZSB0aW1lIHBlciBjaGFubmVsIGluc3RhbmNlXCIpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRpbWVvdXQgPSB0aW1lb3V0O1xuICAgICAgdGhpcy5qb2luZWRPbmNlID0gdHJ1ZTtcbiAgICAgIHRoaXMucmVqb2luKCk7XG4gICAgICByZXR1cm4gdGhpcy5qb2luUHVzaDtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIEhvb2sgaW50byBjaGFubmVsIGNsb3NlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBvbkNsb3NlKGNhbGxiYWNrKSB7XG4gICAgdGhpcy5vbihDSEFOTkVMX0VWRU5UUy5jbG9zZSwgY2FsbGJhY2spO1xuICB9XG4gIC8qKlxuICAgKiBIb29rIGludG8gY2hhbm5lbCBlcnJvcnNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIG9uRXJyb3IoY2FsbGJhY2spIHtcbiAgICByZXR1cm4gdGhpcy5vbihDSEFOTkVMX0VWRU5UUy5lcnJvciwgKHJlYXNvbikgPT4gY2FsbGJhY2socmVhc29uKSk7XG4gIH1cbiAgLyoqXG4gICAqIFN1YnNjcmliZXMgb24gY2hhbm5lbCBldmVudHNcbiAgICpcbiAgICogU3Vic2NyaXB0aW9uIHJldHVybnMgYSByZWYgY291bnRlciwgd2hpY2ggY2FuIGJlIHVzZWQgbGF0ZXIgdG9cbiAgICogdW5zdWJzY3JpYmUgdGhlIGV4YWN0IGV2ZW50IGxpc3RlbmVyXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGNvbnN0IHJlZjEgPSBjaGFubmVsLm9uKFwiZXZlbnRcIiwgZG9fc3R1ZmYpXG4gICAqIGNvbnN0IHJlZjIgPSBjaGFubmVsLm9uKFwiZXZlbnRcIiwgZG9fb3RoZXJfc3R1ZmYpXG4gICAqIGNoYW5uZWwub2ZmKFwiZXZlbnRcIiwgcmVmMSlcbiAgICogLy8gU2luY2UgdW5zdWJzY3JpcHRpb24sIGRvX3N0dWZmIHdvbid0IGZpcmUsXG4gICAqIC8vIHdoaWxlIGRvX290aGVyX3N0dWZmIHdpbGwga2VlcCBmaXJpbmcgb24gdGhlIFwiZXZlbnRcIlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICogQHJldHVybnMge2ludGVnZXJ9IHJlZlxuICAgKi9cbiAgb24oZXZlbnQsIGNhbGxiYWNrKSB7XG4gICAgbGV0IHJlZiA9IHRoaXMuYmluZGluZ1JlZisrO1xuICAgIHRoaXMuYmluZGluZ3MucHVzaCh7IGV2ZW50LCByZWYsIGNhbGxiYWNrIH0pO1xuICAgIHJldHVybiByZWY7XG4gIH1cbiAgLyoqXG4gICAqIFVuc3Vic2NyaWJlcyBvZmYgb2YgY2hhbm5lbCBldmVudHNcbiAgICpcbiAgICogVXNlIHRoZSByZWYgcmV0dXJuZWQgZnJvbSBhIGNoYW5uZWwub24oKSB0byB1bnN1YnNjcmliZSBvbmVcbiAgICogaGFuZGxlciwgb3IgcGFzcyBub3RoaW5nIGZvciB0aGUgcmVmIHRvIHVuc3Vic2NyaWJlIGFsbFxuICAgKiBoYW5kbGVycyBmb3IgdGhlIGdpdmVuIGV2ZW50LlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiAvLyBVbnN1YnNjcmliZSB0aGUgZG9fc3R1ZmYgaGFuZGxlclxuICAgKiBjb25zdCByZWYxID0gY2hhbm5lbC5vbihcImV2ZW50XCIsIGRvX3N0dWZmKVxuICAgKiBjaGFubmVsLm9mZihcImV2ZW50XCIsIHJlZjEpXG4gICAqXG4gICAqIC8vIFVuc3Vic2NyaWJlIGFsbCBoYW5kbGVycyBmcm9tIGV2ZW50XG4gICAqIGNoYW5uZWwub2ZmKFwiZXZlbnRcIilcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG4gICAqIEBwYXJhbSB7aW50ZWdlcn0gcmVmXG4gICAqL1xuICBvZmYoZXZlbnQsIHJlZikge1xuICAgIHRoaXMuYmluZGluZ3MgPSB0aGlzLmJpbmRpbmdzLmZpbHRlcigoYmluZCkgPT4ge1xuICAgICAgcmV0dXJuICEoYmluZC5ldmVudCA9PT0gZXZlbnQgJiYgKHR5cGVvZiByZWYgPT09IFwidW5kZWZpbmVkXCIgfHwgcmVmID09PSBiaW5kLnJlZikpO1xuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgY2FuUHVzaCgpIHtcbiAgICByZXR1cm4gdGhpcy5zb2NrZXQuaXNDb25uZWN0ZWQoKSAmJiB0aGlzLmlzSm9pbmVkKCk7XG4gIH1cbiAgLyoqXG4gICAqIFNlbmRzIGEgbWVzc2FnZSBgZXZlbnRgIHRvIHBob2VuaXggd2l0aCB0aGUgcGF5bG9hZCBgcGF5bG9hZGAuXG4gICAqIFBob2VuaXggcmVjZWl2ZXMgdGhpcyBpbiB0aGUgYGhhbmRsZV9pbihldmVudCwgcGF5bG9hZCwgc29ja2V0KWBcbiAgICogZnVuY3Rpb24uIGlmIHBob2VuaXggcmVwbGllcyBvciBpdCB0aW1lcyBvdXQgKGRlZmF1bHQgMTAwMDBtcyksXG4gICAqIHRoZW4gb3B0aW9uYWxseSB0aGUgcmVwbHkgY2FuIGJlIHJlY2VpdmVkLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBjaGFubmVsLnB1c2goXCJldmVudFwiKVxuICAgKiAgIC5yZWNlaXZlKFwib2tcIiwgcGF5bG9hZCA9PiBjb25zb2xlLmxvZyhcInBob2VuaXggcmVwbGllZDpcIiwgcGF5bG9hZCkpXG4gICAqICAg
1LnJlY2VpdmUoXCJlcnJvclwiLCBlcnIgPT4gY29uc29sZS5sb2coXCJwaG9lbml4IGVycm9yZWRcIiwgZXJyKSlcbiAgICogICAucmVjZWl2ZShcInRpbWVvdXRcIiwgKCkgPT4gY29uc29sZS5sb2coXCJ0aW1lZCBvdXQgcHVzaGluZ1wiKSlcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwYXlsb2FkXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbdGltZW91dF1cbiAgICogQHJldHVybnMge1B1c2h9XG4gICAqL1xuICBwdXNoKGV2ZW50LCBwYXlsb2FkLCB0aW1lb3V0ID0gdGhpcy50aW1lb3V0KSB7XG4gICAgcGF5bG9hZCA9IHBheWxvYWQgfHwge307XG4gICAgaWYgKCF0aGlzLmpvaW5lZE9uY2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdHJpZWQgdG8gcHVzaCAnJHtldmVudH0nIHRvICcke3RoaXMudG9waWN9JyBiZWZvcmUgam9pbmluZy4gVXNlIGNoYW5uZWwuam9pbigpIGJlZm9yZSBwdXNoaW5nIGV2ZW50c2ApO1xuICAgIH1cbiAgICBsZXQgcHVzaEV2ZW50ID0gbmV3IFB1c2godGhpcywgZXZlbnQsIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfSwgdGltZW91dCk7XG4gICAgaWYgKHRoaXMuY2FuUHVzaCgpKSB7XG4gICAgICBwdXNoRXZlbnQuc2VuZCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwdXNoRXZlbnQuc3RhcnRUaW1lb3V0KCk7XG4gICAgICB0aGlzLnB1c2hCdWZmZXIucHVzaChwdXNoRXZlbnQpO1xuICAgIH1cbiAgICByZXR1cm4gcHVzaEV2ZW50O1xuICB9XG4gIC8qKiBMZWF2ZXMgdGhlIGNoYW5uZWxcbiAgICpcbiAgICogVW5zdWJzY3JpYmVzIGZyb20gc2VydmVyIGV2ZW50cywgYW5kXG4gICAqIGluc3RydWN0cyBjaGFubmVsIHRvIHRlcm1pbmF0ZSBvbiBzZXJ2ZXJcbiAgICpcbiAgICogVHJpZ2dlcnMgb25DbG9zZSgpIGhvb2tzXG4gICAqXG4gICAqIFRvIHJlY2VpdmUgbGVhdmUgYWNrbm93bGVkZ2VtZW50cywgdXNlIHRoZSBgcmVjZWl2ZWBcbiAgICogaG9vayB0byBiaW5kIHRvIHRoZSBzZXJ2ZXIgYWNrLCBpZTpcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogY2hhbm5lbC5sZWF2ZSgpLnJlY2VpdmUoXCJva1wiLCAoKSA9PiBhbGVydChcImxlZnQhXCIpIClcbiAgICpcbiAgICogQHBhcmFtIHtpbnRlZ2VyfSB0aW1lb3V0XG4gICAqIEByZXR1cm5zIHtQdXNofVxuICAgKi9cbiAgbGVhdmUodGltZW91dCA9IHRoaXMudGltZW91dCkge1xuICAgIHRoaXMucmVqb2luVGltZXIucmVzZXQoKTtcbiAgICB0aGlzLmpvaW5QdXNoLmNhbmNlbFRpbWVvdXQoKTtcbiAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMubGVhdmluZztcbiAgICBsZXQgb25DbG9zZSA9ICgpID0+IHtcbiAgICAgIGlmICh0aGlzLnNvY2tldC5oYXNMb2dnZXIoKSkgdGhpcy5zb2NrZXQubG9nKFwiY2hhbm5lbFwiLCBgbGVhdmUgJHt0aGlzLnRvcGljfWApO1xuICAgICAgdGhpcy50cmlnZ2VyKENIQU5ORUxfRVZFTlRTLmNsb3NlLCBcImxlYXZlXCIpO1xuICAgIH07XG4gICAgbGV0IGxlYXZlUHVzaCA9IG5ldyBQdXNoKHRoaXMsIENIQU5ORUxfRVZFTlRTLmxlYXZlLCBjbG9zdXJlKHt9KSwgdGltZW91dCk7XG4gICAgbGVhdmVQdXNoLnJlY2VpdmUoXCJva1wiLCAoKSA9PiBvbkNsb3NlKCkpLnJlY2VpdmUoXCJ0aW1lb3V0XCIsICgpID0+IG9uQ2xvc2UoKSk7XG4gICAgbGVhdmVQdXNoLnNlbmQoKTtcbiAgICBpZiAoIXRoaXMuY2FuUHVzaCgpKSB7XG4gICAgICBsZWF2ZVB1c2gudHJpZ2dlcihcIm9rXCIsIHt9KTtcbiAgICB9XG4gICAgcmV0dXJuIGxlYXZlUHVzaDtcbiAgfVxuICAvKipcbiAgICogT3ZlcnJpZGFibGUgbWVzc2FnZSBob29rXG4gICAqXG4gICAqIFJlY2VpdmVzIGFsbCBldmVudHMgZm9yIHNwZWNpYWxpemVkIG1lc3NhZ2UgaGFuZGxpbmdcbiAgICogYmVmb3JlIGRpc3BhdGNoaW5nIHRvIHRoZSBjaGFubmVsIGNhbGxiYWNrcy5cbiAgICpcbiAgICogTXVzdCByZXR1cm4gdGhlIHBheWxvYWQsIG1vZGlmaWVkIG9yIHVubW9kaWZpZWRcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwYXlsb2FkXG4gICAqIEBwYXJhbSB7aW50ZWdlcn0gcmVmXG4gICAqIEByZXR1cm5zIHtPYmplY3R9XG4gICAqL1xuICBvbk1lc3NhZ2UoX2V2ZW50LCBwYXlsb2FkLCBfcmVmKSB7XG4gICAgcmV0dXJuIHBheWxvYWQ7XG4gIH1cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBpc01lbWJlcih0b3BpYywgZXZlbnQsIHBheWxvYWQsIGpvaW5SZWYpIHtcbiAgICBpZiAodGhpcy50b3BpYyAhPT0gdG9waWMpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKGpvaW5SZWYgJiYgam9pblJlZiAhPT0gdGhpcy5qb2luUmVmKCkpIHtcbiAgICAgIGlmICh0aGlzLnNvY2tldC5oYXNMb2dnZXIoKSkgdGhpcy5zb2NrZXQubG9nKFwiY2hhbm5lbFwiLCBcImRyb3BwaW5nIG91dGRhdGVkIG1lc3NhZ2VcIiwgeyB0b3BpYywgZXZlbnQsIHBheWxvYWQsIGpvaW5SZWYgfSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGpvaW5SZWYoKSB7XG4gICAgcmV0dXJuIHRoaXMuam9pblB1c2gucmVmO1xuICB9XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcmVqb2luKHRpbWVvdXQgPSB0aGlzLnRpbWVvdXQpIHtcbiAgICBpZiAodGhpcy5pc0xlYXZpbmcoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnNvY2tldC5sZWF2ZU9wZW5Ub3BpYyh0aGlzLnRvcGljKTtcbiAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMuam9pbmluZztcbiAgICB0aGlzLmpvaW5QdXNoLnJlc2VuZCh0aW1lb3V0KTtcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHRyaWdnZXIoZXZlbnQsIHBheWxvYWQsIHJlZiwgam9pblJlZikge1xuICAgIGxldCBoYW5kbGVkUGF5bG9hZCA9IHRoaXMub25NZXNzYWdlKGV2ZW50LCBwYXlsb2FkLCByZWYsIGpvaW5SZWYpO1xuICAgIGlmIChwYXlsb2FkICYmICFoYW5kbGVkUGF5bG9hZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2hhbm5lbCBvbk1lc3NhZ2UgY2FsbGJhY2tzIG11c3QgcmV0dXJuIHRoZSBwYXlsb2FkLCBtb2RpZmllZCBvciB1bm1vZGlmaWVkXCIpO1xuICAgIH1cbiAgICBsZXQgZXZlbnRCaW5kaW5ncyA9IHRoaXMuYmluZGluZ3MuZmlsdGVyKChiaW5kKSA9PiBiaW5kLmV2ZW50ID09PSBldmVudCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBldmVudEJpbmRpbmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQgYmluZCA9IGV2ZW50QmluZGluZ3NbaV07XG4gICAgICBiaW5kLmNhbGxiYWNrKGhhbmRsZWRQYXlsb2FkLCByZWYsIGpvaW5SZWYgfHwgdGhpcy5qb2luUmVmKCkpO1xuICAgIH1cbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHJlcGx5RXZlbnROYW1lKHJlZikge1xuICAgIHJldHVybi
1BgY2hhbl9yZXBseV8ke3JlZn1gO1xuICB9XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgaXNDbG9zZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUgPT09IENIQU5ORUxfU1RBVEVTLmNsb3NlZDtcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGlzRXJyb3JlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZSA9PT0gQ0hBTk5FTF9TVEFURVMuZXJyb3JlZDtcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGlzSm9pbmVkKCkge1xuICAgIHJldHVybiB0aGlzLnN0YXRlID09PSBDSEFOTkVMX1NUQVRFUy5qb2luZWQ7XG4gIH1cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBpc0pvaW5pbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUgPT09IENIQU5ORUxfU1RBVEVTLmpvaW5pbmc7XG4gIH1cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBpc0xlYXZpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUgPT09IENIQU5ORUxfU1RBVEVTLmxlYXZpbmc7XG4gIH1cbn07XG5cbi8vIGpzL3Bob2VuaXgvYWpheC5qc1xudmFyIEFqYXggPSBjbGFzcyB7XG4gIHN0YXRpYyByZXF1ZXN0KG1ldGhvZCwgZW5kUG9pbnQsIGhlYWRlcnMsIGJvZHksIHRpbWVvdXQsIG9udGltZW91dCwgY2FsbGJhY2spIHtcbiAgICBpZiAoZ2xvYmFsLlhEb21haW5SZXF1ZXN0KSB7XG4gICAgICBsZXQgcmVxID0gbmV3IGdsb2JhbC5YRG9tYWluUmVxdWVzdCgpO1xuICAgICAgcmV0dXJuIHRoaXMueGRvbWFpblJlcXVlc3QocmVxLCBtZXRob2QsIGVuZFBvaW50LCBib2R5LCB0aW1lb3V0LCBvbnRpbWVvdXQsIGNhbGxiYWNrKTtcbiAgICB9IGVsc2UgaWYgKGdsb2JhbC5YTUxIdHRwUmVxdWVzdCkge1xuICAgICAgbGV0IHJlcSA9IG5ldyBnbG9iYWwuWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgIHJldHVybiB0aGlzLnhoclJlcXVlc3QocmVxLCBtZXRob2QsIGVuZFBvaW50LCBoZWFkZXJzLCBib2R5LCB0aW1lb3V0LCBvbnRpbWVvdXQsIGNhbGxiYWNrKTtcbiAgICB9IGVsc2UgaWYgKGdsb2JhbC5mZXRjaCAmJiBnbG9iYWwuQWJvcnRDb250cm9sbGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5mZXRjaFJlcXVlc3QobWV0aG9kLCBlbmRQb2ludCwgaGVhZGVycywgYm9keSwgdGltZW91dCwgb250aW1lb3V0LCBjYWxsYmFjayk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIHN1aXRhYmxlIFhNTEh0dHBSZXF1
1ZXN0IGltcGxlbWVudGF0aW9uIGZvdW5kXCIpO1xuICAgIH1cbiAgfVxuICBzdGF0aWMgZmV0Y2hSZXF1ZXN0KG1ldGhvZCwgZW5kUG9pbnQsIGhlYWRlcnMsIGJvZHksIHRpbWVvdXQsIG9udGltZW91dCwgY2FsbGJhY2spIHtcbiAgICBsZXQgb3B0aW9ucyA9IHtcbiAgICAgIG1ldGhvZCxcbiAgICAgIGhlYWRlcnMsXG4gICAgICBib2R5XG4gICAgfTtcbiAgICBsZXQgY29udHJvbGxlciA9IG51bGw7XG4gICAgaWYgKHRpbWVvdXQpIHtcbiAgICAgIGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgICBjb25zdCBfdGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiBjb250cm9sbGVyLmFib3J0KCksIHRpbWVvdXQpO1xuICAgICAgb3B0aW9ucy5zaWduYWwgPSBjb250cm9sbGVyLnNpZ25hbDtcbiAgICB9XG4gICAgZ2xvYmFsLmZldGNoKGVuZFBvaW50LCBvcHRpb25zKS50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UudGV4dCgpKS50aGVuKChkYXRhKSA9PiB0aGlzLnBhcnNlSlNPTihkYXRhKSkudGhlbigoZGF0YSkgPT4gY2FsbGJhY2sgJiYgY2FsbGJhY2soZGF0YSkpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgIGlmIChlcnIubmFtZSA9PT0gXCJBYm9ydEVycm9yXCIgJiYgb250aW1lb3V0KSB7XG4gICAgICAgIG9udGltZW91dCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2sobnVsbCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGNvbnRyb2xsZXI7XG4gIH1cbiAgc3RhdGljIHhkb21haW5SZXF1ZXN0KHJlcSwgbWV0aG9kLCBlbmRQb2ludCwgYm9keSwgdGltZW91dCwgb250aW1lb3V0LCBjYWxsYmFjaykge1xuICAgIHJlcS50aW1lb3V0ID0gdGltZW91dDtcbiAgICByZXEub3BlbihtZXRob2QsIGVuZFBvaW50KTtcbiAgICByZXEub25sb2FkID0gKCkgPT4ge1xuICAgICAgbGV0IHJlc3BvbnNlID0gdGhpcy5wYXJzZUpTT04ocmVxLnJlc3BvbnNlVGV4dCk7XG4gICAgICBjYWxsYmFjayAmJiBjYWxsYmFjayhyZXNwb25zZSk7XG4gICAgfTtcbiAgICBpZiAob250aW1lb3V0KSB7XG4gICAgICByZXEub250aW1lb3V0ID0gb250aW1lb3V0O1xuICAgIH1cbiAgICByZXEub25wcm9ncmVzcyA9ICgpID0+IHtcbiAgICB9O1xuICAgIHJlcS5zZW5kKGJvZHkpO1xuICAgIHJldHVybiByZXE7XG4gIH1cbiAgc3RhdGljIHhoclJlcXVlc3QocmVxLCBtZXRob2QsIGVuZFBvaW50LCBoZWFkZXJzLCBib2R5LCB0aW1lb3V0LCBvbnRpbWVvdXQsIGNhbGxiYWNrKSB7XG4gICAgcmVxLm9wZW4obWV0aG9kLCBlbmRQb2ludCwgdHJ1ZSk7XG4gICAgcmVxLnRpbWVvdXQgPSB0aW1lb3V0O1xuICAgIGZvciAobGV0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhoZWFkZXJzKSkge1xuICAgICAgcmVxLnNldFJlcXVlc3RIZWFkZXIoa2V5LCB2YWx1ZSk7XG4gICAgfVxuICAgIHJlcS5vbmVycm9yID0gKCkgPT4gY2FsbGJhY2sgJiYgY2FsbGJhY2sobnVsbCk7XG4gICAgcmVxLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgIGlmIChyZXEucmVhZHlTdGF0ZSA9PT0gWEhSX1NUQVRFUy5jb21wbGV0ZSAmJiBjYWxsYmFjaykge1xuICAgICAgICBsZXQgcmVzcG9uc2UgPSB0aGlzLnBhcnNlSlNPTihyZXEucmVzcG9uc2VUZXh0KTtcbiAgICAgICAgY2FsbGJhY2socmVzcG9uc2UpO1xuICAgICAgfVxuICAgIH07XG4gICAgaWYgKG9udGltZW91dCkge1xuICAgICAgcmVxLm9udGltZW91dCA9IG9udGltZW91dDtcbiAgICB9XG4gICAgcmVxLnNlbmQoYm9keSk7XG4gICAgcmV0dXJuIHJlcTtcbiAgfVxuICBzdGF0aWMgcGFyc2VKU09OKHJlc3ApIHtcbiAgICBpZiAoIXJlc3AgfHwgcmVzcCA9PT0gXCJcIikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICByZXR1cm4gSlNPTi5wYXJzZShyZXNwKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIGNvbnNvbGUgJiYgY29uc29sZS5sb2coXCJmYWlsZWQgdG8gcGFyc2UgSlNPTiByZXNwb25zZVwiLCByZXNwKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuICBzdGF0aWMgc2VyaWFsaXplKG9iaiwgcGFyZW50S2V5KSB7XG4gICAgbGV0IHF1ZXJ5U3RyID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgbGV0IHBhcmFtS2V5ID0gcGFyZW50S2V5ID8gYCR7cGFyZW50S2V5fVske2tleX1dYCA6IGtleTtcbiAgICAgIGxldCBwYXJhbVZhbCA9IG9ialtrZXldO1xuICAgICAgaWYgKHR5cGVvZiBwYXJhbVZhbCA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICBxdWVyeVN0ci5wdXNoKHRoaXMuc2VyaWFsaXplKHBhcmFtVmFsLCBwYXJhbUtleSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcXVlcnlTdHIucHVzaChlbmNvZGVVUklDb21wb25lbnQocGFyYW1LZXkpICsgXCI9XCIgKyBlbmNvZGVVUklDb21wb25lbnQocGFyYW1WYWwpKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHF1ZXJ5U3RyLmpvaW4oXCImXCIpO1xuICB9XG4gIHN0YXRpYyBhcHBlbmRQYXJhbXModXJsLCBwYXJhbXMpIHtcbiAgICBpZiAoT2JqZWN0LmtleXMocGFyYW1zKS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB1cmw7XG4gICAgfVxuICAgIGxldCBwcmVmaXggPSB1cmwubWF0Y2goL1xcPy8pID8gXCImXCIgOiBcIj9cIjtcbiAgICByZXR1cm4gYCR7dXJsfSR7cHJlZml4fSR7dGhpcy5zZXJpYWxpemUocGFyYW1zKX1gO1xuICB9XG59O1xuXG4vLyBqcy9waG9lbml4L2xvbmdwb2xsLmpzXG52YXIgYXJyYXlCdWZmZXJUb0Jhc2U2NCA9IChidWZmZXIpID0+IHtcbiAgbGV0IGJpbmFyeSA9IFwiXCI7XG4gIGxldCBieXRlcyA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XG4gIGxldCBsZW4gPSBieXRlcy5ieXRlTGVuZ3RoO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgYmluYXJ5ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0pO1xuICB9XG4gI
1HJldHVybiBidG9hKGJpbmFyeSk7XG59O1xudmFyIExvbmdQb2xsID0gY2xhc3Mge1xuICBjb25zdHJ1Y3RvcihlbmRQb2ludCwgcHJvdG9jb2xzKSB7XG4gICAgaWYgKHByb3RvY29scyAmJiBwcm90b2NvbHMubGVuZ3RoID09PSAyICYmIHByb3RvY29sc1sxXS5zdGFydHNXaXRoKEFVVEhfVE9LRU5fUFJFRklYKSkge1xuICAgICAgdGhpcy5hdXRoVG9rZW4gPSBhdG9iKHByb3RvY29sc1sxXS5zbGljZShBVVRIX1RPS0VOX1BSRUZJWC5sZW5ndGgpKTtcbiAgICB9XG4gICAgdGhpcy5lbmRQb2ludCA9IG51bGw7XG4gICAgdGhpcy50b2tlbiA9IG51bGw7XG4gICAgdGhpcy5za2lwSGVhcnRiZWF0ID0gdHJ1ZTtcbiAgICB0aGlzLnJlcXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpO1xuICAgIHRoaXMuYXdhaXRpbmdCYXRjaEFjayA9IGZhbHNlO1xuICAgIHRoaXMuY3VycmVudEJhdGNoID0gbnVsbDtcbiAgICB0aGlzLmN1cnJlbnRCYXRjaFRpbWVyID0gbnVsbDtcbiAgICB0aGlzLmJhdGNoQnVmZmVyID0gW107XG4gICAgdGhpcy5vbm9wZW4gPSBmdW5jdGlvbigpIHtcbiAgICB9O1xuICAgIHRoaXMub25lcnJvciA9IGZ1bmN0aW9uKCkge1xuICAgIH07XG4gICAgdGhpcy5vbm1lc3NhZ2UgPSBmdW5jdGlvbigpIHtcbiAgICB9O1xuICAgIHRoaXMub25jbG9zZSA9IGZ1bmN0aW9uKCkge1xuICAgIH07XG4gICAgdGhpcy5wb2xsRW5kcG9pbnQgPSB0aGlzLm5vcm1hbGl6ZUVuZHBvaW50KGVuZFBvaW50KTtcbiAgICB0aGlzLnJlYWR5U3RhdGUgPSBTT0NLRVRfU1R
1BVEVTLmNvbm5lY3Rpbmc7XG4gICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnBvbGwoKSwgMCk7XG4gIH1cbiAgbm9ybWFsaXplRW5kcG9pbnQoZW5kUG9pbnQpIHtcbiAgICByZXR1cm4gZW5kUG9pbnQucmVwbGFjZShcIndzOi8vXCIsIFwiaHR0cDovL1wiKS5yZXBsYWNlKFwid3NzOi8vXCIsIFwiaHR0cHM6Ly9cIikucmVwbGFjZShuZXcgUmVnRXhwKFwiKC4qKS9cIiArIFRSQU5TUE9SVFMud2Vic29ja2V0KSwgXCIkMS9cIiArIFRSQU5TUE9SVFMubG9uZ3BvbGwpO1xuICB9XG4gIGVuZHBvaW50VVJMKCkge1xuICAgIHJldHVybiBBamF4LmFwcGVuZFBhcmFtcyh0aGlzLnBvbGxFbmRwb2ludCwgeyB0b2tlbjogdGhpcy50b2tlbiB9KTtcbiAgfVxuICBjbG9zZUFuZFJldHJ5KGNvZGUsIHJlYXNvbiwgd2FzQ2xlYW4pIHtcbiAgICB0aGlzLmNsb3NlKGNvZGUsIHJlYXNvbiwgd2FzQ2xlYW4pO1xuICAgIHRoaXMucmVhZHlTdGF0ZSA9IFNPQ0tFVF9TVEFURVMuY29ubmVjdGluZztcbiAgfVxuICBvbnRpbWVvdXQoKSB7XG4gICAgdGhpcy5vbmVycm9yKFwidGltZW91dFwiKTtcbiAgICB0aGlzLmNsb3NlQW5kUmV0cnkoMTAwNSwgXCJ0aW1lb3V0XCIsIGZhbHNlKTtcbiAgfVxuICBpc0FjdGl2ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5yZWFkeVN0YXRlID09PSBTT0NLRVRfU1RBVEVTLm9wZW4gfHwgdGhpcy5yZWFkeVN0YXRlID09PSBTT0NLRVRfU1RBVEVTLmNvbm5lY3Rpbmc7XG4gIH1cbiAgcG9sbCgpIHtcbiAgICBjb25zdCBoZWFkZXJzID0geyBcIkFjY2VwdFwiOiBcImFwcGxpY2F0aW9uL2pzb25cIiB9O1xuICAgIGlmICh0aGlzLmF1dGhUb2tlbikge1xuICAgICAgaGVhZGVyc1tcIlgtUGhvZW5peC1BdXRoVG9rZW5cIl0gPSB0aGlzLmF1dGhUb2tlbjtcbiAgICB9XG4gICAgdGhpcy5hamF4KFwiR0VUXCIsIGhlYWRlcnMsIG51bGwsICgpID0+IHRoaXMub250aW1lb3V0KCksIChyZXNwKSA9PiB7XG4gICAgICBpZiAocmVzcCkge1xuICAgICAgICB2Y
1XIgeyBzdGF0dXMsIHRva2VuLCBtZXNzYWdlcyB9ID0gcmVzcDtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gNDEwICYmIHRoaXMudG9rZW4gIT09IG51bGwpIHtcbiAgICAgICAgICB0aGlzLm9uZXJyb3IoNDEwKTtcbiAgICAgICAgICB0aGlzLmNsb3NlQW5kUmV0cnkoMzQxMCwgXCJzZXNzaW9uX2dvbmVcIiwgZmFsc2UpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRva2VuID0gdG9rZW47XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0dXMgPSAwO1xuICAgICAgfVxuICAgICAgc3dpdGNoIChzdGF0dXMpIHtcbiAgICAgICAgY2FzZSAyMDA6XG4gICAgICAgICAgbWVzc2FnZXMuZm9yRWFjaCgobXNnKSA9PiB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMub25tZXNzYWdlKHsgZGF0YTogbXNnIH0pLCAwKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB0aGlzLnBvbGwoKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAyMDQ6XG4gICAgICAgICAgdGhpcy5wb2xsKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgNDEwOlxuICAgICAgICAgIHRoaXMucmVhZHlTdGF0ZSA9IFNPQ0tFVF9TVEFURVMub3BlbjtcbiAgICAgICAgICB0aGlzLm9ub3Blbih7fSk7XG4gICAgICAgICAgdGhpcy5wb2xsKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgNDAzOlxuICAgICAgICAgIHRoaXMub25lcnJvcig0MDMpO1xuICAgICAgICAgIHRoaXMuY2xvc2UoMTAwOCwgXCJmb3JiaWRkZW5cIiwgZmFsc2UpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDA6XG4gICAgICAgIGNhc2UgNTAwOlxuICAgICAgICAgIHRoaXMub25lcnJvcig1MDApO1xuICAgICAgICAgIHRoaXMuY2xvc2VBbmRSZXRyeSgxMDExLCBcImludGVybmFsIHNlcnZlciBlcnJvclwiLCA1MDApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5oYW5kbGVkIHBvbGwgc3RhdHVzICR7c3RhdHVzfWApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIC8vIHdlIGNvbGxlY3QgYWxsIHB1c2hlcyB3aXRoaW4gdGhlIGN1cnJlbnQgZXZlbnQgbG9vcCBieVxuICAvLyBzZXRUaW1lb3V0IDAsIHdoaWNoIG9wdGltaXplcyBiYWNrLXRvLWJhY2sgcHJvY2VkdXJhbFxuICAvLyBwdXNoZXMgYWdhaW5zdCBhbiBlbXB0eSBidWZmZXJcbiAgc2VuZChib2R5KSB7XG4gICAgaWYgKHR5cGVvZiBib2R5ICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICBib2R5ID0gYXJyYXlCdWZmZXJUb0Jhc2U2NChib2R5KTtcbiAgICB9XG4gICAgaWYgKHRoaXMuY3VycmVudEJhdGNoKSB7XG4gICAgICB0aGlzLmN1cnJlbnRCYXRjaC5wdXNoKGJvZHkpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5hd2FpdGluZ0JhdGNoQWNrKSB7XG4gICAgICB0aGlzLmJhdGNoQnVmZmVyLnB1c2goYm9keSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3VycmVudEJhdGNoID0gW2JvZHldO1xuICAgICAgdGhpcy5jdXJyZW50QmF0Y2hUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmJhdGNoU2VuZCh0aGlzLmN1cnJlbnRCYXRjaCk7XG4gICAgICAgIHRoaXMuY3VycmVudEJhdGNoID0gbnVsbDtcbiAgICAgIH0sIDApO1xuICAgIH1cbiAgfVxuICBiYXRjaFNlbmQobWVzc2FnZXMsIG9mZnNldCA9IDApIHtcbiAgICB0aGlzLmF3YWl0aW5nQmF0Y2hBY2sgPSB0cnVlO1xuICAgIGNvbnN0IG5leHQgPSBvZmZzZXQgKyBNQVhfTE9OR1BPTExfQkFUQ0hfU0laRTtcbiAgICBjb25zdCBiYXRjaCA9IG1lc3NhZ2VzLnNsaWNlKG9mZnNldCwgbmV4dCk7XG4gICAgdGhpcy5hamF4KFwiUE9TVFwiLCB7IFwiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24veC1uZGpzb25cIiB9LCBiYXRjaC5qb2luKFwiXFxuXCIpLCAoKSA9PiB0aGlzLm9uZXJyb3IoXCJ0aW1lb3V0XCIpLCAocmVzcCkgPT4ge1xuICAgICAgaWYgKCFyZXNwIHx8IHJlc3Auc3RhdHVzICE9PSAyMDApIHtcbiAgICAgICAgdGhpcy5hd2FpdGluZ0JhdGNoQWNrID0gZmFsc2U7XG4gICAgICAgIHRoaXMub25lcnJvcihyZXNwICYmIHJlc3Auc3RhdHVzKTtcbiAgICAgICAgdGhpcy5jbG9zZUFuZFJldHJ5KDEwMTEsIFwiaW50ZXJuYWwgc2VydmVyIGVycm9yXCIsIGZhbHNlKTtcbiAgICAgIH0gZWxzZSBpZiAobmV4dCA8IG1lc3NhZ2VzLmxlbmd0aCkge1xuICAgICAgICB0aGlzLmJhdGNoU2VuZChtZXNzYWdlcywgbmV4dCk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuYmF0Y2hCdWZmZXIubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmJhdGNoU2VuZCh0aGlzLmJhdGNoQnVmZmVyKTtcbiAgICAgICAgdGhpcy5iYXRjaEJ1ZmZlciA9IFtdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5hd2FpdGluZ0JhdGNoQWNrID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgY2xvc2UoY29kZSwgcmVhc29uLCB3YXNDbGVhbikge1xuICAgIGZvciAobGV0IHJlcSBvZiB0aGlzLnJlcXMpIHtcbiAgICAgIHJlcS5hYm9ydCgpO1xuICAgIH1cbiAgICB0aGlzLnJlYWR5U3RhdGUgPSBTT0NLRVRfU1R
1BVEVTLmNsb3NlZDtcbiAgICBsZXQgb3B0cyA9IE9iamVjdC5hc3NpZ24oeyBjb2RlOiAxZTMsIHJlYXNvbjogdm9pZCAwLCB3YXNDbGVhbjogdHJ1ZSB9LCB7IGNvZGUsIHJlYXNvbiwgd2FzQ2xlYW4gfSk7XG4gICAgdGhpcy5iYXRjaEJ1ZmZlciA9IFtdO1xuICAgIGNsZWFyVGltZW91dCh0aGlzLmN1cnJlbnRCYXRjaFRpbWVyKTtcbiAgICB0aGlzLmN1cnJlbnRCYXRjaFRpbWVyID0gbnVsbDtcbiAgICBpZiAodHlwZW9mIENsb3NlRXZlbnQgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgIHRoaXMub25jbG9zZShuZXcgQ2xvc2VFdmVudChcImNsb3NlXCIsIG9wdHMpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vbmNsb3NlKG9wdHMpO1xuICAgIH1cbiAgfVxuICBhamF4KG1ldGhvZCwgaGVhZGVycywgYm9keSwgb25DYWxsZXJUaW1lb3V0LCBjYWxsYmFjaykge1xuICAgIGxldCByZXE7XG4gICAgbGV0IG9udGltZW91dCA9ICgpID0+IHtcbiAgICAgIHRoaXMucmVxcy5kZWxldGUocmVxKTtcbiAgICAgIG9uQ2FsbGVyVGltZW91dCgpO1xuICAgIH07XG4gICAgcmVxID0gQWpheC5yZXF1ZXN0KG1ldGhvZCwgdGhpcy5lbmRwb2ludFVSTCgpLCBoZWFkZXJzLCBib2R5LCB0aGlzLnRpbWVvdXQsIG9udGltZW91dCwgKHJlc3ApID0+IHtcbiAgICAgIHRoaXMucmVxcy5kZWxldGUocmVxKTtcbiAgICAgIGlmICh0aGlzLmlzQWN0aXZlKCkpIHtcbiAgICAgICAgY2FsbGJhY2socmVzcCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5yZXFzLmFkZChyZXEpO1xuICB9XG59O1xuXG4vLyBqcy9waG9lbml4L3ByZXNlbmNlLmpzXG52YXIgUHJlc2VuY2UgPSBjbGFzcyBfUHJlc2VuY2Uge1xuICBjb25zdHJ1Y3RvcihjaGFubmVsLCBvcHRzID0ge30pIHtcbiAgICBsZXQgZXZlbnRzID0gb3B0cy5ldmVudHMgfHwgeyBzdGF0ZTogXCJwcmVzZW5jZV9zdGF0ZVwiLCBkaWZmOiBcInByZXNlbmNlX2RpZmZcIiB9O1xuICAgIHRoaXMuc3RhdGUgPSAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICB0aGlzLnBlbmRpbmdEaWZmcyA9IFtdO1xuICAgIHRoaXMuY2hhbm5lbCA9IGNoYW5uZWw7XG4gICAgdGhpcy5qb2luUmVmID0gbnVsbDtcbiAgICB0aGlzLmNhbGxlciA9IHtcbiAgICAgIG9uSm9pbjogZnVuY3Rpb24oKSB7XG4gICAgICB9LFxuICAgICAgb25MZWF2ZTogZnVuY3Rpb24oKSB7XG4gICAgICB9LFxuICAgICAgb25TeW5jOiBmdW5jdGlvbigpIHtcbiAgICAgIH1cbiAgICB9O1xuICAgIHRoaXMuY2hhbm5lbC5vbihldmVudHMuc3RhdGUsIChuZXdTdGF0ZSkgPT4ge1xuICAgICAgbGV0IHsgb25Kb2luLCBvbkxlYXZlLCBvblN5bmMgfSA9IHRoaXMuY2FsbGVyO1xuICAgICAgdGhpcy5qb2luUmVmID0gdGhpcy5jaGFubmVsLmpvaW5SZWYoKTtcbiAgICAgIHRoaXMuc3RhdGUgPSBfUHJlc2VuY2Uuc3luY1N0YXRlKHRoaXMuc3RhdGUsIG5ld1N0YXRlLCBvbkpvaW4sIG9uTGVhdmUpO1xuICAgICAgdGhpcy5wZW5kaW5nRGlmZnMuZm9yRWFjaCgoZGlmZikgPT4ge1xuICAgICAgICB0aGlzLnN0YXRlID0gX1ByZXNlbmNlLnN5bmNEaWZmKHRoaXMuc3RhdGUsIGRpZmYsIG9uSm9pbiwgb25MZWF2ZSk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMucGVuZGluZ0RpZmZzID0gW107XG4gICAgICBvblN5bmMoKTtcbiAgICB9KTtcbiAgICB0aGlzLmNoYW5uZWwub24oZXZlbnRzLmRpZmYsIChkaWZmKSA9PiB7XG4gICAgICBsZXQgeyBvbkpvaW4sIG9uTGVhdmUsIG9uU3luYyB9ID0gdGhpcy5jYWxsZXI7XG4gICAgICBpZiAodGhpcy5pblBlbmRpbmdTeW5jU3RhdGUoKSkge1xuICAgICAgICB0aGlzLnBlbmRpbmdEaWZmcy5wdXNoKGRpZmYpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IF9QcmVzZW5jZS5zeW5jRGlmZih0aGlzLnN0YXRlLCBkaWZmLCBvbkpvaW4sIG9uTGVhdmUpO1xuICAgICAgICBvblN5bmMoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICBvbkpvaW4oY2FsbGJhY2spIHtcbiAgICB0aGlzLmNhbGxlci5vbkpvaW4gPSBjYWxsYmFjaztcbiAgfVxuICBvbkxlYXZlKGNhbGxiYWNrKSB7XG4gICAgdGhpcy5jYWxsZXIub25MZWF2ZSA9IGNhbGxiYWNrO1xuICB9XG4gIG9uU3luYyhjYWxsYmFjaykge1xuICAgIHRoaXMuY2FsbGVyLm9uU3luYyA9IGNhbGxiYWNrO1xuICB9XG4gIGxpc3QoYnkpIHtcbiAgICByZXR1cm4gX1ByZXNlbmNlLmxpc3QodGhpcy5zdGF0ZSwgYnkpO1xuICB9XG4gIGluUGVuZGluZ1N5bmNTdGF0ZSgpIHtcbiAgICByZXR1cm4gIXRoaXMuam9pblJlZiB8fCB0aGlzLmpvaW5SZWYgIT09IHRoaXMuY2hhbm5lbC5qb2luUmVmKCk7XG4gIH1cbiAgLy8gbG93ZXItbGV2ZWwgcHVibGljIHN0YXRpYyBBUElcbiAgLyoqXG4gICAqIFVzZWQgdG8gc3luYyB0aGUgbGlzdCBvZiBwcmVzZW5jZXMgb24gdGhlIHNlcnZlclxuICAgKiB3aXRoIHRoZSBjbGllbnQncyBzdGF0ZS4gQW4gb3B0aW9uYWwgYG9uSm9pbmAgYW5kIGBvbkxlYXZlYCBjYWxsYmFjayBjYW5cbiAgICogYmUgcHJvdmlkZWQgdG8gcmVhY3QgdG8gY2hhbmdlcyBpbiB0aGUgY2xpZW50J3MgbG9jYWwgcHJlc2VuY2VzIGFjcm9zc1xuICAgKiBkaXNjb25uZWN0cyBhbmQgcmVjb25uZWN0cyB3aXRoIHRoZSBzZXJ2ZXIuXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcmVzZW5jZX1cbiAgICovXG4gIHN0YXRpYyBzeW5jU3RhdGUoY3VycmVudFN0YXRlLCBuZXdTdGF0ZSwgb25Kb2luLCBvbkxlYXZlKSB7XG4gICAgbGV0IHN0YXRlID0gdGhpcy50b051bGxQcm90b09iaih0aGlzLmNsb25lKGN1cnJlbnRTdGF0ZSkpO1xuICAgIG5ld1N0YXRlID0gdGhpcy50b051bGxQcm90b09iaihuZXdTdGF0ZSk7XG4gICAgbGV0IGpvaW5zID0gLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgbGV0IGxlYXZlcyA9IC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMubWFwKHN0YXRlLCAoa2V5LCBwcmVzZW5jZSkgPT4ge1xuICAgICAgaWYgKCFuZXdTdGF0ZVtrZXldKSB7XG4gICAgICAgIGxlYXZlc1trZXldID0gcHJlc2VuY2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5tYXAobmV3U3RhdGUsIChrZXksIG5ld1ByZXNlbmNlKSA9PiB7XG4gICAgICBsZXQgY3VycmVudFByZXNlbmNlID0gc3RhdGVba2V5XTtcbiAgICAgIGlmIChjdXJyZW50UHJlc2VuY2UpIHtcbiAgICAgICAgbGV0IG5ld1JlZnMgPSBuZXdQcmVzZW5jZS5tZXRhcy5tYXAoKG0pID0+IG0ucGh4X3JlZik7XG4gICAgICAgIGxldCBjdXJSZWZzID0gY3VycmVudFByZXNlbmNlLm1ldGFzLm1hcCgobSkgPT4gbS5waHhfcmVmKTtcbiAgICAgICAgbGV0IGpvaW5lZE1ldGFzID0gbmV3UHJlc2VuY2UubWV0YXMuZmlsdGVyKChtKSA9PiBjdXJSZWZzLmluZGV4T2YobS5waHhfcmVmKSA8IDApO1xuICAgICAgICBsZXQgbGVmdE1ldGFzID0gY3VycmVudFByZXNlbmNlLm1ldGFzLmZpbHRlcigobSkgPT4gbmV3
1UmVmcy5pbmRleE9mKG0ucGh4X3JlZikgPCAwKTtcbiAgICAgICAgaWYgKGpvaW5lZE1ldGFzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBqb2luc1trZXldID0gbmV3UHJlc2VuY2U7XG4gICAgICAgICAgam9pbnNba2V5XS5tZXRhcyA9IGpvaW5lZE1ldGFzO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsZWZ0TWV0YXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGxlYXZlc1trZXldID0gdGhpcy5jbG9uZShjdXJyZW50UHJlc2VuY2UpO1xuICAgICAgICAgIGxlYXZlc1trZXldLm1ldGFzID0gbGVmdE1ldGFzO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBqb2luc1trZXldID0gbmV3UHJlc2VuY2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMuc3luY0RpZmYoc3RhdGUsIHsgam9pbnMsIGxlYXZlcyB9LCBvbkpvaW4sIG9uTGVhdmUpO1xuICB9XG4gIC8qKlxuICAgKlxuICAgKiBVc2VkIHRvIHN5bmMgYSBkaWZmIG9mIHByZXNlbmNlIGpvaW4gYW5kIGxlYXZlXG4gICAqIGV2ZW50cyBmcm9tIHRoZSBzZXJ2ZXIsIGFzIHRoZXkgaGFwcGVuLiBMaWtlIGBzeW5jU3RhdGVgLCBgc3luY0RpZmZgXG4gICAqIGFjY2VwdHMgb3B0aW9uYWwgYG9uSm9pbmAgYW5kIGBvbkxlYXZlYCBjYWxsYmFja3MgdG8gcmVhY3QgdG8gYSB1c2VyXG4gICAqIGpvaW5pbmcgb3IgbGVhdmluZyBmcm9tIGEgZGV2aWNlLlxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJlc2VuY2V9XG4gICAqL1xuICBzdGF0aWMgc3luY0RpZmYoc3RhdGUsIGRpZmYsIG9uSm9pbiwgb25MZWF2ZSkge1xuICAgIHN0YXRlID0gdGhpcy50b051bGxQcm90b09iaihzdGF0ZSk7XG4gICAgbGV0IHsgam9pbnMsIGxlYXZlcyB9ID0gdGhpcy5jbG9uZShkaWZmKTtcbiAgICBpZiAoIW9uSm9pbikge1xuICAgICAgb25Kb2luID0gZnVuY3Rpb24oKSB7XG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAoIW9uTGVhdmUpIHtcbiAgICAgIG9uTGVhdmUgPSBmdW5jdGlvbigpIHtcbiAgICAgIH07XG4gICAgfVxuICAgIHRoaXMubWFwKGpvaW5zLCAoa2V5LCBuZXdQcmVzZW5jZSkgPT4ge1xuICAgICAgbGV0IGN1cnJlbnRQcmVzZW5jZSA9IHN0YXRlW2tleV07XG4gICAgICBzdGF0ZVtrZXldID0gdGhpcy5jbG9uZShuZXdQcmVzZW5jZSk7XG4gICAgICBpZiAoY3VycmVudFByZXNlbmNlKSB7XG4gICAgICAgIGxldCBqb2luZWRSZWZzID0gc3RhdGVba2V5XS5tZXRhcy5tYXAoKG0pID0+IG0ucGh4X3JlZik7XG4gICAgICAgIGxldCBjdXJNZXRhcyA9IGN1cnJlbnRQcmVzZW5jZS5tZXRhcy5maWx0ZXIoKG0pID0+IGpvaW5lZ
1FJlZnMuaW5kZXhPZihtLnBoeF9yZWYpIDwgMCk7XG4gICAgICAgIHN0YXRlW2tleV0ubWV0YXMudW5zaGlmdCguLi5jdXJNZXRhcyk7XG4gICAgICB9XG4gICAgICBvbkpvaW4oa2V5LCBjdXJyZW50UHJlc2VuY2UsIG5ld1ByZXNlbmNlKTtcbiAgICB9KTtcbiAgICB0aGlzLm1hcChsZWF2ZXMsIChrZXksIGxlZnRQcmVzZW5jZSkgPT4ge1xuICAgICAgbGV0IGN1cnJlbnRQcmVzZW5jZSA9IHN0YXRlW2tleV07XG4gICAgICBpZiAoIWN1cnJlbnRQcmVzZW5jZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsZXQgcmVmc1RvUmVtb3ZlID0gbGVmdFByZXNlbmNlLm1ldGFzLm1hcCgobSkgPT4gbS5waHhfcmVmKTtcbiAgICAgIGN1cnJlbnRQcmVzZW5jZS5tZXRhcyA9IGN1cnJlbnRQcmVzZW5jZS5tZXRhcy5maWx0ZXIoKHApID0+IHtcbiAgICAgICAgcmV0dXJuIHJlZnNUb1JlbW92ZS5pbmRleE9mKHAucGh4X3JlZikgPCAwO1xuICAgICAgfSk7XG4gICAgICBvbkxlYXZlKGtleSwgY3VycmVudFByZXNlbmNlLCBsZWZ0UHJlc2VuY2UpO1xuICAgICAgaWYgKGN1cnJlbnRQcmVzZW5jZS5tZXRhcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgZGVsZXRlIHN0YXRlW2tleV07XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcmVzZW5jZXMsIHdpdGggc2VsZWN0ZWQgbWV0YWRhdGEuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwcmVzZW5jZXNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2hvb3NlclxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJlc2VuY2V9XG4gICAqL1xuICBzdGF0aWMgbGlzdChwcmVzZW5jZXMsIGNob29zZXIpIHtcbiAgICBpZiAoIWNob29zZXIpIHtcbiAgICAgIGNob29zZXIgPSBmdW5jdGlvbihrZXksIHByZXMpIHtcbiAgICAgICAgcmV0dXJuIHByZXM7XG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5tYXAocHJlc2VuY2VzLCAoa2V5LCBwcmVzZW5jZSkgPT4ge1xuICAgICAgcmV0dXJuIGNob29zZXIoa2V5LCBwcmVzZW5jZSk7XG4gICAgfSk7XG4gIH1cbiAgLy8gcHJpdmF0ZVxuICBzdGF0aWMgbWFwKG9iaiwgZnVuYykge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLm1hcCgoa2V5KSA9PiBmdW5jKGtleSwgb2JqW2tleV0pKTtcbiAgfVxuICAvLyBQcmVzZW5jZSBrZXlzIGFyZSBjaG9zZW4gb24gdGhlIHNlcnZlciBhbmQgbWF5IGNvbGxpZGUgd2l0aFxuICAvLyBPYmplY3QucHJvdG90eXBlIHByb3BlcnRpZXMgKFwiX19wcm90b19fXCIsIFwiY29uc3RydWN0b3JcIiwgLi4uKSwgc28gYW55XG4gIC8vIG9iamVjdCBpbmRleGVkIGJ5IHByZXNlbmNlIGtleSBtdXN0IG5vdCBoYXZlIGEgcHJvdG90eXBlIGNoYWluXG4gIC8vXG4gIC8vIFRPRE86IHJlcGxhY2UgdGhlIG51bGwtcHJvdG90eXBlIG9iamVjdHMgd2l0aCBNYXBzIGluIFBob2VuaXggMi4wXG4gIC8vIChicmVha2luZyBjaGFuZ2UgZm9yIHRoZSBsb3dlci1sZXZlbCBzdGF0aWMgQVBJKVxuICBzdGF0aWMgdG9OdWxsUHJvdG9PYmoob2JqKSB7XG4gICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmopID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gb2JqO1xuICAgIH1cbiAgICBsZXQgY2xlYW5lZCA9IC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG9iaikuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICBjbGVhbmVkW2tleV0gPSBvYmpba2V5XTtcbiAgICB9KTtcbiAgICByZXR1cm4gY2xlYW5lZDtcbiAgfVxuICBzdGF0aWMgY2xvbmUob2JqKSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkob2JqKSk7XG4gIH1cbn07XG5cbi8vIGpzL3Bob2VuaXgvc2VyaWFsaXplci5qc1xudmFyIHNlcmlhbGl6ZXJfZGVmYXVsdCA9IHtcbiAgSEVBREVSX0xFTkdUSDogMSxcbiAgTUVUQV9MRU5HVEg6IDQsXG4gIEtJTkRTOiB7IHB1c2g6IDAsIHJlcGx5OiAxLCBicm9hZGNhc3Q6IDIgfSxcbiAgZW5jb2RlKG1zZywgY2FsbGJhY2spIHtcbiAgICBpZiAobXNnLnBheWxvYWQuY29uc3RydWN0b3IgPT09IEFycmF5QnVmZmVyKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2sodGhpcy5iaW5hcnlFbmNvZGUobXNnKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBwYXlsb2FkID0gW21zZy5qb2luX3JlZiwgbXNnLnJlZiwgbXNnLnRvcGljLCBtc2cuZXZlbnQsIG1zZy5wYXlsb2FkXTtcbiAgICAgIHJldHVybiBjYWxsYmFjayhKU09OLnN0cmluZ2lmeShwYXlsb2FkKSk7XG4gICAgfVxuICB9LFxuICBkZWNvZGUocmF3UGF5bG9hZCwgY2FsbGJhY2spIHtcbiAgICBpZiAocmF3UGF5bG9hZC5jb25zdHJ1Y3RvciA9PT0gQXJyYXlCdWZmZXIpIHtcbiAgICAgIHJldHVybiBjYWxsYmFjayh0aGlzLmJpbmFyeURlY29kZShyYXdQYXlsb2FkKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBbam9pbl9yZWYsIHJlZiwgdG9waWMsIGV2ZW50LCBwYXlsb2FkXSA9IEpTT04ucGFyc2UocmF3UGF5bG9hZCk7XG4gICAgICByZXR1cm4gY2FsbGJhY2soeyBqb2luX3JlZiwgcmVmLCB0b3BpYywgZXZlbnQsIHBheWxvYWQgfSk7XG4gICAgfVxuICB9LFxuICAvLyBwcml2YXRlXG4gIGJpbmFyeUVuY29kZShtZXNzYWdlKSB7XG4gICAgbGV0IHsgam9pbl9yZWYsIHJlZiwgZXZlbnQsIHRvcGljLCBwYXlsb2FkIH0gPSBtZXNzYWdlO1xuICAgIGxldCBlbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKCk7XG4gICAgbGV0IGpvaW5SZWZCeXRlcyA9IGVuY29kZXIuZW5jb2RlKGpvaW5fcmVmKTtcbiAgICBsZXQgcmVmQnl0ZXMgPSBlbmNvZGVyLmVuY29kZShyZWYpO1xuICAgIGxldCB0b3BpY0J5dGVzID0gZW5jb2Rlci5lbmNvZGUodG9waWMpO1xuICAgIGxldCBldmVudEJ5dGVzID0gZW5jb2Rlci5lbmNvZGUoZXZlbnQpO1xuICAgIHRoaXMuYXNzZXJ0RmllbGRTaXplKGpvaW5SZWZCeXRlcy5ieXRlTGVuZ3RoLCBcImpvaW5fcmVmXCIpO1xuICAgIHRoaXMuYXNzZXJ0RmllbGRTaXplKHJlZkJ5dGVzLmJ5dGVMZW5ndGgsIFwicmVmXCIpO1xuICAgIHRoaXMuYXNzZXJ0RmllbGRTaXplKHRvcGljQnl0ZXMuYnl0ZUxlbmd0aCwgXCJ0b3BpY1wiKTtcbiAgICB0aGlzLmFzc2VydEZpZWxkU2l6ZShldmVudEJ5dGVzLmJ5dGVMZW5ndGgsIFwiZXZlbnRcIik7XG4gICAgbGV0IG1ldGFMZW5ndGggPSB0aGlzLk1FVEFfTEVOR1RIICsgam9pblJlZkJ5dGVzLmJ5dGVMZW5ndGggKyByZWZCeXRlcy5ieXRlTGVuZ3RoICsgdG9waWNCeXRlcy5ieXRlTGVuZ3RoICsgZXZlbnRCeXRlcy5ieXRlTGVuZ3RoO1xuICAgIGxldCBoZWFkZXIgPSBuZXcgQXJyYXlCdWZmZXIodGhpcy5IRUFERVJfTEVOR1RIICsgbWV0YUxlbmd0aCk7XG4gICAgbGV0IGhlYWRlckJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoaGVhZGVyKTtcbiAgICBsZXQgdmlldyA9IG5ldyBEYXRhVmlldyhoZWFkZXIpO1xuICAgIGxldCBvZmZzZXQgPSAwO1xuICAgIHZpZXcuc2V0VWludDgob2Zmc2V0KyssIHRoaXMuS0lORFMucHVzaCk7XG4gICAgdmlldy5zZXRVaW50OChvZmZzZXQrKywgam9pblJlZkJ5dGVzLmJ5dGVMZW5ndGgpO1xuICAgIHZpZXcuc2V0VWludDgob2Zmc2V0KyssIHJlZkJ5dGVzLmJ5dGVMZW5ndGgpO1xuICAgIHZpZXcuc2V0VWludDgob2Zmc2V0KyssIHRvcGljQnl0ZXMuYnl0ZUxlbmd0aCk7XG4gICAgdmlldy5zZXRVaW50OChvZmZzZXQrKywgZXZlbnRCeXRlcy5ieXRlTGVuZ3RoKTtcbiAgICBoZWFkZXJCeXRlcy5zZXQoam9pblJlZkJ5dGVzLCBvZmZzZXQpO1xuICAgIG9mZnNldCArPSBqb2luUmVmQnl0ZXMuYnl0ZUxlbmd0aDtcbiAgICBoZWFkZXJCeXRlcy5zZXQocmVmQnl0ZXMsIG9mZnNldCk7XG4gICAgb2Zmc2V0ICs9IHJlZkJ5dGVzLmJ5dGVMZW5ndGg7XG4gICAgaGVhZGVyQnl0ZXMuc2V0KHRvcGljQnl0ZXMsIG9mZnNldCk7XG4gICAgb2Zmc2V0ICs9IHRvcGljQnl0ZXMuYnl0ZUxlbmd0aDtcbiAgICBoZWFkZXJCeXRlcy5zZXQoZXZlbnRCeXRlcywgb2Zmc2V0KTtcbiAgICBvZmZzZXQgKz0gZXZlbnRCeXRlcy5ieXRlTGVuZ3RoO1xuICAgIHZhciBjb21iaW5lZCA9IG5ldyBVaW50OEFycmF5KGhlYWRlci5ieXRlTGVuZ3RoICsgcGF5bG9hZC5ieXRlTGVuZ3RoKTtcbiAgICBjb21iaW5lZC5zZXQoaGVhZG
1VyQnl0ZXMsIDApO1xuICAgIGNvbWJpbmVkLnNldChuZXcgVWludDhBcnJheShwYXlsb2FkKSwgaGVhZGVyLmJ5dGVMZW5ndGgpO1xuICAgIHJldHVybiBjb21iaW5lZC5idWZmZXI7XG4gIH0sXG4gIGFzc2VydEZpZWxkU2l6ZShzaXplLCBuYW1lKSB7XG4gICAgaWYgKHNpemUgPiAyNTUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdW5hYmxlIHRvIGNvbnZlcnQgJHtuYW1lfSB0byBiaW5hcnk6IG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDI1NSBieXRlcywgYnV0IGlzICR7c2l6ZX0gYnl0ZXNgKTtcbiAgICB9XG4gIH0sXG4gIGJpbmFyeURlY29kZShidWZmZXIpIHtcbiAgICBsZXQgdmlldyA9IG5ldyBEYXRhVmlldyhidWZmZXIpO1xuICAgIGxldCBraW5kID0gdmlldy5nZXRVaW50OCgwKTtcbiAgICBsZXQgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigpO1xuICAgIHN3aXRjaCAoa2luZCkge1xuICAgICAgY2FzZSB0aGlzLktJTkRTLnB1c2g6XG4gICAgICAgIHJldHVybiB0aGlzLmRlY29kZVB1c2goYnVmZmVyLCB2aWV3LCBkZWNvZGVyKTtcbiAgICAgIGNhc2UgdGhpcy5LSU5EUy5yZXBseTpcbiAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlUmVwbHkoYnVmZmVyLCB2aWV3LCBkZWNvZGVyKTtcbiAgICAgIGNhc2UgdGhpcy5LSU5EUy5icm9hZGNhc3Q6XG4gICAgICAgIHJldHVybiB0aGlzLmRlY29kZUJyb2FkY2FzdChidWZmZXIsIHZpZXcsIGRlY29kZXIpO1xuICAgIH1cbiAgfSxcbiAgZGVjb2RlUHVzaChidWZmZXIsIHZpZXcsIGRlY29kZXIpIHtcbiAgICBsZXQgam9pblJlZlNpemUgPSB2aWV3LmdldFVpbnQ4KDEpO1xuICAgIGxldCB0b3BpY1NpemUgPSB2aWV3LmdldFVpbnQ4KDIpO1xuICAgIGxldCBldmVudFNpemUgPSB2aWV3LmdldFVpbnQ4KDMpO1xuICAgIGxldCBvZmZzZXQgPSB0aGlzLkhFQURFUl9MRU5HVEggKyB0aGlzLk1FVEFfTEVOR1RIIC0gMTtcbiAgICBsZXQgam9pblJlZiA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIGpvaW5SZWZTaXplKSk7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0ICsgam9pblJlZlNpemU7XG4gICAgbGV0IHRvcGljID0gZGVjb2Rlci5kZWNvZGUoYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgdG9waWNTaXplKSk7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0ICsgdG9waWNTaXplO1xuICAgIGxldCBldmVudCA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIGV2ZW50U2l6ZSkpO1xuICAgIG9mZnNldCA9IG9mZnNldCArIGV2ZW50U2l6ZTtcbiAgICBsZXQgZGF0YSA9IGJ1ZmZlci5zbGljZShvZmZzZXQsIGJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICByZXR1cm4geyBqb2luX3JlZjogam9pblJlZiwgcmVmOiBudWxsLCB0b3BpYywgZXZlbnQsIHBheWxvYWQ6IGRhdGEgfTtcbiAgfSxcbiAgZGVjb2RlUmVwbHkoYnVmZmVyLCB2aWV3LCBkZWNvZGVyKSB7XG4gICAgbGV0IGpvaW5SZWZTaXplID0gdmlldy5nZXRVaW50OCgxKTtcbiAgICBsZXQgcmVmU2l6ZSA9IHZpZXcuZ2V0VWludDgoMik7XG4gICAgbGV0IHRvcGljU2l6ZSA9IHZpZXcuZ2V0VWludDgoMyk7XG4gICAgbGV0IGV2ZW50U2l6ZSA9IHZpZXcuZ2V0VWludDgoNCk7XG4gICAgbGV0IG9mZnNldCA9IHRoaXMuSEVBREVSX0xFTkdUSCArIHRoaXMuTUVUQV9MRU5HVEg7XG4gICAgbGV0IGpvaW5SZWYgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBqb2luUmVmU2l6ZSkpO1xuICAgIG9mZnNldCA9IG9mZnNldCArIGpvaW5SZWZTaXplO1xuICAgIGxldCByZWYgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyByZWZTaXplKSk7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0ICsgcmVmU2l6ZTtcbiAgICBsZXQgdG9waWMgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyB0b3BpY1NpemUpKTtcbiAgICBvZmZzZXQgPSBvZmZzZXQgKyB0b3BpY1NpemU7XG4gICAgbGV0IGV2ZW50ID0gZGVjb2Rlci5kZWNvZGUoYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgZXZlbnRTaXplKSk7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0ICsgZXZlbnRTaXplO1xuICAgIGxldCBkYXRhID0gYnVmZmVyLnNsaWNlKG9mZnNldCwgYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgIGxldCBwYXlsb2FkID0geyBzdGF0dXM6IGV2ZW50LCByZXNwb25zZTogZGF0YSB9O1xuICAgIHJldHVybiB7IGpvaW5fcmVmOiBqb2luUmVmLCByZWYsIHRvcGljLCBldmVudDogQ0hBTk5FTF9FVkVOVFMucmVwbHksIHBheWxvYWQgfTtcbiAgfSxcbiAgZGVjb2RlQnJvYWRjYXN0KGJ1ZmZlciwgdmlldywgZGVjb2Rlcikge1xuICAgIGxldCB0b3BpY1NpemUgPSB2aWV3LmdldFVpbnQ4KDEpO1xuICAgIGxldCBldmVudFNpemUgPSB2aWV3LmdldFVpbnQ4KDIpO1xuICAgIGxldCBvZmZzZXQgPSB0aGlzLkhFQURFUl9MRU5HVEggKyAyO1xuICAgIGxldCB0b3BpYyA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIHRvcGljU2l6ZSkpO1xuICAgIG9mZnNldCA9IG9mZnNldCArIHRvcGljU2l6ZTtcbiAgICBsZXQgZXZlbnQgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBldmVudFNpemUpKTtcbiAgICBvZmZzZXQgPSBvZmZzZXQgKyBldmVudFNpemU7XG4gICAgbGV0IGRhdGEgPSBidWZmZXIuc2xpY2Uob2Zmc2V0LCBidWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgcmV0dXJuIHsgam9pbl9yZWY6IG51bGwsIHJlZjogbnVsbCwgdG9waWMsIGV2ZW50LCBwYXlsb2FkOiBkYXRhIH07XG4gIH1cbn07XG5cbi8vIGpzL3Bob2VuaXgvc29ja2V0LmpzXG52YXIgU29ja2V0ID0gY2xhc3Mge1xuICBjb25zdHJ1Y3RvcihlbmRQb2ludCwgb3B0cyA9IHt9KSB7XG4gICAgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcyA9IHsgb3BlbjogW10sIGNsb3NlOiBbXSwgZXJyb3I6IFtdLCBtZXNzYWdlOiBbXSB9O1xuICAgIHRoaXMuY2hhbm5lbHMgPSBbXTtcbiAgICB0aGlzLnNlbmRCdWZmZXIgPSBbXTtcbiAgICB0aGlzLnJlZiA9IDA7XG4gICAgdGhpcy5mYWxsYmFja1JlZiA9IG51bGw7XG4gICAgdGhpcy50aW1lb3V0ID0gb3B0cy50aW1lb3V0IHx8IERFRkFVTFRfVElNRU9VVDtcbiAgICB0aGlzLnRyYW5zcG9ydCA9IG9wdHMudHJhbnNwb3J0IHx8IGdsb2JhbC5XZWJTb2NrZXQgfHwgTG9uZ1BvbGw7XG4gICAgdGhpcy5wcmltYXJ5UGFzc2VkSGVhbHRoQ2hlY2sgPSBmYWxzZTtcbiAgICB0aGlzLmxvbmdQb2xsRmFsbGJhY2tNcyA9IG9wdHMubG9uZ1BvbGxGYWxsYmFja01zO1xuICAgIHRoaXMuZmFsbGJhY2tUaW1lciA9IG51bGw7XG4gICAgdGhpcy5zZXNzaW9uU3RvcmUgPSBvcHRzLnNlc3Npb25TdG9yYWdlIHx8IGdsb2JhbCAmJiBnbG9iYWwuc2Vzc2lvblN0b3JhZ2U7XG4gICAgdGhpcy5lc3RhYmxpc2hlZENvbm5lY3Rpb25zID0gMDtcbiAgICB0aGlzLmRlZmF1bHRFbmNvZGVyID0gc2VyaWFsaXplcl9kZWZhdWx0LmVuY29kZS5iaW5kKHNlcmlhbGl6ZXJfZGVmYXVsdCk7XG4gICAgdGhpcy5kZWZh
1dWx0RGVjb2RlciA9IHNlcmlhbGl6ZXJfZGVmYXVsdC5kZWNvZGUuYmluZChzZXJpYWxpemVyX2RlZmF1bHQpO1xuICAgIHRoaXMuY2xvc2VXYXNDbGVhbiA9IHRydWU7XG4gICAgdGhpcy5kaXNjb25uZWN0aW5nID0gZmFsc2U7XG4gICAgdGhpcy5iaW5hcnlUeXBlID0gb3B0cy5iaW5hcnlUeXBlIHx8IFwiYXJyYXlidWZmZXJcIjtcbiAgICB0aGlzLmNvbm5lY3RDbG9jayA9IDE7XG4gICAgdGhpcy5wYWdlSGlkZGVuID0gZmFsc2U7XG4gICAgaWYgKHRoaXMudHJhbnNwb3J0ICE9PSBMb25nUG9sbCkge1xuICAgICAgdGhpcy5lbmNvZGUgPSBvcHRzLmVuY29kZSB8fCB0aGlzLmRlZmF1bHRFbmNvZGVyO1xuICAgICAgdGhpcy5kZWNvZGUgPSBvcHRzLmRlY29kZSB8fCB0aGlzLmRlZmF1bHREZWNvZGVyO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmVuY29kZSA9IHRoaXMuZGVmYXVsdEVuY29kZXI7XG4gICAgICB0aGlzLmRlY29kZSA9IHRoaXMuZGVmYXVsdERlY29kZXI7XG4gICAgfVxuICAgIGxldCBhd2FpdGluZ0Nvbm5lY3Rpb25PblBhZ2VTaG93ID0gbnVsbDtcbiAgICBpZiAocGh4V2luZG93ICYmIHBoeFdpbmRvdy5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgICBwaHhXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInBhZ2VoaWRlXCIsIChfZSkgPT4ge1xuICAgICAgICBpZiAodGhpcy5jb25uKSB7XG4gICAgICAgICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgYXdhaXRpbmdDb25uZWN0aW9uT25QYWdlU2hvdyA9IHRoaXMuY29ubmVjdENsb2NrO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHBoeFdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicGFnZXNob3dcIiwgKF9lKSA9PiB7XG4gICAgICAgIGlmIChhd2FpdGluZ0Nvbm5lY3Rpb25PblBhZ2VTaG93ID09PSB0aGlzLmNvbm5lY3RDbG9jaykge1xuICAgICAgICAgIGF3YWl0aW5nQ29ubmVjdGlvbk9uUGFnZVNob3cgPSBudWxsO1xuICAgICAgICAgIHRoaXMuY29ubmVjdCgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHBoeFdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwidmlzaWJpbGl0eWNoYW5nZVwiLCAoKSA9PiB7XG4gICAgICAgIGlmIChkb2N1bWVudC52aXNpYmlsaXR5U3RhdGUgPT09IFwiaGlkZGVuXCIpIHtcbiAgICAgICAgICB0aGlzLnBhZ2VIaWRkZW4gPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucGFnZUhpZGRlbiA9IGZhbHNlO1xuICAgICAgICAgIGlmICghdGhpcy5pc0Nvbm5lY3RlZCgpICYmICF0aGlzLmNsb3NlV2FzQ2xlYW4pIHtcbiAgICAgICAgICAgIHRoaXMudGVhcmRvd24oKCkgPT4gdGhpcy5jb25uZWN0KCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuaGVhcnRiZWF0SW50ZXJ2YWxNcyA9IG9wdHMuaGVhcnRiZWF0SW50ZXJ2YWxNcyB8fCAzZTQ7XG4gICAgdGhpcy5yZWpvaW5BZnRlck1zID0gKHRyaWVzKSA9PiB7XG4gICAgICBpZiAob3B0cy5yZWpvaW5BZnRlck1zKSB7XG4gICAgICAgIHJldHVybiBvcHRzLnJlam9pbkFmdGVyTXModHJpZXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFsxZTMsIDJlMywgNWUzXVt0cmllcyAtIDFdIHx8IDFlNDtcbiAgICAgIH1cbiAgICB9O1xuICAgIHRoaXMucmVjb25uZWN0QWZ0ZXJNcyA9ICh0cmllcykgPT4ge1xuICAgICAgaWYgKG9wdHMucmVjb25uZWN0QWZ0ZXJNcykge1xuICAgICAgICByZXR1cm4gb3B0cy5yZWNvbm5lY3RBZnRlck1zKHRyaWVzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBbMTAsIDUwLCAxMDAsIDE1MCwgMjAwLCAyNTAsIDUwMCwgMWUzLCAyZTNdW3RyaWVzIC0gMV0gfHwgNWUzO1xuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5sb2dnZXIgPSBvcHRzLmxvZ2dlciB8fCBudWxsO1xuICAgIGlmICghdGhpcy5sb2dnZXIgJiYgb3B0cy5kZWJ1Zykge1xuICAgICAgdGhpcy5sb2dnZXIgPSAoa2luZCwgbXNnLCBkYXRhKSA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKGAke2tpbmR9OiAke21zZ31gLCBkYXRhKTtcbiAgICAgIH07XG4gICAgfVxuICAgIHRoaXMubG9uZ3BvbGxlclRpbWVvdXQgPSBvcHRzLmxvbmdwb2xsZXJUaW1lb3V0IHx8IDJlNDtcbiAgICB0aGlzLnBhcmFtcyA9IGNsb3N1cmUob3B0cy5wYXJhbXMgfHwge30pO1xuICAgIHRoaXMuZW5kUG9pbnQgPSBgJHtlbmRQb2ludH0vJHtUUkFOU1BPUlRTLndlYnNvY2tldH1gO1xuICAgIHRoaXMudnNuID0gb3B0cy52c24gfHwgREVGQVVMVF9WU047XG4gICAgdGhpcy5oZWFydGJlYXRUaW1lb3V0VGltZXIgPSBudWxsO1xuICAgIHRoaXMuaGVhcnRiZWF0VGltZXIgPSBudWxsO1xuICAgIHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZiA9IG51bGw7XG4gICAgdGhpcy5yZWNvbm5lY3RUaW1lciA9IG5ldyBUaW1lcigoKSA9PiB7XG4gICAgICBpZiAodGhpcy5wYWdlSGlkZGVuKSB7XG4gICAgICAgIHRoaXMubG9nKFwiTm90IHJlY29ubmVjdGluZyBhcyBwYWdlIGlzIGhpZGRlbiFcIik7XG4gICAgICAgIHRoaXMudGVhcmRvd24oKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy50ZWFyZG93bigoKSA9PiB0aGlzLmNvbm5lY3QoKSk7XG4gICAgfSwgdGhpcy5yZWNvbm5lY3RBZnRlck1zKTtcbiAgICB0aGlzLmF1dGhUb2tlbiA9IG9wdHMuYXV0aFRva2VuICYmIGNsb3N1cmUob3B0cy5hdXRoVG9rZW4pO1xuICB9XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBMb25nUG9sbCB0cmFuc3BvcnQgcmVmZXJlbmNlXG4gICAqL1xuICBnZXRMb25nUG9sbFRyYW5zcG9ydCgpIHtcbiAgICByZXR1cm4gTG9uZ1BvbGw7XG4gIH1cbiAgLyoqXG4gICAqIERpc2Nvbm5lY3RzIGFuZCByZXBsYWNlcyB0aGUgYWN0aXZlIHRyYW5zcG9ydFxuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBuZXdUcmFuc3BvcnQgLSBUaGUgbmV3IHRyYW5zcG9ydCBjbGFzcyB0byBpbnN0YW50aWF0ZVxuICAgKlxuICAgKi9cbiAgcmVwbGFjZVRyYW5zcG9ydChuZXdUcmFuc3BvcnQpIHtcbiAgICB0aGlzLmNvbm5lY3RDbG9jaysrO1xuICAgIHRoaXMuY2xvc2VXYXNDbGVhbiA9IHRydWU7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuZmFsbGJhY2tUaW1lcik7XG4gICAgdGhpcy5yZWNvbm5lY3RUaW1lci5yZXNldCgpO1xuICAgIGlmICh0aGlzLmNvbm4pIHtcbiAgICAgIHRoaXMuY29ubi5jbG9zZSgpO1xuICAgICAgdGhpcy5jb25uID0gbnVsbDtcbiAgICB9XG4gICAgdGhpcy50cmFuc3BvcnQgPSBuZXdUcmFuc3BvcnQ7XG4gIH1cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHNvY2tldCBwcm90b2NvbFxuICAgKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgKi9cbiAgcHJvdG9jb2woKSB7XG4gICAgcmV0dXJuIGxvY2F0aW9uLnByb3RvY29sLm1hdGNoKC9eaHR0cHMvKSA/IFwid3NzXCIgOiBcIndzXCI7XG4gIH1cbiAgLyoqXG4gICAqIFRoZSBmdWxseSBxdWFsaWZpZWQgc29ja2V0IHVybFxuICAgKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgKi9cbiAgZW5kUG9pbnRVUkwoKSB7XG4gICAgbGV0IHVyaSA9IEFqYXguYXBwZW5kUGFyYW1zKFxuICAgICAgQWpheC5hcHBlbmRQYXJhbXModGhpcy5lbmRQb2ludCwgdGhpcy5wYXJhbXMoKSksXG4gICAgICB7IHZzbjogdGhpcy52c24gfV
1xuICAgICk7XG4gICAgaWYgKHVyaS5jaGFyQXQoMCkgIT09IFwiL1wiKSB7XG4gICAgICByZXR1cm4gdXJpO1xuICAgIH1cbiAgICBpZiAodXJpLmNoYXJBdCgxKSA9PT0gXCIvXCIpIHtcbiAgICAgIHJldHVybiBgJHt0aGlzLnByb3RvY29sKCl9OiR7dXJpfWA7XG4gICAgfVxuICAgIHJldHVybiBgJHt0aGlzLnByb3RvY29sKCl9Oi8vJHtsb2NhdGlvbi5ob3N0fSR7dXJpfWA7XG4gIH1cbiAgLyoqXG4gICAqIERpc2Nvbm5lY3RzIHRoZSBzb2NrZXRcbiAgICpcbiAgICogU2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9DbG9zZUV2ZW50I1N0YXR1c19jb2RlcyBmb3IgdmFsaWQgc3RhdHVzIGNvZGVzLlxuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayAtIE9wdGlvbmFsIGNhbGxiYWNrIHdoaWNoIGlzIGNhbGxlZCBhZnRlciBzb2NrZXQgaXMgZGlzY29ubmVjdGVkLlxuICAgKiBAcGFyYW0ge2ludGVnZXJ9IGNvZGUgLSBBIHN0YXR1cyBjb2RlIGZvciBkaXNjb25uZWN0aW9uIChPcHRpb25hbCkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZWFzb24gLSBBIHRleHR1YWwgZGVzY3JpcHRpb24gb2YgdGhlIHJlYXNvbiB0byBkaXNjb25uZWN0LiAoT3B0aW9uYWwpXG4gICAqL1xuICBkaXNjb25uZWN0KGNhbGxiYWNrLCBjb2RlLCByZWFzb24pIHtcbiAgICB0aGlzLmNvbm5lY3RDbG9jaysrO1xuICAgIHRoaXMuZGlzY29ubmVjdGluZyA9IHRydWU7XG4gICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gdHJ1ZTtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5mYWxsYmFja1RpbWVyKTtcbiAgICB0aGlzLnJlY29ubmVjdFRpbWVyLnJlc2V0KCk7XG4gICAgdGhpcy50ZWFyZG93bigoKSA9PiB7XG4gICAgICB0aGlzLmRpc2Nvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKCk7XG4gICAgfSwgY29kZSwgcmVhc29uKTtcbiAgfVxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbXMgdG8gc2VuZCB3aGVuIGNvbm5lY3RpbmcsIGZvciBleGFtcGxlIGB7dXNlcl9pZDogdXNlclRva2VufWBcbiAgICpcbiAgICogUGFzc2luZyBwYXJhbXMgdG8gY29ubmVjdCBpcyBkZXByZWNhdGVkOyBwYXNzIHRoZW0gaW4gdGhlIFNvY2tldCBjb25zdHJ1Y3RvciBpbnN0ZWFkOlxuICAgKiBgbmV3IFNvY2tldChcIi9zb2NrZXRcIiwge3BhcmFtczoge3VzZXJfaWQ6IHVzZXJUb2tlbn19KWAuXG4gICAqL1xuICBjb25uZWN0KHBhcmFtcykge1xuICAgIGlmIChwYXJhbXMpIHtcbiAgICAgIGNvbnNvbGUgJiYgY29uc29sZS5sb2coXCJwYXNzaW5nIHBhcmFtcyB0byBjb25uZWN0IGlzIGRlcHJlY2F0ZWQuIEluc3RlYWQgcGFzcyA6cGFyYW1zIHRvIHRoZSBTb2NrZXQgY29uc3RydWN0b3JcIik7XG4gICAgICB0aGlzLnBhcmFtcyA9IGNsb3N1cmUocGFyYW1zKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuY29ubiAmJiAhdGhpcy5kaXNjb25uZWN0aW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLmxvbmdQb2xsRmFsbGJhY2tNcyAmJiB0aGlzLnRyYW5zcG9ydCAhPT0gTG9uZ1BvbGwpIHtcbiAgICAgIHRoaXMuY29ubmVjdFdpdGhGYWxsYmFjayhMb25nUG9sbCwgdGhpcy5sb25nUG9sbEZhbGxiYWNrTXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRyYW5zcG9ydENvbm5lY3QoKTtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIExvZ3MgdGhlIG1lc3NhZ2UuIE92ZXJyaWRlIGB0aGlzLmxvZ2dlcmAgZm9yIHNwZWNpYWxpemVkIGxvZ2dpbmcuIG5vb3BzIGJ5IGRlZmF1bHRcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtpbmRcbiAgICogQHBhcmFtIHtzdHJpbmd9IG1zZ1xuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YVxuICAgKi9cbiAgbG9nKGtpbmQsIG1zZywgZGF0YSkge1xuICAgIHRoaXMubG9nZ2VyICYmIHRoaXMubG9nZ2VyKGtpbmQsIG1zZywgZGF0YSk7XG4gIH1cbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiBhIGxvZ2dlciBoYXMgYmVlbiBzZXQgb24gdGhpcyBzb2NrZXQuXG4gICAqL1xuICBoYXNMb2dnZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMubG9nZ2VyICE9PSBudWxsO1xuICB9XG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgY2FsbGJhY2tzIGZvciBjb25uZWN0aW9uIG9wZW4gZXZlbnRzXG4gICAqXG4gICAqIEBleGFtcGxlIHNvY2tldC5vbk9wZW4oZnVuY3Rpb24oKXsgY29uc29sZS5pbmZvKFwidGhlIHNvY2tldCB3YXMgb3BlbmVkXCIpIH0pXG4gICAqXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBvbk9wZW4oY2FsbGJhY2spIHtcbiAgICBsZXQgcmVmID0gdGhpcy5tYWtlUmVmKCk7XG4gICAgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcy5vcGVuLnB1c2goW3JlZiwgY2FsbGJhY2tdKTtcbiAgICByZXR1cm4gcmVmO1xuICB9XG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgY2FsbGJhY2tzIGZvciBjb25uZWN0aW9uIGNsb3NlIGV2ZW50c1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgb25DbG9zZShjYWxsYmFjaykge1xuICAgIGxldCByZWYgPSB0aGlzLm1ha2VSZWYoKTtcbiAgICB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzLmNsb3NlLnB1c2goW3JlZiwgY2FsbGJhY2tdKTtcbiAgICByZXR1cm4gcmVmO1xuICB9XG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgY2FsbGJhY2tzIGZvciBjb25uZWN0aW9uIGVycm9yIGV2ZW50c1xuICAgKlxuICAgKiBAZXhhbXBsZSBzb2NrZXQub25FcnJvcihmdW5jdGlvbihlcnJvcil7IGFsZXJ0KFwiQW4gZXJyb3Igb2NjdXJyZWRcIikgfSlcbiAgICpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIG9uRXJyb3IoY2FsbGJhY2spIHtcbiAgICBsZXQgcmVmID0gdGhpcy5tYWtlUmVmKCk7XG4gICAgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcy5lcnJvci5wdXNoKFtyZWYsIGNhbGxiYWNrXSk7XG4gICAgcmV0dXJuIHJlZjtcbiAgfVxuICAvKipcbiAgICogUmVnaXN0ZXJzIGNhbGxiYWNrcyBmb3IgY29ubmVjdGlvbiBtZXNzYWdlIGV2ZW50c1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgb25NZXNzYWdlKGNhbGxiYWNrKSB7XG4gICAgbGV0IHJlZiA9IHRoaXMubWFrZVJlZigpO1xuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3MubWVzc2FnZS5wdXNoKFtyZWYsIGNhbGxiYWNrXSk7XG4gICAgcmV0dXJuIHJlZjtcbiAgfVxuICAvKipcbiAgICogUGluZ3MgdGhlI
1HNlcnZlciBhbmQgaW52b2tlcyB0aGUgY2FsbGJhY2sgd2l0aCB0aGUgUlRUIGluIG1pbGxpc2Vjb25kc1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKlxuICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHBpbmcgd2FzIHB1c2hlZCBvciBmYWxzZSBpZiB1bmFibGUgdG8gYmUgcHVzaGVkLlxuICAgKi9cbiAgcGluZyhjYWxsYmFjaykge1xuICAgIGlmICghdGhpcy5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGxldCByZWYgPSB0aGlzLm1ha2VSZWYoKTtcbiAgICBsZXQgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICB0aGlzLnB1c2goeyB0b3BpYzogXCJwaG9lbml4XCIsIGV2ZW50OiBcImhlYXJ0YmVhdFwiLCBwYXlsb2FkOiB7fSwgcmVmIH0pO1xuICAgIGxldCBvbk1zZ1JlZiA9IHRoaXMub25NZXNzYWdlKChtc2cpID0+IHtcbiAgICAgIGlmIChtc2cucmVmID09PSByZWYpIHtcbiAgICAgICAgdGhpcy5vZmYoW29uTXNnUmVmXSk7XG4gICAgICAgIGNhbGxiYWNrKERhdGUubm93KCkgLSBzdGFydFRpbWUpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufVxuICAgKi9cbiAgdHJhbnNwb3J0TmFtZSh0cmFuc3BvcnQpIHtcbiAgICBzd2l0Y2ggKHRyYW5zcG9ydCkge1xuICAgICAgY2FzZSBMb25nUG9sbDpcbiAgICAgICAgcmV0dXJuIFwiTG9uZ1BvbGxcIjtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB0cmFuc3BvcnQubmFtZTtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICB0cmFuc3BvcnRDb25uZWN0KCkge1xuICAgIHRoaXMuY29ubmVjdENsb2NrKys7XG4gICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gZmFsc2U7XG4gICAgbGV0IHByb3RvY29scyA9IHZvaWQgMDtcbiAgICBpZiAodGhpcy5hdXRoVG9rZW4pIHtcbiAgICAgIHByb3RvY29scyA9IFtcInBob2VuaXhcIiwgYCR7QVVUSF9UT0tFTl9QUkVGSVh9JHtidG9hKHRoaXMuYXV0aFRva2VuKCkpLnJlcGxhY2UoLz0vZywgXCJcIil9YF07XG4gICAgfVxuICAgIHRoaXMuY29ubiA9IG5ldyB0aGlzLnRyYW5zcG9ydCh0aGlzLmVuZFBvaW50VVJMKCksIHByb3RvY29scyk7XG4gICAgdGhpcy5jb25uLmJpbmFyeVR5cGUgPSB0aGlzLmJpbmFyeVR5cGU7XG4gICAgdGhpcy5jb25uLnRpbWVvdXQgPSB0aGlzLmxvbmdwb2xsZXJUaW1lb3V0O1xuICAgIHRoaXMuY29ubi5vbm9wZW4gPSAoKSA9PiB0aGlzLm9uQ29ubk9wZW4oKTtcbiAgICB0aGlzLmNvbm4ub25lcnJvciA9IChlcnJvcikgPT4gdGhpcy5vbkNvbm5FcnJvcihlcnJvcik7XG4gICAgdGhpcy5jb25uLm9ubWVzc2FnZSA9IChldmVudCkgPT4gdGhpcy5vbkNvbm5NZXNzYWdlKGV2ZW50KTtcbiAgICB0aGlzLmNvbm4ub25jbG9zZSA9IChldmVudCkgPT4gdGhpcy5vbkNvbm5DbG9zZShldmVudCk7XG4gIH1cbiAgZ2V0U2Vzc2lvbihrZXkpIHtcbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uU3RvcmUgJiYgdGhpcy5zZXNzaW9uU3RvcmUuZ2V0SXRlbShrZXkpO1xuICB9XG4gIHN0b3JlU2Vzc2lvbihrZXksIHZhbCkge1xuICAgIHRoaXMuc2Vzc2lvblN0b3JlICYmIHRoaXMuc2Vzc2lvblN0b3JlLnNldEl0ZW0oa2V5LCB2YWwpO1xuICB9XG4gIGNvbm5lY3RXaXRoRmFsbGJhY2soZmFsbGJhY2tUcmFuc3BvcnQsIGZhbGxiYWNrVGhyZXNob2xkID0gMjUwMCkge1xuICAgIGNsZWFyVGltZW91dCh0aGlzLmZhbGxiYWNrVGltZXIpO1xuICAgIGxldCBlc3RhYmxpc2hlZCA9IGZhbHNlO1xuICAgIGxldCBwcmltYXJ5VHJhbnNwb3J0ID0gdHJ1ZTtcbiAgICBsZXQgb3BlblJlZiwgZXJyb3JSZWY7XG4gICAgbGV0IGZhbGxiYWNrVHJhbnNwb3J0TmFtZSA9IHRoaXMudHJhbnNwb3J0TmFtZShmYWxsYmFja1RyYW5zcG9ydCk7XG4gICAgbGV0IGZhbGxiYWNrID0gKHJlYXNvbikgPT4ge1xuICAgICAgdGhpcy5sb2coXCJ0cmFuc3BvcnRcIiwgYGZhbGxpbmcgYmFjayB0byAke2ZhbGxiYWNrVHJhbnNwb3J0TmFtZX0uLi5gLCByZWFzb24pO1xuICAgICAgdGhpcy5vZmYoW29wZW5SZWYsIGVycm9yUmVmXSk7XG4gICAgICBwcmltYXJ5VHJhbnNwb3J0ID0gZmFsc2U7XG4gICAgICB0aGlzLnJlcGxhY2VUcmFuc3BvcnQoZmFsbGJhY2tUcmFuc3BvcnQpO1xuICAgICAgdGhpcy50cmFuc3BvcnRDb25uZWN0KCk7XG4gICAgfTtcbiAgICBpZiAodGhpcy5nZXRTZXNzaW9uKGBwaHg6ZmFsbGJhY2s6JHtmYWxsYmFja1RyYW5zcG9ydE5hbWV9YCkpIHtcbiAgICAgIHJldHVybiBmYWxsYmFjayhcIm1lbW9yaXplZFwiKTtcbiAgICB9XG4gICAgdGhpcy5mYWxsYmFja1RpbWVyID0gc2V0VGltZW91dChmYWxsYmFjaywgZmFsbGJhY2tUaHJlc2hvbGQpO1xuICAgIGVycm9yUmVmID0gdGhpcy5vbkVycm9yKChyZWFzb24pID0+IHtcbiAgICAgIHRoaXMubG9nKFwidHJhbnNwb3J0XCIsIFwiZXJyb3JcIiwgcmVhc29uKTtcbiAgICAgIGlmIChwcmltYXJ5VHJhbnNwb3J0ICYmICFlc3RhYmxpc2hlZCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5mYWxsYmFja1RpbWVyKTtcbiAgICAgICAgZmFsbGJhY2socmVhc29uKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAodGhpcy5mYWxsYmFja1JlZikge1xuICAgICAgdGhpcy5vZmYoW3RoaXMuZmFsbGJhY2tSZWZdKTtcbiAgICB9XG4gICAgdGhpcy5mYWxsYmFja1JlZiA9IHRoaXMub25PcGVuKCgpID0+IHtcbiAgICAgIGVzdGFibGlzaGVkID0gdHJ1ZTtcbiAgICAgIGlmICghcHJpbWFyeVRyYW5zcG9ydCkge1xuICAgICAgICBsZXQgZmFsbGJhY2tUcmFuc3BvcnROYW1lMiA9IHRoaXMudHJhbnNwb3J0TmFtZShmYWxsYmFja1RyYW5zcG9ydCk7XG4gICAgICAgIGlmICghdGhpcy5wcmltYXJ5UGFzc2VkSGVhbHRoQ2hlY2spIHtcbiAgICAgICAgICB0aGlzLnN0b3JlU2Vzc2lvbihgcGh4OmZhbGxiYWNrOiR7ZmFsbGJhY2tUcmFuc3BvcnROYW1lMn1gLCBcInRydWVcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMubG9nKFwidHJhbnNwb3J0XCIsIGBlc3RhYmxpc2hlZCAke2ZhbGxiYWNrVHJhbnNwb3J0TmFtZTJ9IGZhbGxiYWNrYCk7XG4gICAgICB9XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5mYWxsYmFja1RpbWVyKTtcbiAgICAgIHRoaXMuZmFsbGJhY2tUaW1lciA9IHNldFRpbWVvdXQoZmFsbGJhY2ssIGZhbGxiYWNrVGhyZXNob2xkKTtcbiAgICAgIHRoaXMucGluZygocnR0KSA9PiB7XG4gICAgICAgI
1HRoaXMubG9nKFwidHJhbnNwb3J0XCIsIFwiY29ubmVjdGVkIHRvIHByaW1hcnkgYWZ0ZXJcIiwgcnR0KTtcbiAgICAgICAgdGhpcy5wcmltYXJ5UGFzc2VkSGVhbHRoQ2hlY2sgPSB0cnVlO1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5mYWxsYmFja1RpbWVyKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHRoaXMudHJhbnNwb3J0Q29ubmVjdCgpO1xuICB9XG4gIGNsZWFySGVhcnRiZWF0cygpIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5oZWFydGJlYXRUaW1lcik7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuaGVhcnRiZWF0VGltZW91dFRpbWVyKTtcbiAgfVxuICBvbkNvbm5PcGVuKCkge1xuICAgIGlmICh0aGlzLmhhc0xvZ2dlcigpKSB0aGlzLmxvZyhcInRyYW5zcG9ydFwiLCBgJHt0aGlzLnRyYW5zcG9ydE5hbWUodGhpcy50cmFuc3BvcnQpfSBjb25uZWN0ZWQgdG8gJHt0aGlzLmVuZFBvaW50VVJMKCl9YCk7XG4gICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gZmFsc2U7XG4gICAgdGhpcy5kaXNjb25uZWN0aW5nID0gZmFsc2U7XG4gICAgdGhpcy5lc3RhYmxpc2hlZENvbm5lY3Rpb25zKys7XG4gICAgdGhpcy5mbHVzaFNlbmRCdWZmZXIoKTtcbiAgICB0aGlzLnJlY29ubmVjdFRpbWVyLnJlc2V0KCk7XG4gICAgdGhpcy5yZXNldEhlYXJ0YmVhdCgpO1xuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3Mub3Blbi5mb3JFYWNoKChbLCBjYWxsYmFja10pID0+IGNhbGxiYWNrKCkpO1xuICB9XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgaGVhcnRiZWF0VGltZW91dCgpIHtcbiAgICBpZiAodGhpcy5wZW5kaW5nSGVhcnRiZWF0UmVmKSB7XG4gICAgICB0aGlzLnBlbmRpbmdIZWFydGJlYXRSZWYgPSBudWxsO1xuICAgICAgaWYgKHRoaXMuaGFzTG9nZ2VyKCkpIHtcbiAgICAgICAgdGhpcy5sb2coXCJ0cmFuc3BvcnRcIiwgXCJoZWFydGJlYXQgdGltZW91dC4gQXR0ZW1wdGluZyB0byByZS1lc3RhYmxpc2ggY29ubmVjdGlvblwiKTtcbiAgICAgIH1cbiAgICAgIHRoaXMudHJpZ2dlckNoYW5FcnJvcigpO1xuICAgICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gZmFsc2U7XG4gICAgICB0aGlzLnRlYXJkb3duKCgpID0+IHRoaXMucmVjb25uZWN0VGltZXIuc2NoZWR1bGVUaW1lb3V0KCksIFdTX0NMT1NFX05PUk1BTCwgXCJoZWFydGJlYXQgdGltZW91dFwiKTtcbiAgICB9XG4gIH1cbiAgcmVzZXRIZWFydGJlYXQoKSB7XG4gICAgaWYgKHRoaXMuY29ubiAmJiB0aGlzLmNvbm4uc2tpcEhlYXJ0YmVhdCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnBlbmRpbmdIZWFydGJlYXRSZWYgPSBudWxsO1xuICAgIHRoaXMuY2xlYXJIZWFydGJlYXRzKCk7XG4gICAgdGhpcy5oZWFydGJlYXRUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zZW5kSGVhcnRiZWF0KCksIHRoaXMuaGVhcnRiZWF0SW50ZXJ2YWxNcyk7XG4gIH1cbiAgdGVhcmRvd24oY2FsbGJhY2ssIGNvZGUsIHJlYXNvbikge1xuICAgIGlmICghdGhpcy5jb25uKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2sgJiYgY2FsbGJhY2soKTtcbiAgICB9XG4gICAgY29uc3QgY29ublRvQ2xvc2UgPSB0aGlzLmNvbm47XG4gICAgdGhpcy53YWl0Rm9yQnVmZmVyRG9uZShjb25uVG9DbG9zZSwgKCkgPT4ge1xuICAgICAgaWYgKGNvZGUpIHtcbiAgICAgICAgY29ublRvQ2xvc2UuY2xvc2UoY29kZSwgcmVhc29uIHx8IFwiXCIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29ublRvQ2xvc2UuY2xvc2UoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMud2FpdEZvclNvY2tldENsb3NlZChjb25uVG9DbG9zZSwgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5jb25uID09PSBjb25uVG9DbG9zZSkge1xuICAgICAgICAgIHRoaXMuY29ubi5vbm9wZW4gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICB9O1xuICAgICAgICAgIHRoaXMuY29ubi5vbmVycm9yID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgfTtcbiAgICAgICAgICB0aGlzLmNvbm4ub25tZXNzYWdlID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgfTtcbiAgICAgICAgICB0aGlzLmNvbm4ub25jbG9zZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIH07XG4gICAgICAgICAgdGhpcy5jb25uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgd2FpdEZvckJ1ZmZlckRvbmUoY29ubiwgY2FsbGJhY2ssIHRyaWVzID0gMSkge1xuICAgIGlmICh0cmllcyA9PT0gNSB8fCAhY29ubi5idWZmZXJlZEFtb3VudCkge1xuICAgICAgY2FsbGJhY2soKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLndhaXRGb3JCdWZmZXJEb25lKGNvbm4sIGNhbGxiYWNrLCB0cmllcyArIDEpO1xuICAgIH0sIDE1MCAqIHRyaWVzKTtcbiAgfVxuICB3YWl0Rm9yU29ja2V0Q2xvc2VkKGNvbm4sIGNhbGxiYWNrLCB0cmllcyA9IDEpIHtcbiAgICBpZiAodHJpZXMgPT09IDUgfHwgY29ubi5yZWFkeVN0YXRlID09PSBTT0NLRVRfU1R
1BVEVTLmNsb3NlZCkge1xuICAgICAgY2FsbGJhY2soKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLndhaXRGb3JTb2NrZXRDbG9zZWQoY29ubiwgY2FsbGJhY2ssIHRyaWVzICsgMSk7XG4gICAgfSwgMTUwICogdHJpZXMpO1xuICB9XG4gIG9uQ29ubkNsb3NlKGV2ZW50KSB7XG4gICAgaWYgKHRoaXMuY29ubikgdGhpcy5jb25uLm9uY2xvc2UgPSAoKSA9PiB7XG4gICAgfTtcbiAgICBsZXQgY2xvc2VDb2RlID0gZXZlbnQgJiYgZXZlbnQuY29kZTtcbiAgICBpZiAodGhpcy5oYXNMb2dnZXIoKSkgdGhpcy5sb2coXCJ0cmFuc3BvcnRcIiwgXCJjbG9zZVwiLCBldmVudCk7XG4gICAgdGhpcy50cmlnZ2VyQ2hhbkVycm9yKCk7XG4gICAgdGhpcy5jbGVhckhlYXJ0YmVhdHMoKTtcbiAgICBpZiAoIXRoaXMuY2xvc2VXYXNDbGVhbiAmJiBjbG9zZUNvZGUgIT09IDFlMykge1xuICAgICAgdGhpcy5yZWNvbm5lY3RUaW1lci5zY2hlZHVsZVRpbWVvdXQoKTtcbiAgICB9XG4gICAgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcy5jbG9zZS5mb3JFYWNoKChbLCBjYWxsYmFja10pID0+IGNhbGxiYWNrKGV2ZW50KSk7XG4gIH1cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBvbkNvbm5FcnJvcihlcnJvcikge1xuICAgIGlmICh0aGlzLmhhc0xvZ2dlcigpKSB0aGlzLmxvZyhcInRyYW5zcG9ydFwiLCBcImVycm9yXCIsIGVycm9yKTtcbiAgICBsZXQgdHJhbnNwb3J0QmVmb3JlID0gdGhpcy50cmFuc3BvcnQ7XG4gICAgbGV0IGVzdGFibGlzaGVkQmVmb3JlID0gdGhpcy5lc3RhYmxpc2hlZENvbm5lY3Rpb25zO1xuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3MuZXJyb3IuZm9yRWFjaCgoWywgY2FsbGJhY2tdKSA9PiB7XG4gICAgICBjYWxsYmFjayhlcnJvciwgdHJhbnNwb3J0QmVmb3JlLCBlc3RhYmxpc2hlZEJlZm9yZSk7XG4gICAgfSk7XG4gICAgaWYgKHRyYW5zcG9ydEJlZm9yZSA9PT0gdGhpcy50cmFuc3BvcnQgfHwgZXN0YWJsaXNoZWRCZWZvcmUgPiAwKSB7XG4gICAgICB0aGlzLnRyaWdnZXJDaGFuRXJyb3IoKTtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICB0cmlnZ2VyQ2hhbkVycm9yKCkge1xuICAgIHRoaXMuY2hhbm5lbHMuZm9yRWFjaCgoY2hhbm5lbCkgPT4ge1xuICAgICAgaWYgKCEoY2hhbm5lbC5pc0Vycm9yZWQoKSB8fCBjaGFubmVsLmlzTGVhdmluZygpIHx8IGNoYW5uZWwuaXNDbG9zZWQoKSkpIHtcbiAgICAgICAgY2hhbm5lbC50cmlnZ2VyKENIQU5ORUxfRVZFTlRTLmVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICAvKipcbiAgICogQHJldHVybnMge3N0cmluZ31cbiAgICovXG4gIGNvbm5lY3Rpb25TdGF0ZSgpIHtcbiAgICBzd2l0Y2ggKHRoaXMuY29ubiAmJiB0aGlzLmNvbm4ucmVhZHlTdGF0ZSkge1xuICAgICAgY2FzZSBTT0NLRVRfU1R
1BVEVTLmNvbm5lY3Rpbmc6XG4gICAgICAgIHJldHVybiBcImNvbm5lY3RpbmdcIjtcbiAgICAgIGNhc2UgU09DS0VUX1NUQVRFUy5vcGVuOlxuICAgICAgICByZXR1cm4gXCJvcGVuXCI7XG4gICAgICBjYXNlIFNPQ0tFVF9TVEFURVMuY2xvc2luZzpcbiAgICAgICAgcmV0dXJuIFwiY2xvc2luZ1wiO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIFwiY2xvc2VkXCI7XG4gICAgfVxuICB9XG4gIC8qKlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICovXG4gIGlzQ29ubmVjdGVkKCkge1xuICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb25TdGF0ZSgpID09PSBcIm9wZW5cIjtcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICpcbiAgICogQHBhcmFtIHtDaGFubmVsfVxuICAgKi9cbiAgcmVtb3ZlKGNoYW5uZWwpIHtcbiAgICB0aGlzLm9mZihjaGFubmVsLnN0YXRlQ2hhbmdlUmVmcyk7XG4gICAgdGhpcy5jaGFubmVscyA9IHRoaXMuY2hhbm5lbHMuZmlsdGVyKChjKSA9PiBjICE9PSBjaGFubmVsKTtcbiAgfVxuICAvKipcbiAgICogUmVtb3ZlcyBgb25PcGVuYCwgYG9uQ2xvc2VgLCBgb25FcnJvcixgIGFuZCBgb25NZXNzYWdlYCByZWdpc3RyYXRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0ge3JlZnN9IC0gbGlzdCBvZiByZWZzIHJldHVybmVkIGJ5IGNhbGxzIHRvXG4gICAqICAgICAgICAgICAgICAgICBgb25PcGVuYCwgYG9uQ2xvc2VgLCBgb25FcnJvcixgIGFuZCBgb25NZXNzYWdlYFxuICAgKi9cbiAgb2ZmKHJlZnMpIHtcbiAgICBmb3IgKGxldCBrZXkgaW4gdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcykge1xuICAgICAgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrc1trZXldID0gdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrc1trZXldLmZpbHRlcigoW3JlZl0pID0+IHtcbiAgICAgICAgcmV0dXJuIHJlZnMuaW5kZXhPZihyZWYpID09PSAtMTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICAvKipcbiAgICogSW5pdGlhdGVzIGEgbmV3IGNoYW5uZWwgZm9yIHRoZSBnaXZlbiB0b3BpY1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9waWNcbiAgICogQHBhcmFtIHtPYmplY3R9IGNoYW5QYXJhbXMgLSBQYXJhbWV0ZXJzIGZvciB0aGUgY2hhbm5lbFxuICAgKiBAcmV0dXJucyB7Q2hhbm5lbH1cbiAgICovXG4gIGNoYW5uZWwodG9waWMsIGNoYW5QYXJhbXMgPSB7fSkge1xuICAgIGxldCBjaGFuID0gbmV3IENoYW5uZWwodG9waWMsIGNoYW5QYXJhbXMsIHRoaXMpO1xuICAgIHRoaXMuY2hhbm5lbHMucHVzaChjaGFuKTtcbiAgICByZXR1cm4gY2hhbjtcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGFcbiAgICovXG4gIHB1c2goZGF0YSkge1xuICAgIGlmICh0aGlzLmhhc0xvZ2dlcigpKSB7XG4gICAgICBsZXQgeyB0b3BpYywgZXZlbnQsIHBheWxvYWQsIHJlZiwgam9pbl9yZWYgfSA9IGRhdGE7XG4gICAgICB0aGlzLmxvZyhcInB1c2hcIiwgYCR7dG9waWN9ICR7ZXZlbnR9ICgke2pvaW5fcmVmfSwgJHtyZWZ9KWAsIHBheWxvYWQpO1xuICAgIH1cbiAgICBpZiAodGhpcy5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICB0aGlzLmVuY29kZShkYXRhLCAocmVzdWx0KSA9PiB0aGlzLmNvbm4uc2VuZChyZXN1bHQpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZW5kQnVmZmVyLnB1c2goKCkgPT4gdGhpcy5lbmNvZGUoZGF0YSwgKHJlc3VsdCkgPT4gdGhpcy5jb25uLnNlbmQocmVzdWx0KSkpO1xuICAgIH1cbiAgfVxuICAvKipcbiAgICogUmV0dXJuIHRoZSBuZXh0IG1lc3NhZ2UgcmVmLCBhY2NvdW50aW5nIGZvciBvdmVyZmxvd3NcbiAgICogQHJldHVybnMge3N0cmluZ31cbiAgICovXG4gIG1ha2VSZWYoKSB7XG4gICAgbGV0IG5ld1JlZiA9IHRoaXMucmVmICsgMTtcbiAgICBpZiAobmV3UmVmID09PSB0aGlzLnJlZikge1xuICAgICAgdGhpcy5yZWYgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlZiA9IG5ld1JlZjtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucmVmLnRvU3RyaW5nKCk7XG4gIH1cbiAgc2VuZEhlYXJ0YmVhdCgpIHtcbiAgICBpZiAodGhpcy5wZW5kaW5nSGVhcnRiZWF0UmVmICYmICF0aGlzLmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5wZW5kaW5nSGVhcnRiZWF0UmVmID0gdGhpcy5tYWtlUmVmKCk7XG4gICAgdGhpcy5wdXNoKHsgdG9waWM6IFwicGhvZW5peFwiLCBldmVudDogXCJoZWFydGJlYXRcIiwgcGF5bG9hZDoge30sIHJlZjogdGhpcy5wZW5kaW5nSGVhcnRiZWF0UmVmIH0pO1xuICAgIHRoaXMuaGVhcnRiZWF0VGltZW91dFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB0aGlzLmhlYXJ0YmVhdFRpbWVvdXQoKSwgdGhpcy5oZWFydGJlYXRJbnRlcnZhbE1zKTtcbiAgfVxuICBmbHVzaFNlbmRCdWZmZXIoKSB7XG4gICAgaWYgKHRoaXMuaXNDb25uZWN0ZWQoKSAmJiB0aGlzLnNlbmRCdWZmZXIubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5zZW5kQnVmZmVyLmZvckVhY2goKGNhbGxiYWNrKSA9PiBjYWxsYmFjaygpKTtcbiAgICAgIHRoaXMuc2VuZEJ1ZmZlciA9IFtdO1xuICAgIH1cbiAgfVxuICBvbkNvbm5NZXNzYWdlKHJhd01lc3NhZ2UpIHtcbiAgICB0aGlzLmRlY29kZShyYXdNZXNzYWdlLmRhdGEsIChtc2cpID0+IHtcbiAgICAgIGxldCB7IHRvcGljLCBldmVudCwgcGF5bG9hZCwgcmVmLCBqb2luX3JlZiB9ID0gbXNnO1xuICAgICAgaWYgKHJlZiAmJiByZWYgPT09IHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZikge1xuICAgICAgICB0aGlzLmNsZWFySGVhcnRiZWF0cygpO1xuICAgICAgICB0aGlzLnBlbmRpbmdIZWFydGJlYXRSZWYgPSBudWxsO1xuICAgICAgICB0aGlzLmhlYXJ0YmVhdFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB0aGlzLnNlbmRIZWFydGJlYXQoKSwgdGhpcy5oZWFydGJlYXRJbnRlcnZhbE1zKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmhhc0xvZ2dlcigpKSB0aGlzLmxvZyhcInJlY2VpdmVcIiwgYCR7cGF5bG9hZC5zdGF0dXMgfHwgXCJcIn0gJHt0b3BpY30gJHtldmVudH0gJHtyZWYgJiYgXCIoXCIgKyByZWYgKyBcIilcIiB8fCBcIlwifWAsIHBheWxvYWQpO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmNoYW5uZWxzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGNoYW5uZWwgPSB0aGlzLmNoYW5uZWxzW2ldO1xuICAgICAgICBpZiAoIWNoYW5uZWwuaXNNZW1iZXIodG9waWMsIGV2ZW50LCBwYXlsb2FkLCBqb2luX3JlZikpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjaGFubmVsLnRyaWdnZXIoZXZlbnQsIHBheWxvYWQsIHJlZiwgam9pbl9yZWYpO1xuICAgICAgfVxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzLm1lc3NhZ2UubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IFssIGNhbGxiYWNrXSA9IHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3MubWVzc2FnZVtpXTtcbiAgICAgICAgY2FsbGJhY2sobXNnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICBsZWF2ZU9wZW5Ub3BpYyh0b3BpYykge1xuICAgIGxldCBkdXBDaGFubmVsID0gdGhpcy5jaGFubmVscy5maW5kKChjKSA9PiBjLnRvcGljID09PSB0b3BpYyAmJiAoYy5pc0pvaW5lZCgpIHx8IGMuaXNKb2luaW5nKCkpKTtcbiAgICBpZiAoZHVwQ2hhbm5lbCkge1xuICAgICAgaWYgKHRoaXMuaGFzTG9nZ2VyKCkpIHRoaXMubG9nKFwidHJhbnNwb3J0XCIsIGBsZWF2aW5nIGR1cGxpY2F0ZSB0b3BpYyBcIiR7dG9waWN9XCJgKTtcbiAgICAgIGR1cENoYW5uZWwubGVhdmUoKTtcbiAgICB9XG4gI
1H1cbn07XG5leHBvcnQge1xuICBDaGFubmVsLFxuICBMb25nUG9sbCxcbiAgUHJlc2VuY2UsXG4gIHNlcmlhbGl6ZXJfZGVmYXVsdCBhcyBTZXJpYWxpemVyLFxuICBTb2NrZXRcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1waG9lbml4Lm1qcy5tYXBcbiIsIi8vIGpzL3Bob2VuaXhfbGl2ZV92aWV3L2NvbnN0YW50cy50c1xudmFyIENPTlNFQ1VUSVZFX1JFTE9BRFMgPSBcImNvbnNlY3V0aXZlLXJlbG9hZHNcIjtcbnZhciBNQVhfUkVMT0FEUyA9IDEwO1xudmFyIFJFTE9BRF9KSVRURVJfTUlOID0gNWUzO1xudmFyIFJFTE9BRF9KSVRURVJfTUFYID0gMWU0O1xudmFyIEZBSUxTQUZFX0pJVFRFUiA9IDNlNDtcbnZhciBQSFhfRVZFTlRfQ0xBU1NFUyA9IFtcbiAgXCJwaHgtY2xpY2stbG9hZGluZ1wiLFxuICBcInBoeC1jaGFuZ2UtbG9hZGluZ1wiLFxuICBcInBoeC1zdWJtaXQtbG9hZGluZ1wiLFxuICBcInBoeC1rZXlkb3duLWxvYWRpbmdcIixcbiAgXCJwaHgta2V5dXAtbG9hZGluZ1wiLFxuICBcInBoeC1ibHVyLWxvYWRpbmdcIixcbiAgXCJwaHgtZm9jdXMtbG9hZGluZ1wiLFxuICBcInBoeC1ob29rLWxvYWRpbmdcIlxuXTtcbnZhciBQSFhfRFJPUF9UQVJHRVRfQUNUSVZFX0NMQVNTID0gXCJwaHgtZHJvcC10YXJnZXQtYWN0aXZlXCI7XG52YXIgUEhYX0NPTVBPTkVOVCA9IFwiZGF0YS1waHgtY29tcG9uZW50XCI7XG52YXIgUEhYX1ZJRVdfUkVGID0gXCJkYXRhLXBoeC12aWV3XCI7XG52YXIgUEhYX0xJVkVfTElOSyA9IFwiZGF0YS1waHgtbGlua1wiO1xudmFyIFBIWF9UUkFDS19TVEFUSUMgPSBcInRyYWNrLXN0YXRpY1wiO1xudmFyIFBIWF9MSU5LX1NUQVRFID0gXCJkYXRhLXBoeC1saW5rLXN0YXRlXCI7XG52YXIgUEhYX1JFRl9MT0FESU5HID0gXCJkYXRhLXBoeC1yZWYtbG9hZGluZ1wiO1xudmFyIFBIWF9SRUZfU1JDID0gXCJkYXRhLXBoeC1yZWYtc3JjXCI7XG52YXIgUEhYX1JFRl9MT0NLID0gXCJkYXRhLXBoeC1yZWYtbG9ja1wiO1xudmFyIFBIWF9QRU5ESU5HX1JFRlMgPSBcInBoeC1wZW5kaW5nLXJlZnNcIjtcbnZhciBQSFhfVFJBQ0tfVVBMT0FEUyA9IFwidHJhY2stdXBsb2Fkc1wiO1xudmFyIFBIWF9VUExPQURfUkVGID0gXCJkYXRhLXBoeC11cGxvYWQtcmVmXCI7XG52YXIgUEhYX1BSRUZMSUdIVEVEX1JFRlMgPSBcImRhdGEtcGh4LXByZWZsaWdodGVkLXJlZnNcIjtcbnZhciBQSFhfRE9ORV9SRUZTID0gXCJkYXRhLXBoeC1kb25lLXJlZnNcIjtcbnZhciBQSFhfRFJPUF9UQVJHRVQgPSBcImRyb3AtdGFyZ2V0XCI7XG52YXIgUEhYX0FDVElWRV9FTlRSWV9SRUZTID0gXCJkYXRhLXBoeC1hY3RpdmUtcmVmc1wiO1xudmFyIFBIWF9MSVZFX0ZJTEVfVVBEQVRFRCA9IFwicGh4OmxpdmUtZmlsZTp1cGRhdGVkXCI7XG52YXIgUEhYX1NLSVAgPSBcImRhdGEtcGh4LXNraXBcIjtcbnZhciBQSFhfTUFHSUNfSUQgPSBcImRhdGEtcGh4LWlkXCI7XG52YXIgUEhYX1BSVU5FID0gXCJkYXRhLXBoeC1wcnVuZVwiO1xudmFyIFBIWF9DT05ORUNURURfQ0xBU1MgPSBcInBoeC1jb25uZWN0ZWRcIjtcbnZhciBQSFhfTE9BRElOR19DTEFTUyA9IFwicGh4LWxvYWRpbmdcIjtcbnZhciBQSFhfRVJST1JfQ0xBU1MgPSBcInBoeC1lcnJvclwiO1xudmFyIFBIWF9DTElFTlRfRVJST1JfQ0xBU1MgPSBcInBoeC1jbGllbnQtZXJyb3JcIjtcbnZhciBQSFhfU0VSVkVSX0VSUk9SX0NMQVNTID0gXCJwaHgtc2VydmVyLWVycm9yXCI7XG52YXIgUEhYX1BBUkVOVF9JRCA9IFwiZGF0YS1waHgtcGFyZW50LWlkXCI7XG52YXIgUEhYX01BSU4gPSBcImRhdGEtcGh4LW1haW5cIjtcbnZhciBQSFhfUk9PVF9JRCA9IFwiZGF0YS1waHgtcm9vdC1pZFwiO1xudmFyIFBIWF9WSUVXUE9SVF9UT1AgPSBcInZpZXdwb3J0LXRvcFwiO1xudmFyIFBIWF9WSUVXUE9SVF9CT1RUT00gPSBcInZpZXdwb3J0LWJvdHRvbVwiO1xudmFyIFBIWF9WSUVXUE9SVF9PVkVSUlVOX1RBUkdFVCA9IFwidmlld3BvcnQtb3ZlcnJ1bi10YXJnZXRcIjtcbnZhciBQSFhfVFJJR0dFUl9BQ1RJT04gPSBcInRyaWdnZXItYWN0aW9uXCI7XG52YXIgUEhYX0hBU19GT0NVU0VEID0gXCJwaHgtaGFzLWZvY3VzZWRcIjtcbnZhciBGT0NVU0FCTEVfSU5QVVRTID0gW1xuICBcInRleHRcIixcbiAgXCJ0ZXh0YXJlYVwiLFxuICBcIm51bWJlclwiLFxuICBcImVtYWlsXCIsXG4gIFwicGFzc3dvcmRcIixcbiAgXCJzZWFyY2hcIixcbiAgXCJ0ZWxcIixcbiAgXCJ1cmxcIixcbiAgXCJkYXRlXCIsXG4gIFwidGltZVwiLFxuICBcImRhdGV0aW1lLWxvY2FsXCIsXG4gIFwiY29sb3JcIixcbiAgXCJyYW5nZVwiXG5dO1xudmFyIENIRUNLQUJMRV9JTlBVVFMgPSBbXCJjaGVja2JveFwiLCBcInJhZGlvXCJdO1xudmFyIFBIWF9IQVNfU1VCTUlUVEVEID0gXCJwaHgtaGFzLXN1Ym1pdHRlZFwiO1xudmFyIFBIWF9TRVNTSU9OID0gXCJkYXRhLXBoeC1zZXNzaW9uXCI7XG52YXIgUEhYX1ZJRVdfU0VMRUNUT1IgPSBgWyR7UEhYX1NFU1NJT059XWA7XG52YXIgUEhYX1NUSUNLWSA9IFwiZGF0YS1waHgtc3RpY2t5XCI7XG52YXIgUEhYX1NUQVRJQyA9IFwiZGF0YS1waHgtc3RhdGljXCI7XG52YXIgUEhYX1JFQURPTkxZID0gXCJkYXRhLXBoeC1yZWFkb25seVwiO1xudmFyIFBIWF9ESVNBQkxFRCA9IFwiZGF0YS1waHgtZGlzYWJsZWRcIjtcbnZhciBQSFhfRElTQUJMRV9XSVRIID0gXCJkaXNhYmxlLXdpdGhcIjtcbnZhciBQSFhfRElTQUJMRV9XSVRIX1JFU1RPUkUgPSBcImRhdGEtcGh4LWRpc2FibGUtd2l0aC1yZXN0b3JlXCI7XG52YXIgUEhYX0hPT0sgPSBcImhvb2tcIjtcbnZhciBQSFhfREVCT1VOQ0UgPSBcImRlYm91bmNlXCI7XG52YXIgUEhYX1RIUk9UVExFID0gXCJ0aHJvdHRsZVwiO1xudmFyIFBIWF9VUERBVEUgPSBcInVwZGF0ZVwiO1xudmFyIFBIWF9TVFJFQU0gPSBcInN0cmVhbVwiO1xudmFyIFBIWF9TVFJFQU1fUkVGID0gXCJkYXRhLXBoeC1zdHJlYW1cIjtcbnZhciBQSFhfUE9SVEFMID0gXCJkYXRhLXBoeC1wb3J0YWxcIjtcbnZhciBQSFhfVEVMRVBPUlRFRF9SRUYgPSBcImRhdGEtcGh4LXRlbGVwb3J0ZWRcIjtcbnZhciBQSFhfVEVMRVBPUlRFRF9TUkMgPSBcImRhdGEtcGh4LXRlbGVwb3J0ZWQtc3JjXCI7XG52YXIgUEhYX1JVTlRJTUVfSE9PSyA9IFwiZGF0YS1waHgtcnVudGltZS1ob29rXCI7XG52YXIgUEhYX0xWX1BJRCA9IFwiZGF0YS1waHgtcGlkXCI7XG52YXIgUEhYX0tFWSA9IFwia2V5XCI7XG52YXIgUEhYX1BSSVZBVEUgPSBcInBoeFByaXZhdGVcIjtcbnZhciBQSFhfQVVUT19SRUNPVkVSID0gXCJhdXRvLXJlY292ZXJcIjtcbnZhciBQSFhfTk9fVU5VU0VEX0ZJRUxEID0gXCJuby11bnVzZWQtZmllbGRcIjtcbnZhciBQSFhfTFZfREVCVUcgPSBcInBoeDpsaXZlLXNvY2tldDpkZWJ1Z1wiO1xudmFyIFBIWF9MVl9QUk9GSUxFID0gXCJwaHg6bGl2ZS1zb2NrZXQ6cHJvZmlsaW5nXCI7XG52YXIgUEhYX0xWX0xBVEVOQ1lfU0lNID0gXCJwaHg6bGl2ZS1zb2NrZXQ6bGF0ZW5jeS1zaW1cIjtcbnZhciBQSFhfTFZfSElTVE9SWV9QT1NJVElPTiA9IFwicGh4Om5hdi1oaXN0b3J5LXBvc2l0aW9uXCI7XG52YXIgUEhYX1BST0dSRVNTID0gXCJwcm9ncmVzc1wiO1xudmFyIFBIWF9NT1VOVEVEID0gXCJtb3VudGVkXCI7XG52YXIgUEhYX1JFTE9BRF9TVEFUVVMgPSBcIl9fcGhvZW5peF9yZWxvYWRfc3RhdHVzX19cIjtcbnZhciBMT0FERVJfVElNRU9VVCA9IDE7XG52YXIgTUFYX0NISUxEX0pPSU5fQVRURU1QVFMgPSAzO1xudmFyIEJFRk9S
1RV9VTkxPQURfTE9BREVSX1RJTUVPVVQgPSAyMDA7XG52YXIgRElTQ09OTkVDVEVEX1RJTUVPVVQgPSA1MDA7XG52YXIgQklORElOR19QUkVGSVggPSBcInBoeC1cIjtcbnZhciBQVVNIX1RJTUVPVVQgPSAzZTQ7XG52YXIgREVCT1VOQ0VfVFJJR0dFUiA9IFwiZGVib3VuY2UtdHJpZ2dlclwiO1xudmFyIFRIUk9UVExFRCA9IFwidGhyb3R0bGVkXCI7XG52YXIgREVCT1VOQ0VfUFJFVl9LRVkgPSBcImRlYm91bmNlLXByZXYta2V5XCI7XG52YXIgREVGQVVMVFMgPSB7XG4gIGRlYm91bmNlOiAzMDAsXG4gIHRocm90dGxlOiAzMDBcbn07XG52YXIgUEhYX1BFTkRJTkdfQVRUUlMgPSBbUEhYX1JFRl9MT0FESU5HLCBQSFhfUkVGX1NSQywgUEhYX1JFRl9MT0NLXTtcbnZhciBTVEFUSUMgPSBcInNcIjtcbnZhciBST09UID0gXCJyXCI7XG52YXIgQ09NUE9ORU5UUyA9IFwiY1wiO1xudmFyIEtFWUVEID0gXCJrXCI7XG52YXIgS0VZRURfQ09VTlQgPSBcImtjXCI7XG52YXIgRVZFTlRTID0gXCJlXCI7XG52YXIgUkVQTFkgPSBcInJcIjtcbnZhciBUSVRMRSA9IFwidFwiO1xudmFyIFRFTVBMQVRFUyA9IFwicFwiO1xudmFyIFNUUkVBTSA9IFwic3RyZWFtXCI7XG5cbi8vIGpzL3Bob2VuaXhfbGl2ZV92aWV3L2VudHJ5X3VwbG9hZGVyLmpzXG52YXIgRW50cnlVcGxvYWRlciA9IGNsYXNzIHtcbiAgY29uc3RydWN0b3IoZW50cnksIGNvbmZpZywgbGl2ZVNvY2tldCkge1xuICAgIGNvbnN0IHsgY2h1bmtfc2l6ZSwgY2h1bmtfdGltZW91dCB9ID0gY29uZmlnO1xuICAgIHRoaXMubGl2ZVNvY2tldCA9IGxpdmVTb2NrZXQ7XG4gICAgdGhpcy5lbnRyeSA9IGVudHJ5O1xuICAgIHRoaXMub2Zmc2V0ID0gMDtcbiAgICB0aGlzLmNodW5rU2l6ZSA9IGNodW5rX3NpemU7XG4gICAgdGhpcy5jaHVua1RpbWVvdXQgPSBjaHVua190aW1lb3V0O1xuICAgIHRoaXMuY2h1bmtUaW1lciA9IG51bGw7XG4gICAgdGhpcy5lcnJvcmVkID0gZmFsc2U7XG4gICAgdGhpcy51cGxvYWRDaGFubmVsID0gbGl2ZVNvY2tldC5jaGFubmVsKGBsdnU6JHtlbnRyeS5yZWZ9YCwge1xuICAgICAgdG9rZW46IGVudHJ5Lm1ldGFkYXRhKClcbiAgICB9KTtcbiAgfVxuICBlcnJvcihyZWFzb24pIHtcbiAgICBpZiAodGhpcy5lcnJvcmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMudXBsb2FkQ2hhbm5lbC5sZWF2ZSgpO1xuICAgIHRoaXMuZXJyb3JlZCA9IHRydWU7XG4gICAgdGhpcy5jaHVua1RpbWVyICE9IG51bGwgJiYgY2xlYXJUaW1lb3V0KHRoaXMuY2h1bmtUaW1lcik7XG4gICAgdGhpcy5lbnRyeS5lcnJvcihyZWFzb24pO1xuICB9XG4gIHVwbG9hZCgpIHtcbiAgICB0aGlzLnVwbG9hZENoYW5uZWwub25FcnJvcigocmVhc29uKSA9PiB0aGlzLmVycm9yKHJlYXNvbikpO1xuICAgIHRoaXMudXBsb2FkQ2hhbm5lbC5qb2luKCkucmVjZWl2ZShcIm9rXCIsIChfZGF0YSkgPT4gdGhpcy5yZWFkTmV4dENodW5rKCkpLnJlY2VpdmUoXCJlcnJvclwiLCAoeyByZWFzb24gfSkgPT4gdGhpcy5lcnJvcihyZWFzb24pKTtcbiAgfVxuICBpc0RvbmUoKSB7XG4gICAgcmV0dXJuIHRoaXMub2Zmc2V0ID49IHRoaXMuZW50cnkuZmlsZS5zaXplO1xuICB9XG4gIHJlYWROZXh0Q2h1bmsoKSB7XG4gICAgY29uc3QgcmVhZGVyID0gbmV3IHdpbmRvdy5GaWxlUmVhZGVyKCk7XG4gICAgY29uc3QgYmxvYiA9IHRoaXMuZW50cnkuZmlsZS5zbGljZShcbiAgICAgIHRoaXMub2Zmc2V0LFxuICAgICAgdGhpcy5jaHVua1NpemUgKyB0aGlzLm9mZnNldFxuICAgICk7XG4gICAgcmVhZGVyLm9ubG9hZCA9IChlKSA9PiB7XG4gICAgICBpZiAoZS50YXJnZXQ/LmVycm9yID09PSBudWxsKSB7XG4gICAgICAgIHRoaXMub2Zmc2V0ICs9IC8qKiBAdHlwZSB7QXJyYXlCdWZmZXJ9ICovXG4gICAgICAgIGUudGFyZ2V0LnJlc3VsdC5ieXRlTGVuZ3RoO1xuICAgICAgICB0aGlzLnB1c2hDaHVuayhcbiAgICAgICAgICAvKiogQHR5cGUge0FycmF5QnVmZmVyfSAqL1xuICAgICAgICAgIGUudGFyZ2V0LnJlc3VsdFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGxvZ0Vycm9yKFwiUmVhZCBlcnJvcjogXCIgKyBlLnRhcmdldD8uZXJyb3IpO1xuICAgICAgfVxuICAgIH07XG4gICAgcmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKGJsb2IpO1xuICB9XG4gIHB1c2hDaHVuayhjaHVuaykge1xuICAgIGlmICghdGhpcy51cGxvYWRDaGFubmVsLmlzSm9pbmVkKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy51cGxvYWRDaGFubmVsLnB1c2goXCJjaHVua1wiLCBjaHVuaywgdGhpcy5jaHVua1RpbWVvdXQpLnJlY2VpdmUoXCJva1wiLCAoKSA9PiB7XG4gICAgICB0aGlzLmVudHJ5LnByb2dyZXNzKHRoaXMub2Zmc2V0IC8gdGhpcy5lbnRyeS5maWxlLnNpemUgKiAxMDApO1xuICAgICAgaWYgKCF0aGlzLmlzRG9uZSgpKSB7XG4gICAgICAgIHRoaXMuY2h1bmtUaW1lciA9IHNldFRpbWVvdXQoXG4gICAgICAgICAgKCkgPT4gdGhpcy5yZWFkTmV4dENodW5rKCksXG4gICAgICAgICAgdGhpcy5saXZlU29ja2V0LmdldExhdGVuY3lTaW0oKSB8fCAwXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSkucmVjZWl2ZShcImVycm9yXCIsICh7IHJlYXNvbiB9KSA9PiB0aGlzLmVycm9yKHJlYXNvbikpO1xuICB9XG59O1xuXG4vLyBqcy9waG9lbml4X2xpdmVfdmlldy91dGlscy50c1xudmFyIGxvZ0Vycm9yID0gKG1zZywgb2JqKSA9PiBjb25zb2xlLmVycm9yICYmIGNvbnNvbGUuZXJyb3IobXNnLCBvYmopO1xudmFyIGVuc3VyZVNhbWVPcmlnaW4gPSAoaHJlZiwga2luZCkgPT4ge1xuICBsZXQgdXJsO1xuICB0cnkge1xuICAgIHVybCA9IG5ldyBVUkwoaHJlZiwgd2luZG93LmxvY2F0aW9uLmhyZWYpO1xuICB9IGNhdGNoIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgZXhwZWN0ZWQgJHtraW5kfSBkZXN0aW5hdGlvbiB0byBiZSBhIHZhbGlkIFVSTCwgZ290OiAke2hyZWZ9YFxuICAgICk7XG4gIH1cbiAgaWYgKHVybC5vcmlnaW4gIT09IHdpbmRvdy5sb2NhdGlvbi5vcmlnaW4pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgY2Fubm90ICR7a2luZH0gdG8gXCIke2hyZWZ9XCIgYmVjYXVzZSBpdHMgb3JpZ2luIGRvZXMgbm90IG1hdGNoIHRoZSBjdXJyZW50IG9yaWdpbiBcIiR7d2luZG93LmxvY2F0aW9uLm9yaWdpbn1cIi4gVXNlIHdpbmRvdy5sb2NhdGlvbiBkaXJlY3RseSBmb3IgY3Jvc3Mtb3JpZ2luIG5hdmlnYXRpb24uYFxuICAgICk7XG4gIH1cbn07XG52YXIgaXNDaWQgPSAoY2lkKSA9PiB7XG4gIGNvbnN0IHR5cGUgPSB0eXBlb2YgY2lkO1xuICByZXR1cm4gdHlwZSA9PT0gXCJudW1iZXJcIiB8fCB0eXBlID09PSBcInN0cmluZ1wiICYmIC9eKDB8WzEtOV1cXGQqKSQvLnRlc3QoY2lkKTtcbn07XG5mdW5jdGlvbiBkZXRlY3REdXBsaWNhdGVJZHMoKSB7XG4gIGNvbnN0IGlkcyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCk7XG4gIGNvbnN0IGVsZW1zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIipbaWRdXCIpO1xuICBmb3IgKGxldCBpID0gMCwgbGVuID0gZWxlbXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBpZiAoaWRzLmhhcyhlbGVtc1tpXS5pZCkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgIGBNdWx0aXBsZSBJRHMgZGV0ZWN0ZWQ6ICR7ZWxlbXNbaV0uaWR9LiBFbnN1cmUgdW5pcXVlIGVsZW1lbnQgaWRzLmBcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGl
1kcy5hZGQoZWxlbXNbaV0uaWQpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gZGV0ZWN0SW52YWxpZFN0cmVhbUluc2VydHMoaW5zZXJ0cykge1xuICBjb25zdCBlcnJvcnMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpO1xuICBPYmplY3Qua2V5cyhpbnNlcnRzKS5mb3JFYWNoKChpZCkgPT4ge1xuICAgIGNvbnN0IHN0cmVhbUVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICAgIGlmIChzdHJlYW1FbCAmJiBzdHJlYW1FbC5wYXJlbnRFbGVtZW50ICYmIHN0cmVhbUVsLnBhcmVudEVsZW1lbnQuZ2V0QXR0cmlidXRlKFwicGh4LXVwZGF0ZVwiKSAhPT0gXCJzdHJlYW1cIikge1xuICAgICAgZXJyb3JzLmFkZChcbiAgICAgICAgYFRoZSBzdHJlYW0gY29udGFpbmVyIHdpdGggaWQgXCIke3N0cmVhbUVsLnBhcmVudEVsZW1lbnQuaWR9XCIgaXMgbWlzc2luZyB0aGUgcGh4LXVwZGF0ZT1cInN0cmVhbVwiIGF0dHJpYnV0ZS4gRW5zdXJlIGl0IGlzIHNldCBmb3Igc3RyZWFtcyB0byB3b3JrIHByb3Blcmx5LmBcbiAgICAgICk7XG4gICAgfVxuICB9KTtcbiAgZXJyb3JzLmZvckVhY2goKGVycm9yKSA9PiBjb25zb2xlLmVycm9yKGVycm9yKSk7XG59XG52YXIgZGVidWcgPSAodmlldywga2luZCwgbXNnLCBvYmopID0+IHtcbiAgaWYgKHZpZXcubGl2ZVNvY2tldC5pc0RlYnVnRW5hYmxlZCgpKSB7XG4gICAgY29uc29sZS5sb2coYCR7dmlldy5pZH0gJHtraW5kfTogJHttc2d9IC0gYCwgb2JqKTtcbiAgfVxufTtcbnZhciBjbG9zdXJlID0gKHZhbCkgPT4gdHlwZW9mIHZhbCA9PT0gXCJmdW5jdGlvblwiID8gdmFsIDogZnVuY3Rpb24oKSB7XG4gIHJldHVybiB2YWw7XG59O1xudmFyIGNsb25lID0gKG9iaikgPT4ge1xuICByZXR1cm4gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShvYmopKTtcbn07XG52YXIgY2xvc2VzdFBoeEJpbmRpbmcgPSAoc3RhcnRFbCwgYmluZGluZywgYm9yZGVyRWwpID0+IHtcbiAgbGV0IGVsID0gc3RhcnRFbDtcbiAgZG8ge1xuICAgIGlmIChlbC5tYXRjaGVzKGBbJHtiaW5kaW5nfV1gKSAmJiAhKFwiZGlzYWJsZWRcIiBpbiBlbCAmJiBlbC5kaXNhYmxlZCkpIHtcbiAgICAgIHJldHVybiBlbDtcbiAgICB9XG4gICAgZWwgPSBlbC5wYXJlbnRFbGVtZW50O1xuICB9IHdoaWxlIChlbCAhPT0gbnVsbCAmJiBlbC5ub2RlVHlwZSA9PT0gMSAmJiAhKGJvcmRlckVsICYmIGJvcmRlckVsLmlzU2FtZU5vZGUoZWwpIHx8IGVsLm1hdGNoZXMoUEhYX1ZJRVdfU0VMRUNUT1IpKSk7XG4gIHJldHVybiBudWxsO1xufTtcbnZhciBpc09iamVjdCA9IChvYmopID0+IHtcbiAgcmV0dXJuIG9iaiAhPT0gbnVsbCAmJiB0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiICYmICEob2JqIGluc3RhbmNlb2YgQXJyYXkpO1xufTtcbnZhciBpc0VxdWFsT2JqID0gKG9iajEsIG9iajIpID0+IEpTT04uc3RyaW5naWZ5KG9iajEpID09PSBKU09OLnN0cmluZ2lmeShvYmoyKTtcbnZhciBpc0VtcHR5ID0gKG9iaikgPT4ge1xuICBmb3IgKGNvbnN0IHggaW4gb2JqKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufTtcbnZhciBtYXliZSA9IChlbCwgY2FsbGJhY2spID0+IGVsICYmIGNhbGxiYWNrKGVsKTtcbnZhciBjaGFubmVsVXBsb2FkZXIgPSBmdW5jdGlvbihlbnRyaWVzLCBvbkVycm9yLCByZXNwLCBsaXZlU29ja2V0KSB7XG4gIGVudHJpZXMuZm9yRWFjaCgoZW50cnkpID0+IHtcbiAgICBjb25zdCBlbnRyeVVwbG9hZGVyID0gbmV3IEVudHJ5VXBsb2FkZXIoZW50cnksIHJlc3AuY29uZmlnLCBsaXZlU29ja2V0KTtcbiAgICBlbnRyeVVwbG9hZGVyLnVwbG9hZCgpO1xuICB9KTtcbn07XG52YXIgZXZlbnRDb250YWluc0ZpbGVzID0gKGUpID0+IHtcbiAgaWYgKGUuZGF0YVRyYW5zZmVyLnR5cGVzKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlLmRhdGFUcmFuc2Zlci50eXBlcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGUuZGF0YVRyYW5zZmVyLnR5cGVzW2ldID09PSBcIkZpbGVzXCIpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn07XG5cbi8vIGpzL3Bob2VuaXhfbGl2ZV92aWV3L2Jyb3dzZXIudHNcbnZhciBCcm93c2VyID0ge1xuICBjYW5QdXNoU3RhdGUoKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBoaXN0b3J5LnB1c2hTdGF0ZSAhPT0gXCJ1bmRlZmluZWRcIjtcbiAgfSxcbiAgZHJvcExvY2FsKGxvY2FsU3RvcmFnZSwgbmFtZXNwYWNlLCBzdWJrZXkpIHtcbiAgICByZXR1cm4gbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0odGhpcy5sb2NhbEtleShuYW1lc3BhY2UsIHN1YmtleSkpO1xuICB9LFxuICB1cGRhdGVMb2NhbChsb2NhbFN0b3JhZ2UsIG5hbWVzcGFjZSwgc3Via2V5LCBpbml0aWFsLCBmdW5jKSB7XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMuZ2V0TG9jYWwobG9jYWxTdG9yYWdlLCBuYW1lc3BhY2UsIHN1YmtleSk7XG4gICAgY29uc3Qga2V5ID0gdGhpcy5sb2NhbEtleShuYW1lc3BhY2UsIHN1YmtleSk7XG4gICAgY29uc3QgbmV3VmFsID0gY3VycmVudCA9PT0gbnVsbCA/IGluaXRpYWwgOiBmdW5jKGN1cnJlbnQpO1xuICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKGtleSwgSlNPTi5zdHJpbmdpZnkobmV3VmFsKSk7XG4gICAgcmV0dXJuIG5ld1ZhbDtcbiAgfSxcbiAgZ2V0TG9jYWwobG9jYWxTdG9yYWdlLCBuYW1lc3BhY2UsIHN1YmtleSkge1xuICAgIHJldHVybiBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMubG9jYWxLZXkobmFtZXNwYWNlLCBzdWJrZXkpKSk7XG4gIH0sXG4gIHVwZGF0ZUN1cnJlbnRTdGF0ZShjYWxsYmFjaykge1xuICAgIGlmICghdGhpcy5jYW5QdXNoU3RhdGUoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBoaXN0b3J5LnJlcGxhY2VTdGF0ZShcbiAgICAgIGNhbGxiYWNrKGhpc3Rvcnkuc3RhdGUgfHwge30pLFxuICAgICAgXCJcIixcbiAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmXG4gICAgKTtcbiAgfSxcbiAgcHVzaFN0YXRlKGtpbmQsIG1ldGEsIHRvKSB7XG4gICAgaWYgKHRoaXMuY2FuUHVzaFN0YXRlKCkpIHtcbiAgICAgIGlmICh0byAhPT0gd2luZG93LmxvY2F0aW9uLmhy
1ZWYpIHtcbiAgICAgICAgaWYgKG1ldGEudHlwZSA9PSBcInJlZGlyZWN0XCIgJiYgbWV0YS5zY3JvbGwpIHtcbiAgICAgICAgICBjb25zdCBjdXJyZW50U3RhdGUgPSBoaXN0b3J5LnN0YXRlIHx8IHt9O1xuICAgICAgICAgIGN1cnJlbnRTdGF0ZS5zY3JvbGwgPSBtZXRhLnNjcm9sbDtcbiAgICAgICAgICBoaXN0b3J5LnJlcGxhY2VTdGF0ZShjdXJyZW50U3RhdGUsIFwiXCIsIHdpbmRvdy5sb2NhdGlvbi5ocmVmKTtcbiAgICAgICAgfVxuICAgICAgICBkZWxldGUgbWV0YS5zY3JvbGw7XG4gICAgICAgIGhpc3Rvcnlba2luZCArIFwiU3RhdGVcIl0obWV0YSwgXCJcIiwgdG8gfHwgbnVsbCk7XG4gICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGhhc2hFbCA9IHRoaXMuZ2V0SGFzaFRhcmdldEVsKHdpbmRvdy5sb2NhdGlvbi5oYXNoKTtcbiAgICAgICAgICBpZiAoaGFzaEVsKSB7XG4gICAgICAgICAgICBoYXNoRWwuc2Nyb2xsSW50b1ZpZXcoKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKG1ldGEudHlwZSA9PT0gXCJyZWRpcmVjdFwiKSB7XG4gICAgICAgICAgICB3aW5kb3cuc2Nyb2xsKDAsIDApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0bykge1xuICAgICAgdGhpcy5yZWRpcmVjdCh0byk7XG4gICAgfVxuICB9LFxuICBzZXRDb29raWUobmFtZSwgdmFsdWUsIG1heEFnZVNlY29uZHMpIHtcbiAgICBjb25zdCBleHBpcmVzID0gdHlwZW9mIG1heEFnZVNlY29uZHMgPT09IFwibnVtYmVyXCIgPyBgIG1heC1hZ2U9JHttYXhBZ2VTZWNvbmRzfTtgIDogXCJcIjtcbiAgICBkb2N1bWVudC5jb29raWUgPSBgJHtuYW1lfT0ke3ZhbHVlfTske2V4cGlyZXN9IHBhdGg9L2A7XG4gIH0sXG4gIGdldENvb2tpZShuYW1lKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmNvb2tpZS5yZXBsYWNlKFxuICAgICAgbmV3IFJlZ0V4cChgKD86KD86XnwuKjtzKikke25hbWV9cyo9cyooW147XSopLiokKXxeLiokYCksXG4gICAgICBcIiQxXCJcbiAgICApO1xuICB9LFxuICBkZWxldGVDb29raWUobmFtZSkge1xuICAgIGRvY3VtZW50LmNvb2tpZSA9IGAke25hbWV9PTsgbWF4LWFnZT0tMTsgcGF0aD0vYDtcbiAgfSxcbiAgcmVkaXJlY3QodG9VUkwsIGZsYXNoID0gbnVsbCwgbmF2aWdhdGUgPSAodXJsKSA9PiB7XG4gICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSB1cmw7XG4gIH0pIHtcbiAgICBpZiAoZmxhc2gpIHtcbiAgICAgIHRoaXMuc2V0Q29va2llKFwiX19waG9lbml4X2ZsYXNoX19cIiwgZmxhc2gsIDYwKTtcbiAgICB9XG4gICAgbmF2aWdhdGUodG9VUkwpO1xuICB9LFxuICBsb2NhbEtleShuYW1lc3BhY2UsIHN1YmtleSkge1xuICAgIHJldHVybiBgJHtuYW1lc3BhY2V9LSR7c3Via2V5fWA7XG4gIH0sXG4gIGdldEhhc2hUYXJnZXRFbChtYXliZUhhc2gpIHtcbiAgICBjb25zdCBoYXNoID0gbWF5YmVIYXNoLnRvU3RyaW5nKCkuc3Vic3RyaW5nKDEpO1xuICAgIGlmIChoYXNoID09PSBcIlwiKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJldHVybiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChoYXNoKSB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBhW25hbWU9XCIke2hhc2h9XCJdYCk7XG4gIH1cbn07XG52YXIgYnJvd3Nlcl9kZWZhdWx0ID0gQnJvd3NlcjtcblxuLy8ganMvcGhvZW5peF9saXZlX3ZpZXcvZG9tLnRzXG52YXIgRE9NID0ge1xuICBieUlkKGlkKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKSB8fCBsb2dFcnJvcihgbm8gaWQgZm91bmQgZm9yICR7aWR9YCk7XG4gIH0sXG4gIGVsZW1lbnRGcm9tVGFyZ2V0KHRhcmdldCkge1xuICAgIGlmICghKHRhcmdldCBpbnN0YW5jZW9mIE5vZGUpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKHRhcmdldC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0YXJnZXQucGFyZW50RWxlbWVudDtcbiAgICB9XG4gIH0sXG4gIHJlbW92ZUNsYXNzKGVsLCBjbGFzc05hbWUpIHtcbiAgICBlbC5jbGFzc0xpc3QucmVtb3ZlKGNsYXNzTmFtZSk7XG4gICAgaWYgKGVsLmNsYXNzTGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShcImNsYXNzXCIpO1xuICAgIH1cbiAgfSxcbiAgYWxsKG5vZGUsIHF1ZXJ5LCBjYWxsYmFjaykge1xuICAgIGlmICghbm9kZSkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICBjb25zdCBhcnJheSA9IEFycmF5LmZyb20obm9kZS5xdWVyeVNlbGVjdG9yQWxsKHF1ZXJ5KSk7XG4gICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICBhcnJheS5mb3JFYWNoKGNhbGxiYWNrKTtcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5O1xuICB9LFxuICBjaGlsZE5vZGVMZW5ndGgoaHRtbCkge1xuICAgIGNvbnN0IHRlbXBsYXRlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRlbXBsYXRlXCIpO1xuICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IGh0bWw7XG4gICAgcmV0dXJuIHRlbXBsYXRlLmNvbnRlbnQuY2hpbGRFbGVtZW50Q291bnQ7XG4gIH0sXG4gIGlzVXBsb2FkSW5wdXQoZWwpIHtcbiAgICByZXR1cm4gZWwudHlwZSA9PT0gXCJmaWxlXCIgJiYgZWwuZ2V0QXR0cmlidXRlKFBIWF9VUExPQURfUkVGKSAhPT0gbnVsbDtcbiAgfSxcbiAgaXNBdXRvVXBsb2FkKGlucHV0RWwpIHtcbiAgICByZXR1cm4gaW5wdXRFbC5oYXNBdHRyaWJ1dGUoXCJkYXRhLXBoeC1hdXRvLXVwbG9hZFwiKTtcbiAgfSxcbiAgZmluZFVwbG9hZElucHV0cyhub2RlKSB7XG4gICAgY29uc3QgZm9ybUlkID0gbm9kZS5pZDtcbiAgICBjb25zdCBpbnB1dHNPdXRzaWRlRm9ybSA9IHRoaXMuYWxsKFxuICAgICAgZG9jdW1lbnQsXG4gICAgICBgaW5wdXRbdHlwZT1cImZpbGVcIl1bJHtQSFhfVVBMT0FEX1JFRn1dW2Zvcm09XCIke2Zvcm1JZH1cIl1gXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5hbGwobm9kZSwgYGlucHV0W3R5cGU9XCJmaWxlXCJdWyR7UEhYX1VQTE9BRF9SRUZ9XWApLmNvbmNhdChcbiAgICAgIGlucHV0c091dHNpZGVGb3JtXG4gICAgKTtcbiAgfSxcbiAgZmluZENvbXBvbmVudCh2aWV3SWQsIGNpZCwgZG9jMiA9IGRvY3VtZW50KSB7XG4gICAgcmV0dXJuIGRvYzIucXVlcnlTZWxlY3RvcihcbiAgICAgIGBbJHtQSFhfVklFV19SRUZ9PVwiJHt2aWV3SWR9XCJdWyR7UEhYX0NPTVBPTkVOVH09XCIke2NpZH1cIl1gXG4gICAgKTtcbiAgfSxcbiAgZ2V0Q29tcG9uZW50KHZpZXdJZCwgY2lkLCBkb2MyID0gZG9jdW1lbnQpIHtcbiAgICBjb25zdCBlbCA9IHRoaXMuZmluZENvbXBvbmVudCh2aWV3SWQsIGNpZCwgZG9jMik7XG4gICAgaWYgKCFlbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgbm8gY29tcG9uZW50IGZvdW5kIG1hdGNoaW5nIHZpZXdJZCAke3ZpZXdJZH0gYW5kIGNpZCAke2NpZH1gXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gZWw7XG4gIH0sXG4gIGlzUGh4RGVzdHJveWVkKG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS5pZCAmJiBET00ucHJpdmF0ZShub2RlLCBcImRlc3Ryb3llZFwiKSA/IHRydWUgOiBmYWxzZTtcbiAgfSxcbiAgd2FudHNOZXdUYWIoZSkge1xuICAgIGNvbnN0IHdhbnRzTmV3VGFiID0gZS5jdHJsS2V5IHx8IGUuc2hpZnRLZXkgfHwgZS5tZXRhS2V5IHx8IGUuYnV0dG9uICYmIGUuYnV0dG9uID09PSAxO1xuICAgIGNvbnN0IGlzRG93bmxvYWQgPSBlLnRhcmdldCBpbnN0YW5jZW9mIEhUTUxBbmNob3JFbGVtZW50ICYmIGUudGFyZ2V0Lmhhc0F0dHJpYnV0ZShcImRvd25sb2FkXCIpO1xuICAgIGNvbnN0IGlzVGFyZ2V0QmxhbmsgPSBlLnRhcmdldC5oYXNBdHRyaWJ1dGUoXCJ0YXJnZXRcIikgJiYgZS50YXJnZXQuZ2V0QXR0cmlidXRlKFwidGFyZ2V0XCIpLnRvTG93ZXJDYXNlKCkgPT09IFwiX2JsYW5rXCI7XG4gICAgY29uc3QgaXNUYXJnZXROYW1lZFRhYiA9IGUudGFyZ2V0Lmhhc0F0dHJpYnV0ZShcInRhcmdldFwiKSAmJiAhZS
150YXJnZXQuZ2V0QXR0cmlidXRlKFwidGFyZ2V0XCIpLnN0YXJ0c1dpdGgoXCJfXCIpO1xuICAgIHJldHVybiB3YW50c05ld1RhYiB8fCBpc1RhcmdldEJsYW5rIHx8IGlzRG93bmxvYWQgfHwgaXNUYXJnZXROYW1lZFRhYjtcbiAgfSxcbiAgaXNVbmxvYWRhYmxlRm9ybVN1Ym1pdChlKSB7XG4gICAgY29uc3QgaXNEaWFsb2dTdWJtaXQgPSBlLnRhcmdldCAmJiBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoXCJtZXRob2RcIikgPT09IFwiZGlhbG9nXCIgfHwgZS5zdWJtaXR0ZXIgJiYgZS5zdWJtaXR0ZXIuZ2V0QXR0cmlidXRlKFwiZm9ybW1ldGhvZFwiKSA9PT0gXCJkaWFsb2dcIjtcbiAgICBpZiAoaXNEaWFsb2dTdWJtaXQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuICFlLmRlZmF1bHRQcmV2ZW50ZWQgJiYgIXRoaXMud2FudHNOZXdUYWIoZSk7XG4gICAgfVxuICB9LFxuICBpc05ld1BhZ2VDbGljayhlLCBjdXJyZW50TG9jYXRpb24pIHtcbiAgICBjb25zdCBocmVmID0gZS50YXJnZXQgaW5zdGFuY2VvZiBIVE1MQW5jaG9yRWxlbWVudCA/IGUudGFyZ2V0LmdldEF0dHJpYnV0ZShcImhyZWZcIikgOiBudWxsO1xuICAgIGxldCB1cmw7XG4gICAgaWYgKGUuZGVmYXVsdFByZXZlbnRlZCB8fCBocmVmID09PSBudWxsIHx8IHRoaXMud2FudHNOZXdUYWIoZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKGhyZWYuc3RhcnRzV2l0aChcIm1haWx0bzpcIikgfHwgaHJlZi5zdGFydHNXaXRoKFwidGVsOlwiKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoZS50YXJnZXQuaXNDb250ZW50RWRpdGFibGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIHVybCA9IG5ldyBVUkwoaHJlZik7XG4gICAgfSBjYXRjaCB7XG4gICAgICB0cnkge1xuICAgICAgICB1cmwgPSBuZXcgVVJMKGhyZWYsIGN1cnJlbnRMb2NhdGlvbik7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh1cmwuaG9zdCA9PT0gY3VycmVudExvY2F0aW9uLmhvc3QgJiYgdXJsLnByb3RvY29sID09PSBjdXJyZW50TG9jYXRpb24ucHJvdG9jb2wpIHtcbiAgICAgIGlmICh1cmwucGF0aG5hbWUgPT09IGN1cnJlbnRMb2NhdGlvbi5wYXRobmFtZSAmJiB1cmwuc2VhcmNoID09PSBjdXJyZW50TG9jYXRpb24uc2VhcmNoKSB7XG4gICAgICAgIHJldHVybiB1cmwuaGFzaCA9PT0gXCJcIiAmJiAhdXJsLmhyZWYuZW5kc1dpdGgoXCIjXCIpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdXJsLnByb3RvY29sLnN0YXJ0c1dpdGgoXCJodHRwXCIpO1xuICB9LFxuICBtYXJrUGh4Q2hpbGREZXN0cm95ZWQoZWwpIHtcbiAgICBpZiAodGhpcy5pc1BoeENoaWxkKGVsKSkge1xuICAgICAgZWwuc2V0QXR0cmlidXRlKFBIWF9TRVNTSU9OLCBcIlwiKTtcbiAgICB9XG4gICAgdGhpcy5wdXRQcml2YXRlKGVsLCBcImRlc3Ryb3llZFwiLCB0cnVlKTtcbiAgfSxcbiAgZmluZFBoeENoaWxkcmVuSW5GcmFnbWVudChodG1sLCBwYXJlbnRJZCkge1xuICAgIGNvbnN0IHRlbXBsYXRlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRlbXBsYXRlXCIpO1xuICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IGh0bWw7XG4gICAgcmV0dXJuIHRoaXMuZmluZFBoeENoaWxkcmVuKHRlbXBsYXRlLmNvbnRlbnQsIHBhcmVudElkKTtcbiAgfSxcbiAgaXNJZ25vcmVkKGVsLCBwaHhVcGRhdGUpIHtcbiAgICByZXR1cm4gKGVsLmdldEF0dHJpYnV0ZShwaHhVcGRhdGUpIHx8IGVsLmdldEF0dHJpYnV0ZShcImRhdGEtcGh4LXVwZGF0ZVwiKSkgPT09IFwiaWdub3JlXCI7XG4gIH0sXG4gIGlzUGh4VXBkYXRlKGVsLCBwaHhVcGRhdGUsIHVwZGF0ZVR5cGVzKSB7XG4gICAgcmV0dXJuIGVsLmdldEF0dHJpYnV0ZSAmJiB1cGRhdGVUeXBlcy5pbmRleE9mKGVsLmdldEF0dHJpYnV0ZShwaHhVcGRhdGUpKSA+PSAwO1xuICB9LFxuICBmaW5kUGh4U3RpY2t5KGVsKSB7XG4gICAgcmV0dXJuIHRoaXMuYWxsKGVsLCBgWyR7UEhYX1NUSUNLWX1dYCk7XG4gIH0sXG4gIGZpbmRQaHhDaGlsZHJlbihlbCwgcGFyZW50SWQpIHtcbiAgICByZXR1cm4gdGhpcy5hbGwoZWwsIGAke1BIWF9WSUVXX1NFTEVDVE9SfVske1BIWF9QQVJFTlRfSUR9PVwiJHtwYXJlbnRJZH1cIl1gKTtcbiAgfSxcbiAgZmluZEV4aXN0aW5nUGFyZW50Q0lEcyh2aWV3SWQsIGNpZHMpIHtcbiAgICBjb25zdCBwYXJlbnRDaWRzID0gLyogQF9fUFVSRV9fICovIG5ldyBTZXQoKTtcbiAgICBjb25zdCBjaGlsZHJlbkNpZHMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpO1xuICAgIGNpZHMuZm9yRWFjaCgoY2lkKSA9PiB7XG4gICAgICB0aGlzLmFsbChcbiAgICAgICAgZG9jdW1lbnQsXG4gICAgICAgIGBbJHtQSFhfVklFV19SRUZ9PVwiJHt2aWV3SWR9XCJdWyR7UEhYX0NPTVBPTkVOVH09XCIke2NpZH1cIl1gXG4gICAgICApLmZvckVhY2goKHBhcmVudCkgPT4ge1xuICAgICAgICBwYXJlbnRDaWRzLmFkZChjaWQpO1xuICAgICAgICB0aGlzLmFsbChwYXJlbnQsIGBbJHtQSFhfVklFV19SRUZ9PVwiJHt2aWV3SWR9XCJdWyR7UEhYX0NPTVBPTkVOVH1dYCkubWFwKChlbCkgPT4gcGFyc2VJbnQoZWwuZ2V0QXR0cmlidXRlKFBIWF9DT01QT05FTlQpKSkuZm9yRWFjaCgoY2hpbGRDSUQpID0+IGNoaWxkcmVuQ2lkcy5hZGQoY2hpbGRDSUQpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIGNoaWxkcmVuQ2lkcy5mb3JFYWNoKChjaGlsZENpZCkgPT4gcGFyZW50Q2lkcy5kZWxldGUoY2hpbGRDaWQpKTtcbiAgICByZXR1cm4gcGFyZW50Q2lkcztcbiAgfSxcbiAgcHJpdmF0ZShlbCwga2V5KSB7XG4gICAgcmV0dXJuIGVsW1BIWF9QUklWQVRFXSAmJiBlbFtQSFhfUFJJVkFURV1ba2V5XTtcbiAgfSxcbiAgZGVsZXRlUHJpdmF0ZShlbCwga2V5KSB7XG4gICAgZWxbUEhYX1BSSVZBVEVdICYmIGRlbGV0ZSBlbFtQSFhfUFJJVkFURV1ba2V5XTtcbiAgfSxcbiAgcHV0UHJpdmF0ZShlbCwga2V5LCB2YWx1ZSkge1xuICAgIGlmICghZWxbUEhYX1BSSVZBVEVdKSB7XG4gICAgICBlbFtQSFhfUFJJVkFURV0gPSB7fTtcbiAgICB9XG4gICAgZWxbUEhYX1BSSVZBVEVdW2tleV0gPSB2YWx1ZTtcbiAgfSxcbiAgdXBkYXRlUHJpdmF0ZShlbCwga2V5LCBkZWZhdWx0VmFsLCB1cGRhdGVGdW5jKSB7XG4gICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLnByaXZhdGUoZWwsIGtleSk7XG4gICAgaWYgKGV4aXN0aW5nID09PSB2b2lkIDApIHtcbiAgICAgIHRoaXMucHV0UHJpdmF0ZShlbCwga2V5LCB1cGRhdGVGdW5jKGRlZmF1bHRWYWwpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wdXRQcml2YXRlKGVsLCBrZXksIHVwZGF0ZUZ1bmMoZXhpc3R
1pbmcpKTtcbiAgICB9XG4gIH0sXG4gIHN5bmNQZW5kaW5nQXR0cnMoZnJvbUVsLCB0b0VsKSB7XG4gICAgaWYgKCFmcm9tRWwuaGFzQXR0cmlidXRlKFBIWF9SRUZfU1JDKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBQSFhfRVZFTlRfQ0xBU1NFUy5mb3JFYWNoKChjbGFzc05hbWUpID0+IHtcbiAgICAgIGZyb21FbC5jbGFzc0xpc3QuY29udGFpbnMoY2xhc3NOYW1lKSAmJiB0b0VsLmNsYXNzTGlzdC5hZGQoY2xhc3NOYW1lKTtcbiAgICB9KTtcbiAgICBQSFhfUEVORElOR19BVFRSUy5maWx0ZXIoKGF0dHIpID0+IGZyb21FbC5oYXNBdHRyaWJ1dGUoYXR0cikpLmZvckVhY2goXG4gICAgICAoYXR0cikgPT4ge1xuICAgICAgICB0b0VsLnNldEF0dHJpYnV0ZShhdHRyLCBmcm9tRWwuZ2V0QXR0cmlidXRlKGF0dHIpKTtcbiAgICAgIH1cbiAgICApO1xuICB9LFxuICBjb3B5UHJpdmF0ZXModGFyZ2V0LCBzb3VyY2UpIHtcbiAgICBpZiAoc291cmNlW1BIWF9QUklWQVRFXSkge1xuICAgICAgdGFyZ2V0W1BIWF9QUklWQVRFXSA9IHNvdXJjZVtQSFhfUFJJVkFURV07XG4gICAgfVxuICB9LFxuICBwdXRUaXRsZShzdHIpIHtcbiAgICBjb25zdCB0aXRsZUVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcInRpdGxlXCIpO1xuICAgIGlmICh0aXRsZUVsKSB7XG4gICAgICBjb25zdCB7IHByZWZpeCwgc3VmZml4LCBkZWZhdWx0OiBkZWZhdWx0VGl0bGUgfSA9IHRpdGxlRWwuZGF0YXNldDtcbiAgICAgIGNvbnN0IGlzRW1wdHkyID0gdHlwZW9mIHN0ciAhPT0gXCJzdHJpbmdcIiB8fCBzdHIudHJpbSgpID09PSBcIlwiO1xuICAgICAgaWYgKGlzRW1wdHkyICYmIHR5cGVvZiBkZWZhdWx0VGl0bGUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgaW5uZXIgPSBpc0VtcHR5MiA/IGRlZmF1bHRUaXRsZSA6IHN0cjtcbiAgICAgIGRvY3VtZW50LnRpdGxlID0gYCR7cHJlZml4IHx8IFwiXCJ9JHtpbm5lciB8fCBcIlwifSR7c3VmZml4IHx8IFwiXCJ9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgZG9jdW1lbnQudGl0bGUgPSBzdHI7XG4gICAgfVxuICB9LFxuICBkZWJvdW5jZShlbCwgZXZlbnQsIHBoeERlYm91bmNlLCBkZWZhdWx0RGVib3VuY2UsIHBoeFRocm90dGxlLCBkZWZhdWx0VGhyb3R0bGUsIGFzeW5jRmlsdGVyLCBjYWxsYmFjaykge1xuICAgIGxldCBkZWJvdW5jZSA9IGVsLmdldEF0dHJpYnV0ZShwaHhEZWJvdW5jZSk7XG4gICAgbGV0IHRocm90dGxlID0gZWwuZ2V0QXR0cmlidXRlKHBoeFRocm90dGxlKTtcbiAgICBpZiAoZGVib3VuY2UgPT09IFwiXCIpIHtcbiAgICAgIGRlYm91bmNlID0gZGVmYXVsdERlYm91bmNlO1xuICAgIH1cbiAgICBpZiAodGhyb3R0bGUgPT09IFwiXCIpIHtcbiAgICAgIHRocm90dGxlID0gZGVmYXVsdFRocm90dGxlO1xuICAgIH1cbiAgICBjb25zdCB2YWx1ZSA9IGRlYm91bmNlIHx8IHRocm90dGxlO1xuICAgIHN3aXRjaCAodmFsdWUpIHtcbiAgICAgIGNhc2UgbnVsbDpcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgICBjYXNlIFwiYmx1clwiOlxuICAgICAgICB0aGlzLmluY0N5Y2xlKGVsLCBcImRlYm91bmNlLWJsdXItY3ljbGVcIiwgKCkgPT4ge1xuICAgICAgICAgIGlmIChhc3luY0ZpbHRlcigpKSB7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLm9uY2UoZWwsIFwiZGVib3VuY2UtYmx1clwiKSkge1xuICAgICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICBcImJsdXJcIixcbiAgICAgICAgICAgICgpID0+IHRoaXMudHJpZ2dlckN5Y2xlKGVsLCBcImRlYm91bmNlLWJsdXItY3ljbGVcIilcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGNvbnN0IHRpbWVvdXQgPSBwYXJzZUludCh2YWx1ZSk7XG4gICAgICAgIGNvbnN0IHRyaWdnZXIgPSAoKSA9PiB0aHJvdHRsZSA/IHRoaXMuZGVsZXRlUHJpdmF0ZShlbCwgVEhST1RUTEVEKSA6IGNhbGxiYWNrKCk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRDeWNsZSA9IHRoaXMuaW5jQ3ljbGUoZWwsIERFQk9VTkNFX1RSSUdHRVIsIHRyaWdnZXIpO1xuICAgICAgICBpZiAoaXNOYU4odGltZW91dCkpIHtcbiAgICAgICAgICByZXR1cm4gbG9nRXJyb3IoYGludmFsaWQgdGhyb3R0bGUvZGVib3VuY2UgdmFsdWU6ICR7dmFsdWV9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRocm90dGxlKSB7XG4gICAgICAgICAgbGV0IG5ld0tleURvd24gPSBmYWxzZTtcbiAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJrZXlkb3duXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZXZLZXkgPSB0aGlzLnByaXZhdGUoZWwsIERFQk9VTkNFX1BSRVZfS0VZKTtcbiAgICAgICAgICAgIHRoaXMucHV0UHJpdmF0ZShlbCwgREVCT1VOQ0VfUFJFVl9LRVksIGV2ZW50LmtleSk7XG4gICAgICAgICAgICBuZXdLZXlEb3duID0gcHJldktleSAhPT0gZXZlbnQua2V5O1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5ld0tleURvd24gJiYgdGhpcy5wcml2YXRlKGVsLCBUSFJPVFRMRUQpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICBjb25zdCB0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChhc3luY0ZpbHRlcigpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyQ3ljbGUoZWwsIERFQk9VTkNFX1RSSUdHRVIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgICAgIHRoaXMucHV0UHJpdmF0ZShlbCwgVEhST1RUTEVELCB0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBpZiAoYXN5bmNGaWx0ZXIoKSkge1xuICAgICAgICAgICAgICB0aGlzLnRyaWdnZXJDeWNsZShlbCwgREVCT1VOQ0VfVFJJR0dFUiwgY3VycmVudEN5Y2xlKTtcbiAgICAgICAgICAgI
1H1cbiAgICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBmb3JtID0gZWwuZm9ybTtcbiAgICAgICAgaWYgKGZvcm0gJiYgdGhpcy5vbmNlKGZvcm0sIFwiYmluZC1kZWJvdW5jZVwiKSkge1xuICAgICAgICAgIGZvcm0uYWRkRXZlbnRMaXN0ZW5lcihcInN1Ym1pdFwiLCAoKSA9PiB7XG4gICAgICAgICAgICBBcnJheS5mcm9tKG5ldyBGb3JtRGF0YShmb3JtKS5lbnRyaWVzKCksIChbbmFtZV0pID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgbmFtZWRJdGVtID0gZm9ybS5lbGVtZW50cy5uYW1lZEl0ZW0obmFtZSk7XG4gICAgICAgICAgICAgIGNvbnN0IGlucHV0ID0gbmFtZWRJdGVtIGluc3RhbmNlb2YgUmFkaW9Ob2RlTGlzdCA/IG5hbWVkSXRlbVswXSA6IG5hbWVkSXRlbTtcbiAgICAgICAgICAgICAgaWYgKGlucHV0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbmNDeWNsZShpbnB1dCwgREVCT1VOQ0VfVFJJR0dFUik7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWxldGVQcml2YXRlKGlucHV0LCBUSFJPVFRMRUQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5vbmNlKGVsLCBcImJpbmQtZGVib3VuY2VcIikpIHtcbiAgICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKFwiYmx1clwiLCAoKSA9PiB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wcml2YXRlKGVsLCBUSFJPVFRMRUQpKTtcbiAgICAgICAgICAgIGlmIChhc3luY0ZpbHRlcigpKSB7XG4gICAgICAgICAgICAgIHRoaXMudHJpZ2dlckN5Y2xlKGVsLCBERUJPVU5DRV9UUklHR0VSKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgfSxcbiAgdHJpZ2dlckN5Y2xlKGVsLCBrZXksIGN1cnJlbnRDeWNsZSkge1xuICAgIGNvbnN0IFtjeWNsZSwgdHJpZ2dlcl0gPSB0aGlzLnByaXZhdGUoZWwsIGtleSk7XG4gICAgaWYgKCFjdXJyZW50Q3ljbGUpIHtcbiAgICAgIGN1cnJlbnRDeWNsZSA9IGN5Y2xlO1xuICAgIH1cbiAgICBpZiAoY3VycmVudEN5Y2xlID09PSBjeWNsZSkge1xuICAgICAgdGhpcy5pbmNDeWNsZShlbCwga2V5KTtcbiAgICAgIHRyaWdnZXIoKTtcbiAgICB9XG4gIH0sXG4gIG9uY2UoZWwsIGtleSkge1xuICAgIGlmICh0aGlzLnByaXZhdGUoZWwsIGtleSkgPT09IHRydWUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdGhpcy5wdXRQcml2YXRlKGVsLCBrZXksIHRydWUpO1xuICAgIHJldHVybiB0cnVlO1xuICB9LFxuICBpbmNDeWNsZShlbCwga2V5LCB0cmlnZ2VyID0gZnVuY3Rpb24oKSB7XG4gIH0pIHtcbiAgICBsZXQgW2N1cnJlbnRDeWNsZV0gPSB0aGlzLnByaXZhdGUoZWwsIGtleSkgfHwgWzAsIHRyaWdnZXJdO1xuICAgIGN1cnJlbnRDeWNsZSsrO1xuICAgIHRoaXMucHV0UHJpdmF0ZShlbCwga2V5LCBbY3VycmVudEN5Y2xlLCB0cmlnZ2VyXSk7XG4gICAgcmV0dXJuIGN1cnJlbnRDeWNsZTtcbiAgfSxcbiAgLy8gbWFpbnRhaW5zIG9yIGFkZHMgcHJpdmF0ZWx5IHVzZWQgaG9vayBpbmZvcm1hdGlvblxuICAvLyBmcm9tRWwgYW5kIHRvRWwgY2FuIGJlIHRoZSBzYW1lIGVsZW1lbnQgaW4gdGhlIGNhc2Ugb2YgYSBuZXdseSBhZGRlZCBub2RlXG4gIC8vIGZyb21FbCBhbmQgdG9FbCBjYW4gYmUgYW55IEhUTUwgbm9kZSB0eXBlLCBzbyB3ZSBuZWVkIHRvIGNoZWNrIGlmIGl0J3MgYW4gZWxlbWVudCBub2RlXG4gIG1haW50YWluUHJpdmF0ZUhvb2tzKGZyb21FbCwgdG9FbCwgcGh4Vmlld3BvcnRUb3AsIHBoeFZpZXdwb3J0Qm90dG9tKSB7XG4gICAgaWYgKGZyb21FbC5oYXNBdHRyaWJ1dGUgJiYgZnJvbUVsLmhhc0F0dHJpYnV0ZShcImRhdGEtcGh4LWhvb2tcIikgJiYgIXRvRWwuaGFzQXR0cmlidXRlKFwiZGF0YS1waHgtaG9va1wiKSkge1xuICAgICAgdG9FbC5zZXRBdHRyaWJ1dGUoXCJkYXRhLXBoeC1ob29rXCIsIGZyb21FbC5nZXRBdHRyaWJ1dGUoXCJkYXRhLXBoeC1ob29rXCIpKTtcbiAgICB9XG4gICAgaWYgKHRvRWwuaGFzQXR0cmlidXRlICYmICh0b0VsLmhhc0F0dHJpYnV0ZShwaHhWaWV3cG9ydFRvcCkgfHwgdG9FbC5oYXNBdHRyaWJ1dGUocGh4Vmlld3BvcnRCb3R0b20pKSkge1xuICAgICAgdG9FbC5zZXRBdHRyaWJ1dGUoXCJkYXRhLXBoeC1ob29rXCIsIFwiUGhvZW5peC5JbmZpbml0ZVNjcm9sbFwiKTtcbiAgICB9XG4gIH0sXG4gIHB1dEN1c3RvbUVsSG9vayhlbCwgaG9vaykge1xuICAgIGlmIChlbC5pc0Nvbm5lY3RlZCkge1xuICAgICAgZWwuc2V0QXR0cmlidXRlKFwiZGF0YS1waHgtaG9va1wiLCBcIlwiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcihgXG4gICAgICAgIGhvb2sgYXR0YWNoZWQgdG8gbm9uLWNvbm5lY3RlZCBET00gZWxlbWVudFxuICAgICAgICBlbnN1cmUgeW91IGFyZSBjYWxsaW5nIGNyZWF0ZUhvb2sgd2l0aGluIHlvdXIgY29ubmVjdGVkQ2FsbGJhY2suICR7ZWwub3V0ZXJIVE1MfVxuICAgICAgYCk7XG4gICAgfVxuICAgIHRoaXMucHV0UHJpdmF0ZShlbCwgXCJjdXN0b20tZWwtaG9va1wiLCBob29rKTtcbiAgfSxcbiAgZ2V0Q3VzdG9tRWxIb29rKGVsKSB7XG4gICAgcmV0dXJuIHRoaXMucHJpdmF0ZShlbCwgXCJjdXN0b20tZWwtaG9va1wiKTtcbiAgfSxcbiAgaXNVc2VkSW5wdXQoZWwpIHtcbiAgICByZXR1cm4gZWwubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmICh0aGlzLnByaXZhdGUoZWwsIFBIWF9IQVNfRk9DVVNFRCkgfHwgdGhpcy5wcml2YXRlKGVsLCBQSFhfSEFTX1NVQk1JVFRFRCkpO1xuICB9LFxuICByZXNldEZvcm0oZm9ybSkge1xuICAgIEFycmF5LmZyb20oZm9ybS5lbGVtZW50cykuZm9yRWFjaCgoaW5wdXQpID0+IHtcbiAgICAgIHRoaXMuZGVsZXRlUHJpdmF0ZShpbnB1dCwgUEhYX0hBU19GT0NVU0VEKTtcbiAgICAgIHRoaXMuZGVsZXRlUHJpdmF0ZShpbnB1dCwgUEhYX0hBU19TVUJNSVRURUQpO1xuICAgIH0pO1xuICB9LFxuICBpc1BoeENoaWxkKG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS5nZXRBdHRyaWJ1dGUgJiYgbm9kZS5nZXRBdHRyaWJ1dGUoUEhYX1BBUkVOVF9JRCk7XG4gIH0sXG4gIGlzUGh4U3RpY2t5KG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS5nZXRBdHRyaWJ1dGUgJiYgbm9kZS5nZXRBdHRyaWJ1dGUoUEhYX1NUSUNLWSkgIT09IG51bGw7XG4gIH0sXG4gIGlzQ2hpbGRPZkFueShlbCwgcGFyZW50cykge1xuICAgIHJldHVybiAhIXBhcmVudHMuZmluZCgocGFyZW50KSA9PiBwYXJlbnQuY29udGFpbnMoZWwpKTtcbiAgfSxcbiAgZmlyc3RQaHhDaGlsZChlbCkge1xuICAgIHJldHVybi
1B0aGlzLmlzUGh4Q2hpbGQoZWwpID8gZWwgOiB0aGlzLmFsbChlbCwgYFske1BIWF9QQVJFTlRfSUR9XWApWzBdO1xuICB9LFxuICBpc1BvcnRhbFRlbXBsYXRlKGVsKSB7XG4gICAgcmV0dXJuIGVsLnRhZ05hbWUgPT09IFwiVEVNUExBVEVcIiAmJiBlbC5oYXNBdHRyaWJ1dGUoUEhYX1BPUlRBTCk7XG4gIH0sXG4gIGNsb3Nlc3RWaWV3RWwoZWwpIHtcbiAgICBjb25zdCBwb3J0YWxPclZpZXdFbCA9IGVsLmNsb3Nlc3QoXG4gICAgICBgWyR7UEhYX1RFTEVQT1JURURfUkVGfV0sJHtQSFhfVklFV19TRUxFQ1RPUn1gXG4gICAgKTtcbiAgICBpZiAoIXBvcnRhbE9yVmlld0VsKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKHBvcnRhbE9yVmlld0VsLmhhc0F0dHJpYnV0ZShQSFhfVEVMRVBPUlRFRF9SRUYpKSB7XG4gICAgICByZXR1cm4gdGhpcy5ieUlkKHBvcnRhbE9yVmlld0VsLmdldEF0dHJpYnV0ZShQSFhfVEVMRVBPUlRFRF9SRUYpKTtcbiAgICB9IGVsc2UgaWYgKHBvcnRhbE9yVmlld0VsLmhhc0F0dHJpYnV0ZShQSFhfU0VTU0lPTikpIHtcbiAgICAgIHJldHVybiBwb3J0YWxPclZpZXdFbDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH0sXG4gIGRpc3BhdGNoRXZlbnQodGFyZ2V0LCBuYW1lLCBvcHRzID0ge30pIHtcbiAgICBsZXQgZGVmYXVsdEJ1YmJsZSA9IHRydWU7XG4gICAgY29uc3QgaXNVcGxvYWRUYXJnZXQgPSB0YXJnZXQubm9kZU5hbWUgPT09IFwiSU5QVVRcIiAmJiB0YXJnZXQudHlwZSA9PT0gXCJmaWxlXCI7XG4gICAgaWYgKGlzVXBsb2FkVGFyZ2V0ICYmIG5hbWUgPT09IFwiY2xpY2tcIikge1xuICAgICAgZGVmYXVsdEJ1YmJsZSA9IGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCBidWJibGVzID0gb3B0cy5idWJibGVzID09PSB2b2lkIDAgPyBkZWZhdWx0QnViYmxlIDogISFvcHRzLmJ1YmJsZXM7XG4gICAgY29uc3QgZXZlbnRPcHRzID0ge1xuICAgICAgYnViYmxlcyxcbiAgICAgIGNhbmNlbGFibG
1U6IHRydWUsXG4gICAgICBkZXRhaWw6IG9wdHMuZGV0YWlsIHx8IHt9XG4gICAgfTtcbiAgICBjb25zdCBldmVudCA9IG5hbWUgPT09IFwiY2xpY2tcIiA/IG5ldyBNb3VzZUV2ZW50KFwiY2xpY2tcIiwgZXZlbnRPcHRzKSA6IG5ldyBDdXN0b21FdmVudChuYW1lLCBldmVudE9wdHMpO1xuICAgIHRhcmdldC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgfSxcbiAgY2xvbmVOb2RlKG5vZGUsIGh0bWwpIHtcbiAgICBpZiAodHlwZW9mIGh0bWwgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgIHJldHVybiBub2RlLmNsb25lTm9kZSh0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgY2xvbmVkID0gbm9kZS5jbG9uZU5vZGUoZmFsc2UpO1xuICAgICAgY2xvbmVkLmlubmVySFRNTCA9IGh0bWw7XG4gICAgICByZXR1cm4gY2xvbmVkO1xuICAgIH1cbiAgfSxcbiAgLy8gbWVyZ2UgYXR0cmlidXRlcyBmcm9tIHNvdXJjZSB0byB0YXJnZXRcbiAgLy8gaWYgYW4gZWxlbWVudCBpcyBpZ25vcmVkLCB3ZSBvbmx5IG1lcmdlIGRhdGEgYXR0cmlidXRlc1xuICAvLyBpbmNsdWRpbmcgcmVtb3ZpbmcgZGF0YSBhdHRyaWJ1dGVzIHRoYXQgYXJlIG5vIGxvbmdlciBpbiB0aGUgc291cmNlXG4gIG1lcmdlQXR0cnModGFyZ2V0LCBzb3VyY2UsIG9wdHMgPSB7fSkge1xuICAgIGNvbnN0IGV4Y2x1ZGUgPSBuZXcgU2V0KG9wdHMuZXhjbHVkZSB8fCBbXSk7XG4gICAgY29uc3QgaXNJZ25vcmVkID0gb3B0cy5pc0lnbm9yZWQ7XG4gICAgY29uc3Qgc291cmNlQXR0cnMgPSBzb3VyY2UuYXR0cmlidXRlcztcbiAgICBmb3IgKGxldCBpID0gc291cmNlQXR0cnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGNvbnN0IG5hbWUgPSBzb3VyY2VBdHRyc1tpXS5uYW1lO1xuICAgICAgaWYgKCFleGNsdWRlLmhhcyhuYW1lKSkge1xuICAgICAgICBjb25zdCBzb3VyY2VWYWx1ZSA9IHNvdXJjZS5nZXRBdHRyaWJ1dGUobmFtZSk7XG4gICAgICAgIGlmICh0YXJnZXQuZ2V0QXR0cmlidXRlKG5hbWUpICE9PSBzb3VyY2VWYWx1ZSAmJiAoIWlzSWdub3JlZCB8fCBpc0lnbm9yZWQgJiYgbmFtZS5zdGFydHNXaXRoKFwiZGF0YS1cIikpKSB7XG4gICAgICAgICAgdGFyZ2V0LnNldEF0dHJpYnV0ZShuYW1lLCBzb3VyY2VWYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChuYW1lID09PSBcInZhbHVlXCIpIHtcbiAgICAgICAgICBjb25zdCBzb3VyY2VWYWx1ZSA9IHNvdXJjZS52YWx1ZSA/PyBzb3VyY2UuZ2V0QXR0cmlidXRlKG5hbWUpO1xuICAgICAgICAgIGlmICh0YXJnZXQudmFsdWUgPT09IHNvdXJjZVZhbHVlKSB7XG4gICAgICAgICAgICB0YXJnZXQuc2V0QXR0cmlidXRlKFwidmFsdWVcIiwgc291cmNlLmdldEF0dHJpYnV0ZShuYW1lKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHRhcmdldEF0dHJzID0gdGFyZ2V0LmF0dHJpYnV0ZXM7XG4gICAgZm9yIChsZXQgaSA9IHRhcmdldEF0dHJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBjb25zdCBuYW1lID0gdGFyZ2V0QXR0cnNbaV0ubmFtZTtcbiAgICAgIGlmIChpc0lnbm9yZWQpIHtcbiAgICAgICAgaWYgKG5hbWUuc3RhcnRzV2l0aChcImRhdGEtXCIpICYmICFzb3VyY2UuaGFzQXR0cmlidXRlKG5hbWUpICYmICFQSFhfUEVORElOR19BVFRSUy5pbmNsdWRlcyhuYW1lKSkge1xuICAgICAgICAgIHRhcmdldC5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICghc291cmNlLmhhc0F0dHJpYnV0ZShuYW1lKSkge1xuICAgICAgICAgIHRhcmdldC5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIG1lcmdlRm9jdXNlZElucHV0KHRhcmdldCwgc291cmNlKSB7XG4gICAgaWYgKCEodGFyZ2V0IGluc3RhbmNlb2YgSFRNTFNlbGVjdEVsZW1lbnQpKSB7XG4gICAgICBET00ubWVyZ2VBdHRycyh0YXJnZXQsIHNvdXJjZSwgeyBleGNsdWRlOiBbXCJ2YWx1ZVwiXSB9KTtcbiAgICB9XG4gICAgaWYgKHNvdXJjZS5yZWFkT25seSkge1xuICAgICAgdGFyZ2V0LnNldEF0dHJpYnV0ZShcInJlYWRvbmx5XCIsIHRydWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0YXJnZXQucmVtb3ZlQXR0cmlidXRlKFwicmVhZG9ubHlcIik7XG4gICAgfVxuICB9LFxuICBoYXNTZWxlY3Rpb25SYW5nZShlbCkge1xuICAgIHJldHVybiBlbC5zZXRTZWxlY3Rpb25SYW5nZSAmJiAoZWwudHlwZSA9PT0gXCJ0ZXh0XCIgfHwgZWwudHlwZSA9PT0gXCJ0ZXh0YXJlYVwiKTtcbiAgfSxcbiAgcmVzdG9yZUZvY3VzKGZvY3VzZWQsIHNlbGVjdGlvblN0YXJ0LCBzZWxlY3Rpb25FbmQpIHtcbiAgICBpZiAoZm9jdXNlZCBpbnN0YW5jZW9mIEhUTUxTZWxlY3RFbGVtZW50KSB7XG4gICAgICBmb2N1c2VkLmZvY3VzKCk7XG4gICAgfVxuICAgIGlmICghRE9NLmlzVGV4dHVhbElucHV0KGZvY3VzZWQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHdhc0ZvY3VzZWQgPSBmb2N1c2VkLm1hdGNoZXMoXCI6Zm9jdXNcIik7XG4gICAgaWYgKCF3YXNGb2N1c2VkKSB7XG4gICAgICBmb2N1c2VkLmZvY3VzKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmhhc1NlbGVjdGlvblJhbmdlKGZvY3VzZWQpKSB7XG4gICAgICBmb2N1c2VkLnNldFNlbGVjdGlvblJhbmdlKHNlbGVjdGlvblN0YXJ0LCBzZWxlY3Rpb25FbmQpO1xuICAgIH1cbiAgfSxcbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZWxlbWVudCBpcyBhbiBpbnB1dCB0aGF0IGNhbiBiZSBmb2N1c2VkIGFuZCBlZGl0ZWQgYnkgdGhlIHVzZXIsXG4gICAqIHNvIHdlIGNhbiBza2lwIHBhdGNoaW5nIGl0IGlmIGl0IGhhcyBmb2N1cy5cbiAgICovXG4gIGlzRWRpdGFibGVJbnB1dChlbCkge1xuICAgIHJldHVybiB0aGlzLmlzRm9ybUFzc29jaWF0ZWQoZWwpICYmICEoZWwgaW5zdGFuY2VvZiBIVE1MQnV0dG9uRWxlbWVudCkgJiYgIShlbCBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQgJiYgZWwudHlwZSA9PT0gXCJidXR0b25cIik7XG4gIH0sXG4gIGlzRm9ybUFzc29jaWF0ZWQoZWwpIHtcbiAgICBpZiAoIShlbCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSlcbiAgICAgIHJldHVybi
1BmYWxzZTtcbiAgICBpZiAoZWwubG9jYWxOYW1lKSB7XG4gICAgICBjb25zdCBjdXN0b21FbCA9IGN1c3RvbUVsZW1lbnRzLmdldChlbC5sb2NhbE5hbWUpO1xuICAgICAgaWYgKGN1c3RvbUVsKSB7XG4gICAgICAgIHJldHVybiBjdXN0b21FbC5mb3JtQXNzb2NpYXRlZCA9PT0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGVsIGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCB8fCBlbCBpbnN0YW5jZW9mIEhUTUxTZWxlY3RFbGVtZW50IHx8IGVsIGluc3RhbmNlb2YgSFRNTFRleHRBcmVhRWxlbWVudCB8fCBlbCBpbnN0YW5jZW9mIEhUTUxCdXR0b25FbGVtZW50O1xuICB9LFxuICBzeW5jQXR0cnNUb1Byb3BzKGVsKSB7XG4gICAgaWYgKGVsIGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCAmJiBDSEVDS0FCTEVfSU5QVVRTLmluZGV4T2YoZWwudHlwZS50b0xvY2FsZUxvd2VyQ2FzZSgpKSA+PSAwKSB7XG4gICAgICBlbC5jaGVja2VkID0gZWwuZ2V0QXR0cmlidXRlKFwiY2hlY2tlZFwiKSAhPT0gbnVsbDtcbiAgICB9XG4gIH0sXG4gIGlzVGV4dHVhbElucHV0KGVsKSB7XG4gICAgcmV0dXJuIEZPQ1VTQUJMRV9JTlBVVFMuaW5kZXhPZihlbC50eXBlKSA+PSAwO1xuICB9LFxuICBpc05vd1RyaWdnZXJGb3JtRXh0ZXJuYWwoZWwsIHBoeFRyaWdnZXJFeHRlcm5hbCkge1xuICAgIHJldHVybiBlbC5nZXRBdHRyaWJ1dGUgJiYgZWwuZ2V0QXR0cmlidXRlKHBoeFRyaWdnZXJFeHRlcm5hbCkgIT09IG51bGwgJiYgZG9jdW1lbnQuYm9keS5jb250YWlucyhlbCk7XG4gIH0sXG4gIGNsZWFuQ2hpbGROb2Rlcyhjb250YWluZXIsIHBoeFVwZGF0ZSkge1xuICAgIGlmIChET00uaXNQaHhVcGRhdGUoY29udGFpbmVyLCBwaHhVcGRhdGUsIFtcImFwcGVuZFwiLCBcInByZXBlbmRcIiwgUEhYX1NUUkVBTV0pKSB7XG4gICAgICBjb25zdCB0b1JlbW92ZSA9IFtdO1xuICAgICAgY29udGFpbmVyLmNoaWxkTm9kZXMuZm9yRWFjaCgoY2hpbGROb2RlKSA9PiB7XG4gICAgICAgIGlmICghKFwiaWRcIiBpbiBjaGlsZE5vZGUpIHx8ICFjaGlsZE5vZGUuaWQpIHtcbiAgICAgICAgICBjb25zdCBpc0VtcHR5VGV4dE5vZGUgPSBjaGlsZE5vZGUubm9kZVR5cGUgPT09IE5vZGUuVEVYVF9OT0RFICYmIGNoaWxkTm9kZS5ub2RlVmFsdWUgJiYgY2hpbGROb2RlLm5vZGVWYWx1ZS50cmltKCkgPT09IFwiXCI7XG4gICAgICAgICAgaWYgKCFpc0VtcHR5VGV4dE5vZGUgJiYgY2hpbGROb2RlLm5vZGVUeXBlICE9PSBOb2RlLkNPTU1FTlRfTk9ERSkge1xuICAgICAgICAgICAgbG9nRXJyb3IoXG4gICAgICAgICAgICAgIGBvbmx5IEhUTUwgZWxlbWVudCB0YWdzIHdpdGggYW4gaWQgYXJlIGFsbG93ZWQgaW5zaWRlIGNvbnRhaW5lcnMgd2l0aCBwaHgtdXBkYXRlLlxuXG5yZW1vdmluZyBpbGxlZ2FsIG5vZGU6IFwiJHsoXCJvdXRlckhUTUxcIiBpbiBjaGlsZE5vZGUgJiYgY2hpbGROb2RlLm91dGVySFRNTCB8fCBjaGlsZE5vZGUubm9kZVZhbHVlIHx8IFwiXCIpLnRyaW0oKX1cIlxuXG5gXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0b1JlbW92ZS5wdXNoKGNoaWxkTm9kZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdG9SZW1vdmUuZm9yRWFjaCgoY2hpbGROb2RlKSA9PiBjaGlsZE5vZGUucmVtb3ZlKCkpO1xuICAgIH1cbiAgfSxcbiAgcmVwbGFjZVJvb3RDb250YWluZXIoY29udGFpbmVyLCB0YWdOYW1lLCBhdHRycykge1xuICAgIGNvbnN0IHJldGFpbmVkQXR0cnMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldChbXG4gICAgICBcImlkXCIsXG4gICAgICBQSFhfU0VTU0lPTixcbiAgICAgIFBIWF9TVEFUSUMsXG4gICAgICBQSFhfTUFJTixcbiAgICAgIFBIWF9ST09UX0lEXG4gICAgXSk7XG4gICAgaWYgKGNvbnRhaW5lci50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09IHRhZ05hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgQXJyYXkuZnJvbShjb250YWluZXIuYXR0cmlidXRlcykuZmlsdGVyKChhdHRyKSA9PiAhcmV0YWluZWRBdHRycy5oYXMoYXR0ci5uYW1lLnRvTG93ZXJDYXNlKCkpKS5mb3JFYWNoKChhdHRyKSA9PiBjb250YWluZXIucmVtb3ZlQXR0cmlidXRlKGF0dHIubmFtZSkpO1xuICAgICAgT2JqZWN0LmtleXMoYXR0cnMpLmZpbHRlcigobmFtZSkgPT4gIXJldGFpbmVkQXR0cnMuaGFzKG5hbWUudG9Mb3dlckNhc2UoKSkpLmZvckVhY2goKGF0dHIpID0+IGNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoYXR0ciwgYXR0cnNbYXR0cl0pKTtcbiAgICAgIHJldHVybiBjb250YWluZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG5ld0NvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSk7XG4gICAgICBPYmplY3Qua2V5cyhhdHRycykuZm9yRWFjaChcbiAgICAgICAgKGF0dHIpID0+IG5ld0NvbnRhaW5lci5zZXRBdHRyaWJ1dGUoYXR0ciwgYXR0cnNbYXR0cl0pXG4gICAgICApO1xuICAgICAgcmV0YWluZWRBdHRycy5mb3JFYWNoKChhdHRyKSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gY29udGFpbmVyLmdldEF0dHJpYnV0ZShhdHRyKTtcbiAgICAgICAgaWYgKHZhbHVlICE9PSBudWxsKSB7XG4gICAgICAgICAgbmV3Q29udGFpbmVyLnNldEF0dHJpYnV0ZShhdHRyLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgbmV3Q29udGFpbmVyLmlubmVySFRNTCA9IGNvbnRhaW5lci5pbm5lckhUTUw7XG4gICAgICBjb250YWluZXIucmVwbGFjZVdpdGgobmV3Q29udGFpbmVyKTtcbiAgICAgIHJldHVybiBuZXdDb250YWluZXI7XG4gICAgfVxuICB9LFxuICBnZXRTdGlja3koZWwsIG5hbWUsIGRlZmF1bHRWYWwpIHtcbiAgICBjb25zdCBvcCA9IChET00ucHJpdmF0ZShlbCwgXCJzdGlja3lcIikgfHwgW10pLmZpbmQoXG4gICAgICAoW2V4aXN0aW5nTmFtZV0pID0+IG5hbWUgPT09IGV4aXN0aW5nTmFtZVxuICAgICk7XG4gICAgaWYgKG9wKSB7XG4gICAgICBjb25zdCBbX25hbWUsIF9vcCwgc3Rhc2hlZFJlc3VsdF0gPSBvcDtcbiAgICAgIHJldHVybiBzdGFzaGVkUmVzdWx0O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdHlwZW9mIGRlZmF1bHRWYWwgPT09IFwiZnVuY3Rpb25cIiA/IGRlZmF1bHRWYWwoKSA6IGRlZmF1bHRWYWw7XG4gICAgfVxuICB9LFxuICBkZWxldGVTdGlja3koZWwsIG5hbW
1UpIHtcbiAgICB0aGlzLnVwZGF0ZVByaXZhdGUoZWwsIFwic3RpY2t5XCIsIFtdLCAob3BzKSA9PiB7XG4gICAgICByZXR1cm4gb3BzLmZpbHRlcigoW2V4aXN0aW5nTmFtZSwgX10pID0+IGV4aXN0aW5nTmFtZSAhPT0gbmFtZSk7XG4gICAgfSk7XG4gIH0sXG4gIHB1dFN0aWNreShlbCwgbmFtZSwgb3ApIHtcbiAgICBjb25zdCBzdGFzaGVkUmVzdWx0ID0gb3AoZWwpO1xuICAgIHRoaXMudXBkYXRlUHJpdmF0ZShlbCwgXCJzdGlja3lcIiwgW10sIChvcHMpID0+IHtcbiAgICAgIGNvbnN0IGV4aXN0aW5nSW5kZXggPSBvcHMuZmluZEluZGV4KFxuICAgICAgICAoW2V4aXN0aW5nTmFtZV0pID0+IG5hbWUgPT09IGV4aXN0aW5nTmFtZVxuICAgICAgKTtcbiAgICAgIGlmIChleGlzdGluZ0luZGV4ID49IDApIHtcbiAgICAgICAgb3BzW2V4aXN0aW5nSW5kZXhdID0gW25hbWUsIG9wLCBzdGFzaGVkUmVzdWx0XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9wcy5wdXNoKFtuYW1lLCBvcCwgc3Rhc2hlZFJlc3VsdF0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9wcztcbiAgICB9KTtcbiAgfSxcbiAgYXBwbHlTdGlja3lPcGVyYXRpb25zKGVsKSB7XG4gICAgY29uc3Qgb3BzID0gRE9NLnByaXZhdGUoZWwsIFwic3RpY2t5XCIpO1xuICAgIGlmICghb3BzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIG9wcy5mb3JFYWNoKChbbmFtZSwgb3AsIF9zdGFzaGVkXSkgPT4gdGhpcy5wdXRTdGlja3koZWwsIG5hbWUsIG9wKSk7XG4gIH0sXG4gIGlzTG9ja2VkKGVsKSB7XG4gICAgcmV0dXJuIGVsLmhhc0F0dHJpYnV0ZSAmJiBlbC5oYXNBdHRyaWJ1dGUoUEhYX1JFRl9MT0NLKTtcbiAgfSxcbiAgYXR0cmlidXRlSWdub3JlZChhdHRyaWJ1dGUsIGlnbm9yZWRBdHRyaWJ1dGVzKSB7XG4gICAgcmV0dXJuIGlnbm9yZWRBdHRyaWJ1dGVzLnNvbWUoXG4gICAgICAodG9JZ25vcmUpID0+IGF0dHJpYnV0ZS5uYW1lID09IHRvSWdub3JlIHx8IHRvSWdub3JlID09PSBcIipcIiB8fCB0b0lnbm9yZS5pbmNsdWRlcyhcIipcIikgJiYgYXR0cmlidXRlLm5hbWUubWF0Y2godG9JZ25vcmUpICE9IG51bGxcbiAgICApO1xuICB9XG59O1xudmFyIGRvbV9kZWZhdWx0ID0gRE9NO1xuXG4vLyBqcy9waG9lbml4X2xpdmVfdmlldy91cGxvYWRfZW50cnkuanNcbnZhciBVcGxvYWRFbnRyeSA9IGNsYXNzIHtcbiAgc3RhdGljIGlzQWN0aXZlKGZpbGVFbCwgZmlsZSkge1xuICAgIGNvbnN0IGlzTmV3ID0gZmlsZS5fcGh4UmVmID09PSB2b2lkIDA7XG4gICAgY29uc3QgYWN0aXZlUmVmcyA9IGZpbGVFbC5nZXRBdHRyaWJ1dGUoUEhYX0FDVElWRV9FTlRSWV9SRUZTKS5zcGxpdChcIixcIik7XG4gICAgY29uc3QgaXNBY3RpdmUgPSBhY3RpdmVSZWZzLmluZGV4T2YoTGl2ZVVwbG9hZGVyLmdlbkZpbGVSZWYoZmlsZSkpID49IDA7XG4gICAgcmV0dXJuIGZpbGUuc2l6ZSA+IDAgJiYgKGlzTmV3IHx8IGlzQWN0aXZlKTtcbiAgfVxuICBzdGF0aWMgaXNQcmVmbGlnaHRlZChmaWxlRWwsIGZpbGUpIHtcbiAgICBjb25zdCBwcmVmbGlnaHRlZFJlZnMgPSBmaWxlRWwuZ2V0QXR0cmlidXRlKFBIWF9QUkVGTElHSFRFRF9SRUZTKS5zcGxpdChcIixcIik7XG4gICAgY29uc3QgaXNQcmVmbGlnaHRlZCA9IHByZWZsaWdodGVkUmVmcy5pbmRleE9mKExpdmVVcGxvYWRlci5nZW5GaWxlUmVmKGZpbGUpKSA+PSAwO1xuICAgIHJldHVybiBpc1ByZWZsaWdodGVkICYmIHRoaXMuaXNBY3RpdmUoZmlsZUVsLCBmaWxlKTtcbiAgfVxuICBzdGF0aWMgaXNQcmVmbGlnaHRJblByb2dyZXNzKGZpbGUpIHtcbiAgICByZXR1cm4gZmlsZS5fcHJlZmxpZ2h0SW5Qcm9ncmVzcyA9PT0gdHJ1ZTtcbiAgfVxuICBzdGF0aWMgbWFya1ByZWZsaWdodEluUHJvZ3Jlc3MoZmlsZSkge1xuICAgIGZpbGUuX3ByZWZsaWdodEluUHJvZ3Jlc3MgPSB0cnVlO1xuICB9XG4gIGNvbnN0cnVjdG9yKGZpbGVFbCwgZmlsZSwgdmlldywgYXV0b1VwbG9hZCkge1xuICAgIHRoaXMucmVmID0gTGl2ZVVwbG9hZGVyLmdlbkZpbGVSZWYoZmlsZSk7XG4gICAgdGhpcy5maWxlRWwgPSBmaWxlRWw7XG4gICAgdGhpcy5maWxlID0gZmlsZTtcbiAgICB0aGlzLnZpZXcgPSB2aWV3O1xuICAgIHRoaXMubWV0YSA9IG51bGw7XG4gICAgdGhpcy5faXNDYW5jZWxsZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9pc0RvbmUgPSBmYWxzZTtcbiAgICB0aGlzLl9wcm9ncmVzcyA9IDA7XG4gICAgdGhpcy5fbGFzdFByb2dyZXNzU2VudCA9IC0xO1xuICAgIHRoaXMuX29uRG9uZSA9IGZ1bmN0aW9uKCkge1xuICAgIH07XG4gICAgdGhpcy5fb25FbFVwZGF0ZWQgPSB0aGlzLm9uRWxVcGRhdGVkLmJpbmQodGhpcyk7XG4gICAgdGhpcy5maWxlRWwuYWRkRXZlbnRMaXN0ZW5lcihQSFhfTElWRV9GSUxFX1VQREFURUQsIHRoaXMuX29uRWxVcGRhdGVkKTtcbiAgICB0aGlzLmF1dG9VcGxvYWQgPSBhdXRvVXBsb2FkO1xuICB9XG4gIG1ldGFkYXRhKCkge1xuICAgIHJldHVybiB0aGlzLm1ldGE7XG4gIH1cbiAgcHJvZ3Jlc3MocHJvZ3Jlc3MpIHtcbiAgICB0aGlzLl9wcm9ncmVzcyA9IE1hdGguZmxvb3IocHJvZ3Jlc3MpO1xuICAgIGlmICh0aGlzLl9wcm9ncmVzcyA+IHRoaXMuX2xhc3RQcm9ncmVzc1NlbnQpIHtcbiAgICAgIGlmICh0aGlzLl9wcm9ncmVzcyA+PSAxMDApIHtcbiAgICAgICAgdGhpcy5fcHJvZ3Jlc3MgPSAxMDA7XG4gICAgICAgIHRoaXMuX2xhc3RQcm9ncmVzc1NlbnQgPSAxMDA7XG4gICAgICAgIHRoaXMuX2lzRG9uZSA9IHRydWU7XG4gICAgICAgIHRoaXMudmlldy5wdXNoRmlsZVByb2dyZXNzKHRoaXMuZmlsZUVsLCB0aGlzLnJlZiwgMTAwLCAoKSA9PiB7XG4gICAgICAgICAgTGl2ZVVwbG9hZGVyLnVudHJhY2tGaWxlKHRoaXMuZmlsZUVsLCB0aGlzLmZpbGUpO1xuICAgICAgICAgIHRoaXMuX29uRG9uZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2xhc3RQcm9ncmVzc1NlbnQgPSB0aGlzLl9wcm9ncmVzcztcbiAgICAgICAgdGhpcy52aWV3LnB1c2hGaWxlUHJvZ3Jlc3ModGhpcy5maWxlRWwsIHRoaXMucmVmLCB0aGlzLl9wcm9ncmVzcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlzQ2FuY2VsbGVkKCkge1xuICAgIHJldHVybi
1B0aGlzLl9pc0NhbmNlbGxlZDtcbiAgfVxuICBjYW5jZWwoKSB7XG4gICAgdGhpcy5maWxlLl9wcmVmbGlnaHRJblByb2dyZXNzID0gZmFsc2U7XG4gICAgdGhpcy5faXNDYW5jZWxsZWQgPSB0cnVlO1xuICAgIHRoaXMuX2lzRG9uZSA9IHRydWU7XG4gICAgdGhpcy5fb25Eb25lKCk7XG4gIH1cbiAgaXNEb25lKCkge1xuICAgIHJldHVybiB0aGlzLl9pc0RvbmU7XG4gIH1cbiAgZXJyb3IocmVhc29uID0gXCJmYWlsZWRcIikge1xuICAgIHRoaXMuZmlsZUVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoUEhYX0xJVkVfRklMRV9VUERBVEVELCB0aGlzLl9vbkVsVXBkYXRlZCk7XG4gICAgdGhpcy52aWV3LnB1c2hGaWxlUHJvZ3Jlc3ModGhpcy5maWxlRWwsIHRoaXMucmVmLCB7IGVycm9yOiByZWFzb24gfSk7XG4gICAgaWYgKCF0aGlzLmlzQXV0b1VwbG9hZCgpKSB7XG4gICAgICBMaXZlVXBsb2FkZXIuY2xlYXJGaWxlcyh0aGlzLmZpbGVFbCk7XG4gICAgfVxuICB9XG4gIGlzQXV0b1VwbG9hZCgpIHtcbiAgICByZXR1cm4gdGhpcy5hdXRvVXBsb2FkO1xuICB9XG4gIC8vcHJpdmF0ZVxuICBvbkRvbmUoY2FsbGJhY2spIHtcbiAgICB0aGlzLl9vbkRvbmUgPSAoKSA9PiB7XG4gICAgICB0aGlzLmZpbGVFbC5yZW1vdmVFdmVudExpc3RlbmVyKFBIWF9MSVZFX0ZJTEVfVVBEQVRFRCwgdGhpcy5fb25FbFVwZGF0ZWQpO1xuICAgICAgY2FsbGJhY2soKTtcbiAgICB9O1xuICB9XG4gIG9uRWxVcGRhdGVkKCkge1xuICAgIGNvbnN0IGFjdGl2ZVJlZnMgPSB0aGlzLmZpbGVFbC5nZXRBdHRyaWJ1dGUoUEhYX0FDVElWRV9FTlRSWV9SRUZTKS5zcGxpdChcIixcIik7XG4gICAgaWYgKGFjdGl2ZVJlZnMuaW5kZXhPZih0aGlzLnJlZikgPT09IC0xKSB7XG4gICAgICBMaXZlVXBsb2FkZXIudW50cmFja0ZpbGUodGhpcy5maWxlRWwsIHRoaXMuZmlsZSk7XG4gICAgICB0aGlzLmNhbmNlbCgpO1xuICAgIH1cbiAgfVxuICB0b1ByZWZsaWdodFBheWxvYWQoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGxhc3RfbW9kaWZpZWQ6IHRoaXMuZmlsZS5sYXN0TW9kaWZpZWQsXG4gICAgICBuYW1lOiB0aGlzLmZpbGUubmFtZSxcbiAgICAgIHJlbGF0aXZlX3BhdGg6IHRoaXMuZmlsZS53ZWJraXRSZWxhdGl2ZVBhdGgsXG4gICAgICBzaXplOiB0aGlzLmZpbGUuc2l6ZSxcbiAgICAgIHR5cGU6IHRoaXMuZmlsZS50eXBlLFxuICAgICAgcmVmOiB0aGlzLnJlZixcbiAgICAgIG1ldGE6IHR5cGVvZiB0aGlzLmZpbGUubWV0YSA9PT0gXCJmdW5jdGlvblwiID8gdGhpcy5maWxlLm1ldGEoKSA6IHZvaWQgMFxuICAgIH07XG4gIH1cbiAgdXBsb2FkZXIodXBsb2FkZXJzKSB7XG4gICAgaWYgKHRoaXMubWV0YS51cGxvYWRlcikge1xuICAgICAgY29uc3QgY2FsbGJhY2sgPSB1cGxvYWRlcnNbdGhpcy5tZXRhLnVwbG9hZGVyXSB8fCBsb2dFcnJvcihgbm8gdXBsb2FkZXIgY29uZmlndXJlZCBmb3IgJHt0aGlzLm1ldGEudXBsb2FkZXJ9YCk7XG4gICAgICByZXR1cm4geyBuYW1lOiB0aGlzLm1ldGEudXBsb2FkZXIsIGNhbGxiYWNrIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB7IG5hbWU6IFwiY2hhbm5lbFwiLCBjYWxsYmFjazogY2hhbm5lbFVwbG9hZGVyIH07XG4gICAgfVxuICB9XG4gIHppcFBvc3RGbGlnaHQocmVzcCkge1xuICAgIHRoaXMubWV0YSA9IHJlc3AuZW50cmllc1t0aGlzLnJlZl07XG4gICAgaWYgKCF0aGlzLm1ldGEpIHtcbiAgICAgIGxvZ0Vycm9yKGBubyBwcmVmbGlnaHQgdXBsb2FkIHJlc3BvbnNlIHJldHVybmVkIHdpdGggcmVmICR7dGhpcy5yZWZ9YCwge1xuICAgICAgICBpbnB1dDogdGhpcy5maWxlRWwsXG4gICAgICAgIHJlc3BvbnNlOiByZXNwXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn07XG5cbi8vIGpzL3Bob2VuaXhfbGl2ZV92aWV3L2xpdmVfdXBsb2FkZXIuanNcbnZhciBsaXZlVXBsb2FkZXJGaWxlUmVmID0gMDtcbnZhciBMaXZlVXBsb2FkZXIgPSBjbGFzcyBfTGl2ZVVwbG9hZGVyIHtcbiAgc3RhdGljIGdlbkZpbGVSZWYoZmlsZSkge1xuICAgIGNvbnN0IHJlZiA9IGZpbGUuX3BoeFJlZjtcbiAgICBpZiAocmVmICE9PSB2b2lkIDApIHtcbiAgICAgIHJldHVybiByZWY7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZpbGUuX3BoeFJlZiA9IChsaXZlVXBsb2FkZXJGaWxlUmVmKyspLnRvU3RyaW5nKCk7XG4gICAgICByZXR1cm4gZmlsZS5fcGh4UmVmO1xuICAgIH1cbiAgfVxuICBzdGF0aWMgZ2V0RW50cnlEYXRhVVJMKGlucHV0RWwsIHJlZikge1xuICAgIGNvbnN0IGZpbGUgPSB0aGlzLmFjdGl2ZUZpbGVzKGlucHV0RWwpLmZpbmQoXG4gICAgICAoZmlsZTIpID0+IHRoaXMuZ2VuRmlsZVJlZihmaWxlMikgPT09IHJlZlxuICAgICk7XG4gICAgaWYgKCFmaWxlKVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIFVSTC5jcmVhdGVPYmplY3RVUkwoZmlsZSk7XG4gIH1cbiAgc3RhdGljIGhhc1VwbG9hZHNJblByb2dyZXNzKGZvcm1FbCkge1xuICAgIGxldCBhY3RpdmUgPSAwO1xuICAgIGRvbV9kZWZhdWx0LmZpbmRVcGxvYWRJbnB1dHMoZm9ybUVsKS5mb3JFYWNoKChpbnB1dCkgPT4ge1xuICAgICAgaWYgKGlucHV0LmdldEF0dHJpYnV0ZShQSFhfUFJFRkxJR0hURURfUkVGUykgIT09IGlucHV0LmdldEF0dHJpYnV0ZShQSFhfRE9ORV9SRUZTKSkge1xuICAgICAgICBhY3RpdmUrKztcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gYWN0aXZlID4gMDtcbiAgfVxuICBzdGF0aWMgc2VyaWFsaXplVXBsb2FkcyhpbnB1dEVsKSB7XG4gICAgY29uc3QgZmlsZXMgPSB0aGlzLmFjdGl2ZUZpbGVzKGlucHV0RWwpO1xuICAgIGNvbnN0IGZpbGVEYXRhID0ge307XG4gICAgZmlsZXMuZm9yRWFjaCgoZmlsZSkgPT4ge1xuICAgICAgY29uc3QgZW50cnkgPSB7IHBhdGg6IGlucHV0RWwubmFtZSB9O1xuICAgICAgY29uc3QgdXBsb2FkUmVmID0gaW5wdXRFbC5nZXRBdHRyaWJ1dGUoUEhYX1VQTE9BRF9SRUYpO1xuICAgICAgZmlsZURhdGFbdXBsb2FkUmVmXSA9IGZpbGVEYXRhW3VwbG9hZFJlZl0gfHwgW107XG4gICAgICBlbnRyeS5yZWYgPSB0aGlzLmdlbkZpbGVSZWYoZmlsZSk7XG4gICAgICBlbnRyeS5sYXN0X21vZGlmaWVkID0gZmlsZS5sYXN0TW9kaWZpZWQ7XG4gICAgICBlbnRyeS5uYW1lID0gZmlsZS5uYW1lIHx8IGVudHJ5LnJlZjtcbiAgICAgIGVudHJ5LnJlbGF0aXZlX3BhdGggPSBmaWxlLndlYmtpdFJlbGF0aXZlUGF0aDtcbiAgICAgIGVudHJ5LnR5cGUgPSBmaWxlLnR5cGU7XG4gICAgICBlbnRyeS5zaXplID0gZmlsZS5zaXplO1xuICAgICAgaWYgKHR5cGVvZiBmaWxlLm1ldGEgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBlbnRyeS5tZXRhID0gZmlsZS5tZXRhKCk7XG4gICAgICB9XG4gICAgICBmaWxlRGF0YVt1cGxvYWRSZWZdLnB1c2goZW50cnkpO1xuICAgIH0pO1xuICAgIHJldHVybi
1BmaWxlRGF0YTtcbiAgfVxuICBzdGF0aWMgY2xlYXJGaWxlcyhpbnB1dEVsKSB7XG4gICAgaW5wdXRFbC52YWx1ZSA9IG51bGw7XG4gICAgaW5wdXRFbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1VQTE9BRF9SRUYpO1xuICAgIGRvbV9kZWZhdWx0LnB1dFByaXZhdGUoaW5wdXRFbCwgXCJmaWxlc1wiLCBbXSk7XG4gIH1cbiAgc3RhdGljIHVudHJhY2tGaWxlKGlucHV0RWwsIGZpbGUpIHtcbiAgICBkb21fZGVmYXVsdC5wdXRQcml2YXRlKFxuICAgICAgaW5wdXRFbCxcbiAgICAgIFwiZmlsZXNcIixcbiAgICAgIGRvbV9kZWZhdWx0LnByaXZhdGUoaW5wdXRFbCwgXCJmaWxlc1wiKS5maWx0ZXIoKGYpID0+ICFPYmplY3QuaXMoZiwgZmlsZSkpXG4gICAgKTtcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHtIVE1MSW5wdXRFbGVtZW50fSBpbnB1dEVsXG4gICAqIEBwYXJhbSB7QXJyYXk8RmlsZXxCbG9iPn0gZmlsZXNcbiAgICogQHBhcmFtIHtEYXRhVHJhbnNmZXJ9IFtkYXRhVHJhbnNmZXJdXG4gICAqL1xuICBzdGF0aWMgdHJhY2tGaWxlcyhpbnB1dEVsLCBmaWxlcywgZGF0YVRyYW5zZmVyKSB7XG4gICAgaWYgKGlucHV0RWwuZ2V0QXR0cmlidXRlKFwibXVsdGlwbGVcIikgIT09IG51bGwpIHtcbiAgICAgIGNvbnN0IG5ld0ZpbGVzID0gZmlsZXMuZmlsdGVyKFxuICAgICAgICAoZmlsZSkgPT4gIXRoaXMuYWN0aXZlRmlsZXMoaW5wdXRFbCkuZmluZCgoZikgPT4gT2JqZWN0LmlzKGYsIGZpbGUpKVxuICAgICAgKTtcbiAgICAgIGRvbV9kZWZhdWx0LnVwZGF0ZVByaXZhdGUoXG4gICAgICAgIGlucHV0RWwsXG4gICAgICAgIFwiZmlsZXNcIixcbiAgICAgICAgW10sXG4gICAgICAgIChleGlzdGluZykgPT4gZXhpc3RpbmcuY29uY2F0KG5ld0ZpbGVzKVxuICAgICAgKTtcbiAgICAgIGlucHV0RWwudmFsdWUgPSBcIlwiO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoZGF0YVRyYW5zZmVyICYmIGRhdGFUcmFuc2Zlci5maWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGlucHV0RWwuZmlsZXMgPSBkYXRhVHJhbnNmZXIuZmlsZXM7XG4gICAgICB9XG4gICAgICBkb21fZGVmYXVsdC5wdXRQcml2YXRlKGlucHV0RWwsIFwiZmlsZXNcIiwgZmlsZXMpO1xuICAgIH1cbiAgfVxuICBzdGF0aWMgYWN0aXZlRmlsZUlucHV0cyhmb3JtRWwpIHtcbiAgICBjb25zdCBmaWxlSW5wdXRzID0gZG9tX2RlZmF1bHQuZmluZFVwbG9hZElucHV0cyhmb3JtRWwpO1xuICAgIHJldHVybiBBcnJheS5mcm9tKGZpbGVJbnB1dHMpLmZpbHRlcihcbiAgICAgIChlbCkgPT4gZWwuZmlsZXMgJiYgdGhpcy5hY3RpdmVGaWxlcyhlbCkubGVuZ3RoID4gMFxuICAgICk7XG4gIH1cbiAgc3RhdGljIGFjdGl2ZUZpbGVzKGlucHV0KSB7XG4gICAgcmV0dXJuIChkb21fZGVmYXVsdC5wcml2YXRlKGlucHV0LCBcImZpbGVzXCIpIHx8IFtdKS5maWx0ZXIoXG4gICAgICAoZikgPT4gVXBsb2FkRW50cnkuaXNBY3RpdmUoaW5wdXQsIGYpXG4gICAgKTtcbiAgfVxuICBzdGF0aWMgaW5wdXRzQXdhaXRpbmdQcmVmbGlnaHQoZm9ybUVsKSB7XG4gICAgY29uc3QgZmlsZUlucHV0cyA9IGRvbV9kZWZhdWx0LmZpbmRVcGxvYWRJbnB1dHMoZm9ybUVsKTtcbiAgICByZXR1cm4gQXJyYXkuZnJvbShmaWxlSW5wdXRzKS5maWx0ZXIoXG4gICAgICAoaW5wdXQpID0+IHRoaXMuZmlsZXNBd2FpdGluZ1ByZWZsaWdodChpbnB1dCkubGVuZ3RoID4gMFxuICAgICk7XG4gIH1cbiAgc3RhdGljIGZpbGVzQXdhaXRpbmdQcmVmbGlnaHQoaW5wdXQpIHtcbiAgICByZXR1cm4gdGhpcy5hY3RpdmVGaWxlcyhpbnB1dCkuZmlsdGVyKFxuICAgICAgKGYpID0+ICFVcGxvYWRFbnRyeS5pc1ByZWZsaWdodGVkKGlucHV0LCBmKSAmJiAhVXBsb2FkRW50cnkuaXNQcmVmbGlnaHRJblByb2dyZXNzKGYpXG4gICAgKTtcbiAgfVxuICBzdGF0aWMgbWFya1ByZWZsaWdodEluUHJvZ3Jlc3MoZW50cmllcykge1xuICAgIGVudHJpZXMuZm9yRWFjaCgoZW50cnkpID0+IFVwbG9hZEVudHJ5Lm1hcmtQcmVmbGlnaHRJblByb2dyZXNzKGVudHJ5LmZpbGUpKTtcbiAgfVxuICBjb25zdHJ1Y3RvcihpbnB1dEVsLCB2aWV3LCBvbkNvbXBsZXRlKSB7XG4gICAgdGhpcy5hdXRvVXBsb2FkID0gZG9tX2RlZmF1bHQuaXNBdXRvVXBsb2FkKGlucHV0RWwpO1xuICAgIHRoaXMudmlldyA9IHZpZXc7XG4gICAgdGhpcy5vbkNvbXBsZXRlID0gb25Db21wbGV0ZTtcbiAgICB0aGlzLl9lbnRyaWVzID0gQXJyYXkuZnJvbShcbiAgICAgIF9MaXZlVXBsb2FkZXIuZmlsZXNBd2FpdGluZ1ByZWZsaWdodChpbnB1dEVsKSB8fCBbXVxuICAgICkubWFwKChmaWxlKSA9PiBuZXcgVXBsb2FkRW50cnkoaW5wdXRFbCwgZmlsZSwgdmlldywgdGhpcy5hdXRvVXBsb2FkKSk7XG4gICAgX0xpdmVVcGxvYWRlci5tYXJrUHJlZmxpZ2h0SW5Qcm9ncmVzcyh0aGlzLl9lbnRyaWVzKTtcbiAgICB0aGlzLm51bUVudHJpZXNJblByb2dyZXNzID0gdGhpcy5fZW50cmllcy5sZW5ndGg7XG4gIH1cbiAgaXNBdXRvVXBsb2FkKCkge1xuICAgIHJldHVybiB0aGlzLmF1dG9VcGxvYWQ7XG4gIH1cbiAgZW50cmllcygpIHtcbiAgICByZXR1cm4gdGhpcy5fZW50cmllcztcbiAgfVxuICBpbml0QWRhcHRlclVwbG9hZChyZXNwLCBvbkVycm9yLCBsaXZlU29ja2V0KSB7XG4gICAgdGhpcy5fZW50cmllcyA9IHRoaXMuX2VudHJpZXMubWFwKChlbnRyeSkgPT4ge1xuICAgICAgaWYgKGVudHJ5LmlzQ2FuY2VsbGVkKCkpIHtcbiAgICAgICAgdGhpcy5udW1FbnRyaWVzSW5Qcm9ncmVzcy0tO1xuICAgICAgICBpZiAodGhpcy5udW1FbnRyaWVzSW5Qcm9ncmVzcyA9PT0gMCkge1xuICAgICAgICAgIHRoaXMub25Db21wbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbnRyeS56aXBQb3N0RmxpZ2h0KHJlc3ApO1xuICAgICAgICBlbnRyeS5vbkRvbmUoKCkgPT4ge1xuICAgICAgICAgIHRoaXMubnVtRW50cmllc0luUHJvZ3Jlc3MtLTtcbiAgICAgICAgICBpZiAodGhpcy5udW1FbnRyaWVzSW5Qcm9ncmVzcyA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5vbkNvbXBsZXRlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybi
1BlbnRyeTtcbiAgICB9KTtcbiAgICBjb25zdCBncm91cGVkRW50cmllcyA9IHRoaXMuX2VudHJpZXMucmVkdWNlKChhY2MsIGVudHJ5KSA9PiB7XG4gICAgICBpZiAoIWVudHJ5Lm1ldGEpIHtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH1cbiAgICAgIGNvbnN0IHsgbmFtZSwgY2FsbGJhY2sgfSA9IGVudHJ5LnVwbG9hZGVyKGxpdmVTb2NrZXQudXBsb2FkZXJzKTtcbiAgICAgIGFjY1tuYW1lXSA9IGFjY1tuYW1lXSB8fCB7IGNhbGxiYWNrLCBlbnRyaWVzOiBbXSB9O1xuICAgICAgYWNjW25hbWVdLmVudHJpZXMucHVzaChlbnRyeSk7XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9KTtcbiAgICBmb3IgKGNvbnN0IG5hbWUgaW4gZ3JvdXBlZEVudHJpZXMpIHtcbiAgICAgIGNvbnN0IHsgY2FsbGJhY2ssIGVudHJpZXMgfSA9IGdyb3VwZWRFbnRyaWVzW25hbWVdO1xuICAgICAgY2FsbGJhY2soZW50cmllcywgb25FcnJvciwgcmVzcCwgbGl2ZVNvY2tldCk7XG4gICAgfVxuICB9XG59O1xuXG4vLyBqcy9waG9lbml4X2xpdmVfdmlldy9hcmlhLnRzXG52YXIgQVJJQSA9IHtcbiAgYW55T2YoaW5zdGFuY2UsIGNsYXNzZXMpIHtcbiAgICByZXR1cm4gY2xhc3Nlcy5zb21lKChuYW1lKSA9PiBpbnN0YW5jZSBpbnN0YW5jZW9mIG5hbWUpO1xuICB9LFxuICBpc0ZvY3VzYWJsZShlbCwgaW50ZXJhY3RpdmVPbmx5ID0gZmFsc2UpIHtcbiAgICByZXR1cm4gZWwgaW5zdGFuY2VvZiBIVE1MQW5jaG9yRWxlbWVudCAmJiBlbC5yZWwgIT09IFwiaWdub3JlXCIgfHwgZWwgaW5zdGFuY2VvZiBIVE1MQXJlYUVsZW1lbnQgJiYgZWwuaHJlZiAhPT0gdm9pZCAwIHx8ICEoXCJkaXNhYmxlZFwiIGluIGVsICYmIGVsLmRpc2FibGVkKSAmJiB0aGlzLmFueU9mKGVsLCBbXG4gICAgICBIVE1MSW5wdXRFbGVtZW50LFxuICAgICAgSFRNTFNlbGVjdEVsZW1lbnQsXG4gICAgICBIVE1MVGV4dEFyZWFFbGVtZW50LFxuICAgICAgSFRNTEJ1dHRvbkVsZW1lbnRcbiAgICBdKSB8fCBlbCBpbnN0YW5jZW9mIEhUTUxJRnJhbWVFbGVtZW50IHx8IGVsIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgJiYgZWwudGFiSW5kZXggPj0gMCAmJiBlbC5nZXRBdHRyaWJ1dGUoXCJhcmlhLWhpZGRlblwiKSAhPT0gXCJ0cnVlXCIgfHwgIWludGVyYWN0aXZlT25seSAmJiBlbC5nZXRBdHRyaWJ1dGUoXCJ0YWJpbmRleFwiKSAhPT0gbnVsbCAmJiBlbC5nZXRBdHRyaWJ1dGUoXCJhcmlhLWhpZGRlblwiKSAhPT0gXCJ0cnVlXCI7XG4gIH0sXG4gIGF0dGVtcHRGb2N1cyhlbCwgaW50ZXJhY3RpdmVPbmx5ID0gZmFsc2UpIHtcbiAgICBpZiAodGhpcy5pc0ZvY3VzYWJsZShlbCwgaW50ZXJhY3RpdmVPbmx5KSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgZWwuZm9jdXMoKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gISFkb2N1bWVudC5hY3RpdmVFbGVtZW50ICYmIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQuaXNTYW1lTm9kZShlbCk7XG4gIH0sXG4gIGZvY3VzRmlyc3RJbnRlcmFjdGl2ZShlbCkge1xuICAgIGxldCBjaGlsZCA9IGVsLmZpcnN0RWxlbWVudENoaWxkO1xuICAgIHdoaWxlIChjaGlsZCkge1xuICAgICAgaWYgKHRoaXMuYXR0ZW1wdEZvY3VzKGNoaWxkLCB0cnVlKSB8fCB0aGlzLmZvY3VzRmlyc3RJbnRlcmFjdGl2ZShjaGlsZCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBjaGlsZCA9IGNoaWxkLm5leHRFbGVtZW50U2libGluZztcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9LFxuICBmb2N1c0ZpcnN0KGVsKSB7XG4gICAgbGV0IGNoaWxkID0gZWwuZmlyc3RFbGVtZW50Q2hpbGQ7XG4gICAgd2hpbGUgKGNoaWxkKSB7XG4gICAgICBpZiAodGhpcy5hdHRlbXB0Rm9jdXMoY2hpbGQpIHx8IHRoaXMuZm9jdXNGaXJzdChjaGlsZCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBjaGlsZCA9IGNoaWxkLm5leHRFbGVtZW50U2libGluZztcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9LFxuICBmb2N1c0xhc3QoZWwpIHtcbiAgICBsZXQgY2hpbGQgPSBlbC5sYXN0RWxlbWVudENoaWxkO1xuICAgIHdoaWxlIChjaGlsZCkge1xuICAgICAgaWYgKHRoaXMuYXR0ZW1wdEZvY3VzKGNoaWxkKSB8fCB0aGlzLmZvY3VzTGFzdChjaGlsZCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBjaGlsZCA9IGNoaWxkLnByZXZpb3VzRWxlbWVudFNpYmxpbmc7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcbnZhciBhcmlhX2RlZmF1bHQgPSBBUklBO1xuXG4vLyBqcy9waG9lbml4X2xpdmVfdmlldy9ob29rcy50c1xudmFyIGZpbmRTY3JvbGxDb250YWluZXIgPSAoZWwpID0+IHtcbiAgaWYgKFtcIkhUTUxcIiwgXCJCT0RZXCJdLmluZGV4T2YoZWwubm9kZU5hbWUudG9VcHBlckNhc2UoKSkgPj0gMClcbiAgICByZXR1cm4gbnVsbDtcbiAgaWYgKFtcInNjcm9sbFwiLCBcImF1dG9cIl0uaW5kZXhPZihnZXRDb21wdXRlZFN0eWxlKGVsKS5vdmVyZmxvd1kpID49IDApXG4gICAgcmV0dXJuIGVsO1xuICByZXR1cm4gZmluZFNjcm9sbENvbnRhaW5lcihlbC5wYXJlbnRFbGVtZW50KTtcbn07XG52YXIgc2Nyb2xsVG9wID0gKHNjcm9sbENvbnRhaW5lcikgPT4ge1xuICBpZiAoc2Nyb2xsQ29udGFpbmVyKSB7XG4gICAgcmV0dXJuIHNjcm9sbENvbnRhaW5lci5zY3JvbGxUb3A7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxUb3A7XG4gIH1cbn07XG52YXIgYm90dG9tID0gKHNjcm9sbENvbnRhaW5lcikgPT4ge1xuICBpZiAoc2Nyb2xsQ29udGFpbmVyKSB7XG4gICAgcmV0dXJuIHNjcm9sbENvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5ib3R0b207XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHdpbmRvdy5pbm5lckhlaWdodCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0O1xuICB9XG59O1xudmFyIHRvcCA9IChzY3JvbGxDb250YWluZXIpID0+IHtcbiAgaWYgKHNjcm9sbENvbnRhaW5lcikge1xuICAgIHJldHVybi
1BzY3JvbGxDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAwO1xuICB9XG59O1xudmFyIGlzQXRWaWV3cG9ydFRvcCA9IChlbCwgc2Nyb2xsQ29udGFpbmVyKSA9PiB7XG4gIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgcmV0dXJuIE1hdGguY2VpbChyZWN0LnRvcCkgPj0gdG9wKHNjcm9sbENvbnRhaW5lcikgJiYgTWF0aC5mbG9vcihyZWN0LnRvcCkgPD0gYm90dG9tKHNjcm9sbENvbnRhaW5lcik7XG59O1xudmFyIGlzQXRWaWV3cG9ydEJvdHRvbSA9IChlbCwgc2Nyb2xsQ29udGFpbmVyKSA9PiB7XG4gIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgcmV0dXJuIE1hdGguY2VpbChyZWN0LmJvdHRvbSkgPj0gdG9wKHNjcm9sbENvbnRhaW5lcikgJiYgTWF0aC5mbG9vcihyZWN0LmJvdHRvbSkgPD0gYm90dG9tKHNjcm9sbENvbnRhaW5lcik7XG59O1xudmFyIGlzV2l0aGluVmlld3BvcnQgPSAoZWwsIHNjcm9sbENvbnRhaW5lcikgPT4ge1xuICBjb25zdCByZWN0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gIHJldHVybiBNYXRoLmNlaWwocmVjdC50b3ApID49IHRvcChzY3JvbGxDb250YWluZXIpICYmIE1hdGguZmxvb3IocmVjdC50b3ApIDw9IGJvdHRvbShzY3JvbGxDb250YWluZXIpO1xufTtcbnZhciBJbmZpbml0ZVNjcm9sbCA9IHtcbiAgbW91bnRlZCgpIHtcbiAgICB0aGlzLnNjcm9sbENvbnRhaW5lciA9IGZpbmRTY3JvbGxDb250YWluZXIodGhpcy5lbCk7XG4gICAgbGV0IHNjcm9sbEJlZm9yZSA9IHNjcm9sbFRvcCh0aGlzLnNjcm9sbENvbnRhaW5lcik7XG4gICAgbGV0IHRvcE92ZXJyYW4gPSBmYWxzZTtcbiAgICBjb25zdCB0aHJvdHRsZUludGVydmFsID0gNTAwO1xuICAgIGxldCBwZW5kaW5nT3AgPSBudWxsO1xuICAgIGNvbnN0IG9uVG9wT3ZlcnJ1biA9IHRoaXMudGhyb3R0bGUoXG4gICAgICB0aHJvdHRsZUludGVydmFsLFxuICAgICAgKHRvcEV2ZW50LCBmaXJzdENoaWxkKSA9PiB7XG4gICAgICAgIHBlbmRpbmdPcCA9ICgpID0+IHRydWU7XG4gICAgICAgIHRoaXMubGl2ZVNvY2tldC5qcygpLnB1c2godGhpcy5lbCwgdG9wRXZlbnQsIHtcbiAgICAgICAgICB2YWx1ZTogeyBpZDogZmlyc3RDaGlsZC5pZCwgX292ZXJyYW46IHRydWUgfSxcbiAgICAgICAgICBjYWxsYmFjazogKCkgPT4ge1xuICAgICAgICAgICAgcGVuZGluZ09wID0gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICk7XG4gICAgY29uc3Qgb25GaXJzdENoaWxkQXRUb3AgPSB0aGlzLnRocm90dGxlKFxuICAgICAgdGhyb3R0bGVJbnRlcnZhbCxcbiAgICAgICh0b3BFdmVudCwgZmlyc3RDaGlsZCkgPT4ge1xuICAgICAgICBwZW5kaW5nT3AgPSAoKSA9PiBmaXJzdENoaWxkLnNjcm9sbEludG9WaWV3KHsgYmxvY2s6IFwic3RhcnRcIiB9KTtcbiAgICAgICAgdGhpcy5saXZlU29ja2V0LmpzKCkucHVzaCh0aGlzLmVsLCB0b3BFdmVudCwge1xuICAgICAgICAgIHZhbHVlOiB7IGlkOiBmaXJzdENoaWxkLmlkIH0sXG4gICAgICAgICAgY2FsbGJhY2s6ICgpID0+IHtcbiAgICAgICAgICAgIHBlbmRpbmdPcCA9IG51bGw7XG4gICAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFpc1dpdGhpblZpZXdwb3J0KGZpcnN0Q2hpbGQsIHRoaXMuc2Nyb2xsQ29udGFpbmVyKSkge1xuICAgICAgICAgICAgICAgIGZpcnN0Q2hpbGQuc2Nyb2xsSW50b1ZpZXcoeyBibG9jazogXCJzdGFydFwiIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICk7XG4gICAgY29uc3Qgb25MYXN0Q2hpbGRBdEJvdHRvbSA9IHRoaXMudGhyb3R0bGUoXG4gICAgICB0aHJvdHRsZUludGVydmFsLFxuICAgICAgKGJvdHRvbUV2ZW50LCBsYXN0Q2hpbGQpID0+IHtcbiAgICAgICAgcGVuZGluZ09wID0gKCkgPT4gbGFzdENoaWxkLnNjcm9sbEludG9WaWV3KHsgYmxvY2s6IFwiZW5kXCIgfSk7XG4gICAgICAgIHRoaXMubGl2ZVNvY2tldC5qcygpLnB1c2godGhpcy5lbCwgYm90dG9tRXZlbnQsIHtcbiAgICAgICAgICB2YWx1ZTogeyBpZDogbGFzdENoaWxkLmlkIH0sXG4gICAgICAgICAgY2FsbGJhY2s6ICgpID0+IHtcbiAgICAgICAgICAgIHBlbmRpbmdPcCA9IG51bGw7XG4gICAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFpc1dpdGhpblZpZXdwb3J0KGxhc3RDaGlsZCwgdGhpcy5zY3JvbGxDb250YWluZXIpKSB7XG4gICAgICAgICAgICAgICAgbGFzdENoaWxkLnNjcm9sbEludG9WaWV3KHsgYmxvY2s6IFwiZW5kXCIgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLm9uU2Nyb2xsID0gKF9lKSA9PiB7XG4gICAgICBjb25zdCBzY3JvbGxOb3cgPSBzY3JvbGxUb3AodGhpcy5zY3JvbGxDb250YWluZXIpO1xuICAgICAgaWYgKHBlbmRpbmdPcCkge1xuICAgICAgICBzY3JvbGxCZWZvcmUgPSBzY3JvbGxOb3c7XG4gICAgICAgIHJldHVybiBwZW5kaW5nT3AoKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlY3QgPSB0aGlzLmZpbmRPdmVycnVuVGFyZ2V0KCk7XG4gICAgICBjb25zdCB0b3BFdmVudCA9IHRoaXMuZWwuZ2V0QXR0cmlidXRlKFxuICAgICAgICB0aGlzLmxpdmVTb2NrZXQuYmluZGluZyhcInZpZXdwb3J0LXRvcFwiKVxuICAgICAgKTtcbiAgICAgIGNvbnN0IGJvdHRvbUV2ZW50ID0gdGhpcy5lbC5nZXRBdHRyaWJ1dGUoXG4gICAgICAgIHRoaXMubGl2ZVNvY2tldC5iaW5kaW5nKFwidmlld3BvcnQtYm90dG9tXCIpXG4gICAgICApO1xuICAgICAgY29uc3QgbGFzdENoaWxkID0gdGhpcy5lbC5sYXN0RWxlbWVudENoaWxkO1xuICAgICAgY29uc3QgZmlyc3RDaGlsZCA9IHRoaXMuZWwuZmlyc3RFbGVtZW50Q2hpbGQ7XG4gICAgICBjb25zdCBpc1Njcm9sbGluZ1VwID0gc2Nyb2xsTm93IDwgc2Nyb2xsQmVmb3JlO1xuICAgICAgY29uc3QgaXNTY3JvbGxpbmdEb3duID0gc2Nyb2xsTm93ID4gc2Nyb2xsQmVmb3JlO1xuICAgICAgaWYgKGlzU2Nyb2xsaW5nVXAgJiYgdG9wRXZlbnQgJiYgIXRvcE92ZXJyYW4gJiYgcmVjdC50b3AgPj0gMCkge1xuICAgICAgICB0b3BPdmVycmFuID0gdHJ1ZTtcbiAgICAgICAgb25Ub3BPdmVycnVuKHRvcEV2ZW50LCBmaXJzdENoaWxkKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNTY3JvbGxpbmdEb3duICYmIHRvcE92ZXJyYW4gJiYgcmVjdC50b3AgPD0gMCkge1xuICAgICAgICB0b3BPdmVycmFuID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAodG9wRXZlbnQgJiYgaXNTY3JvbGxpbmdVcCAmJiBmaXJzdENoaWxkICYmIGlzQXRWaWV3cG9ydFRvcChmaXJzdENoaWxkLCB0aGlzLnNjcm9sbENvbnRhaW5lcikpIHtcbiAgICAgICAgb25GaXJzdENoaWxkQXRUb3AodG9wRXZlbnQsIGZpcnN0Q2hpbGQpO1xuICAgICAgfSBlbHNlIGlmIChib3R0b21FdmVudCAmJiBpc1Njcm9sbGluZ0Rvd24gJiYgbGFzdENoaWxkICYmIGlzQXRWaWV3cG9ydEJvdHRvbShsYXN0Q2hpbGQsIHRoaXMuc2Nyb2xsQ29udGFpbmVyKSkge1xuICAgICAgICBvbkxhc3RDaGlsZEF0Qm90dG9tKGJvdHRvbUV2ZW50LCBsYXN0Q2hpbGQpO1xuICAgICAgfVxuICAgICAgc2Nyb2xsQmVmb3JlID0gc2Nyb2xsTm93O1xuICAgIH07XG4gICAgaWYgKHRoaXMuc2Nyb2xsQ29udGFpbmVyKSB7XG4gICAgICB0aGlzLnNjcm9sbENvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsIHRoaXMub25TY3JvbGwpO1xuICAgIH0gZWxzZSB7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLCB0aGlzLm9uU2Nyb2xsKTtcbiAgICB9XG4gI
1H0sXG4gIHVwZGF0ZWQoKSB7XG4gICAgaWYgKHRoaXMuc2Nyb2xsQ29udGFpbmVyICYmICF0aGlzLnNjcm9sbENvbnRhaW5lci5pc0Nvbm5lY3RlZCkge1xuICAgICAgdGhpcy5kZXN0cm95ZWQoKTtcbiAgICAgIHRoaXMubW91bnRlZCgpO1xuICAgIH1cbiAgfSxcbiAgZGVzdHJveWVkKCkge1xuICAgIGlmICh0aGlzLnNjcm9sbENvbnRhaW5lcikge1xuICAgICAgdGhpcy5zY3JvbGxDb250YWluZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLCB0aGlzLm9uU2Nyb2xsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgdGhpcy5vblNjcm9sbCk7XG4gICAgfVxuICB9LFxuICB0aHJvdHRsZShpbnRlcnZhbCwgY2FsbGJhY2spIHtcbiAgICBsZXQgbGFzdENhbGxBdCA9IDA7XG4gICAgbGV0IHRpbWVyO1xuICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IHJlbWFpbmluZ1RpbWUgPSBpbnRlcnZhbCAtIChub3cgLSBsYXN0Q2FsbEF0KTtcbiAgICAgIGlmIChyZW1haW5pbmdUaW1lIDw9IDAgfHwgcmVtYWluaW5nVGltZSA+IGludGVydmFsKSB7XG4gICAgICAgIGlmICh0aW1lcikge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICAgICAgdGltZXIgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGxhc3RDYWxsQXQgPSBub3c7XG4gICAgICAgIGNhbGxiYWNrKC4uLmFyZ3MpO1xuICAgICAgfSBlbHNlIGlmICghdGltZXIpIHtcbiAgICAgICAgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBsYXN0Q2FsbEF0ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICB0aW1lciA9IG51bGw7XG4gICAgICAgICAgY2FsbGJhY2soLi4uYXJncyk7XG4gICAgICAgIH0sIHJlbWFpbmluZ1RpbWUpO1xuICAgICAgfVxuICAgIH07XG4gIH0sXG4gIGZpbmRPdmVycnVuVGFyZ2V0KCkge1xuICAgIGxldCByZWN0O1xuICAgIGNvbnN0IG92ZXJydW5UYXJnZXQgPSB0aGlzLmVsLmdldEF0dHJpYnV0ZShcbiAgICAgIHRoaXMubGl2ZVNvY2tldC5iaW5kaW5nKFBIWF9WSUVXUE9SVF9PVkVSUlVOX1RBUkdFVClcbiAgICApO1xuICAgIGlmIChvdmVycnVuVGFyZ2V0KSB7XG4gICAgICBjb25zdCBvdmVycnVuRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChvdmVycnVuVGFyZ2V0KTtcbiAgICAgIGlmIChvdmVycnVuRWwpIHtcbiAgICAgICAgcmVjdCA9IG92ZXJydW5FbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcImRpZCBub3QgZmluZCBlbGVtZW50IHdpdGggaWQgXCIgKyBvdmVycnVuVGFyZ2V0KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmVjdCA9IHRoaXMuZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgfVxuICAgIHJldHVybiByZWN0O1xuICB9XG59O1xudmFyIExpdmVGaWxlVXBsb2FkID0ge1xuICBhY3RpdmVSZWZzKCkge1xuICAgIHJldHVybiB0aGlzLmVsLmdldEF0dHJpYnV0ZShQSFhfQUNUSVZFX0VOVFJZX1JFRlMpO1xuICB9LFxuICBwcmVmbGlnaHRlZFJlZnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZWwuZ2V0QXR0cmlidXRlKFBIWF9QUkVGTElHSFRFRF9SRUZTKTtcbiAgfSxcbiAgbW91bnRlZCgpIHtcbiAgICB0aGlzLmpzKCkuaWdub3JlQXR0cmlidXRlcyh0aGlzLmVsLCBbXCJ2YWx1ZVwiXSk7XG4gICAgdGhpcy5wcmVmbGlnaHRlZFdhcyA9IHRoaXMucHJlZmxpZ2h0ZWRSZWZzKCk7XG4gIH0sXG4gIHVwZGF0ZWQoKSB7XG4gICAgY29uc3QgbmV3UHJlZmxpZ2h0cyA9IHRoaXMucHJlZmxpZ2h0ZWRSZWZzKCk7XG4gICAgaWYgKHRoaXMucHJlZmxpZ2h0ZWRXYXMgIT09IG5ld1ByZWZsaWdodHMpIHtcbiAgICAgIHRoaXMucHJlZmxpZ2h0ZWRXYXMgPSBuZXdQcmVmbGlnaHRzO1xuICAgICAgaWYgKG5ld1ByZWZsaWdodHMgPT09IFwiXCIpIHtcbiAgICAgICAgdGhpcy5fX3ZpZXcoKS5jYW5jZWxTdWJtaXQodGhpcy5lbC5mb3JtKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRoaXMuYWN0aXZlUmVmcygpID09PSBcIlwiKSB7XG4gICAgICB0aGlzLmVsLnZhbHVlID0gXCJcIjtcbiAgICB9XG4gICAgdGhpcy5lbC5kaXNwYXRjaEV2ZW50KG5ldyBDdXN0b21FdmVudChQSFhfTElWRV9GSUxFX1VQREFURUQpKTtcbiAgfVxufTtcbnZhciBMaXZlSW1nUHJldmlldyA9IHtcbiAgbW91bnRlZCgpIHtcbiAgICB0aGlzLnJlZiA9IHRoaXMuZWwuZ2V0QXR0cmlidXRlKFwiZGF0YS1waHgtZW50cnktcmVmXCIpO1xuICAgIHRoaXMuaW5wdXRFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFxuICAgICAgdGhpcy5lbC5nZXRBdHRyaWJ1dGUoUEhYX1VQTE9BRF9SRUYpXG4gICAgKTtcbiAgICB0aGlzLnVybCA9IExpdmVVcGxvYWRlci5nZXRFbnRyeURhdGFVUkwodGhpcy5pbnB1dEVsLCB0aGlzLnJlZik7XG4gICAgdGhpcy5lbC5zcmMgPSB0aGlzLnVybDtcbiAgfSxcbiAgZGVzdHJveWVkKCkge1xuICAgIFVSTC5yZXZva2VPYmplY3RVUkwodGhpcy51cmwpO1xuICB9XG59O1xudmFyIEhvb2tzID0ge1xuICBMaXZlRmlsZVVwbG9hZCxcbiAgTGl2ZUltZ1ByZXZpZXcsXG4gIEZvY3VzV3JhcDoge1xuICAgIG1vdW50ZWQoKSB7XG4gICAgICB0aGlzLmZvY3VzU3RhcnQgPSB0aGlzLmVsLmZpcnN0RWxlbWVudENoaWxkO1xuICAgICAgdGhpcy5mb2N1c0VuZCA9IHRoaXMuZWwubGFzdEVsZW1lbnRDaGlsZDtcbiAgICAgIHRoaXMuZm9jdXNTdGFydC5hZGRFdmVudExpc3RlbmVyKFwiZm9jdXNcIiwgKGUpID0+IHtcbiAgICAgICAgaWYgKCFlLnJlbGF0ZWRUYXJnZXQgfHwgIXRoaXMuZWwuY29udGFpbnMoZS5yZWxhdGVkVGFyZ2V0KSkge1xuICAgICAgICAgIGNvbnN0IG5leHRGb2N1cyA9IGUudGFyZ2V0Lm5leHRFbGVtZW50U2libGluZztcbiAgICAgICAgICBhcmlhX2RlZmF1bHQuYXR0ZW1wdEZvY3VzKG5leHRGb2N1cykgfHwgYXJpYV9kZWZhdWx0LmZvY3VzRmlyc3QobmV4dEZvY3VzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhcmlhX2RlZmF1bHQuZm9jdXNMYXN0KHRoaXMuZWwpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuZm9jdXNFbmQuYWRkRXZlbnRMaXN0ZW5lcihcImZvY3VzXCIsIChlKSA9PiB7XG4gICAgICAgIGlmICghZS5yZWxhdGVkVGFyZ2V0IHx8ICF0aGlzLmVsLmNvbnRhaW5zKGUucmVsYXRlZF
1RhcmdldCkpIHtcbiAgICAgICAgICBjb25zdCBuZXh0Rm9jdXMgPSBlLnRhcmdldC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nO1xuICAgICAgICAgIGFyaWFfZGVmYXVsdC5hdHRlbXB0Rm9jdXMobmV4dEZvY3VzKSB8fCBhcmlhX2RlZmF1bHQuZm9jdXNMYXN0KG5leHRGb2N1cyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYXJpYV9kZWZhdWx0LmZvY3VzRmlyc3QodGhpcy5lbCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKCF0aGlzLmVsLmNvbnRhaW5zKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpKSB7XG4gICAgICAgIHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcihcInBoeDpzaG93LWVuZFwiLCAoKSA9PiB0aGlzLmVsLmZvY3VzKCkpO1xuICAgICAgICBpZiAod2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5lbCkuZGlzcGxheSAhPT0gXCJub25lXCIpIHtcbiAgICAgICAgICBhcmlhX2RlZmF1bHQuZm9jdXNGaXJzdCh0aGlzLmVsKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgSW5maW5pdGVTY3JvbGxcbn07XG52YXIgaG9va3NfZGVmYXVsdCA9IEhvb2tzO1xuXG4vLyBqcy9waG9lbml4X2xpdmVfdmlldy9lbGVtZW50X3JlZi50c1xudmFyIEVsZW1lbnRSZWYgPSBjbGFzcyB7XG4gIHN0YXRpYyBvblVubG9jayhlbCwgY2FsbGJhY2spIHtcbiAgICBpZiAoIWRvbV9kZWZhdWx0LmlzTG9ja2VkKGVsKSAmJiAhZWwuY2xvc2VzdChgWyR7UEhYX1JFRl9MT0NLfV1gKSkge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfVxuICAgIGNvbnN0IGNsb3Nlc3RMb2NrID0gZWwuY2xvc2VzdChgWyR7UEhYX1JFRl9MT0NLfV1gKTtcbiAgICBjb25zdCByZWYgPSBjbG9zZXN0TG9jay5jbG9zZXN0KGBbJHtQSFhfUkVGX0xPQ0t9XWApLmdldEF0dHJpYnV0ZShQSFhfUkVGX0xPQ0spO1xuICAgIGNsb3Nlc3RMb2NrLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBgcGh4OnVuZG8tbG9jazoke3JlZn1gLFxuICAgICAgKCkgPT4ge1xuICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgfSxcbiAgICAgIHsgb25jZTogdHJ1ZSB9XG4gICAgKTtcbiAgfVxuICBjb25zdHJ1Y3RvcihlbCkge1xuICAgIHRoaXMuZWwgPSBlbDtcbiAgICB0aGlzLmxvYWRpbmdSZWYgPSBlbC5oYXNBdHRyaWJ1dGUoUEhYX1JFRl9MT0FESU5HKSA/IHBhcnNlSW50KGVsLmdldEF0dHJpYnV0ZShQSFhfUkVGX0xPQURJTkcpLCAxMCkgOiBudWxsO1xuICAgIHRoaXMubG9ja1JlZiA9IGVsLmhhc0F0dHJpYnV0ZShQSFhfUkVGX0xPQ0spID8gcGFyc2VJbnQoZWwuZ2V0QXR0cmlidXRlKFBIWF9SRUZfTE9DSyksIDEwKSA6IG51bGw7XG4gIH1cbiAgLy8gcHVibGljXG4gIG1heWJlVW5kbyhyZWYsIHBoeEV2ZW50LCBlYWNoQ2xvbmVDYWxsYmFjaykge1xuICAgIGlmICghdGhpcy5pc1dpdGhpbihyZWYpKSB7XG4gICAgICBkb21fZGVmYXVsdC51cGRhdGVQcml2YXRlKHRoaXMuZWwsIFBIWF9QRU5ESU5HX1JFRlMsIFtdLCAocGVuZGluZ1JlZnMpID0+IHtcbiAgICAgICAgcGVuZGluZ1JlZnMucHVzaChyZWYpO1xuICAgICAgICByZXR1cm4gcGVuZGluZ1JlZnM7XG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy51bmRvTG9ja3MocmVmLCBwaHhFdmVudCwgZWFjaENsb25lQ2FsbGJhY2spO1xuICAgIHRoaXMudW5kb0xvYWRpbmcocmVmLCBwaHhFdmVudCk7XG4gICAgZG9tX2RlZmF1bHQudXBkYXRlUHJpdmF0ZSh0aGlzLmVsLCBQSFhfUEVORElOR19SRUZTLCBbXSwgKHBlbmRpbmdSZWZzKSA9PiB7XG4gICAgICByZXR1cm4gcGVuZGluZ1JlZnMuZmlsdGVyKChwZW5kaW5nUmVmKSA9PiB7XG4gICAgICAgIGxldCBvcHRzID0ge1xuICAgICAgICAgIGRldGFpbDogeyByZWY6IHBlbmRpbmdSZWYsIGV2ZW50OiBwaHhFdmVudCB9LFxuICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2VcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHRoaXMubG9hZGluZ1JlZiAmJiB0aGlzLmxvYWRpbmdSZWYgPiBwZW5kaW5nUmVmKSB7XG4gICAgICAgICAgdGhpcy5lbC5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KGBwaHg6dW5kby1sb2FkaW5nOiR7cGVuZGluZ1JlZn1gLCBvcHRzKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMubG9ja1JlZiAmJiB0aGlzLmxvY2tSZWYgPiBwZW5kaW5nUmVmKSB7XG4gICAgICAgICAgdGhpcy5lbC5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KGBwaHg6dW5kby1sb2NrOiR7cGVuZGluZ1JlZn1gLCBvcHRzKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBlbmRpbmdSZWYgPiByZWY7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBpZiAodGhpcy5pc0Z1bGx5UmVzb2x2ZWRCeShyZWYpKSB7XG4gICAgICB0aGlzLmVsLnJlbW92ZUF0dHJpYnV0ZShQSFhfUkVGX1NSQyk7XG4gICAgfVxuICB9XG4gIC8vIHByaXZhdGVcbiAgaXNXaXRoaW4ocmVmKSB7XG4gICAgcmV0dXJuICEodGhpcy5sb2FkaW5nUmVmICE9PSBudWxsICYmIHRoaXMubG9hZGluZ1JlZiA+IHJlZiAmJiB0aGlzLmxvY2tSZWYgIT09IG51bGwgJiYgdGhpcy5sb2NrUmVmID4gcmVmKTtcbiAgfVxuICAvLyBDaGVjayBmb3IgY2xvbmVkIFBIWF9SRUZfTE9DSyBlbGVtZW50IHRoYXQgaGFzIGJlZW4gbW9ycGhlZCBiZWhpbmRcbiAgLy8gdGhlIHNjZW5lcyB3aGlsZSB0aGlzIGVsZW1lbnQgd2FzIGxvY2tlZCBpbiB0aGUgRE9NLlxuICAvLyBXaGVuIHdlIGFwcGx5IHRoZSBjbG9uZWQgdHJlZSB0byB0aGUgYWN0aXZlIERPTSBlbGVtZW50LCB3ZSBtdXN0XG4gIC8vXG4gIC8vICAgMS4gZXhlY3V0ZSBwZW5kaW5nIG1vdW50ZWQgaG9va3MgZm9yIG5vZGVzIG5vdyBpbiB0aGUgRE9NXG4gIC8vICAgMi4gdW5kbyBhbnkgcmVmIGluc2lkZSB0aGUgY2xvbmVkIHRyZWUgdGhhdCBoYXMgc2luY2UgYmVlbiBhY2snZFxuICB1bmRvTG9ja3MocmVmLCBwaHhFdmVudCwgZWFjaENsb25lQ2FsbGJhY2spIHtcbiAgICBpZiAoIXRoaXMuaXNMb2NrVW5kb25lQnkocmVmKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBjbG9uZWRUcmVlID0gZG9tX2RlZmF1bHQucHJpdmF0ZSh0aGlzLmVsLCBQSFhfUkVGX0xPQ0spO1xuICAgIGlmIChjbG9uZWRUcmVlKSB7XG4gICAgICBlYWNoQ2xvbmVDYWxsYmFjayhjbG9uZWRUcmVlKTtcbiAgICAgIGRvbV9kZWZhdWx0LmRlbGV0ZVByaXZhdGUodGhpcy5lbCwgUEhYX1JFRl9MT0NLKTtcbiAgICB9XG4gICAgdGhpcy5lbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1JFRl9MT0NLKTtcbiAgICBjb25zdCBvcHRzID0ge1xuICAgICAgZGV0YWlsOiB7IHJlZiwgZXZlbnQ6IHBoeEV2ZW50IH0sXG4gICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgY2FuY2VsYWJsZTogZmFsc2VcbiAgICB9O1xuICAgIHRoaXMuZWwuZGlzcGF0Y2hFdmVudChcbiAgICAgIG5ldyBDdXN0b21FdmVudChgcGh4OnVuZG8tbG9jazoke3RoaXMubG9ja1JlZn1gLCBvcHRzKVxuICAgICk7XG4gIH1cbiAgdW5kb0xvYWRpbmcocmVmLCBwaHhFdmVudCkge1xuICAgIGlmICghdGhpcy5pc0xvYWRpbmdVbmRvbmVCeShyZWYpKSB7XG4gICAgICBpZiAodGhpcy5jYW5VbmRvTG9hZGluZyhyZWYpICYmIHRoaXMuZWwuY2xhc3NMaXN0LmNvbnRhaW5zKFwicGh4LXN1Ym1pdC1sb2FkaW5nXCIpKSB7XG4gICAgICAgI
1HRoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZShcInBoeC1jaGFuZ2UtbG9hZGluZ1wiKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuY2FuVW5kb0xvYWRpbmcocmVmKSkge1xuICAgICAgdGhpcy5lbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1JFRl9MT0FESU5HKTtcbiAgICAgIGNvbnN0IGRpc2FibGVkVmFsID0gdGhpcy5lbC5nZXRBdHRyaWJ1dGUoUEhYX0RJU0FCTEVEKTtcbiAgICAgIGNvbnN0IHJlYWRPbmx5VmFsID0gdGhpcy5lbC5nZXRBdHRyaWJ1dGUoUEhYX1JFQURPTkxZKTtcbiAgICAgIGlmIChyZWFkT25seVZhbCAhPT0gbnVsbCAmJiBcInJlYWRPbmx5XCIgaW4gdGhpcy5lbCkge1xuICAgICAgICB0aGlzLmVsLnJlYWRPbmx5ID0gcmVhZE9ubHlWYWwgPT09IFwidHJ1ZVwiID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgICB0aGlzLmVsLnJlbW92ZUF0dHJpYnV0ZShQSFhfUkVBRE9OTFkpO1xuICAgICAgfVxuICAgICAgaWYgKGRpc2FibGVkVmFsICE9PSBudWxsICYmIFwiZGlzYWJsZWRcIiBpbiB0aGlzLmVsKSB7XG4gICAgICAgIHRoaXMuZWwuZGlzYWJsZWQgPSBkaXNhYmxlZFZhbCA9PT0gXCJ0cnVlXCIgPyB0cnVlIDogZmFsc2U7XG4gICAgICAgIHRoaXMuZWwucmVtb3ZlQXR0cmlidXRlKFBIWF9ESVNBQkxFRCk7XG4gICAgICB9XG4gICAgICBjb25zdCBkaXNhYmxlUmVzdG9yZSA9IHRoaXMuZWwuZ2V0QXR0cmlidXRlKFBIWF9ESVNBQkxFX1dJVEhfUkVTVE9SRSk7XG4gICAgICBpZiAoZGlzYWJsZVJlc3RvcmUgIT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5lbC50ZXh0Q29udGVudCA9IGRpc2FibGVSZXN0b3JlO1xuICAgICAgICB0aGlzLmVsLnJlbW92ZUF0dHJpYnV0ZShQSFhfRElTQUJMRV9XSVRIX1JFU1RPUkUpO1xuICAgICAgfVxuICAgICAgY29uc3Qgb3B0cyA9IHtcbiAgICAgICAgZGV0YWlsOiB7IHJlZiwgZXZlbnQ6IHBoeEV2ZW50IH0sXG4gICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgIGNhbmNlbGFibG
1U6IGZhbHNlXG4gICAgICB9O1xuICAgICAgdGhpcy5lbC5kaXNwYXRjaEV2ZW50KFxuICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoYHBoeDp1bmRvLWxvYWRpbmc6JHt0aGlzLmxvYWRpbmdSZWZ9YCwgb3B0cylcbiAgICAgICk7XG4gICAgfVxuICAgIFBIWF9FVkVOVF9DTEFTU0VTLmZvckVhY2goKG5hbWUpID0+IHtcbiAgICAgIGlmIChuYW1lICE9PSBcInBoeC1zdWJtaXQtbG9hZGluZ1wiIHx8IHRoaXMuY2FuVW5kb0xvYWRpbmcocmVmKSkge1xuICAgICAgICBkb21fZGVmYXVsdC5yZW1vdmVDbGFzcyh0aGlzLmVsLCBuYW1lKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICBpc0xvYWRpbmdVbmRvbmVCeShyZWYpIHtcbiAgICByZXR1cm4gdGhpcy5sb2FkaW5nUmVmID09PSBudWxsID8gZmFsc2UgOiB0aGlzLmxvYWRpbmdSZWYgPD0gcmVmO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgaXNMb2NrVW5kb25lQnkocmVmKSB7XG4gICAgcmV0dXJuIHRoaXMubG9ja1JlZiA9PT0gbnVsbCA/IGZhbHNlIDogdGhpcy5sb2NrUmVmIDw9IHJlZjtcbiAgfVxuICBpc0Z1bGx5UmVzb2x2ZWRCeShyZWYpIHtcbiAgICByZXR1cm4gKHRoaXMubG9hZGluZ1JlZiA9PT0gbnVsbCB8fCB0aGlzLmxvYWRpbmdSZWYgPD0gcmVmKSAmJiAodGhpcy5sb2NrUmVmID09PSBudWxsIHx8IHRoaXMubG9ja1JlZiA8PSByZWYpO1xuICB9XG4gIC8vIG9ubHkgcmVtb3ZlIHRoZSBwaHgtc3VibWl0LWxvYWRpbmcgY2xhc3MgaWYgd2UgYXJlIG5vdCBsb2NrZWRcbiAgY2FuVW5kb0xvYWRpbmcocmVmKSB7XG4gICAgcmV0dXJuIHRoaXMubG9ja1JlZiA9PT0gbnVsbCB8fCB0aGlzLmxvY2tSZWYgPD0gcmVmO1xuICB9XG59O1xuXG4vLyBqcy9waG9lbml4X2xpdmVfdmlldy9kb21fcG9zdF9tb3JwaF9yZXN0b3Jlci50c1xudmFyIERPTVBvc3RNb3JwaFJlc3RvcmVyID0gY2xhc3Mge1xuICBjb25zdHJ1Y3Rvcihjb250YWluZXJCZWZvcmUsIGNvbnRhaW5lckFmdGVyLCB1cGRhdGVUeXBlKSB7XG4gICAgY29uc3QgaWRzQmVmb3JlID0gLyogQF9fUFVSRV9fICovIG5ldyBTZXQoKTtcbiAgICBjb25zdCBpZHNBZnRlciA9IG5ldyBTZXQoXG4gICAgICBbLi4uY29udGFpbmVyQWZ0ZXIuY2hpbGRyZW5dLm1hcCgoY2hpbGQpID0+IGNoaWxkLmlkKVxuICAgICk7XG4gICAgY29uc3QgZWxlbWVudHNUb01vZGlmeSA9IFtdO1xuICAgIEFycmF5LmZyb20oY29udGFpbmVyQmVmb3JlLmNoaWxkcmVuKS5mb3JFYWNoKChjaGlsZCkgPT4ge1xuICAgICAgaWYgKGNoaWxkLmlkKSB7XG4gICAgICAgIGlkc0JlZm9yZS5hZGQoY2hpbGQuaWQpO1xuICAgICAgICBpZiAoaWRzQWZ0ZXIuaGFzKGNoaWxkLmlkKSkge1xuICAgICAgICAgIGNvbnN0IHByZXZpb3VzRWxlbWVudElkID0gY2hpbGQucHJldmlvdXNFbGVtZW50U2libGluZyAmJiBjaGlsZC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nLmlkO1xuICAgICAgICAgIGVsZW1lbnRzVG9Nb2RpZnkucHVzaCh7XG4gICAgICAgICAgICBlbGVtZW50SWQ6IGNoaWxkLmlkLFxuICAgICAgICAgICAgcHJldmlvdXNFbGVtZW50SWRcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMuY29udGFpbmVySWQgPSBjb250YWluZXJBZnRlci5pZDtcbiAgICB0aGlzLnVwZGF0ZVR5cGUgPSB1cGRhdGVUeXBlO1xuICAgIHRoaXMuZWxlbWVudHNUb01vZGlmeSA9IGVsZW1lbnRzVG9Nb2RpZnk7XG4gICAgdGhpcy5lbGVtZW50SWRzVG9BZGQgPSBbLi4uaWRzQWZ0ZXJdLmZpbHRlcigoaWQpID0+ICFpZHNCZWZvcmUuaGFzKGlkKSk7XG4gIH1cbiAgLy8gV2UgZG8gdGhlIGZvbGxvd2luZyB0byBvcHRpbWl6ZSBhcHBlbmQvcHJlcGVuZCBvcGVyYXRpb25zOlxuICAvLyAgIDEpIFRyYWNrIGlkcyBvZiBtb2RpZmllZCBlbGVtZW50cyAmIG9mIG5ldyBlbGVtZW50c1xuICAvLyAgIDIpIEFsbCB0aGUgbW9kaWZpZWQgZWxlbWVudHMgYXJlIHB1dCBiYWNrIGluIHRoZSBjb3JyZWN0IHBvc2l0aW9uIGluIHRoZSBET00gdHJlZVxuICAvLyAgICAgIGJ5IHN0b3JpbmcgdGhlIGlkIG9mIHRoZWlyIHByZXZpb3VzIHNpYmxpbmdcbiAgLy8gICAzKSBOZXcgZWxlbWVudHMgYXJlIGdvaW5nIHRvIGJlIHB1dCBpbiB0aGUgcmlnaHQgcGxhY2UgYnkgbW9ycGhkb20gZHVyaW5nIGFwcGVuZC5cbiAgLy8gICAgICBGb3IgcHJlcGVuZCwgd2UgbW92ZSB0aGVtIHRvIHRoZSBmaXJzdCBwb3NpdGlvbiBpbiB0aGUgY29udGFpbmVyXG4gIHBlcmZvcm0oKSB7XG4gICAgY29uc3QgY29udGFpbmVyID0gZG9tX2RlZmF1bHQuYnlJZCh0aGlzLmNvbnRhaW5lcklkKTtcbiAgICBpZiAoIWNvbnRhaW5lcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmVsZW1lbnRzVG9Nb2RpZnkuZm9yRWFjaCgoZWxlbWVudFRvTW9kaWZ5KSA9PiB7XG4gICAgICBpZiAoZWxlbWVudFRvTW9kaWZ5LnByZXZpb3VzRWxlbWVudElkKSB7XG4gICAgICAgIG1heWJlKFxuICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW1lbnRUb01vZGlmeS5wcmV2aW91c0VsZW1lbnRJZCksXG4gICAgICAgICAgKHByZXZpb3VzRWxlbSkgPT4ge1xuICAgICAgICAgICAgbWF5YmUoXG4gICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW1lbnRUb01vZGlmeS5lbGVtZW50SWQpLFxuICAgICAgICAgICAgICAoZWxlbSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGlzSW5SaWdodFBsYWNlID0gZWxlbS5wcmV2aW91c0VsZW1lbnRTaWJsaW5nICYmIGVsZW0ucHJldmlvdXNFbGVtZW50U2libGluZy5pZCA9PSBwcmV2aW91c0VsZW0uaWQ7XG4gICAgICAgICAgICAgICAgaWYgKCFpc0luUmlnaHRQbGFjZSkge1xuICAgICAgICAgICAgICAgICAgcHJldmlvdXNFbGVtLmluc2VydEFkamFjZW50RWxlbWVudChcImFmdGVyZW5kXCIsIGVsZW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtYXliZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtZW50VG9Nb2RpZnkuZWxlbWVudElkKSwgKGVsZW0pID0+IHtcbiAgICAgICAgICBjb25zdCBpc0luUmlnaHRQbGFjZSA9IGVsZW0ucHJldmlvdXNFbGVtZW50U2libGluZyA9PSBudWxsO1xuICAgICAgICAgIGlmICghaXNJblJpZ2h0UGxhY2UpIHtcbiAgICAgICAgICAgIGNvbnRhaW5lci5pbnNlcnRBZGphY2VudEVsZW1lbnQoXCJhZnRlcmJlZ2luXCIsIGVsZW0pO1xuICAgICAgICAgI
1H1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKHRoaXMudXBkYXRlVHlwZSA9PSBcInByZXBlbmRcIikge1xuICAgICAgdGhpcy5lbGVtZW50SWRzVG9BZGQucmV2ZXJzZSgpLmZvckVhY2goKGVsZW1JZCkgPT4ge1xuICAgICAgICBtYXliZShcbiAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtSWQpLFxuICAgICAgICAgIChlbGVtKSA9PiBjb250YWluZXIuaW5zZXJ0QWRqYWNlbnRFbGVtZW50KFwiYWZ0ZXJiZWdpblwiLCBlbGVtKVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59O1xuXG4vLyAuLi9ub2RlX21vZHVsZXMvbW9ycGhkb20vZGlzdC9tb3JwaGRvbS1lc20uanNcbnZhciBET0NVTUVOVF9GUkFHTUVOVF9OT0RFID0gMTE7XG5mdW5jdGlvbiBtb3JwaEF0dHJzKGZyb21Ob2RlLCB0b05vZGUpIHtcbiAgdmFyIHRvTm9kZUF0dHJzID0gdG9Ob2RlLmF0dHJpYnV0ZXM7XG4gIHZhciBhdHRyO1xuICB2YXIgYXR0ck5hbWU7XG4gIHZhciBhdHRyTmFtZXNwYWNlVVJJO1xuICB2YXIgYXR0clZhbHVlO1xuICB2YXIgZnJvbVZhbHVlO1xuICBpZiAodG9Ob2RlLm5vZGVUeXBlID09PSBET0NVTUVOVF9GUkFHTUVOVF9OT0RFIHx8IGZyb21Ob2RlLm5vZGVUeXBlID09PSBET0NVTUVOVF9GUkFHTUVOVF9OT0RFKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGZvciAodmFyIGkgPSB0b05vZGVBdHRycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGF0dHIgPSB0b05vZGVBdHRyc1tpXTtcbiAgICBhdHRyTmFtZSA9IGF0dHIubmFtZTtcbiAgICBhdHRyTmFtZXNwYWNlVVJJID0gYXR0ci5uYW1lc3BhY2VVUkk7XG4gICAgYXR0clZhbHVlID0gYXR0ci52YWx1ZTtcbiAgICBpZiAoYXR0ck5hbWVzcGFjZVVSSSkge1xuICAgICAgYXR0ck5hbWUgPSBhdHRyLmxvY2FsTmFtZSB8fCBhdHRyTmFtZTtcbiAgICAgIGZyb21WYWx1ZSA9IGZyb21Ob2RlLmdldEF0dHJpYnV0ZU5TKGF0dHJOYW1lc3BhY2VVUkksIGF0dHJOYW1lKTtcbiAgICAgIGlmIChmcm9tVmFsdWUgIT09IGF0dHJWYWx1ZSkge1xuICAgICAgICBpZiAoYXR0ci5wcmVmaXggPT09IFwieG1sbnNcIikge1xuICAgICAgICAgIGF0dHJOYW1lID0gYXR0ci5uYW1lO1xuICAgICAgICB9XG4gICAgICAgIGZyb21Ob2RlLnNldEF0dHJpYnV0ZU5TKGF0dHJOYW1lc3BhY2VVUkksIGF0dHJOYW1lLCBhdHRyVmFsdWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmcm9tVmFsdWUgPSBmcm9tTm9kZS5nZXRBdHRyaWJ1dGUoYXR0ck5hbWUpO1xuICAgICAgaWYgKGZyb21WYWx1ZSAhPT0gYXR0clZhbHVlKSB7XG4gICAgICAgIGZyb21Ob2RlLnNldEF0dHJpYnV0ZShhdHRyTmFtZSwgYXR0clZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgdmFyIGZyb21Ob2RlQXR0cnMgPSBmcm9tTm9kZS5hdHRyaWJ1dGVzO1xuICBmb3IgKHZhciBkID0gZnJvbU5vZGVBdHRycy5sZW5ndGggLSAxOyBkID49IDA7IGQtLSkge1xuICAgIGF0dHIgPSBmcm9tTm9kZUF0dHJzW2RdO1xuICAgIGF0dHJOYW1lID0gYXR0ci5uYW1lO1xuICAgIGF0dHJOYW1lc3BhY2VVUkkgPSBhdHRyLm5hbWVzcGFjZVVSSTtcbiAgICBpZiAoYXR0ck5hbWVzcGFjZVVSSSkge1xuICAgICAgYXR0ck5hbWUgPSBhdHRyLmxvY2FsTmFtZSB8fCBhdHRyTmFtZTtcbiAgICAgIGlmICghdG9Ob2RlLmhhc0F0dHJpYnV0ZU5TKGF0dHJOYW1lc3BhY2VVUkksIGF0dHJOYW1lKSkge1xuICAgICAgICBmcm9tTm9kZS5yZW1vdmVBdHRyaWJ1dGVOUyhhdHRyTmFtZXNwYWNlVVJJLCBhdHRyTmFtZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdG9Ob2RlLmhhc0F0dHJpYnV0ZShhdHRyTmFtZSkpIHtcbiAgICAgICAgZnJvbU5vZGUucmVtb3ZlQXR0cmlidXRlKGF0dHJOYW1lKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbnZhciByYW5nZTtcbnZhciBOU19YSFRNTCA9IFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiO1xudmFyIGRvYyA9IHR5cGVvZiBkb2N1bWVudCA9PT0gXCJ1bmRlZmluZWRcIiA/IHZvaWQgMCA6IGRvY3VtZW50O1xudmFyIEhBU19URU1QTEFURV9TVVBQT1JUID0gISFkb2MgJiYgXCJjb250ZW50XCIgaW4gZG9jLmNyZWF0ZUVsZW1lbnQoXCJ0ZW1wbGF0ZVwiKTtcbnZhciBIQVNfUkFOR0VfU1VQUE9SVCA9ICEhZG9jICYmIGRvYy5jcmVhdGVSYW5nZSAmJiBcImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudFwiIGluIGRvYy5jcmVhdGVSYW5nZSgpO1xuZnVuY3Rpb24gY3JlYXRlRnJhZ21lbnRGcm9tVGVtcGxhdGUoc3RyKSB7XG4gIHZhciB0ZW1wbGF0ZSA9IGRvYy5jcmVhdGVFbGVtZW50KFwidGVtcGxhdGVcIik7XG4gIHRlbXBsYXRlLmlubmVySFRNTCA9IHN0cjtcbiAgcmV0dXJuIHRlbXBsYXRlLmNvbnRlbnQuY2hpbGROb2Rlc1swXTtcbn1cbmZ1bmN0aW9uIGNyZWF0ZUZyYWdtZW50RnJvbVJhbmdlKHN0cikge1xuICBpZiAoIXJhbmdlKSB7XG4gICAgcmFuZ2UgPSBkb2MuY3JlYXRlUmFuZ2UoKTtcbiAgICByYW5nZS5zZWxlY3ROb2RlKGRvYy5ib2R5KTtcbiAgfVxuICB2YXIgZnJhZ21lbnQgPSByYW5nZS5jcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQoc3RyKTtcbiAgcmV0dXJuIGZyYWdtZW50LmNoaWxkTm9kZXNbMF07XG59XG5mdW5jdGlvbiBjcmVhdGVGcmFnbWVudEZyb21XcmFwKHN0cikge1xuICB2YXIgZnJhZ21lbnQgPSBkb2MuY3JlYXRlRWxlbWVudChcImJvZHlcIik7XG4gIGZyYWdtZW50LmlubmVySFRNTCA9IHN0cjtcbiAgcmV0dXJuIGZyYWdtZW50LmNoaWxkTm9kZXNbMF07XG59XG5mdW5jdGlvbiB0b0VsZW1lbnQoc3RyKSB7XG4gIHN0ciA9IHN0ci50cmltKCk7XG4gIGlmIChIQVNfVEVNUExBVEVfU1VQUE9SVCkge1xuICAgIHJldHVybiBjcmVhdGVGcmFnbWVudEZyb21UZW1wbGF0ZShzdHIpO1xuICB9IGVsc2UgaWYgKEhBU19SQU5HRV9TVVBQT1JUKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUZyYWdtZW50RnJvbVJhbmdlKHN0cik7XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUZyYWdtZW50RnJvbVdyYXAoc3RyKTtcbn1cbmZ1bmN0aW9uIGNvbXBhcmVOb2RlTmFtZXMoZnJvbUVsLCB0b0VsKSB7XG4gIHZhciBmcm9tTm9kZU5hbWUgPSBmcm9tRWwubm9kZU5hbWU7XG4gIHZhciB0b05vZGVOYW1lID0gdG9FbC5ub2RlTmFtZTtcbiAgdmFyIGZyb21
1Db2RlU3RhcnQsIHRvQ29kZVN0YXJ0O1xuICBpZiAoZnJvbU5vZGVOYW1lID09PSB0b05vZGVOYW1lKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgZnJvbUNvZGVTdGFydCA9IGZyb21Ob2RlTmFtZS5jaGFyQ29kZUF0KDApO1xuICB0b0NvZGVTdGFydCA9IHRvTm9kZU5hbWUuY2hhckNvZGVBdCgwKTtcbiAgaWYgKGZyb21Db2RlU3RhcnQgPD0gOTAgJiYgdG9Db2RlU3RhcnQgPj0gOTcpIHtcbiAgICByZXR1cm4gZnJvbU5vZGVOYW1lID09PSB0b05vZGVOYW1lLnRvVXBwZXJDYXNlKCk7XG4gIH0gZWxzZSBpZiAodG9Db2RlU3RhcnQgPD0gOTAgJiYgZnJvbUNvZGVTdGFydCA+PSA5Nykge1xuICAgIHJldHVybiB0b05vZGVOYW1lID09PSBmcm9tTm9kZU5hbWUudG9VcHBlckNhc2UoKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnROUyhuYW1lLCBuYW1lc3BhY2VVUkkpIHtcbiAgcmV0dXJuICFuYW1lc3BhY2VVUkkgfHwgbmFtZXNwYWNlVVJJID09PSBOU19YSFRNTCA/IGRvYy5jcmVhdGVFbGVtZW50KG5hbWUpIDogZG9jLmNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VVUkksIG5hbWUpO1xufVxuZnVuY3Rpb24gbW92ZUNoaWxkcmVuKGZyb21FbCwgdG9FbCkge1xuICB2YXIgY3VyQ2hpbGQgPSBmcm9tRWwuZmlyc3RDaGlsZDtcbiAgd2hpbGUgKGN1ckNoaWxkKSB7XG4gICAgdmFyIG5leHRDaGlsZCA9IGN1ckNoaWxkLm5leHRTaWJsaW5nO1xuICAgIHRvRWwuYXBwZW5kQ2hpbGQoY3VyQ2hpbGQpO1xuICAgIGN1ckNoaWxkID0gbmV4dENoaWxkO1xuICB9XG4gIHJldHVybiB0b0VsO1xufVxuZnVuY3Rpb24gc3luY0Jvb2xlYW5BdHRyUHJvcChmcm9tRWwsIHRvRWwsIG5hbWUpIHtcbiAgaWYgKGZyb21FbFtuYW1lXSAhPT0gdG9FbFtuYW1lXSkge1xuICAgIGZyb21FbFtuYW1lXSA9IHRvRWxbbmFtZV07XG4gICAgaWYgKGZyb21FbFtuYW1lXSkge1xuICAgICAgZnJvbUVsLnNldEF0dHJpYnV0ZShuYW1lLCBcIlwiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZnJvbUVsLnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgICB9XG4gIH1cbn1cbnZhciBzcGVjaWFsRWxIYW5kbGVycyA9IHtcbiAgT1BUSU9OOiBmdW5jdGlvbihmcm9tRWwsIHRvRWwpIHtcbiAgICB2YXIgcGFyZW50Tm9kZSA9IGZyb21FbC5wYXJlbnROb2RlO1xuICAgIGlmIChwYXJlbnROb2RlKSB7XG4gICAgICB2Y
1XIgcGFyZW50TmFtZSA9IHBhcmVudE5vZGUubm9kZU5hbWUudG9VcHBlckNhc2UoKTtcbiAgICAgIGlmIChwYXJlbnROYW1lID09PSBcIk9QVEdST1VQXCIpIHtcbiAgICAgICAgcGFyZW50Tm9kZSA9IHBhcmVudE5vZGUucGFyZW50Tm9kZTtcbiAgICAgICAgcGFyZW50TmFtZSA9IHBhcmVudE5vZGUgJiYgcGFyZW50Tm9kZS5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpO1xuICAgICAgfVxuICAgICAgaWYgKHBhcmVudE5hbWUgPT09IFwiU0VMRUNUXCIgJiYgIXBhcmVudE5vZGUuaGFzQXR0cmlidXRlKFwibXVsdGlwbGVcIikpIHtcbiAgICAgICAgaWYgKGZyb21FbC5oYXNBdHRyaWJ1dGUoXCJzZWxlY3RlZFwiKSAmJiAhdG9FbC5zZWxlY3RlZCkge1xuICAgICAgICAgIGZyb21FbC5zZXRBdHRyaWJ1dGUoXCJzZWxlY3RlZFwiLCBcInNlbGVjdGVkXCIpO1xuICAgICAgICAgIGZyb21FbC5yZW1vdmVBdHRyaWJ1dGUoXCJzZWxlY3RlZFwiKTtcbiAgICAgICAgfVxuICAgICAgICBwYXJlbnROb2RlLnNlbGVjdGVkSW5kZXggPSAtMTtcbiAgICAgIH1cbiAgICB9XG4gICAgc3luY0Jvb2xlYW5BdHRyUHJvcChmcm9tRWwsIHRvRWwsIFwic2VsZWN0ZWRcIik7XG4gIH0sXG4gIC8qKlxuICAgKiBUaGUgXCJ2YWx1ZVwiIGF0dHJpYnV0ZSBpcyBzcGVjaWFsIGZvciB0aGUgPGlucHV0PiBlbGVtZW50IHNpbmNlIGl0IHNldHNcbiAgICogdGhlIGluaXRpYWwgdmFsdWUuIENoYW5naW5nIHRoZSBcInZhbHVlXCIgYXR0cmlidXRlIHdpdGhvdXQgY2hhbmdpbmcgdGhlXG4gICAqIFwidmFsdWVcIiBwcm9wZXJ0eSB3aWxsIGhhdmUgbm8gZWZmZWN0IHNpbmNlIGl0IGlzIG9ubHkgdXNlZCB0byB0aGUgc2V0IHRoZVxuICAgKiBpbml0aWFsIHZhbHVlLiAgU2ltaWxhciBmb3IgdGhlIFwiY2hlY2tlZFwiIGF0dHJpYnV0ZSwgYW5kIFwiZGlzYWJsZWRcIi5cbiAgICovXG4gIElOUFVUOiBmdW5jdGlvbihmcm9tRWwsIHRvRWwpIHtcbiAgICBzeW5jQm9vbGVhbkF0dHJQcm9wKGZyb21FbCwgdG9FbCwgXCJjaGVja2VkXCIpO1xuICAgIHN5bmNCb29sZWFuQXR0clByb3AoZnJvbUVsLCB0b0VsLCBcImRpc2FibGVkXCIpO1xuICAgIGlmIChmcm9tRWwudmFsdWUgIT09IHRvRWwudmFsdWUpIHtcbiAgICAgIGZyb21FbC52YWx1ZSA9IHRvRWwudmFsdWU7XG4gICAgfVxuICAgIGlmICghdG9FbC5oYXNBdHRyaWJ1dGUoXCJ2YWx1ZVwiKSkge1xuICAgICAgZnJvbUVsLnJlbW92ZUF0dHJpYnV0ZShcInZhbHVlXCIpO1xuICAgIH1cbiAgfSxcbiAgVEVYVEFSRUE6IGZ1bmN0aW9uKGZyb21FbCwgdG9FbCkge1xuICAgIHZhciBuZXdWYWx1ZSA9IHRvRWwudmFsdWU7XG4gICAgaWYgKGZyb21FbC52YWx1ZSAhPT0gbmV3VmFsdWUpIHtcbiAgICAgIGZyb21FbC52YWx1ZSA9IG5ld1ZhbHVlO1xuICAgIH1cbiAgICB2YXIgZmlyc3RDaGlsZCA9IGZyb21FbC5maXJzdENoaWxkO1xuICAgIGlmIChmaXJzdENoaWxkKSB7XG4gICAgICB2Y
1XIgb2xkVmFsdWUgPSBmaXJzdENoaWxkLm5vZGVWYWx1ZTtcbiAgICAgIGlmIChvbGRWYWx1ZSA9PSBuZXdWYWx1ZSB8fCAhbmV3VmFsdWUgJiYgb2xkVmFsdWUgPT0gZnJvbUVsLnBsYWNlaG9sZGVyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGZpcnN0Q2hpbGQubm9kZVZhbHVlID0gbmV3VmFsdWU7XG4gICAgfVxuICB9LFxuICBTRUxFQ1Q6IGZ1bmN0aW9uKGZyb21FbCwgdG9FbCkge1xuICAgIGlmICghdG9FbC5oYXNBdHRyaWJ1dGUoXCJtdWx0aXBsZVwiKSkge1xuICAgICAgdmFyIHNlbGVjdGVkSW5kZXggPSAtMTtcbiAgICAgIHZhciBpID0gMDtcbiAgICAgIHZhciBjdXJDaGlsZCA9IGZyb21FbC5maXJzdENoaWxkO1xuICAgICAgdmFyIG9wdGdyb3VwO1xuICAgICAgdmFyIG5vZGVOYW1lO1xuICAgICAgd2hpbGUgKGN1ckNoaWxkKSB7XG4gICAgICAgIG5vZGVOYW1lID0gY3VyQ2hpbGQubm9kZU5hbWUgJiYgY3VyQ2hpbGQubm9kZU5hbWUudG9VcHBlckNhc2UoKTtcbiAgICAgICAgaWYgKG5vZGVOYW1lID09PSBcIk9QVEdST1VQXCIpIHtcbiAgICAgICAgICBvcHRncm91cCA9IGN1ckNoaWxkO1xuICAgICAgICAgIGN1ckNoaWxkID0gb3B0Z3JvdXAuZmlyc3RDaGlsZDtcbiAgICAgICAgICBpZiAoIWN1ckNoaWxkKSB7XG4gICAgICAgICAgICBjdXJDaGlsZCA9IG9wdGdyb3VwLm5leHRTaWJsaW5nO1xuICAgICAgICAgICAgb3B0Z3JvdXAgPSBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAobm9kZU5hbWUgPT09IFwiT1BUSU9OXCIpIHtcbiAgICAgICAgICAgIGlmIChjdXJDaGlsZC5oYXNBdHRyaWJ1dGUoXCJzZWxlY3RlZFwiKSkge1xuICAgICAgICAgICAgICBzZWxlY3RlZEluZGV4ID0gaTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpKys7XG4gICAgICAgICAgfVxuICAgICAgICAgIGN1ckNoaWxkID0gY3VyQ2hpbGQubmV4dFNpYmxpbmc7XG4gICAgICAgICAgaWYgKCFjdXJDaGlsZCAmJiBvcHRncm91cCkge1xuICAgICAgICAgICAgY3VyQ2hpbGQgPSBvcHRncm91cC5uZXh0U2libGluZztcbiAgICAgICAgICAgIG9wdGdyb3VwID0gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZyb21FbC5zZWxlY3RlZEluZGV4ID0gc2VsZWN0ZWRJbmRleDtcbiAgICB9XG4gIH1cbn07XG52YXIgRUxFTUVOVF9OT0RFID0gMTtcbnZhciBET0NVTUVOVF9GUkFHTUVOVF9OT0RFJDEgPSAxMTtcbnZhciBURVhUX05PREUgPSAzO1xudmFyIENPTU1FTlRfTk9ERSA9IDg7XG5mdW5jdGlvbiBub29wKCkge1xufVxuZnVuY3Rpb24gZGVmYXVsdEdldE5vZGVLZXkobm9kZSkge1xuICBpZiAobm9kZSkge1xuICAgIHJldHVybiBub2RlLmdldEF0dHJpYnV0ZSAmJiBub2RlLmdldEF0dHJpYnV0ZShcImlkXCIpIHx8IG5vZGUuaWQ7XG4gIH1cbn1cbmZ1bmN0aW9uIG1vcnBoZG9tRmFjdG9yeShtb3JwaEF0dHJzMikge1xuICByZXR1cm4gZnVuY3Rpb24gbW9ycGhkb20yKGZyb21Ob2RlLCB0b05vZGUsIG9wdGlvbnMpIHtcbiAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB0b05vZGUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIGlmIChmcm9tTm9kZS5ub2RlTmFtZSA9PT0gXCIjZG9jdW1lbnRcIiB8fCBmcm9tTm9kZS5ub2RlTmFtZSA9PT0gXCJIVE1MXCIpIHtcbiAgICAgICAgdmFyIHRvTm9kZUh0bWwgPSB0b05vZGU7XG4gICAgICAgIHRvTm9kZSA9IGRvYy5jcmVhdGVFbGVtZW50KFwiaHRtbFwiKTtcbiAgICAgICAgdG9Ob2RlLmlubmVySFRNTCA9IHRvTm9kZUh0bWw7XG4gICAgICB9IGVsc2UgaWYgKGZyb21Ob2RlLm5vZGVOYW1lID09PSBcIkJPRFlcIikge1xuICAgICAgICB2Y
1XIgdG9Ob2RlQm9keSA9IHRvTm9kZTtcbiAgICAgICAgdG9Ob2RlID0gZG9jLmNyZWF0ZUVsZW1lbnQoXCJodG1sXCIpO1xuICAgICAgICB0b05vZGUuaW5uZXJIVE1MID0gdG9Ob2RlQm9keTtcbiAgICAgICAgdmFyIGJvZHlFbGVtZW50ID0gdG9Ob2RlLnF1ZXJ5U2VsZWN0b3IoXCJib2R5XCIpO1xuICAgICAgICBpZiAoYm9keUVsZW1lbnQpIHtcbiAgICAgICAgICB0b05vZGUgPSBib2R5RWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdG9Ob2RlID0gdG9FbGVtZW50KHRvTm9kZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0b05vZGUubm9kZVR5cGUgPT09IERPQ1VNRU5UX0ZSQUdNRU5UX05PREUkMSkge1xuICAgICAgdG9Ob2RlID0gdG9Ob2RlLmZpcnN0RWxlbWVudENoaWxkO1xuICAgIH1cbiAgICB2YXIgZ2V0Tm9kZUtleSA9IG9wdGlvbnMuZ2V0Tm9kZUtleSB8fCBkZWZhdWx0R2V0Tm9kZUtleTtcbiAgICB2YXIgb25CZWZvcmVOb2RlQWRkZWQgPSBvcHRpb25zLm9uQmVmb3JlTm9kZUFkZGVkIHx8IG5vb3A7XG4gICAgdmFyIG9uTm9kZUFkZGVkID0gb3B0aW9ucy5vbk5vZGVBZGRlZCB8fCBub29wO1xuICAgIHZhciBvbkJlZm9yZUVsVXBkYXRlZCA9IG9wdGlvbnMub25CZWZvcmVFbFVwZGF0ZWQgfHwgbm9vcDtcbiAgICB2YXIgb25FbFVwZGF0ZWQgPSBvcHRpb25zLm9uRWxVcGRhdGVkIHx8IG5vb3A7XG4gICAgdmFyIG9uQmVmb3JlTm9kZURpc2NhcmRlZCA9IG9wdGlvbnMub25CZWZvcmVOb2RlRGlzY2FyZGVkIHx8IG5vb3A7XG4gICAgdmFyIG9uTm9kZURpc2NhcmRlZCA9IG9wdGlvbnMub25Ob2RlRGlzY2FyZGVkIHx8IG5vb3A7XG4gICAgdmFyIG9uQmVmb3JlRWxDaGlsZHJlblVwZGF0ZWQgPSBvcHRpb25zLm9uQmVmb3JlRWxDaGlsZHJlblVwZGF0ZWQgfHwgbm9vcDtcbiAgICB2YXIgc2tpcEZyb21DaGlsZHJlbiA9IG9wdGlvbnMuc2tpcEZyb21DaGlsZHJlbiB8fCBub29wO1xuICAgIHZhciBhZGRDaGlsZCA9IG9wdGlvbnMuYWRkQ2hpbGQgfHwgZnVuY3Rpb24ocGFyZW50LCBjaGlsZCkge1xuICAgICAgcmV0dXJuIHBhcmVudC5hcHBlbmRDaGlsZChjaGlsZCk7XG4gICAgfTtcbiAgICB2YXIgY2hpbGRyZW5Pbmx5ID0gb3B0aW9ucy5jaGlsZHJlbk9ubHkgPT09IHRydWU7XG4gICAgdmFyIGZyb21Ob2Rlc0xvb2t1cCA9IC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHZhciBrZXllZFJlbW92YWxMaXN0ID0gW107XG4gICAgZnVuY3Rpb24gYWRkS2V5ZWRSZW1vdmFsKGtleSkge1xuICAgICAga2V5ZWRSZW1vdmFsTGlzdC5wdXNoKGtleSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHdhbGtEaXNjYXJkZWRDaGlsZE5vZGVzKG5vZGUsIHNraXBLZXllZE5vZGVzKSB7XG4gICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgIHZhciBjdXJDaGlsZCA9IG5vZGUuZmlyc3RDaGlsZDtcbiAgICAgICAgd2hpbGUgKGN1ckNoaWxkKSB7XG4gICAgICAgICAgdmFyIGtleSA9IHZvaWQgMDtcbiAgICAgICAgICBpZiAoc2tpcEtleWVkTm9kZXMgJiYgKGtleSA9IGdldE5vZGVLZXkoY3VyQ2hpbGQpKSkge1xuICAgICAgICAgICAgYWRkS2V5ZWRSZW1vdmFsKGtleSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9uTm9kZURpc2NhcmRlZChjdXJDaGlsZCk7XG4gICAgICAgICAgICBpZiAoY3VyQ2hpbGQuZmlyc3RDaGlsZCkge1xuICAgICAgICAgICAgICB3YWxrRGlzY2FyZGVkQ2hpbGROb2RlcyhjdXJDaGlsZCwgc2tpcEtleWVkTm9kZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBjdXJDaGlsZCA9IGN1ckNoaWxkLm5leHRTaWJsaW5nO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIHJlbW92ZU5vZGUobm9kZSwgcGFyZW50Tm9kZSwgc2tpcEtleWVkTm9kZXMpIHtcbiAgICAgIGlmIChvbkJlZm9yZU5vZGVEaXNjYXJkZWQobm9kZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChwYXJlbnROb2RlKSB7XG4gICAgICAgIHBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobm9kZSk7XG4gICAgICB9XG4gICAgICBvbk5vZGVEaXNjYXJkZWQobm9kZSk7XG4gICAgICB3YWxrRGlzY2FyZGVkQ2hpbGROb2Rlcyhub2RlLCBza2lwS2V5ZWROb2Rlcyk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGluZGV4VHJlZShub2RlKSB7XG4gICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFIHx8IG5vZGUubm9kZVR5cGUgPT09IERPQ1VNRU5UX0ZSQUdNRU5UX05PREUkMSkge1xuICAgICAgICB2Y
1XIgY3VyQ2hpbGQgPSBub2RlLmZpcnN0Q2hpbGQ7XG4gICAgICAgIHdoaWxlIChjdXJDaGlsZCkge1xuICAgICAgICAgIHZhciBrZXkgPSBnZXROb2RlS2V5KGN1ckNoaWxkKTtcbiAgICAgICAgICBpZiAoa2V5KSB7XG4gICAgICAgICAgICBmcm9tTm9kZXNMb29rdXBba2V5XSA9IGN1ckNoaWxkO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpbmRleFRyZWUoY3VyQ2hpbGQpO1xuICAgICAgICAgIGN1ckNoaWxkID0gY3VyQ2hpbGQubmV4dFNpYmxpbmc7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaW5kZXhUcmVlKGZyb21Ob2RlKTtcbiAgICBmdW5jdGlvbiBoYW5kbGVOb2RlQWRkZWQoZWwpIHtcbiAgICAgIG9uTm9kZUFkZGVkKGVsKTtcbiAgICAgIHZhciBjdXJDaGlsZCA9IGVsLmZpcnN0Q2hpbGQ7XG4gICAgICB3aGlsZSAoY3VyQ2hpbGQpIHtcbiAgICAgICAgdmFyIG5leHRTaWJsaW5nID0gY3VyQ2hpbGQubmV4dFNpYmxpbmc7XG4gICAgICAgIHZhciBrZXkgPSBnZXROb2RlS2V5KGN1ckNoaWxkKTtcbiAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgIHZhciB1bm1hdGNoZWRGcm9tRWwgPSBmcm9tTm9kZXNMb29rdXBba2V5XTtcbiAgICAgICAgICBpZiAodW5tYXRjaGVkRnJvbUVsICYmIGNvbXBhcmVOb2RlTmFtZXMoY3VyQ2hpbGQsIHVubWF0Y2hlZEZyb21FbCkpIHtcbiAgICAgICAgICAgIGN1ckNoaWxkLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKHVubWF0Y2hlZEZyb21FbCwgY3VyQ2hpbGQpO1xuICAgICAgICAgICAgbW9ycGhFbCh1bm1hdGNoZWRGcm9tRWwsIGN1ckNoaWxkKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaGFuZGxlTm9kZUFkZGVkKGN1ckNoaWxkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaGFuZGxlTm9kZUFkZGVkKGN1ckNoaWxkKTtcbiAgICAgICAgfVxuICAgICAgICBjdXJDaGlsZCA9IG5leHRTaWJsaW5nO1xuICAgICAgfVxuICAgIH1cbiAgICBmdW5jdGlvbiBjbGVhbnVwRnJvbUVsKGZyb21FbCwgY3VyRnJvbU5vZGVDaGlsZCwgY3VyRnJvbU5vZGVLZXkpIHtcbiAgICAgIHdoaWxlIChjdXJGcm9tTm9kZUNoaWxkKSB7XG4gICAgICAgIHZhciBmcm9tTmV4dFNpYmxpbmcgPSBjdXJGcm9tTm9kZUNoaWxkLm5leHRTaWJsaW5nO1xuICAgICAgICBpZiAoY3VyRnJvbU5vZGVLZXkgPSBnZXROb2RlS2V5KGN1ckZyb21Ob2RlQ2hpbGQpKSB7XG4gICAgICAgICAgYWRkS2V5ZWRSZW1vdmFsKGN1ckZyb21Ob2RlS2V5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZW1vdmVOb2RlKFxuICAgICAgICAgICAgY3VyRnJvbU5vZGVDaGlsZCxcbiAgICAgICAgICAgIGZyb21FbCxcbiAgICAgICAgICAgIHRydWVcbiAgICAgICAgICAgIC8qIHNraXAga2V5ZWQgbm9kZXMgKi9cbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGN1ckZyb21Ob2RlQ2hpbGQgPSBmcm9tTmV4dFNpYmxpbmc7XG4gICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIG1vcnBoRWwoZnJvbUVsLCB0b0VsLCBjaGlsZHJlbk9ubHkyKSB7XG4gICAgICB2Y
1XIgdG9FbEtleSA9IGdldE5vZGVLZXkodG9FbCk7XG4gICAgICBpZiAodG9FbEtleSkge1xuICAgICAgICBkZWxldGUgZnJvbU5vZGVzTG9va3VwW3RvRWxLZXldO1xuICAgICAgfVxuICAgICAgaWYgKCFjaGlsZHJlbk9ubHkyKSB7XG4gICAgICAgIHZhciBiZWZvcmVVcGRhdGVSZXN1bHQgPSBvbkJlZm9yZUVsVXBkYXRlZChmcm9tRWwsIHRvRWwpO1xuICAgICAgICBpZiAoYmVmb3JlVXBkYXRlUmVzdWx0ID09PSBmYWxzZSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChiZWZvcmVVcGRhdGVSZXN1bHQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgIGZyb21FbCA9IGJlZm9yZVVwZGF0ZVJlc3VsdDtcbiAgICAgICAgICBpbmRleFRyZWUoZnJvbUVsKTtcbiAgICAgICAgfVxuICAgICAgICBtb3JwaEF0dHJzMihmcm9tRWwsIHRvRWwpO1xuICAgICAgICBvbkVsVXBkYXRlZChmcm9tRWwpO1xuICAgICAgICBpZiAob25CZWZvcmVFbENoaWxkcmVuVXBkYXRlZChmcm9tRWwsIHRvRWwpID09PSBmYWxzZSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZyb21FbC5ub2RlTmFtZSAhPT0gXCJURVhUQVJFQVwiKSB7XG4gICAgICAgIG1vcnBoQ2hpbGRyZW4oZnJvbUVsLCB0b0VsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNwZWNpYWxFbEhhbmRsZXJzLlRFWFRBUkVBKGZyb21FbCwgdG9FbCk7XG4gICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIG1vcnBoQ2hpbGRyZW4oZnJvbUVsLCB0b0VsKSB7XG4gICAgICB2Y
1XIgc2tpcEZyb20gPSBza2lwRnJvbUNoaWxkcmVuKGZyb21FbCwgdG9FbCk7XG4gICAgICB2YXIgY3VyVG9Ob2RlQ2hpbGQgPSB0b0VsLmZpcnN0Q2hpbGQ7XG4gICAgICB2YXIgY3VyRnJvbU5vZGVDaGlsZCA9IGZyb21FbC5maXJzdENoaWxkO1xuICAgICAgdmFyIGN1clRvTm9kZUtleTtcbiAgICAgIHZhciBjdXJGcm9tTm9kZUtleTtcbiAgICAgIHZhciBmcm9tTmV4dFNpYmxpbmc7XG4gICAgICB2YXIgdG9OZXh0U2libGluZztcbiAgICAgIHZhciBtYXRjaGluZ0Zyb21FbDtcbiAgICAgIG91dGVyOlxuICAgICAgICB3aGlsZSAoY3VyVG9Ob2RlQ2hpbGQpIHtcbiAgICAgICAgICB0b05leHRTaWJsaW5nID0gY3VyVG9Ob2RlQ2hpbGQubmV4dFNpYmxpbmc7XG4gICAgICAgICAgY3VyVG9Ob2RlS2V5ID0gZ2V0Tm9kZUtleShjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgICAgd2hpbGUgKCFza2lwRnJvbSAmJiBjdXJGcm9tTm9kZUNoaWxkKSB7XG4gICAgICAgICAgICBmcm9tTmV4dFNpYmxpbmcgPSBjdXJGcm9tTm9kZUNoaWxkLm5leHRTaWJsaW5nO1xuICAgICAgICAgICAgaWYgKGN1clRvTm9kZUNoaWxkLmlzU2FtZU5vZGUgJiYgY3VyVG9Ob2RlQ2hpbGQuaXNTYW1lTm9kZShjdXJGcm9tTm9kZUNoaWxkKSkge1xuICAgICAgICAgICAgICBjdXJUb05vZGVDaGlsZCA9IHRvTmV4dFNpYmxpbmc7XG4gICAgICAgICAgICAgIGN1ckZyb21Ob2RlQ2hpbGQgPSBmcm9tTmV4dFNpYmxpbmc7XG4gICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY3VyRnJvbU5vZGVLZXkgPSBnZXROb2RlS2V5KGN1ckZyb21Ob2RlQ2hpbGQpO1xuICAgICAgICAgICAgdmFyIGN1ckZyb21Ob2RlVHlwZSA9IGN1ckZyb21Ob2RlQ2hpbGQubm9kZVR5cGU7XG4gICAgICAgICAgICB2Y
1XIgaXNDb21wYXRpYmxlID0gdm9pZCAwO1xuICAgICAgICAgICAgaWYgKGN1ckZyb21Ob2RlVHlwZSA9PT0gY3VyVG9Ob2RlQ2hpbGQubm9kZVR5cGUpIHtcbiAgICAgICAgICAgICAgaWYgKGN1ckZyb21Ob2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgICAgICAgICAgaWYgKGN1clRvTm9kZUtleSkge1xuICAgICAgICAgICAgICAgICAgaWYgKGN1clRvTm9kZUtleSAhPT0gY3VyRnJvbU5vZGVLZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoaW5nRnJvbUVsID0gZnJvbU5vZGVzTG9va3VwW2N1clRvTm9kZUtleV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICBpZiAoZnJvbU5leHRTaWJsaW5nID09PSBtYXRjaGluZ0Zyb21FbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNDb21wYXRpYmxlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZyb21FbC5pbnNlcnRCZWZvcmUobWF0Y2hpbmdGcm9tRWwsIGN1ckZyb21Ob2RlQ2hpbGQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1ckZyb21Ob2RlS2V5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGFkZEtleWVkUmVtb3ZhbChjdXJGcm9tTm9kZUtleSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVOb2RlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1ckZyb21Ob2RlQ2hpbGQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbUVsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBza2lwIGtleWVkIG5vZGVzICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkID0gbWF0Y2hpbmdGcm9tRWw7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJGcm9tTm9kZUtleSA9IGdldE5vZGVLZXkoY3VyRnJvbU5vZGVDaGlsZCk7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIGlzQ29tcGF0aWJsZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjdXJGcm9tTm9kZUtleSkge1xuICAgICAgICAgICAgICAgICAgaXNDb21wYXRpYmxlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlzQ29tcGF0aWJsZSA9IGlzQ29tcGF0aWJsZSAhPT0gZmFsc2UgJiYgY29tcGFyZU5vZGVOYW1lcyhjdXJGcm9tTm9kZUNoaWxkLCBjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgICAgICAgICAgaWYgKGlzQ29tcGF0aWJsZSkge1xuICAgICAgICAgICAgICAgICAgbW9ycGhFbChjdXJGcm9tTm9kZUNoaWxkLCBjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGN1ckZyb21Ob2RlVHlwZSA9PT0gVEVYVF9OT0RFIHx8IGN1ckZyb21Ob2RlVHlwZSA9PSBDT01NRU5UX05PREUpIHtcbiAgICAgICAgICAgICAgICBpc0NvbXBhdGlibGUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGlmIChjdXJGcm9tTm9kZUNoaWxkLm5vZGVWYWx1ZSAhPT0gY3VyVG9Ob2RlQ2hpbGQubm9kZVZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkLm5vZGVWYWx1ZSA9IGN1clRvTm9kZUNoaWxkLm5vZGVWYWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc0NvbXBhdGlibGUpIHtcbiAgICAgICAgICAgICAgY3VyVG9Ob2RlQ2hpbGQgPSB0b05leHRTaWJsaW5nO1xuICAgICAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkID0gZnJvbU5leHRTaWJsaW5nO1xuICAgICAgICAgICAgICBjb250aW51ZSBvdXRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjdXJGcm9tTm9kZUtleSkge1xuICAgICAgICAgICAgICBhZGRLZXllZFJlbW92YWwoY3VyRnJvbU5vZGVLZXkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmVtb3ZlTm9kZShcbiAgICAgICAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkLFxuICAgICAgICAgICAgICAgIGZyb21FbCxcbiAgICAgICAgICAgICAgICB0cnVlXG4gICAgICAgICAgICAgICAgLyogc2tpcCBrZXllZCBub2RlcyAqL1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY3VyRnJvbU5vZGVDaGlsZCA9IGZyb21OZXh0U2libGluZztcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGN1clRvTm9kZUtleSAmJiAobWF0Y2hpbmdGcm9tRWwgPSBmcm9tTm9kZXNMb29rdXBbY3VyVG9Ob2RlS2V5XSkgJiYgY29tcGFyZU5vZGVOYW1lcyhtYXRjaGluZ0Zyb21FbCwgY3VyVG9Ob2RlQ2hpbGQpKSB7XG4gICAgICAgICAgICBpZiAoIXNraXBGcm9tKSB7XG4gICAgICAgICAgICAgIGFkZENoaWxkKGZyb21FbCwgbWF0Y2hpbmdGcm9tRWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbW9ycGhFbChtYXRjaGluZ0Zyb21FbCwgY3VyVG9Ob2RlQ2hpbGQpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2Y
1XIgb25CZWZvcmVOb2RlQWRkZWRSZXN1bHQgPSBvbkJlZm9yZU5vZGVBZGRlZChjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgICAgICBpZiAob25CZWZvcmVOb2RlQWRkZWRSZXN1bHQgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgIGlmIChvbkJlZm9yZU5vZGVBZGRlZFJlc3VsdCkge1xuICAgICAgICAgICAgICAgIGN1clRvTm9kZUNoaWxkID0gb25CZWZvcmVOb2RlQWRkZWRSZXN1bHQ7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKGN1clRvTm9kZUNoaWxkLmFjdHVhbGl6ZSkge1xuICAgICAgICAgICAgICAgIGN1clRvTm9kZUNoaWxkID0gY3VyVG9Ob2RlQ2hpbGQuYWN0dWFsaXplKGZyb21FbC5vd25lckRvY3VtZW50IHx8IGRvYyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgYWRkQ2hpbGQoZnJvbUVsLCBjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgICAgICAgIGhhbmRsZU5vZGVBZGRlZChjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGN1clRvTm9kZUNoaWxkID0gdG9OZXh0U2libGluZztcbiAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkID0gZnJvbU5leHRTaWJsaW5nO1xuICAgICAgICB9XG4gICAgICBjbGVhbnVwRnJvbUVsKGZyb21FbCwgY3VyRnJvbU5vZGVDaGlsZCwgY3VyRnJvbU5vZGVLZXkpO1xuICAgICAgdmFyIHNwZWNpYWxFbEhhbmRsZXIgPSBzcGVjaWFsRWxIYW5kbGVyc1tmcm9tRWwubm9kZU5hbWVdO1xuICAgICAgaWYgKHNwZWNpYWxFbEhhbmRsZXIpIHtcbiAgICAgICAgc3BlY2lhbEVsSGFuZGxlcihmcm9tRWwsIHRvRWwpO1xuICAgICAgfVxuICAgIH1cbiAgICB2YXIgbW9ycGhlZE5vZGUgPSBmcm9tTm9kZTtcbiAgICB2YXIgbW9ycGhlZE5vZGVUeXBlID0gbW9ycGhlZE5vZGUubm9kZVR5cGU7XG4gICAgdmFyIHRvTm9kZVR5cGUgPSB0b05vZGUubm9kZVR5cGU7XG4gICAgaWYgKCFjaGlsZHJlbk9ubHkpIHtcbiAgICAgIGlmIChtb3JwaGVkTm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSkge1xuICAgICAgICBpZiAodG9Ob2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgICAgaWYgKCFjb21wYXJlTm9kZU5hbWVzKGZyb21Ob2RlLCB0b05vZGUpKSB7XG4gICAgICAgICAgICBvbk5vZGVEaXNjYXJkZWQoZnJvbU5vZGUpO1xuICAgICAgICAgICAgbW9ycGhlZE5vZGUgPSBtb3ZlQ2hpbGRyZW4oZnJvbU5vZGUsIGNyZWF0ZUVsZW1lbnROUyh0b05vZGUubm9kZU5hbWUsIHRvTm9kZS5uYW1lc3BhY2VVUkkpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbW9ycGhlZE5vZGUgPSB0b05vZGU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAobW9ycGhlZE5vZGVUeXBlID09PSBURVhUX05PREUgfHwgbW9ycGhlZE5vZGVUeXBlID09PSBDT01NRU5UX05PREUpIHtcbiAgICAgICAgaWYgKHRvTm9kZVR5cGUgPT09IG1vcnBoZWROb2RlVHlwZSkge1xuICAgICAgICAgIGlmIChtb3JwaGVkTm9kZS5ub2RlVmFsdWUgIT09IHRvTm9kZS5ub2RlVmFsdWUpIHtcbiAgICAgICAgICAgIG1vcnBoZWROb2RlLm5vZGVWYWx1ZSA9IHRvTm9kZS5ub2RlVmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBtb3JwaGVkTm9kZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtb3JwaGVkTm9kZSA9IHRvTm9kZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAobW9ycGhlZE5vZGUgPT09IHRvTm9kZSkge1xuICAgICAgb25Ob2RlRGlzY2FyZGVkKGZyb21Ob2RlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRvTm9kZS5pc1NhbWVOb2RlICYmIHRvTm9kZS5pc1NhbWVOb2RlKG1vcnBoZWROb2RlKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBtb3JwaEVsKG1vcnBoZWROb2RlLCB0b05vZGUsIGNoaWxkcmVuT25seSk7XG4gICAgICBpZiAoa2V5ZWRSZW1vdmFsTGlzdCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0ga2V5ZWRSZW1vdmFsTGlzdC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgIHZhciBlbFRvUmVtb3ZlID0gZnJvbU5vZGVzTG9va3VwW2tleWVkUmVtb3ZhbExpc3RbaV1dO1xuICAgICAgICAgIGlmIChlbFRvUmVtb3ZlKSB7XG4gICAgICAgICAgICByZW1vdmVOb2RlKGVsVG9SZW1vdmUsIGVsVG9SZW1vdmUucGFyZW50Tm9kZSwgZmFsc2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWNoaWxkcmVuT25seSAmJiBtb3JwaGVkTm9kZSAhPT0gZnJvbU5vZGUgJiYgZnJvbU5vZGUucGFyZW50Tm9kZSkge1xuICAgICAgaWYgKG1vcnBoZWROb2RlLmFjdHVhbGl6ZSkge1xuICAgICAgICBtb3JwaGVkTm9kZSA9IG1vcnBoZWROb2RlLmFjdHVhbGl6ZShmcm9tTm9kZS5vd25lckRvY3VtZW50IHx8IGRvYyk7XG4gICAgICB9XG4gICAgICBmcm9tTm9kZS5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChtb3JwaGVkTm9kZSwgZnJvbU5vZGUpO1xuICAgIH1cbiAgICByZXR1cm4gbW9ycGhlZE5vZGU7XG4gIH07XG59XG52YXIgbW9ycGhkb20gPSBtb3JwaGRvbUZhY3RvcnkobW9ycGhBdHRycyk7XG52YXIgbW9ycGhkb21fZXNtX2RlZmF1bHQgPSBtb3JwaGRvbTtcblxuLy8ganMvcGhvZW5peF9saXZlX3ZpZXcvZG9tX3BhdGNoLnRzXG52YXIgRE9NUGF0Y2ggPSBjbGFzcyB7XG4gIGNvbnN0cnVjdG9yKHZpZXcsIGNvbnRhaW5lciwgaHRtbCwgc3RyZWFtcywgdGFyZ2V0Q0lELCBvcHRzID0ge30pIHtcbiAgICB0aGlzLnZpZXcgPSB2aWV3O1xuICAgIHRoaXMubGl2ZVNvY2tldCA9IHZpZXcubGl2ZVNvY2tldDtcbiAgICB0aGlzLmNvbnRhaW5lciA9IGNvbnRhaW5lcjtcbiAgICB0aGlzLnJvb3RJRCA9IHZpZXcucm9vdC5pZDtcbiAgICB0aGlzLmh0bWwgPSBodG1sO1xuICAgIHRoaXMuc3RyZWFtcyA9IHN0cmVhbXM7XG4gICAgdGhpcy5zdHJlYW1JbnNlcnRzID0ge307XG4gICAgdGhpcy5zdHJlYW1Db21wb25lbnRSZXN0b3JlID0ge307XG4gICAgdGhpcy50YXJnZXRDSUQgPSB0YXJnZXRDSUQ7XG4gICAgdGhpcy5wZW5kaW5nUmVtb3ZlcyA9IFtdO1xuICAgIHRoaXMucGh4UmVtb3ZlID0gdGhpcy5saXZlU29ja2V0LmJpbmRpbmcoXCJyZW1vdmVcIik7XG4gICAgdGhpcy50YXJnZXRDb250YWluZXIgPSB0YXJnZXRDSUQgPyBkb21fZGVmYXVsdC5nZXRDb21wb25lbnQodGhpcy52aWV3LmlkLCB0YXJnZXRDSUQpIDogY29udGFpbmVyO1xuICAgIHRoaXMuYmVmb3JlVXBkYXRlZENhbGxiYWNrcyA9IFtdO1xuICAgIHRoaXMuYWZ0ZXJBZGRlZENhbGxiYWNrcyA9IFtdO1xuICAgIHRoaXMuYWZ0ZXJVcGRhdGVkQ2FsbGJhY2tzID0gW107XG4gICAgdGhpcy5hZnRlclBoeENoaWxkQWRkZWRDYWxsYmFja3MgPSBbXTtcbiAgICB0aGlzLmFmdGVyRGlzY2FyZGVkQ2FsbGJhY2tzID0gW107XG4gICAgdGhpcy5hZnRlclRyYW5zaXRpb25zRGlzY2FyZGVkQ2FsbGJhY2tzID0gW107XG4gICAgdGhpcy53aXRoQ2hpbGRyZW4gPSBvcHRzLndpdGhDaGlsZHJlbiB8fCBvcHRzLnVuZG9SZWYgIT09IHZvaWQgMCB8fCBmYWxzZTtcbiAgICB0aGlzLnVuZG9SZWYgPSBvcHRzLnVuZG9SZWYgPz8gbnVsbDtcbiAgfVxuICBiZWZvcmVVcGRhdGVkKGNhbGxiYWNrKSB7XG4gICAgdGhpcy5iZWZvcmVVcGRhdGVkQ2FsbGJhY2tzLnB1c2goY2FsbGJhY2spO1xuICB9XG4gIGFmdGVyQWRkZWQoY2FsbGJhY2spIHtcbiAgICB0aGlzLmFmdGVyQWRkZWRDYWxsYmFja3MucHVzaChjYWxsYmFjayk7XG4gIH1cbiAgYWZ0ZXJVcGRhdGVkKGNhbGxiYWNrKSB7XG4gICAgdGhpcy5hZnRlclVwZGF0ZWRDYWxsYmFja3MucHVzaChjYWxsYmFjayk7XG4gIH1cbiAgYWZ0ZXJQaHhDaGlsZEFkZGVkKGNhbGxiYWNrKSB7XG4gICAgdGhpcy5hZnRlclBoeENoaWxkQWRkZWRDYWxsYmFja3MucHVzaChjYWxsYmFjayk7XG4gIH1cbiAgYWZ0ZXJEaXNjYXJkZWQoY2FsbGJhY2spIHtcbiAgICB0aGlzLmFmdGVyRGlzY2FyZGVkQ2FsbGJhY2tzLnB1c2goY2FsbGJhY2spO1xuICB9XG4gIGFmdGVyVHJhbnNpdGlvbnNEaXNjYXJkZWQoY2FsbGJhY2spIHtcbiAgICB0aGlzLmFmdGVyVHJhbnNpdGlvbnNEaXNjYXJkZWRDYWxsYmFja3MucHVzaChjYWxsYmFjayk7XG4gIH1cbiAgbWFya1BydW5hYmxlQ29udGVudEZvclJlbW92YWwoKSB7XG4gICAgY29uc3QgcGh4VXBkYXRlID0gdGhpcy5saXZlU29ja2V0LmJpbmRpbmcoUEhYX1VQREFURSk7XG4gICAgZG9tX2RlZmF1bHQuYWxsKFxuICAgICAgdGhpcy5jb250YWluZXIsXG4gICAgICBgWyR7cGh4VXBkYXRlfT1hcHBlbmRdID4gKiwgWyR7cGh4VXBkYXRlfT1wcmVwZW5kXSA+ICpgLFxuICAgICAgKGVsKSA9PiB7XG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZShQSFhfUFJVTkUsIFwiXCIpO1xuICAgICAgfVxuICAgICk7XG4gIH1cbiAgcGVyZm9ybShpc0pvaW5QYXRjaCkge1xuICAgIGNvbnN0IHsgdmlldywgbGl2ZVNvY2tldCwgaHRtbCwgY29udGFpbmVyIH0gPSB0aGlzO1xuICAgIGxldCB0YXJnZXRDb250YWluZXIgPSB0aGlzLnRhcmdldENvbnRhaW5lcjtcbiAgICBpZiAodGhpcy50YXJnZXRDSUQpIHtcbiAgICAgIGNvbnN0IGNsb3Nlc3RMb2NrID0gdGFyZ2V0Q29udGFpbmVyLmNsb3Nlc3QoYFske1BIWF9SRUZfTE9DS31dYCk7XG4gICAgICBpZiAoY2xvc2VzdExvY2sgJiYgIWNsb3Nlc3RMb2NrLmlzU2FtZU5vZGUodGFyZ2V0Q29udGFpbmVyKSkge1xuICAgICAgICBjb25zdCBjbG9uZWRUcmVlID0gZG9tX2RlZmF1bHQucHJpdmF0ZShjbG9zZXN0TG9jaywgUEhYX1JFRl9MT0NLKTtcbiAgICAgICAgaWYgKGNsb25lZFRyZWUpIHtcbiAgICAgICAgICB0YXJnZXRDb250YWluZXIgPSBjbG9uZWRUcmVlLnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgICAgICBgW2RhdGEtcGh4LWNvbXBvbmVudD1cIiR7dGhpcy50YXJnZXRDSUR9XCJdYFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKCF0YXJnZXRDb250YWluZXIpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgI
1H1cbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgZm9jdXNlZCA9IGxpdmVTb2NrZXQuZ2V0QWN0aXZlRWxlbWVudCgpO1xuICAgIGNvbnN0IHsgc2VsZWN0aW9uU3RhcnQsIHNlbGVjdGlvbkVuZCB9ID0gZm9jdXNlZCAmJiBkb21fZGVmYXVsdC5oYXNTZWxlY3Rpb25SYW5nZShmb2N1c2VkKSA/IGZvY3VzZWQgOiB7fTtcbiAgICBjb25zdCBwaHhVcGRhdGUgPSBsaXZlU29ja2V0LmJpbmRpbmcoUEhYX1VQREFURSk7XG4gICAgY29uc3QgcGh4Vmlld3BvcnRUb3AgPSBsaXZlU29ja2V0LmJpbmRpbmcoUEhYX1ZJRVdQT1JUX1RPUCk7XG4gICAgY29uc3QgcGh4Vmlld3BvcnRCb3R0b20gPSBsaXZlU29ja2V0LmJpbmRpbmcoUEhYX1ZJRVdQT1JUX0JPVFRPTSk7XG4gICAgY29uc3QgcGh4VHJpZ2dlckV4dGVybmFsID0gbGl2ZVNvY2tldC5iaW5kaW5nKFBIWF9UUklHR0VSX0FDVElPTik7XG4gICAgY29uc3QgYWRkZWQgPSBbXTtcbiAgICBjb25zdCB1cGRhdGVzID0gW107XG4gICAgY29uc3QgYXBwZW5kUHJlcGVuZFVwZGF0ZXMgPSBbXTtcbiAgICBsZXQgcG9ydGFsQ2FsbGJhY2tzID0gW107XG4gICAgbGV0IGV4dGVybmFsRm9ybVRyaWdnZXJlZCA9IG51bGw7XG4gICAgY29uc3QgbW9ycGggPSAodGFyZ2V0Q29udGFpbmVyMiwgc291cmNlLCB3aXRoQ2hpbGRyZW4gPSB0aGlzLndpdGhDaGlsZHJlbikgPT4ge1xuICAgICAgY29uc3QgbW9ycGhDYWxsYmFja3MgPSB7XG4gICAgICAgIC8vIG5vcm1hbGx5LCB3ZSBhcmUgcnVubmluZyB3aXRoIGNoaWxkcmVuT25seSwgYXMgdGhlIHBhdGNoIEhUTUwgZm9yIGEgTFZcbiAgICAgICAgLy8gZG9lcyBub3QgaW5jbHVkZSB0aGUgTFYgYXR0cnMgKGRhdGEtcGh4LXNlc3Npb24sIGV0Yy4pXG4gICAgICAgIC8vIHdoZW4gd2UgYXJlIHBhdGNoaW5nIGEgbGl2ZSBjb21wb25lbnQsIHdlIGRvIHdhbnQgdG8gcGF0Y2ggdGhlIHJvb3QgZWxlbWVudCBhcyB3ZWxsO1xuICAgICAgICAvLyBhbm90aGVyIGNhc2UgaXMgdGhlIHJlY3Vyc2l2ZSBwYXRjaCBvZiBhIHN0cmVhbSBpdGVtIHRoYXQgd2FzIGtlcHQgb24gcmVzZXQgKC0+IG9uQmVmb3JlTm9kZUFkZGVkKVxuICAgICAgICBjaGlsZHJlbk9ubHk6IHRhcmdldENvbnRhaW5lcjIuZ2V0QXR0cmlidXRlKFBIWF9DT01QT05FTlQpID09PSBudWxsICYmICF3aXRoQ2hpbGRyZW4sXG4gICAgICAgIGdldE5vZGVLZXk6IChub2RlKSA9PiB7XG4gICAgICAgICAgaWYgKCEobm9kZSBpbnN0YW5jZW9mIEVsZW1lbnQpKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgaWYgKGRvbV9kZWZhdWx0LmlzUGh4RGVzdHJveWVkKG5vZGUpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGlzSm9pblBhdGNoKSB7XG4gICAgICAgICAgICByZXR1cm4gbm9kZS5pZDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGRvbV9kZWZhdWx0LnByaXZhdGUobm9kZSwgXCJjbGllbnRzaWRlSWRBdHRyaWJ1dGVcIikpIHtcbiAgICAgICAgICAgIHJldHVybiBub2RlLmdldEF0dHJpYnV0ZShQSFhfTUFHSUNfSUQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbm9kZS5pZCB8fCBub2RlLmdldEF0dHJpYnV0ZShQSFhfTUFHSUNfSUQpO1xuICAgICAgICB9LFxuICAgICAgICAvLyBza2lwIGluZGV4aW5nIGZyb20gY2hpbGRyZW4gd2hlbiBjb250YWluZXIgaXMgc3RyZWFtXG4gICAgICAgIHNraXBGcm9tQ2hpbGRyZW46IChmcm9tKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGZyb20uZ2V0QXR0cmlidXRlKHBoeFVwZGF0ZSkgPT09IFBIWF9TVFJFQU07XG4gICAgICAgIH0sXG4gICAgICAgIC8vIHRlbGwgbW9ycGhkb20gaG93IHRvIGFkZCBhIGNoaWxkXG4gICAgICAgIGFkZENoaWxkOiAocGFyZW50LCBjaGlsZCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgcmVmLCBzdHJlYW1BdCB9ID0gdGhpcy5nZXRTdHJlYW1JbnNlcnQoY2hpbGQpO1xuICAgICAgICAgIGlmIChyZWYgPT09IHZvaWQgMCkge1xuICAgICAgICAgICAgcmV0dXJuIHBhcmVudC5hcHBlbmRDaGlsZChjaGlsZCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuc2V0U3RyZWFtUmVmKGNoaWxkLCByZWYpO1xuICAgICAgICAgIGlmIChzdHJlYW1BdCA9PT0gMCkge1xuICAgICAgICAgICAgcGFyZW50Lmluc2VydEFkamFjZW50RWxlbWVudChcImFmdGVyYmVnaW5cIiwgY2hpbGQpO1xuICAgICAgICAgIH0gZWxzZSBpZiAoc3RyZWFtQXQgPT09IC0xKSB7XG4gICAgICAgICAgICBjb25zdCBsYXN0Q2hpbGQgPSBwYXJlbnQubGFzdEVsZW1lbnRDaGlsZDtcbiAgICAgICAgICAgIGlmIChsYXN0Q2hpbGQgJiYgIWxhc3RDaGlsZC5oYXNBdHRyaWJ1dGUoUEhYX1NUUkVBTV9SRUYpKSB7XG4gICAgICAgICAgICAgIGNvbnN0IG5vblN0cmVhbUNoaWxkID0gQXJyYXkuZnJvbShwYXJlbnQuY2hpbGRyZW4pLmZpbmQoXG4gICAgICAgICAgICAgICAgKGMpID0+ICFjLmhhc0F0dHJpYnV0ZShQSFhfU1RSRUFNX1JFRilcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShjaGlsZCwgbm9uU3RyZWFtQ2hpbGQgPz8gbnVsbCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBwYXJlbnQuYXBwZW5kQ2hpbGQoY2hpbGQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoc3RyZWFtQXQgPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBzaWJsaW5nID0gQXJyYXkuZnJvbShwYXJlbnQuY2hpbGRyZW4pW3N0cmVhbUF0XTtcbiAgICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoY2hpbGQsIHNpYmxpbmcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgb25CZWZvcmVOb2RlQWRkZWQ6IChlbCkgPT4ge1xuICAgICAgICAgIGlmICghKGVsIGluc3RhbmNlb2YgRWxlbWVudCkpIHtcbiAgICAgICAgICAgIHJldHVybiBlbDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHRoaXMuZ2V0U3RyZWFtSW5zZXJ0KGVsKT8udXBkYXRlT25seSAmJiAhdGhpcy5zdHJlYW1Db21wb25lbnRSZXN0b3JlW2VsLmlkXSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgI
1H1cbiAgICAgICAgICBkb21fZGVmYXVsdC5tYWludGFpblByaXZhdGVIb29rcyhlbCwgZWwsIHBoeFZpZXdwb3J0VG9wLCBwaHhWaWV3cG9ydEJvdHRvbSk7XG4gICAgICAgICAgbGV0IG1vcnBoZWRFbCA9IGVsO1xuICAgICAgICAgIGlmICh0aGlzLnN0cmVhbUNvbXBvbmVudFJlc3RvcmVbZWwuaWRdKSB7XG4gICAgICAgICAgICBtb3JwaGVkRWwgPSB0aGlzLnN0cmVhbUNvbXBvbmVudFJlc3RvcmVbZWwuaWRdO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3RyZWFtQ29tcG9uZW50UmVzdG9yZVtlbC5pZF07XG4gICAgICAgICAgICBtb3JwaChtb3JwaGVkRWwsIGVsLCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG1vcnBoZWRFbDtcbiAgICAgICAgfSxcbiAgICAgICAgb25Ob2RlQWRkZWQ6IChlbCkgPT4ge1xuICAgICAgICAgIGlmICghKGVsIGluc3RhbmNlb2YgRWxlbWVudCkpIHtcbiAgICAgICAgICAgIGFkZGVkLnB1c2goZWwpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLm1heWJlUmVPcmRlclN0cmVhbShlbCwgdHJ1ZSk7XG4gICAgICAgICAgaWYgKGRvbV9kZWZhdWx0LmlzUG9ydGFsVGVtcGxhdGUoZWwpKSB7XG4gICAgICAgICAgICBwb3J0YWxDYWxsYmFja3MucHVzaCgoKSA9PiB0aGlzLnRlbGVwb3J0KGVsLCBtb3JwaCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZWwgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50ICYmIGVsLnNyY3NldCkge1xuICAgICAgICAgICAgZWwuc3Jjc2V0ID0gZWwuc3Jjc2V0O1xuICAgICAgICAgIH0gZWxzZSBpZiAoZWwgaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50ICYmIGVsLmF1dG9wbGF5KSB7XG4gICAgICAgICAgICBlbC5wbGF5KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChkb21fZGVmYXVsdC5pc05vd1RyaWdnZXJGb3JtRXh0ZXJuYWwoZWwsIHBoeFRyaWdnZXJFeHRlcm5hbCkpIHtcbiAgICAgICAgICAgIGV4dGVybmFsRm9ybVRyaWdnZXJlZCA9IGVsO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZG9tX2RlZmF1bHQuaXNQaHhDaGlsZChlbCkgJiYgdmlldy5vd25zRWxlbWVudChlbCkgfHwgZG9tX2RlZmF1bHQuaXNQaHhTdGlja3koZWwpICYmIHZpZXcub3duc0VsZW1lbnQoZWwucGFyZW50Tm9kZSkpIHtcbiAgICAgICAgICAgIHRoaXMudHJhY2tBZnRlclBoeENoaWxkQWRkZWQoZWwpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZWwubm9kZU5hbWUgPT09IFwiU0NSSVBUXCIgJiYgZWwuaGFzQXR0cmlidXRlKFBIWF9SVU5USU1FX0hPT0spKSB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZVJ1bnRpbWVIb29rKGVsLCBzb3VyY2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBhZGRlZC5wdXNoKGVsKTtcbiAgICAgICAgfSxcbiAgICAgICAgb25Ob2RlRGlzY2FyZGVkOiAoZWwpID0+IHRoaXMub25Ob2RlRGlzY2FyZGVkKGVsKSxcbiAgICAgICAgb25CZWZvcmVOb2RlRGlzY2FyZGVkOiAoZWwpID0+IHtcbiAgICAgICAgICBpZiAoIShlbCBpbnN0YW5jZW9mIEVsZW1lbnQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGVsLmdldEF0dHJpYnV0ZShQSFhfUFJVTkUpICE9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGVsLnBhcmVudEVsZW1lbnQgIT09IG51bGwgJiYgZWwuaWQgJiYgZG9tX2RlZmF1bHQuaXNQaHhVcGRhdGUoZWwucGFyZW50RWxlbWVudCwgcGh4VXBkYXRlLCBbXG4gICAgICAgICAgICBQSFhfU1RSRUFNLFxuICAgICAgICAgICAgXCJhcHBlbmRcIixcbiAgICAgICAgICAgIFwicHJlcGVuZFwiXG4gICAgICAgICAgXSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGVsLmdldEF0dHJpYnV0ZShQSFhfVEVMRVBPUlRFRF9SRUYpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0aGlzLm1heWJlUGVuZGluZ1JlbW92ZShlbCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHRoaXMuc2tpcENJRFNpYmxpbmcoZWwpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChkb21fZGVmYXVsdC5pc1BvcnRhbFRlbXBsYXRlKGVsKSkge1xuICAgICAgICAgICAgY29uc3QgdGVsZXBvcnRlZEVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXG4gICAgICAgICAgICAgIGVsLmNvbnRlbnQuZmlyc3RFbGVtZW50Q2hpbGQ/LmlkIHx8IFwiXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAodGVsZXBvcnRlZEVsKSB7XG4gICAgICAgICAgICAgIHRlbGVwb3J0ZWRFbC5yZW1vdmUoKTtcbiAgICAgICAgICAgICAgbW9ycGhDYWxsYmFja3Mub25Ob2RlRGlzY2FyZGVkKHRlbGVwb3J0ZWRFbCk7XG4gICAgICAgICAgICAgIHRoaXMudmlldy5kcm9wUG9ydGFsRWxlbWVudElkKHRlbGVwb3J0ZWRFbC5pZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9LFxuICAgICAgICBvbkVsVXBkYXRlZDogKGVsKSA9PiB7XG4gICAgICAgICAgaWYgKGRvbV9kZWZhdWx0LmlzTm93VHJpZ2dlckZvcm1FeHRlcm5hbChlbCwgcGh4VHJpZ2dlckV4dGVybmFsKSkge1xuICAgICAgICAgICAgZXh0ZXJuYWxGb3JtVHJpZ2dlcmVkID0gZWw7XG4gICAgICAgICAgfVxuICAgICAgICAgIHVwZGF0ZXMucHVzaChlbCk7XG4gICAgICAgICAgdGhpcy5tYXliZVJlT3JkZXJTdHJlYW0oZWwsIGZhbHNlKTtcbiAgICAgICAgfSxcbiAgICAgICAgb25CZWZvcmVFbFVwZGF0ZWQ6IChmcm9tRWwsIHRvRWwpID0+IHtcbiAgICAgICAgICBpZiAoZnJvbUVsLmlkICYmIGZyb21FbC5pc1NhbWVOb2RlKHRhcmdldENvbnRhaW5lcjIpICYmIGZyb21FbC5pZCAhPT0gdG9FbC5pZCkge1xuICAgICAgICAgICAgbW9ycGhDYWxsYmFja3Mub25Ob2RlRGlzY2FyZGVkKGZyb21FbCk7XG4gICAgICAgICAgICBmcm9tRWwucmVwbGFjZVdpdGgodG9FbCk7XG4gICAgICAgICAgICByZXR1cm4gbW9ycGhDYWxsYmFja3Mub25Ob2RlQWRkZWQodG9FbCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRvbV9kZWZhdWx0LnN5bmNQZW5kaW5nQXR0cnMoZnJvbUVsLCB0b0VsKTtcbiAgICAgICAgICBkb21fZGVmYXVsdC5tYWludGFpblByaXZhdGVIb29rcyhcbiAgICAgICAgICAgIGZyb21FbCxcbiAgICAgICAgICAgI
1HRvRWwsXG4gICAgICAgICAgICBwaHhWaWV3cG9ydFRvcCxcbiAgICAgICAgICAgIHBoeFZpZXdwb3J0Qm90dG9tXG4gICAgICAgICAgKTtcbiAgICAgICAgICBkb21fZGVmYXVsdC5jbGVhbkNoaWxkTm9kZXModG9FbCwgcGh4VXBkYXRlKTtcbiAgICAgICAgICBjb25zdCBpc0ZvY3VzZWRGb3JtRWwgPSBmb2N1c2VkICYmIGZyb21FbC5pc1NhbWVOb2RlKGZvY3VzZWQpICYmIGRvbV9kZWZhdWx0LmlzRWRpdGFibGVJbnB1dChmcm9tRWwpO1xuICAgICAgICAgIGNvbnN0IGZvY3VzZWRTZWxlY3RDaGFuZ2VkID0gaXNGb2N1c2VkRm9ybUVsICYmIHRoaXMuaXNDaGFuZ2VkU2VsZWN0KGZyb21FbCwgdG9FbCk7XG4gICAgICAgICAgaWYgKHRoaXMuc2tpcENJRFNpYmxpbmcodG9FbCkpIHtcbiAgICAgICAgICAgIHRoaXMubWF5YmVDbG9uZUxvY2tlZEVsZW1lbnQoZnJvbUVsLCBpc0ZvY3VzZWRGb3JtRWwpO1xuICAgICAgICAgICAgdGhpcy5jb3B5TmVzdGVkUHJpdmF0ZUxvY2soZnJvbUVsLCB0b0VsKTtcbiAgICAgICAgICAgIHRoaXMubWF5YmVSZU9yZGVyU3RyZWFtKGZyb21FbCk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChkb21fZGVmYXVsdC5pc1BoeFN0aWNreShmcm9tRWwpKSB7XG4gICAgICAgICAgICBbUEhYX1NFU1NJT04sIFBIWF9TVEFUSUMsIFBIWF9ST09UX0lEXS5tYXAoKGF0dHIpID0+IFtcbiAgICAgICAgICAgICAgYXR0cixcbiAgICAgICAgICAgICAgZnJvbUVsLmdldEF0dHJpYnV0ZShhdHRyKSxcbiAgICAgICAgICAgICAgdG9FbC5nZXRBdHRyaWJ1dGUoYXR0cilcbiAgICAgICAgICAgIF0pLmZvckVhY2goKFthdHRyLCBmcm9tVmFsLCB0b1ZhbF0pID0+IHtcbiAgICAgICAgICAgICAgaWYgKHRvVmFsICYmIGZyb21WYWwgIT09IHRvVmFsKSB7XG4gICAgICAgICAgICAgICAgZnJvbUVsLnNldEF0dHJpYnV0ZShhdHRyLCB0b1ZhbCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZG9tX2RlZmF1bHQuaXNJZ25vcmVkKGZyb21FbCwgcGh4VXBkYXRlKSB8fCBmcm9tRWwuZm9ybSAmJiBmcm9tRWwuZm9ybS5pc1NhbWVOb2RlKGV4dGVybmFsRm9ybVRyaWdnZXJlZCkpIHtcbiAgICAgICAgICAgIHRoaXMudHJhY2tCZWZvcmVVcGRhdGVkKGZyb21FbCwgdG9FbCk7XG4gICAgICAgICAgICBkb21fZGVmYXVsdC5tZXJnZUF0dHJzKGZyb21FbCwgdG9FbCwge1xuICAgICAgICAgICAgICBpc0lnbm9yZWQ6IGRvbV9kZWZhdWx0LmlzSWdub3JlZChmcm9tRWwsIHBoeFVwZGF0ZSlcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdXBkYXRlcy5wdXNoKGZyb21FbCk7XG4gICAgICAgICAgICBkb21fZGVmYXVsdC5hcHBseVN0aWNreU9wZXJhdGlvbnMoZnJvbUVsKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGZyb21FbC50eXBlID09PSBcIm51bWJlclwiICYmIGZyb21FbC52YWxpZGl0eSAmJiBmcm9tRWwudmFsaWRpdHkuYmFkSW5wdXQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZnJvbUVsID0gdGhpcy5tYXliZUNsb25lTG9ja2VkRWxlbWVudChmcm9tRWwsIGlzRm9jdXNlZEZvcm1FbCk7XG4gICAgICAgICAgaWYgKGRvbV9kZWZhdWx0LmlzUGh4Q2hpbGQodG9FbCkpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZXZTZXNzaW9uID0gZnJvbUVsLmdldEF0dHJpYnV0ZShQSFhfU0VTU0lPTik7XG4gICAgICAgICAgICBkb21fZGVmYXVsdC5tZXJnZUF0dHJzKGZyb21FbCwgdG9FbCwgeyBleGNsdWRlOiBbUEhYX1NUQVRJQ10gfSk7XG4gICAgICAgICAgICBpZiAocHJldlNlc3Npb24gIT09IFwiXCIpIHtcbiAgICAgICAgICAgICAgZnJvbUVsLnNldEF0dHJpYnV0ZShQSFhfU0VTU0lPTiwgcHJldlNlc3Npb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZnJvbUVsLnNldEF0dHJpYnV0ZShQSFhfUk9PVF9JRCwgdGhpcy5yb290SUQpO1xuICAgICAgICAgICAgZG9tX2RlZmF1bHQuYXBwbHlTdGlja3lPcGVyYXRpb25zKGZyb21FbCk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuY29weU5lc3RlZFByaXZhdGVMb2NrKGZyb21FbCwgdG9FbCk7XG4gICAgICAgICAgZG9tX2RlZmF1bHQuY29weVByaXZhdGVzKHRvRWwsIGZyb21FbCk7XG4gICAgICAgICAgaWYgKGRvbV9kZWZhdWx0LmlzUG9ydGFsVGVtcGxhdGUodG9FbCkpIHtcbiAgICAgICAgICAgIHBvcnRhbENhbGxiYWNrcy5wdXNoKCgpID0+IHRoaXMudGVsZXBvcnQodG9FbCwgbW9ycGgpKTtcbiAgICAgICAgICAgIGZyb21FbC5jb250ZW50LnJlcGxhY2VDaGlsZHJlbih0b0VsLmNvbnRlbnQuY2xvbmVOb2RlKHRydWUpKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGlzRm9jdXNlZEZvcm1FbCAmJiBmcm9tRWwud
1HlwZSAhPT0gXCJoaWRkZW5cIiAmJiAhZm9jdXNlZFNlbGVjdENoYW5nZWQpIHtcbiAgICAgICAgICAgIHRoaXMudHJhY2tCZWZvcmVVcGRhdGVkKGZyb21FbCwgdG9FbCk7XG4gICAgICAgICAgICBkb21fZGVmYXVsdC5tZXJnZUZvY3VzZWRJbnB1dChmcm9tRWwsIHRvRWwpO1xuICAgICAgICAgICAgZG9tX2RlZmF1bHQuc3luY0F0dHJzVG9Qcm9wcyhmcm9tRWwpO1xuICAgICAgICAgICAgdXBkYXRlcy5wdXNoKGZyb21FbCk7XG4gICAgICAgICAgICBkb21fZGVmYXVsdC5hcHBseVN0aWNreU9wZXJhdGlvbnMoZnJvbUVsKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGZvY3VzZWRTZWxlY3RDaGFuZ2VkKSB7XG4gICAgICAgICAgICAgIGZyb21FbC5ibHVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZG9tX2RlZmF1bHQuaXNQaHhVcGRhdGUodG9FbCwgcGh4VXBkYXRlLCBbXCJhcHBlbmRcIiwgXCJwcmVwZW5kXCJdKSkge1xuICAgICAgICAgICAgICBhcHBlbmRQcmVwZW5kVXBkYXRlcy5wdXNoKFxuICAgICAgICAgICAgICAgIG5ldyBET01Qb3N0TW9ycGhSZXN0b3JlcihcbiAgICAgICAgICAgICAgICAgIGZyb21FbCxcbiAgICAgICAgICAgICAgICAgIHRvRWwsXG4gICAgICAgICAgICAgICAgICB0b0VsLmdldEF0dHJpYnV0ZShwaHhVcGRhdGUpXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZG9tX2RlZmF1bHQuc3luY0F0dHJzVG9Qcm9wcyh0b0VsKTtcbiAgICAgICAgICAgIGRvbV9kZWZhdWx0LmFwcGx5U3RpY2t5T3BlcmF0aW9ucyh0b0VsKTtcbiAgICAgICAgICAgIHRoaXMudHJhY2tCZWZvcmVVcGRhdGVkKGZyb21FbCwgdG9FbCk7XG4gICAgICAgICAgICByZXR1cm4gZnJvbUVsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIG1vcnBoZG9tX2VzbV9kZWZhdWx0KHRhcmdldENvbnRhaW5lcjIsIHNvdXJjZSwgbW9ycGhDYWxsYmFja3MpO1xuICAgIH07XG4gICAgdGhpcy50cmFja0JlZm9yZVVwZGF0ZWQoY29udGFpbmVyLCBjb250YWluZXIpO1xuICAgIGxpdmVTb2NrZXQudGltZShcIm1vcnBoZG9tXCIsICgpID0+IHtcbiAgICAgIHRoaXMuc3RyZWFtcy5mb3JFYWNoKChbcmVmLCBpbnNlcnRzLCBkZWxldGVJZHMsIHJlc2V0XSkgPT4ge1xuICAgICAgICBpbnNlcnRzLmZvckVhY2goKFtrZXksIHN0cmVhbUF0LCBsaW1pdCwgdXBkYXRlT25seV0pID0+IHtcbiAgICAgICAgICB0aGlzLnN0cmVhbUluc2VydHNba2V5XSA9IHsgcmVmLCBzdHJlYW1BdCwgbGltaXQsIHJlc2V0LCB1cGRhdGVPbmx5IH07XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocmVzZXQgIT09IHZvaWQgMCkge1xuICAgICAgICAgIGRvbV9kZWZhdWx0LmFsbChkb2N1bWVudCwgYFske1BIWF9TVFJFQU1fUkVGfT1cIiR7cmVmfVwiXWAsIChjaGlsZCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVTdHJlYW1DaGlsZEVsZW1lbnQoY2hpbGQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGRlbGV0ZUlkcy5mb3JFYWNoKChpZCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNoaWxkID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICAgICAgICAgIGlmIChjaGlsZCkge1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVTdHJlYW1DaGlsZEVsZW1lbnQoY2hpbGQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIGlmIChpc0pvaW5QYXRjaCkge1xuICAgICAgICBkb21fZGVmYXVsdC5hbGwodGhpcy5jb250YWluZXIsIGBbJHtwaHhVcGRhdGV9PSR7UEhYX1NUUkVBTX1dYCkuZmlsdGVyKChlbCkgPT4gdGhpcy52aWV3Lm93bnNFbGVtZW50KGVsKSkuZm9yRWFjaCgoZWwpID0+IHtcbiAgICAgICAgICBBcnJheS5mcm9tKGVsLmNoaWxkcmVuKS5mb3JFYWNoKChjaGlsZCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVTdHJlYW1DaGlsZEVsZW1lbnQoY2hpbGQsIHRydWUpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIG1vcnBoKHRhcmdldENvbnRhaW5lciwgaHRtbCk7XG4gICAgICBsZXQgdGVsZXBvcnRDb3VudCA9IDA7XG4gICAgICB3aGlsZSAocG9ydGFsQ2FsbGJhY2tzLmxlbmd0aCA+IDAgJiYgdGVsZXBvcnRDb3VudCA8IDUpIHtcbiAgICAgICAgY29uc3QgY29weSA9IHBvcnRhbENhbGxiYWNrcy5zbGljZSgpO1xuICAgICAgICBwb3J0YWxDYWxsYmFja3MgPSBbXTtcbiAgICAgICAgY29weS5mb3JFYWNoKChjYWxsYmFjaykgPT4gY2FsbGJhY2soKSk7XG4gICAgICAgIHRlbGVwb3J0Q291bnQrKztcbiAgICAgIH1cbiAgICAgIHRoaXMudmlldy5wb3J0YWxFbGVtZW50SWRzLmZvckVhY2goKGlkKSA9PiB7XG4gICAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICAgICAgICBpZiAoZWwpIHtcbiAgICAgICAgICBjb25zdCBzcmNJZCA9IGVsLmdldEF0dHJpYnV0ZShQSFhfVEVMRVBPUlRFRF9TUkMpO1xuICAgICAgICAgIGlmIChzcmNJZCkge1xuICAgICAgICAgICAgY29uc3Qgc291cmNlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoc3JjSWQpO1xuICAgICAgICAgICAgaWYgKCFzb3VyY2UpIHtcbiAgICAgICAgICAgICAgZWwucmVtb3ZlKCk7XG4gICAgICAgICAgICAgIHRoaXMub25Ob2RlRGlzY2FyZGVkKGVsKTtcbiAgICAgICAgICAgICAgdGhpcy52aWV3LmRyb3BQb3J0YWxFbGVtZW50SWQoaWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgaWYgKGxpdmVTb2NrZXQuaXNEZWJ1Z0VuYWJsZWQoKSkge1xuICAgICAgZGV0ZWN0RHVwbGljYXRlSWRzKCk7XG4gICAgICBkZXRlY3RJbnZhbGlkU3RyZWFtSW5zZXJ0cyh0aGlzLnN0cmVhbUluc2VydHMpO1xuICAgICAgQXJyYXkuZnJvbShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiaW5wdXRbbmFtZT1pZF1cIikpLmZvckVhY2goXG4gICAgICAgIChub2RlKSA9PiB7XG4gICAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50ICYmIG5vZGUuZm9ybSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICAgICAgJ0RldGVjdGVkIGFuIGlucHV0IHdpdGggbmFtZT1cImlkXCIgaW5zaWRlIGEgZm9ybSEgVGhpcyB3aWxsIGNhdXNlIHByb2JsZW1zIHdoZW4gcGF0Y2hpbmcgdGhlIERPTS5cXG4nLFxuICAgICAgICAgICAgICBub2RlXG4gICAgICAgICAgICApO1xuICAgICAgICAgI
1H1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKGFwcGVuZFByZXBlbmRVcGRhdGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGxpdmVTb2NrZXQudGltZShcInBvc3QtbW9ycGggYXBwZW5kL3ByZXBlbmQgcmVzdG9yYXRpb25cIiwgKCkgPT4ge1xuICAgICAgICBhcHBlbmRQcmVwZW5kVXBkYXRlcy5mb3JFYWNoKCh1cGRhdGUpID0+IHVwZGF0ZS5wZXJmb3JtKCkpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGxpdmVTb2NrZXQuc2lsZW5jZUV2ZW50cyhcbiAgICAgICgpID0+IGRvbV9kZWZhdWx0LnJlc3RvcmVGb2N1cyhmb2N1c2VkLCBzZWxlY3Rpb25TdGFydCwgc2VsZWN0aW9uRW5kKVxuICAgICk7XG4gICAgZG9tX2RlZmF1bHQuZGlzcGF0Y2hFdmVudChkb2N1bWVudCwgXCJwaHg6dXBkYXRlXCIpO1xuICAgIGFkZGVkLmZvckVhY2goKGVsKSA9PiB0aGlzLnRyYWNrQWZ0ZXJBZGRlZChlbCkpO1xuICAgIHVwZGF0ZXMuZm9yRWFjaCgoZWwpID0+IHRoaXMudHJhY2tBZnRlclVwZGF0ZWQoZWwpKTtcbiAgICB0aGlzLnRyYW5zaXRpb25QZW5kaW5nUmVtb3ZlcygpO1xuICAgIGlmIChleHRlcm5hbEZvcm1UcmlnZ2VyZWQpIHtcbiAgICAgIGxpdmVTb2NrZXQudW5sb2FkKCk7XG4gICAgICBjb25zdCBzdWJtaXR0ZXIgPSBkb21fZGVmYXVsdC5wcml2YXRlKGV4dGVybmFsRm9ybVRyaWdnZXJlZCwgXCJzdWJtaXR0ZXJcIik7XG4gICAgICBpZiAoc3VibWl0dGVyICYmIHN1Ym1pdHRlci5uYW1lICYmIHRhcmdldENvbnRhaW5lci5jb250YWlucyhzdWJtaXR0ZXIpKSB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImlucHV0XCIpO1xuICAgICAgICBpbnB1dC50eXBlID0gXCJoaWRkZW5cIjtcbiAgICAgICAgY29uc3QgZm9ybUlkID0gc3VibWl0dGVyLmdldEF0dHJpYnV0ZShcImZvcm1cIik7XG4gICAgICAgIGlmIChmb3JtSWQpIHtcbiAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoXCJmb3JtXCIsIGZvcm1JZCk7XG4gICAgICAgIH1cbiAgICAgICAgaW5wdXQubmFtZSA9IHN1Ym1pdHRlci5uYW1lO1xuICAgICAgICBpbnB1dC52YWx1ZSA9IHN1Ym1pdHRlci52YWx1ZTtcbiAgICAgICAgc3VibWl0dGVyLnBhcmVudEVsZW1lbnQuaW5zZXJ0QmVmb3JlKGlucHV0LCBzdWJtaXR0ZXIpO1xuICAgICAgfVxuICAgICAgT2JqZWN0LmdldFByb3RvdHlwZU9mKGV4dGVybmFsRm9ybVRyaWdnZXJlZCkuc3VibWl0LmNhbGwoXG4gICAgICAgIGV4dGVybmFsRm9ybVRyaWdnZXJlZFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgdHJhY2tCZWZvcmVVcGRhdGVkKGZyb21FbCwgdG9FbCkge1xuICAgIHRoaXMuYmVmb3JlVXBkYXRlZENhbGxiYWNrcy5mb3JFYWNoKChjYikgPT4gY2IoZnJvbUVsLCB0b0VsKSk7XG4gIH1cbiAgdHJhY2tBZnRlckFkZGVkKGVsKSB7XG4gICAgdGhpcy5hZnRlckFkZGVkQ2FsbGJhY2tzLmZvckVhY2goKGNiKSA9PiBjYihlbCkpO1xuICB9XG4gIHRyYWNrQWZ0ZXJVcGRhdGVkKGVsKSB7XG4gICAgdGhpcy5hZnRlclVwZGF0ZWRDYWxsYmFja3MuZm9yRWFjaCgoY2IpID0+IGNiKGVsKSk7XG4gIH1cbiAgdHJhY2tBZnRlclBoeENoaWxkQWRkZWQoZWwpIHtcbiAgICB0aGlzLmFmdGVyUGh4Q2hpbGRBZGRlZENhbGxiYWNrcy5mb3JFYWNoKChjYikgPT4gY2IoZWwpKTtcbiAgfVxuICB0cmFja0FmdGVyRGlzY2FyZGVkKGVsKSB7XG4gICAgdGhpcy5hZnRlckRpc2NhcmRlZENhbGxiYWNrcy5mb3JFYWNoKChjYikgPT4gY2IoZWwpKTtcbiAgfVxuICB0cmFja0FmdGVyVHJhbnNpdGlvbnNEaXNjYXJkZWQoZWxzKSB7XG4gICAgdGhpcy5hZnRlclRyYW5zaXRpb25zRGlzY2FyZGVkQ2FsbGJhY2tzLmZvckVhY2goKGNiKSA9PiBjYihlbHMpKTtcbiAgfVxuICBvbk5vZGVEaXNjYXJkZWQoZWwpIHtcbiAgICBpZiAoZG9tX2RlZmF1bHQuaXNQaHhDaGlsZChlbCkgfHwgZG9tX2RlZmF1bHQuaXNQaHhTdGlja3koZWwpKSB7XG4gICAgICB0aGlzLmxpdmVTb2NrZXQuZGVzdHJveVZpZXdCeUVsKGVsKTtcbiAgICB9XG4gICAgdGhpcy50cmFja0FmdGVyRGlzY2FyZGVkKGVsKTtcbiAgfVxuICBtYXliZVBlbmRpbmdSZW1vdmUobm9kZSkge1xuICAgIGlmIChub2RlLmdldEF0dHJpYnV0ZSAmJiBub2RlLmdldEF0dHJpYnV0ZSh0aGlzLnBoeFJlbW92ZSkgIT09IG51bGwpIHtcbiAgICAgIHRoaXMucGVuZGluZ1JlbW92ZXMucHVzaChub2RlKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJlbW92ZVN0cmVhbUNoaWxkRWxlbWVudChjaGlsZCwgZm9yY2UgPSBmYWxzZSkge1xuICAgIGlmICghZm9yY2UgJiYgIXRoaXMudmlldy5vd25zRWxlbWVudChjaGlsZCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuc3RyZWFtSW5zZXJ0c1tjaGlsZC5pZF0pIHtcbiAgICAgIHRoaXMuc3RyZWFtQ29tcG9uZW50UmVzdG9yZVtjaGlsZC5pZF0gPSBjaGlsZDtcbiAgICAgIGNoaWxkLnJlbW92ZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIXRoaXMubWF5YmVQZW5kaW5nUmVtb3ZlKGNoaWxkKSkge1xuICAgICAgICBjaGlsZC5yZW1vdmUoKTtcbiAgICAgICAgdGhpcy5vbk5vZGVEaXNjYXJkZWQoY2hpbGQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBnZXRTdHJlYW1JbnNlcnQoZWwpIHtcbiAgICBjb25zdCBpbnNlcnQgPSBlbC5pZCA/IHRoaXMuc3RyZWFtSW5zZXJ0c1tlbC5pZF0gOiB7fTtcbiAgICByZXR1cm4gaW5zZXJ0IHx8IHt9O1xuICB9XG4gIHNldFN0cmVhbVJlZihlbCwgcmVmKSB7XG4gICAgZG9tX2RlZmF1bHQucHV0U3RpY2t5KFxuICAgICAgZWwsXG4gICAgICBQSFhfU1RSRUFNX1JFRixcbiAgICAgIChlbDIpID0+IGVsMi5zZXRBdHRyaWJ1dGUoUEhYX1NUUkVBTV9SRUYsIHJlZilcbiAgICApO1xuICB9XG4gIG1heWJlUmVPcmRlclN0cmVhbShlbCwgaXNOZXcgPSBmYWxzZSkge1xuICAgIGNvbnN0IHsgcmVmLCBzdHJlYW1BdCwgcmVzZXQgfSA9IHRoaXMuZ2V0U3RyZWFtSW5zZXJ0KGVsKTtcbiAgICBpZiAoc3RyZWFtQXQgPT09IHZvaWQgMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnNldFN0cmVhbVJlZihlbCwgcmVmKTtcbiAgICBpZiAoIXJlc2V0ICYmICFpc05ldykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIWVsLnBhcmVudEVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHN0cmVhbUF0ID09PSAwKSB7XG4gICAgICB0aGlzLm1vdmVPckluc2VydEJlZm9yZShcbiAgICAgICAgZWwucGFyZW50RWxlbWVudCxcbiAgICAgICAgZWwsXG4gICAgICAgIGVsLnBhcmVudEVsZW1lbnQuZmlyc3RFbGVtZW50Q2hpbGRcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmIChzdHJlYW1B
1dCA+IDApIHtcbiAgICAgIGNvbnN0IGNoaWxkcmVuID0gQXJyYXkuZnJvbShlbC5wYXJlbnRFbGVtZW50LmNoaWxkcmVuKTtcbiAgICAgIGNvbnN0IG9sZEluZGV4ID0gY2hpbGRyZW4uaW5kZXhPZihlbCk7XG4gICAgICBpZiAoc3RyZWFtQXQgPj0gY2hpbGRyZW4ubGVuZ3RoIC0gMSkge1xuICAgICAgICB0aGlzLm1vdmVPckluc2VydEJlZm9yZShlbC5wYXJlbnRFbGVtZW50LCBlbCwgbnVsbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBzaWJsaW5nID0gY2hpbGRyZW5bc3RyZWFtQXRdO1xuICAgICAgICBpZiAob2xkSW5kZXggPiBzdHJlYW1BdCkge1xuICAgICAgICAgIHRoaXMubW92ZU9ySW5zZXJ0QmVmb3JlKGVsLnBhcmVudEVsZW1lbnQsIGVsLCBzaWJsaW5nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLm1vdmVPckluc2VydEJlZm9yZShcbiAgICAgICAgICAgIGVsLnBhcmVudEVsZW1lbnQsXG4gICAgICAgICAgICBlbCxcbiAgICAgICAgICAgIHNpYmxpbmcubmV4dEVsZW1lbnRTaWJsaW5nXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLm1heWJlTGltaXRTdHJlYW0oZWwpO1xuICB9XG4gIC8vIFJlb3JkZXIgYSBjaGlsZCB3aXRoaW4gaXRzIHBhcmVudC4gV2hlbiBzdXBwb3J0ZWQsIHVzZSB0aGUgYXRvbWljXG4gIC8vIG1vdmVCZWZvcmUgKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9Ob2RlL21vdmVCZWZvcmUpXG4gIC8vIHNvIGNvbm5lY3RlZCBjdXN0b20gZWxlbWVudHMgKGFuZCBvdGhlciBzdGF0ZS1iZWFyaW5nIG5vZGVzIGxpa2UgaWZyYW1lcylcbiAgLy8gYXJlIG5vdCBkaXNjb25uZWN0ZWQgYW5kIHJlY29ubmVjdGVkIGJ5IHRoZSBtb3ZlLiBGYWxscyBiYWNrIHRvXG4gIC8vIGluc2VydEJlZm9yZSBvdGhlcndpc2UuIFBhc3NpbmcgYHJlZiA9PT0gbnVsbGAgbW92ZXMgdG8gdGhlIGVuZC5cbiAgLy8gU2VlIGFsc28gaHR0cHM6Ly9naXRodWIuY29tL3Bob2VuaXhmcmFtZXdvcmsvcGhvZW5peF9saXZlX3ZpZXcvaXNzdWVzLzQyMTIuXG4gIG1vdmVPckluc2VydEJlZm9yZShwYXJlbnQsIGNoaWxkLCByZWYpIHtcbiAgICBpZiAodHlwZW9mIHBhcmVudC5tb3ZlQmVmb3JlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHBhcmVudC5tb3ZlQmVmb3JlKGNoaWxkLCByZWYpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGNhdGNoIHtcbiAgICAgIH1cbiAgICB9XG4gICAgcGFyZW50Lmluc2VydEJlZm9yZShjaGlsZCwgcmVmKTtcbiAgfVxuICBtYXliZUxpbWl0U3RyZWFtKGVsKSB7XG4gICAgY29uc3QgeyBsaW1pdCB9ID0gdGhpcy5nZXRTdHJlYW1JbnNlcnQoZWwpO1xuICAgIGlmIChsaW1pdCAhPT0gbnVsbCkge1xuICAgICAgY29uc3QgY2hpbGRyZW4gPSBBcnJheS5mcm9tKGVsLnBhcmVudEVsZW1lbnQuY2hpbGRyZW4pO1xuICAgICAgaWYgKGxpbWl0IDwgMCAmJiBjaGlsZHJlbi5sZW5ndGggPiBsaW1pdCAqIC0xKSB7XG4gICAgICAgIGNoaWxkcmVuLnNsaWNlKDAsIGNoaWxkcmVuLmxlbmd0aCArIGxpbWl0KS5mb3JFYWNoKChjaGlsZCkgPT4gdGhpcy5yZW1vdmVTdHJlYW1DaGlsZEVsZW1lbnQoY2hpbGQpKTtcbiAgICAgIH0gZWxzZSBpZiAobGltaXQgPj0gMCAmJiBjaGlsZHJlbi5sZW5ndGggPiBsaW1pdCkge1xuICAgICAgICBjaGlsZHJlbi5zbGljZShsaW1pdCkuZm9yRWFjaCgoY2hpbGQpID0+IHRoaXMucmVtb3ZlU3RyZWFtQ2hpbGRFbGVtZW50KGNoaWxkKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHRyYW5zaXRpb25QZW5kaW5nUmVtb3ZlcygpIHtcbiAgICBjb25zdCB7IHBlbmRpbmdSZW1vdmVzLCBsaXZlU29ja2V0IH0gPSB0aGlzO1xuICAgIGlmIChwZW5kaW5nUmVtb3Zlcy5sZW5ndGggPiAwKSB7XG4gICAgICBsaXZlU29ja2V0LnRyYW5zaXRpb25SZW1vdmVzKHBlbmRpbmdSZW1vdmVzLCB0aGlzLnZpZXcsICgpID0+IHtcbiAgICAgICAgcGVuZGluZ1JlbW92ZXMuZm9yRWFjaCgoZWwpID0+IHtcbiAgICAgICAgICBjb25zdCBjaGlsZCA9IGRvbV9kZWZhdWx0LmZpcnN0UGh4Q2hpbGQoZWwpO1xuICAgICAgICAgIGlmIChjaGlsZCkge1xuICAgICAgICAgICAgbGl2ZVNvY2tldC5kZXN0cm95Vmlld0J5RWwoY2hpbGQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbC5yZW1vdmUoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudHJhY2tBZnRlclRyYW5zaXRpb25zRGlzY2FyZGVkKHBlbmRpbmdSZW1vdmVzKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICBpc0NoYW5nZWRTZWxlY3QoZnJvbUVsLCB0b0VsKSB7XG4gICAgaWYgKCEoZnJvbUVsIGluc3RhbmNlb2YgSFRNTFNlbGVjdEVsZW1lbnQpIHx8IGZyb21FbC5tdWx0aXBsZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoZnJvbUVsLm9wdGlvbnMubGVuZ3RoICE9PSB0b0VsLm9wdGlvbnMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgdG9FbC52YWx1ZSA9IGZyb21FbC52YWx1ZTtcbiAgICByZXR1cm4gIWZyb21FbC5pc0VxdWFsTm9kZSh0b0VsKTtcbiAgfVxuICBza2lwQ0lEU2libGluZyhlbCkge1xuICAgIHJldHVybiBlbC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUgJiYgZWwuaGFzQXR0cmlidXRlKFBIWF9TS0lQKTtcbiAgfVxuICBtYXliZUNsb25lTG9ja2VkRWxlbWVudChmcm9tRWwsIGlzRm9jdXNlZEZvcm1FbCkge1xuICAgIGlmICghZnJvbUVsLmhhc0F0dHJpYnV0ZShQSFhfUkVGX1NSQykpXG4gICAgICByZXR1cm4gZnJvbUVsO1xuICAgIGNvbnN0IHJlZiA9IG5ldyBFbGVtZW50UmVmKGZyb21FbCk7XG4gICAgaWYgKCFmcm9tRWwuaGFzQXR0cmlidXRlKFBIWF9SRUZfTE9DSykgfHwgdGhpcy51bmRvUmVmICE9PSBudWxsICYmIHJlZi5pc0xvY2tVbmRvbmVCeSh0aGlzLnVuZG9SZWYpKSB7XG4gICAgICByZXR1cm4gZnJvbUVsO1xuICAgIH1cbiAgICBkb21fZGVmYXVsdC5hcHBseVN0aWNreU9wZXJhdGlvbnMoZnJvbUVsKTtcbiAgICBjb25zdCBjbG9uZTIgPSBmcm9tRWwuaGFzQXR0cmlidXRlKFBIWF9SRUZfTE9DSykgPyBkb21fZGVmYXVsdC5wcml2YXRlKGZyb21FbCwgUEhYX1JFRl9MT0NLKSB8fCBmcm9tRWwuY2xvbmVOb2RlKHRydWUpIDogbnVsbDtcbiAgICBpZiAoIWNsb25lMilcbiAgICAgIHJldHVybi
1Bmcm9tRWw7XG4gICAgZG9tX2RlZmF1bHQucHV0UHJpdmF0ZShmcm9tRWwsIFBIWF9SRUZfTE9DSywgY2xvbmUyKTtcbiAgICByZXR1cm4gaXNGb2N1c2VkRm9ybUVsID8gZnJvbUVsIDogY2xvbmUyO1xuICB9XG4gIGNvcHlOZXN0ZWRQcml2YXRlTG9jayhmcm9tRWwsIHRvRWwpIHtcbiAgICBpZiAodGhpcy51bmRvUmVmID09PSBudWxsIHx8ICFkb21fZGVmYXVsdC5wcml2YXRlKHRvRWwsIFBIWF9SRUZfTE9DSykpXG4gICAgICByZXR1cm47XG4gICAgZG9tX2RlZmF1bHQucHV0UHJpdmF0ZShmcm9tRWwsIFBIWF9SRUZfTE9DSywgZG9tX2RlZmF1bHQucHJpdmF0ZSh0b0VsLCBQSFhfUkVGX0xPQ0spKTtcbiAgfVxuICBpbmRleE9mKHBhcmVudCwgY2hpbGQpIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbShwYXJlbnQuY2hpbGRyZW4pLmluZGV4T2YoY2hpbGQpO1xuICB9XG4gIHRlbGVwb3J0KGVsLCBtb3JwaCkge1xuICAgIGNvbnN0IHRhcmdldFNlbGVjdG9yID0gZWwuZ2V0QXR0cmlidXRlKFBIWF9QT1JUQUwpO1xuICAgIGNvbnN0IHBvcnRhbENvbnRhaW5lciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGFyZ2V0U2VsZWN0b3IpO1xuICAgIGlmICghcG9ydGFsQ29udGFpbmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwicG9ydGFsIHRhcmdldCB3aXRoIHNlbGVjdG9yIFwiICsgdGFyZ2V0U2VsZWN0b3IgKyBcIiBub3QgZm91bmRcIlxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgdG9UZWxlcG9ydCA9IGVsLmNvbnRlbnQuZmlyc3RFbGVtZW50Q2hpbGQ7XG4gICAgaWYgKHRoaXMuc2tpcENJRFNpYmxpbmcodG9UZWxlcG9ydCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCF0b1RlbGVwb3J0Py5pZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcInBoeC1wb3J0YWwgdGVtcGxhdGUgbXVzdCBoYXZlIGEgc2luZ2xlIHJvb3QgZWxlbWVudCB3aXRoIElEIVwiXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBleGlzdGluZyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRvVGVsZXBvcnQuaWQpO1xuICAgIGxldCBwb3J0YWxUYXJnZXQ7XG4gICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICBpZiAoIXBvcnRhbENvbnRhaW5lci5jb250YWlucyhleGlzdGluZykpIHtcbiAgICAgICAgcG9ydGFsQ29udGFpbmVyLmFwcGVuZENoaWxkKGV4aXN0aW5nKTtcbiAgICAgIH1cbiAgICAgIHBvcnRhbFRhcmdldCA9IGV4aXN0aW5nO1xuICAgIH0gZWxzZSB7XG4gICAgICBwb3J0YWxUYXJnZXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRvVGVsZXBvcnQudGFnTmFtZSk7XG4gICAgICBwb3J0YWxDb250YWluZXIuYXBwZW5kQ2hpbGQocG9ydGFsVGFyZ2V0KTtcbiAgICB9XG4gICAgdG9UZWxlcG9ydC5zZXRBdHRyaWJ1dGUoUEhYX1RFTEVQT1JURURfUkVGLCB0aGlzLnZpZXcuaWQpO1xuICAgIHRvVGVsZXBvcnQuc2V0QXR0cmlidXRlKFBIWF9URUxFUE9SVEVEX1NSQywgZWwuaWQpO1xuICAgIG1vcnBoKHBvcnRhbFRhcmdldCwgdG9UZWxlcG9ydCwgdHJ1ZSk7XG4gICAgdG9UZWxlcG9ydC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1RFTEVQT1JURURfUkVGKTtcbiAgICB0b1RlbGVwb3J0LnJlbW92ZUF0dHJpYnV0ZShQSFhfVEVMRVBPUlRFRF9TUkMpO1xuICAgIHRoaXMudmlldy5wdXNoUG9ydGFsRWxlbWVudElkKHRvVGVsZXBvcnQuaWQpO1xuICB9XG4gIGhhbmRsZVJ1bnRpbWVIb29rKGVsLCBzb3VyY2UpIHtcbiAgICBjb25zdCBuYW1lID0gZWwuZ2V0QXR0cmlidXRlKFBIWF9SVU5USU1FX0hPT0spO1xuICAgIGxldCBub25jZSA9IGVsLmhhc0F0dHJpYnV0ZShcIm5vbmNlXCIpID8gZWwuZ2V0QXR0cmlidXRlKFwibm9uY2VcIikgOiBudWxsO1xuICAgIGlmIChlbC5oYXNBdHRyaWJ1dGUoXCJub25jZVwiKSkge1xuICAgICAgY29uc3QgdGVtcGxhdGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidGVtcGxhdGVcIik7XG4gICAgICB0ZW1wbGF0ZS5pbm5lckhUTUwgPSBzb3VyY2U7XG4gICAgICBub25jZSA9IHRlbXBsYXRlLmNvbnRlbnQucXVlcnlTZWxlY3Rvcihgc2NyaXB0WyR7UEhYX1JVTlRJTUVfSE9PS309XCIke0NTUy5lc2NhcGUobmFtZSl9XCJdYCk/LmdldEF0dHJpYnV0ZShcIm5vbmNlXCIpID8/IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIik7XG4gICAgc2NyaXB0LnRleHRDb250ZW50ID0gZWwudGV4dENvbnRlbnQ7XG4gICAgZG9tX2RlZmF1bHQubWVyZ2VBdHRycyhzY3JpcHQsIGVsLCB7IGlzSWdub3JlZDogZmFsc2UgfSk7XG4gICAgaWYgKG5vbmNlKSB7XG4gICAgICBzY3JpcHQubm9uY2UgPSBub25jZTtcbiAgICB9XG4gICAgZWwucmVwbGFjZVdpdGgoc2NyaXB0KTtcbiAgICBlbCA9IHNjcmlwdDtcbiAgfVxufTtcblxuLy8ganMvcGhvZW5peF9saXZlX3ZpZXcvcmVuZGVyZWQuanNcbnZhciBWT0lEX1RBR1MgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldChbXG4gIFwiYXJlYVwiLFxuICBcImJhc2VcIixcbiAgXCJiclwiLFxuICBcImNvbFwiLFxuICBcImNvbW1hbmRcIixcbiAgXCJlbWJlZFwiLFxuICBcImhyXCIsXG4gIFwiaW1nXCIsXG4gIFwiaW5wdXRcIixcbiAgXCJrZXlnZW5cIixcbiAgXCJsaW5rXCIsXG4gIFwibWV0YVwiLFxuICBcInBhcmFtXCIsXG4gIFwic291cmNlXCIsXG4gIFwidHJhY2tcIixcbiAgXCJ3YnJcIlxuXSk7XG52YXIgcXVvdGVDaGFycyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KFtcIidcIiwgJ1wiJ10pO1xudmFyIG1vZGlmeVJvb3QgPSAoaHRtbCwgYXR0cnMsIGNsZWFySW5uZXJIVE1MKSA9PiB7XG4gIGxldCBpID0gMDtcbiAgbGV0IGluc2lkZUNvbW1lbnQgPSBmYWxzZTtcbiAgbGV0IGJlZm9yZVRhZywgYWZ0ZXJUYWcsIHRhZywgdGFnTmFtZUVuZHNBdCwgaWQsIG5ld0hUTUw7XG4gIGNvbnN0IGxvb2thaGVhZCA9IGh0bWwubWF0Y2goL14oXFxzKig/OjwhLS0uKj8tLT5cXHMqKSopPChbXlxcc1xcLz5dKykvKTtcbiAgaWYgKGxvb2thaGVhZCA9PT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgbWFsZm9ybWVkIGh0bWwgJHtodG1sfWApO1xuICB9XG4gIGkgPSBsb29rYWhlYWRbMF0ubGVuZ3RoO1xuICBiZWZvcmVUYWcgPSBsb29rYWhlYWRbMV07XG4gIHRhZyA9IGxvb2thaGVhZFsyXTtcbiAgdGFnTmFtZUVuZHNBdCA9IGk7XG4gIGZvciAoaTsgaSA8IGh0bWwubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoaHRtbC5jaGFyQXQoaSkgPT09IFwiPlwiKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgaWYgKGh0bWwuY2hhckF0KGkpID09PSBcIj1cIikge1xuICAgICAgY29uc3QgaXNJZCA9IGh0bWwuc2xpY2UoaSAtIDMsIGkpID09PSBcIiBpZFwiO1xuICAgICAgaSsrO1xuICAgICAgY29uc3QgY2hhciA9IGh0bWwuY2hhckF0KGkpO1xuICAgICAgaWYgKHF1b3RlQ2hhcnMuaGFzKGNoYXIpKSB7XG4gICAgICAgIGNvbnN0IGF0dHJTdGFydHNBdCA9IGk7XG4gICAgICAgIGkrKztcbiAgICAgICAgZm9yIChpOyBpIDwgaHRtbC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGlmIChodG1sLmNoYXJBdChpKSA9PT0gY2hhcikge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpc0lkKSB7XG4gICAgICAgICAgaWQgPSBodG1sLnNsaWNlKGF0dHJTdGFydHNBdCArIDEsIGkpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGxldCBjbG9zZUF0ID0gaHRtbC5sZW5ndGggLSAxO1xuICBpbnNpZGVDb21tZW50ID0gZmFsc2U7XG4gIHdoaWxlIChjbG9zZUF0ID49IGJlZm9yZVRhZy5sZW5ndGggKyB0YWcubGVuZ3RoKSB7XG4gICAgY29uc3QgY2hhciA9IGh0bWwuY2hhckF0KGNsb3NlQXQpO1xuICAgIGlmIChpbnNpZGVDb21tZW50KSB7XG4gICAgICBpZiAoY2hhciA9PT0gXCItXCIgJiYgaHRtbC5zbGljZShjbG9zZUF0IC0gMywgY2xvc2VBdCkgPT09IFwiPCEtXCIpIHtcbiAgICAgICAgaW5zaWRlQ29tbWVudCA9IGZhbHNlO1xuICAgICAgICBjbG9zZUF0IC09IDQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjbG9zZUF0IC09IDE7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChjaGFyID09PSBcIj5cIiAmJiBodG
11sLnNsaWNlKGNsb3NlQXQgLSAyLCBjbG9zZUF0KSA9PT0gXCItLVwiKSB7XG4gICAgICBpbnNpZGVDb21tZW50ID0gdHJ1ZTtcbiAgICAgIGNsb3NlQXQgLT0gMztcbiAgICB9IGVsc2UgaWYgKGNoYXIgPT09IFwiPlwiKSB7XG4gICAgICBicmVhaztcbiAgICB9IGVsc2Uge1xuICAgICAgY2xvc2VBdCAtPSAxO1xuICAgIH1cbiAgfVxuICBhZnRlclRhZyA9IGh0bWwuc2xpY2UoY2xvc2VBdCArIDEsIGh0bWwubGVuZ3RoKTtcbiAgY29uc3QgYXR0cnNTdHIgPSBPYmplY3Qua2V5cyhhdHRycykubWFwKChhdHRyKSA9PiBhdHRyc1thdHRyXSA9PT0gdHJ1ZSA/IGF0dHIgOiBgJHthdHRyfT1cIiR7YXR0cnNbYXR0cl19XCJgKS5qb2luKFwiIFwiKTtcbiAgaWYgKGNsZWFySW5uZXJIVE1MKSB7XG4gICAgY29uc3QgaWRBdHRyU3RyID0gaWQgPyBgIGlkPVwiJHtpZH1cImAgOiBcIlwiO1xuICAgIGlmIChWT0lEX1RBR1MuaGFzKHRhZykpIHtcbiAgICAgIG5ld0hUTUwgPSBgPCR7dGFnfSR7aWRBdHRyU3RyfSR7YXR0cnNTdHIgPT09IFwiXCIgPyBcIlwiIDogXCIgXCJ9JHthdHRyc1N0cn0vPmA7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5ld0hUTUwgPSBgPCR7dGFnfSR7aWRBdHRyU3RyfSR7YXR0cnNTdHIgPT09IFwiXCIgPyBcIlwiIDogXCIgXCJ9JHthdHRyc1N0cn0+PC8ke3RhZ30+YDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgcmVzdCA9IGh0bWwuc2xpY2UodGFnTmFtZUVuZHNBdCwgY2xvc2VBdCArIDEpO1xuICAgIG5ld0hUTUwgPSBgPCR7dGFnfSR7YXR0cnNTdHIgPT09IFwiXCIgPyBcIlwiIDogXCIgXCJ9JHthdHRyc1N0cn0ke3Jlc3R9YDtcbiAgfVxuICByZXR1cm4gW25ld0hUTUwsIGJlZm9yZVRhZywgYWZ0ZXJUYWddO1xufTtcbnZhciBSZW5kZXJlZCA9IGNsYXNzIHtcbiAgc3RhdGljIGV4dHJhY3QoZGlmZikge1xuICAgIGNvbnN0IHsgW1JFUExZXTogcmVwbHksIFtFVkVOVFNdOiBldmVudHMsIFtUSVRMRV06IHRpdGxlIH0gPSBkaWZmO1xuICAgIGRlbGV0ZSBkaWZmW1JFUExZXTtcbiAgICBkZWxldGUgZGlmZltFVkVOVFNdO1xuICAgIGRlbGV0ZSBkaWZmW1RJVExFXTtcbiAgICByZXR1cm4geyBkaWZmLCB0aXRsZSwgcmVwbHk6IHJlcGx5IHx8IG51bGwsIGV2ZW50czogZXZlbnRzIHx8IFtdIH07XG4gIH1cbiAgY29uc3RydWN0b3Iodmlld0lkLCByZW5kZXJlZCkge1xuICAgIHRoaXMudmlld0lkID0gdmlld0lkO1xuICAgIHRoaXMucmVuZGVyZWQgPSB7fTtcbiAgICB0aGlzLm1hZ2ljSWQgPSAwO1xuICAgIHRoaXMubWVyZ2VEaWZmKHJlbmRlcmVkKTtcbiAgfVxuICBwYXJlbnRWaWV3SWQoKSB7XG4gICAgcmV0dXJuIHRoaXMudmlld0lkO1xuICB9XG4gIHRvU3RyaW5nKG9ubHlDaWRzKSB7XG4gICAgY29uc3QgeyBidWZmZXI6IHN0ciwgc3RyZWFtcyB9ID0gdGhpcy5yZWN1cnNpdmVUb1N0cmluZyhcbiAgICAgIHRoaXMucmVuZGVyZWQsXG4gICAgICB0aGlzLnJlbmRlcmVkW0NPTVBPTkVOVFNdLFxuICAgICAgb25seUNpZHMsXG4gICAgICB0cnVlLFxuICAgICAge31cbiAgICApO1xuICAgIHJldHVybiB7IGJ1ZmZlcjogc3RyLCBzdHJlYW1zIH07XG4gIH1cbiAgcmVjdXJzaXZlVG9TdHJpbmcocmVuZGVyZWQsIGNvbXBvbmVudHMgPSByZW5kZXJlZFtDT01QT05FTlRTXSwgb25seUNpZHMsIGNoYW5nZVRyYWNraW5nLCByb290QXR0cnMpIHtcbiAgICBvbmx5Q2lkcyA9IG9ubHlDaWRzID8gbmV3IFNldChvbmx5Q2lkcykgOiBudWxsO1xuICAgIGNvbnN0IG91dHB1dCA9IHtcbiAgICAgIGJ1ZmZlcjogXCJcIixcbiAgICAgIGNvbXBvbmVudHMsXG4gICAgICBvbmx5Q2lkcyxcbiAgICAgIHN0cmVhbXM6IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KClcbiAgICB9O1xuICAgIHRoaXMudG9PdXRwdXRCdWZmZXIocmVuZGVyZWQsIG51bGwsIG91dHB1dCwgY2hhbmdlVHJhY2tpbmcsIHJvb3RBdHRycyk7XG4gICAgcmV0dXJuIHsgYnVmZmVyOiBvdXRwdXQuYnVmZmVyLCBzdHJlYW1zOiBvdXRwdXQuc3RyZWFtcyB9O1xuICB9XG4gIGNvbXBvbmVudENJRHMoZGlmZikge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhkaWZmW0NPTVBPTkVOVFNdIHx8IHt9KS5tYXAoKGkpID0+IHBhcnNlSW50KGkpKTtcbiAgfVxuICBpc0NvbXBvbmVudE9ubHlEaWZmKGRpZmYpIHtcbiAgICBpZiAoIWRpZmZbQ09NUE9ORU5UU10pIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGRpZmYpLmxlbmd0aCA9PT0gMTtcbiAgfVxuICBnZXRDb21wb25lbnQoZGlmZiwgY2lkKSB7XG4gICAgcmV0dXJuIGRpZmZbQ09NUE9ORU5UU11bY2lkXTtcbiAgfVxuICByZXNldFJlbmRlcihjaWQpIHtcbiAgICBpZiAodGhpcy5yZW5kZXJlZFtDT01QT05FTlRTXVtjaWRdKSB7XG4gICAgICB0aGlzLnJlbmRlcmVkW0NPTVBPTkVOVFNdW2NpZF0ucmVzZXQgPSB0cnVlO1xuICAgIH1cbiAgfVxuICBtZXJnZURpZmYoZGlmZikge1xuICAgIGNvbnN0IG5ld2MgPSBkaWZmW0NPTVBPTkVOVFNdO1xuICAgIGNvbnN0IGNhY2hlID0ge307XG4gICAgZGVsZXRlIGRpZmZbQ09NUE9ORU5UU107XG4gICAgdGhpcy5yZW5kZXJlZCA9IHRoaXMubXV0YWJsZU1lcmdlKHRoaXMucmVuZGVyZWQsIGRpZmYpO1xuICAgIHRoaXMucmVuZGVyZWRbQ09NUE9ORU5UU10gPSB0aGlzLnJlbmRlcmVkW0NPTVBPTkVOVFNdIHx8IHt9O1xuICAgIGlmIChuZXdjKSB7XG4gICAgICBjb25zdCBvbGRjID0gdGhpcy5yZW5kZXJlZFtDT01QT05FTlRTXTtcbiAgICAgIGZvciAoY29uc3QgY2lkIGluIG5ld2MpIHtcbiAgICAgICAgbmV3Y1tjaWRdID0gdGhpcy5jYWNoZWRGaW5kQ29tcG9uZW50KGNpZCwgbmV3Y1tjaWRdLCBvbGRjLCBuZXdjLCBjYWNoZSk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGNpZCBpbiBuZXdjKSB7XG4gICAgICAgIG9sZGNbY2lkXSA9IG5ld2NbY2lkXTtcbiAgICAgIH1cbiAgICAgIGRpZmZbQ09NUE9ORU5UU10gPSBuZXdjO1xuICAgIH1cbiAgfVxuICBjYWNoZWRGaW5kQ29tcG9uZW50KGNpZCwgY2RpZmYsIG9sZGMsIG5ld2MsIGNhY2hlKSB7XG4gICAgaWYgKGNhY2hlW2NpZF0pIHtcbiAgICAgIHJldHVybi
1BjYWNoZVtjaWRdO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgbmRpZmYsIHN0YXQsIHNjaWQgPSBjZGlmZltTVEFUSUNdO1xuICAgICAgaWYgKGlzQ2lkKHNjaWQpKSB7XG4gICAgICAgIGxldCB0ZGlmZjtcbiAgICAgICAgaWYgKHNjaWQgPiAwKSB7XG4gICAgICAgICAgdGRpZmYgPSB0aGlzLmNhY2hlZEZpbmRDb21wb25lbnQoc2NpZCwgbmV3Y1tzY2lkXSwgb2xkYywgbmV3YywgY2FjaGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRkaWZmID0gb2xkY1stc2NpZF07XG4gICAgICAgIH1cbiAgICAgICAgc3RhdCA9IHRkaWZmW1NUQVRJQ107XG4gICAgICAgIG5kaWZmID0gdGhpcy5jbG9uZU1lcmdlKHRkaWZmLCBjZGlmZiwgdHJ1ZSk7XG4gICAgICAgIG5kaWZmW1NUQVRJQ10gPSBzdGF0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmRpZmYgPSBjZGlmZltTVEFUSUNdICE9PSB2b2lkIDAgfHwgb2xkY1tjaWRdID09PSB2b2lkIDAgPyBjZGlmZiA6IHRoaXMuY2xvbmVNZXJnZShvbGRjW2NpZF0sIGNkaWZmLCBmYWxzZSk7XG4gICAgICB9XG4gICAgICBjYWNoZVtjaWRdID0gbmRpZmY7XG4gICAgICByZXR1cm4gbmRpZmY7XG4gICAgfVxuICB9XG4gIG11dGFibGVNZXJnZSh0YXJnZXQsIHNvdXJjZSkge1xuICAgIGlmIChzb3VyY2VbU1RBVElDXSAhPT0gdm9pZCAwKSB7XG4gICAgICByZXR1cm4gc291cmNlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRvTXV0YWJsZU1lcmdlKHRhcmdldCwgc291cmNlKTtcbiAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuICB9XG4gIGRvTXV0YWJsZU1lcmdlKHRhcmdldCwgc291cmNlKSB7XG4gICAgaWYgKHNvdXJjZVtLRVlFRF0pIHtcbiAgICAgIHRoaXMubWVyZ2VLZXllZCh0YXJnZXQsIHNvdXJjZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoY29uc3Qga2V5IGluIHNvdXJjZSkge1xuICAgICAgICBjb25zdCB2YWwgPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgY29uc3QgdGFyZ2V0VmFsID0gdGFyZ2V0W2tleV07XG4gICAgICAgIGNvbnN0IGlzT2JqVmFsID0gaXNPYmplY3QodmFsKTtcbiAgICAgICAgaWYgKGlzT2JqVmFsICYmIHZhbFtTVEFUSUNdID09PSB2b2lkIDAgJiYgaXNPYmplY3QodGFyZ2V0VmFsKSkge1xuICAgICAgICAgIHRoaXMuZG9NdXRhYmxlTWVyZ2UodGFyZ2V0VmFsLCB2YWwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRhcmdldFtrZXldID0gdmFsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh0YXJnZXRbUk9PVF0pIHtcbiAgICAgIHRhcmdldC5uZXdSZW5kZXIgPSB0cnVlO1xuICAgIH1cbiAgfVxuICBjbG9uZShkaWZmKSB7XG4gICAgaWYgKFwic3RydWN0dXJlZENsb25lXCIgaW4gd2luZG93KSB7XG4gICAgICByZXR1cm4gc3RydWN0dXJlZENsb25lKGRpZmYpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShkaWZmKSk7XG4gICAgfVxuICB9XG4gIC8vIGtleWVkIGNvbXByZWhlbnNpb25zXG4gIG1lcmdlS2V5ZWQodGFyZ2V0LCBzb3VyY2UpIHtcbiAgICBjb25zdCBjbG9uZWRUYXJnZXQgPSB0aGlzLmNsb25lKHRhcmdldCk7XG4gICAgT2JqZWN0LmVud
1HJpZXMoc291cmNlW0tFWUVEXSkuZm9yRWFjaCgoW2ksIGVudHJ5XSkgPT4ge1xuICAgICAgaWYgKGkgPT09IEtFWUVEX0NPVU5UKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGVudHJ5KSkge1xuICAgICAgICBjb25zdCBbb2xkX2lkeCwgZGlmZl0gPSBlbnRyeTtcbiAgICAgICAgdGFyZ2V0W0tFWUVEXVtpXSA9IGNsb25lZFRhcmdldFtLRVlFRF1bb2xkX2lkeF07XG4gICAgICAgIHRoaXMuZG9NdXRhYmxlTWVyZ2UodGFyZ2V0W0tFWUVEXVtpXSwgZGlmZik7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBlbnRyeSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICBjb25zdCBvbGRfaWR4ID0gZW50cnk7XG4gICAgICAgIHRhcmdldFtLRVlFRF1baV0gPSBjbG9uZWRUYXJnZXRbS0VZRURdW29sZF9pZHhdO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZW50cnkgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgaWYgKCF0YXJnZXRbS0VZRURdW2ldKSB7XG4gICAgICAgICAgdGFyZ2V0W0tFWUVEXVtpXSA9IHt9O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZG9NdXRhYmxlTWVyZ2UodGFyZ2V0W0tFWUVEXVtpXSwgZW50cnkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChzb3VyY2VbS0VZRURdW0tFWUVEX0NPVU5UXSA8IHRhcmdldFtLRVlFRF1bS0VZRURfQ09VTlRdKSB7XG4gICAgICBmb3IgKGxldCBpID0gc291cmNlW0tFWUVEXVtLRVlFRF9DT1VOVF07IGkgPCB0YXJnZXRbS0VZRURdW0tFWUVEX0NPVU5UXTsgaSsrKSB7XG4gICAgICAgIGRlbGV0ZSB0YXJnZXRbS0VZRURdW2ldO1xuICAgICAgfVxuICAgIH1cbiAgICB0YXJnZXRbS0VZRURdW0tFWUVEX0NPVU5UXSA9IHNvdXJjZVtLRVlFRF1bS0VZRURfQ09VTlRdO1xuICAgIGlmIChzb3VyY2VbU1RSRUFNXSkge1xuICAgICAgdGFyZ2V0W1NUUkVBTV0gPSBzb3VyY2VbU1RSRUFNXTtcbiAgICB9XG4gICAgaWYgKHNvdXJjZVtURU1QTEFURVNdKSB7XG4gICAgICB0YXJnZXRbVEVNUExBVEVTXSA9IHNvdXJjZVtURU1QTEFURVNdO1xuICAgIH1cbiAgfVxuICAvLyBNZXJnZXMgY2lkIHRyZWVzIHRvZ2V0aGVyLCBjb3B5aW5nIHN0YXRpY3MgZnJvbSBzb3VyY2UgdHJlZS5cbiAgLy9cbiAgLy8gVGhlIGBwcnVuZU1hZ2ljSWRgIGlzIHBhc3NlZCB0byBjb250cm9sIHBydW5pbmcgdGhlIG1hZ2ljSWQgb2YgdGhlXG4gIC8vIHRhcmdldC4gV2UgbXVzdCBhbHdheXMgcHJ1bmUgdGhlIG1hZ2ljSWQgd2hlbiB3ZSBhcmUgc2hhcmluZyBzdGF0aWNzXG4gIC8vIGZyb20gYW5vdGhlciBjb21wb25lbnQuIElmIG5vdCBwcnVuaW5nLCB3ZSByZXBsaWNhdGUgdGhlIGxvZ2ljIGZyb21cbiAgLy8gbXV0YWJsZU1lcmdlLCB3aGVyZSB3ZSBzZXQgbmV3UmVuZGVyIHRvIHRydWUgaWYgdGhlcmUgaXMgYSByb290XG4gIC8vIChlZmZlY3RpdmVseSBmb3JjaW5nIHRoZSBuZXcgdmVyc2lvbiB0byBiZSByZW5kZXJlZCBpbnN0ZWFkIG9mIHNraXBwZWQpXG4gIC8vXG4gIGNsb25lTWVyZ2UodGFyZ2V0LCBzb3VyY2UsIHBydW5lTWFnaWNJZCkge1xuICAgIGxldCBtZXJnZWQ7XG4gICAgaWYgKHNvdXJjZVtLRVlFRF0pIHtcbiAgICAgIG1lcmdlZCA9IHRoaXMuY2xvbmUodGFyZ2V0KTtcbiAgICAgIHRoaXMubWVyZ2VLZXllZChtZXJnZWQsIHNvdXJjZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1lcmdlZCA9IHsgLi4udGFyZ2V0LCAuLi5zb3VyY2UgfTtcbiAgICAgIGZvciAoY29uc3Qga2V5IGluIG1lcmdlZCkge1xuICAgICAgICBjb25zdCB2YWwgPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgY29uc3QgdGFyZ2V0VmFsID0gdGFyZ2V0W2tleV07XG4gICAgICAgIGlmIChpc09iamVjdCh2YWwpICYmIHZhbFtTVEFUSUNdID09PSB2b2lkIDAgJiYgaXNPYmplY3QodGFyZ2V0VmFsKSkge1xuICAgICAgICAgIG1lcmdlZFtrZXldID0gdGhpcy5jbG9uZU1lcmdlKHRhcmdldFZhbCwgdmFsLCBwcnVuZU1hZ2ljSWQpO1xuICAgICAgICB9IGVsc2UgaWYgKHZhbCA9PT0gdm9pZCAwICYmIGlzT2JqZWN0KHRhcmdldFZhbCkpIHtcbiAgICAgICAgICBtZXJnZWRba2V5XSA9IHRoaXMuY2xvbmVNZXJnZSh0YXJnZXRWYWwsIHt9LCBwcnVuZU1hZ2ljSWQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChwcnVuZU1hZ2ljSWQpIHtcbiAgICAgIGRlbGV0ZSBtZXJnZWQubWFnaWNJZDtcbiAgICAgIGRlbGV0ZSBtZXJnZWQubmV3UmVuZGVyO1xuICAgIH0gZWxzZSBpZiAodGFyZ2V0W1JPT1RdKSB7XG4gICAgICBtZXJnZWQubmV3UmVuZGVyID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIG1lcmdlZDtcbiAgfVxuICBjb21wb25lbnRUb1N0cmluZyhjaWQpIHtcbiAgICBjb25zdCB7IGJ1ZmZlcjogc3RyLCBzdHJlYW1zIH0gPSB0aGlzLnJlY3Vyc2l2ZUNJRFRvU3RyaW5nKFxuICAgICAgdGhpcy5yZW5kZXJlZFtDT01QT05FTlRTXSxcbiAgICAgIGNpZCxcbiAgICAgIG51bGxcbiAgICApO1xuICAgIGNvbnN0IFtzdHJpcHBlZEhUTUwsIF9iZWZvcmUsIF9hZnRlcl0gPSBtb2RpZnlSb290KHN0ciwge30pO1xuICAgIHJldHVybiB7IGJ1ZmZlcjogc3RyaXBwZWRIVE1MLCBzdHJlYW1zIH07XG4gIH1cbiAgcHJ1bmVDSURzKGNpZHMpIHtcbiAgICBjaWRzLmZvckVhY2goKGNpZCkgPT4gZGVsZXRlIHRoaXMucmVuZGVyZWRbQ09NUE9ORU5UU11bY2lkXSk7XG4gIH1cbiAgLy8gcHJpdmF0ZVxuICBnZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVuZGVyZWQ7XG4gIH1cbiAgaXNOZXdGaW5nZXJwcmludChkaWZmID0ge30pIHtcbiAgICByZXR1cm4gISFkaWZmW1NUQVRJQ107XG4gIH1cbiAgdGVtcGxhdGVTdGF0aWMocGFydCwgdGVtcGxhdGVzKSB7XG4gICAgaWYgKHR5cGVvZiBwYXJ0ID09PSBcIm51bWJlclwiKSB7XG4gICAgICByZXR1cm4gdGVtcGxhdGVzW3BhcnRdO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcGFydDtcbiAgICB9XG4gIH1cbiAgbmV4dE1hZ2ljSUQoKSB7XG4gICAgdGhpcy5tYWdpY0lkKys7XG4gICAgcmV0dXJuIGBtJHt0aGlzLm1hZ2ljSWR9LSR7dGhpcy5wYXJlbnRWaWV3SWQoKX1gO1xuICB9XG4gIC8vIENvbnZlcnRzIHJlbmRlcmVkIHRyZWUgdG8gb3V0cHV0IGJ1ZmZlci5cbiAgLy9cbiAgLy8gY2hhbmdlVHJhY2tpbmcgY29udHJvbHMgaWYgd2UgY2FuIGFwcGx5IHRoZSBQSFhfU0tJUCBvcHRpbWl6YXRpb24uXG4gIHRvT3V0cHV0QnVmZmVyKHJlbmRlcmVkLCB0ZW1wbGF0ZXMsIG91dHB1dCwgY2hhbmdlVHJhY2tpbmcsIHJvb3RBdHRycyA9IHt9KSB7XG4gICAgaWYgKHJlbmRlcmVkW0tFWUVEXSkge1xuICAgICAgcmV0dXJuIHRoaXMuY29tcHJlaGVuc2lvblRvQnVmZmVyKFxuICAgICAgICByZW5kZXJlZCxcbiAgICAgICAgdGVtcGxhdGVzLFxuICAgICAgICBvdXRwdXQsXG4gICAgICAgIGNoYW5nZVRyYWNraW5nXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAocmVuZGVyZWRbVEVNUExBVEVTXSkge1xuICAgICAgdGVtcGxhdGVzID0gcmVuZGVyZWRbVEVNUExBVEVTXTtcbiAgICAgIGRlbGV0ZSByZW5kZXJlZFtURU1QTEFURVNdO1xuICAgIH1cbiAgICBsZXQgeyBbU1RBVElDXTogc3RhdGljcyB9ID0gcmVuZGVyZWQ7XG4gICAgc3RhdGljcyA9IHRoaXMudGVtcGxhdGVTdGF0aWMoc3RhdGljcywgdGVtcGxhdGVzKTtcbiAgICByZW5kZXJlZFtTVEFUSUNd
1ID0gc3RhdGljcztcbiAgICBjb25zdCBpc1Jvb3QgPSByZW5kZXJlZFtST09UXTtcbiAgICBjb25zdCBwcmV2QnVmZmVyID0gb3V0cHV0LmJ1ZmZlcjtcbiAgICBpZiAoaXNSb290KSB7XG4gICAgICBvdXRwdXQuYnVmZmVyID0gXCJcIjtcbiAgICB9XG4gICAgaWYgKGNoYW5nZVRyYWNraW5nICYmIGlzUm9vdCAmJiAhcmVuZGVyZWQubWFnaWNJZCkge1xuICAgICAgcmVuZGVyZWQubmV3UmVuZGVyID0gdHJ1ZTtcbiAgICAgIHJlbmRlcmVkLm1hZ2ljSWQgPSB0aGlzLm5leHRNYWdpY0lEKCk7XG4gICAgfVxuICAgIG91dHB1dC5idWZmZXIgKz0gc3RhdGljc1swXTtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHN0YXRpY3MubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMuZHluYW1pY1RvQnVmZmVyKHJlbmRlcmVkW2kgLSAxXSwgdGVtcGxhdGVzLCBvdXRwdXQsIGNoYW5nZVRyYWNraW5nKTtcbiAgICAgIG91dHB1dC5idWZmZXIgKz0gc3RhdGljc1tpXTtcbiAgICB9XG4gICAgaWYgKGlzUm9vdCkge1xuICAgICAgbGV0IHNraXAgPSBmYWxzZTtcbiAgICAgIGxldCBhdHRycztcbiAgICAgIGlmIChjaGFuZ2VUcmFja2luZyB8fCByZW5kZXJlZC5tYWdpY0lkKSB7XG4gICAgICAgIHNraXAgPSBjaGFuZ2VUcmFja2luZyAmJiAhcmVuZGVyZWQubmV3UmVuZGVyO1xuICAgICAgICBhdHRycyA9IHsgW1BIWF9NQUdJQ19JRF06IHJlbmRlcmVkLm1hZ2ljSWQsIC4uLnJvb3RBdHRycyB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXR0cnMgPSByb290QXR0cnM7XG4gICAgICB9XG4gICAgICBpZiAoc2tpcCkge1xuICAgICAgICBhdHRyc1tQSFhfU0tJUF0gPSB0cnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgW25ld1Jvb3QsIGNvbW1lbnRCZWZvcmUsIGNvbW1lbnRBZnRlcl0gPSBtb2RpZnlSb290KFxuICAgICAgICBvdXRwdXQuYnVmZmVyLFxuICAgICAgICBhdHRycyxcbiAgICAgICAgc2tpcFxuICAgICAgKTtcbiAgICAgIHJlbmRlcmVkLm5ld1JlbmRlciA9IGZhbHNlO1xuICAgICAgb3V0cHV0LmJ1ZmZlciA9IHByZXZCdWZmZXIgKyBjb21tZW50QmVmb3JlICsgbmV3Um9vdCArIGNvbW1lbnRBZnRlcjtcbiAgICB9XG4gIH1cbiAgY29tcHJlaGVuc2lvblRvQnVmZmVyKHJlbmRlcmVkLCB0ZW1wbGF0ZXMsIG91dHB1dCwgY2hhbmdlVHJhY2tpbmcpIHtcbiAgICBjb25zdCBrZXllZFRlbXBsYXRlcyA9IHRlbXBsYXRlcyB8fCByZW5kZXJlZFtURU1QTEFURVNdO1xuICAgIGNvbnN0IHN0YXRpY3MgPSB0aGlzLnRlbXBsYXRlU3RhdGljKHJlbmRlcmVkW1NUQVRJQ10sIHRlbXBsYXRlcyk7XG4gICAgcmVuZGVyZWRbU1RBVElDXSA9IHN0YXRpY3M7XG4gICAgZGVsZXRlIHJlbmRlcmVkW1RFTVBMQVRFU107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZW5kZXJlZFtLRVlFRF1bS0VZRURfQ09VTlRdOyBpKyspIHtcbiAgICAgIG91dHB1dC5idWZmZXIgKz0gc3RhdGljc1swXTtcbiAgICAgIGZvciAobGV0IGogPSAxOyBqIDwgc3RhdGljcy5sZW5ndGg7IGorKykge1xuICAgICAgICB0aGlzLmR5bmFtaWNUb0J1ZmZlcihcbiAgICAgICAgICByZW5kZXJlZFtLRVlFRF1baV1baiAtIDFdLFxuICAgICAgICAgIGtleWVkVGVtcGxhdGVzLFxuICAgICAgICAgIG91dHB1dCxcbiAgICAgICAgICBjaGFuZ2VUcmFja2luZ1xuICAgICAgICApO1xuICAgICAgICBvdXRwdXQuYnVmZmVyICs9IHN0YXRpY3Nbal07XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChyZW5kZXJlZFtTVFJFQU1dKSB7XG4gICAgICBjb25zdCBzdHJlYW0gPSByZW5kZXJlZFtTVFJFQU1dO1xuICAgICAgY29uc3QgW19yZWYsIF9pbnNlcnRzLCBkZWxldGVJZHMsIHJlc2V0XSA9IHN0cmVhbSB8fCBbbnVsbCwge30sIFtdLCBudWxsXTtcbiAgICAgIGlmIChzdHJlYW0gIT09IHZvaWQgMCAmJiAocmVuZGVyZWRbS0VZRURdW0tFWUVEX0NPVU5UXSA+IDAgfHwgZGVsZXRlSWRzLmxlbmd0aCA+IDAgfHwgcmVzZXQpKSB7XG4gICAgICAgIGRlbGV0ZSByZW5kZXJlZFtTVFJFQU1dO1xuICAgICAgICByZW5kZXJlZFtLRVlFRF0gPSB7XG4gICAgICAgICAgW0tFWUVEX0NPVU5UXTogMFxuICAgICAgICB9O1xuICAgICAgICBvdXRwdXQuc3RyZWFtcy5hZGQoc3RyZWFtKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZHluYW1pY1RvQnVmZmVyKHJlbmRlcmVkLCB0ZW1wbGF0ZXMsIG91dHB1dCwgY2hhbmdlVHJhY2tpbmcpIHtcbiAgICBpZiAodHlwZW9mIHJlbmRlcmVkID09PSBcIm51bWJlclwiKSB7XG4gICAgICBjb25zdCB7IGJ1ZmZlcjogc3RyLCBzdHJlYW1zIH0gPSB0aGlzLnJlY3Vyc2l2ZUNJRFRvU3RyaW5nKFxuICAgICAgICBvdXRwdXQuY29tcG9uZW50cyxcbiAgICAgICAgcmVuZGVyZWQsXG4gICAgICAgIG91dHB1dC5vbmx5Q2lkc1xuICAgICAgKTtcbiAgICAgIG91dHB1dC5idWZmZXIgKz0gc3RyO1xuICAgICAgb3V0cHV0LnN0cmVhbXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldChbLi4ub3V0cHV0LnN0cmVhbXMsIC4uLnN0cmVhbXNdKTtcbiAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KHJlbmRlcmVkKSkge1xuICAgICAgdGhpcy50b091dHB1dEJ1ZmZlcihyZW5kZXJlZCwgdGVtcGxhdGVzLCBvdXRwdXQsIGNoYW5nZVRyYWNraW5nLCB7fSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dC5idWZmZXIgKz0gcmVuZGVyZWQ7XG4gICAgfVxuICB9XG4gIHJlY3Vyc2l2ZUNJRFRvU3RyaW5nKGNvbXBvbmVudHMsIGNpZCwgb25seUNpZHMpIHtcbiAgICBjb25zdCBjb21wb25lbnQgPSBjb21wb25lbnRzW2NpZF0gfHwgbG9nRXJyb3IoYG5vIGNvbXBvbmVudCBmb3IgQ0lEICR7Y2lkfWAsIGNvbXBvbmVudHMpO1xuICAgIGNvbnN0IGF0dHJzID0geyBbUEhYX0NPTVBPTkVOVF06IGNpZCwgW1BIWF9WSUVXX1JFRl06IHRoaXMudmlld0lkIH07XG4gICAgY29uc3Qgc2tpcCA9IG9ubHlDaWRzICYmICFvbmx5Q2lkcy5oYXMoY2lkKTtcbiAgICBjb21wb25lbnQubmV3UmVuZGVyID0gIXNraXA7XG4gICAgY29tcG9uZW50Lm1hZ2ljSWQgPSBgYyR7Y2lkfS0ke3RoaXMucGFyZW50Vmlld0lkKCl9YDtcbiAgICBjb25zdCBjaGFuZ2VUcmFja2luZyA9ICFjb21wb25lbnQucmVzZXQ7XG4gICAgY29uc3QgeyBidWZmZXI6IGh0bWwsIHN0cmVhbXMgfSA9IHRoaXMucmVjdXJzaXZlVG9TdHJpbmc
1oXG4gICAgICBjb21wb25lbnQsXG4gICAgICBjb21wb25lbnRzLFxuICAgICAgb25seUNpZHMsXG4gICAgICBjaGFuZ2VUcmFja2luZyxcbiAgICAgIGF0dHJzXG4gICAgKTtcbiAgICBkZWxldGUgY29tcG9uZW50LnJlc2V0O1xuICAgIHJldHVybiB7IGJ1ZmZlcjogaHRtbCwgc3RyZWFtcyB9O1xuICB9XG59O1xuXG4vLyBqcy9waG9lbml4X2xpdmVfdmlldy9qcy5qc1xudmFyIGZvY3VzU3RhY2sgPSBbXTtcbnZhciBkZWZhdWx0X3RyYW5zaXRpb25fdGltZSA9IDIwMDtcbnZhciBKUyA9IHtcbiAgLy8gcHJpdmF0ZVxuICBleGVjKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBkZWZhdWx0cykge1xuICAgIGNvbnN0IFtkZWZhdWx0S2luZCwgZGVmYXVsdEFyZ3NdID0gZGVmYXVsdHMgfHwgW1xuICAgICAgbnVsbCxcbiAgICAgIHsgY2FsbGJhY2s6IGRlZmF1bHRzICYmIGRlZmF1bHRzLmNhbGxiYWNrIH1cbiAgICBdO1xuICAgIGNvbnN0IGNvbW1hbmRzID0gQXJyYXkuaXNBcnJheShwaHhFdmVudCkgPyBwaHhFdmVudCA6IHR5cGVvZiBwaHhFdmVudCA9PT0gXCJzdHJpbmdcIiAmJiBwaHhFdmVudC5zdGFydHNXaXRoKFwiW1wiKSA/IEpTT04ucGFyc2UocGh4RXZlbnQpIDogW1tkZWZhdWx0S2luZCwgZGVmYXVsdEFyZ3NdXTtcbiAgICBjb21tYW5kcy5mb3JFYWNoKChba2luZCwgYXJnc10pID0+IHtcbiAgICAgIGlmIChraW5kID09PSBkZWZhdWx0S2luZCkge1xuICAgICAgICBhcmdzID0geyAuLi5kZWZhdWx0QXJncywgLi4uYXJncyB9O1xuICAgICAgICBhcmdzLmNhbGxiYWNrID0gYXJncy5jYWxsYmFjayB8fCBkZWZhdWx0QXJncy5jYWxsYmFjaztcbiAgICAgIH1cbiAgICAgIHRoaXMuZmlsdGVyVG9FbHModmlldy5saXZlU29ja2V0LCBzb3VyY2VFbCwgYXJncykuZm9yRWFjaCgoZWwpID0+IHtcbiAgICAgICAgdGhpc1tgZXhlY18ke2tpbmR9YF0oZSwgZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsLCBhcmdzKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBpc1Zpc2libGUoZWwpIHtcbiAgICByZXR1cm4gISEoZWwub2Zmc2V0V2lkdGggfHwgZWwub2Zmc2V0SGVpZ2h0IHx8IGVsLmdldENsaWVudFJlY3RzKCkubGVuZ3RoID4gMCk7XG4gIH0sXG4gIC8vIHJldHVybnMgdHJ1ZSBpZiBhbnkgcGFydCBvZiB0aGUgZWxlbWVudCBpcyBpbnNpZGUgdGhlIHZpZXdwb3J0XG4gIGlzSW5WaWV3cG9ydChlbCkge1xuICAgIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCB3aW5kb3dIZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodDtcbiAgICBjb25zdCB3aW5kb3dXaWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aDtcbiAgICByZXR1cm4gcmVjdC5yaWdodCA+IDAgJiYgcmVjdC5ib3R0b20gPiAwICYmIHJlY3QubGVmdCA8IHdpbmRvd1dpZHRoICYmIHJlY3QudG9wIDwgd2luZG93SGVpZ2h0O1xuICB9LFxuICAvLyBwcml2YXRlXG4gIC8vIGNvbW1hbmRzXG4gIGV4ZWNfZXhlYyhlLCBldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIHsgYXR0ciwgdG8gfSkge1xuICAgIGNvbnN0IGVuY29kZWRKUyA9IGVsLmdldEF0dHJpYnV0ZShhdHRyKTtcbiAgICBpZiAoIWVuY29kZWRKUykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBleHBlY3RlZCAke2F0dHJ9IHRvIGNvbnRhaW4gSlMgY29tbWFuZCBvbiBcIiR7dG99XCJgKTtcbiAgICB9XG4gICAgdmlldy5saXZlU29ja2V0LmV4ZWNKUyhlbCwgZW5jb2RlZEpTLCBldmVudFR5cGUpO1xuICB9LFxuICBleGVjX2Rpc3BhdGNoKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBldmVudCwgZGV0YWlsLCBidWJibGVzLCBibG9ja2luZyB9KSB7XG4gICAgZGV0YWlsID0gZGV0YWlsIHx8IHt9O1xuICAgIGRldGFpbC5kaXNwYXRjaGVyID0gc291cmNlRWw7XG4gICAgaWYgKGJsb2NraW5nKSB7XG4gICAgICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIF9yZWplY3QpID0+IHtcbiAgICAgICAgZGV0YWlsLmRvbmUgPSByZXNvbHZlO1xuICAgICAgfSk7XG4gICAgICB2aWV3LmxpdmVTb2NrZXQuYXN5bmNUcmFuc2l0aW9uKHByb21pc2UpO1xuICAgIH1cbiAgICBkb21fZGVmYXVsdC5kaXNwYXRjaEV2ZW50KGVsLCBldmVudCwgeyBkZXRhaWwsIGJ1YmJsZXMgfSk7XG4gIH0sXG4gIGV4ZWNfcHVzaChlLCBldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIGFyZ3MpIHtcbiAgICBjb25zdCB7XG4gICAgICBldmVudCxcbiAgICAgIGRhdGEsXG4gICAgICB0YXJnZXQsXG4gICAgICBwYWdlX2xvYWRpbmcsXG4gICAgICBsb2FkaW5nLFxuICAgICAgdmFsdWUsXG4gICAgICBkaXNwYXRjaGVyLFxuICAgICAgY2FsbGJhY2tcbiAgICB9ID0gYXJncztcbiAgICBjb25zdCBwdXNoT3B0cyA9IHtcbiAgICAgIGxvYWRpbmcsXG4gICAgICB2YWx1ZSxcbiAgICAgIHRhcmdldCxcbiAgICAgIHBhZ2VfbG9hZGluZzogISFwYWdlX2xvYWRpbmcsXG4gICAgICBvcmlnaW5hbEV2ZW50OiBlXG4gICAgfTtcbiAgICBjb25zdCB0YXJnZXRTcmMgPSBldmVudFR5cGUgPT09IFwiY2hhbmdlXCIgJiYgZGlzcGF0Y2hlciA/IGRpc3BhdGNoZXIgOiBzb3VyY2VFbDtcbiAgICBjb25zdCBwaHhUYXJnZXQgPSB0YXJnZXQgfHwgdGFyZ2V0U3JjLmdldEF0dHJpYnV0ZSh2aWV3LmJpbmRpbmcoXCJ0YXJnZXRcIikpIHx8IHRhcmdldFNyYztcbiAgICBjb25zdCBoYW5kbGVyID0gKHRhcmdldFZpZXcsIHRhcmdldEN0eCkgPT4ge1xuICAgICAgaWYgKCF0YXJnZXRWaWV3LmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGV2ZW50VHlwZSA9PT0gXCJjaGFuZ2VcIikge1xuICAgICAgICBsZXQgeyBuZXdDaWQsIF90YXJnZXQgfSA9IGFyZ3M7XG4gICAgICAgIF90YXJnZXQgPSBfdGFyZ2V0IHx8IChkb21fZGVmYXVsdC5pc0Zvcm1Bc3NvY2lhdG
1VkKHNvdXJjZUVsKSA/IHNvdXJjZUVsLm5hbWUgOiB2b2lkIDApO1xuICAgICAgICBpZiAoX3RhcmdldCkge1xuICAgICAgICAgIHB1c2hPcHRzLl90YXJnZXQgPSBfdGFyZ2V0O1xuICAgICAgICB9XG4gICAgICAgIHRhcmdldFZpZXcucHVzaElucHV0KFxuICAgICAgICAgIHNvdXJjZUVsLFxuICAgICAgICAgIHRhcmdldEN0eCxcbiAgICAgICAgICBuZXdDaWQsXG4gICAgICAgICAgZXZlbnQgfHwgcGh4RXZlbnQsXG4gICAgICAgICAgcHVzaE9wdHMsXG4gICAgICAgICAgY2FsbGJhY2tcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoZXZlbnRUeXBlID09PSBcInN1Ym1pdFwiKSB7XG4gICAgICAgIGNvbnN0IHsgc3VibWl0dGVyIH0gPSBhcmdzO1xuICAgICAgICB0YXJnZXRWaWV3LnN1Ym1pdEZvcm0oXG4gICAgICAgICAgc291cmNlRWwsXG4gICAgICAgICAgdGFyZ2V0Q3R4LFxuICAgICAgICAgIGV2ZW50IHx8IHBoeEV2ZW50LFxuICAgICAgICAgIHN1Ym1pdHRlcixcbiAgICAgICAgICBwdXNoT3B0cyxcbiAgICAgICAgICBjYWxsYmFja1xuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGFyZ2V0Vmlldy5wdXNoRXZlbnQoXG4gICAgICAgICAgZXZlbnRUeXBlLFxuICAgICAgICAgIHNvdXJjZUVsLFxuICAgICAgICAgIHRhcmdldEN0eCxcbiAgICAgICAgICBldmVudCB8fCBwaHhFdmVudCxcbiAgICAgICAgICBkYXRhLFxuICAgICAgICAgIHB1c2hPcHRzLFxuICAgICAgICAgIGNhbGxiYWNrXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfTtcbiAgICBpZiAoYXJncy50YXJnZXRWaWV3ICYmIGFyZ3MudGFyZ2V0Q3R4KSB7XG4gICAgICBoYW5kbGVyKGFyZ3MudGFyZ2V0VmlldywgYXJncy50YXJnZXRDdHgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2aWV3LndpdGhpblRhcmdldHMocGh4VGFyZ2V0LCBoYW5kbGVyKTtcbiAgICB9XG4gIH0sXG4gIGV4ZWNfbmF2aWdhdGUoZSwgZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsLCB7IGhyZWYsIHJlcGxhY2UgfSkge1xuICAgIHZpZXcubGl2ZVNvY2tldC5oaXN0b3J5UmVkaXJlY3QoXG4gICAgICBlLFxuICAgICAgaHJlZixcbiAgICAgIHJlcGxhY2UgPyBcInJlcGxhY2VcIiA6IFwicHVzaFwiLFxuICAgICAgbnVsbCxcbiAgICAgIHNvdXJjZUVsXG4gICAgKTtcbiAgfSxcbiAgZXhlY19wYXRjaChlLCBldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIHsgaHJlZiwgcmVwbGFjZSB9KSB7XG4gICAgdmlldy5saXZlU29ja2V0LnB1c2hIaXN0b3J5UGF0Y2goXG4gICAgICBlLFxuICAgICAgaHJlZixcbiAgICAgIHJlcGxhY2UgPyBcInJlcGxhY2VcIiA6IFwicHVzaFwiLFxuICAgICAgc291cmNlRWxcbiAgICApO1xuICB9LFxuICBleGVjX2ZvY3VzKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCkge1xuICAgIGFyaWFfZGVmYXVsdC5hdHRlbXB0Rm9jdXMoZWwpO1xuICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiBhcmlhX2RlZmF1bHQuYXR0ZW1wdEZvY3VzKGVsKSk7XG4gICAgfSk7XG4gIH0sXG4gIGV4ZWNfZm9jdXNfZmlyc3QoZSwgZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsKSB7XG4gICAgYXJpYV9kZWZhdWx0LmZvY3VzRmlyc3RJbnRlcmFjdGl2ZShlbCkgfHwgYXJpYV9kZWZhdWx0LmZvY3VzRmlyc3QoZWwpO1xuICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZShcbiAgICAgICAgKCkgPT4gYXJpYV9kZWZhdWx0LmZvY3VzRmlyc3RJbnRlcmFjdGl2ZShlbCkgfHwgYXJpYV9kZWZhdWx0LmZvY3VzRmlyc3QoZWwpXG4gICAgICApO1xuICAgIH0pO1xuICB9LFxuICBleGVjX3B1c2hfZm9jdXMoZSwgZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsKSB7XG4gICAgZm9jdXNTdGFjay5wdXNoKGVsIHx8IHNvdXJjZUVsKTtcbiAgfSxcbiAgZXhlY19wb3BfZm9jdXMoX2UsIF9ldmVudFR5cGUsIF9waHhFdmVudCwgX3ZpZXcsIF9zb3VyY2VFbCwgX2VsKSB7XG4gICAgY29uc3QgZWwgPSBmb2N1c1N0YWNrLnBvcCgpO1xuICAgIGlmIChlbCkge1xuICAgICAgZWwuZm9jdXMoKTtcbiAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IGVsLmZvY3VzKCkpO1xuICAgICAgfSk7XG4gICAgfVxuICB9LFxuICBleGVjX2FkZF9jbGFzcyhlLCBldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIHsgbmFtZXMsIHRyYW5zaXRpb24sIHRpbWUsIGJsb2NraW5nIH0pIHtcbiAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgbmFtZXMsIFtdLCB0cmFuc2l0aW9uLCB0aW1lLCB2aWV3LCBibG9ja2luZyk7XG4gIH0sXG4gIGV4ZWNfcmVtb3ZlX2NsYXNzKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBuYW1lcywgdHJhbnNpdGlvbiwgdGltZSwgYmxvY2tpbmcgfSkge1xuICAgIHRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCBbXSwgbmFtZXMsIHRyYW5zaXRpb24sIHRpbWUsIHZpZXcsIGJsb2NraW5nKTtcbiAgfSxcbiAgZXhlY190b2dnbGVfY2xhc3MoZSwgZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsLCB7IG5hbWVzLCB0cmFuc2l0aW9uLCB0aW1lLCBibG9ja2luZyB9KSB7XG4gICAgdGhpcy50b2dnbGVDbGFzc2VzKGVsLCBuYW1lcywgdHJhbnNpdGlvbiwgdGltZSwgdmlldywgYmxvY2tpbmcpO1xuICB9LFxuICBleGVjX3RvZ2dsZV9hdHRyKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBhdHRyOiBbYXR0ciwgdmFsMSwgdmFsMl0gfSkge1xuICAgIHRoaXMudG9nZ2xlQXR0cihlbCwgYXR0ciwgdmFsMSwgdmFsMik7XG4gIH0sXG4gIGV4ZWNfaWdub3JlX2F0dHJzKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBhdHRycyB9KSB7XG4gICAgdGhpcy5pZ25vcmVBdHRycyhlbCwgYX
1R0cnMpO1xuICB9LFxuICBleGVjX3RyYW5zaXRpb24oZSwgZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsLCB7IHRpbWUsIHRyYW5zaXRpb24sIGJsb2NraW5nIH0pIHtcbiAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgW10sIFtdLCB0cmFuc2l0aW9uLCB0aW1lLCB2aWV3LCBibG9ja2luZyk7XG4gIH0sXG4gIGV4ZWNfdG9nZ2xlKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBkaXNwbGF5LCBpbnMsIG91dHMsIHRpbWUsIGJsb2NraW5nIH0pIHtcbiAgICB0aGlzLnRvZ2dsZShldmVudFR5cGUsIHZpZXcsIGVsLCBkaXNwbGF5LCBpbnMsIG91dHMsIHRpbWUsIGJsb2NraW5nKTtcbiAgfSxcbiAgZXhlY19zaG93KGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBkaXNwbGF5LCB0cmFuc2l0aW9uLCB0aW1lLCBibG9ja2luZyB9KSB7XG4gICAgdGhpcy5zaG93KGV2ZW50VHlwZSwgdmlldywgZWwsIGRpc3BsYXksIHRyYW5zaXRpb24sIHRpbWUsIGJsb2NraW5nKTtcbiAgfSxcbiAgZXhlY19oaWRlKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBkaXNwbGF5LCB0cmFuc2l0aW9uLCB0aW1lLCBibG9ja2luZyB9KSB7XG4gICAgdGhpcy5oaWRlKGV2ZW50VHlwZSwgdmlldywgZWwsIGRpc3BsYXksIHRyYW5zaXRpb24sIHRpbWUsIGJsb2NraW5nKTtcbiAgfSxcbiAgZXhlY19zZXRfYXR0cihlLCBldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIHsgYXR0cjogW2F0dHIsIHZhbF0gfSkge1xuICAgIHRoaXMuc2V0T3JSZW1vdmVBdHRycyhlbCwgW1thdHRyLCB2YWxdXSwgW10pO1xuICB9LFxuICBleGVjX3JlbW92ZV9hdHRyKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBhdHRyIH0pIHtcbiAgICB0aGlzLnNldE9yUmVtb3ZlQXR0cnMoZWwsIFtdLCBbYXR0cl0pO1xuICB9LFxuICBpZ25vcmVBdHRycyhlbCwgYXR0cnMpIHtcbiAgICBkb21fZGVmYXVsdC5wdXRQcml2YXRlKGVsLCBcIkpTOmlnbm9yZV9hdHRyc1wiLCB7XG4gICAgICBhcHBseTogKGZyb21FbCwgdG9FbCkgPT4ge1xuICAgICAgICBsZXQgZnJvbUF0dHJpYnV0ZXMgPSBBcnJheS5mcm9tKGZyb21FbC5hdHRyaWJ1dGVzKTtcbiAgICAgICAgbGV0IGZyb21BdHRyaWJ1dGVOYW1lcyA9IGZyb21BdHRyaWJ1dGVzLm1hcCgoYXR0cikgPT4gYXR0ci5uYW1lKTtcbiAgICAgICAgQXJyYXkuZnJvbSh0b0VsLmF0dHJpYnV0ZXMpLmZpbHRlcigoYXR0cikgPT4ge1xuICAgICAgICAgIHJldHVybiAhZnJvbUF0dHJpYnV0ZU5hbWVzLmluY2x1ZGVzKGF0dHIubmFtZSk7XG4gICAgICAgIH0pLmZvckVhY2goKGF0dHIpID0+IHtcbiAgICAgICAgICBpZiAoZG9tX2RlZmF1bHQuYXR0cmlidXRlSWdub3JlZChhdHRyLCBhdHRycykpIHtcbiAgICAgICAgICAgIHRvRWwucmVtb3ZlQXR0cmlidXRlKGF0dHIubmFtZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgZnJvbUF0dHJpYnV0ZXMuZm9yRWFjaCgoYXR0cikgPT4ge1xuICAgICAgICAgIGlmIChkb21fZGVmYXVsdC5hdHRyaWJ1dGVJZ25vcmVkKGF0dHIsIGF0dHJzKSkge1xuICAgICAgICAgICAgdG9FbC5zZXRBdHRyaWJ1dGUoYXR0ci5uYW1lLCBhdHRyLnZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9LFxuICBvbkJlZm9yZUVsVXBkYXRlZChmcm9tRWwsIHRvRWwpIHtcbiAgICBjb25zdCBpZ25vcmVBdHRycyA9IGRvbV9kZWZhdWx0LnByaXZhdGUoZnJvbUVsLCBcIkpTOmlnbm9yZV9hdHRyc1wiKTtcbiAgICBpZiAoaWdub3JlQXR0cnMpIHtcbiAgICAgIGlnbm9yZUF0dHJzLmFwcGx5KGZyb21FbCwgdG9FbCk7XG4gICAgfVxuICB9LFxuICAvLyB1dGlscyBmb3IgY29tbWFuZHNcbiAgc2hvdyhldmVudFR5cGUsIHZpZXcsIGVsLCBkaXNwbGF5LCB0cmFuc2l0aW9uLCB0aW1lLCBibG9ja2luZykge1xuICAgIGlmICghdGhpcy5pc1Zpc2libGUoZWwpKSB7XG4gICAgICB0aGlzLnRvZ2dsZShcbiAgICAgICAgZXZlbnRUeXBlLFxuICAgICAgICB2aWV3LFxuICAgICAgICBlbCxcbiAgICAgICAgZGlzcGxheSxcbiAgICAgICAgdHJhbnNpdGlvbixcbiAgICAgICAgbnVsbCxcbiAgICAgICAgdGltZSxcbiAgICAgICAgYmxvY2tpbmdcbiAgICAgICk7XG4gICAgfVxuICB9LFxuICBoaWRlKGV2ZW50VHlwZSwgdmlldywgZWwsIGRpc3BsYXksIHRyYW5zaXRpb24sIHRpbWUsIGJsb2NraW5nKSB7XG4gICAgaWYgKHRoaXMuaXNWaXNpYmxlKGVsKSkge1xuICAgICAgdGhpcy50b2dnbGUoXG4gICAgICAgIGV2ZW50VHlwZSxcbiAgICAgICAgdmlldyxcbiAgICAgICAgZWwsXG4gICAgICAgIGRpc3BsYXksXG4gICAgICAgIG51bGwsXG4gICAgICAgIHRyYW5zaXRpb24sXG4gICAgICAgIHRpbWUsXG4gICAgICAgIGJsb2NraW5nXG4gICAgICApO1xuICAgIH1cbiAgfSxcbiAgdG9nZ2xlKGV2ZW50VHlwZSwgdmlldywgZWwsIGRpc3BsYXksIGlucywgb3V0cywgdGltZSwgYmxvY2tpbmcpIHtcbiAgICB0aW1lID0gdGltZSB8fCBkZWZhdWx0X3RyYW5zaXRpb25fdGltZTtcbiAgICBjb25zdCBbaW5DbGFzc2VzLCBpblN0YXJ0Q2xhc3NlcywgaW5FbmRDbGFzc2VzXSA9IGlucyB8fCBbW10sIFtdLCBbXV07XG4gICAgY29uc3QgW291dENsYXNzZXMsIG91dFN0YXJ0Q2xhc3Nlcywgb3V0RW5kQ2xhc3Nlc10gPSBvdXRzIHx8IFtbXSwgW10sIFtdXTtcbiAgICBpZiAoaW5DbGFzc2VzLmxlbmd0aCA+IDAgfHwgb3V0Q2xhc3Nlcy5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAodGhpcy5pc1Zpc2libGUoZWwpKSB7XG4gICAgICAgIGNvbnN0IG9uU3RhcnQgPSAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoXG4gICAgICAgICAgICBlbCxcbiAgICAgICAgICAgIG91dFN0YXJ0Q2xhc3NlcyxcbiAgICAgICAgICAgIGluQ2xhc3Nlcy5jb25jYXQoaW5TdGFydENsYXNzZXMpLmNvbmNhdChpbkVuZENsYXNzZXMpXG4gICAgICAgICAgKTtcbiAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgI
1HRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCBvdXRDbGFzc2VzLCBbXSk7XG4gICAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKFxuICAgICAgICAgICAgICAoKSA9PiB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgb3V0RW5kQ2xhc3Nlcywgb3V0U3RhcnRDbGFzc2VzKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgb25FbmQgPSAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIFtdLCBvdXRDbGFzc2VzLmNvbmNhdChvdXRFbmRDbGFzc2VzKSk7XG4gICAgICAgICAgZG9tX2RlZmF1bHQucHV0U3RpY2t5KFxuICAgICAgICAgICAgZWwsXG4gICAgICAgICAgICBcInRvZ2dsZVwiLFxuICAgICAgICAgICAgKGN1cnJlbnRFbCkgPT4gY3VycmVudEVsLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIlxuICAgICAgICAgICk7XG4gICAgICAgICAgZWwuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJwaHg6aGlkZS1lbmRcIikpO1xuICAgICAgICB9O1xuICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcInBoeDpoaWRlLXN0YXJ0XCIpKTtcbiAgICAgICAgaWYgKGJsb2NraW5nID09PSBmYWxzZSkge1xuICAgICAgICAgIG9uU3RhcnQoKTtcbiAgICAgICAgICBzZXRUaW1lb3V0KG9uRW5kLCB0aW1lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2aWV3LnRyYW5zaXRpb24odGltZSwgb25TdGFydCwgb25FbmQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZXZlbnRUeXBlID09PSBcInJlbW92ZVwiKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9uU3RhcnQgPSAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoXG4gICAgICAgICAgICBlbCxcbiAgICAgICAgICAgIGluU3RhcnRDbGFzc2VzLFxuICAgICAgICAgICAgb3V0Q2xhc3Nlcy5jb25jYXQob3V0U3RhcnRDbGFzc2VzKS5jb25jYXQob3V0RW5kQ2xhc3NlcylcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IHN0aWNreURpc3BsYXkgPSBkaXNwbGF5IHx8IHRoaXMuZGVmYXVsdERpc3BsYXkoZWwpO1xuICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIGluQ2xhc3NlcywgW10pO1xuICAgICAgICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgICAgIGRvbV9kZWZhdWx0LnB1dFN0aWNreShcbiAgICAgICAgICAgICAgICBlbCxcbiAgICAgICAgICAgICAgICBcInRvZ2dsZVwiLFxuICAgICAgICAgICAgICAgIChjdXJyZW50RWwpID0+IGN1cnJlbnRFbC5zdHlsZS5kaXNwbGF5ID0gc3RpY2t5RGlzcGxheVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgaW5FbmRDbGFzc2VzLCBpblN0YXJ0Q2xhc3Nlcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgb25FbmQgPSAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIFtdLCBpbkNsYXNzZXMuY29uY2F0KGluRW5kQ2xhc3NlcykpO1xuICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwicGh4OnNob3ctZW5kXCIpKTtcbiAgICAgICAgfTtcbiAgICAgICAgZWwuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJwaHg6c2hvdy1zdGFydFwiKSk7XG4gICAgICAgIGlmIChibG9ja2luZyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICBvblN0YXJ0KCk7XG4gICAgICAgICAgc2V0VGltZW91dChvbkVuZCwgdGltZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmlldy50cmFuc2l0aW9uKHRpbWUsIG9uU3RhcnQsIG9uRW5kKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5pc1Zpc2libGUoZWwpKSB7XG4gICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwicGh4OmhpZGUtc3RhcnRcIikpO1xuICAgICAgICAgIGRvbV9kZWZhdWx0LnB1dFN0aWNreShcbiAgICAgICAgICAgIGVsLFxuICAgICAgICAgICAgXCJ0b2dnbGVcIixcbiAgICAgICAgICAgIChjdXJyZW50RWwpID0+IGN1cnJlbnRFbC5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCJcbiAgICAgICAgICApO1xuICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwicGh4OmhpZGUtZW5kXCIpKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcInBoeDpzaG93LXN0YXJ0XCIpKTtcbiAgICAgICAgICBjb25zdCBzdGlja3lEaXNwbGF5ID0gZGlzcGxheSB8fCB0aGlzLmRlZmF1bHREaXNwbGF5KGVsKTtcbiAgICAgICAgICBkb21fZGVmYXVsdC5wdXRTdGlja3koXG4gICAgICAgICAgICBlbCxcbiAgICAgICAgICAgIFwidG9nZ2xlXCIsXG4gICAgICAgICAgICAoY3VycmVudEVsKSA9PiBjdXJyZW50RWwuc3R5bGUuZGlzcGxheSA9IHN0aWNreURpc3BsYXlcbiAgICAgICAgICApO1xuICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwicGh4OnNob3ctZW5kXCIpKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuICB0b2dnbGVDbGFzc2VzKGVsLCBjbGFzc2VzLCB0cmFuc2l0aW9uLCB0aW1lLCB2aWV3LCBibG9ja2luZykge1xuICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgY29uc3QgW3ByZXZBZGRzLCBwcmV2UmVtb3Zlc10gPSBkb21fZGVmYXVsdC5nZXRTdGlja3koZWwsIFwiY2xhc3Nlc1wiLCBbW10sIFtdXSk7XG4gICAgICBjb25zdCBuZXdBZGRzID0gY2xhc3Nlcy5maWx0ZXIoXG4gICAgICAgIChuYW1lKSA9PiBwcmV2QWRkcy5pbmRleE9mKG5hbW
1UpIDwgMCAmJiAhZWwuY2xhc3NMaXN0LmNvbnRhaW5zKG5hbWUpXG4gICAgICApO1xuICAgICAgY29uc3QgbmV3UmVtb3ZlcyA9IGNsYXNzZXMuZmlsdGVyKFxuICAgICAgICAobmFtZSkgPT4gcHJldlJlbW92ZXMuaW5kZXhPZihuYW1lKSA8IDAgJiYgZWwuY2xhc3NMaXN0LmNvbnRhaW5zKG5hbWUpXG4gICAgICApO1xuICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoXG4gICAgICAgIGVsLFxuICAgICAgICBuZXdBZGRzLFxuICAgICAgICBuZXdSZW1vdmVzLFxuICAgICAgICB0cmFuc2l0aW9uLFxuICAgICAgICB0aW1lLFxuICAgICAgICB2aWV3LFxuICAgICAgICBibG9ja2luZ1xuICAgICAgKTtcbiAgICB9KTtcbiAgfSxcbiAgdG9nZ2xlQXR0cihlbCwgYXR0ciwgdmFsMSwgdmFsMikge1xuICAgIGlmIChlbC5oYXNBdHRyaWJ1dGUoYXR0cikpIHtcbiAgICAgIGlmICh2YWwyICE9PSB2b2lkIDApIHtcbiAgICAgICAgaWYgKGVsLmdldEF0dHJpYnV0ZShhdHRyKSA9PT0gdmFsMSkge1xuICAgICAgICAgIHRoaXMuc2V0T3JSZW1vdmVBdHRycyhlbCwgW1thdHRyLCB2YWwyXV0sIFtdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNldE9yUmVtb3ZlQXR0cnMoZWwsIFtbYXR0ciwgdmFsMV1dLCBbXSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0T3JSZW1vdmVBdHRycyhlbCwgW10sIFthdHRyXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0T3JSZW1vdmVBdHRycyhlbCwgW1thdHRyLCB2YWwxXV0sIFtdKTtcbiAgICB9XG4gIH0sXG4gIGFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgYWRkcywgcmVtb3ZlcywgdHJhbnNpdGlvbiwgdGltZSwgdmlldywgYmxvY2tpbmcpIHtcbiAgICB0aW1lID0gdGltZSB8fCBkZWZhdWx0X3RyYW5zaXRpb25fdGltZTtcbiAgICBjb25zdCBbdHJhbnNpdGlvblJ1biwgdHJhbnNpdGlvblN0YXJ0LCB0cmFuc2l0aW9uRW5kXSA9IHRyYW5zaXRpb24gfHwgW1xuICAgICAgW10sXG4gICAgICBbXSxcbiAgICAgIFtdXG4gICAgXTtcbiAgICBpZiAodHJhbnNpdGlvblJ1bi5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBvblN0YXJ0ID0gKCkgPT4ge1xuICAgICAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhcbiAgICAgICAgICBlbCxcbiAgICAgICAgICB0cmFuc2l0aW9uU3RhcnQsXG4gICAgICAgICAgW10uY29uY2F0KHRyYW5zaXRpb25SdW4pLmNvbmNhdCh0cmFuc2l0aW9uRW5kKVxuICAgICAgICApO1xuICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgdHJhbnNpdGlvblJ1biwgW10pO1xuICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoXG4gICAgICAgICAgICAoKSA9PiB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgdHJhbnNpdGlvbkVuZCwgdHJhbnNpdGlvblN0YXJ0KVxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICAgIGNvbnN0IG9uRG9uZSA9ICgpID0+IHRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKFxuICAgICAgICBlbCxcbiAgICAgICAgYWRkcy5jb25jYXQodHJhbnNpdGlvbkVuZCksXG4gICAgICAgIHJlbW92ZXMuY29uY2F0KHRyYW5zaXRpb25SdW4pLmNvbmNhdCh0cmFuc2l0aW9uU3RhcnQpXG4gICAgICApO1xuICAgICAgaWYgKGJsb2NraW5nID09PSBmYWxzZSkge1xuICAgICAgICBvblN0YXJ0KCk7XG4gICAgICAgIHNldFRpbWVvdXQob25Eb25lLCB0aW1lKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZpZXcudHJhbnNpdGlvbih0aW1lLCBvblN0YXJ0LCBvbkRvbmUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgIGNvbnN0IFtwcmV2QWRkcywgcHJldlJlbW92ZXNdID0gZG9tX2RlZmF1bHQuZ2V0U3RpY2t5KGVsLCBcImNsYXNzZXNcIiwgW1tdLCBbXV0pO1xuICAgICAgY29uc3Qga2VlcEFkZHMgPSBhZGRzLmZpbHRlcihcbiAgICAgICAgKG5hbWUpID0+IHByZXZBZGRzLmluZGV4T2YobmFtZSkgPCAwICYmICFlbC5jbGFzc0xpc3QuY29udGFpbnMobmFtZSlcbiAgICAgICk7XG4gICAgICBjb25zdCBrZWVwUmVtb3ZlcyA9IHJlbW92ZXMuZmlsdGVyKFxuICAgICAgICAobmFtZSkgPT4gcHJldlJlbW92ZXMuaW5kZXhPZihuYW1lKSA8IDAgJiYgZWwuY2xhc3NMaXN0LmNvbnRhaW5zKG5hbWUpXG4gICAgICApO1xuICAgICAgY29uc3QgbmV3QWRkcyA9IHByZXZBZGRzLmZpbHRlcigobmFtZSkgPT4gcmVtb3Zlcy5pbmRleE9mKG5hbWUpIDwgMCkuY29uY2F0KGtlZXBBZGRzKTtcbiAgICAgIGNvbnN0IG5ld1JlbW92ZXMgPSBwcmV2UmVtb3Zlcy5maWx0ZXIoKG5hbWUpID0+IGFkZHMuaW5kZXhPZihuYW1lKSA8IDApLmNvbmNhdChrZWVwUmVtb3Zlcyk7XG4gICAgICBkb21fZGVmYXVsdC5wdXRTdGlja3koZWwsIFwiY2xhc3Nlc1wiLCAoY3VycmVudEVsKSA9PiB7XG4gICAgICAgIGN1cnJlbnRFbC5jbGFzc0xpc3QucmVtb3ZlKC4uLm5ld1JlbW92ZXMpO1xuICAgICAgICBjdXJyZW50RWwuY2xhc3NMaXN0LmFkZCguLi5uZXdBZGRzKTtcbiAgICAgICAgcmV0dXJuIFtuZXdBZGRzLCBuZXdSZW1vdmVzXTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBzZXRPclJlbW92ZUF0dHJzKGVsLCBzZXRzLCByZW1vdmVzKSB7XG4gICAgY29uc3QgW3ByZXZTZXRzLCBwcmV2UmVtb3Zlc10gPSBkb21fZGVmYXVsdC5nZXRTdGlja3koZWwsIFwiYXR0cnNcIiwgW1tdLCBbXV0pO1xuICAgIGNvbnN0IGFsdGVyZWRBdHRycyA9IHNldHMubWFwKChbYXR0ciwgX3ZhbF0pID0+IGF0dHIpLmNvbmNhdChyZW1vdmVzKTtcbiAgICBjb25zdCBuZXdTZXRzID0gcHJldlNldHMuZmlsdGVyKChbYXR0ciwgX3ZhbF0pID0+ICFhbHRlcmVkQXR0cnMuaW5jbHVkZXMoYXR0cikpLmNvbmNhdChzZXRzKTtcbiAgICBjb25zdCBuZXdSZW1vdmVzID0gcHJldlJlbW92ZXMuZmlsdGVyKChhdHRyKSA9PiAhYWx0ZXJlZEF0dHJzLmluY2x1ZGVzKGF0dHIpKS5jb25jYXQocmVtb3Zlcyk7XG4gICAgaWYgKHNldHMuc29tZSgoW2F0dHIsIF92YWxdKSA9PiBhdHRyID09PSBcImlkXCIpKSB7XG4gICAgICBkb21fZGVmYXVsdC5wdXRQcml2YXRlKGVsLCBcImNsaWVudHNpZGVJZEF0dHJpYnV0ZVwiLCB0cnVlKTtcbiAgICB9XG4gICAgZG9tX2RlZmF1bHQucHV0U3RpY2t5KGVsLCBcImF0dHJzXCIsIChjdXJyZW50RWwpID0+IHtcbiAgICAgIG5ld1JlbW92ZXMuZm9yRWFjaCgoYXR0cikgPT4gY3VycmVudEVsLnJlbW92ZUF0dHJpYnV0ZShhdHRyKSk7XG4gICAgICBuZXdTZXRzLmZvckVhY2goKFthdHRyLCB2YWxdKSA9PiBjdXJyZW50RWwuc2V0QXR0cmlidXRlKGF0dHIsIHZhbCkpO1xuICAgICAgcmV0dXJuIFtuZXdTZXRzLCBuZXdSZW1vdmVzXTtcbiAgICB9KTtcbiAgfSxcbiAgaGFzQWxsQ2xhc3NlcyhlbCwgY2xhc3Nlcykge1xuICAgIHJldHVybi
1BjbGFzc2VzLmV2ZXJ5KChuYW1lKSA9PiBlbC5jbGFzc0xpc3QuY29udGFpbnMobmFtZSkpO1xuICB9LFxuICBpc1RvZ2dsZWRPdXQoZWwsIG91dENsYXNzZXMpIHtcbiAgICByZXR1cm4gIXRoaXMuaXNWaXNpYmxlKGVsKSB8fCB0aGlzLmhhc0FsbENsYXNzZXMoZWwsIG91dENsYXNzZXMpO1xuICB9LFxuICBmaWx0ZXJUb0VscyhsaXZlU29ja2V0LCBzb3VyY2VFbCwgeyB0byB9KSB7XG4gICAgY29uc3QgZGVmYXVsdFF1ZXJ5ID0gKCkgPT4ge1xuICAgICAgaWYgKHR5cGVvZiB0byA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCh0byk7XG4gICAgICB9IGVsc2UgaWYgKHRvLmNsb3Nlc3QpIHtcbiAgICAgICAgY29uc3QgdG9FbCA9IHNvdXJjZUVsLmNsb3Nlc3QodG8uY2xvc2VzdCk7XG4gICAgICAgIHJldHVybiB0b0VsID8gW3RvRWxdIDogW107XG4gICAgICB9IGVsc2UgaWYgKHRvLmlubmVyKSB7XG4gICAgICAgIHJldHVybiBzb3VyY2VFbC5xdWVyeVNlbGVjdG9yQWxsKHRvLmlubmVyKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiB0byA/IGxpdmVTb2NrZXQuanNRdWVyeVNlbGVjdG9yQWxsKHNvdXJjZUVsLCB0bywgZGVmYXVsdFF1ZXJ5KSA6IFtzb3VyY2VFbF07XG4gIH0sXG4gIGRlZmF1bHREaXNwbGF5KGVsKSB7XG4gICAgcmV0dXJuIHsgdHI6IFwidGFibGUtcm93XCIsIHRkOiBcInRhYmxlLWNlbGxcIiB9W2VsLnRhZ05hbWUudG9Mb3dlckNhc2UoKV0gfHwgXCJibG9ja1wiO1xuICB9LFxuICB0cmFuc2l0aW9uQ2xhc3Nlcyh2YWwpIHtcbiAgICBpZiAoIXZhbCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGxldCBbdHJhbnMsIHRTdGFydCwgdEVuZF0gPSBBcnJheS5pc0FycmF5KHZhbCkgPyB2YWwgOiBbdmFsLnNwbGl0KFwiIFwiKSwgW10sIFtdXTtcbiAgICB0cmFucyA9IEFycmF5LmlzQXJyYXkodHJhbnMpID8gdHJhbnMgOiB0cmFucy5zcGxpdChcIiBcIik7XG4gICAgdFN0YXJ0ID0gQXJyYXkuaXNBcnJheSh0U3RhcnQpID8gdFN0YXJ0IDogdFN0YXJ0LnNwbGl0KFwiIFwiKTtcbiAgICB0RW5kID0gQXJyYXkuaXNBcnJheSh0RW5kKSA/IHRFbmQgOiB0RW5kLnNwbGl0KFwiIFwiKTtcbiAgICByZXR1cm4gW3RyYW5zLCB0U3RhcnQsIHRFbmRdO1xuICB9XG59O1xudmFyIGpzX2RlZmF1bHQgPSBKUztcblxuLy8ganMvcGhvZW5peF9saXZlX3ZpZXcvanNfY29tbWFuZHMudHNcbnZhciBqc19jb21tYW5kc19kZWZhdWx0ID0gKGxpdmVTb2NrZXQsIGV2ZW50VHlwZSkgPT4ge1xuICByZXR1cm4ge1xuICAgIGV4ZWMoZWwsIGVuY29kZWRKUykge1xuICAgICAgbGl2ZVNvY2tldC5leGVjSlMoZWwsIGVuY29kZWRKUywgZXZlbnRUeXBlKTtcbiAgICB9LFxuICAgIHNob3coZWwsIG9wdHMgPSB7fSkge1xuICAgICAgY29uc3Qgb3duZXIgPSBsaXZlU29ja2V0Lm93bmVyKGVsKTtcbiAgICAgIGpzX2RlZmF1bHQuc2hvdyhcbiAgICAgICAgZXZlbnRUeXBlLFxuICAgICAgICBvd25lcixcbiAgICAgICAgZWwsXG4gICAgICAgIG9wdHMuZGlzcGxheSxcbiAgICAgICAganNfZGVmYXVsdC50cmFuc2l0aW9uQ2xhc3NlcyhvcHRzLnRyYW5zaXRpb24pLFxuICAgICAgICBvcHRzLnRpbWUsXG4gICAgICAgIG9wdHMuYmxvY2tpbmdcbiAgICAgICk7XG4gICAgfSxcbiAgICBoaWRlKGVsLCBvcHRzID0ge30pIHtcbiAgICAgIGNvbnN0IG93bmVyID0gbGl2ZVNvY2tldC5vd25lcihlbCk7XG4gICAgICBqc19kZWZhdWx0LmhpZGUoXG4gICAgICAgIGV2ZW50VHlwZSxcbiAgICAgICAgb3duZXIsXG4gICAgICAgIGVsLFxuICAgICAgICBudWxsLFxuICAgICAgICBqc19kZWZhdWx0LnRyYW5zaXRpb25DbGFzc2VzKG9wdHMudHJhbnNpdGlvbiksXG4gICAgICAgIG9wdHMudGltZSxcbiAgICAgICAgb3B0cy5ibG9ja2luZ1xuICAgICAgKTtcbiAgICB9LFxuICAgIHRvZ2dsZShlbCwgb3B0cyA9IHt9KSB7XG4gICAgICBjb25zdCBvd25lciA9IGxpdmVTb2NrZXQub3duZXIoZWwpO1xuICAgICAgY29uc3QgaW5UcmFuc2l0aW9uID0ganNfZGVmYXVsdC50cmFuc2l0aW9uQ2xhc3NlcyhvcHRzLmluKTtcbiAgICAgIGNvbnN0IG91dFRyYW5zaXRpb24gPSBqc19kZWZhdWx0LnRyYW5zaXRpb25DbGFzc2VzKG9wdHMub3V0KTtcbiAgICAgIGpzX2RlZmF1bHQudG9nZ2xlKFxuICAgICAgICBldmVudFR5cGUsXG4gICAgICAgIG93bmVyLFxuICAgICAgICBlbCxcbiAgICAgICAgb3B0cy5kaXNwbGF5LFxuICAgICAgICBpblRyYW5zaXRpb24sXG4gICAgICAgIG91dFRyYW5zaXRpb24sXG4gICAgICAgIG9wdHMudGltZSxcbiAgICAgICAgb3B0cy5ibG9ja2luZ1xuICAgICAgKTtcbiAgICB9LFxuICAgIGFkZENsYXNzKGVsLCBuYW1lcywgb3B0cyA9IHt9KSB7XG4gICAgICBjb25zdCBjbGFzc05hbWVzID0gQXJyYXkuaXNBcnJheShuYW1lcykgPyBuYW1lcyA6IG5hbWVzLnNwbGl0KFwiIFwiKTtcbiAgICAgIGNvbnN0IG93bmVyID0gbGl2ZVNvY2tldC5vd25lcihlbCk7XG4gICAgICBqc19kZWZhdWx0LmFkZE9yUmVtb3ZlQ2xhc3NlcyhcbiAgICAgICAgZWwsXG4gICAgICAgIGNsYXNzTmFtZXMsXG4gICAgICAgIFtdLFxuICAgICAgICBqc19kZWZhdWx0LnRyYW5zaXRpb25DbGFzc2VzKG9wdHMudHJhbnNpdGlvbiksXG4gICAgICAgIG9wdHMudGltZSxcbiAgICAgICAgb3duZXIsXG4gICAgICAgIG9wdHMuYmxvY2tpbmdcbiAgICAgICk7XG4gICAgfSxcbiAgICByZW1vdmVDbGFzcyhlbCwgbmFtZXMsIG9wdHMgPSB7fSkge1xuICAgICAgY29uc3QgY2xhc3NOYW1lcyA9IEFycmF5LmlzQXJyYXkobmFtZXMpID8gbmFtZXMgOiBuYW1lcy5zcGxpdChcIiBcIik7XG4gICAgICBjb25zdCBvd25lciA9IGxpdmVTb2NrZXQub3duZXIoZWwpO1xuICAgICAganNfZGVmYXVsdC5hZGRPclJlbW92ZUNsYXNzZXMoXG4gICAgICAgIGVsLFxuICAgICAgICBbXSxcbiAgICAgICAgY2xhc3NOYW1lcyxcbiAgICAgICAganNfZGVmYXVsdC50cmFuc2l0aW9uQ2xhc3NlcyhvcHRzLnRyYW5zaXRpb24pLFxuICAgICAgICBvcHRzLnRpbWUsXG4gICAgICAgIG93bmVyLFxuICAgICAgICBvcHRzLmJsb2NraW5nXG4gICAgICApO1xuICAgIH0sXG4gICAgdG9nZ2xlQ2xhc3MoZWwsIG5hbWVzLCBvcHRzID0ge30pIHtcbiAgICAgIGNvbnN0IGNsYXNzTmFtZXMgPSBBcnJheS5pc0FycmF
15KG5hbWVzKSA/IG5hbWVzIDogbmFtZXMuc3BsaXQoXCIgXCIpO1xuICAgICAgY29uc3Qgb3duZXIgPSBsaXZlU29ja2V0Lm93bmVyKGVsKTtcbiAgICAgIGpzX2RlZmF1bHQudG9nZ2xlQ2xhc3NlcyhcbiAgICAgICAgZWwsXG4gICAgICAgIGNsYXNzTmFtZXMsXG4gICAgICAgIGpzX2RlZmF1bHQudHJhbnNpdGlvbkNsYXNzZXMob3B0cy50cmFuc2l0aW9uKSxcbiAgICAgICAgb3B0cy50aW1lLFxuICAgICAgICBvd25lcixcbiAgICAgICAgb3B0cy5ibG9ja2luZ1xuICAgICAgKTtcbiAgICB9LFxuICAgIHRyYW5zaXRpb24oZWwsIHRyYW5zaXRpb24sIG9wdHMgPSB7fSkge1xuICAgICAgY29uc3Qgb3duZXIgPSBsaXZlU29ja2V0Lm93bmVyKGVsKTtcbiAgICAgIGpzX2RlZmF1bHQuYWRkT3JSZW1vdmVDbGFzc2VzKFxuICAgICAgICBlbCxcbiAgICAgICAgW10sXG4gICAgICAgIFtdLFxuICAgICAgICBqc19kZWZhdWx0LnRyYW5zaXRpb25DbGFzc2VzKHRyYW5zaXRpb24pLFxuICAgICAgICBvcHRzLnRpbWUsXG4gICAgICAgIG93bmVyLFxuICAgICAgICBvcHRzLmJsb2NraW5nXG4gICAgICApO1xuICAgIH0sXG4gICAgc2V0QXR0cmlidXRlKGVsLCBhdHRyLCB2YWwpIHtcbiAgICAgIGpzX2RlZmF1bHQuc2V0T3JSZW1vdmVBdHRycyhlbCwgW1thdHRyLCB2YWxdXSwgW10pO1xuICAgIH0sXG4gICAgcmVtb3ZlQXR0cmlidXRlKGVsLCBhdHRyKSB7XG4gICAgICBqc19kZWZhdWx0LnNldE9yUmVtb3ZlQXR0cnMoZWwsIFtdLCBbYXR0cl0pO1xuICAgIH0sXG4gICAgdG9nZ2xlQXR0cmlidXRlKGVsLCBhdHRyLCB2YWwxLCB2YWwyKSB7XG4gICAgICBqc19kZWZhdWx0LnRvZ2dsZUF0dHIoZWwsIGF0dHIsIHZhbDEsIHZhbDIpO1xuICAgIH0sXG4gICAgcHVzaChlbCwgdHlwZSwgb3B0cyA9IHt9KSB7XG4gICAgICBsaXZlU29ja2V0LndpdGhpbk93bmVycyhlbCwgKHZpZXcpID0+IHtcbiAgICAgICAgY29uc3QgZGF0YSA9IG9wdHMudmFsdWUgfHwge307XG4gICAgICAgIGRlbGV0ZSBvcHRzLnZhbHVlO1xuICAgICAgICBsZXQgZSA9IG5ldyBDdXN0b21FdmVudChcInBoeDpleGVjXCIsIHsgZGV0YWlsOiB7IHNvdXJjZUVsZW1lbnQ6IGVsIH0gfSk7XG4gICAgICAgIGpzX2RlZmF1bHQuZXhlYyhlLCBldmVudFR5cGUsIHR5cGUsIHZpZXcsIGVsLCBbXCJwdXNoXCIsIHsgZGF0YSwgLi4ub3B0cyB9XSk7XG4gICAgICB9KTtcbiAgICB9LFxuICAgIG5hdmlnYXRlKGhyZWYsIG9wdHMgPSB7fSkge1xuICAgICAgZW5zdXJlU2FtZU9yaWdpbihocmVmLCBcIm5hdmlnYXRlXCIpO1xuICAgICAgY29uc3QgY3VzdG9tRXZlbnQgPSBuZXcgQ3VzdG9tRXZlbnQoXCJwaHg6ZXhlY1wiKTtcbiAgICAgIGxpdmVTb2NrZXQuaGlzdG9yeVJlZGlyZWN0KFxuICAgICAgICBjdXN0b21FdmVudCxcbiAgICAgICAgaHJlZixcbiAgICAgICAgb3B0cy5yZXBsYWNlID8gXCJyZXBsYWNlXCIgOiBcInB1c2hcIixcbiAgICAgICAgbnVsbCxcbiAgICAgICAgbnVsbFxuICAgICAgKTtcbiAgICB9LFxuICAgIHBhdGNoKGhyZWYsIG9wdHMgPSB7fSkge1xuICAgICAgZW5zdXJlU2FtZU9yaWdpbihocmVmLCBcInBhdGNoXCIpO1xuICAgICAgY29uc3QgY3VzdG9tRXZlbnQgPSBuZXcgQ3VzdG9tRXZlbnQoXCJwaHg6ZXhlY1wiKTtcbiAgICAgIGxpdmVTb2NrZXQucHVzaEhpc3RvcnlQYXRjaChcbiAgICAgICAgY3VzdG9tRXZlbnQsXG4gICAgICAgIGhyZWYsXG4gICAgICAgIG9wdHMucmVwbGFjZSA/IFwicmVwbGFjZVwiIDogXCJwdXNoXCIsXG4gICAgICAgIG51bGxcbiAgICAgICk7XG4gICAgfSxcbiAgICBpZ25vcmVBdHRyaWJ1dGVzKGVsLCBhdHRycykge1xuICAgICAganNfZGVmYXVsdC5pZ25vcmVBdHRycyhlbCwgQXJyYXkuaXNBcnJheShhdHRycykgPyBhdHRycyA6IFthdHRyc10pO1xuICAgIH1cbiAgfTtcbn07XG5cbi8vIGpzL3Bob2VuaXhfbGl2ZV92aWV3L3ZpZXdfaG9vay50c1xudmFyIEhPT0tfSUQgPSBcImhvb2tJZFwiO1xudmFyIERFQURfSE9PSyA9IFwiZGVhZEhvb2tcIjtcbnZhciB2aWV3SG9va0lEID0gMTtcbnZhciBWaWV3SG9vayA9IGNsYXNzIF9WaWV3SG9vayB7XG4gIGdldCBsaXZlU29ja2V0KCkge1xuICAgIHJldHVybiB0aGlzLl9fbGl2ZVNvY2tldCgpO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgc3RhdGljIG1ha2VJRCgpIHtcbiAgICByZXR1cm4gdmlld0hvb2tJRCsrO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgc3RhdGljIGVsZW1lbnRJRChlbCkge1xuICAgIHJldHVybiBkb21fZGVmYXVsdC5wcml2YXRlKGVsLCBIT09LX0lEKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIHN0YXRpYyBkZWFkSG9vayhlbCkge1xuICAgIHJldHVybiBkb21fZGVmYXVsdC5wcml2YXRlKGVsLCBERUFEX0hPT0spID09PSB0cnVlO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgY29uc3RydWN0b3IodmlldywgZWwsIGNhbGxiYWNrcykge1xuICAgIHRoaXMuZWwgPSBlbDtcbiAgICB0aGlzLl9fYXR0YWNoVmlldyh2aWV3KTtcbiAgICB0aGlzLl9fbGlzdGVuZXJzID0gLyogQF9fUFVSRV9fICovIG5ldyBTZXQoKTtcbiAgICB0aGlzLl9faXNEaXNjb25uZWN0ZWQgPSBmYWxzZTtcbiAgICBkb21fZGVmYXVsdC5wdXRQcml2YXRlKHRoaXMuZWwsIEhPT0tfSUQsIF9WaWV3SG9vay5tYWtlSUQoKSk7XG4gICAgaWYgKHZpZXcgJiYgdmlldy5pc0RlYWQpIHtcbiAgICAgIGRvbV9kZWZhdWx0LnB1dFByaXZhdGUodGhpcy5lbCwgREVBRF9IT09LLCB0cnVlKTtcbiAgICB9XG4gICAgaWYgKGNhbGxiYWNrcykge1xuICAgICAgY29uc3QgcHJvdGVjdGVkUHJvcHMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldChbXG4gICAgICAgIFwiZWxcIixcbiAgICAgICAgXCJsaXZlU29ja2V0XCIsXG4gICAgICAgIFwiX192aWV3XCIsXG4gICAgICAgIFwiX19saXN0ZW5lcnNcIixcbiAgICAgICAgXCJfX2lzRGlzY29ubmVjdGVkXCIsXG4gICAgICAgIFwiY29uc3RydWN0b3JcIixcbiAgICAgICAgLy8gU3RhbmRhcmQgb2JqZWN0IHByb3BlcnRpZXNcbiAgICAgICAgLy8gQ29yZSBWaWV3SG9vayBBUEkgbWV0aG9kc1xuICAgICAgICBcImpzXCIsXG4gICAgICAgIFwicHVzaEV2ZW50XCIsXG4gICAgICAgIFwicHVzaEV2ZW50VG9cIixcbiAgICAgICAgXCJoYW5kbGVFdmVudFwiLFxuICAgICAgICBcInJlbW92ZUhhbmRsZUV2ZW50XCIsXG4gICAgICAgIFwidXBsb2FkXCIsXG4gICAgICAgIFwidXBsb2FkVG9cIixcbiAgICAgICAgLy8gSW50ZXJuYWwgbGlmZWN5Y2xlIGNhbGxlcnNcbiAgICAgICAgXCJfX21vdW50ZWRcIixcbiAgICAgICAgXCJfX3VwZGF0ZWRcIixcbiAgICAgICAgXCJfX2JlZm9yZVVwZGF0ZVwiLFxuICAgICAgICBcIl9fZGVzdHJveWVkXCIsXG4gICAgICAgIFwiX19yZWNvbm5lY3RlZFwiLFxuICAgICAgICBcIl9fZGlzY29ubmVjdGVkXCIsXG4gICAgICAgIFwiX19jbGVhbnVwX19cIlxuICAgICAgXSk7XG4gICAgICBmb3IgKGNvbnN0IGtleSBpbiBjYWxsYmFja3MpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChjYWxsYmFja3MsIGtleSkpIHtcbiAgICAgICAgICB0aGlzW2tleV0gPSBjYWxsYmFja3Nba2V5XTtcbiAgICAgICAgICBpZiAocHJvdGVjdGVkUHJvcHMuaGFzKGtleSkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgYEhvb2sgb2JqZWN0IGZvciBlbGVtZW50ICMke2VsLmlkfSBvdmVyd3JpdGVzIGNvcmUgcHJvcGVydHkgJyR7a2V5fSchYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgI
1H1cbiAgICAgIH1cbiAgICAgIGNvbnN0IGxpZmVjeWNsZU1ldGhvZHMgPSBbXG4gICAgICAgIFwibW91bnRlZFwiLFxuICAgICAgICBcImJlZm9yZVVwZGF0ZVwiLFxuICAgICAgICBcInVwZGF0ZWRcIixcbiAgICAgICAgXCJkZXN0cm95ZWRcIixcbiAgICAgICAgXCJkaXNjb25uZWN0ZWRcIixcbiAgICAgICAgXCJyZWNvbm5lY3RlZFwiXG4gICAgICBdO1xuICAgICAgbGlmZWN5Y2xlTWV0aG9kcy5mb3JFYWNoKChtZXRob2ROYW1lKSA9PiB7XG4gICAgICAgIGlmIChjYWxsYmFja3NbbWV0aG9kTmFtZV0gJiYgdHlwZW9mIGNhbGxiYWNrc1ttZXRob2ROYW1lXSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgdGhpc1ttZXRob2ROYW1lXSA9IGNhbGxiYWNrc1ttZXRob2ROYW1lXTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX19hdHRhY2hWaWV3KHZpZXcpIHtcbiAgICBpZiAodmlldykge1xuICAgICAgdGhpcy5fX3ZpZXcgPSAoKSA9PiB2aWV3O1xuICAgICAgdGhpcy5fX2xpdmVTb2NrZXQgPSAoKSA9PiB2aWV3LmxpdmVTb2NrZXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX192aWV3ID0gKCkgPT4ge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYGhvb2sgbm90IHlldCBhdHRhY2hlZCB0byBhIGxpdmUgdmlldzogJHt0aGlzLmVsLm91dGVySFRNTH1gXG4gICAgICAgICk7XG4gICAgICB9O1xuICAgICAgdGhpcy5fX2xpdmVTb2NrZXQgPSAoKSA9PiB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgaG9vayBub3QgeWV0IGF0dGFjaGVkIHRvIGEgbGl2ZSB2aWV3OiAke3RoaXMuZWwub3V0ZXJIVE1MfWBcbiAgICAgICAgKTtcbiAgICAgIH07XG4gICAgfVxuICB9XG4gIC8vIERlZmF1bHQgbGlmZWN5Y2xlIG1ldGhvZHNcbiAgbW91bnRlZCgpIHtcbiAgfVxuICBiZWZvcmVVcGRhdGUoKSB7XG4gIH1cbiAgdXBkYXRlZCgpIHtcbiAgfVxuICBkZXN0cm95ZWQoKSB7XG4gIH1cbiAgZGlzY29ubmVjdGVkKCkge1xuICB9XG4gIHJlY29ubmVjdGVkKCkge1xuICB9XG4gIC8vIEludGVybmFsIGxpZmVjeWNsZSBjYWxsZXJzIC0gY2FsbGVkIGJ5IHRoZSBWaWV3XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX19tb3VudGVkKCkge1xuICAgIHRoaXMubW91bnRlZCgpO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX191cGRhdGVkKCkge1xuICAgIHRoaXMudXBkYXRlZCgpO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX19iZWZvcmVVcGRhdGUoKSB7XG4gICAgdGhpcy5iZWZvcmVVcGRhdGUoKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIF9fZGVzdHJveWVkKCkge1xuICAgIHRoaXMuZGVzdHJveWVkKCk7XG4gICAgZG9tX2RlZmF1bHQuZGVsZXRlUHJpdmF0ZSh0aGlzLmVsLCBIT09LX0lEKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIF9fcmVjb25uZWN0ZWQoKSB7XG4gICAgaWYgKHRoaXMuX19pc0Rpc2Nvbm5lY3RlZCkge1xuICAgICAgdGhpcy5fX2lzRGlzY29ubmVjdGVkID0gZmFsc2U7XG4gICAgICB0aGlzLnJlY29ubmVjdGVkKCk7XG4gICAgfVxuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX19kaXNjb25uZWN0ZWQoKSB7XG4gICAgdGhpcy5fX2lzRGlzY29ubmVjdGVkID0gdHJ1ZTtcbiAgICB0aGlzLmRpc2Nvbm5lY3RlZCgpO1xuICB9XG4gIGpzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5qc19jb21tYW5kc19kZWZhdWx0KHRoaXMuX192aWV3KCkubGl2ZVNvY2tldCwgXCJob29rXCIpLFxuICAgICAgZXhlYzogKGVuY29kZWRKUykgPT4ge1xuICAgICAgICB0aGlzLl9fdmlldygpLmxpdmVTb2NrZXQuZXhlY0pTKHRoaXMuZWwsIGVuY29kZWRKUywgXCJob29rXCIpO1xuICAgICAgfVxuICAgIH07XG4gIH1cbiAgcHVzaEV2ZW50KGV2ZW50LCBwYXlsb2FkLCBvblJlcGx5KSB7XG4gICAgY29uc3QgcHJvbWlzZSA9IHRoaXMuX192aWV3KCkucHVzaEhvb2tFdmVudChcbiAgICAgIHRoaXMuZWwsXG4gICAgICBudWxsLFxuICAgICAgZXZlbnQsXG4gICAgICBwYXlsb2FkIHx8IHt9XG4gICAgKTtcbiAgICBpZiAob25SZXBseSA9PT0gdm9pZCAwKSB7XG4gICAgICByZXR1cm4gcHJvbWlzZS50aGVuKCh7IHJlcGx5IH0pID0+IHJlcGx5KTtcbiAgICB9XG4gICAgcHJvbWlzZS50aGVuKFxuICAgICAgKHsgcmVwbHksIHJlZiB9KSA9PiBvblJlcGx5KHJlcGx5LCByZWYpXG4gICAgKS5jYXRjaCgoKSA9PiB7XG4gICAgfSk7XG4gIH1cbiAgcHVzaEV2ZW50VG8oc2VsZWN0b3JPclRhcmdldCwgZXZlbnQsIHBheWxvYWQsIG9uUmVwbHkpIHtcbiAgICBpZiAob25SZXBseSA9PT0gdm9pZCAwKSB7XG4gICAgICBjb25zdCB0YXJnZXRQYWlyID0gW107XG4gICAgICB0aGlzLl9fdmlldygpLndpdGhpblRhcmdldHMoXG4gICAgICAgIHNlbGVjdG9yT3JUYXJnZXQsXG4gICAgICAgICh2aWV3LCB0YXJnZXRDdHgpID0+IHtcbiAgICAgICAgICB0YXJnZXRQYWlyLnB1c2goeyB2aWV3LCB0YXJnZXRDdHggfSk7XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgICBjb25zdCBwcm9taXNlcyA9IHRhcmdldFBhaXIubWFwKCh7IHZpZXcsIHRhcmdldEN0eCB9KSA9PiB7XG4gICAgICAgIHJldHVybiB2aWV3LnB1c2hIb29rRXZlbnQoXG4gICAgICAgICAgdGhpcy5lbCxcbiAgICAgICAgICB0YXJnZXRDdHgsXG4gICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgcGF5bG9hZCB8fCB7fVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gUHJvbWlzZS5hbGxTZXR0bGVkKHByb21pc2VzKTtcbiAgICB9XG4gICAgdGhpcy5fX3ZpZXcoKS53aXRoaW5UYXJnZXRzKFxuICAgICAgc2VsZWN0b3JPclRhcmdldCxcbiAgICAgICh2aWV3LCB0YXJnZXRDdHgpID0+IHtcbiAgICAgICAgdmlldy5wdXNoSG9va0V2ZW50KHRoaXMuZWwsIHRhcmdldEN0eCwgZXZlbnQsIHBheWxvYWQgfHwge30pLnRoZW4oXG4gICAgICAgICAgKHsgcmVwbHksIHJlZiB9KSA9PiBvblJlcGx5KHJlcGx5LCByZWYpXG4gICAgICAgICkuY2F0Y2goKCkgPT4ge1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICApO
11xuICB9XG4gIGhhbmRsZUV2ZW50KGV2ZW50LCBjYWxsYmFjaykge1xuICAgIGNvbnN0IGNhbGxiYWNrUmVmID0ge1xuICAgICAgZXZlbnQsXG4gICAgICBjYWxsYmFjazogKGN1c3RvbUV2ZW50KSA9PiBjYWxsYmFjayhjdXN0b21FdmVudC5kZXRhaWwpXG4gICAgfTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIGBwaHg6JHtldmVudH1gLFxuICAgICAgY2FsbGJhY2tSZWYuY2FsbGJhY2tcbiAgICApO1xuICAgIHRoaXMuX19saXN0ZW5lcnMuYWRkKGNhbGxiYWNrUmVmKTtcbiAgICByZXR1cm4gY2FsbGJhY2tSZWY7XG4gIH1cbiAgcmVtb3ZlSGFuZGxlRXZlbnQocmVmKSB7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBgcGh4OiR7cmVmLmV2ZW50fWAsXG4gICAgICByZWYuY2FsbGJhY2tcbiAgICApO1xuICAgIHRoaXMuX19saXN0ZW5lcnMuZGVsZXRlKHJlZik7XG4gIH1cbiAgdXBsb2FkKG5hbWUsIGZpbGVzKSB7XG4gICAgcmV0dXJuIHRoaXMuX192aWV3KCkuZGlzcGF0Y2hVcGxvYWRzKG51bGwsIG5hbWUsIGZpbGVzKTtcbiAgfVxuICB1cGxvYWRUbyhzZWxlY3Rvck9yVGFyZ2V0LCBuYW1lLCBmaWxlcykge1xuICAgIHJldHVybiB0aGlzLl9fdmlldygpLndpdGhpblRhcmdldHMoXG4gICAgICBzZWxlY3Rvck9yVGFyZ2V0LFxuICAgICAgKHZpZXcsIHRhcmdldEN0eCkgPT4ge1xuICAgICAgICB2aWV3LmRpc3BhdGNoVXBsb2Fkcyh0YXJnZXRDdHgsIG5hbWUsIGZpbGVzKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX19jbGVhbnVwX18oKSB7XG4gICAgdGhpcy5fX2xpc3RlbmVycy5mb3JFYWNoKFxuICAgICAgKGNhbGxiYWNrUmVmKSA9PiB0aGlzLnJlbW92ZUhhbmRsZUV2ZW50KGNhbGxiYWNrUmVmKVxuICAgICk7XG4gIH1cbn07XG5cbi8vIGpzL3Bob2VuaXhfbGl2ZV92aWV3L3ZpZXcudHNcbnZhciBwcmVwZW5kRm9ybURhdGFLZXkgPSAoa2V5LCBwcmVmaXgpID0+IHtcbiAgY29uc3QgaXNBcnJheSA9IGtleS5lbmRzV2l0aChcIltdXCIpO1xuICBsZXQgYmFzZUtleSA9IGlzQXJyYXkgPyBrZXkuc2xpY2UoMCwgLTIpIDoga2V5O1xuICBiYXNlS2V5ID0gYmFzZUtleS5yZXBsYWNlKC8oW15cXFtcXF1dKykoXFxdPyQpLywgYCR7cHJlZml4fSQxJDJgKTtcbiAgaWYgKGlzQXJyYXkpIHtcbiAgICBiYXNlS2V5ICs9IFwiW11cIjtcbiAgfVxuICByZXR1cm4gYmFzZUtleTtcbn07XG52YXIgVmlldyA9IGNsYXNzIF9WaWV3IHtcbiAgc3RhdGljIGNsb3Nlc3RWaWV3KGVsKSB7XG4gICAgY29uc3QgbGl2ZVZpZXdFbCA9IGVsLmNsb3Nlc3QoUEhYX1ZJRVdfU0VMRUNUT1IpO1xuICAgIHJldHVybiBsaXZlVmlld0VsID8gZG9tX2RlZmF1bHQucHJpdmF0ZShsaXZlVmlld0VsLCBcInZpZXdcIikgOiBudWxsO1xuICB9XG4gIGNvbnN0cnVjdG9yKGVsLCBsaXZlU29ja2V0LCBwYXJlbnRWaWV3LCBmbGFzaCA9IG51bGwsIGxpdmVSZWZlcmVyID0gbnVsbCkge1xuICAgIHRoaXMucmVuZGVyZWQgPSBudWxsO1xuICAgIHRoaXMuaXNEZWFkID0gZmFsc2U7XG4gICAgdGhpcy5saXZlU29ja2V0ID0gbGl2ZVNvY2tldDtcbiAgICB0aGlzLmZsYXNoID0gZmxhc2g7XG4gICAgdGhpcy5wYXJlbnQgPSBwYXJlbnRWaWV3O1xuICAgIHRoaXMucm9vdCA9IHBhcmVudFZpZXcgPyBwYXJlbnRWaWV3LnJvb3QgOiB0aGlzO1xuICAgIHRoaXMuZWwgPSBlbDtcbiAgICBjb25zdCBib3VuZFZpZXcgPSBkb21fZGVmYXVsdC5wcml2YXRlKHRoaXMuZWwsIFwidmlld1wiKTtcbiAgICBpZiAoYm91bmRWaWV3ICE9PSB2b2lkIDAgJiYgYm91bmRWaWV3LmlzRGVhZCAhPT0gdHJ1ZSkge1xuICAgICAgbG9nRXJyb3IoXG4gICAgICAgIGBUaGUgRE9NIGVsZW1lbnQgZm9yIHRoaXMgdmlldyBoYXMgYWxyZWFkeSBiZWVuIGJvdW5kIHRvIGEgdmlldy5cblxuICAgICAgICBBbiBlbGVtZW50IGNhbiBvbmx5IGV2ZXIgYmUgYXNzb2NpYXRlZCB3aXRoIGEgc2luZ2xlIHZpZXchXG4gICAgICAgIFBsZWFzZSBlbnN1cmUgdGhhdCB5b3UgYXJlIG5vdCB0cnlpbmcgdG8gaW5pdGlhbGl6ZSBtdWx0aXBsZSBMaXZlU29ja2V0cyBvbiB0aGUgc2FtZSBwYWdlLlxuICAgICAgICBUaGlzIGNvdWxkIGhhcHBlbiBpZiB5b3UncmUgYWNjaWRlbnRhbGx5IHRyeWluZyB0byByZW5kZXIgeW91ciByb290IGxheW91dCBtb3JlIHRoYW4gb25jZS5cbiAgICAgICAgRW5zdXJlIHRoYXQgdGhlIHRlbXBsYXRlIHNldCBvbiB0aGUgTGl2ZVZpZXcgaXMgZGlmZmVyZW50IHRoYW4gdGhlIHJvb3QgbGF5b3V0LlxuICAgICAgYCxcbiAgICAgICAgeyB2aWV3OiBib3VuZFZpZXcgfVxuICAgICAgKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBiaW5kIG11bHRpcGxlIHZpZXdzIHRvIHRoZSBzYW1lIERPTSBlbGVtZW50LlwiKTtcbiAgICB9XG4gICAgZG9tX2RlZmF1bHQucHV0UHJpdmF0ZSh0aGlzLmVsLCBcInZpZXdcIiwgdGhpcyk7XG4gICAgdGhpcy5pZCA9IHRoaXMuZWwuaWQ7XG4gICAgdGhpcy5lbC5zZXRBdHRyaWJ1dGUoUEhYX1JPT1RfSUQsIHRoaXMucm9vdC5pZCk7XG4gICAgdGhpcy5yZWYgPSAwO1xuICAgIHRoaXMubGFzdEFja1JlZiA9IG51bGw7XG4gICAgdGhpcy5jaGlsZEpvaW5zID0gMDtcbiAgICB0aGlzLmxvYWRlclRpbWVyID0gbnVsbDtcbiAgICB0aGlzLmRpc2Nvbm5lY3RlZFRpbWVyID0gbnVsbDtcbiAgICB0aGlzLnBlbmRpbmdEaWZmcyA9IFtdO1xuICAgIHRoaXMucGVuZGluZ0Zvcm1zID0gLyogQF9fUFVSRV9fICovIG5ldyBTZXQoKTtcbiAgICB0aGlzLnJlZGlyZWN0ID0gZmFsc2U7XG4gICAgdGhpcy5ocmVmID0gbnVsbDtcbiAgICB0aGlzLmpvaW5Db3VudCA9IHRoaXMucGFyZW50ID8gdGhpcy5wYXJlbnQuam9pbkNvdW50IC0gMSA6IDA7XG4gICAgdGhpcy5qb2luQXR0ZW1wdHMgPSAwO1xuICAgIHRoaXMuam9pblBlbmRpbmcgPSB0cnVlO1xuICAgIHRoaXMuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgdGhpcy5qb2luQ2FsbGJhY2sgPSBmdW5jdGlvbihvbkRvbmUpIHtcbiAgICAgIG9uRG9uZSAmJiBvbkRvbmUoKTtcbiAgICB9O1xuICAgIHRoaXMuc3RvcENhbGxiYWNrID0gZnVuY3Rpb24oKSB7XG4gICAgfTtcbiAgICB0aGlzLnBlbmRpbmdKb2luT3BzID0gW107XG4gICAgdGhpcy52aWV3SG9va3MgPSB7fTtcbiAgICB0aGlzLmZvcm1TdWJtaXRzID0gW107XG4gICAgdGhpcy5jaGlsZHJlbiA9IHRoaXMucGFyZW50ID8gbnVsbCA6IHt9O1xuICAgIHRoaXMucm9vdC5jaGlsZHJlblt0aGlzLmlkXSA9IHt9O1xuICAgIHRoaXMuZm9ybXNGb3JSZWNvdmVyeSA9IHt9O1xuICAgIHRoaXMuY2hhbm5lbCA9IHRoaXMubGl2ZVNvY2tldC5jaGFubmVsKGBsdjoke3RoaXMuaWR9YCwgKCkgPT4ge1xuICAgICAgY29uc3QgdXJsID0gdGh
1pcy5ocmVmICYmIHRoaXMuZXhwYW5kVVJMKHRoaXMuaHJlZik7XG4gICAgICByZXR1cm4ge1xuICAgICAgICByZWRpcmVjdDogdGhpcy5yZWRpcmVjdCA/IHVybCA6IHZvaWQgMCxcbiAgICAgICAgdXJsOiB0aGlzLnJlZGlyZWN0ID8gdm9pZCAwIDogdXJsIHx8IHZvaWQgMCxcbiAgICAgICAgcGFyYW1zOiB0aGlzLmNvbm5lY3RQYXJhbXMobGl2ZVJlZmVyZXIpLFxuICAgICAgICBzZXNzaW9uOiB0aGlzLmdldFNlc3Npb24oKSxcbiAgICAgICAgc3RhdGljOiB0aGlzLmdldFN0YXRpYygpLFxuICAgICAgICBmbGFzaDogdGhpcy5mbGFzaCA/PyB2b2lkIDAsXG4gICAgICAgIHN0aWNreTogdGhpcy5lbC5oYXNBdHRyaWJ1dGUoUEhYX1NUSUNLWSlcbiAgICAgIH07XG4gICAgfSk7XG4gICAgdGhpcy5wb3J0YWxFbGVtZW50SWRzID0gLyogQF9fUFVSRV9fICovIG5ldyBTZXQoKTtcbiAgfVxuICBzZXRIcmVmKGhyZWYpIHtcbiAgICB0aGlzLmhyZWYgPSBocmVmO1xuICB9XG4gIHNldFJlZGlyZWN0KGhyZWYpIHtcbiAgICB0aGlzLnJlZGlyZWN0ID0gdHJ1ZTtcbiAgICB0aGlzLmhyZWYgPSBocmVmO1xuICB9XG4gIGlzTWFpbigpIHtcbiAgICByZXR1cm4gdGhpcy5lbC5oYXNBdHRyaWJ1dGUoUEhYX01BSU4pO1xuICB9XG4gIGNvbm5lY3RQYXJhbXMobGl2ZVJlZmVyZXIpIHtcbiAgICBjb25zdCBwYXJhbXMgPSB0aGlzLmxpdmVTb2NrZXQucGFyYW1zKHRoaXMuZWwpO1xuICAgIGNvbnN0IG1hbmlmZXN0ID0gZG9tX2RlZmF1bHQuYWxsKGRvY3VtZW50LCBgWyR7dGhpcy5iaW5kaW5nKFBIWF9UUkFDS19TVEFUSUMpfV1gKS5tYXAoXG4gICAgICAobm9kZSkgPT4gXCJzcmNcIiBpbiBub2RlICYmIG5vZGUuc3JjIHx8IFwiaHJlZlwiIGluIG5vZGUgJiYgbm9kZS5ocmVmXG4gICAgKS5maWx0ZXIoKHVybCkgPT4gdHlwZW9mIHVybCA9PT0gXCJzdHJpbmdcIik7XG4gICAgaWYgKG1hbmlmZXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgIHBhcmFtc1tcIl90cmFja19zdGF0aWNcIl0gPSBtYW5pZmVzdDtcbiAgICB9XG4gICAgcGFyYW1zW1wiX21vdW50c1wiXSA9IHRoaXMuam9pbkNvdW50O1xuICAgIHBhcmFtc1tcIl9tb3VudF9hdHRlbXB0c1wiXSA9IHRoaXMuam9pbkF0dGVtcHRzO1xuICAgIHBhcmFtc1tcIl9saXZlX3JlZmVyZXJcIl0gPSBsaXZlUmVmZXJlciA/PyB2b2lkIDA7XG4gICAgdGhpcy5qb2luQXR0ZW1wdHMrKztcbiAgICByZXR1cm4gcGFyYW1zO1xuICB9XG4gIGlzQ29ubmVjdGVkKCkge1xuICAgIHJldHVybiB0aGlzLmNoYW5uZWwuY2FuUHVzaCgpO1xuICB9XG4gIGdldFNlc3Npb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuZWwuZ2V0QXR0cmlidXRlKFBIWF9TRVNTSU9OKTtcbiAgfVxuICBnZXRTdGF0aWMoKSB7XG4gICAgY29uc3QgdmFsID0gdGhpcy5lbC5nZXRBdHRyaWJ1dGUoUEhYX1NUQVRJQyk7XG4gICAgcmV0dXJuIHZhbCA9PT0gXCJcIiA/IG51bGwgOiB2YWw7XG4gIH1cbiAgZGVzdHJveShjYWxsYmFjayA9IGZ1bmN0aW9uKCkge1xuICB9KSB7XG4gICAgdGhpcy5kZXN0cm95QWxsQ2hpbGRyZW4oKTtcbiAgICB0aGlzLmRlc3Ryb3lQb3J0YWxFbGVtZW50cygpO1xuICAgIHRoaXMuZGVzdHJveWVkID0gdHJ1ZTtcbiAgICBkb21fZGVmYXVsdC5kZWxldGVQcml2YXRlKHRoaXMuZWwsIFwidmlld1wiKTtcbiAgICBkZWxldGUgdGhpcy5yb290LmNoaWxkcmVuW3RoaXMuaWRdO1xuICAgIGlmICh0aGlzLnBhcmVudCkge1xuICAgICAgZGVsZXRlIHRoaXMucm9vdC5jaGlsZHJlblt0aGlzLnBhcmVudC5pZF1bdGhpcy5pZF07XG4gICAgfVxuICAgIHRoaXMubG9hZGVyVGltZXIgIT0gbnVsbCAmJiBjbGVhclRpbWVvdXQodGhpcy5sb2FkZXJUaW1lcik7XG4gICAgY29uc3Qgb25GaW5pc2hlZCA9ICgpID0+IHtcbiAgICAgIGNhbGxiYWNrKCk7XG4gICAgICBmb3IgKGNvbnN0IGlkIGluIHRoaXMudmlld0hvb2tzKSB7XG4gICAgICAgIHRoaXMuZGVzdHJveUhvb2sodGhpcy52aWV3SG9va3NbaWRdKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGRvbV9kZWZhdWx0Lm1hcmtQaHhDaGlsZERlc3Ryb3llZCh0aGlzLmVsKTtcbiAgICB0aGlzLmxvZyhcImRlc3Ryb3llZFwiLCAoKSA9PiBbXCJ0aGUgY2hpbGQgaGFzIGJlZW4gcmVtb3ZlZCBmcm9tIHRoZSBwYXJlbnRcIl0pO1xuICAgIHRoaXMuY2hhbm5lbC5sZWF2ZSgpLnJlY2VpdmUoXCJva1wiLCBvbkZpbmlzaGVkKS5yZWNlaXZlKFwiZXJyb3JcIiwgb25GaW5pc2hlZCkucmVjZWl2ZShcInRpbWVvdXRcIiwgb25GaW5pc2hlZCk7XG4gIH1cbiAgc2V0Q29udGFpbmVyQ2xhc3NlcyguLi5jbGFzc2VzKSB7XG4gICAgdGhpcy5lbC5jbGFzc0xpc3QucmVtb3ZlKFxuICAgICAgUEhYX0NPTk5FQ1RFRF9DTEFTUyxcbiAgICAgIFBIWF9MT0FESU5HX0NMQVNTLFxuICAgICAgUEhYX0VSUk9SX0NMQVNTLFxuICAgICAgUEhYX0NMSUVOVF9FUlJPUl9DTEFTUyxcbiAgICAgIFBIWF9TRVJWRVJfRVJST1JfQ0xBU1NcbiAgICApO1xuICAgIHRoaXMuZWwuY2xhc3NMaXN0LmFkZCguLi5jbGFzc2VzKTtcbiAgfVxuICBzaG93TG9hZGVyKHRpbWVvdXQpIHtcbiAgICB0aGlzLmxvYWRlclRpbWVyICE9IG51bGwgJiYgY2xlYXJUaW1lb3V0KHRoaXMubG9hZGVyVGltZXIpO1xuICAgIGlmICh0aW1lb3V0KSB7XG4gICAgICB0aGlzLmxvYWRlclRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB0aGlzLnNob3dMb2FkZXIoKSwgdGltZW91dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoY29uc3QgaWQgaW4gdGhpcy52aWV3SG9va3MpIHtcbiAgICAgICAgdGhpcy52aWV3SG9va3NbaWRdLl9fZGlzY29ubmVjdGVkKCk7XG4gICAgICB9XG4gICAgICB0aGlzLnNldENvbnRhaW5lckNsYXNzZXMoUEhYX0xPQURJTkdfQ0xBU1MpO1xuICAgIH1cbiAgfVxuICBleGVjQWxsKGJpbmRpbmcpIHtcbiAgICBkb21fZGVmYXVsdC5hbGwoXG4gICAgICB0aGlzLmVsLFxuICAgICAgYFske2JpbmRpbmd9XWAsXG4gICAgICAoZWwpID0+IHRoaXMubGl2ZVNvY2tldC5leGVjSlMoZWwsIGVsLmdldEF0dHJpYnV0ZShiaW5kaW5nKSlcbiAgICApO1xuICB9XG4gIGhpZGVMb2FkZXIoKSB7XG4gICAgdGhpcy5sb2FkZXJUaW1lciAhPSBudWxsICYmIGNsZWFyVGltZW91dCh0aGlzLmxvYWRlclRpbWVyKTtcbiAgICB0aGlzLmRpc2Nvbm5lY3RlZFRpbWVyICE9IG51bGwgJiYgY2xlYXJUaW1lb3V0KHRoaXMuZGlzY29ubmVjdGVkVGltZXIpO1xuICAgIHRoaXMuc2V0Q29udGFpbmVyQ2xhc3NlcyhQS
1FhfQ09OTkVDVEVEX0NMQVNTKTtcbiAgICB0aGlzLmV4ZWNBbGwodGhpcy5iaW5kaW5nKFwiY29ubmVjdGVkXCIpKTtcbiAgfVxuICB0cmlnZ2VyUmVjb25uZWN0ZWQoKSB7XG4gICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLnZpZXdIb29rcykge1xuICAgICAgdGhpcy52aWV3SG9va3NbaWRdLl9fcmVjb25uZWN0ZWQoKTtcbiAgICB9XG4gIH1cbiAgbG9nKGtpbmQsIG1zZ0NhbGxiYWNrKSB7XG4gICAgdGhpcy5saXZlU29ja2V0LmxvZyh0aGlzLCBraW5kLCBtc2dDYWxsYmFjayk7XG4gIH1cbiAgdHJhbnNpdGlvbih0aW1lLCBvblN0YXJ0LCBvbkRvbmUgPSBmdW5jdGlvbigpIHtcbiAgfSkge1xuICAgIHRoaXMubGl2ZVNvY2tldC50cmFuc2l0aW9uKHRpbWUsIG9uU3RhcnQsIG9uRG9uZSk7XG4gIH1cbiAgLy8gY2FsbHMgdGhlIGNhbGxiYWNrIHdpdGggdGhlIHZpZXcgYW5kIHRhcmdldCBlbGVtZW50IGZvciB0aGUgZ2l2ZW4gcGh4VGFyZ2V0XG4gIC8vIHRhcmdldHMgY2FuIGJlOlxuICAvLyAgKiBhbiBlbGVtZW50IGl0c2VsZiwgdGhlbiBpdCBpcyBzaW1wbHkgcGFzc2VkIHRvIGxpdmVTb2NrZXQub3duZXI7XG4gIC8vICAqIGEgQ0lEIChDb21wb25lbnQgSUQpLCB0aGVuIHdlIGZpcnN0IHNlYXJjaCB0aGUgY29tcG9uZW50J3MgZWxlbWVudCBpbiB0aGUgRE9NXG4gIC8vICAqIGEgc2VsZWN0b3IsIHRoZW4gd2Ugc2VhcmNoIHRoZSBzZWxlY3RvciBpbiB0aGUgRE9NIGFuZCBjYWxsIHRoZSBjYWxsYmFja1xuICAvLyAgICBmb3IgZWFjaCBlbGVtZW50IGZvdW5kIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgb3duZXIgdmlld1xuICB3aXRoaW5UYXJnZXRzKHBoeFRhcmdldCwgY2FsbGJhY2ssIGRvbSA9IGRvY3VtZW50KSB7XG4gICAgaWYgKHBoeFRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50IHx8IHBoeFRhcmdldCBpbnN0YW5jZW9mIFNWR0VsZW1lbnQpIHtcbiAgICAgIHJldHVybiB0aGlzLmxpdmVTb2NrZXQub3duZXIoXG4gICAgICAgIHBoeFRhcmdldCxcbiAgICAgICAgKHZpZXcpID0+IGNhbGxiYWNrKHZpZXcsIHBoeFRhcmdldClcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChpc0NpZChwaHhUYXJnZXQpKSB7XG4gICAgICBjb25zdCB0YXJnZXQgPSBkb21fZGVmYXVsdC5maW5kQ29tcG9uZW50KHRoaXMuaWQsIHBoeFRhcmdldCwgZG9tKTtcbiAgICAgIGlmICghdGFyZ2V0KSB7XG4gICAgICAgIGxvZ0Vycm9yKGBubyBjb21wb25lbnQgZm91bmQgbWF0Y2hpbmcgcGh4LXRhcmdldCBvZiAke3BoeFRhcmdldH1gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNhbGxiYWNrKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgdHlwZW9mIHBoeFRhcmdldCA9PT0gXCJudW1iZXJcIiA/IHBoeFRhcmdldCA6IHBhcnNlSW50KHBoeFRhcmdldClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgdGFyZ2V0cyA9IEFycmF5LmZyb20oZG9tLnF1ZXJ5U2VsZWN0b3JBbGwocGh4VGFyZ2V0KSk7XG4gICAgICBpZiAodGFyZ2V0cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgbG9nRXJyb3IoXG4gICAgICAgICAgYG5vdGhpbmcgZm91bmQgbWF0Y2hpbmcgdGhlIHBoeC10YXJnZXQgc2VsZWN0b3IgXCIke3BoeFRhcmdldH1cImBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHRhcmdldHMuZm9yRWFjaChcbiAgICAgICAgKHRhcmdldCkgPT4gdGhpcy5saXZlU29ja2V0Lm93bmVyKHRhcmdldCwgKHZpZXcpID0+IGNhbGxiYWNrKHZpZXcsIHRhcmdldCkpXG4gICAgICApO1xuICAgIH1cbiAgfVxuICBhcHBseURpZmYodHlwZSwgcmF3RGlmZiwgY2FsbGJhY2spIHtcbiAgICB0aGlzLmxvZyh0eXBlLCAoKSA9PiBbXCJcIiwgY2xvbmUocmF3RGlmZildKTtcbiAgICBjb25zdCB7IGRpZmYsIHJlcGx5LCBldmVudHMsIHRpdGxlIH0gPSBSZW5kZXJlZC5leHRyYWN0KHJhd0RpZmYpO1xuICAgIGNvbnN0IGV2ID0gZXZlbnRzLnJlZHVjZShcbiAgICAgIChhY2MsIGFyZ3MpID0+IHtcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID09PSAzICYmIGFyZ3NbMl0gPT0gdHJ1ZSkge1xuICAgICAgICAgIGFjYy5wcmUucHVzaChhcmdzLnNsaWNlKDAsIC0xKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYWNjLnBvc3QucHVzaChhcmdzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSxcbiAgICAgIHsgcHJlOiBbXSwgcG9zdDogW10gfVxuICAgICk7XG4gICAgdGhpcy5saXZlU29ja2V0LmRpc3BhdGNoRXZlbnRzKGV2LnByZSk7XG4gICAgY29uc3QgdXBkYXRlID0gKCkgPT4ge1xuICAgICAgY2FsbGJhY2soeyBkaWZmLCByZXBseSwgZXZlbnRzOiBldi5wb3N0IH0pO1xuICAgICAgaWYgKHR5cGVvZiB0aXRsZSA9PT0gXCJzdHJpbmdcIiB8fCB0eXBlID09IFwibW91bnRcIiAmJiB0aGlzLmlzTWFpbigpKSB7XG4gICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gZG9tX2RlZmF1bHQucHV0VGl0bGUodGl0bGUpKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGlmIChcIm9uRG9jdW1lbnRQYXRjaFwiIGluIHRoaXMubGl2ZVNvY2tldC5kb21DYWxsYmFja3MpIHtcbiAgICAgIHRoaXMubGl2ZVNvY2tldC50cmlnZ2VyRE9NKFwib25Eb2N1bWVudFBhdGNoXCIsIFt1cGRhdGVdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdXBkYXRlKCk7XG4gICAgfVxuICB9XG4gIG9uSm9pbihyZXNwKSB7XG4gICAgY29uc3QgeyByZW5kZXJlZCwgY29udGFpbmVyLCBsaXZldmlld192ZXJzaW9uLCBwaWQgfSA9IHJlc3A7XG4gICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgY29uc3QgW3RhZywgYXR0cnNdID0gY29udGFpbmVyO1xuICAgICAgdGhpcy5lbCA9IGRvbV9kZWZhdWx0LnJlcGxhY2VSb290Q29udGFpbmVyKHRoaXMuZWwsIHRhZywgYXR0cnMpO1xuICAgICAgZG9tX2RlZmF1bHQucHV0UHJpdmF0ZSh0aGlzLmVsLCBcInZpZXdcIiwgdGhpcyk7XG4gICAgfVxuICAgIHRoaXMuY2hpbGRKb2lucyA9IDA7XG4gICAgdGhpcy5qb2luUGVuZGluZyA9IHRydWU7XG4gICAgdGhpcy5mbGFzaCA9IG51bGw7XG4gICAgaWYgKHRoaXMucm9vdCA9PT0gdGhpcykge1xuICAgICAgdGhpcy5mb3Jtc0ZvclJlY292ZXJ5ID0gdGhpcy5nZXRGb3Jtc0ZvclJlY292ZXJ5KCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmlzTWFpbigpICYmIHdpbmRvdy5oaXN0b3J5LnN0YXRlID09PSBudWxsKSB7XG4gICAgICBicm93c2VyX2RlZmF1bHQucHVzaFN0YXRlKFwicmVwbGFjZVwiLCB7XG4gICAgICAgI
1HR5cGU6IFwicGF0Y2hcIixcbiAgICAgICAgaWQ6IHRoaXMuaWQsXG4gICAgICAgIHBvc2l0aW9uOiB0aGlzLmxpdmVTb2NrZXQuY3VycmVudEhpc3RvcnlQb3NpdGlvblxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChsaXZldmlld192ZXJzaW9uICE9PSB0aGlzLmxpdmVTb2NrZXQudmVyc2lvbigpKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGBMaXZlVmlldyBhc3NldCB2ZXJzaW9uIG1pc21hdGNoLiBKYXZhU2NyaXB0IHZlcnNpb24gJHt0aGlzLmxpdmVTb2NrZXQudmVyc2lvbigpfSB2cy4gc2VydmVyICR7bGl2ZXZpZXdfdmVyc2lvbn0uIFRvIGF2b2lkIGlzc3VlcywgcGxlYXNlIGVuc3VyZSB0aGF0IHlvdXIgYXNzZXRzIHVzZSB0aGUgc2FtZSB2ZXJzaW9uIGFzIHRoZSBzZXJ2ZXIuYFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHBpZCkge1xuICAgICAgdGhpcy5lbC5zZXRBdHRyaWJ1dGUoUEhYX0xWX1BJRCwgcGlkKTtcbiAgICB9XG4gICAgYnJvd3Nlcl9kZWZhdWx0LmRyb3BMb2NhbChcbiAgICAgIHRoaXMubGl2ZVNvY2tldC5sb2NhbFN0b3JhZ2UsXG4gICAgICB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUsXG4gICAgICBDT05TRUNVVElWRV9SRUxPQURTXG4gICAgKTtcbiAgICB0aGlzLmFwcGx5RGlmZihcIm1vdW50XCIsIHJlbmRlcmVkLCAoeyBkaWZmLCBldmVudHMgfSkgPT4ge1xuICAgICAgdGhpcy5yZW5kZXJlZCA9IG5ldyBSZW5kZXJlZCh0aGlzLmlkLCBkaWZmKTtcbiAgICAgIGNvbnN0IFtodG1sLCBzdHJlYW1zXSA9IHRoaXMucmVuZGVyQ29udGFpbmVyKG51bGwsIFwiam9pblwiKTtcbiAgICAgIHRoaXMuZHJvcFBlbmRpbmdSZWZzKCk7XG4gICAgICB0aGlzLmpvaW5Db3VudCsrO1xuICAgICAgdGhpcy5qb2luQXR0ZW1wdHMgPSAwO1xuICAgICAgdGhpcy5tYXliZVJlY292ZXJGb3JtcyhodG1sLCAoKSA9PiB7XG4gICAgICAgIHRoaXMub25Kb2luQ29tcGxldGUocmVzcCwgaHRtbCwgc3RyZWFtcywgZXZlbnRzKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIGRyb3BQZW5kaW5nUmVmcygpIHtcbiAgICBkb21fZGVmYXVsdC5hbGwoZG9jdW1lbnQsIGBbJHtQSFhfUkVGX1NSQ309XCIke3RoaXMucmVmU3JjKCl9XCJdYCwgKGVsKSA9PiB7XG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1JFRl9MT0FESU5HKTtcbiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShQSFhfUkVGX1NSQyk7XG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1JFRl9MT0NLKTtcbiAgICB9KTtcbiAgfVxuICBvbkpvaW5Db21wbGV0ZSh7IGxpdmVfcGF0Y2ggfSwgaHRtbCwgc3RyZWFtcywgZXZlbnRzKSB7XG4gICAgaWYgKHRoaXMuam9pbkNvdW50ID4gMSB8fCB0aGlzLnBhcmVudCAmJiAhdGhpcy5wYXJlbnQuaXNKb2luUGVuZGluZygpKSB7XG4gICAgICByZXR1cm4gdGhpcy5hcHBseUpvaW5QYXRjaChsaXZlX3BhdGNoLCBodG1sLCBzdHJlYW1zLCBldmVudHMpO1xuICAgIH1cbiAgICBjb25zdCBuZXdDaGlsZHJlbiA9IGRvbV9kZWZhdWx0LmZpbmRQaHhDaGlsZHJlbkluRnJhZ21lbnQoaHRtbCwgdGhpcy5pZCkuZmlsdGVyKFxuICAgICAgKHRvRWwpID0+IHtcbiAgICAgICAgY29uc3QgZnJvbUVsID0gdG9FbC5pZCAmJiB0aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoYFtpZD1cIiR7dG9FbC5pZH1cIl1gKTtcbiAgICAgICAgY29uc3QgcGh4U3RhdGljID0gZnJvbUVsICYmIGZyb21FbC5nZXRBdHRyaWJ1dGUoUEhYX1NUQVRJQyk7XG4gICAgICAgIGlmIChwaHhTdGF0aWMpIHtcbiAgICAgICAgICB0b0VsLnNldEF0dHJpYnV0ZShQSFhfU1RBVElDLCBwaHhTdGF0aWMpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmcm9tRWwpIHtcbiAgICAgICAgICBmcm9tRWwuc2V0QXR0cmlidXRlKFBIWF9ST09UX0lELCB0aGlzLnJvb3QuaWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmpvaW5DaGlsZCh0b0VsKTtcbiAgICAgIH1cbiAgICApO1xuICAgIGlmIChuZXdDaGlsZHJlbi5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmICh0aGlzLnBhcmVudCkge1xuICAgICAgICB0aGlzLnJvb3QucGVuZGluZ0pvaW5PcHMucHVzaChbXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICAoKSA9PiB0aGlzLmFwcGx5Sm9pblBhdGNoKGxpdmVfcGF0Y2gsIGh0bWwsIHN0cmVhbXMsIGV2ZW50cylcbiAgICAgICAgXSk7XG4gICAgICAgIHRoaXMucGFyZW50LmFja0pvaW4odGhpcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm9uQWxsQ2hpbGRKb2luc0NvbXBsZXRlKCk7XG4gICAgICAgIHRoaXMuYXBwbHlKb2luUGF0Y2gobGl2ZV9wYXRjaCwgaHRtbCwgc3RyZWFtcywgZXZlbnRzKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yb290LnBlbmRpbmdKb2luT3BzLnB1c2goW1xuICAgICAgICB0aGlzLFxuICAgICAgICAoKSA9PiB0aGlzLmFwcGx5Sm9pblBhdGNoKGxpdmVfcGF0Y2gsIGh0bWwsIHN0cmVhbXMsIGV2ZW50cylcbiAgICAgIF0pO1xuICAgIH1cbiAgfVxuICBhdHRhY2hUcnVlRG9jRWwoKSB7XG4gICAgY29uc3QgZWwgPSBkb21fZGVmYXVsdC5ieUlkKHRoaXMuaWQpO1xuICAgIGlmICghZWwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcInVuYWJsZSB0byBmaW5kIHJvb3QgZWxlbWVudCBmb3Igdmlld1wiKTtcbiAgICB9XG4gICAgdGhpcy5lbCA9IGVsO1xuICAgIGRvbV9kZWZhdWx0LnB1dFByaXZhdGUodGhpcy5lbCwgXCJ2aWV3XCIsIHRoaXMpO1xuICAgIHRoaXMuZWwuc2V0QXR0cmlidXRlKFBIWF9ST09UX0lELCB0aGlzLnJvb3QuaWQpO1xuICB9XG4gIC8vIHRoaXMgaXMgaW52b2tlZCBmb3IgZGVhZCBhbmQgbGl2ZSB2aWV3cywgc28gd2UgbXVzdCBmaWx0ZXIgYnlcbiAgLy8gYnkgb3duZXIgdG8gZW5zdXJlIHdlIGFyZW4ndCBkdXBsaWNhdGluZyBob29rcyBhY3Jvc3MgZGlzY29ubmVjdFxuICAvLyBhbmQgY29ubmVjdGVkIHN0YXRlcy4gVGhpcyBhbHNvIGhhbmRsZXMgY2FzZXMgd2hlcmUgaG9va3MgZXhpc3RcbiAgLy8gaW4gYSByb290IGxheW91dCB3aXRoIGEgTFYgaW4gdGhlIGJvZHlcbiAgZXhlY05ld01vdW50ZWQocGFyZW50ID0gZG9jdW1lbnQpIHtcbiAgICBsZXQgcGh4Vmlld3BvcnRUb3AgPSB0aGlzLmJpbmRpbmcoUEhYX1ZJRVdQT1JUX1RPUCk7XG4gICAgbGV0IHBoeFZpZXdwb3J0Qm90dG9tID0gdGhpcy5iaW5kaW5nKFBIWF9WSUVXUE9SVF9CT1RUT00pO1xuICAgIHRoaXMuYWxsKFxuICAgICAgcGFyZW50LFxuICAgICAgYFske3BoeFZpZXdwb3J0VG9wfV0sIFske3BoeFZpZXdwb3J0Qm90dG9tfV1gLFxuICAgICAgKGhvb2tFbCkgPT4ge1xuICAgICAgICBkb21fZGVmYXVsdC5tYWludGFpblByaXZhdGVIb29rcyhcbiAgICAgICAgICBob29rRWwsXG4gICAgICAgICAgaG9va0VsLFxuICAgICAgICAgI
1HBoeFZpZXdwb3J0VG9wLFxuICAgICAgICAgIHBoeFZpZXdwb3J0Qm90dG9tXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMubWF5YmVBZGROZXdIb29rKGhvb2tFbCk7XG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLmFsbChcbiAgICAgIHBhcmVudCxcbiAgICAgIGBbJHt0aGlzLmJpbmRpbmcoUEhYX0hPT0spfV0sIFtkYXRhLXBoeC0ke1BIWF9IT09LfV1gLFxuICAgICAgKGhvb2tFbCkgPT4ge1xuICAgICAgICB0aGlzLm1heWJlQWRkTmV3SG9vayhob29rRWwpO1xuICAgICAgfVxuICAgICk7XG4gICAgdGhpcy5hbGwocGFyZW50LCBgWyR7dGhpcy5iaW5kaW5nKFBIWF9NT1VOVEVEKX1dYCwgKGVsKSA9PiB7XG4gICAgICB0aGlzLm1heWJlTW91bnRlZChlbCk7XG4gICAgfSk7XG4gIH1cbiAgYWxsKHBhcmVudCwgc2VsZWN0b3IsIGNhbGxiYWNrKSB7XG4gICAgZG9tX2RlZmF1bHQuYWxsKHBhcmVudCwgc2VsZWN0b3IsIChlbCkgPT4ge1xuICAgICAgaWYgKHRoaXMub3duc0VsZW1lbnQoZWwpKSB7XG4gICAgICAgIGNhbGxiYWNrKGVsKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICBhcHBseUpvaW5QYXRjaChsaXZlX3BhdGNoLCBodG1sLCBzdHJlYW1zLCBldmVudHMpIHtcbiAgICBpZiAodGhpcy5qb2luQ291bnQgPiAxKSB7XG4gICAgICBpZiAodGhpcy5wZW5kaW5nSm9pbk9wcy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5wZW5kaW5nSm9pbk9wcy5mb3JFYWNoKChjYikgPT4gdHlwZW9mIGNiID09PSBcImZ1bmN0aW9uXCIgJiYgY2IoKSk7XG4gICAgICAgIHRoaXMucGVuZGluZ0pvaW5PcHMgPSBbXTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5hdHRhY2hUcnVlRG9jRWwoKTtcbiAgICBjb25zdCBwYXRjaCA9IG5ldyBET01QYXRjaCh0aGlzLCB0aGlzLmVsLCBodG1sLCBzdHJlYW1zLCBudWxsKTtcbiAgICBwYXRjaC5tYXJrUHJ1bmFibGVDb250ZW50Rm9yUmVtb3ZhbCgpO1xuICAgIHRoaXMucGVyZm9ybVBhdGNoKHBhdGNoLCBmYWxzZSwgdHJ1ZSk7XG4gICAgdGhpcy5qb2luTmV3Q2hpbGRyZW4oKTtcbiAgICB0aGlzLmV4ZWNOZXdNb3VudGVkKCk7XG4gICAgdGhpcy5qb2luUGVuZGluZyA9IGZhbHNlO1xuICAgIHRoaXMubGl2ZVNvY2tldC5kaXNwYXRjaEV2ZW50cyhldmVudHMpO1xuICAgIHRoaXMuYXBwbHlQZW5kaW5nVXBkYXRlcygpO1xuICAgIGlmIChsaXZlX3BhdGNoKSB7XG4gICAgICBjb25zdCB7IGtpbmQsIHRvIH0gPSBsaXZlX3BhdGNoO1xuICAgICAgdGhpcy5saXZlU29ja2V0Lmhpc3RvcnlQYXRjaCh0bywga2luZCk7XG4gICAgfVxuICAgIHRoaXMuaGlkZUxvYWRlcigpO1xuICAgIGlmICh0aGlzLmpvaW5Db3VudCA+IDEpIHtcbiAgICAgIHRoaXMudHJpZ2dlclJlY29ubmVjdGVkKCk7XG4gICAgfVxuICAgIHRoaXMuc3RvcENhbGxiYWNrKCk7XG4gIH1cbiAgdHJpZ2dlckJlZm9yZVVwZGF0ZUhvb2soZnJvbUVsLCB0b0VsKSB7XG4gICAgdGhpcy5saXZlU29ja2V0LnRyaWdnZXJET00oXCJvbkJlZm9yZUVsVXBkYXRlZFwiLCBbZnJvbUVsLCB0b0VsXSk7XG4gICAgY29uc3QgaG9vayA9IHRoaXMuZ2V0SG9vayhmcm9tRWwpO1xuICAgIGNvbnN0IGlzSWdub3JlZCA9IGhvb2sgJiYgZG9tX2RlZmF1bHQuaXNJZ25vcmVkKGZyb21FbCwgdGhpcy5iaW5kaW5nKFBIWF9VUERBVEUpKTtcbiAgICBpZiAoaG9vayAmJiAhZnJvbUVsLmlzRXF1YWxOb2RlKHRvRWwpICYmICEoaXNJZ25vcmVkICYmIGlzRXF1YWxPYmooZnJvbUVsLmRhdGFzZXQsIHRvRWwuZGF0YXNldCkpKSB7XG4gICAgICBob29rLl9fYmVmb3JlVXBkYXRlKCk7XG4gICAgICByZXR1cm4gaG9vaztcbiAgICB9XG4gIH1cbiAgbWF5YmVNb3VudGVkKGVsKSB7XG4gICAgY29uc3QgcGh4TW91bnRlZCA9IGVsLmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoUEhYX01PVU5URUQpKTtcbiAgICBjb25zdCBoYXNCZWVuSW52b2tlZCA9IHBoeE1vdW50ZWQgJiYgZG9tX2RlZmF1bHQucHJpdmF0ZShlbCwgXCJtb3VudGVkXCIpO1xuICAgIGlmIChwaHhNb3VudGVkICYmICFoYXNCZWVuSW52b2tlZCkge1xuICAgICAgdGhpcy5saXZlU29ja2V0LmV4ZWNKUyhlbCwgcGh4TW91bnRlZCk7XG4gICAgICBkb21fZGVmYXVsdC5wdXRQcml2YXRlKGVsLCBcIm1vdW50ZWRcIiwgdHJ1ZSk7XG4gICAgfVxuICB9XG4gIG1heWJlQWRkTmV3SG9vayhlbCkge1xuICAgIGNvbnN0IG5ld0hvb2sgPSB0aGlzLmFkZEhvb2soZWwpO1xuICAgIGlmIChuZXdIb29rKSB7XG4gICAgICBuZXdIb29rLl9fbW91bnRlZCgpO1xuICAgIH1cbiAgfVxuICBwZXJmb3JtUGF0Y2gocGF0Y2gsIHBydW5lQ2lkcywgaXNKb2luUGF0Y2ggPSBmYWxzZSkge1xuICAgIGNvbnN0IHJlbW92ZWRFbHMgPSBbXTtcbiAgICBsZXQgcGh4Q2hpbGRyZW5BZGRlZCA9IGZhbHNlO1xuICAgIGNvbnN0IHVwZGF0ZWRIb29rSWRzID0gLyogQF9fUFVSRV9fICovIG5ldyBTZXQoKTtcbiAgICB0aGlzLmxpdmVTb2NrZXQudHJpZ2dlckRPTShcIm9uUGF0Y2hTdGFydFwiLCBbcGF0Y2gudGFyZ2V0Q29udGFpbmVyXSk7XG4gICAgcGF0Y2guYWZ0ZXJBZGRlZCgoZWwpID0+IHtcbiAgICAgIHRoaXMubGl2ZVNvY2tldC50cmlnZ2VyRE9NKFwib25Ob2RlQWRkZWRcIiwgW2VsXSk7XG4gICAgICBjb25zdCBwaHhWaWV3cG9ydFRvcCA9IHRoaXMuYmluZGluZyhQSFhfVklFV1BPUlRfVE9QKTtcbiAgICAgIGNvbnN0IHBoeFZpZXdwb3J0Qm90dG9tID0gdGhpcy5iaW5kaW5nKFBIWF9WSUVXUE9SVF9CT1RUT00pO1xuICAgICAgZG9tX2RlZmF1bHQubWFpbnRhaW5Qcml2YXRlSG9va3MoZWwsIGVsLCBwaHhWaWV3cG9ydFRvcCwgcGh4Vmlld3BvcnRCb3R0b20pO1xuICAgICAgdGhpcy5tYXliZUFkZE5ld0hvb2soZWwpO1xuICAgICAgaWYgKGVsLmdldEF0dHJpYnV0ZSkge1xuICAgICAgICB0aGlzLm1heWJlTW91bnRlZChlbCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcGF0Y2guYWZ0ZXJQaHhDaGlsZEFkZGVkKChlbCkgPT4ge1xuICAgICAgaWYgKGRvbV9kZWZhdWx0LmlzUGh4U3RpY2t5KGVsKSkge1xuICAgICAgICB0aGlzLmxpdmVTb2NrZXQuam9pblJvb3RWaWV3cygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGh4Q2hpbGRyZW5BZGRlZCA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcGF0Y2guYmVmb3JlVXBkYXRlZCgoZnJvbUVsLCB0b0VsKSA9PiB7XG4gICAgICBjb25zdCBob29rID0gdGhpcy50cmlnZ2VyQmVmb3JlVXBkYXRlSG9vayhmcm9tRWwsIHRvRWwpO1xuICAgICAgaWYgKGhvb2spIHtcbiAgICAgICAgdXBkYXRlZEhvb2tJZHMuYWRkKGZyb21FbC5pZCk7XG4gICAgICB9XG4gICAgICBqc19kZWZhdWx0Lm9uQmVmb3JlRWxVcGRhdGVkKGZyb21FbCwgdG9FbCk7XG4gICAgfSk7XG4gICAgcGF0Y2guYWZ0ZXJVcGRhdGVkKChlbCkgPT4ge1xuICAgICAgaWYgKHVwZGF0ZWRIb29rSWRzLmhhcyhlbC5pZCkpIHtcbiAgICAgICAgY29uc3QgaG9vayA9IHRoaXMuZ2V0SG9vayhlbCk7XG4gICAgICAgIGhvb2sgJiYgaG9vay5fX3VwZGF0ZWQoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBwYXRjaC5hZnRlckRpc2NhcmRlZCgoZWwpID0+IHtcbiAgICAgIGlmIChlbC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgICAgcmVtb3ZlZEVscy5wdXNoKGVsKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBwYXRjaC5hZnRlclRyYW5zaXRpb25zRGlzY2FyZGVkKFxuICAgICAgKGVscykgPT4gdGhpcy5hZnRlckVsZW1lbnRzUmVtb3ZlZChlbHMsIHBydW5lQ2lkcylcbiAgICApO
11xuICAgIHBhdGNoLnBlcmZvcm0oaXNKb2luUGF0Y2gpO1xuICAgIHRoaXMuYWZ0ZXJFbGVtZW50c1JlbW92ZWQocmVtb3ZlZEVscywgcHJ1bmVDaWRzKTtcbiAgICB0aGlzLmxpdmVTb2NrZXQudHJpZ2dlckRPTShcIm9uUGF0Y2hFbmRcIiwgW3BhdGNoLnRhcmdldENvbnRhaW5lcl0pO1xuICAgIHJldHVybiBwaHhDaGlsZHJlbkFkZGVkO1xuICB9XG4gIGFmdGVyRWxlbWVudHNSZW1vdmVkKGVsZW1lbnRzLCBwcnVuZUNpZHMpIHtcbiAgICBjb25zdCBkZXN0cm95ZWRDSURzID0gW107XG4gICAgZWxlbWVudHMuZm9yRWFjaCgocGFyZW50KSA9PiB7XG4gICAgICBjb25zdCBjb21wb25lbnRzID0gZG9tX2RlZmF1bHQuYWxsKFxuICAgICAgICBwYXJlbnQsXG4gICAgICAgIGBbJHtQSFhfVklFV19SRUZ9PVwiJHt0aGlzLmlkfVwiXVske1BIWF9DT01QT05FTlR9XWBcbiAgICAgICk7XG4gICAgICBjb25zdCBob29rcyA9IGRvbV9kZWZhdWx0LmFsbChcbiAgICAgICAgcGFyZW50LFxuICAgICAgICBgWyR7dGhpcy5iaW5kaW5nKFBIWF9IT09LKX1dLCBbZGF0YS1waHgtaG9va11gXG4gICAgICApO1xuICAgICAgY29tcG9uZW50cy5jb25jYXQocGFyZW50KS5mb3JFYWNoKChlbCkgPT4ge1xuICAgICAgICBjb25zdCBjaWQgPSB0aGlzLmNvbXBvbmVudElEKGVsKTtcbiAgICAgICAgaWYgKGlzQ2lkKGNpZCkgJiYgZGVzdHJveWVkQ0lEcy5pbmRleE9mKGNpZCkgPT09IC0xICYmIGVsLmdldEF0dHJpYnV0ZShQSFhfVklFV19SRUYpID09PSB0aGlzLmlkKSB7XG4gICAgICAgICAgZGVzdHJveWVkQ0lEcy5wdXNoKGNpZCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaG9va3MuY29uY2F0KHBhcmVudCkuZm9yRWFjaCgoaG9va0VsKSA9PiB7XG4gICAgICAgIGNvbnN0IGhvb2sgPSB0aGlzLmdldEhvb2soaG9va0VsKTtcbiAgICAgICAgaG9vayAmJiB0aGlzLmRlc3Ryb3lIb29rKGhvb2spO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgaWYgKHBydW5lQ2lkcykge1xuICAgICAgdGhpcy5tYXliZVB1c2hDb21wb25lbnRzRGVzdHJveWVkKGRlc3Ryb3llZENJRHMpO1xuICAgIH1cbiAgfVxuICBqb2luTmV3Q2hpbGRyZW4oKSB7XG4gICAgZG9tX2RlZmF1bHQuZmluZFBoeENoaWxkcmVuKGRvY3VtZW50LCB0aGlzLmlkKS5mb3JFYWNoKChlbCkgPT4gdGhpcy5qb2luQ2hpbGQoZWwpKTtcbiAgfVxuICBtYXliZVJlY292ZXJGb3JtcyhodG1sLCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHBoeENoYW5nZSA9IHRoaXMuYmluZGluZyhcImNoYW5nZVwiKTtcbiAgICBjb25zdCBvbGRGb3JtcyA9IHRoaXMucm9vdC5mb3Jtc0ZvclJlY292ZXJ5O1xuICAgIGNvbnN0IHRlbXBsYXRlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRlbXBsYXRlXCIpO1xuICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IGh0bWw7XG4gICAgaWYgKCF0ZW1wbGF0ZS5jb250ZW50LmZpcnN0RWxlbWVudENoaWxkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGRvbV9kZWZhdWx0LmFsbCh0ZW1wbGF0ZS5jb250ZW50LCBgWyR7UEhYX1BPUlRBTH1dYCkuZm9yRWFjaCgocG9ydGFsVGVtcGxhdGUpID0+IHtcbiAgICAgIGlmICghKHBvcnRhbFRlbXBsYXRlIGluc3RhbmNlb2YgSFRNTFRlbXBsYXRlRWxlbWVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGVtcGxhdGUuY29udGVudC5maXJzdEVsZW1lbnRDaGlsZD8uYXBwZW5kQ2hpbGQoXG4gICAgICAgIHBvcnRhbFRlbXBsYXRlLmNvbnRlbnQuZmlyc3RFbGVtZW50Q2hpbGRcbiAgICAgICk7XG4gICAgfSk7XG4gICAgY29uc3Qgcm9vdEVsID0gdGVtcGxhdGUuY29udGVudC5maXJzdEVsZW1lbnRDaGlsZDtcbiAgICByb290RWwuaWQgPSB0aGlzLmlkO1xuICAgIHJvb3RFbC5zZXRBdHRyaWJ1dGUoUEhYX1JPT1RfSUQsIHRoaXMucm9vdC5pZCk7XG4gICAgcm9vdEVsLnNldEF0dHJpYnV0ZShQSFhfU0VTU0lPTiwgdGhpcy5nZXRTZXNzaW9uKCkpO1xuICAgIHJvb3RFbC5zZXRBdHRyaWJ1dGUoUEhYX1NUQVRJQywgdGhpcy5nZXRTdGF0aWMoKSA/PyBcIlwiKTtcbiAgICB0aGlzLnBhcmVudCAmJiByb290RWwuc2V0QXR0cmlidXRlKFBIWF9QQVJFTlRfSUQsIHRoaXMucGFyZW50LmlkKTtcbiAgICBkb21fZGVmYXVsdC5wdXRQcml2YXRlKHJvb3RFbCwgXCJ2aWV3XCIsIHRoaXMpO1xuICAgIGNvbnN0IGZvcm1zVG9SZWNvdmVyID0gKFxuICAgICAgLy8gd2UgZ28gb3ZlciBhbGwgZm9ybXMgaW4gdGhlIG5ldyBET007IGJlY2F1c2UgdGhpcyBpcyBvbmx5IHRoZSBIVE1MIGZvciB0aGUgY3VycmVudFxuICAgICAgLy8gdmlldywgd2UgY2FuIGJlIHN1cmUgdGhhdCBhbGwgZm9ybXMgYXJlIG93bmVkIGJ5IHRoaXMgdmlldzpcbiAgICAgIGRvbV9kZWZhdWx0LmFsbCh0ZW1wbGF0ZS5jb250ZW50LCBcImZvcm1cIikuZmlsdGVyKChuZXdGb3JtKSA9PiBuZXdGb3JtLmlkICYmIG9sZEZvcm1zW25ld0Zvcm0uaWRdKS5maWx0ZXIoKG5ld0Zvcm0pID0+ICF0aGlzLnBlbmRpbmdGb3Jtcy5oYXMobmV3Rm9ybS5pZCkpLmZpbHRlcihcbiAgICAgICAgKG5ld0Zvcm0pID0+IG9sZEZvcm1zW25ld0Zvcm0uaWRdLmdldEF0dHJpYnV0ZShwaHhDaGFuZ2UpID09PSBuZXdGb3JtLmdldEF0dHJpYnV0ZShwaHhDaGFuZ2UpXG4gICAgICApLm1hcCgobmV3Rm9ybSkgPT4ge1xuICAgICAgICByZXR1cm4gW29sZEZvcm1zW25ld0Zvcm0uaWRdLCBuZXdGb3JtXTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICBpZiAoZm9ybXNUb1JlY292ZXIubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgICB9XG4gICAgZm9ybXNUb1JlY292ZXIuZm9yRWFjaCgoW29sZEZvcm0sIG5ld0Zvcm1dLCBpKSA9PiB7XG4gICAgICB0aGlzLnBlbmRpbmdGb3Jtcy5hZGQobmV3Rm9ybS5pZCk7XG4gICAgICB0aGlzLnB1c2hGb3JtUmVjb3ZlcnkoXG4gICAgICAgIG9sZEZvcm0sXG4gICAgICAgIG5ld0Zvcm0sXG4gICAgICAgIHRlbXBsYXRlLmNvbnRlbnQuZmlyc3RFbGVtZW50Q2hpbGQsXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0aGlzLnBlbmRpbmdGb3Jtcy5kZWxldGUobmV3Rm9ybS5pZCk7XG4gICAgICAgICAgaWYgKGkgPT09IGZvcm1zVG9SZWNvdmVyLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG4gIGdldENoaWxkQnlJZChpZCkge1xuICAgIHJldHVybi
1B0aGlzLnJvb3QuY2hpbGRyZW5bdGhpcy5pZF1baWRdO1xuICB9XG4gIGdldERlc2NlbmRlbnRCeUVsKGVsKSB7XG4gICAgaWYgKGVsLmlkID09PSB0aGlzLmlkKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuY2hpbGRyZW4gJiYgdGhpcy5jaGlsZHJlbltlbC5nZXRBdHRyaWJ1dGUoUEhYX1BBUkVOVF9JRCldPy5bZWwuaWRdO1xuICAgIH1cbiAgfVxuICBkZXN0cm95RGVzY2VuZGVudChpZCkge1xuICAgIGZvciAoY29uc3QgcGFyZW50SWQgaW4gdGhpcy5yb290LmNoaWxkcmVuKSB7XG4gICAgICBmb3IgKGNvbnN0IGNoaWxkSWQgaW4gdGhpcy5yb290LmNoaWxkcmVuW3BhcmVudElkXSkge1xuICAgICAgICBpZiAoY2hpbGRJZCA9PT0gaWQpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5yb290LmNoaWxkcmVuW3BhcmVudElkXVtjaGlsZElkXS5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgam9pbkNoaWxkKGVsKSB7XG4gICAgY29uc3QgY2hpbGQgPSB0aGlzLmdldENoaWxkQnlJZChlbC5pZCk7XG4gICAgaWYgKCFjaGlsZCkge1xuICAgICAgY29uc3QgdmlldyA9IG5ldyBfVmlldyhlbCwgdGhpcy5saXZlU29ja2V0LCB0aGlzKTtcbiAgICAgIHRoaXMucm9vdC5jaGlsZHJlblt0aGlzLmlkXVt2aWV3LmlkXSA9IHZpZXc7XG4gICAgICB2aWV3LmpvaW4oKTtcbiAgICAgIHRoaXMuY2hpbGRKb2lucysrO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIGlzSm9pblBlbmRpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMuam9pblBlbmRpbmc7XG4gIH1cbiAgYWNrSm9pbihfY2hpbGQpIHtcbiAgICB0aGlzLmNoaWxkSm9pbnMtLTtcbiAgICBpZiAodGhpcy5jaGlsZEpvaW5zID09PSAwKSB7XG4gICAgICBpZiAodGhpcy5wYXJlbnQpIHtcbiAgICAgICAgdGhpcy5wYXJlbnQuYWNrSm9pbih0aGlzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMub25BbGxDaGlsZEpvaW5zQ29tcGxldGUoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgb25BbGxDaGlsZEpvaW5zQ29tcGxldGUoKSB7XG4gICAgdGhpcy5wZW5kaW5nRm9ybXMuY2xlYXIoKTtcbiAgICB0aGlzLmZvcm1zRm9yUmVjb3ZlcnkgPSB7fTtcbiAgICB0aGlzLmpvaW5DYWxsYmFjaygoKSA9PiB7XG4gICAgICB0aGlzLnBlbmRpbmdKb2luT3BzLmZvckVhY2goKFt2aWV3LCBvcF0pID0+IHtcbiAgICAgICAgaWYgKCF2aWV3LmlzRGVzdHJveWVkKCkpIHtcbiAgICAgICAgICBvcCgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMucGVuZGluZ0pvaW5PcHMgPSBbXTtcbiAgICB9KTtcbiAgfVxuICB1cGRhdGUoZGlmZiwgZXZlbnRzLCBpc1BlbmRpbmcgPSBmYWxzZSkge1xuICAgIGlmICh0aGlzLmlzSm9pblBlbmRpbmcoKSB8fCB0aGlzLmxpdmVTb2NrZXQuaGFzUGVuZGluZ0xpbmsoKSAmJiB0aGlzLnJvb3QuaXNNYWluKCkpIHtcbiAgICAgIGlmICghaXNQZW5kaW5nKSB7XG4gICAgICAgIHRoaXMucGVuZGluZ0RpZmZzLnB1c2goeyBkaWZmLCBldmVudHMgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRoaXMucmVuZGVyZWQubWVyZ2VEaWZmKGRpZmYpO1xuICAgIGxldCBwaHhDaGlsZHJlbkFkZGVkID0gZmFsc2U7XG4gICAgaWYgKHRoaXMucmVuZGVyZWQuaXNDb21wb25lbnRPbmx5RGlmZihkaWZmKSkge1xuICAgICAgdGhpcy5saXZlU29ja2V0LnRpbWUoXCJjb21wb25lbnQgcGF0Y2ggY29tcGxldGVcIiwgKCkgPT4ge1xuICAgICAgICBjb25zdCBwYXJlbnRDaWRzID0gZG9tX2RlZmF1bHQuZmluZEV4aXN0aW5nUGFyZW50Q0lEcyhcbiAgICAgICAgICB0aGlzLmlkLFxuICAgICAgICAgIHRoaXMucmVuZGVyZWQuY29tcG9uZW50Q0lEcyhkaWZmKVxuICAgICAgICApO1xuICAgICAgICBwYXJlbnRDaWRzLmZvckVhY2goKHBhcmVudENJRCkgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLmNvbXBvbmVudFBhdGNoKFxuICAgICAgICAgICAgdGhpcy5yZW5kZXJlZC5nZXRDb21wb25lbnQoZGlmZiwgcGFyZW50Q0lEKSxcbiAgICAgICAgICAgIHBhcmVudENJRFxuICAgICAgICAgICkpIHtcbiAgICAgICAgICAgIHBoeENoaWxkcmVuQWRkZWQgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKCFpc0VtcHR5KGRpZmYpKSB7XG4gICAgICB0aGlzLmxpdmVTb2NrZXQudGltZShcImZ1bGwgcGF0Y2ggY29tcGxldGVcIiwgKCkgPT4ge1xuICAgICAgICBjb25zdCBbaHRtbCwgc3RyZWFtc10gPSB0aGlzLnJlbmRlckNvbnRhaW5lcihkaWZmLCBcInVwZGF0ZVwiKTtcbiAgICAgICAgY29uc3QgcGF0Y2ggPSBuZXcgRE9NUGF0Y2godGhpcywgdGhpcy5lbCwgaHRtbCwgc3RyZWFtcywgbnVsbCk7XG4gICAgICAgIHBoeENoaWxkcmVuQWRkZWQgPSB0aGlzLnBlcmZvcm1QYXRjaChwYXRjaCwgdHJ1ZSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhpcy5saXZlU29ja2V0LmRpc3BhdGNoRXZlbnRzKGV2ZW50cyk7XG4gICAgaWYgKHBoeENoaWxkcmVuQWRkZWQpIHtcbiAgICAgIHRoaXMuam9pbk5ld0NoaWxkcmVuKCk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJlbmRlckNvbnRhaW5lcihkaWZmLCBraW5kKSB7XG4gICAgcmV0dXJuIHRoaXMubGl2ZVNvY2tldC50aW1lKGB0b1N0cmluZyBkaWZmICgke2tpbmR9KWAsICgpID0+IHtcbiAgICAgIGNvbnN0IHRhZyA9IHRoaXMuZWwudGFnTmFtZTtcbiAgICAgIGNvbnN0IGNpZHMgPSBkaWZmID8gdGhpcy5yZW5kZXJlZC5jb21wb25lbnRDSURzKGRpZmYpIDogbnVsbDtcbiAgICAgIGNvbnN0IHsgYnVmZmVyOiBodG1sLCBzdHJlYW1zIH0gPSB0aGlzLnJlbmRlcmVkLnRvU3RyaW5nKGNpZHMpO1xuICAgICAgcmV0dXJuIFtgPCR7dGFnfT4ke2h0bWx9PC8ke3RhZ30+YCwgc3RyZWFtc107XG4gICAgfSk7XG4gIH1cbiAgY29tcG9uZW50UGF0Y2goZGlmZiwgY2lkKSB7XG4gICAgaWYgKGlzRW1wdHkoZGlmZikpXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgY29uc3QgeyBidWZmZXI6IGh0bWwsIHN0cmVhbXMgfSA9IHRoaXMucmVuZGVyZWQuY29tcG9uZW50VG9TdHJpbmc
1oY2lkKTtcbiAgICBjb25zdCBwYXRjaCA9IG5ldyBET01QYXRjaCh0aGlzLCB0aGlzLmVsLCBodG1sLCBzdHJlYW1zLCBjaWQpO1xuICAgIGNvbnN0IGNoaWxkcmVuQWRkZWQgPSB0aGlzLnBlcmZvcm1QYXRjaChwYXRjaCwgdHJ1ZSk7XG4gICAgcmV0dXJuIGNoaWxkcmVuQWRkZWQ7XG4gIH1cbiAgZ2V0SG9vayhlbCkge1xuICAgIHJldHVybiB0aGlzLnZpZXdIb29rc1tWaWV3SG9vay5lbGVtZW50SUQoZWwpXTtcbiAgfVxuICBhZGRIb29rKGVsKSB7XG4gICAgY29uc3QgaG9va0VsSWQgPSBWaWV3SG9vay5lbGVtZW50SUQoZWwpO1xuICAgIGlmIChlbC5nZXRBdHRyaWJ1dGUgJiYgIXRoaXMub3duc0VsZW1lbnQoZWwpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChob29rRWxJZCAmJiAhdGhpcy52aWV3SG9va3NbaG9va0VsSWRdKSB7XG4gICAgICBpZiAoVmlld0hvb2suZGVhZEhvb2soZWwpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGhvb2sgPSBkb21fZGVmYXVsdC5nZXRDdXN0b21FbEhvb2soZWwpIHx8IGxvZ0Vycm9yKGBubyBob29rIGZvdW5kIGZvciBjdXN0b20gZWxlbWVudDogJHtlbC5pZH1gKTtcbiAgICAgIHRoaXMudmlld0hvb2tzW2hvb2tFbElkXSA9IGhvb2s7XG4gICAgICBob29rLl9fYXR0YWNoVmlldyh0aGlzKTtcbiAgICAgIHJldHVybiBob29rO1xuICAgIH0gZWxzZSBpZiAoaG9va0VsSWQgfHwgIWVsLmdldEF0dHJpYnV0ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBob29rTmFtZSA9IGVsLmdldEF0dHJpYnV0ZShgZGF0YS1waHgtJHtQSFhfSE9PS31gKSB8fCBlbC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFBIWF9IT09LKSk7XG4gICAgICBpZiAoIWhvb2tOYW1lKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGhvb2tEZWZpbml0aW9uID0gdGhpcy5saXZlU29ja2V0LmdldEhvb2tEZWZpbml0aW9uKGhvb2tOYW1lKTtcbiAgICAgIGlmIChob29rRGVmaW5pdGlvbikge1xuICAgICAgICBpZiAoIWVsLmlkKSB7XG4gICAgICAgICAgbG9nRXJyb3IoXG4gICAgICAgICAgICBgbm8gRE9NIElEIGZvciBob29rIFwiJHtob29rTmFtZX1cIi4gSG9va3MgcmVxdWlyZSBhIHVuaXF1ZSBJRCBvbiBlYWNoIGVsZW1lbnQuYCxcbiAgICAgICAgICAgIGVsXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGhvb2tJbnN0YW5jZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAodHlwZW9mIGhvb2tEZWZpbml0aW9uID09PSBcImZ1bmN0aW9uXCIgJiYgaG9va0RlZmluaXRpb24ucHJvdG90eXBlIGluc3RhbmNlb2YgVmlld0hvb2spIHtcbiAgICAgICAgICAgIGhvb2tJbnN0YW5jZSA9IG5ldyBob29rRGVmaW5pdGlvbih0aGlzLCBlbCk7XG4gICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaG9va0RlZmluaXRpb24gPT09IFwib2JqZWN0XCIgJiYgaG9va0RlZmluaXRpb24gIT09IG51bGwpIHtcbiAgICAgICAgICAgIGhvb2tJbnN0YW5jZSA9IG5ldyBWaWV3SG9vayh0aGlzLCBlbCwgaG9va0RlZmluaXRpb24pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2dFcnJvcihcbiAgICAgICAgICAgICAgYEludmFsaWQgaG9vayBkZWZpbml0aW9uIGZvciBcIiR7aG9va05hbWV9XCIuIEV4cGVjdGVkIGEgY2xhc3MgZXh0ZW5kaW5nIFZpZXdIb29rIG9yIGFuIG9iamVjdCBkZWZpbml0aW9uLmAsXG4gICAgICAgICAgICAgIGVsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGUgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFN0cmluZyhlKTtcbiAgICAgICAgICBsb2dFcnJvcihgRmFpbGVkIHRvIGNyZWF0ZSBob29rIFwiJHtob29rTmFtZX1cIjogJHtlcnJvck1lc3NhZ2V9YCwgZWwpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZpZXdIb29rc1tWaWV3SG9vay5lbGVtZW50SUQoaG9va0luc3RhbmNlLmVsKV0gPSBob29rSW5zdGFuY2U7XG4gICAgICAgIHJldHVybiBob29rSW5zdGFuY2U7XG4gICAgICB9IGVsc2UgaWYgKGhvb2tOYW1lICE9PSBudWxsKSB7XG4gICAgICAgIGxvZ0Vycm9yKGB1bmtub3duIGhvb2sgZm91bmQgZm9yIFwiJHtob29rTmFtZX1cImAsIGVsKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZGVzdHJveUhvb2soaG9vaykge1xuICAgIGNvbnN0IGhvb2tJZCA9IFZpZXdIb29rLmVsZW1lbnRJRChob29rLmVsKTtcbiAgICBob29rLl9fZGVzdHJveWVkKCk7XG4gICAgaG9vay5fX2NsZWFudXBfXygpO1xuICAgIGRlbGV0ZSB0aGlzLnZpZXdIb29rc1tob29rSWRdO1xuICB9XG4gIGFwcGx5UGVuZGluZ1VwZGF0ZXMoKSB7XG4gICAgdGhpcy5wZW5kaW5nRGlmZnMgPSB0aGlzLnBlbmRpbmdEaWZmcy5maWx0ZXIoXG4gICAgICAoeyBkaWZmLCBldmVudHMgfSkgPT4gIXRoaXMudXBkYXRlKGRpZmYsIGV2ZW50cywgdHJ1ZSlcbiAgICApO1xuICAgIHRoaXMuZWFjaENoaWxkKChjaGlsZCkgPT4gY2hpbGQuYXBwbHlQZW5kaW5nVXBkYXRlcygpKTtcbiAgfVxuICBlYWNoQ2hpbGQoY2FsbGJhY2spIHtcbiAgICBjb25zdCBjaGlsZHJlbiA9IHRoaXMucm9vdC5jaGlsZHJlblt0aGlzLmlkXSB8fCB7fTtcbiAgICBmb3IgKGNvbnN0IGlkIGluIGNoaWxkcmVuKSB7XG4gICAgICBjYWxsYmFjayh0aGlzLmdldENoaWxkQnlJZChpZCkpO1xuICAgIH1cbiAgfVxuICBvbkNoYW5uZWwoZXZlbnQsIGNiKSB7XG4gICAgdGhpcy5saXZlU29ja2V0Lm9uQ2hhbm5lbCh0aGlzLmNoYW5uZWwsIGV2ZW50LCAocmVzcCkgPT4ge1xuICAgICAgaWYgKHRoaXMuaXNKb2luUGVuZGluZygpKSB7XG4gICAgICAgIGlmICh0aGlzLmpvaW5Db3VudCA+IDEpIHtcbiAgICAgICAgICB0aGlzLnBlbmRpbmdKb2luT3BzLnB1c2goKCkgPT4gY2IocmVzcCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucm9vdC5wZW5kaW5nSm9pbk9wcy5wdXNoKFt0aGlzLCAoKSA9PiBjYihyZXNwKV0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmxpdmVTb2NrZXQucmVxdWVzdERPTVVwZGF0ZSgoKSA9PiBjYihyZXNwKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgYmluZENoYW5uZWwoKSB7XG4gICAgdGhpcy5saXZlU29ja2V0Lm9uQ2hhbm5lbCh0aGlzLmNoYW5uZWwsIFwiZGlmZlwiLCAocmF3RGlmZikgPT4ge1xuICAgICAgdGhpcy5saXZlU29ja2V0LnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgICB0aGlzLmFwcGx5
1RGlmZihcbiAgICAgICAgICBcInVwZGF0ZVwiLFxuICAgICAgICAgIHJhd0RpZmYsXG4gICAgICAgICAgKHsgZGlmZiwgZXZlbnRzIH0pID0+IHRoaXMudXBkYXRlKGRpZmYsIGV2ZW50cylcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHRoaXMub25DaGFubmVsKFxuICAgICAgXCJyZWRpcmVjdFwiLFxuICAgICAgKHsgdG8sIGZsYXNoIH0pID0+IHRoaXMub25SZWRpcmVjdCh7IHRvLCBmbGFzaCB9KVxuICAgICk7XG4gICAgdGhpcy5vbkNoYW5uZWwoXCJsaXZlX3BhdGNoXCIsIChyZWRpcikgPT4gdGhpcy5vbkxpdmVQYXRjaChyZWRpcikpO1xuICAgIHRoaXMub25DaGFubmVsKFwibGl2ZV9yZWRpcmVjdFwiLCAocmVkaXIpID0+IHRoaXMub25MaXZlUmVkaXJlY3QocmVkaXIpKTtcbiAgICB0aGlzLmNoYW5uZWwub25FcnJvcigocmVhc29uKSA9PiB0aGlzLm9uRXJyb3IocmVhc29uKSk7XG4gICAgdGhpcy5jaGFubmVsLm9uQ2xvc2UoKHJlYXNvbikgPT4gdGhpcy5vbkNsb3NlKHJlYXNvbikpO1xuICB9XG4gIGRlc3Ryb3lBbGxDaGlsZHJlbigpIHtcbiAgICB0aGlzLmVhY2hDaGlsZCgoY2hpbGQpID0+IGNoaWxkLmRlc3Ryb3koKSk7XG4gIH1cbiAgb25MaXZlUmVkaXJlY3QocmVkaXIpIHtcbiAgICBjb25zdCB7IHRvLCBraW5kLCBmbGFzaCB9ID0gcmVkaXI7XG4gICAgY29uc3QgdXJsID0gdGhpcy5leHBhbmRVUkwodG8pO1xuICAgIGNvbnN0IGUgPSBuZXcgQ3VzdG9tRXZlbnQoXCJwaHg6c2VydmVyLW5hdmlnYXRlXCIsIHtcbiAgICAgIGRldGFpbDogeyB0bywga2luZCwgZmxhc2ggfVxuICAgIH0pO1xuICAgIHRoaXMubGl2ZVNvY2tldC5oaXN0b3J5UmVkaXJlY3QoZSwgdXJsLCBraW5kLCBmbGFzaCk7XG4gIH1cbiAgb25MaXZlUGF0Y2gocmVkaXIpIHtcbiAgICBjb25zdCB7IHRvLCBraW5kIH0gPSByZWRpcjtcbiAgICB0aGlzLmhyZWYgPSB0aGlzLmV4cGFuZFVSTCh0byk7XG4gICAgdGhpcy5saXZlU29ja2V0Lmhpc3RvcnlQYXRjaCh0bywga2luZCk7XG4gIH1cbiAgZXhwYW5kVVJMKHRvKSB7XG4gICAgcmV0dXJuIHRvLnN0YXJ0c1dpdGgoXCIvXCIpID8gYCR7d2luZG93LmxvY2F0aW9uLnByb3RvY29sfS8vJHt3aW5kb3cubG9jYXRpb24uaG9zdH0ke3RvfWAgOiB0bztcbiAgfVxuICBvblJlZGlyZWN0KHtcbiAgICB0byxcbiAgICBmbGFzaCxcbiAgICByZWxvYWRUb2tlblxuICB9KSB7XG4gICAgdGhpcy5saXZlU29ja2V0LnJlZGlyZWN0KHRvLCBmbGFzaCA/PyBudWxsLCByZWxvYWRUb2tlbiA/PyBudWxsKTtcbiAgfVxuICBpc0Rlc3Ryb3llZCgpIHtcbiAgICByZXR1cm4gdGhpcy5kZXN0cm95ZWQ7XG4gIH1cbiAgam9pbkRlYWQoKSB7XG4gICAgdGhpcy5pc0RlYWQgPSB0cnVlO1xuICB9XG4gIGpvaW4oY2FsbGJhY2spIHtcbiAgICB0aGlzLnNob3dMb2FkZXIodGhpcy5saXZlU29ja2V0LmxvYWRlclRpbWVvdXQpO1xuICAgIHRoaXMuYmluZENoYW5uZWwoKTtcbiAgICBpZiAodGhpcy5pc01haW4oKSkge1xuICAgICAgdGhpcy5zdG9wQ2FsbGJhY2sgPSB0aGlzLmxpdmVTb2NrZXQud2l0aFBhZ2VMb2FkaW5nKHtcbiAgICAgICAgdG86IHRoaXMuaHJlZixcbiAgICAgICAga2luZDogXCJpbml0aWFsXCJcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLmpvaW5DYWxsYmFjayA9IChvbkRvbmUpID0+IHtcbiAgICAgIG9uRG9uZSA9IG9uRG9uZSB8fCBmdW5jdGlvbigpIHtcbiAgICAgIH07XG4gICAgICBjYWxsYmFjayA/IGNhbGxiYWNrKHRoaXMuam9pbkNvdW50LCBvbkRvbmUpIDogb25Eb25lKCk7XG4gICAgfTtcbiAgICB0aGlzLndyYXBQdXNoKCgpID0+IHRoaXMuY2hhbm5lbC5qb2luKCksIHtcbiAgICAgIG9rOiAocmVzcCkgPT4gdGhpcy5saXZlU29ja2V0LnJlcXVlc3RET01VcGRhdGUoKCkgPT4gdGhpcy5vbkpvaW4ocmVzcCkpLFxuICAgICAgZXJyb3I6IChlcnJvcikgPT4gdGhpcy5vbkpvaW5FcnJvcihlcnJvciksXG4gICAgICB0aW1lb3V0OiAoKSA9PiB0aGlzLm9uSm9pbkVycm9yKHsgcmVhc29uOiBcInRpbWVvdXRcIiB9KVxuICAgIH0pO1xuICB9XG4gIG9uSm9pbkVycm9yKHJlc3ApIHtcbiAgICBpZiAocmVzcC5ldmVudHMpIHtcbiAgICAgIHRoaXMubGl2ZVNvY2tldC5kaXNwYXRjaEV2ZW50cyhyZXNwLmV2ZW50cyk7XG4gICAgfVxuICAgIGlmIChyZXNwLnJlYXNvbiA9PT0gXCJyZWxvYWRcIikge1xuICAgICAgdGhpcy5sb2coXCJlcnJvclwiLCAoKSA9PiBbXG4gICAgICAgIGBmYWlsZWQgbW91bnQgd2l0aCAke3Jlc3Auc3RhdHVzfS4gRmFsbGluZyBiYWNrIHRvIHBhZ2UgcmVsb2FkYCxcbiAgICAgICAgcmVzcFxuICAgICAgXSk7XG4gICAgICB0aGlzLm9uUmVkaXJlY3Qoe1xuICAgICAgICB0bzogdGhpcy5saXZlU29ja2V0Lm1haW4uaHJlZixcbiAgICAgICAgcmVsb2FkVG9rZW46IHJlc3AudG9rZW5cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSBpZiAocmVzcC5yZWFzb24gPT09IFwidW5hdXRob3JpemVkXCIgfHwgcmVzcC5yZWFzb24gPT09IFwic3RhbGVcIikge1xuICAgICAgdGhpcy5sb2coXCJlcnJvclwiLCAoKSA9PiBbXG4gICAgICAgIFwidW5hdXRob3JpemVkIGxpdmVfcmVkaXJlY3QuIEZhbGxpbmcgYmFjayB0byBwYWdlIHJlcXVlc3RcIixcbiAgICAgICAgcmVzcFxuICAgICAgXSk7XG4gICAgICB0aGlzLm9uUmVkaXJlY3QoeyB0bzogdGhpcy5saXZlU29ja2V0Lm1haW4uaHJlZiwgZmxhc2g6IHRoaXMuZmxhc2ggfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChyZXNwLnJlZGlyZWN0IHx8IHJlc3AubGl2ZV9yZWRpcmVjdCkge1xuICAgICAgdGhpcy5qb2luUGVuZGluZyA9IGZhbHNlO1xuICAgICAgdGhpcy5jaGFubmVsLmxlYXZlKCk7XG4gICAgfVxuICAgIGlmIChyZXNwLnJlZGlyZWN0KSB7XG4gICAgICByZXR1cm4gdGhpcy5vblJlZGlyZWN0KHJlc3AucmVkaXJlY3QpO1xuICAgIH1cbiAgICBpZiAocmVzcC5saXZlX3JlZGlyZWN0KSB7XG4gICAgICByZXR1cm4gdGhpcy5vbkxpdmVSZWRpcmVjdChyZXNwLmxpdmVfcmVkaXJlY3QpO1xuICAgIH1cbiAgICB0aGlzLmxvZyhcImVycm9yXCIsICgpID0+IFtcInVuYWJsZSB0byBqb2luXCIsIHJlc3BdKTtcbiAgICBpZiAodGhpcy5pc01haW4oKSkge1xuICAgICAgdGhpcy5kaXNwbGF5RXJyb3IoXG4gICAgICAgIFtQSFhfTE9BRElOR19DTEFTUywgUEhYX0VSUk9SX0NMQVNTLCBQSFhfU0VSVkVSX0VSUk9SX0NMQVNTXSxcbiAgICAgICAgeyB1bnN0cnVjdHVyZWRFcnJvcjogcmVzcCwgZXJyb3JLaW5kOiBcInNlcnZlclwiIH1cbiAgICAgICk7XG4gICAgICBpZiAodGhpcy5saXZlU29ja2V0LmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgdGhpcy5saXZlU29ja2V0LnJlbG9hZFdpdGhKaXR0ZXIodGhpcyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLmpvaW5BdHRlbXB0cyA+PSBNQVhfQ0hJTERfSk9JTl9BVFRFTVBUUykge1xuICAgICAgICB0aGlzLnJvb3QuZGlzcGxheUVycm9yKFxuICAgICAgICAgIFtQSFhfTE9BRElOR19DTEFTUywgUEhYX0VSUk9SX0NMQVNTLCBQSFhfU0VSVkVSX0VSUk9SX0NMQVNTXSxcbiAgICAgICAgICB7IHVuc3RydWN0dXJlZEVycm9yOiByZXNwLCBlcnJvcktpbmQ6IFwic2VydmVyXCIgfVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmxvZyhcImVycm9yXCIsICgpID0+IFtcbiAgICAgICAgICBgZ2l2aW5nIHVwIHRyeWluZyB0byBtb3VudCBhZnRlciAke01BWF9DSElMRF9KT0lOX0FUVEVNUFRTfSB0cmllc2AsXG4gICAgICAgICAgcmVzcFxuICAgICAgICBdKTtcbiAgICAgICAgdGhpcy5kZXN0cm95KCk7XG4gICAgICB9XG4gICAgICBjb25zdCB0cnVlQ2hpbGRFbCA9IGRvbV9kZWZhdWx0LmJ5SWQodGhpcy5lbC5pZCk7XG4gICAgICBpZiAodHJ1ZUNoaWxkRWwpIHtcbiAgICAgICAgZG9tX2RlZmF1bHQubWVyZ2VBdHRycyh0cnVlQ2hpbGRFbCwgdGhpcy5lbCk7XG4gICAgICAgI
1HRoaXMuZGlzcGxheUVycm9yKFxuICAgICAgICAgIFtQSFhfTE9BRElOR19DTEFTUywgUEhYX0VSUk9SX0NMQVNTLCBQSFhfU0VSVkVSX0VSUk9SX0NMQVNTXSxcbiAgICAgICAgICB7IHVuc3RydWN0dXJlZEVycm9yOiByZXNwLCBlcnJvcktpbmQ6IFwic2VydmVyXCIgfVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmVsID0gdHJ1ZUNoaWxkRWw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmRlc3Ryb3koKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgb25DbG9zZShyZWFzb24pIHtcbiAgICBpZiAodGhpcy5pc0Rlc3Ryb3llZCgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLmlzTWFpbigpICYmIHRoaXMubGl2ZVNvY2tldC5oYXNQZW5kaW5nTGluaygpICYmIHJlYXNvbiAhPT0gXCJsZWF2ZVwiKSB7XG4gICAgICByZXR1cm4gdGhpcy5saXZlU29ja2V0LnJlbG9hZFdpdGhKaXR0ZXIodGhpcyk7XG4gICAgfVxuICAgIHRoaXMuZGVzdHJveUFsbENoaWxkcmVuKCk7XG4gICAgdGhpcy5saXZlU29ja2V0LmRyb3BBY3RpdmVFbGVtZW50KHRoaXMpO1xuICAgIGlmICh0aGlzLmxpdmVTb2NrZXQuaXNVbmxvYWRlZCgpKSB7XG4gICAgICB0aGlzLnNob3dMb2FkZXIoQkVGT1JFX1VOTE9BRF9MT0FERVJfVElNRU9VVCk7XG4gICAgfVxuICB9XG4gIG9uRXJyb3IocmVhc29uKSB7XG4gICAgdGhpcy5vbkNsb3NlKHJlYXNvbik7XG4gICAgaWYgKHRoaXMubGl2ZVNvY2tldC5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICB0aGlzLmxvZyhcImVycm9yXCIsICgpID0+IFtcInZpZXcgY3Jhc2hlZFwiLCByZWFzb25dKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmxpdmVTb2NrZXQuaXNVbmxvYWRlZCgpKSB7XG4gICAgICBpZiAodGhpcy5saXZlU29ja2V0LmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgdGhpcy5kaXNwbGF5RXJyb3IoXG4gICAgICAgICAgW1BIWF9MT0FESU5HX0NMQVNTLCBQSFhfRVJST1JfQ0xBU1MsIFBIWF9TRVJWRVJfRVJST1JfQ0xBU1NdLFxuICAgICAgICAgIHsgdW5zdHJ1Y3R1cmVkRXJyb3I6IHJlYXNvbiwgZXJyb3JLaW5kOiBcInNlcnZlclwiIH1cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZGlzcGxheUVycm9yKFxuICAgICAgICAgIFtQSFhfTE9BRElOR19DTEFTUywgUEhYX0VSUk9SX0NMQVNTLCBQSFhfQ0xJRU5UX0VSUk9SX0NMQVNTXSxcbiAgICAgICAgICB7IHVuc3RydWN0dXJlZEVycm9yOiByZWFzb24sIGVycm9yS2luZDogXCJjbGllbnRcIiB9XG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGRpc3BsYXlFcnJvcihjbGFzc2VzLCBkZXRhaWxzID0ge30pIHtcbiAgICBpZiAodGhpcy5pc01haW4oKSkge1xuICAgICAgZG9tX2RlZmF1bHQuZGlzcGF0Y2hFdmVudCh3aW5kb3csIFwicGh4OnBhZ2UtbG9hZGluZy1zdGFydFwiLCB7XG4gICAgICAgIGRldGFpbDogeyB0bzogdGhpcy5ocmVmLCBraW5kOiBcImVycm9yXCIsIC4uLmRldGFpbHMgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuc2hvd0xvYWRlcigpO1xuICAgIHRoaXMuc2V0Q29udGFpbmVyQ2xhc3NlcyguLi5jbGFzc2VzKTtcbiAgICB0aGlzLmRlbGF5ZWREaXNjb25uZWN0ZWQoKTtcbiAgfVxuICBkZWxheWVkRGlzY29ubmVjdGVkKCkge1xuICAgIHRoaXMuZGlzY29ubmVjdGVkVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuZXhlY0FsbCh0aGlzLmJpbmRpbmcoXCJkaXNjb25uZWN0ZWRcIikpO1xuICAgIH0sIHRoaXMubGl2ZVNvY2tldC5kaXNjb25uZWN0ZWRUaW1lb3V0KTtcbiAgfVxuICB3cmFwUHVzaChjYWxsZXJQdXNoLCByZWNlaXZlcykge1xuICAgIGNvbnN0IGxhdGVuY3kgPSB0aGlzLmxpdmVTb2NrZXQuZ2V0TGF0ZW5jeVNpbSgpO1xuICAgIGNvbnN0IHdpdGhMYXRlbmN5ID0gbGF0ZW5jeSA/IChjYikgPT4gc2V0VGltZW91dCgoKSA9PiAhdGhpcy5pc0Rlc3Ryb3llZCgpICYmIGNiKCksIGxhdGVuY3kpIDogKGNiKSA9PiAhdGhpcy5pc0Rlc3Ryb3llZCgpICYmIGNiKCk7XG4gICAgd2l0aExhdGVuY3koKCkgPT4ge1xuICAgICAgY2FsbGVyUHVzaCgpLnJlY2VpdmUoXG4gICAgICAgIFwib2tcIixcbiAgICAgICAgKHJlc3ApID0+IHdpdGhMYXRlbmN5KCgpID0+IHJlY2VpdmVzLm9rICYmIHJlY2VpdmVzLm9rKHJlc3ApKVxuICAgICAgKS5yZWNlaXZlKFxuICAgICAgICBcImVycm9yXCIsXG4gICAgICAgIChyZWFzb24pID0+IHdpdGhMYXRlbmN5KCgpID0+IHJlY2VpdmVzLmVycm9yICYmIHJlY2VpdmVzLmVycm9yKHJlYXNvbikpXG4gICAgICApLnJlY2VpdmUoXG4gICAgICAgIFwidGltZW91dFwiLFxuICAgICAgICAoKSA9PiB3aXRoTGF0ZW5jeSgoKSA9PiByZWNlaXZlcy50aW1lb3V0ICYmIHJlY2VpdmVzLnRpbWVvdXQoKSlcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cbiAgcHVzaFdpdGhSZXBseShyZWZHZW5lcmF0b3IsIGV2ZW50LCBwYXlsb2FkKSB7XG4gICAgaWYgKCF0aGlzLmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJubyBjb25uZWN0aW9uXCIpKTtcbiAgICB9XG4gICAgY29uc3QgW3JlZiwgW2VsXSwgb3B0c10gPSByZWZHZW5lcmF0b3IgPyByZWZHZW5lcmF0b3IoeyBwYXlsb2FkIH0pIDogW251bGwsIFtdLCB7fV07XG4gICAgY29uc3Qgb2xkSm9pbkNvdW50ID0gdGhpcy5qb2luQ291bnQ7XG4gICAgbGV0IG9uTG9hZGluZ0RvbmUgPSBmdW5jdGlvbigpIHtcbiAgICB9O1xuICAgIGlmIChvcHRzLnBhZ2VfbG9hZGluZykge1xuICAgICAgb25Mb2FkaW5nRG9uZSA9IHRoaXMubGl2ZVNvY2tldC53aXRoUGFnZUxvYWRpbmcoe1xuICAgICAgICBraW5kOiBcImVsZW1lbnRcIixcbiAgICAgICAgdGFyZ2V0OiBlbFxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgcGF5bG9hZC5jaWQgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgIGRlbGV0ZSBwYXlsb2FkLmNpZDtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMud3JhcFB1c2goKCkgPT4gdGhpcy5jaGFubmVsLnB1c2goZXZlbnQsIHBheWxvYWQsIFBVU0hfVElNRU9VVCksIHtcbiAgICAgICAgb2s6IChyZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlZiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5sYXN0QWNrUmVmID0gcmVmO1xuICAgICAgICAgI
1H1cbiAgICAgICAgICBjb25zdCBmaW5pc2ggPSAoaG9va1JlcGx5KSA9PiB7XG4gICAgICAgICAgICBpZiAocmVzcC5yZWRpcmVjdCkge1xuICAgICAgICAgICAgICB0aGlzLm9uUmVkaXJlY3QocmVzcC5yZWRpcmVjdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVzcC5saXZlX3BhdGNoKSB7XG4gICAgICAgICAgICAgIHRoaXMub25MaXZlUGF0Y2gocmVzcC5saXZlX3BhdGNoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZXNwLmxpdmVfcmVkaXJlY3QpIHtcbiAgICAgICAgICAgICAgdGhpcy5vbkxpdmVSZWRpcmVjdChyZXNwLmxpdmVfcmVkaXJlY3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgb25Mb2FkaW5nRG9uZSgpO1xuICAgICAgICAgICAgcmVzb2x2ZSh7IHJlc3AsIHJlcGx5OiBob29rUmVwbHksIHJlZiB9KTtcbiAgICAgICAgICB9O1xuICAgICAgICAgIGlmIChyZXNwLmRpZmYpIHtcbiAgICAgICAgICAgIHRoaXMubGl2ZVNvY2tldC5yZXF1ZXN0RE9NVXBkYXRlKCgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5hcHBseURpZmYoXCJ1cGRhdGVcIiwgcmVzcC5kaWZmLCAoeyBkaWZmLCByZXBseSwgZXZlbnRzIH0pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAocmVmICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLnVuZG9SZWZzKHJlZiwgcGF5bG9hZC5ldmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlKGRpZmYsIGV2ZW50cyk7XG4gICAgICAgICAgICAgICAgZmluaXNoKHJlcGx5KTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHJlZiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICB0aGlzLnVuZG9SZWZzKHJlZiwgcGF5bG9hZC5ldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmaW5pc2gobnVsbCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKHJlYXNvbikgPT4gcmVqZWN0KG5ldyBFcnJvcihgZmFpbGVkIHdpdGggcmVhc29uOiAke0pTT04uc3RyaW5naWZ5KHJlYXNvbil9YCkpLFxuICAgICAgICB0aW1lb3V0OiAoKSA9PiB7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcInRpbWVvdXRcIikpO1xuICAgICAgICAgIGlmICh0aGlzLmpvaW5Db3VudCA9PT0gb2xkSm9pbkNvdW50KSB7XG4gICAgICAgICAgICB0aGlzLmxpdmVTb2NrZXQucmVsb2FkV2l0aEppdHRlcih0aGlzLCAoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMubG9nKFwidGltZW91dFwiLCAoKSA9PiBbXG4gICAgICAgICAgICAgICAgXCJyZWNlaXZlZCB0aW1lb3V0IHdoaWxlIGNvbW11bmljYXRpbmcgd2l0aCBzZXJ2ZXIuIEZhbGxpbmcgYmFjayB0byBoYXJkIHJlZnJlc2ggZm9yIHJlY292ZXJ5XCJcbiAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIHVuZG9SZWZzKHJlZiwgcGh4RXZlbnQsIG9ubHlFbHMpIHtcbiAgICBpZiAoIXRoaXMuaXNDb25uZWN0ZWQoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzZWxlY3RvciA9IGBbJHtQSFhfUkVGX1NSQ309XCIke3RoaXMucmVmU3JjKCl9XCJdYDtcbiAgICBpZiAob25seUVscykge1xuICAgICAgb25seUVscyA9IG5ldyBTZXQob25seUVscyk7XG4gICAgICBkb21fZGVmYXVsdC5hbGwoZG9jdW1lbnQsIHNlbGVjdG9yLCAocGFyZW50KSA9PiB7XG4gICAgICAgIGlmIChvbmx5RWxzICYmICFvbmx5RWxzLmhhcyhwYXJlbnQpKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGRvbV9kZWZhdWx0LmFsbChcbiAgICAgICAgICBwYXJlbnQsXG4gICAgICAgICAgc2VsZWN0b3IsXG4gICAgICAgICAgKGNoaWxkKSA9PiB0aGlzLnVuZG9FbFJlZihjaGlsZCwgcmVmLCBwaHhFdmVudClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy51bmRvRWxSZWYocGFyZW50LCByZWYsIHBoeEV2ZW50KTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBkb21fZGVmYXVsdC5hbGwoZG9jdW1lbnQsIHNlbGVjdG9yLCAoZWwpID0+IHRoaXMudW5kb0VsUmVmKGVsLCByZWYsIHBoeEV2ZW50KSk7XG4gICAgfVxuICB9XG4gIHVuZG9FbFJlZihlbCwgcmVmLCBwaHhFdmVudCkge1xuICAgIGNvbnN0IGVsUmVmID0gbmV3IEVsZW1lbnRSZWYoZWwpO1xuICAgIGVsUmVmLm1heWJlVW5kbyhyZWYsIHBoeEV2ZW50LCAoY2xvbmVkVHJlZSkgPT4ge1xuICAgICAgY29uc3QgcGF0Y2ggPSBuZXcgRE9NUGF0Y2godGhpcywgZWwsIGNsb25lZFRyZWUsIC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCksIG51bGwsIHtcbiAgICAgICAgdW5kb1JlZjogcmVmXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHBoeENoaWxkcmVuQWRkZWQgPSB0aGlzLnBlcmZvcm1QYXRjaChwYXRjaCwgdHJ1ZSk7XG4gICAgICBkb21fZGVmYXVsdC5hbGwoXG4gICAgICAgIGVsLFxuICAgICAgICBgWyR7UEhYX1JFRl9TUkN9PVwiJHt0aGlzLnJlZlNyYygpfVwiXWAsXG4gICAgICAgIChjaGlsZCkgPT4gdGhpcy51bmRvRWxSZWYoY2hpbGQsIHJlZiwgcGh4RXZlbnQpXG4gICAgICApO1xuICAgICAgaWYgKHBoeENoaWxkcmVuQWRkZWQpIHtcbiAgICAgICAgdGhpcy5qb2luTmV3Q2hpbGRyZW4oKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICByZWZTcmMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZWwuaWQ7XG4gIH1cbiAgcHV0UmVmKGVsZW1lbnRzLCBwaHhFdmVudCwgZXZlbnRUeXBlLCBvcHRzID0ge30pIHtcbiAgICBjb25zdCBuZXdSZWYgPSB0aGlzLnJlZisrO1xuICAgIGNvbnN0IGRpc2FibGVXaXRoID0gdGhpcy5iaW5kaW5nKFBIWF9ESVNBQkxFX1dJVEgpO1xuICAgIGlmIChvcHRzLmxvYWRpbmcpIHtcbiAgICAgIGNvbnN0IGxvYWRpbmdFbHMgPSBkb21fZGVmYXVsdC5hbGwoZG9jdW1lbnQsIG9wdHMubG9hZGluZykubWFwKChlbCkgPT4ge1xuICAgICAgICByZXR1cm4geyBlbCwgbG9jazogdHJ1ZSwgbG9hZGluZzogdHJ1ZSB9O1xuICAgICAgfSk7XG4gICAgICBlbGVtZW50cyA9IGVsZW1lbnRzLmNvbmNhdChsb2FkaW5nRWxzKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCB7IGVsLCBsb2NrLCBsb2FkaW5nIH0gb2YgZWxlbWVudHMpIHtcbiAgICAgIGlmICghbG9jayAmJiAhbG9hZGluZykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJwdXRSZWYgcmVxdWlyZXMgbG9jayBvciBsb2FkaW5nXCIpO1xuICAgICAgfVxuICAgICAgZWwuc2V0QXR0cmlidXRlKFBIWF9SRUZfU1JDLCB0aGlzLnJlZlNyYygpKTtcbiAgICAgIGlmIChsb2FkaW5nKSB7XG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZShQSFhfUkVGX0xPQURJTkcsIG5ld1JlZi50b1N0cmluZygpKTtcbiAgICAgIH1cbiAgICAgIGlmIChsb2NrKSB7XG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZShQSFhfUkVGX0xPQ0ssIG5ld1JlZi50b1N0cmluZygpKTtcbiAgICAgIH1cbiAgICAgIGlmICghbG9hZGluZyB8fCBvcHRzLnN1Ym1pdHRlciAmJiAhKGVsID09PSBvcHRzLnN1Ym1pdHRlciB8fCBlbCA9PT0gb3B0cy5mb3JtKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGxvY2tDb21wbGV0ZVByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKGBwaHg6dW5kby1sb2NrOiR7bmV3UmVmfWAsICgpID0+IHJlc29sdmUoZGV0YWlsKSwge1xuICAgICAgICAgIG9uY2U6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGxvYWRpbmdDb21wbGV0ZVByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgIGBwaHg6dW5kby1sb2FkaW5nOiR7bmV3UmVmfWAsXG4gICAgICAgICAgKCkgPT4gcmVzb2x2ZShkZXRhaWwpLFxuICAgICAgICAgI
1Hsgb25jZTogdHJ1ZSB9XG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICAgIGVsLmNsYXNzTGlzdC5hZGQoYHBoeC0ke2V2ZW50VHlwZX0tbG9hZGluZ2ApO1xuICAgICAgY29uc3QgZGlzYWJsZVRleHQgPSBlbC5nZXRBdHRyaWJ1dGUoZGlzYWJsZVdpdGgpO1xuICAgICAgaWYgKGRpc2FibGVUZXh0ICE9PSBudWxsKSB7XG4gICAgICAgIGlmICghZWwuZ2V0QXR0cmlidXRlKFBIWF9ESVNBQkxFX1dJVEhfUkVTVE9SRSkpIHtcbiAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoUEhYX0RJU0FCTEVfV0lUSF9SRVNUT1JFLCBlbC50ZXh0Q29udGVudCB8fCBcIlwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGlzYWJsZVRleHQgIT09IFwiXCIpIHtcbiAgICAgICAgICBlbC50ZXh0Q29udGVudCA9IGRpc2FibGVUZXh0O1xuICAgICAgICB9XG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBQSFhfRElTQUJMRUQsXG4gICAgICAgICAgZWwuZ2V0QXR0cmlidXRlKFBIWF9ESVNBQkxFRCkgfHwgKFwiZGlzYWJsZWRcIiBpbiBlbCA/IFN0cmluZyhlbC5kaXNhYmxlZCkgOiBcIlwiKVxuICAgICAgICApO1xuICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiLCBcIlwiKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRldGFpbCA9IHtcbiAgICAgICAgZXZlbnQ6IHBoeEV2ZW50LFxuICAgICAgICBldmVudFR5cGUsXG4gICAgICAgIHJlZjogbmV3UmVmLFxuICAgICAgICBpc0xvYWRpbmc6IGxvYWRpbmcsXG4gICAgICAgIGlzTG9ja2VkOiBsb2NrLFxuICAgICAgICBsb2NrRWxlbWVudHM6IGVsZW1lbnRzLmZpbHRlcigoeyBsb2NrOiBsb2NrMiB9KSA9PiBsb2NrMikubWFwKCh7IGVsOiBlbDIgfSkgPT4gZWwyKSxcbiAgICAgICAgbG9hZGluZ0VsZW1lbnRzOiBlbGVtZW50cy5maWx0ZXIoKHsgbG9hZGluZzogbG9hZGluZzIgfSkgPT4gbG9hZGluZzIpLm1hcCgoeyBlbDogZWwyIH0pID0+IGVsMiksXG4gICAgICAgIHVubG9jazogKGVscykgPT4ge1xuICAgICAgICAgIGVscyA9IEFycmF5LmlzQXJyYXkoZWxzKSA/IGVscyA6IFtlbHNdO1xuICAgICAgICAgIHRoaXMudW5kb1JlZnMobmV3UmVmLCBwaHhFdmVudCwgZWxzKTtcbiAgICAgICAgfSxcbiAgICAgICAgbG9ja0NvbXBsZXRlOiBsb2NrQ29tcGxldGVQcm9taXNlLFxuICAgICAgICBsb2FkaW5nQ29tcGxldGU6IGxvYWRpbmdDb21wbGV0ZVByb21pc2UsXG4gICAgICAgIGxvY2s6IChsb2NrRWwpID0+IHtcbiAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzQWNrZWQobmV3UmVmKSkge1xuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShkZXRhaWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9ja0VsLnNldEF0dHJpYnV0ZShQSFhfUkVGX0xPQ0ssIG5ld1JlZik7XG4gICAgICAgICAgICBsb2NrRWwuc2V0QXR0cmlidXRlKFBIWF9SRUZfU1JDLCB0aGlzLnJlZlNyYygpKTtcbiAgICAgICAgICAgIGxvY2tFbC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICBgcGh4OmxvY2stc3RvcDoke25ld1JlZn1gLFxuICAgICAgICAgICAgICAoKSA9PiByZXNvbHZlKGRldGFpbCksXG4gICAgICAgICAgICAgIHsgb25jZTogdHJ1ZSB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgaWYgKG9wdHMucGF5bG9hZCkge1xuICAgICAgICBkZXRhaWxbXCJwYXlsb2FkXCJdID0gb3B0cy5wYXlsb2FkO1xuICAgICAgfVxuICAgICAgaWYgKG9wdHMudGFyZ2V0KSB7XG4gICAgICAgIGRldGFpbFtcInRhcmdldFwiXSA9IG9wdHMudGFyZ2V0O1xuICAgICAgfVxuICAgICAgaWYgKG9wdHMub3JpZ2luYWxFdmVudCkge1xuICAgICAgICBkZXRhaWxbXCJvcmlnaW5hbEV2ZW50XCJdID0gb3B0cy5vcmlnaW5hbEV2ZW50O1xuICAgICAgfVxuICAgICAgZWwuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgbmV3IEN1c3RvbUV2ZW50KFwicGh4OnB1c2hcIiwge1xuICAgICAgICAgIGRldGFpbCxcbiAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgIGNhbmNlbGFibG
1U6IGZhbHNlXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgICAgaWYgKHBoeEV2ZW50KSB7XG4gICAgICAgIGVsLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KGBwaHg6cHVzaDoke3BoeEV2ZW50fWAsIHtcbiAgICAgICAgICAgIGRldGFpbCxcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZVxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBbbmV3UmVmLCBlbGVtZW50cy5tYXAoKHsgZWwgfSkgPT4gZWwpLCBvcHRzXTtcbiAgfVxuICBpc0Fja2VkKHJlZikge1xuICAgIHJldHVybiB0aGlzLmxhc3RBY2tSZWYgIT09IG51bGwgJiYgdGhpcy5sYXN0QWNrUmVmID49IHJlZjtcbiAgfVxuICBjb21wb25lbnRJRChlbCkge1xuICAgIGNvbnN0IGNpZCA9IGVsLmdldEF0dHJpYnV0ZSAmJiBlbC5nZXRBdHRyaWJ1dGUoUEhYX0NPTVBPTkVOVCk7XG4gICAgcmV0dXJuIGNpZCA/IHBhcnNlSW50KGNpZCkgOiBudWxsO1xuICB9XG4gIHRhcmdldENvbXBvbmVudElEKHRhcmdldCwgdGFyZ2V0Q3R4LCBvcHRzID0ge30pIHtcbiAgICBpZiAoaXNDaWQodGFyZ2V0Q3R4KSkge1xuICAgICAgcmV0dXJuIHRhcmdldEN0eDtcbiAgICB9XG4gICAgY29uc3QgY2lkT3JTZWxlY3RvciA9IG9wdHMudGFyZ2V0IHx8IHRhcmdldC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFwidGFyZ2V0XCIpKTtcbiAgICBpZiAoaXNDaWQoY2lkT3JTZWxlY3RvcikpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgY2lkT3JTZWxlY3RvciA9PT0gXCJudW1iZXJcIiA/IGNpZE9yU2VsZWN0b3IgOiBwYXJzZUludChjaWRPclNlbGVjdG9yKTtcbiAgICB9IGVsc2UgaWYgKHRhcmdldEN0eCAmJiAoY2lkT3JTZWxlY3RvciAhPT0gbnVsbCB8fCBvcHRzLnRhcmdldCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmNsb3Nlc3RDb21wb25lbnRJRCh0YXJnZXRDdHgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cbiAgY2xvc2VzdENvbXBvbmVudElEKHRhcmdldEN0eCkge1xuICAgIGlmIChpc0NpZCh0YXJnZXRDdHgpKSB7XG4gICAgICByZXR1cm4gdGFyZ2V0Q3R4O1xuICAgIH0gZWxzZSBpZiAodGFyZ2V0Q3R4KSB7XG4gICAgICByZXR1cm4gbWF5YmUoXG4gICAgICAgIC8vIFdlIGVpdGhlciB1c2UgdGhlIGNsb3Nlc3QgZGF0YS1waHgtY29tcG9uZW50IGJpbmRpbmcsIG9yIC1cbiAgICAgICAgLy8gaW4gY2FzZSBvZiBwb3J0YWxzIC0gY29udGludWUgd2l0aCB0aGUgcG9ydGFsIHNvdXJjZS5cbiAgICAgICAgLy8gVGhpcyBpcyBuZWNlc3NhcnkgaWYgdGVsZXBvcnRpbmcgYW4gZWxlbWVudCBvdXRzaWRlIG9mIGl0cyBMaXZlQ29tcG9uZW50LlxuICAgICAgICB0YXJnZXRDdHguY2xvc2VzdChgWyR7UEhYX0NPTVBPTkVOVH1dLFske1BIWF9URUxFUE9SVEVEX1NSQ31dYCksXG4gICAgICAgIChlbCkgPT4ge1xuICAgICAgICAgIGlmIChlbC5oYXNBdHRyaWJ1dGUoUEhYX0NPTVBPTkVOVCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm93bnNFbGVtZW50KGVsKSAmJiB0aGlzLmNvbXBvbmVudElEKGVsKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGVsLmhhc0F0dHJpYnV0ZShQSFhfVEVMRVBPUlRFRF9TUkMpKSB7XG4gICAgICAgICAgICBjb25zdCBwb3J0YWxQYXJlbnQgPSBkb21fZGVmYXVsdC5ieUlkKGVsLmdldEF0dHJpYnV0ZShQSFhfVEVMRVBPUlRFRF9TUkMpKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNsb3Nlc3RDb21wb25lbnRJRChwb3J0YWxQYXJlbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG4gIHB1c2hIb29rRXZlbnQoZWwsIHRhcmdldEN0eCwgZXZlbnQsIHBheWxvYWQpIHtcbiAgICBpZiAoIXRoaXMuaXNDb25uZWN0ZWQoKSkge1xuICAgICAgdGhpcy5sb2coXCJob29rXCIsICgpID0+IFtcbiAgICAgICAgXCJ1bmFibGUgdG8gcHVzaCBob29rIGV2ZW50LiBMaXZlVmlldyBub3QgY29ubmVjdGVkXCIsXG4gICAgICAgIGV2ZW50LFxuICAgICAgICBwYXlsb2FkXG4gICAgICBdKTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgbmV3IEVycm9yKFwidW5hYmxlIHRvIHB1c2ggaG9vayBldmVudC4gTGl2ZVZpZXcgbm90IGNvbm5lY3RlZFwiKVxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgcmVmR2VuZXJhdG9yID0gKCkgPT4gdGhpcy5wdXRSZWYoW3sgZWwsIGxvYWRpbmc6IHRydWUsIGxvY2s6IHRydWUgfV0sIGV2ZW50LCBcImhvb2tcIiwge1xuICAgICAgcGF5bG9hZCxcbiAgICAgIHRhcmdldDogdGFyZ2V0Q3R4XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMucHVzaFdpdGhSZXBseShyZWZHZW5lcmF0b3IsIFwiZXZlbnRcIiwge1xuICAgICAgdHlwZTogXCJob29rXCIsXG4gICAgICBldmVudCxcbiAgICAgIHZhbHVlOiBwYXlsb2FkLFxuICAgICAgY2lkOiB0aGlzLmNsb3Nlc3RDb21wb25lbnRJRCh0YXJnZXRDdHgpXG4gICAgfSkudGhlbihcbiAgICAgICh7IHJlc3A6IF9yZXNwLCByZXBseSwgcmVmIH0pID0+ICh7IHJlcGx5LCByZWYgfSlcbiAgICApO1xuICB9XG4gIGV4dHJhY3RNZXRhKGVsLCBtZXRhLCB2YWx1ZSkge1xuICAgIGNvbnN0IHByZWZpeCA9IHRoaXMuYmluZGluZyhcInZhbHVlLVwiKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVsLmF0dHJpYnV0ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICghbWV0YSkge1xuICAgICAgICBtZXRhID0ge307XG4gICAgICB9XG4gICAgICBjb25zdCBuYW1lID0gZWwuYXR0cmlidXRlc1tpXS5uYW1lO1xuICAgICAgaWYgKG5hbWUuc3RhcnRzV2l0aChwcmVmaXgpKSB7XG4gICAgICAgIG1ldGFbbmFtZS5yZXBsYWNlKHByZWZpeCwgXCJcIildID0gZWwuZ2V0QXR0cmlidXRlKG5hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZWwudmFsdWUgIT09IHZvaWQgMCAmJiAhKGVsIGluc3RhbmNlb2YgSFRNTEZvcm1FbGVtZW50KSkge1xuICAgICAgaWYgKCFtZXRhKSB7XG4gICAgICAgIG1ldGEgPSB7fTtcbiAgICAgIH1cbiAgICAgIG1ldGEudmFsdWUgPSBlbC52YWx1ZTtcbiAgICAgIGlmIChlbC50YWdOYW1lID09PSBcIklOUFVUXCIgJiYgQ0hFQ0tBQkxFX0lOUFVUUy5pbmRleE9mKG
1VsLnR5cGUpID49IDAgJiYgIWVsLmNoZWNrZWQpIHtcbiAgICAgICAgZGVsZXRlIG1ldGEudmFsdWU7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh2YWx1ZSkge1xuICAgICAgaWYgKCFtZXRhKSB7XG4gICAgICAgIG1ldGEgPSB7fTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3Qga2V5IGluIHZhbHVlKSB7XG4gICAgICAgIG1ldGFba2V5XSA9IHZhbHVlW2tleV07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtZXRhO1xuICB9XG4gIHNlcmlhbGl6ZUZvcm0oZm9ybSwgb3B0cyA9IHt9LCBvbmx5TmFtZXMgPSBbXSkge1xuICAgIGNvbnN0IHsgc3VibWl0dGVyIH0gPSBvcHRzO1xuICAgIGxldCBpbmplY3RlZEVsZW1lbnQ7XG4gICAgaWYgKHN1Ym1pdHRlciAmJiBzdWJtaXR0ZXIubmFtZSkge1xuICAgICAgY29uc3QgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7XG4gICAgICBpbnB1dC50eXBlID0gXCJoaWRkZW5cIjtcbiAgICAgIGNvbnN0IGZvcm1JZCA9IHN1Ym1pdHRlci5nZXRBdHRyaWJ1dGUoXCJmb3JtXCIpO1xuICAgICAgaWYgKGZvcm1JZCkge1xuICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoXCJmb3JtXCIsIGZvcm1JZCk7XG4gICAgICB9XG4gICAgICBpbnB1dC5uYW1lID0gc3VibWl0dGVyLm5hbWU7XG4gICAgICBpbnB1dC52YWx1ZSA9IHN1Ym1pdHRlci52YWx1ZTtcbiAgICAgIHN1Ym1pdHRlci5wYXJlbnRFbGVtZW50Lmluc2VydEJlZm9yZShpbnB1dCwgc3VibWl0dGVyKTtcbiAgICAgIGluamVjdGVkRWxlbWVudCA9IGlucHV0O1xuICAgIH1cbiAgICBjb25zdCBmb3JtRGF0YSA9IG5ldyBGb3JtRGF0YShmb3JtKTtcbiAgICBjb25zdCB0b1JlbW92ZSA9IFtdO1xuICAgIGZvcm1EYXRhLmZvckVhY2goKHZhbCwga2V5LCBfaW5kZXgpID0+IHtcbiAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBGaWxlKSB7XG4gICAgICAgIHRvUmVtb3ZlLnB1c2goa2V5KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0b1JlbW92ZS5mb3JFYWNoKChrZXkpID0+IGZvcm1EYXRhLmRlbGV0ZShrZXkpKTtcbiAgICBjb25zdCBwYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKCk7XG4gICAgY29uc3QgeyBpbnB1dHNVbnVzZWQsIG9ubHlIaWRkZW5JbnB1dHMgfSA9IEFycmF5LmZyb20oZm9ybS5lbGVtZW50cykucmVkdWNlKFxuICAgICAgKGFjYywgaW5wdXQpID0+IHtcbiAgICAgICAgaWYgKCFkb21fZGVmYXVsdC5pc0Zvcm1Bc3NvY2lhdGVkKGlucHV0KSkge1xuICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyBpbnB1dHNVbnVzZWQ6IGlucHV0c1VudXNlZDIsIG9ubHlIaWRkZW5JbnB1dHM6IG9ubHlIaWRkZW5JbnB1dHMyIH0gPSBhY2M7XG4gICAgICAgIGNvbnN0IGtleSA9IGlucHV0Lm5hbWU7XG4gICAgICAgIGlmICgha2V5KSB7XG4gICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgfVxuICAgICAgICBpZiAoaW5wdXRzVW51c2VkMltrZXldID09PSB2b2lkIDApIHtcbiAgICAgICAgICBpbnB1dHNVbnVzZWQyW2tleV0gPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvbmx5SGlkZGVuSW5wdXRzMltrZXldID09PSB2b2lkIDApIHtcbiAgICAgICAgICBvbmx5SGlkZGVuSW5wdXRzMltrZXldID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbnB1dFNraXBVbnVzZWRGaWVsZCA9IGlucHV0Lmhhc0F0dHJpYnV0ZShcbiAgICAgICAgICB0aGlzLmJpbmRpbmcoUEhYX05PX1VOVVNFRF9GSUVMRClcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgaXNVc2VkID0gZG9tX2RlZmF1bHQucHJpdmF0ZShpbnB1dCwgUEhYX0hBU19GT0NVU0VEKSB8fCBkb21fZGVmYXVsdC5wcml2YXRlKGlucHV0LCBQSFhfSEFTX1NVQk1JVFRFRCkgfHwgaW5wdXRTa2lwVW51c2VkRmllbGQ7XG4gICAgICAgIGNvbnN0IGlzSGlkZGVuID0gaW5wdXQudHlwZSA9PT0gXCJoaWRkZW5cIjtcbiAgICAgICAgaW5wdXRzVW51c2VkMltrZXldID0gaW5wdXRzVW51c2VkMltrZXldICYmICFpc1VzZWQ7XG4gICAgICAgIG9ubHlIaWRkZW5JbnB1dHMyW2tleV0gPSBvbmx5SGlkZGVuSW5wdXRzMltrZXldICYmIGlzSGlkZGVuO1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSxcbiAgICAgIHsgaW5wdXRzVW51c2VkOiB7fSwgb25seUhpZGRlbklucHV0czoge30gfVxuICAgICk7XG4gICAgY29uc3QgZm9ybVNraXBVbnVzZWRGaWVsZHMgPSBmb3JtLmhhc0F0dHJpYnV0ZShcbiAgICAgIHRoaXMuYmluZGluZyhQSFhfTk9fVU5VU0VEX0ZJRUxEKVxuICAgICk7XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWxdIG9mIGZvcm1EYXRhLmVudHJpZXMoKSkge1xuICAgICAgaWYgKG9ubHlOYW1lcy5sZW5ndGggPT09IDAgfHwgb25seU5hbWVzLmluZGV4T2Yoa2V5KSA+PSAwKSB7XG4gICAgICAgIGNvbnN0IGlzVW51c2VkID0gaW5wdXRzVW51c2VkW2tleV07XG4gICAgICAgIGNvbnN0IGhpZGRlbiA9IG9ubHlIaWRkZW5JbnB1dHNba2V5XTtcbiAgICAgICAgY29uc3Qgc2tpcFVudXNlZENoZWNrID0gZm9ybVNraXBVbnVzZWRGaWVsZHM7XG4gICAgICAgIGlmICghc2tpcFVudXNlZENoZWNrICYmIGlzVW51c2VkICYmICEoc3VibWl0dGVyICYmIHN1Ym1pdHRlci5uYW1lID09IGtleSkgJiYgIWhpZGRlbikge1xuICAgICAgICAgIHBhcmFtcy5hcHBlbmQocHJlcGVuZEZvcm1EYXRhS2V5KGtleSwgXCJfdW51c2VkX1wiKSwgXCJcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB2YWwgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICBwYXJhbXMuYXBwZW5kKGtleSwgdmFsKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc3VibWl0dGVyICYmIGluamVjdGVkRWxlbWVudCkge1xuICAgICAgc3VibWl0dGVyLnBhcmVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoaW5qZWN0ZWRFbGVtZW50KTtcbiAgICB9XG4gICAgcmV0dXJuIHBhcmFtcy50b1N0cmluZygpO1xuICB9XG4gIHB1c2hFdmVudCh0eXBlLCBlbCwgdGFyZ2V0Q3R4LCBwaHhFdmVudCwgbWV0YSwgb3B0cyA9IHt9LCBvblJlcGx5KSB7XG4gICAgdGhpcy5wdXNoV2l0aFJlcGx5KFxuICAgICAgKG1heWJlUGF5bG9hZCkgPT4gdGhpcy5wdXRSZWYoW3sgZWwsIGxvYWRpbmc6IHRydWUsIGxvY2s6IHRydWUgfV0sIHBoeEV2ZW50LCB0eX
1BlLCB7XG4gICAgICAgIC4uLm9wdHMsXG4gICAgICAgIHBheWxvYWQ6IG1heWJlUGF5bG9hZD8ucGF5bG9hZFxuICAgICAgfSksXG4gICAgICBcImV2ZW50XCIsXG4gICAgICB7XG4gICAgICAgIHR5cGUsXG4gICAgICAgIGV2ZW50OiBwaHhFdmVudCxcbiAgICAgICAgdmFsdWU6IHRoaXMuZXh0cmFjdE1ldGEoZWwsIG1ldGEsIG9wdHMudmFsdWUpLFxuICAgICAgICBjaWQ6IHRoaXMudGFyZ2V0Q29tcG9uZW50SUQoZWwsIHRhcmdldEN0eCwgb3B0cylcbiAgICAgIH1cbiAgICApLnRoZW4oKHsgcmVwbHkgfSkgPT4gb25SZXBseSAmJiBvblJlcGx5KHJlcGx5KSkuY2F0Y2goKGVycm9yKSA9PiBsb2dFcnJvcihcIkZhaWxlZCB0byBwdXNoIGV2ZW50XCIsIGVycm9yKSk7XG4gIH1cbiAgcHVzaEZpbGVQcm9ncmVzcyhmaWxlRWwsIGVudHJ5UmVmLCBwcm9ncmVzcywgb25SZXBseSA9IGZ1bmN0aW9uKCkge1xuICB9KSB7XG4gICAgdGhpcy5saXZlU29ja2V0LndpdGhpbk93bmVycyhmaWxlRWwuZm9ybSwgKHZpZXcsIHRhcmdldEN0eCkgPT4ge1xuICAgICAgdmlldy5wdXNoV2l0aFJlcGx5KG51bGwsIFwicHJvZ3Jlc3NcIiwge1xuICAgICAgICBldmVudDogZmlsZUVsLmdldEF0dHJpYnV0ZSh2aWV3LmJpbmRpbmcoUEhYX1BST0dSRVNTKSksXG4gICAgICAgIHJlZjogZmlsZUVsLmdldEF0dHJpYnV0ZShQSFhfVVBMT0FEX1JFRiksXG4gICAgICAgIGVudHJ5X3JlZjogZW50cnlSZWYsXG4gICAgICAgIHByb2dyZXNzLFxuICAgICAgICBjaWQ6IHZpZXcudGFyZ2V0Q29tcG9uZW50SUQoZmlsZUVsLmZvcm0sIHRhcmdldEN0eClcbiAgICAgIH0pLnRoZW4oKCkgPT4gb25SZXBseSgpKS5jYXRjaCgoZXJyb3IpID0+IGxvZ0Vycm9yKFwiRmFpbGVkIHRvIHB1c2ggZmlsZSBwcm9ncmVzc1wiLCBlcnJvcikpO1xuICAgIH0pO1xuICB9XG4gIHB1c2hJbnB1dChpbnB1dEVsLCB0YXJnZXRDdHgsIGZvcmNlQ2lkLCBwaHhFdmVudCwgb3B0cywgY2FsbGJhY2spIHtcbiAgICBpZiAoIWlucHV0RWwuZm9ybSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZm9ybSBldmVudHMgcmVxdWlyZSB0aGUgaW5wdXQgdG8gYmUgaW5zaWRlIGEgZm9ybVwiKTtcbiAgICB9XG4gICAgbGV0IHVwbG9hZHM7XG4gICAgY29uc3QgY2lkID0gaXNDaWQoZm9yY2VDaWQpID8gZm9yY2VDaWQgOiB0aGlzLnRhcmdldENvbXBvbmVudElEKGlucHV0RWwuZm9ybSwgdGFyZ2V0Q3R4LCBvcHRzKTtcbiAgICBjb25zdCByZWZHZW5lcmF0b3IgPSAobWF5YmVQYXlsb2FkKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5wdXRSZWYoXG4gICAgICAgIFtcbiAgICAgICAgICB7IGVsOiBpbnB1dEVsLCBsb2FkaW5nOiB0cnVlLCBsb2NrOiB0cnVlIH0sXG4gICAgICAgICAgeyBlbDogaW5wdXRFbC5mb3JtLCBsb2FkaW5nOiB0cnVlLCBsb2NrOiB0cnVlIH1cbiAgICAgICAgXSxcbiAgICAgICAgcGh4RXZlbnQsXG4gICAgICAgIFwiY2hhbmdlXCIsXG4gICAgICAgIHsgLi4ub3B0cywgcGF5bG9hZDogbWF5YmVQYXlsb2FkPy5wYXlsb2FkIH1cbiAgICAgICk7XG4gICAgfTtcbiAgICBsZXQgZm9ybURhdGE7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuZXh0cmFjdE1ldGEoaW5wdXRFbC5mb3JtLCB7fSwgb3B0cy52YWx1ZSk7XG4gICAgY29uc3Qgc2VyaWFsaXplT3B0cyA9IHt9O1xuICAgIGlmIChpbnB1dEVsIGluc3RhbmNlb2YgSFRNTEJ1dHRvbkVsZW1lbnQpIHtcbiAgICAgIHNlcmlhbGl6ZU9wdHMuc3VibWl0dGVyID0gaW5wdXRFbDtcbiAgICB9XG4gICAgaWYgKGlucHV0RWwuZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhcImNoYW5nZVwiKSkpIHtcbiAgICAgIGZvcm1EYXRhID0gdGhpcy5zZXJpYWxpemVGb3JtKGlucHV0RWwuZm9ybSwgc2VyaWFsaXplT3B0cywgW1xuICAgICAgICBpbnB1dEVsLm5hbWVcbiAgICAgIF0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3JtRGF0YSA9IHRoaXMuc2VyaWFsaXplRm9ybShpbnB1dEVsLmZvcm0sIHNlcmlhbGl6ZU9wdHMpO1xuICAgIH1cbiAgICBpZiAoZG9tX2RlZmF1bHQuaXNVcGxvYWRJbnB1dChpbnB1dEVsKSAmJiBpbnB1dEVsLmZpbGVzICYmIGlucHV0RWwuZmlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgTGl2ZVVwbG9hZGVyLnRyYWNrRmlsZXMoaW5wdXRFbCwgQXJyYXkuZnJvbShpbnB1dEVsLmZpbGVzKSk7XG4gICAgfVxuICAgIHVwbG9hZHMgPSBMaXZlVXBsb2FkZXIuc2VyaWFsaXplVXBsb2FkcyhpbnB1dEVsKTtcbiAgICBjb25zdCBldmVudCA9IHtcbiAgICAgIHR5cGU6IFwiZm9ybVwiLFxuICAgICAgZXZlbnQ6IHBoeEV2ZW50LFxuICAgICAgdmFsdWU6IGZvcm1EYXRhLFxuICAgICAgbWV0YToge1xuICAgICAgICAvLyBubyB0YXJnZXQgd2FzIGltcGxpY2l0bHkgc2VudCBhcyBcInVuZGVmaW5lZFwiIGluIExWIDw9IDEuMC41LCB0aGVyZWZvcmVcbiAgICAgICAgLy8gd2UgaGF2ZSB0byBrZWVwIGl0LiBJbiAxLjAuNiB3ZSBzd2l0Y2hlZCBmcm9tIHBhc3NpbmcgbWV0YSBhcyBVUkwgZW5jb2RlZCBkYXRhXG4gICAgICAgIC8vIHRvIHBhc3NpbmcgaXQgZGlyZWN0bHkgaW4gdGhlIGV2ZW50LCBidXQgdGhlIEpTT04gZW5jb2RlIHdvdWxkIGRyb3Aga2V5cyB3aXRoXG4gICAgICAgIC8vIHVuZGVmaW5lZCB2YWx1ZXMuXG4gICAgICAgIF90YXJnZXQ6IG9wdHMuX3RhcmdldCB8fCBcInVuZGVmaW5lZFwiLFxuICAgICAgICAuLi5tZXRhXG4gICAgICB9LFxuICAgICAgdXBsb2FkcyxcbiAgICAgIGNpZFxuICAgIH07XG4gICAgdGhpcy5wdXNoV2l0aFJlcGx5KHJlZkdlbmVyYXRvciwgXCJldmVudFwiLCBldmVudCkudGhlbigoeyByZXNwIH0pID0+IHtcbiAgICAgIGlmIChkb21fZGVmYXVsdC5pc1VwbG9hZElucHV0KGlucHV0RWwpICYmIGRvbV9kZWZhdWx0LmlzQXV0b1VwbG9hZChpbnB1dEVsKSkge1xuICAgICAgICBFbGVtZW50UmVmLm9uVW5sb2NrKGlucHV0RWwsICgpID0+IHtcbiAgICAgICAgICBpZiAoTGl2ZVVwbG9hZGVyLmZpbGVzQXdhaXRpbmdQcmVmbGlnaHQoaW5wdXRFbCkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgW3JlZiwgX2Vsc10gPSByZWZHZW5lcmF0b3IoKTtcbiAgICAgICAgICAgI
1HRoaXMudW5kb1JlZnMocmVmLCBwaHhFdmVudCwgW2lucHV0RWwuZm9ybV0pO1xuICAgICAgICAgICAgdGhpcy51cGxvYWRGaWxlcyhcbiAgICAgICAgICAgICAgaW5wdXRFbC5mb3JtLFxuICAgICAgICAgICAgICBwaHhFdmVudCxcbiAgICAgICAgICAgICAgdGFyZ2V0Q3R4LFxuICAgICAgICAgICAgICByZWYsXG4gICAgICAgICAgICAgIGNpZCxcbiAgICAgICAgICAgICAgKF91cGxvYWRzKSA9PiB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2socmVzcCk7XG4gICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyQXdhaXRpbmdTdWJtaXQoaW5wdXRFbC5mb3JtLCBwaHhFdmVudCk7XG4gICAgICAgICAgICAgICAgdGhpcy51bmRvUmVmcyhyZWYsIHBoeEV2ZW50KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2socmVzcCk7XG4gICAgICB9XG4gICAgfSkuY2F0Y2goKGVycm9yKSA9PiBsb2dFcnJvcihcIkZhaWxlZCB0byBwdXNoIGlucHV0IGV2ZW50XCIsIGVycm9yKSk7XG4gIH1cbiAgdHJpZ2dlckF3YWl0aW5nU3VibWl0KGZvcm1FbCwgcGh4RXZlbnQpIHtcbiAgICBjb25zdCBhd2FpdGluZ1N1Ym1pdCA9IHRoaXMuZ2V0U2NoZWR1bGVkU3VibWl0KGZvcm1FbCk7XG4gICAgaWYgKGF3YWl0aW5nU3VibWl0KSB7XG4gICAgICBjb25zdCBbX2VsLCBfcmVmLCBfb3B0cywgY2FsbGJhY2tdID0gYXdhaXRpbmdTdWJtaXQ7XG4gICAgICB0aGlzLmNhbmNlbFN1Ym1pdChmb3JtRWwsIHBoeEV2ZW50KTtcbiAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxuICB9XG4gIGdldFNjaGVkdWxlZFN1Ym1pdChmb3JtRWwpIHtcbiAgICByZXR1cm4gdGhpcy5mb3JtU3VibWl0cy5maW5kKFxuICAgICAgKFtlbCwgX3JlZiwgX29wdHMsIF9jYWxsYmFja10pID0+IGVsLmlzU2FtZU5vZGUoZm9ybUVsKVxuICAgICk7XG4gIH1cbiAgc2NoZWR1bGVTdWJtaXQoZm9ybUVsLCByZWYsIG9wdHMsIGNhbGxiYWNrKSB7XG4gICAgaWYgKHRoaXMuZ2V0U2NoZWR1bGVkU3VibWl0KGZvcm1FbCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICB0aGlzLmZvcm1TdWJtaXRzLnB1c2goW2Zvcm1FbCwgcmVmLCBvcHRzLCBjYWxsYmFja10pO1xuICB9XG4gIGNhbmNlbFN1Ym1pdChmb3JtRWwsIHBoeEV2ZW50KSB7XG4gICAgdGhpcy5mb3JtU3VibWl0cyA9IHRoaXMuZm9ybVN1Ym1pdHMuZmlsdGVyKFxuICAgICAgKFtlbCwgcmVmLCBfb3B0cywgX2NhbGxiYWNrXSkgPT4ge1xuICAgICAgICBpZiAoZWwuaXNTYW1lTm9kZShmb3JtRWwpKSB7XG4gICAgICAgICAgdGhpcy51bmRvUmVmcyhyZWYsIHBoeEV2ZW50KTtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICApO1xuICB9XG4gIGRpc2FibGVGb3JtKGZvcm1FbCwgcGh4RXZlbnQsIG9wdHMgPSB7fSkge1xuICAgIGNvbnN0IGZpbHRlcklnbm9yZWQgPSAoZWwpID0+IHtcbiAgICAgIGNvbnN0IHVzZXJJZ25vcmVkID0gY2xvc2VzdFBoeEJpbmRpbmcoXG4gICAgICAgIGVsLFxuICAgICAgICBgJHt0aGlzLmJpbmRpbmcoUEhYX1VQREFURSl9PWlnbm9yZWAsXG4gICAgICAgIGVsLmZvcm1cbiAgICAgICk7XG4gICAgICByZXR1cm4gISh1c2VySWdub3JlZCB8fCBjbG9zZXN0UGh4QmluZGluZyhlbCwgXCJkYXRhLXBoeC11cGRhdGU9aWdub3JlXCIsIGVsLmZvcm0pKTtcbiAgICB9O1xuICAgIGNvbnN0IGZpbHRlckRpc2FibGVzID0gKGVsKSA9PiB7XG4gICAgICByZXR1cm4gZWwuaGFzQXR0cmlidXRlKHRoaXMuYmluZGluZyhQSFhfRElTQUJMRV9XSVRIKSk7XG4gICAgfTtcbiAgICBjb25zdCBmaWx0ZXJCdXR0b24gPSAoZWwpID0+IGVsLnRhZ05hbWUgPT0gXCJCVVRUT05cIjtcbiAgICBjb25zdCBmaWx0ZXJJbnB1dCA9IChlbCkgPT4gW1wiSU5QVVRcIiwgXCJURVhUQVJFQVwiXS5pbmNsdWRlcyhlbC50YWdOYW1lKTtcbiAgICBjb25zdCBmb3JtRWxlbWVudHMgPSBBcnJheS5mcm9tKGZvcm1FbC5lbGVtZW50cyk7XG4gICAgY29uc3QgZGlzYWJsZXMgPSBmb3JtRWxlbWVudHMuZmlsdGVyKGZpbHRlckRpc2FibGVzKTtcbiAgICBjb25zdCBidXR0b25zID0gZm9ybUVsZW1lbnRzLmZpbHRlcihmaWx0ZXJCdXR0b24pLmZpbHRlcihmaWx0ZXJJZ25vcmVkKTtcbiAgICBjb25zdCBpbnB1dHMgPSBmb3JtRWxlbWVudHMuZmlsdGVyKGZpbHRlcklucHV0KS5maWx0ZXIoZmlsdGVySWdub3JlZCk7XG4gICAgYnV0dG9ucy5mb3JFYWNoKChidXR0b24pID0+IHtcbiAgICAgIGJ1dHRvbi5zZXRBdHRyaWJ1dGUoUEhYX0RJU0FCTEVELCBidXR0b24uZGlzYWJsZWQudG9TdHJpbmcoKSk7XG4gICAgICBidXR0b24uZGlzYWJsZWQgPSB0cnVlO1xuICAgIH0pO1xuICAgIGlucHV0cy5mb3JFYWNoKChpbnB1dCkgPT4ge1xuICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKFBIWF9SRUFET05MWSwgaW5wdXQucmVhZE9ubHkudG9TdHJpbmcoKSk7XG4gICAgICBpbnB1dC5yZWFkT25seSA9IHRydWU7XG4gICAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50ICYmIGlucHV0LmZpbGVzKSB7XG4gICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZShQSFhfRElTQUJMRUQsIGlucHV0LmRpc2FibGVkLnRvU3RyaW5nKCkpO1xuICAgICAgICBpbnB1dC5kaXNhYmxlZCA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgZm9ybUVscyA9IGRpc2FibGVzLmNvbmNhdChidXR0b25zKS5jb25jYXQoaW5wdXRzKS5tYXAoKGVsKSA9PiB7XG4gICAgICByZXR1cm4geyBlbCwgbG9hZGluZzogdHJ1ZSwgbG9jazogdHJ1ZSB9O1xuICAgIH0pO1xuICAgIGNvbnN0IGVscyA9IFtcbiAgICAgIHsgZWw6IGZvcm1FbCwgbG9hZGluZzogdHJ1ZSwgbG9jazogZmFsc2UgfSxcbiAgICAgIC4uLmZvcm1FbHNcbiAgICBdLnJldmVyc2UoKTtcbiAgICByZXR1cm4gdGhpcy5wdXRSZWYoZWxzLCBwaHhFdmVudCwgXCJzdWJtaXRcIiwgb3B0cyk7XG4gIH1cbiAgcHVzaEZvcm1TdWJtaXQoZm9ybUVsLCB0YXJnZXRDdHgsIHBoeEV2ZW50LCBzdWJtaXR0ZXIsIG9wdHMsIG9uUmVwbHkpIHtcbiAgICBjb25zdCByZWZHZW5lcmF0b3IgPSAobWF5YmVQYXlsb2FkKSA9PiB0aGlzLmRpc2FibGVGb3JtKGZvcm1FbCwgcGh4RXZlbnQsIHtcbiAgICAgIC4uLm9wdHMsXG4gICAgICBmb3JtOiBmb3JtRWwsXG4gICAgICBwYXlsb2FkOiBtYXliZVBheWxvYWQ/LnBheWxvYWQsXG4gICAgICBzdWJtaXR0ZXJcbiAgICB9KTtcbiAgICBkb21fZGVmYXVsdC5wdXRQcml2YXRlKGZvcm1FbCwgXCJzdWJtaXR0ZXJcIiwgc3VibWl0dGVyKTtcbiAgICBjb25zdCBjaWQgPSB0aGlzLnRhcmdldENvbXBvbmVudElEKGZvcm1FbCwgdGFyZ2V0Q3R4KTtcbiAgICBpZiAoTGl2ZVVwbG9hZGVyLmhhc1VwbG9hZHNJblByb2dyZXNzKGZvcm1FbCkpIHtcbiAgICAgIGNvbnN0IFtyZWYsIF9lbHNdID0gcmVmR2VuZXJhdG9yKCk7XG4gICAgICBjb25zdCBwdXNoID0gKCkgPT4gdGhpcy5wdXNoRm9ybVN1Ym1pdChcbiAgICAgICAgZm9ybUVsLFxuICAgICAgICB0YXJnZXRDdHgsXG4gICAgICAgI
1HBoeEV2ZW50LFxuICAgICAgICBzdWJtaXR0ZXIsXG4gICAgICAgIG9wdHMsXG4gICAgICAgIG9uUmVwbHlcbiAgICAgICk7XG4gICAgICByZXR1cm4gdGhpcy5zY2hlZHVsZVN1Ym1pdChmb3JtRWwsIHJlZiwgb3B0cywgcHVzaCk7XG4gICAgfSBlbHNlIGlmIChMaXZlVXBsb2FkZXIuaW5wdXRzQXdhaXRpbmdQcmVmbGlnaHQoZm9ybUVsKS5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBbcmVmLCBlbHNdID0gcmVmR2VuZXJhdG9yKCk7XG4gICAgICBjb25zdCBwcm94eVJlZkdlbiA9ICgpID0+IFtyZWYsIGVscywgb3B0c107XG4gICAgICB0aGlzLnVwbG9hZEZpbGVzKGZvcm1FbCwgcGh4RXZlbnQsIHRhcmdldEN0eCwgcmVmLCBjaWQsIChfdXBsb2FkcykgPT4ge1xuICAgICAgICBpZiAoTGl2ZVVwbG9hZGVyLmlucHV0c0F3YWl0aW5nUHJlZmxpZ2h0KGZvcm1FbCkubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnVuZG9SZWZzKHJlZiwgcGh4RXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1ldGEgPSB0aGlzLmV4dHJhY3RNZXRhKGZvcm1FbCwge30sIG9wdHMudmFsdWUpO1xuICAgICAgICBjb25zdCBmb3JtRGF0YSA9IHRoaXMuc2VyaWFsaXplRm9ybShmb3JtRWwsIHsgc3VibWl0dGVyIH0pO1xuICAgICAgICB0aGlzLnB1c2hXaXRoUmVwbHkocHJveHlSZWZHZW4sIFwiZXZlbnRcIiwge1xuICAgICAgICAgIHR5cGU6IFwiZm9ybVwiLFxuICAgICAgICAgIGV2ZW50OiBwaHhFdmVudCxcbiAgICAgICAgICB2YWx1ZTogZm9ybURhdGEsXG4gICAgICAgICAgbWV0YSxcbiAgICAgICAgICBjaWRcbiAgICAgICAgfSkudGhlbigoeyByZXNwIH0pID0+IG9uUmVwbHkocmVzcCkpLmNhdGNoKChlcnJvcikgPT4gbG9nRXJyb3IoXCJGYWlsZWQgdG8gcHVzaCBmb3JtIHN1Ym1pdFwiLCBlcnJvcikpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICghKGZvcm1FbC5oYXNBdHRyaWJ1dGUoUEhYX1JFRl9TUkMpICYmIGZvcm1FbC5jbGFzc0xpc3QuY29udGFpbnMoXCJwaHgtc3VibWl0LWxvYWRpbmdcIikpKSB7XG4gICAgICBjb25zdCBtZXRhID0gdGhpcy5leHRyYWN0TWV0YShmb3JtRWwsIHt9LCBvcHRzLnZhbHVlKTtcbiAgICAgIGNvbnN0IGZvcm1EYXRhID0gdGhpcy5zZXJpYWxpemVGb3JtKGZvcm1FbCwgeyBzdWJtaXR0ZXIgfSk7XG4gICAgICB0aGlzLnB1c2hXaXRoUmVwbHkocmVmR2VuZXJhdG9yLCBcImV2ZW50XCIsIHtcbiAgICAgICAgdHlwZTogXCJmb3JtXCIsXG4gICAgICAgIGV2ZW50OiBwaHhFdmVudCxcbiAgICAgICAgdmFsdWU6IGZvcm1EYXRhLFxuICAgICAgICBtZXRhLFxuICAgICAgICBjaWRcbiAgICAgIH0pLnRoZW4oKHsgcmVzcCB9KSA9PiBvblJlcGx5KHJlc3ApKS5jYXRjaCgoZXJyb3IpID0+IGxvZ0Vycm9yKFwiRmFpbGVkIHRvIHB1c2ggZm9ybSBzdWJtaXRcIiwgZXJyb3IpKTtcbiAgICB9XG4gIH1cbiAgdXBsb2FkRmlsZXMoZm9ybUVsLCBwaHhFdmVudCwgdGFyZ2V0Q3R4LCByZWYsIGNpZCwgb25Db21wbGV0ZSkge1xuICAgIGNvbnN0IGpvaW5Db3VudEF0VXBsb2FkID0gdGhpcy5qb2luQ291bnQ7XG4gICAgY29uc3QgaW5wdXRFbHMgPSBMaXZlVXBsb2FkZXIuYWN0aXZlRmlsZUlucHV0cyhmb3JtRWwpO1xuICAgIGxldCBudW1GaWxlSW5wdXRzSW5Qcm9ncmVzcyA9IGlucHV0RWxzLmxlbmd0aDtcbiAgICBpbnB1dEVscy5mb3JFYWNoKChpbnB1dEVsKSA9PiB7XG4gICAgICBjb25zdCB1cGxvYWRlciA9IG5ldyBMaXZlVXBsb2FkZXIoaW5wdXRFbCwgdGhpcywgKCkgPT4ge1xuICAgICAgICBudW1GaWxlSW5wdXRzSW5Qcm9ncmVzcy0tO1xuICAgICAgICBpZiAobnVtRmlsZUlucHV0c0luUHJvZ3Jlc3MgPT09IDApIHtcbiAgICAgICAgICBvbkNvbXBsZXRlKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgY29uc3QgZW50cmllcyA9IHVwbG9hZGVyLmVudHJpZXMoKS5tYXAoKGVudHJ5KSA9PiBlbnRyeS50b1ByZWZsaWdodFBheWxvYWQoKSk7XG4gICAgICBpZiAoZW50cmllcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgbnVtRmlsZUlucHV0c0luUHJvZ3Jlc3MtLTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgcmVmOiBpbnB1dEVsLmdldEF0dHJpYnV0ZShQSFhfVVBMT0FEX1JFRiksXG4gICAgICAgIGVudHJpZXMsXG4gICAgICAgIGNpZDogdGhpcy50YXJnZXRDb21wb25lbnRJRChpbnB1dEVsLmZvcm0sIHRhcmdldEN0eClcbiAgICAgIH07XG4gICAgICB0aGlzLmxvZyhcInVwbG9hZFwiLCAoKSA9PiBbXCJzZW5kaW5nIHByZWZsaWdodCByZXF1ZXN0XCIsIH
1BheWxvYWRdKTtcbiAgICAgIHRoaXMucHVzaFdpdGhSZXBseShudWxsLCBcImFsbG93X3VwbG9hZFwiLCBwYXlsb2FkKS50aGVuKCh7IHJlc3AgfSkgPT4ge1xuICAgICAgICB0aGlzLmxvZyhcInVwbG9hZFwiLCAoKSA9PiBbXCJnb3QgcHJlZmxpZ2h0IHJlc3BvbnNlXCIsIHJlc3BdKTtcbiAgICAgICAgdXBsb2FkZXIuZW50cmllcygpLmZvckVhY2goKGVudHJ5KSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3AuZW50cmllcyAmJiAhcmVzcC5lbnRyaWVzW2VudHJ5LnJlZl0pIHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlRmFpbGVkRW50cnlQcmVmbGlnaHQoXG4gICAgICAgICAgICAgIGVudHJ5LnJlZixcbiAgICAgICAgICAgICAgXCJmYWlsZWQgcHJlZmxpZ2h0XCIsXG4gICAgICAgICAgICAgIHVwbG9hZGVyXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChyZXNwLmVycm9yIHx8IE9iamVjdC5rZXlzKHJlc3AuZW50cmllcykubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhpcy51bmRvUmVmcyhyZWYsIHBoeEV2ZW50KTtcbiAgICAgICAgICBjb25zdCBlcnJvcnMgPSByZXNwLmVycm9yIHx8IFtdO1xuICAgICAgICAgIGVycm9ycy5tYXAoKFtlbnRyeV9yZWYsIHJlYXNvbl0pID0+IHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlRmFpbGVkRW50cnlQcmVmbGlnaHQoZW50cnlfcmVmLCByZWFzb24sIHVwbG9hZGVyKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBvbkVycm9yID0gKGNhbGxiYWNrKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNoYW5uZWwub25FcnJvcigoKSA9PiB7XG4gICAgICAgICAgICAgIGlmICh0aGlzLmpvaW5Db3VudCA9PT0gam9pbkNvdW50QXRVcGxvYWQpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9O1xuICAgICAgICAgIHVwbG9hZGVyLmluaXRBZGFwdGVyVXBsb2FkKHJlc3AsIG9uRXJyb3IsIHRoaXMubGl2ZVNvY2tldCk7XG4gICAgICAgIH1cbiAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4gbG9nRXJyb3IoXCJGYWlsZWQgdG8gcHVzaCB1cGxvYWRcIiwgZXJyb3IpKTtcbiAgICB9KTtcbiAgfVxuICBoYW5kbGVGYWlsZWRFbnRyeVByZWZsaWdodCh1cGxvYWRSZWYsIHJlYXNvbiwgdXBsb2FkZXIpIHtcbiAgICBpZiAodXBsb2FkZXIuaXNBdXRvVXBsb2FkKCkpIHtcbiAgICAgIGNvbnN0IGVudHJ5ID0gdXBsb2FkZXIuZW50cmllcygpLmZpbmQoKGVudHJ5MikgPT4gZW50cnkyLnJlZiA9PT0gdXBsb2FkUmVmLnRvU3RyaW5nKCkpO1xuICAgICAgaWYgKGVudHJ5KSB7XG4gICAgICAgIGVudHJ5LmNhbmNlbCgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB1cGxvYWRlci5lbnRyaWVzKCkubWFwKChlbnRyeSkgPT4gZW50cnkuY2FuY2VsKCkpO1xuICAgIH1cbiAgICB0aGlzLmxvZyhcInVwbG9hZFwiLCAoKSA9PiBbYGVycm9yIGZvciBlbnRyeSAke3VwbG9hZFJlZn1gLCByZWFzb25dKTtcbiAgfVxuICBkaXNwYXRjaFVwbG9hZHModGFyZ2V0Q3R4LCBuYW1lLCBmaWxlc09yQmxvYnMpIHtcbiAgICBjb25zdCB0YXJnZXRFbGVtZW50ID0gdGhpcy50YXJnZXRDdHhFbGVtZW50KHRhcmdldEN0eCkgfHwgdGhpcy5lbDtcbiAgICBjb25zdCBpbnB1dHMgPSBkb21fZGVmYXVsdC5maW5kVXBsb2FkSW5wdXRzKHRhcmdldEVsZW1lbnQpLmZpbHRlcihcbiAgICAgIChlbCkgPT4gZWwubmFtZSA9PT0gbmFtZVxuICAgICk7XG4gICAgaWYgKGlucHV0cy5sZW5ndGggPT09IDApIHtcbiAgICAgIGxvZ0Vycm9yKGBubyBsaXZlIGZpbGUgaW5wdXRzIGZvdW5kIG1hdGNoaW5nIHRoZSBuYW1lIFwiJHtuYW1lfVwiYCk7XG4gICAgfSBlbHNlIGlmIChpbnB1dHMubGVuZ3RoID4gMSkge1xuICAgICAgbG9nRXJyb3IoYGR1cGxpY2F0ZSBsaXZlIGZpbGUgaW5wdXRzIGZvdW5kIG1hdGNoaW5nIHRoZSBuYW1lIFwiJHtuYW1lfVwiYCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRvbV9kZWZhdWx0LmRpc3BhdGNoRXZlbnQoaW5wdXRzWzBdLCBQSFhfVFJBQ0tfVVBMT0FEUywge1xuICAgICAgICBkZXRhaWw6IHsgZmlsZXM6IGZpbGVzT3JCbG9icyB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbiAgdGFyZ2V0Q3R4RWxlbWVudCh0YXJnZXRDdHgpIHtcbiAgICBpZiAoaXNDaWQodGFyZ2V0Q3R4KSkge1xuICAgICAgY29uc3QgdGFyZ2V0ID0gZG9tX2RlZmF1bHQuZmluZENvbXBvbmVudCh0aGlzLmlkLCB0YXJnZXRDdHgpO1xuICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9IGVsc2UgaWYgKHRhcmdldEN0eCkge1xuICAgICAgcmV0dXJuIHRhcmdldEN0eDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG4gIHB1c2hGb3JtUmVjb3Zlcnkob2xkRm9ybSwgbmV3Rm9ybSwgdGVtcGxhdGVEb20sIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgcGh4Q2hhbmdlID0gdGhpcy5iaW5kaW5nKFwiY2hhbmdlXCIpO1xuICAgIGNvbnN0IHBoeFRhcmdldCA9IG5ld0Zvcm0uZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhcInRhcmdldFwiKSkgfHwgbmV3Rm9ybTtcbiAgICBjb25zdCBwaHhFdmVudCA9IG5ld0Zvcm0uZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhQSFhfQVVUT19SRUNPVkVSKSkgfHwgbmV3Rm9ybS5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFwiY2hhbmdlXCIpKTtcbiAgICBjb25zdCBpbnB1dHMgPSBBcnJheS5mcm9tKG9sZEZvcm0uZWxlbWVudHMpLmZpbHRlcihcbiAgICAgIChlbCkgPT4gZG9tX2RlZmF1bHQuaXNGb3JtQXNzb2NpYXRlZChlbCkgJiYgZWwubmFtZSAmJiAhZWwuaGFzQXR0cmlidXRlKHBoeENoYW5nZSlcbiAgICApO1xuICAgIGlmIChpbnB1dHMubGVuZ3RoID09PSAwKSB7XG4gICAgICBjYWxsYmFjaygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpbnB1dHMuZm9yRWFjaChcbiAgICAgIChpbnB1dDIpID0+IGlucHV0Mi5oYXNBdHRyaWJ1dGUoUEhYX1VQTE9BRF9SRUYpICYmIExpdmVVcGxvYWRlci5jbGVhckZpbGVzKGlucHV0MilcbiAgICApO
11xuICAgIGNvbnN0IGlucHV0ID0gaW5wdXRzLmZpbmQoKGVsKSA9PiBlbC50eXBlICE9PSBcImhpZGRlblwiKSB8fCBpbnB1dHNbMF07XG4gICAgbGV0IHBlbmRpbmcgPSAwO1xuICAgIHRoaXMud2l0aGluVGFyZ2V0cyhcbiAgICAgIHBoeFRhcmdldCxcbiAgICAgICh0YXJnZXRWaWV3LCB0YXJnZXRDdHgpID0+IHtcbiAgICAgICAgY29uc3QgY2lkID0gdGhpcy50YXJnZXRDb21wb25lbnRJRChuZXdGb3JtLCB0YXJnZXRDdHgpO1xuICAgICAgICBwZW5kaW5nKys7XG4gICAgICAgIGxldCBlID0gbmV3IEN1c3RvbUV2ZW50KFwicGh4OmZvcm0tcmVjb3ZlcnlcIiwge1xuICAgICAgICAgIGRldGFpbDogeyBzb3VyY2VFbGVtZW50OiBvbGRGb3JtIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGpzX2RlZmF1bHQuZXhlYyhlLCBcImNoYW5nZVwiLCBwaHhFdmVudCwgdGhpcywgaW5wdXQsIFtcbiAgICAgICAgICBcInB1c2hcIixcbiAgICAgICAgICB7XG4gICAgICAgICAgICBfdGFyZ2V0OiBpbnB1dC5uYW1lLFxuICAgICAgICAgICAgdGFyZ2V0VmlldyxcbiAgICAgICAgICAgIHRhcmdldEN0eCxcbiAgICAgICAgICAgIG5ld0NpZDogY2lkLFxuICAgICAgICAgICAgY2FsbGJhY2s6ICgpID0+IHtcbiAgICAgICAgICAgICAgcGVuZGluZy0tO1xuICAgICAgICAgICAgICBpZiAocGVuZGluZyA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIF0pO1xuICAgICAgfSxcbiAgICAgIHRlbXBsYXRlRG9tXG4gICAgKTtcbiAgfVxuICBwdXNoTGlua1BhdGNoKGUsIGhyZWYsIHRhcmdldEVsLCBjYWxsYmFjaykge1xuICAgIGNvbnN0IGxpbmtSZWYgPSB0aGlzLmxpdmVTb2NrZXQuc2V0UGVuZGluZ0xpbmsoaHJlZik7XG4gICAgY29uc3QgbG9hZGluZyA9IGUuaXNUcnVzdGVkICYmIGUudHlwZSAhPT0gXCJwb3BzdGF0ZVwiO1xuICAgIGNvbnN0IHJlZkdlbiA9IHRhcmdldEVsID8gKCkgPT4gdGhpcy5wdXRSZWYoXG4gICAgICBbeyBlbDogdGFyZ2V0RWwsIGxvYWRpbmcsIGxvY2s6IHRydWUgfV0sXG4gICAgICBudWxsLFxuICAgICAgXCJjbGlja1wiXG4gICAgKSA6IG51bGw7XG4gICAgY29uc3QgZmFsbGJhY2sgPSAoKSA9PiB0aGlzLmxpdmVTb2NrZXQucmVkaXJlY3Qod2luZG93LmxvY2F0aW9uLmhyZWYsIG51bGwsIG51bGwpO1xuICAgIGNvbnN0IHVybCA9IGhyZWYuc3RhcnRzV2l0aChcIi9cIikgPyBgJHtsb2NhdGlvbi5wcm90b2NvbH0vLyR7bG9jYXRpb24uaG9zdH0ke2hyZWZ9YCA6IGhyZWY7XG4gICAgdGhpcy5wdXNoV2l0aFJlcGx5KHJlZkdlbiwgXCJsaXZlX3BhdGNoXCIsIHsgdXJsIH0pLnRoZW4oXG4gICAgICAoeyByZXNwIH0pID0+IHtcbiAgICAgICAgdGhpcy5saXZlU29ja2V0LnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwLmxpbmtfcmVkaXJlY3QpIHtcbiAgICAgICAgICAgIHRoaXMubGl2ZVNvY2tldC5yZXBsYWNlTWFpbihocmVmLCBudWxsLCBjYWxsYmFjaywgbGlua1JlZik7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXNwLnJlZGlyZWN0KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmxpdmVTb2NrZXQuY29tbWl0UGVuZGluZ0xpbmsobGlua1JlZikpIHtcbiAgICAgICAgICAgICAgdGhpcy5ocmVmID0gaHJlZjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuYXBwbHlQZW5kaW5nVXBkYXRlcygpO1xuICAgICAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2sobGlua1JlZik7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICAoeyBlcnJvcjogX2Vycm9yLCB0aW1lb3V0OiBfdGltZW91dCB9KSA9PiBmYWxsYmFjaygpXG4gICAgKTtcbiAgfVxuICBnZXRGb3Jtc0ZvclJlY292ZXJ5KCkge1xuICAgIGlmICh0aGlzLmpvaW5Db3VudCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjb25zdCBwaHhDaGFuZ2UgPSB0aGlzLmJpbmRpbmcoXCJjaGFuZ2VcIik7XG4gICAgcmV0dXJuIGRvbV9kZWZhdWx0LmFsbChcbiAgICAgIGRvY3VtZW50LFxuICAgICAgYCMke0NTUy5lc2NhcGUodGhpcy5pZCl9IGZvcm1bJHtwaHhDaGFuZ2V9XSwgWyR7UEhYX1RFTEVQT1JURURfUkVGfT1cIiR7Q1NTLmVzY2FwZSh0aGlzLmlkKX1cIl0gZm9ybVske3BoeENoYW5nZX1dYFxuICAgICkuZmlsdGVyKChmb3JtKSA9PiBmb3JtIGluc3RhbmNlb2YgSFRNTEZvcm1FbGVtZW50KS5maWx0ZXIoKGZvcm0p
1ID0+IGZvcm0uaWQpLmZpbHRlcigoZm9ybSkgPT4gZm9ybS5lbGVtZW50cy5sZW5ndGggPiAwKS5maWx0ZXIoXG4gICAgICAoZm9ybSkgPT4gZm9ybS5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFBIWF9BVVRPX1JFQ09WRVIpKSAhPT0gXCJpZ25vcmVcIlxuICAgICkubWFwKChmb3JtKSA9PiB7XG4gICAgICBjb25zdCBjbG9uZWRGb3JtID0gZm9ybS5jbG9uZU5vZGUodHJ1ZSk7XG4gICAgICBtb3JwaGRvbV9lc21fZGVmYXVsdChjbG9uZWRGb3JtLCBmb3JtLCB7XG4gICAgICAgIG9uQmVmb3JlRWxVcGRhdGVkOiAoZnJvbUVsLCB0b0VsKSA9PiB7XG4gICAgICAgICAgZG9tX2RlZmF1bHQuY29weVByaXZhdGVzKGZyb21FbCwgdG9FbCk7XG4gICAgICAgICAgaWYgKGZyb21FbC5nZXRBdHRyaWJ1dGUoXCJmb3JtXCIpID09PSBmb3JtLmlkICYmIGZyb21FbC5wYXJlbnROb2RlKSB7XG4gICAgICAgICAgICBmcm9tRWwucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChmcm9tRWwpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjb25zdCBleHRlcm5hbEVsZW1lbnRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgYFtmb3JtPVwiJHtDU1MuZXNjYXBlKGZvcm0uaWQpfVwiXWBcbiAgICAgICk7XG4gICAgICBBcnJheS5mcm9tKGV4dGVybmFsRWxlbWVudHMpLmZvckVhY2goKGVsKSA9PiB7XG4gICAgICAgIGNvbnN0IGNsb25lZEVsID0gZWwuY2xvbmVOb2RlKHRydWUpO1xuICAgICAgICBtb3JwaGRvbV9lc21fZGVmYXVsdChjbG9uZWRFbCwgZWwpO1xuICAgICAgICBkb21fZGVmYXVsdC5jb3B5UHJpdmF0ZXMoY2xvbmVkRWwsIGVsKTtcbiAgICAgICAgY2xvbmVkRWwucmVtb3ZlQXR0cmlidXRlKFwiZm9ybVwiKTtcbiAgICAgICAgY2xvbmVkRm9ybS5hcHBlbmRDaGlsZChjbG9uZWRFbCk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBjbG9uZWRGb3JtO1xuICAgIH0pLnJlZHVjZSgoYWNjLCBmb3JtKSA9PiB7XG4gICAgICBhY2NbZm9ybS5pZF0gPSBmb3JtO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSk7XG4gIH1cbiAgbWF5YmVQdXNoQ29tcG9uZW50c0Rlc3Ryb3llZChkZXN0cm95ZWRDSURzKSB7XG4gICAgbGV0IHdpbGxEZXN0cm95Q0lEcyA9IGRlc3Ryb3llZENJRHMuZmlsdGVyKChjaWQpID0+IHtcbiAgICAgIHJldHVybiBkb21fZGVmYXVsdC5maW5kQ29tcG9uZW50KHRoaXMuaWQsIGNpZCkgPT09IG51bGw7XG4gICAgfSk7XG4gICAgY29uc3Qgb25FcnJvciA9IChlcnJvcikgPT4ge1xuICAgICAgaWYgKCF0aGlzLmlzRGVzdHJveWVkKCkpIHtcbiAgICAgICAgbG9nRXJyb3IoXCJGYWlsZWQgdG8gcHVzaCBjb21wb25lbnRzIGRlc3Ryb3llZFwiLCBlcnJvcik7XG4gICAgICB9XG4gICAgfTtcbiAgICBpZiAod2lsbERlc3Ryb3lDSURzLmxlbmd0aCA+IDApIHtcbiAgICAgIHdpbGxEZXN0cm95Q0lEcy5mb3JFYWNoKChjaWQpID0+IHRoaXMucmVuZGVyZWQucmVzZXRSZW5kZXIoY2lkKSk7XG4gICAgICB0aGlzLnB1c2hXaXRoUmVwbHkobnVsbCwgXCJjaWRzX3dpbGxfZGVzdHJveVwiLCB7IGNpZHM6IHdpbGxEZXN0cm95Q0lEcyB9KS50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5saXZlU29ja2V0LnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgICAgIGxldCBjb21wbGV0ZWx5RGVzdHJveUNJRHMgPSB3aWxsRGVzdHJveUNJRHMuZmlsdGVyKChjaWQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBkb21fZGVmYXVsdC5maW5kQ29tcG9uZW50KHRoaXMuaWQsIGNpZCkgPT09IG51bGw7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKGNvbXBsZXRlbHlEZXN0cm95Q0lEcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLnB1c2hXaXRoUmVwbHkobnVsbCwgXCJjaWRzX2Rlc3Ryb3llZFwiLCB7XG4gICAgICAgICAgICAgIGNpZHM6IGNvbXBsZXRlbHlEZXN0cm95Q0lEc1xuICAgICAgICAgICAgfSkudGhlbigoeyByZXNwIH0pID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlZC5wcnVuZUNJRHMocmVzcC5jaWRzKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKG9uRXJyb3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KS5jYXRjaChvbkVycm9yKTtcbiAgICB9XG4gIH1cbiAgb3duc0VsZW1lbnQoZWwpIHtcbiAgICBsZXQgcGFyZW50Vmlld0VsID0gZG9tX2RlZmF1bHQuY2xvc2VzdFZpZXdFbChlbCk7XG4gICAgcmV0dXJuIGVsLmdldEF0dHJpYnV0ZShQSFhfUEFSRU5UX0lEKSA9PT0gdGhpcy5pZCB8fCBwYXJlbnRWaWV3RWwgJiYgcGFyZW50Vmlld0VsLmlkID09PSB0aGlzLmlkIHx8ICFwYXJlbnRWaWV3RWwgJiYgdGhpcy5pc0RlYWQ7XG4gIH1cbiAgc3VibWl0Rm9ybShmb3JtLCB0YXJnZXRDdHgsIHBoeEV2ZW50LCBzdWJtaXR0ZXIsIG9wdHMgPSB7fSkge1xuICAgIGRvbV9kZWZhdWx0LnB1dFByaXZhdGUoZm9ybSwgUEhYX0hBU19TVUJNSVRURUQsIHRydWUpO1xuICAgIGNvbnN0IGlucHV0cyA9IEFycmF5LmZyb20oZm9ybS5lbGVtZW50cyk7XG4gICAgaW5wdXRzLmZvckVhY2goKGlucHV0KSA9PiBkb21fZGVmYXVsdC5wdXRQcml2YXRlKGlucHV0LCBQSFhfSEFTX1NVQk1JVFRFRCwgdHJ1ZSkpO1xuICAgIHRoaXMubGl2ZVNvY2tldC5ibHVyQWN0aXZlRWxlbWVudCgpO1xuICAgIHRoaXMucHVzaEZvcm1TdWJtaXQoZm9ybSwgdGFyZ2V0Q3R4LCBwaHhFdmVudCwgc3VibWl0dGVyLCBvcHRzLCAoKSA9PiB7XG4gICAgICB0aGlzLmxpdmVTb2NrZXQucmVzdG9yZVByZXZpb3VzbHlBY3RpdmVGb2N1cygpO1xuICAgIH0pO1xuICB9XG4gIGJpbmRpbmcoa2luZCkge1xuICAgIHJldHVybiB0aGlzLmxpdmVTb2NrZXQuYmluZGluZyhraW5kKTtcbiAgfVxuICAvLyBwaHgtcG9ydGFsXG4gIHB1c2hQb3J0YWxFbGVtZW50SWQoaWQpIHtcbiAgICB0aGlzLnBvcnRhbEVsZW1lbnRJZHMuYWRkKGlkKTtcbiAgfVxuICBkcm9wUG9ydGFsRWxlbWVudElkKGlkKSB7XG4gICAgdGhpcy5wb3J0YWxFbGVtZW50SWRzLmRlbGV0ZShpZCk7XG4gIH1cbiAgZGVzdHJveVBvcnRhbEVsZW1lbnRzKCkge1xuICAgIGlmICghdGhpcy5saXZlU29ja2V0LnVubG9hZGVkKSB7XG4gICAgICB0aGlzLnBvcnRhbEVsZW1lbnRJZHMuZm9yRWFjaCgoaWQpID0+IHtcbiAgICAgICAgY29uc3QgZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7XG4gICAgICAgIGlmIChlbCkge1xuICAgICAgICAgIGVsLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gI
1H1cbn07XG5cbi8vIGpzL3Bob2VuaXhfbGl2ZV92aWV3L2xpdmVfc29ja2V0LnRzXG52YXIgaXNVc2VkSW5wdXQgPSAoZWwpID0+IGRvbV9kZWZhdWx0LmlzVXNlZElucHV0KGVsKTtcbnZhciBMaXZlU29ja2V0ID0gY2xhc3Mge1xuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBMaXZlU29ja2V0IGluc3RhbmNlLlxuICAgKi9cbiAgY29uc3RydWN0b3IodXJsLCBwaHhTb2NrZXQsIG9wdHMgPSB7fSkge1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICB0aGlzLnVubG9hZGVkID0gZmFsc2U7XG4gICAgaWYgKCFwaHhTb2NrZXQgfHwgcGh4U29ja2V0LmNvbnN0cnVjdG9yLm5hbWUgPT09IFwiT2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgXG4gICAgICBhIHBob2VuaXggU29ja2V0IG11c3QgYmUgcHJvdmlkZWQgYXMgdGhlIHNlY29uZCBhcmd1bWVudCB0byB0aGUgTGl2ZVNvY2tldCBjb25zdHJ1Y3Rvci4gRm9yIGV4YW1wbGU6XG5cbiAgICAgICAgICBpbXBvcnQge1NvY2tldH0gZnJvbSBcInBob2VuaXhcIlxuICAgICAgICAgIGltcG9ydCB7TGl2ZVNvY2tldH0gZnJvbSBcInBob2VuaXhfbGl2ZV92aWV3XCJcbiAgICAgICAgICBsZXQgbGl2ZVNvY2tldCA9IG5ldyBMaXZlU29ja2V0KFwiL2xpdmVcIiwgU29ja2V0LCB7Li4ufSlcbiAgICAgIGApO1xuICAgIH1cbiAgICB0aGlzLnNvY2tldCA9IG5ldyBwaHhTb2NrZXQodXJsLCBvcHRzKTtcbiAgICB0aGlzLmJpbmRpbmdQcmVmaXggPSBvcHRzLmJpbmRpbmdQcmVmaXggfHwgQklORElOR19QUkVGSVg7XG4gICAgdGhpcy5wYXJhbXMgPSBjbG9zdXJlKG9wdHMucGFyYW1zIHx8IHt9KTtcbiAgICB0aGlzLnZpZXdMb2dnZXIgPSBvcHRzLnZpZXdMb2dnZXI7XG4gICAgdGhpcy5tZXRhZGF0YUNhbGxiYWNrcyA9IG9wdHMubWV0YWRhdGEgfHwge307XG4gICAgdGhpcy5kZWZhdWx0cyA9IE9iamVjdC5hc3NpZ24oY2xvbmUoREVGQVVMVFMpLCBvcHRzLmRlZmF1bHRzIHx8IHt9KTtcbiAgICB0aGlzLnByZXZBY3RpdmUgPSBudWxsO1xuICAgIHRoaXMuc2lsZW5jZWQgPSBmYWxzZTtcbiAgICB0aGlzLm1haW4gPSBudWxsO1xuICAgIHRoaXMub3V0Z29pbmdNYWluRWwgPSBudWxsO1xuICAgIHRoaXMuY2xpY2tTdGFydGVkQXRUYXJnZXQgPSBudWxsO1xuICAgIHRoaXMubGlua1JlZiA9IDE7XG4gICAgdGhpcy5yb290cyA9IHt9O1xuICAgIHRoaXMuaHJlZiA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmO1xuICAgIHRoaXMucGVuZGluZ0xpbmsgPSBudWxsO1xuICAgIHRoaXMuY3VycmVudExvY2F0aW9uID0gY2xvbmUod2luZG93LmxvY2F0aW9uKTtcbiAgICB0aGlzLmhvb2tzID0gb3B0cy5ob29rcyB8fCB7fTtcbiAgICB0aGlzLnVwbG9hZGVycyA9IG9wdHMudXBsb2FkZXJzIHx8IHt9O1xuICAgIHRoaXMubG9hZGVyVGltZW91dCA9IG9wdHMubG9hZGVyVGltZW91dCB8fCBMT0FERVJfVElNRU9VVDtcbiAgICB0aGlzLmRpc2Nvbm5lY3RlZFRpbWVvdXQgPSBvcHRzLmRpc2Nvbm5lY3RlZFRpbWVvdXQgfHwgRElTQ09OTkVDVEVEX1RJTUVPVVQ7XG4gICAgdGhpcy5yZWxvYWRXaXRoSml0dGVyVGltZXIgPSBudWxsO1xuICAgIHRoaXMubWF4UmVsb2FkcyA9IG9wdHMubWF4UmVsb2FkcyB8fCBNQVhfUkVMT0FEUztcbiAgICB0aGlzLnJlbG9hZEppdHRlck1pbiA9IG9wdHMucmVsb2FkSml0dGVyTWluIHx8IFJFTE9BRF9KSVRURVJfTUlOO1xuICAgIHRoaXMucmVsb2FkSml0dGVyTWF4ID0gb3B0cy5yZWxvYWRKaXR0ZXJNYXggfHwgUkVMT0FEX0pJVFRFUl9NQVg7XG4gICAgdGhpcy5mYWlsc2FmZUppdHRlciA9IG9wdHMuZmFpbHNhZmVKaXR0ZXIgfHwgRkFJTFNBRkVfSklUVEVSO1xuICAgIHRoaXMubG9jYWxTdG9yYWdlID0gb3B0cy5sb2NhbFN0b3JhZ2UgfHwgd2luZG93LmxvY2FsU3RvcmFnZTtcbiAgICB0aGlzLnNlc3Npb25TdG9yYWdlID0gb3B0cy5zZXNzaW9uU3RvcmFnZSB8fCB3aW5kb3cuc2Vzc2lvblN0b3JhZ2U7XG4gICAgdGhpcy5ib3VuZFRvcExldmVsRXZlbnRzID0gZmFsc2U7XG4gICAgdGhpcy5ib3VuZEV2ZW50TmFtZXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpO1xuICAgIHRoaXMuYmxvY2tQaHhDaGFuZ2VXaGlsZUNvbXBvc2luZyA9IG9wdHMuYmxvY2tQaHhDaGFuZ2VXaGlsZUNvbXBvc2luZyB8fCBmYWxzZTtcbiAgICB0aGlzLnNlcnZlckNsb3NlUmVmID0gbnVsbDtcbiAgICB0aGlzLmRvbUNhbGxiYWNrcyA9IE9iamVjdC5hc3NpZ24oXG4gICAgICB7XG4gICAgICAgIGpzUXVlcnlTZWxlY3RvckFsbDogbnVsbCxcbiAgICAgICAgb25QYXRjaFN0YXJ0OiBjbG9zdXJlKCksXG4gICAgICAgIG9uUGF0Y2hFbmQ6IGNsb3N1cmUoKSxcbiAgICAgICAgb25Ob2RlQWRkZWQ6IGNsb3N1cmUoKSxcbiAgICAgICAgb25CZWZvcmVFbFVwZGF0ZWQ6IGNsb3N1cmUoKVxuICAgICAgfSxcbiAgICAgIG9wdHMuZG9tIHx8IHt9XG4gICAgKTtcbiAgICB0aGlzLnRyYW5zaXRpb25zID0gbmV3IFRyYW5zaXRpb25TZXQoKTtcbiAgICB0aGlzLmN1cnJlbnRIaXN0b3J5UG9zaXRpb24gPSBwYXJzZUludCh0aGlzLnNlc3Npb25TdG9yYWdlLmdldEl0ZW0oUEhYX0xWX0hJU1RPUllfUE9TSVRJT04pIHx8IFwiMFwiKSB8fCAwO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicGFnZWhpZGVcIiwgKF9lKSA9PiB7XG4gICAgICB0aGlzLnVubG9hZGVkID0gdHJ1ZTtcbiAgICB9KTtcbiAgICB0aGlzLnNvY2tldC5vbk9wZW4oKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuaXNVbmxvYWRlZCgpKSB7XG4gICAgICAgIHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICAvLyBwdWJsaWNcbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHZlcnNpb24gb2YgdGhlIExpdmVWaWV3IGNsaWVudC5cbiAgICovXG4gIHZlcnNpb24oKSB7XG4gICAgcmV0dXJuIFwiMS4yLjZcIjtcbiAgfVxuICAvKipcbiAgICogUmV0dXJucyB0cnVlIGlmIHByb2ZpbGluZyBpcyBlbmFibGVkLiBTZWUge0BsaW5rIGVuYWJsZVByb2ZpbGluZ30gYW5kIHtAbGluayBkaXNhYmxlUHJvZmlsaW5nfS5cbiAgICovXG4gIGlzUHJvZmlsZUVuYWJsZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbShQSFhfTFZfUFJPRklMRSkgPT09IFwidHJ1ZVwiO1xuICB9XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRydWUgaWYgZGVidWdnaW5nIGlzIGVuYWJsZWQuIFNlZSB7QGxpbmsgZW5hYmxlRGVidWd9IGFuZCB7QGxpbmsgZGlzYWJsZURlYnVnfS5cbiAgICovXG4gIGlzRGVidWdFbmFibGVkKCkge1xuICAgIHJldHVybi
1B0aGlzLnNlc3Npb25TdG9yYWdlLmdldEl0ZW0oUEhYX0xWX0RFQlVHKSA9PT0gXCJ0cnVlXCI7XG4gIH1cbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiBkZWJ1Z2dpbmcgaXMgZGlzYWJsZWQuIFNlZSB7QGxpbmsgZW5hYmxlRGVidWd9IGFuZCB7QGxpbmsgZGlzYWJsZURlYnVnfS5cbiAgICovXG4gIGlzRGVidWdEaXNhYmxlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uU3RvcmFnZS5nZXRJdGVtKFBIWF9MVl9ERUJVRykgPT09IFwiZmFsc2VcIjtcbiAgfVxuICAvKipcbiAgICogRW5hYmxlcyBkZWJ1Z2dpbmcuXG4gICAqXG4gICAqIFdoZW4gZGVidWdnaW5nIGlzIGVuYWJsZWQsIHRoZSBMaXZlVmlldyBjbGllbnQgd2lsbCBsb2cgZGVidWcgaW5mb3JtYXRpb24gdG8gdGhlIGNvbnNvbGUuXG4gICAqIFNlZSBbRGVidWdnaW5nIGNsaWVudCBldmVudHNdKGh0dHBzOi8vcGhvZW5peC1saXZlLXZpZXcuaGV4ZG9jcy5wbS9qcy1pbnRlcm9wLmh0bWwjZGVidWdnaW5nLWNsaWVudC1ldmVudHMpIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICAgKi9cbiAgZW5hYmxlRGVidWcoKSB7XG4gICAgdGhpcy5zZXNzaW9uU3RvcmFnZS5zZXRJdGVtKFBIWF9MVl9ERUJVRywgXCJ0cnVlXCIpO1xuICB9XG4gIC8qKlxuICAgKiBFbmFibGVzIHByb2ZpbGluZy5cbiAgICpcbiAgICogV2hlbiBwcm9maWxpbmcgaXMgZW5hYmxlZCwgdGhlIExpdmVWaWV3IGNsaWVudCB3aWxsIGxvZyBwcm9maWxpbmcgaW5mb3JtYXRpb24gdG8gdGhlIGNvbnNvbGUuXG4gICAqL1xuICBlbmFibGVQcm9maWxpbmcoKSB7XG4gICAgdGhpcy5zZXNzaW9uU3RvcmFnZS5zZXRJdGVtKFBIWF9MVl9QUk9GSUxFLCBcInRydWVcIik7XG4gIH1cbiAgLyoqXG4gICAqIERpc2FibGVzIGRlYnVnZ2luZy5cbiAgICovXG4gIGRpc2FibGVEZWJ1ZygpIHtcbiAgICB0aGlzLnNlc3Npb25TdG9yYWdlLnNldEl0ZW0oUEhYX0xWX0RFQlVHLCBcImZhbHNlXCIpO1xuICB9XG4gIC8qKlxuICAgKiBEaXNhYmxlcyBwcm9maWxpbmcuXG4gICAqL1xuICBkaXNhYmxlUHJvZmlsaW5nKCkge1xuICAgIHRoaXMuc2Vzc2lvblN0b3JhZ2UucmVtb3ZlSXRlbShQSFhfTFZfUFJPRklMRSk7XG4gIH1cbiAgLyoqXG4gICAqIEVuYWJsZXMgbGF0ZW5jeSBzaW11bGF0aW9uLlxuICAgKlxuICAgKiBXaGVuIGxhdGVuY3kgc2ltdWxhdGlvbiBpcyBlbmFibGVkLCB0aGUgTGl2ZVZpZXcgY2xpZW50IHdpbGwgYWRkIGEgZGVsYXkgdG8gcmVxdWVzdHMgYW5kIHJlc3BvbnNlcyBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAqIFNlZSBbU2ltdWxhdGluZyBMYXRlbmN5XShodHRwczovL3Bob2VuaXgtbGl2ZS12aWV3LmhleGRvY3MucG0vanMtaW50ZXJvcC5odG1sI3NpbXVsYXRpbmctbGF0ZW5jeSkgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gICAqL1xuICBlbmFibGVMYXRlbmN5U2ltKHVwcGVyQm91bmRNcykge1xuICAgIHRoaXMuZW5hYmxlRGVidWcoKTtcbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIFwibGF0ZW5jeSBzaW11bGF0b3IgZW5hYmxlZCBmb3IgdGhlIGR1cmF0aW9uIG9mIHRoaXMgYnJvd3NlciBzZXNzaW9uLiBDYWxsIGRpc2FibGVMYXRlbmN5U2ltKCkgdG8gZGlzYWJsZVwiXG4gICAgKTtcbiAgICB0aGlzLnNlc3Npb25TdG9yYWdlLnNldEl0ZW0oUEhYX0xWX0xBVEVOQ1lfU0lNLCB1cHBlckJvdW5kTXMudG9TdHJpbmcoKSk7XG4gIH1cbiAgLyoqXG4gICAqIERpc2FibGVzIGxhdGVuY3kgc2ltdWxhdGlvbi5cbiAgICovXG4gIGRpc2FibGVMYXRlbmN5U2ltKCkge1xuICAgIHRoaXMuc2Vzc2lvblN0b3JhZ2UucmVtb3ZlSXRlbShQSFhfTFZfTEFURU5DWV9TSU0pO1xuICB9XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGxhdGVuY3kgc2ltdWxhdGlvbiB1cHBlciBib3VuZC5cbiAgICovXG4gIGdldExhdGVuY3lTaW0oKSB7XG4gICAgY29uc3Qgc3RyID0gdGhpcy5zZXNzaW9uU3RvcmFnZS5nZXRJdGVtKFBIWF9MVl9MQVRFTkNZX1NJTSk7XG4gICAgcmV0dXJuIHN0ciA/IHBhcnNlSW50KHN0cikgOiBudWxsO1xuICB9XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBQaG9lbml4IFNvY2tldCBpbnN0YW5jZS5cbiAgICovXG4gIGdldFNvY2tldCgpIHtcbiAgICByZXR1cm4gdGhpcy5zb2NrZXQ7XG4gIH1cbiAgLyoqXG4gICAqIENvbm5lY3RzIHRvIHRoZSBMaXZlVmlldyBzZXJ2ZXIuXG4gICAqL1xuICBjb25uZWN0KCkge1xuICAgIGlmICh3aW5kb3cubG9jYXRpb24uaG9zdG5hbWUgPT09IFwibG9jYWxob3N0XCIgJiYgIXRoaXMuaXNEZWJ1Z0Rpc2FibGVkKCkpIHtcbiAgICAgIHRoaXMuZW5hYmxlRGVidWcoKTtcbiAgICB9XG4gICAgY29uc3QgZG9Db25uZWN0ID0gKCkgPT4ge1xuICAgICAgdGhpcy5yZXNldFJlbG9hZFN0YXR1cygpO1xuICAgICAgaWYgKHRoaXMuam9pblJvb3RWaWV3cygpKSB7XG4gICAgICAgIHRoaXMuYmluZFRvcExldmVsRXZlbnRzKCk7XG4gICAgICAgIHRoaXMuc29ja2V0LmNvbm5lY3QoKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5tYWluKSB7XG4gICAgICAgIHRoaXMuc29ja2V0LmNvbm5lY3QoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYmluZFRvcExldmVsRXZlbnRzKHsgZGVhZDogdHJ1ZSB9KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuam9pbkRlYWRWaWV3KCk7XG4gICAgfTtcbiAgICBpZiAoW1wiY29tcGxldGVcIiwgXCJsb2FkZWRcIiwgXCJpbnRlcmFjdGl2ZVwiXS5pbmRleE9mKGRvY3VtZW50LnJlYWR5U3RhdGUpID49IDApIHtcbiAgICAgIGRvQ29ubmVjdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkb2
1N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiRE9NQ29udGVudExvYWRlZFwiLCAoKSA9PiBkb0Nvbm5lY3QoKSk7XG4gICAgfVxuICB9XG4gIC8qKlxuICAgKiBEaXNjb25uZWN0cyBmcm9tIHRoZSBMaXZlVmlldyBzZXJ2ZXIuXG4gICAqL1xuICBkaXNjb25uZWN0KGNhbGxiYWNrKSB7XG4gICAgdGhpcy5yZWxvYWRXaXRoSml0dGVyVGltZXIgIT0gbnVsbCAmJiBjbGVhclRpbWVvdXQodGhpcy5yZWxvYWRXaXRoSml0dGVyVGltZXIpO1xuICAgIGlmICh0aGlzLnNlcnZlckNsb3NlUmVmKSB7XG4gICAgICB0aGlzLnNvY2tldC5vZmYoW3RoaXMuc2VydmVyQ2xvc2VSZWZdKTtcbiAgICAgIHRoaXMuc2VydmVyQ2xvc2VSZWYgPSBudWxsO1xuICAgIH1cbiAgICB0aGlzLnNvY2tldC5kaXNjb25uZWN0KGNhbGxiYWNrKTtcbiAgfVxuICAvKipcbiAgICogQ2FuIGJlIHVzZWQgdG8gcmVwbGFjZSB0aGUgdHJhbnNwb3J0IHVzZWQgYnkgdGhlIHVuZGVybHlpbmcgUGhvZW5peCBTb2NrZXQuXG4gICAqL1xuICByZXBsYWNlVHJhbnNwb3J0KHRyYW5zcG9ydCkge1xuICAgIHRoaXMucmVsb2FkV2l0aEppdHRlclRpbWVyICE9IG51bGwgJiYgY2xlYXJUaW1lb3V0KHRoaXMucmVsb2FkV2l0aEppdHRlclRpbWVyKTtcbiAgICB0aGlzLnNvY2tldC5yZXBsYWNlVHJhbnNwb3J0KHRyYW5zcG9ydCk7XG4gICAgdGhpcy5jb25uZWN0KCk7XG4gIH1cbiAgLyoqXG4gICAqIEV4ZWN1dGVzIGFuIGVuY29kZWQgSlMgY29tbWFuZCwgdGFyZ2V0aW5nIHRoZSBnaXZlbiBlbGVtZW50LlxuICAgKlxuICAgKiBTZWUgW2BQaG9lbml4LkxpdmVWaWV3LkpTYF0oaHR0cHM6Ly9waG9lbml4LWxpdmUtdmlldy5oZXhkb2NzLnBtL1Bob2VuaXguTGl2ZVZpZXcuSlMuaHRtbCkgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gICAqL1xuICBleGVjSlMoZWwsIGVuY29kZWRKUywgZXZlbnRUeXBlID0gbnVsbCkge1xuICAgIGNvbnN0IGUgPSBuZXcgQ3VzdG9tRXZlbnQoXCJwaHg6ZXhlY1wiLCB7IGRldGFpbDogeyBzb3VyY2VFbGVtZW50OiBlbCB9IH0pO1xuICAgIHRoaXMub3duZXIoZWwsICh2aWV3KSA9PiBqc19kZWZhdWx0LmV4ZWMoZSwgZXZlbnRUeXBlLCBlbmNvZGVkSlMsIHZpZXcsIGVsKSk7XG4gIH1cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gb2JqZWN0IHdpdGggbWV0aG9kcyB0byBtYW5pcHVsYXRlIHRoZSBET00gYW5kIGV4ZWN1dGUgSmF2YVNjcmlwdC5cbiAgICogVGhlIGFwcGxpZWQgY2hhbmdlcyBpbnRlZ3JhdGUgd2l0aCBzZXJ2ZXIgRE9NIHBhdGNoaW5nLlxuICAgKlxuICAgKiBTZWUgW0phdmFTY3JpcHQgaW50ZXJvcGVyYWJpbGl0eV0oaHR0cHM6Ly9waG9lbml4LWxpdmUtdmlldy5oZXhkb2NzLnBtL2pzLWludGVyb3AuaHRtbCkgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gICAqL1xuICBqcygpIHtcbiAgICByZXR1cm4ganNfY29tbWFuZHNfZGVmYXVsdCh0aGlzLCBcImpzXCIpO1xuICB9XG4gIC8vIHByaXZhdGVcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICB1bmxvYWQoKSB7XG4gICAgaWYgKHRoaXMudW5sb2FkZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMubWFpbiAmJiB0aGlzLmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgIHRoaXMubG9nKHRoaXMubWFpbiwgXCJzb2NrZXRcIiwgKCkgPT4gW1wiZGlzY29ubmVjdCBmb3IgcGFnZSBuYXZcIl0pO1xuICAgIH1cbiAgICB0aGlzLnVubG9hZGVkID0gdHJ1ZTtcbiAgICB0aGlzLmRlc3Ryb3lBbGxWaWV3cygpO1xuICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgdHJpZ2dlckRPTShraW5kLCBhcmdzKSB7XG4gICAgdGhpcy5kb21DYWxsYmFja3Nba2luZF0oLi4uYXJncyk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICB0aW1lKG5hbWUsIGZ1bmMpIHtcbiAgICBpZiAoIXRoaXMuaXNQcm9maWxlRW5hYmxlZCgpIHx8ICFjb25zb2xlLnRpbWUpIHtcbiAgICAgIHJldHVybiBmdW5jKCk7XG4gICAgfVxuICAgIGNvbnNvbGUudGltZShuYW1lKTtcbiAgICBjb25zdCByZXN1bHQgPSBmdW5jKCk7XG4gICAgY29uc29sZS50aW1lRW5kKG5hbWUpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBsb2codmlldywga2luZCwgbXNnQ2FsbGJhY2spIHtcbiAgICBpZiAodGhpcy52aWV3TG9nZ2VyKSB7XG4gICAgICBjb25zdCBbbXNnLCBvYmpdID0gbXNnQ2FsbGJhY2soKTtcbiAgICAgIHRoaXMudmlld0xvZ2dlcih2aWV3LCBraW5kLCBtc2csIG9iaik7XG4gICAgfSBlbHNlIGlmICh0aGlzLmlzRGVidWdFbmFibGVkKCkpIHtcbiAgICAgIGNvbnN0IFttc2csIG9ial0gPSBtc2dDYWxsYmFjaygpO1xuICAgICAgZGVidWcodmlldywga2luZCwgbXNnLCBvYmopO1xuICAgIH1cbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIHJlcXVlc3RET01VcGRhdGUoY2FsbGJhY2spIHtcbiAgICB0aGlzLnRyYW5zaXRpb25zLmFmdGVyKGNhbGxiYWNrKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGFzeW5jVHJhbnNpdGlvbihwcm9taXNlKSB7XG4gICAgdGhpcy50cmFuc2l0aW9ucy5hZGRBc3luY1RyYW5zaXRpb24ocHJvbWlzZSk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICB0cmFuc2l0aW9uKHRpbWUsIG9uU3RhcnQsIG9uRG9uZSA9IGZ1bmN0aW9uKCkge1xuICB9KSB7XG4gICAgdGhpcy50cmFuc2l0aW9ucy5hZGRUcmFuc2l0aW9uKHRpbWUsIG9uU3RhcnQsIG9uRG9uZSk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBvbkNoYW5uZWwoY2hhbm5lbCwgZXZlbnQsIGNiKSB7XG4gICAgY2hhbm5lbC5vbihldmVudCwgKGRhdGEpID0+IHtcbiAgICAgIGNvbnN0IGxhdGVuY3kgPSB0aGlzLmdldExhdGVuY3lTaW0oKTtcbiAgICAgIGlmICghbGF0ZW5jeSkge1xuICAgICAgICBjYihkYXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gY2IoZGF0YSksIGxhdGVuY3kpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcmVsb2FkV2l0aEppdHRlcih2aWV3LCBsb2cpIHtcbiAgICB0aGlzLnJlbG9hZFdpdGhKaXR0ZXJUaW1lciAhPSBudWxsICYmIGNsZWFyVGltZW91dCh0aGlzLnJlbG9hZFdpdGhKaXR0ZXJUaW1lcik7XG4gICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgY29uc3QgbWluTXMgPSB0aGlzLnJlbG9hZEppdHRlck1pbjtcbiAgICBjb25zdCBtYXhNcyA9IHRoaXMucmVsb2FkSml0dGVyTWF4O1xuICAgIGxldCBhZnRlck1zID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogKG1heE1zIC0gbWluTXMgKyAxKSkgKyBtaW5NcztcbiAgICBjb25zdCB0cmllcyA9IGJyb3dzZXJfZGVmYXVsdC51cGRhdGVMb2NhbChcbiAgICAgIHRoaXMubG9jYWxTdG9yYWdlLFxuICAgICAgd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLFxuICAgICAgQ09OU0VDVVRJVkVfUkVMT0FEUyxcbiAgICAgIDAsXG4gICAgICAoY291bnQpID0+IGNvdW50ICsgMVxuICAgICk7XG4gICAgaWYgKHRyaWVzID49IHRoaXMubWF4UmVsb2Fkcykge1xuICAgICAgYWZ0ZXJNcyA9IHRoaXMuZmFpbHNhZmVKaXR0ZXI7XG4gICAgfVxuICAgIHRoaXMucmVsb2FkV2l0aEppdHRlclRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAodmlldy5pc0Rlc3Ryb3llZCgpIHx8IHZpZXcuaXNDb25uZWN0ZWQoKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2aWV3LmRlc3Ryb3koKTtcbiAgICAgIGxvZyA/IGxvZygpIDogdGhpcy5sb2codmlldywgXCJqb2luXCIsICgpID0+IFtcbiAgICAgICAgYGVuY291bnRlcmVkICR7dHJpZXN9IGNvbnNlY3V0aXZlIHJlbG9hZHNgXG4gICAgICBdKTtcbiAgICAgIGlmICh0cmllcyA+PSB0aGlzLm1heFJlbG9hZHMpIHtcbiAgICAgICAgdGhpcy5sb2codmlldywgXCJqb2luXCIsICgpID0+IFtcbiAgICAgICAgICBgZXhjZWVkZWQgJHt0aGlzLm1heFJlbG9hZHN9IGNvbnNlY3V0aXZlIHJlbG9hZHMuIEVudGVyaW5nIGZhaWxzYWZlIG1vZGVgXG4gICAgICAgIF0pO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMucGVuZGluZ0xpbmsgIT09IG51bGwpIHtcbiAgICAgICAgd2luZG93LmxvY2F0aW9uLmhy
1ZWYgPSB0aGlzLnBlbmRpbmdMaW5rO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgd2luZG93LmxvY2F0aW9uLnJlbG9hZCgpO1xuICAgICAgfVxuICAgIH0sIGFmdGVyTXMpO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgZ2V0SG9va0RlZmluaXRpb24obmFtZSkge1xuICAgIGlmICghbmFtZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5tYXliZUludGVybmFsSG9vayhuYW1lKSB8fCB0aGlzLmhvb2tzW25hbWVdIHx8IHRoaXMubWF5YmVSdW50aW1lSG9vayhuYW1lKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIG1heWJlSW50ZXJuYWxIb29rKG5hbWUpIHtcbiAgICByZXR1cm4gbmFtZSAmJiBuYW1lLnN0YXJ0c1dpdGgoXCJQaG9lbml4LlwiKSAmJiBob29rc19kZWZhdWx0W25hbWUuc3BsaXQoXCIuXCIpWzFdXTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIG1heWJlUnVudGltZUhvb2sobmFtZSkge1xuICAgIGNvbnN0IHJ1bnRpbWVIb29rID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgIGBzY3JpcHRbJHtQSFhfUlVOVElNRV9IT09LfT1cIiR7Q1NTLmVzY2FwZShuYW1lKX1cIl1gXG4gICAgKTtcbiAgICBpZiAoIXJ1bnRpbWVIb29rKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCBjYWxsYmFja3MgPSB3aW5kb3dbYHBoeF9ob29rXyR7bmFtZX1gXTtcbiAgICBpZiAoIWNhbGxiYWNrcyB8fCB0eXBlb2YgY2FsbGJhY2tzICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIGxvZ0Vycm9yKFwiYSBydW50aW1lIGhvb2sgbXVzdCBiZSBhIGZ1bmN0aW9uXCIsIHJ1bnRpbWVIb29rKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaG9va0RlZmluaXRvbiA9IGNhbGxiYWNrcygpO1xuICAgIGlmIChob29rRGVmaW5pdG9uICYmICh0eXBlb2YgaG9va0RlZmluaXRvbiA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgaG9va0RlZmluaXRvbiA9PT0gXCJmdW5jdGlvblwiKSkge1xuICAgICAgcmV0dXJuIGhvb2tEZWZpbml0b247XG4gICAgfVxuICAgIGxvZ0Vycm9yKFxuICAgICAgXCJydW50aW1lIGhvb2sgbXVzdCByZXR1cm4gYW4gb2JqZWN0IHdpdGggaG9vayBjYWxsYmFja3Mgb3IgYW4gaW5zdGFuY2Ugb2YgVmlld0hvb2tcIixcbiAgICAgIHJ1bnRpbWVIb29rXG4gICAgKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGlzVW5sb2FkZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMudW5sb2FkZWQ7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBpc0Nvbm5lY3RlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5zb2NrZXQuaXNDb25uZWN0ZWQoKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGdldEJpbmRpbmdQcmVmaXgoKSB7XG4gICAgcmV0dXJuIHRoaXMuYmluZGluZ1ByZWZpeDtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGJpbmRpbmcoa2luZCkge1xuICAgIHJldHVybiBgJHt0aGlzLmdldEJpbmRpbmdQcmVmaXgoKX0ke2tpbmR9YDtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGNoYW5uZWwodG9waWMsIHBhcmFtcykge1xuICAgIHJldHVybiB0aGlzLnNvY2tldC5jaGFubmVsKHRvcGljLCBwYXJhbXMpO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgam9pbkRlYWRWaWV3KCkge1xuICAgIGNvbnN0IGJvZHkgPSBkb2N1bWVudC5ib2R5O1xuICAgIGlmIChib2R5ICYmICF0aGlzLmlzUGh4Vmlldyhib2R5KSAmJiAhdGhpcy5pc1BoeFZpZXcoZG9jdW1lbnQuZmlyc3RFbGVtZW50Q2hpbGQpKSB7XG4gICAgICBjb25zdCB2aWV3ID0gdGhpcy5uZXdSb290Vmlldyhib2R5KTtcbiAgICAgIHZpZXcuc2V0SHJlZih0aGlzLmdldEhyZWYoKSk7XG4gICAgICB2aWV3LmpvaW5EZWFkKCk7XG4gICAgICBpZiAoIXRoaXMubWFpbikge1xuICAgICAgICB0aGlzLm1haW4gPSB2aWV3O1xuICAgICAgfVxuICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgIHZpZXcuZXhlY05ld01vdW50ZWQoKTtcbiAgICAgICAgdGhpcy5tYXliZVNjcm9sbChoaXN0b3J5LnN0YXRlPy5zY3JvbGwpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgam9pblJvb3RWaWV3cygpIHtcbiAgICBsZXQgcm9vdHNGb3VuZCA9IGZhbHNlO1xuICAgIGRvbV9kZWZhdWx0LmFsbChcbiAgICAgIGRvY3VtZW50LFxuICAgICAgYCR7UEhYX1ZJRVdfU0VMRUNUT1J9Om5vdChbJHtQSFhfUEFSRU5UX0lEfV0pYCxcbiAgICAgIChyb290RWwpID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLmdldFJvb3RCeUlkKHJvb3RFbC5pZCkpIHtcbiAgICAgICAgICBjb25zdCB2aWV3ID0gdGhpcy5uZXdSb290Vmlldyhyb290RWwpO1xuICAgICAgICAgIGlmICghZG9tX2RlZmF1bHQuaXNQaHhTdGlja3kocm9vdEVsKSkge1xuICAgICAgICAgICAgdmlldy5zZXRIcmVmKHRoaXMuZ2V0SHJlZigpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmlldy5qb2luKCk7XG4gICAgICAgICAgaWYgKHJvb3RFbC5oYXNBdHRyaWJ1dGUoUEhYX01BSU4pKSB7XG4gICAgICAgICAgICB0aGlzLm1haW4gPSB2aWV3O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByb290c0ZvdW5kID0gdHJ1ZTtcbiAgICAgIH1cbiAgICApO1xuICAgIHJldHVybiByb290c0ZvdW5kO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcmVkaXJlY3QodG8sIGZsYXNoLCByZWxvYWRUb2tlbikge1xuICAgIGlmIChyZWxvYWRUb2tlbikge1xuICAgICAgYnJvd3Nlcl9kZWZhdWx0LnNldENvb2tpZShQSFhfUkVMT0FEX1NUQVRVUywgcmVsb2FkVG9rZW4sIDYwKTtcbiAgICB9XG4gICAgdGhpcy51bmxvYWQoKTtcbiAgICBicm93c2VyX2RlZmF1bHQucmVkaXJlY3QodG8sIGZsYXNoKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIHJlcGxhY2VNYWluKGhyZWYsIGZsYXNoLCBjYWxsYmFjayA9IG51bGwsIGxpbmtSZWYgPSB0aGlzLnNldFBlbmRpbmdMaW5rKGhyZWYpKSB7XG4gICAgaWYgKCF0aGlzLm1haW4pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbGl2ZVJlZmVyZXIgPSB0aGlzLmN1cnJlbnRMb2NhdGlvbi5ocmVmO1xuICAgIHRoaXMub3V0Z29pbmdNYWluRWwgPSB0aGlzLm91dGdvaW5nTWFpbkVsIHx8IHRoaXMubWFpbi5lbDtcbiAgICBjb25zdCBzdGlja2llcyA9IGRvbV9kZWZhdWx0LmZpbmRQaHhTdGlja3koZG9jdW1lbnQpIHx8IFtdO1xuICAgIGNvbnN0IHJlbW92ZUVscyA9IGRvbV9kZWZhdWx0LmFsbChcbiAgICAgIHRoaXMub3V0Z29pbmdNYWluRWwsXG4gICAgICBgWyR7dGhpcy5iaW5kaW5nKFwicmVtb3ZlXCIpfV1gXG4gICAgKS5maWx0ZXIoKGVsKSA9PiAhZG9tX2RlZmF1bHQuaXNDaGlsZE9mQW55KGVsLCBzdGlja2llcykpO1xuICAgIGNvbnN0IG5ld01haW5FbCA9IGRvbV9kZWZhdWx0LmNsb25lTm9kZSh0aGlzLm91dGdvaW5nTWFpbkVsLCBcIlwiKTtcbiAgICBjb25zdCBvbGRNYWluVmlldyA9IHRoaXMubWFpbjtcbiAgICBvbGRNYWluVmlldy5zaG93TG9hZGVyKHRoaXMubG9hZGVyVGltZW91dCk7XG4gICAgb2xkTWFpblZpZXcuZGVzdHJveSgpO1xuICAgIHRoaXMubWFpbiA9IHRoaXMubmV3Um9vdFZpZXcobmV3TWFpbkVsLCBmbGFzaCwgbGl2ZVJlZmVyZXIpO1xuICAgIHRoaXMubWFpbi5zZXRSZWRpcmVjdChocmVmKTtcbiAgICB0aGlzLnRyYW5zaXRpb25SZW1vdmVzKHJlbW92ZUVscywgb2xkTWFpblZpZXcpO1xuICAgIHRoaXMubWFpbi5qb2luKChqb2luQ291bnQsIG9uRG9uZSkgPT4ge1xuICAgICAgaWYgKGpvaW5Db3VudCA9PT0gMSAmJi
1B0aGlzLmNvbW1pdFBlbmRpbmdMaW5rKGxpbmtSZWYpKSB7XG4gICAgICAgIHRoaXMucmVxdWVzdERPTVVwZGF0ZSgoKSA9PiB7XG4gICAgICAgICAgcmVtb3ZlRWxzLmZvckVhY2goKGVsKSA9PiBlbC5yZW1vdmUoKSk7XG4gICAgICAgICAgc3RpY2tpZXMuZm9yRWFjaCgoZWwpID0+IG5ld01haW5FbC5hcHBlbmRDaGlsZChlbCkpO1xuICAgICAgICAgIHRoaXMub3V0Z29pbmdNYWluRWwucmVwbGFjZVdpdGgobmV3TWFpbkVsKTtcbiAgICAgICAgICB0aGlzLm91dGdvaW5nTWFpbkVsID0gbnVsbDtcbiAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjayhsaW5rUmVmKTtcbiAgICAgICAgICBvbkRvbmUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICB0cmFuc2l0aW9uUmVtb3ZlcyhlbGVtZW50cywgdmlldywgY2FsbGJhY2spIHtcbiAgICBjb25zdCByZW1vdmVBdHRyID0gdGhpcy5iaW5kaW5nKFwicmVtb3ZlXCIpO1xuICAgIGNvbnN0IHNpbGVuY2VFdmVudHMgPSAoZSkgPT4ge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICB9O1xuICAgIGVsZW1lbnRzLmZvckVhY2goKGVsKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGV2ZW50IG9mIHRoaXMuYm91bmRFdmVudE5hbWVzKSB7XG4gICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIHNpbGVuY2VFdmVudHMsIHRydWUpO1xuICAgICAgfVxuICAgICAgY29uc3QgZSA9IG5ldyBDdXN0b21FdmVudChcInBoeDpleGVjXCIsIHsgZGV0YWlsOiB7IHNvdXJjZUVsZW1lbnQ6IGVsIH0gfSk7XG4gICAgICBqc19kZWZhdWx0LmV4ZWMoZSwgXCJyZW1vdmVcIiwgZWwuZ2V0QXR0cmlidXRlKHJlbW92ZUF0dHIpLCB2aWV3LCBlbCk7XG4gICAgfSk7XG4gICAgdGhpcy5yZXF1ZXN0RE9NVXBkYXRlKCgpID0+IHtcbiAgICAgIGVsZW1lbnRzLmZvckVhY2goKGVsKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3QgZXZlbnQgb2YgdGhpcy5ib3VuZEV2ZW50TmFtZXMpIHtcbiAgICAgICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50LCBzaWxlbmNlRXZlbnRzLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpO1xuICAgIH0pO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgaXNQaHhWaWV3KGVsKSB7XG4gICAgcmV0dXJuIGVsLmdldEF0dHJpYnV0ZSAmJiBlbC5nZXRBdHRyaWJ1dGUoUEhYX1NFU1NJT04pICE9PSBudWxsO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgbmV3Um9vdFZpZXcoZWwsIGZsYXNoLCBsaXZlUmVmZXJlcikge1xuICAgIGNvbnN0IHZpZXcgPSBuZXcgVmlldyhlbCwgdGhpcywgbnVsbCwgZmxhc2gsIGxpdmVSZWZlcmVyKTtcbiAgICB0aGlzLnJvb3RzW3ZpZXcuaWRdID0gdmlldztcbiAgICByZXR1cm4gdmlldztcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIG93bmVyKGNoaWxkRWwsIGNhbGxiYWNrKSB7XG4gICAgbGV0IHZpZXc7XG4gICAgY29uc3Qgdmlld0VsID0gZG9tX2RlZmF1bHQuY2xvc2VzdFZpZXdFbChjaGlsZEVsKTtcbiAgICBpZiAodmlld0VsKSB7XG4gICAgICB2aWV3ID0gZG9tX2RlZmF1bHQucHJpdmF0ZSh2aWV3RWwsIFwidmlld1wiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFjaGlsZEVsLmlzQ29ubmVjdGVkKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgdmlldyA9IHRoaXMubWFpbjtcbiAgICB9XG4gICAgcmV0dXJuIHZpZXcgJiYgY2FsbGJhY2sgPyBjYWxsYmFjayh2aWV3KSA6IHZpZXc7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICB3aXRoaW5Pd25lcnMoY2hpbGRFbCwgY2FsbGJhY2spIHtcbiAgICB0aGlzLm93bmVyKGNoaWxkRWwsICh2aWV3KSA9PiBjYWxsYmFjayh2aWV3LCBjaGlsZEVsKSk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBnZXRWaWV3QnlFbChlbCkge1xuICAgIGNvbnN0IHJvb3RJZCA9IGVsLmdldEF0dHJpYnV0ZShQSFhfUk9PVF9JRCk7XG4gICAgcmV0dXJuIG1heWJlKFxuICAgICAgdGhpcy5nZXRSb290QnlJZChyb290SWQpLFxuICAgICAgKHJvb3QpID0+IHJvb3QuZ2V0RGVzY2VuZGVudEJ5RWwoZWwpXG4gICAgKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGdldFJvb3RCeUlkKGlkKSB7XG4gICAgcmV0dXJuIHRoaXMucm9vdHNbaWRdO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgZGVzdHJveUFsbFZpZXdzKCkge1xuICAgIGZvciAoY29uc3QgaWQgaW4gdGhpcy5yb290cykge1xuICAgICAgdGhpcy5yb290c1tpZF0uZGVzdHJveSgpO1xuICAgICAgZGVsZXRlIHRoaXMucm9vdHNbaWRdO1xuICAgIH1cbiAgICB0aGlzLm1haW4gPSBudWxsO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgZGVzdHJveVZpZXdCeUVsKGVsKSB7XG4gICAgY29uc3Qgcm9vdCA9IHRoaXMuZ2V0Um9vdEJ5SWQoZWwuZ2V0QXR0cmlidXRlKFBIWF9ST09UX0lEKSk7XG4gICAgaWYgKHJvb3QgJiYgcm9vdC5pZCA9PT0gZWwuaWQpIHtcbiAgICAgIHJvb3QuZGVzdHJveSgpO1xuICAgICAgZGVsZXRlIHRoaXMucm9vdHNbcm9vdC5pZF07XG4gICAgfSBlbHNlIGlmIChyb290KSB7XG4gICAgICByb290LmRlc3Ryb3lEZXNjZW5kZW50KGVsLmlkKTtcbiAgICB9XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBnZXRBY3RpdmVFbGVtZW50KCkge1xuICAgIHJldHVybiBkb2N1bWVudC5hY3RpdmVFbGVtZW50O1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgZHJvcEFjdGl2ZUVsZW1lbnQodmlldykge1xuICAgIGlmICh0aGlzLnByZXZBY3RpdmUgJiYgdmlldy5vd25zRWxlbWVudCh0aGlzLnByZXZBY3RpdmUpKSB7XG4gICAgICB0aGlzLnByZXZBY3RpdmUgPSBudWxsO1xuICAgIH1cbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIHJlc3RvcmVQcmV2aW91c2x5QWN0aXZlRm9jdXMoKSB7XG4gICAgaWYgKHRoaXMucHJldkFjdGl2ZSAmJiB0aGlzLnByZXZBY3RpdmUgIT09IGRvY3VtZW50LmJvZHkgJiYgdGhpcy5wcmV2QWN0aXZlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgIHRoaXMucHJldkFjdGl2ZS5mb2N1cygpO1xuICAgIH1cbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGJsdXJBY3RpdmVFbGVtZW50KCkge1xuICAgIHRoaXMucHJldkFjdGl2ZSA9IHRoaXMuZ2V0QWN0aXZlRWxlbWVudCgpO1xuICAgIGlmICh0aGlzLnByZXZBY3RpdmUgIT09IGRvY3VtZW50LmJvZHkgJiYgdGhpcy5wcmV2QWN0aXZlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgIHRoaXMucHJldkFjdGl2ZS5ibHVyKCk7XG4gICAgfVxuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgYmluZFRvcExldmVsRXZlbnRzKHsgZGVhZCB9ID0ge30pIHtcbiAgICBpZiAodGhpcy5ib3VuZFRvcExldmVsRXZlbnRzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYm91bmRUb3BMZXZlbEV2ZW50cyA9IHRydWU7XG4gICAgdGhpcy5zZXJ2ZXJDbG9zZVJlZiA9IHRoaXMuc29ja2V0Lm9uQ2xvc2UoKGV2ZW50KSA9PiB7XG4gICAgICBpZiAoZXZlbnQgJiYgZXZlbnQuY29kZSA9PT0gMWUzICYmIHRoaXMubWFpbikge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWxvYWRXaXRoSml0dGVyKHRoaXMubWFpbik7XG4gICAgICB9XG4gICAgfSk7XG4gICAgZG9jdW1lbnQuYm9keS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgZnVuY3Rpb24oKSB7XG4gICAgfSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBcInBhZ2VzaG93XCIsXG4gICAgICAoZSkgPT4ge1xuICAgICAgICBpZiAoZS5wZXJzaXN0ZWQpIHtcbiAgICAgICAgICB0aGlzLmdldFNvY2tldCgpLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICB0aGlzLndpdGhQYWdlTG9hZGluZyh7IHRvOiB3aW5kb3cubG9jYXRpb24uaHJlZiwga2luZDogXCJyZWRpcmVjdFwiIH0pO1xuICAgICAgICAgI
1HdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHRydWVcbiAgICApO1xuICAgIGlmICghZGVhZCkge1xuICAgICAgdGhpcy5iaW5kTmF2KCk7XG4gICAgfVxuICAgIHRoaXMuYmluZENsaWNrcygpO1xuICAgIGlmICghZGVhZCkge1xuICAgICAgdGhpcy5iaW5kRm9ybXMoKTtcbiAgICB9XG4gICAgdGhpcy5iaW5kKFxuICAgICAgeyBrZXl1cDogXCJrZXl1cFwiLCBrZXlkb3duOiBcImtleWRvd25cIiB9LFxuICAgICAgKGUsIHR5cGUsIHZpZXcsIHRhcmdldEVsLCBwaHhFdmVudCwgX3BoeFRhcmdldCkgPT4ge1xuICAgICAgICBjb25zdCBtYXRjaEtleSA9IHRhcmdldEVsLmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoUEhYX0tFWSkpO1xuICAgICAgICBjb25zdCBwcmVzc2VkS2V5ID0gZS5rZXkgJiYgZS5rZXkudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgaWYgKG1hdGNoS2V5ICYmIG1hdGNoS2V5LnRvTG93ZXJDYXNlKCkgIT09IHByZXNzZWRLZXkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGF0YSA9IHsga2V5OiBlLmtleSwgLi4udGhpcy5ldmVudE1ldGEodHlwZSwgZSwgdGFyZ2V0RWwpIH07XG4gICAgICAgIGpzX2RlZmF1bHQuZXhlYyhlLCB0eXBlLCBwaHhFdmVudCwgdmlldywgdGFyZ2V0RWwsIFtcInB1c2hcIiwgeyBkYXRhIH1dKTtcbiAgICAgIH1cbiAgICApO1xuICAgIHRoaXMuYmluZChcbiAgICAgIHsgYmx1cjogXCJmb2N1c291dFwiLCBmb2N1czogXCJmb2N1c2luXCIgfSxcbiAgICAgIChlLCB0eXBlLCB2aWV3LCB0YXJnZXRFbCwgcGh4RXZlbnQsIHBoeFRhcmdldCkgPT4ge1xuICAgICAgICBpZiAoIXBoeFRhcmdldCkge1xuICAgICAgICAgIGNvbnN0IGRhdGEgPSB7IC4uLnRoaXMuZXZlbnRNZXRhKHR5cGUsIGUsIHRhcmdldEVsKSB9O1xuICAgICAgICAgIGpzX2RlZmF1bHQuZXhlYyhlLCB0eXBlLCBwaHhFdmVudCwgdmlldywgdGFyZ2V0RWwsIFtcInB1c2hcIiwgeyBkYXRhIH1dKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICk7XG4gICAgdGhpcy5iaW5kKFxuICAgICAgeyBibHVyOiBcImJsdXJcIiwgZm9jdXM6IFwiZm9jdXNcIiB9LFxuICAgICAgKGUsIHR5cGUsIHZpZXcsIHRhcmdldEVsLCBwaHhFdmVudCwgcGh4VGFyZ2V0KSA9PiB7XG4gICAgICAgIGlmIChwaHhUYXJnZXQgPT09IFwid2luZG93XCIpIHtcbiAgICAgICAgICBjb25zdCBkYXRhID0gdGhpcy5ldmVudE1ldGEodHlwZSwgZSwgdGFyZ2V0RWwpO1xuICAgICAgICAgIGpzX2RlZmF1bHQuZXhlYyhlLCB0eXBlLCBwaHhFdmVudCwgdmlldywgdGFyZ2V0RWwsIFtcInB1c2hcIiwgeyBkYXRhIH1dKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICk7XG4gICAgdGhpcy5vbihcImRyYWdvdmVyXCIsIChlKSA9PiBlLnByZXZlbnREZWZhdWx0KCkpO1xuICAgIHRoaXMub24oXCJkcmFnZW50ZXJcIiwgKGUpID0+IHtcbiAgICAgIGxldCB0YXJnZXQgPSBlLnRhcmdldCAmJiBkb21fZGVmYXVsdC5lbGVtZW50RnJvbVRhcmdldChlLnRhcmdldCk7XG4gICAgICBpZiAoIXRhcmdldCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBkcm9wem9uZSA9IGNsb3Nlc3RQaHhCaW5kaW5nKHRhcmdldCwgdGhpcy5iaW5kaW5nKFBIWF9EUk9QX1RBUkdFVCkpO1xuICAgICAgaWYgKCFkcm9wem9uZSB8fCAhKGRyb3B6b25lIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChldmVudENvbnRhaW5zRmlsZXMoZSkpIHtcbiAgICAgICAgdGhpcy5qcygpLmFkZENsYXNzKGRyb3B6b25lLCBQSFhfRFJPUF9UQVJHRVRfQUNUSVZFX0NMQVNTKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLm9uKFwiZHJhZ2xlYXZlXCIsIChlKSA9PiB7XG4gICAgICBsZXQgdGFyZ2V0ID0gZS50YXJnZXQgJiYgZG9tX2RlZmF1bHQuZWxlbWVudEZyb21UYXJnZXQoZS50YXJnZXQpO1xuICAgICAgaWYgKCF0YXJnZXQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgZHJvcHpvbmUgPSBjbG9zZXN0UGh4QmluZGluZyh0YXJnZXQsIHRoaXMuYmluZGluZyhQSFhfRFJPUF9UQVJHRVQpKTtcbiAgICAgIGlmICghZHJvcHpvbmUgfHwgIShkcm9wem9uZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCByZWN0ID0gZHJvcHpvbmUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBpZiAoZS5jbGllbnRYIDw9IHJlY3QubGVmdCB8fCBlLmNsaWVudFggPj0gcmVjdC5yaWdodCB8fCBlLmNsaWVudFkgPD0gcmVjdC50b3AgfHwgZS5jbGllbnRZID49IHJlY3QuYm90dG9tKSB7XG4gICAgICAgIHRoaXMuanMoKS5yZW1vdmVDbGFzcyhkcm9wem9uZSwgUEhYX0RST1BfVEFSR0VUX0FDVElWRV9DTEFTUyk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5vbihcImRyb3BcIiwgKGUpID0+IHtcbiAgICAgIGxldCB0YXJnZXQgPSBlLnRhcmdldCAmJiBkb21fZGVmYXVsdC5lbGVtZW50RnJvbVRhcmdldChlLnRhcmdldCk7XG4gICAgICBpZiAoIXRhcmdldCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBjb25zdCBkcm9wem9uZSA9IGNsb3Nlc3RQaHhCaW5kaW5nKHRhcmdldCwgdGhpcy5iaW5kaW5nKFBIWF9EUk9QX1RBUkdFVCkpO1xuICAgICAgaWYgKCFkcm9wem9uZSB8fCAhKGRyb3B6b25lIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuanMoKS5yZW1vdmVDbGFzcyhkcm9wem9uZSwgUEhYX0RST1BfVEFSR0VUX0FDVElWRV9DTEFTUyk7XG4gICAgICBpZiAoIWUuZGF0YVRyYW5zZmVyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRyb3BUYXJnZXRJZCA9IGRyb3B6b25lLmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoUEhYX0RST1BfVEFSR0VUKSk7XG4gICAgICBjb25zdCBkcm9wVGFyZ2V0ID0gZHJvcFRhcmdldElkICYmIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGRyb3BUYXJnZXRJZCk7XG4gICAgICBjb25zdCBmaWxlcyA9IEFycmF5LmZyb20oZS5kYXRhV
1HJhbnNmZXIuZmlsZXMgfHwgW10pO1xuICAgICAgaWYgKCFkcm9wVGFyZ2V0IHx8ICEoZHJvcFRhcmdldCBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQpIHx8IGRyb3BUYXJnZXQuZGlzYWJsZWQgfHwgZmlsZXMubGVuZ3RoID09PSAwIHx8ICEoZHJvcFRhcmdldC5maWxlcyBpbnN0YW5jZW9mIEZpbGVMaXN0KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBMaXZlVXBsb2FkZXIudHJhY2tGaWxlcyhkcm9wVGFyZ2V0LCBmaWxlcywgZS5kYXRhVHJhbnNmZXIpO1xuICAgICAgZHJvcFRhcmdldC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcImlucHV0XCIsIHsgYnViYmxlczogdHJ1ZSB9KSk7XG4gICAgfSk7XG4gICAgdGhpcy5vbihQSFhfVFJBQ0tfVVBMT0FEUywgKGUpID0+IHtcbiAgICAgIGNvbnN0IHVwbG9hZFRhcmdldCA9IGUudGFyZ2V0ICYmIGRvbV9kZWZhdWx0LmVsZW1lbnRGcm9tVGFyZ2V0KGUudGFyZ2V0KTtcbiAgICAgIGlmICghZG9tX2RlZmF1bHQuaXNVcGxvYWRJbnB1dCh1cGxvYWRUYXJnZXQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZpbGVzID0gQXJyYXkuZnJvbShlLmRldGFpbC5maWxlcyB8fCBbXSkuZmlsdGVyKFxuICAgICAgICAoZikgPT4gZiBpbnN0YW5jZW9mIEZpbGUgfHwgZiBpbnN0YW5jZW9mIEJsb2JcbiAgICAgICk7XG4gICAgICBMaXZlVXBsb2FkZXIudHJhY2tGaWxlcyh1cGxvYWRUYXJnZXQsIGZpbGVzKTtcbiAgICAgIHVwbG9hZFRhcmdldC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcImlucHV0XCIsIHsgYnViYmxlczogdHJ1ZSB9KSk7XG4gICAgfSk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBldmVudE1ldGEoZXZlbnROYW1lLCBlLCB0YXJnZXRFbCkge1xuICAgIGNvbnN0IGNhbGxiYWNrID0gdGhpcy5tZXRhZGF0YUNhbGxiYWNrc1tldmVudE5hbWVdO1xuICAgIHJldHVybiBjYWxsYmFjayA/IGNhbGxiYWNrKGUsIHRhcmdldEVsKSA6IHt9O1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgc2V0UGVuZGluZ0xpbmsoaHJlZikge1xuICAgIHRoaXMubGlua1JlZisrO1xuICAgIHRoaXMucGVuZGluZ0xpbmsgPSBocmVmO1xuICAgIHRoaXMucmVzZXRSZWxvYWRTdGF0dXMoKTtcbiAgICByZXR1cm4gdGhpcy5saW5rUmVmO1xuICB9XG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICogYW55dGltZSB3ZSBhcmUgbmF2aWdhdGluZyBvciBjb25uZWN0aW5nLCBkcm9wIHJlbG9hZCBjb29raWUgaW4gY2FzZVxuICAgKiB3ZSBpc3N1ZSB0aGUgY29va2llIGJ1dCB0aGUgbmV4dCByZXF1ZXN0IHdhcyBpbnRlcnJ1cHRlZCBhbmQgdGhlIHNlcnZlciBuZXZlciBkcm9wcGVkIGl0XG4gICAqL1xuICByZXNldFJlbG9hZFN0YXR1cygpIHtcbiAgICBicm93c2VyX2RlZmF1bHQuZGVsZXRlQ29va2llKFBIWF9SRUxPQURfU1RBVFVTKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGNvbW1pdFBlbmRpbmdMaW5rKGxpbmtSZWYpIHtcbiAgICBpZiAodGhpcy5saW5rUmVmICE9PSBsaW5rUmVmKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0aGlzLnBlbmRpbmdMaW5rICE9PSBudWxsKSB7XG4gICAgICB0aGlzLmhyZWYgPSB0aGlzLnBlbmRpbmdMaW5rO1xuICAgICAgdGhpcy5wZW5kaW5nTGluayA9IG51bGw7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgZ2V0SHJlZigpIHtcbiAgICByZXR1cm4gdGhpcy5ocmVmO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgaGFzUGVuZGluZ0xpbmsoKSB7XG4gICAgcmV0dXJuICEhdGhpcy5wZW5kaW5nTGluaztcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGJpbmQoZXZlbnRzLCBjYWxsYmFjaykge1xuICAgIGZvciAoY29uc3QgZXZlbnQgaW4gZXZlbnRzKSB7XG4gICAgICBjb25zdCBicm93c2VyRXZlbnROYW1lID0gZXZlbnRzW2V2ZW50XTtcbiAgICAgIHRoaXMub24oYnJvd3NlckV2ZW50TmFtZSwgKGUpID0+IHtcbiAgICAgICAgY29uc3QgYmluZGluZyA9IHRoaXMuYmluZGluZyhldmVudCk7XG4gICAgICAgIGNvbnN0IHdpbmRvd0JpbmRpbmcgPSB0aGlzLmJpbmRpbmcoYHdpbmRvdy0ke2V2ZW50fWApO1xuICAgICAgICBjb25zdCB0YXJnZXRQaHhFdmVudCA9IGUudGFyZ2V0IGluc3RhbmNlb2YgRWxlbWVudCAmJiBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoYmluZGluZyk7XG4gICAgICAgIGlmICghKGUudGFyZ2V0IGluc3RhbmNlb2YgRWxlbWVudCkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRhcmdldFBoeEV2ZW50KSB7XG4gICAgICAgICAgdGhpcy5kZWJvdW5jZShlLnRhcmdldCwgZSwgYnJvd3NlckV2ZW50TmFtZSwgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy53aXRoaW5Pd25lcnMoZS50YXJnZXQsICh2aWV3KSA9PiB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrKFxuICAgICAgICAgICAgICAgIGUsXG4gICAgICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICAgICAgdmlldyxcbiAgICAgICAgICAgICAgICBlLnRhcmdldCxcbiAgICAgICAgICAgICAgICB0YXJnZXRQaHhFdmVudCxcbiAgICAgICAgICAgICAgICBudWxsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkb21fZGVmYXVsdC5hbGwoZG9jdW1lbnQsIGBbJHt3aW5kb3dCaW5kaW5nfV1gLCAoZWwpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBoeEV2ZW50ID0gZWwuZ2V0QXR0cmlidXRlKHdpbmRvd0JpbmRpbmcpO1xuICAgICAgICAgICAgdGhpcy5kZWJvdW5jZShlbCwgZSwgYnJvd3NlckV2ZW50TmFtZSwgKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLndpdGhpbk93bmVycyhlbCwgKHZpZXcpID0+IHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhcbiAgICAgICAgICAgICAgICAgIGUsXG4gICAgICAgICAgICAgICAgICBldmVudCxcbiAgICAgICAgICAgICAgICAgIHZpZXcsXG4gICAgICAgICAgICAgICAgICBlbCxcbiAgICAgICAgICAgICAgICAgIHBoeEV2ZW50LFxuICAgICAgICAgICAgICAgICAgXCJ3aW5kb3dcIlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgI
1H0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGJpbmRDbGlja3MoKSB7XG4gICAgdGhpcy5vbihcIm1vdXNlZG93blwiLCAoZSkgPT4gdGhpcy5jbGlja1N0YXJ0ZWRBdFRhcmdldCA9IGUudGFyZ2V0KTtcbiAgICB0aGlzLmJpbmRDbGljaygpO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgYmluZENsaWNrKCkge1xuICAgIGNvbnN0IGNsaWNrID0gdGhpcy5iaW5kaW5nKFwiY2xpY2tcIik7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBcImNsaWNrXCIsXG4gICAgICAoZSkgPT4ge1xuICAgICAgICBsZXQgdGFyZ2V0ID0gZS50YXJnZXQgJiYgZG9tX2RlZmF1bHQuZWxlbWVudEZyb21UYXJnZXQoZS50YXJnZXQpO1xuICAgICAgICBpZiAoIXRhcmdldCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZS5kZXRhaWwgPT09IDApXG4gICAgICAgICAgdGhpcy5jbGlja1N0YXJ0ZWRBdFRhcmdldCA9IHRhcmdldDtcbiAgICAgICAgY29uc3QgY2xpY2tTdGFydGVkQXRUYXJnZXQgPSB0aGlzLmNsaWNrU3RhcnRlZEF0VGFyZ2V0IHx8IHRhcmdldDtcbiAgICAgICAgdGFyZ2V0ID0gY2xvc2VzdFBoeEJpbmRpbmcodGFyZ2V0LCBjbGljayk7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hDbGlja0F3YXkoZSwgY2xpY2tTdGFydGVkQXRUYXJnZXQpO1xuICAgICAgICB0aGlzLmNsaWNrU3RhcnRlZEF0VGFyZ2V0ID0gbnVsbDtcbiAgICAgICAgaWYgKCF0YXJnZXQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGh4RXZlbnQgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKGNsaWNrKTtcbiAgICAgICAgaWYgKCFwaHhFdmVudCkge1xuICAgICAgICAgIGlmIChkb21fZGVmYXVsdC5pc05ld1BhZ2VDbGljayhlLCB3aW5kb3cubG9jYXRpb24pKSB7XG4gICAgICAgICAgICB0aGlzLnVubG9hZCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRhcmdldC5nZXRBdHRyaWJ1dGUoXCJocmVmXCIpID09PSBcIiNcIikge1xuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGFyZ2V0Lmhhc0F0dHJpYnV0ZShQSFhfUkVGX1NSQykpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kZWJvdW5jZSh0YXJnZXQsIGUsIFwiY2xpY2tcIiwgKCkgPT4ge1xuICAgICAgICAgIHRoaXMud2l0aGluT3duZXJzKHRhcmdldCwgKHZpZXcpID0+IHtcbiAgICAgICAgICAgIGpzX2RlZmF1bHQuZXhlYyhlLCBcImNsaWNrXCIsIHBoeEV2ZW50LCB2aWV3LCB0YXJnZXQsIFtcbiAgICAgICAgICAgICAgXCJwdXNoXCIsXG4gICAgICAgICAgICAgIHsgZGF0YTogdGhpcy5ldmVudE1ldGEoXCJjbGlja1wiLCBlLCB0YXJnZXQpIH1cbiAgICAgICAgICAgIF0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICBmYWxzZVxuICAgICk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBkaXNwYXRjaENsaWNrQXdheShlLCBjbGlja1N0YXJ0ZWRBdCkge1xuICAgIGNvbnN0IHBoeENsaWNrQXdheSA9IHRoaXMuYmluZGluZyhcImNsaWNrLWF3YXlcIik7XG4gICAgY29uc3QgcG9ydGFsID0gY2xpY2tTdGFydGVkQXQuY2xvc2VzdChgWyR7UEhYX1RFTEVQT1JURURfU1JDfV1gKTtcbiAgICBjb25zdCBwb3J0YWxTdGFydGVkQXQgPSBwb3J0YWwgJiYgZG9tX2RlZmF1bHQuYnlJZChwb3J0YWwuZ2V0QXR0cmlidXRlKFBIWF9URUxFUE9SVEVEX1NSQykpO1xuICAgIGRvbV9kZWZhdWx0LmFsbChkb2N1bWVudCwgYFske3BoeENsaWNrQXdheX1dYCwgKGVsKSA9PiB7XG4gICAgICBsZXQgc3RhcnRlZEF0ID0gY2xpY2tTdGFydGVkQXQ7XG4gICAgICBpZiAocG9ydGFsICYmICFwb3J0YWwuY29udGFpbnMoZWwpKSB7XG4gICAgICAgIHN0YXJ0ZWRBdCA9IHBvcnRhbFN0YXJ0ZWRBdDtcbiAgICAgIH1cbiAgICAgIGlmICghKGVsLmlzU2FtZU5vZGUoc3RhcnRlZEF0KSB8fCBlbC5jb250YWlucyhzdGFydGVkQXQpIHx8IC8vIFdoZW4gY2xpY2tpbmcgYSBsaW5rIHdpdGggY3VzdG9tIG1ldGhvZCxcbiAgICAgIC8vIHBob2VuaXhfaHRtbCB0cmlnZ2VycyBhIGNsaWNrIG9uIGEgc3VibWl0IGJ1dHRvblxuICAgICAgLy8gb2YgYSBoaWRkZW4gZm9ybSBhcHBlbmRlZCB0byB0aGUgYm9keS4gRm9yIHN1Y2ggY2FzZXNcbiAgICAgIC8vIHdoZXJlIHRoZSBjbGlja2VkIHRhcmdldCBpcyBoaWRkZW4sIHdlIHNraXAgY2xpY2stYXdheS5cbiAgICAgIC8vXG4gICAgICAvLyBBbHNvLCB3aGVuIHdlIGhhdmUgYSBwb3J0YWwsIHdlIGRvbid0IHdhbnQgdG8gY2hlY2sgdGhlIHZpc2liaWxpdHlcbiAgICAgIC8vIG9mIHRoZSBwb3J0YWwgc291cmNlLCBhcyBpdCdzIGEgPHRlbXBsYXRlPiB0aGF0IGlzIGFsd2F5cyBub3QgdmlzaWJsZS5cbiAgICAgIC8vIEluc3RlYWQsIGNoZWNrIHRoZSB2aXNpYmlsaXR5IG9mIHRoZSBvcmlnaW5hbCBjbGljayB0YXJnZXQuXG4gICAgICAhanNfZGVmYXVsdC5pc1Zpc2libGUoY2xpY2tTdGFydGVkQXQpKSkge1xuICAgICAgICB0aGlzLndpdGhpbk93bmVycyhlbCwgKHZpZXcpID0+IHtcbiAgICAgICAgICBjb25zdCBwaHhFdmVudCA9IGVsLmdldEF0dHJpYnV0ZShwaHhDbGlja0F3YXkpO1xuICAgICAgICAgIGlmIChqc19kZWZhdWx0LmlzVmlzaWJsZShlbCkgJiYganNfZGVmYXVsdC5pc0luVmlld3BvcnQoZWwpKSB7XG4gICAgICAgICAgICBqc19kZWZhdWx0LmV4ZWMoZSwgXCJjbGlja1wiLCBwaHhFdmVudCwgdmlldywgZWwsIFtcbiAgICAgICAgICAgICAgXCJwdXNoXCIsXG4gICAgICAgICAgICAgIHsgZGF0YTogdGhpcy5ldmVudE1ldGEoXCJjbGlja1wiLCBlLCBlLnRhcmdldCkgfVxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGJpbmROYXYoKSB7XG4gICAgaWYgKCFicm93c2VyX2RlZmF1bHQuY2FuUHVzaFN0YXRlKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGhpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb24pIHtcbiAgICAgIGhpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb24gPSBcIm1hbnVhbFwiO1xuICAgIH1cbiAgICBsZXQgc2Nyb2xsVGltZXIgPSBudWxsO1xuICAgIHdpbmRvdy5hZGR
1FdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsIChfZSkgPT4ge1xuICAgICAgc2Nyb2xsVGltZXIgIT0gbnVsbCAmJiBjbGVhclRpbWVvdXQoc2Nyb2xsVGltZXIpO1xuICAgICAgc2Nyb2xsVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgYnJvd3Nlcl9kZWZhdWx0LnVwZGF0ZUN1cnJlbnRTdGF0ZShcbiAgICAgICAgICAoc3RhdGUpID0+IE9iamVjdC5hc3NpZ24oc3RhdGUsIHsgc2Nyb2xsOiB3aW5kb3cuc2Nyb2xsWSB9KVxuICAgICAgICApO1xuICAgICAgfSwgMTAwKTtcbiAgICB9KTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIFwicG9wc3RhdGVcIixcbiAgICAgIChldmVudCkgPT4ge1xuICAgICAgICBpZiAoIXRoaXMucmVnaXN0ZXJOZXdMb2NhdGlvbih3aW5kb3cubG9jYXRpb24pKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgdHlwZSwgYmFja1R5cGUsIGlkLCBzY3JvbGwsIHBvc2l0aW9uIH0gPSBldmVudC5zdGF0ZSB8fCB7fTtcbiAgICAgICAgY29uc3QgaHJlZiA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmO1xuICAgICAgICBjb25zdCBpc0ZvcndhcmQgPSBwb3NpdGlvbiA+IHRoaXMuY3VycmVudEhpc3RvcnlQb3NpdGlvbjtcbiAgICAgICAgY29uc3QgbmF2VHlwZSA9IGlzRm9yd2FyZCA/IHR5cGUgOiBiYWNrVHlwZSB8fCB0eXBlO1xuICAgICAgICB0aGlzLmN1cnJlbnRIaXN0b3J5UG9zaXRpb24gPSBwb3NpdGlvbiB8fCAwO1xuICAgICAgICB0aGlzLnNlc3Npb25TdG9yYWdlLnNldEl0ZW0oXG4gICAgICAgICAgUEhYX0xWX0hJU1RPUllfUE9TSVRJT04sXG4gICAgICAgICAgdGhpcy5jdXJyZW50SGlzdG9yeVBvc2l0aW9uLnRvU3RyaW5nKClcbiAgICAgICAgKTtcbiAgICAgICAgZG9tX2RlZmF1bHQuZGlzcGF0Y2hFdmVudCh3aW5kb3csIFwicGh4Om5hdmlnYXRlXCIsIHtcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIGhyZWYsXG4gICAgICAgICAgICBwYXRjaDogbmF2VHlwZSA9PT0gXCJwYXRjaFwiLFxuICAgICAgICAgICAgcG9wOiB0cnVlLFxuICAgICAgICAgICAgZGlyZWN0aW9uOiBpc0ZvcndhcmQgPyBcImZvcndhcmRcIiA6IFwiYmFja3dhcmRcIlxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucmVxdWVzdERPTVVwZGF0ZSgoKSA9PiB7XG4gICAgICAgICAgY29uc3QgY2FsbGJhY2sgPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLm1heWJlU2Nyb2xsKHNjcm9sbCk7XG4gICAgICAgICAgfTtcbiAgICAgICAgICBpZiAodGhpcy5tYWluICYmIHRoaXMubWFpbi5pc0Nvbm5lY3RlZCgpICYmIG5hdlR5cGUgPT09IFwicGF0Y2hcIiAmJiBpZCA9PT0gdGhpcy5tYWluLmlkKSB7XG4gICAgICAgICAgICB0aGlzLm1haW4ucHVzaExpbmtQYXRjaChldmVudCwgaHJlZiwgbnVsbCwgY2FsbGJhY2spO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnJlcGxhY2VNYWluKGhyZWYsIG51bGwsIGNhbGxiYWNrKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICAgIGZhbHNlXG4gICAgKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIFwiY2xpY2tcIixcbiAgICAgIChlKSA9PiB7XG4gICAgICAgIGxldCBlbCA9IGUudGFyZ2V0ICYmIGRvbV9kZWZhdWx0LmVsZW1lbnRGcm9tVGFyZ2V0KGUudGFyZ2V0KTtcbiAgICAgICAgaWYgKCFlbCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB0YXJnZXQgPSBjbG9zZXN0UGh4QmluZGluZyhcbiAgICAgICAgICBlbCxcbiAgICAgICAgICBQSFhfTElWRV9MSU5LXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHR5cGUgPSB0YXJnZXQgJiYgdGFyZ2V0LmdldEF0dHJpYnV0ZShQSFhfTElWRV9MSU5LKTtcbiAgICAgICAgaWYgKCF0eXBlIHx8ICF0aGlzLmlzQ29ubmVjdGVkKCkgfHwgIXRoaXMubWFpbiB8fCBkb21fZGVmYXVsdC53YW50c05ld1RhYihlKSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBocmVmID0gdGFyZ2V0LmhyZWYgaW5zdGFuY2VvZiBTVkdBbmltYXRlZFN0cmluZyA/IHRhcmdldC5ocmVmLmJhc2VWYWwgOiB0YXJnZXQuaHJlZjtcbiAgICAgICAgY29uc3QgbGlua1N0YXRlID0gdGFyZ2V0LmdldEF0dHJpYnV0ZShQSFhfTElOS19TVEFURSk7XG4gICAgICAgIGlmIChsaW5rU3RhdGUgIT09IFwicmVwbGFjZVwiICYmIGxpbmtTdGF0ZSAhPT0gXCJwdXNoXCIpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgZXhwZWN0ZWQgJHtQSFhfTElOS19TVEFURX0gdG8gYmUgXCJyZXBsYWNlXCIgb3IgXCJwdXNoXCIsIGdvdDogJHtsaW5rU3RhdGV9YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICAgICAgICBpZiAodGhpcy5wZW5kaW5nTGluayA9PT0gaHJlZikge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgICAgIGlmICh0eXBlID09PSBcInBhdGNoXCIpIHtcbiAgICAgICAgICAgIHRoaXMucHVzaEhpc3RvcnlQYXRjaChlLCBocmVmLCBsaW5rU3RhdGUsIHRhcmdldCk7XG4gICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSBcInJlZGlyZWN0XCIpIHtcbiAgICAgICAgICAgIHRoaXMuaGlzdG9yeVJlZGlyZWN0KGUsIGhyZWYsIGxpbmtTdGF0ZSwgbnVsbCwgdGFyZ2V0KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICBgZXhwZWN0ZWQgJHtQSFhfTElWRV9MSU5LfSB0byBiZSBcInBhdGNoXCIgb3IgXCJyZWRpcmVjdFwiLCBnb3Q6ICR7dHlwZX1gXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBwaHhDbGljayA9IHRhcmdldC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFwiY2xpY2tcIikpO1xuICAgICAgICAgIGlmIChwaHhDbGljaykge1xuICAgICAgICAgICAgdGhpcy5yZXF1ZXN0RE9NVXBkYXRlKCgpID0+IHRoaXMuZXhlY0pTKHRhcmdldCwgcGh4Q2xpY2ssIFwiY2xpY2tcIikpO1xuICAgICAgICAgI
1H1cbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgZmFsc2VcbiAgICApO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgbWF5YmVTY3JvbGwoc2Nyb2xsKSB7XG4gICAgaWYgKHR5cGVvZiBzY3JvbGwgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgIHdpbmRvdy5zY3JvbGxUbygwLCBzY3JvbGwpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgZGlzcGF0Y2hFdmVudChldmVudCwgcGF5bG9hZCA9IHt9KSB7XG4gICAgZG9tX2RlZmF1bHQuZGlzcGF0Y2hFdmVudCh3aW5kb3csIGBwaHg6JHtldmVudH1gLCB7IGRldGFpbDogcGF5bG9hZCB9KTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGRpc3BhdGNoRXZlbnRzKGV2ZW50cykge1xuICAgIGV2ZW50cy5mb3JFYWNoKChbZXZlbnQsIHBheWxvYWRdKSA9PiB0aGlzLmRpc3BhdGNoRXZlbnQoZXZlbnQsIHBheWxvYWQpKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIHdpdGhQYWdlTG9hZGluZyhpbmZvLCBjYWxsYmFjaykge1xuICAgIGRvbV9kZWZhdWx0LmRpc3BhdGNoRXZlbnQod2luZG93LCBcInBoeDpwYWdlLWxvYWRpbmctc3RhcnRcIiwgeyBkZXRhaWw6IGluZm8gfSk7XG4gICAgY29uc3QgZG9uZSA9ICgpID0+IGRvbV9kZWZhdWx0LmRpc3BhdGNoRXZlbnQod2luZG93LCBcInBoeDpwYWdlLWxvYWRpbmctc3RvcFwiLCB7IGRldGFpbDogaW5mbyB9KTtcbiAgICByZXR1cm4gY2FsbGJhY2sgPyBjYWxsYmFjayhkb25lKSA6IGRvbmU7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwdXNoSGlzdG9yeVBhdGNoKGUsIGhyZWYsIGxpbmtTdGF0ZSwgdGFyZ2V0RWwpIHtcbiAgICBpZiAoIXRoaXMuaXNDb25uZWN0ZWQoKSB8fCAhKHRoaXMubWFpbiAmJiB0aGlzLm1haW4uaXNNYWluKCkpKSB7XG4gICAgICByZXR1cm4gYnJvd3Nlcl9kZWZhdWx0LnJlZGlyZWN0KGhyZWYpO1xuICAgIH1cbiAgICB0aGlzLndpdGhQYWdlTG9hZGluZyh7IHRvOiBocmVmLCBraW5kOiBcInBhdGNoXCIgfSwgKGRvbmUpID0+IHtcbiAgICAgIHRoaXMubWFpbi5wdXNoTGlua1BhdGNoKGUsIGhyZWYsIHRhcmdldEVsLCAobGlua1JlZikgPT4ge1xuICAgICAgICB0aGlzLmhpc3RvcnlQYXRjaChocmVmLCBsaW5rU3RhdGUsIGxpbmtSZWYpO1xuICAgICAgICBkb25lKCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGhpc3RvcnlQYXRjaChocmVmLCBsaW5rU3RhdGUsIGxpbmtSZWYgPSB0aGlzLnNldFBlbmRpbmdMaW5rKGhyZWYpKSB7XG4gICAgaWYgKCF0aGlzLmNvbW1pdFBlbmRpbmdMaW5rKGxpbmtSZWYpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuY3VycmVudEhpc3RvcnlQb3NpdGlvbisrO1xuICAgIHRoaXMuc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShcbiAgICAgIFBIWF9MVl9ISVNUT1JZX1BPU0lUSU9OLFxuICAgICAgdGhpcy5jdXJyZW50SGlzdG9yeVBvc2l0aW9uLnRvU3RyaW5nKClcbiAgICApO1xuICAgIGJyb3dzZXJfZGVmYXVsdC51cGRhdGVDdXJyZW50U3RhdGUoKHN0YXRlKSA9PiAoeyAuLi5zdGF0ZSwgYmFja1R5cGU6IFwicGF0Y2hcIiB9KSk7XG4gICAgYnJvd3Nlcl9kZWZhdWx0LnB1c2hTdGF0ZShcbiAgICAgIGxpbmtTdGF0ZSxcbiAgICAgIHtcbiAgICAgICAgdHlwZTogXCJwYXRjaFwiLFxuICAgICAgICBpZDogdGhpcy5tYWluLmlkLFxuICAgICAgICBwb3NpdGlvbjogdGhpcy5jdXJyZW50SGlzdG9yeVBvc2l0aW9uXG4gICAgICB9LFxuICAgICAgaHJlZlxuICAgICk7XG4gICAgZG9tX2RlZmF1bHQuZGlzcGF0Y2hFdmVudCh3aW5kb3csIFwicGh4Om5hdmlnYXRlXCIsIHtcbiAgICAgIGRldGFpbDogeyBwYXRjaDogdHJ1ZSwgaHJlZiwgcG9wOiBmYWxzZSwgZGlyZWN0aW9uOiBcImZvcndhcmRcIiB9XG4gICAgfSk7XG4gICAgdGhpcy5yZWdpc3Rlck5ld0xvY2F0aW9uKHdpbmRvdy5sb2NhdGlvbik7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBoaXN0b3J5UmVkaXJlY3QoZSwgaHJlZiwgbGlua1N0YXRlLCBmbGFzaCwgdGFyZ2V0RWwpIHtcbiAgICBjb25zdCBjbGlja0xvYWRpbmcgPSB0YXJnZXRFbCAmJiBlLmlzVHJ1c3RlZCAmJiBlLnR5cGUgIT09IFwicG9wc3RhdGVcIjtcbiAgICBpZiAoY2xpY2tMb2FkaW5nKSB7XG4gICAgICB0YXJnZXRFbC5jbGFzc0xpc3QuYWRkKFwicGh4LWNsaWNrLWxvYWRpbmdcIik7XG4gICAgfVxuICAgIGlmICghdGhpcy5pc0Nvbm5lY3RlZCgpIHx8ICEodGhpcy5tYWluICYmIHRoaXMubWFpbi5pc01haW4oKSkpIHtcbiAgICAgIHJldHVybiBicm93c2VyX2RlZmF1bHQucmVkaXJlY3QoaHJlZiwgZmxhc2gpO1xuICAgIH1cbiAgICBpZiAoL15cXC8kfF5cXC9bXlxcL10rLiokLy50ZXN0KGhyZWYpKSB7XG4gICAgICBjb25zdCB7IHByb3RvY29sLCBob3N0IH0gPSB3aW5kb3cubG9jYXRpb247XG4gICAgICBocmVmID0gYCR7cHJvdG9jb2x9Ly8ke2hvc3R9JHtocmVmfWA7XG4gICAgfVxuICAgIGNvbnN0IHNjcm9sbCA9IHdpbmRvdy5zY3JvbGxZO1xuICAgIHRoaXMud2l0aFBhZ2VMb2FkaW5nKHsgdG86IGhyZWYsIGtpbmQ6IFwicmVkaXJlY3RcIiB9LCAoZG9uZSkgPT4ge1xuICAgICAgdGhpcy5yZXBsYWNlTWFpbihocmVmLCBmbGFzaCwgKGxpbmtSZWYpID0+IHtcbiAgICAgICAgaWYgKGxpbmtSZWYgPT09IHRoaXMubGlua1JlZikge1xuICAgICAgICAgIHRoaXMuY3VycmVudEhpc3RvcnlQb3NpdGlvbisrO1xuICAgICAgICAgIHRoaXMuc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShcbiAgICAgICAgICAgIFBIWF9MVl9ISVNUT1JZX1BPU0lUSU9OLFxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SGlzdG9yeVBvc2l0aW9uLnRvU3RyaW5nKClcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyb3dzZXJfZGVmYXVsdC51cGRhdGVDdXJyZW50U3RhdGUoKHN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgICAgICBiYWNrVHlwZTogXCJyZWRpcmVjdFwiXG4gICAgICAgICAgfSkpO1xuICAgICAgICAgIGJyb3dzZXJfZGVmYXVsdC5wdXNoU3RhdGUoXG4gICAgICAgICAgICBsaW5rU3RhdGUsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgI
1HR5cGU6IFwicmVkaXJlY3RcIixcbiAgICAgICAgICAgICAgaWQ6IHRoaXMubWFpbi5pZCxcbiAgICAgICAgICAgICAgc2Nyb2xsLFxuICAgICAgICAgICAgICBwb3NpdGlvbjogdGhpcy5jdXJyZW50SGlzdG9yeVBvc2l0aW9uXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaHJlZlxuICAgICAgICAgICk7XG4gICAgICAgICAgZG9tX2RlZmF1bHQuZGlzcGF0Y2hFdmVudCh3aW5kb3csIFwicGh4Om5hdmlnYXRlXCIsIHtcbiAgICAgICAgICAgIGRldGFpbDogeyBocmVmLCBwYXRjaDogZmFsc2UsIHBvcDogZmFsc2UsIGRpcmVjdGlvbjogXCJmb3J3YXJkXCIgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRoaXMucmVnaXN0ZXJOZXdMb2NhdGlvbih3aW5kb3cubG9jYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjbGlja0xvYWRpbmcpIHtcbiAgICAgICAgICB0YXJnZXRFbC5jbGFzc0xpc3QucmVtb3ZlKFwicGh4LWNsaWNrLWxvYWRpbmdcIik7XG4gICAgICAgIH1cbiAgICAgICAgZG9uZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICByZWdpc3Rlck5ld0xvY2F0aW9uKG5ld0xvY2F0aW9uKSB7XG4gICAgY29uc3QgeyBwYXRobmFtZSwgc2VhcmNoIH0gPSB0aGlzLmN1cnJlbnRMb2NhdGlvbjtcbiAgICBpZiAocGF0aG5hbWUgKyBzZWFyY2ggPT09IG5ld0xvY2F0aW9uLnBhdGhuYW1lICsgbmV3TG9jYXRpb24uc2VhcmNoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3VycmVudExvY2F0aW9uID0gY2xvbmUobmV3TG9jYXRpb24pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgYmluZEZvcm1zKCkge1xuICAgIGxldCBpdGVyYXRpb25zID0gMDtcbiAgICBsZXQgZXh0ZXJuYWxGb3JtU3VibWl0dGVkID0gZmFsc2U7XG4gICAgdGhpcy5vbihcInN1Ym1pdFwiLCAoZSkgPT4ge1xuICAgICAgaWYgKCEoZS50YXJnZXQgaW5zdGFuY2VvZiBIVE1MRm9ybUVsZW1lbnQpKVxuICAgICAgICByZXR1cm47XG4gICAgICBjb25zdCBwaHhTdWJtaXQgPSBlLnRhcmdldC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFwic3VibWl0XCIpKTtcbiAgICAgIGNvbnN0IHBoeENoYW5nZSA9IGUudGFyZ2V0LmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoXCJjaGFuZ2VcIikpO1xuICAgICAgaWYgKCFleHRlcm5hbEZvcm1TdWJtaXR0ZWQgJiYgcGh4Q2hhbmdlICYmICFwaHhTdWJtaXQpIHtcbiAgICAgICAgZXh0ZXJuYWxGb3JtU3VibWl0dGVkID0gdHJ1ZTtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLndpdGhpbk93bmVycyhlLnRhcmdldCwgKHZpZXcpID0+IHtcbiAgICAgICAgICB2aWV3LmRpc2FibGVGb3JtKGUudGFyZ2V0KTtcbiAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgIGlmIChkb21fZGVmYXVsdC5pc1VubG9hZGFibGVGb3JtU3VibWl0KGUpKSB7XG4gICAgICAgICAgICAgIHRoaXMudW5sb2FkKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlLnRhcmdldC5zdWJtaXQoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5vbihcInN1Ym1pdFwiLCAoZSkgPT4ge1xuICAgICAgaWYgKCEoZS50YXJnZXQgaW5zdGFuY2VvZiBIVE1MRm9ybUVsZW1lbnQpKVxuICAgICAgICByZXR1cm47XG4gICAgICBjb25zdCBwaHhFdmVudCA9IGUudGFyZ2V0LmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoXCJzdWJtaXRcIikpO1xuICAgICAgaWYgKCFwaHhFdmVudCkge1xuICAgICAgICBpZiAoZG9tX2RlZmF1bHQuaXNVbmxvYWRhYmxlRm9ybVN1Ym1pdChlKSkge1xuICAgICAgICAgIHRoaXMudW5sb2FkKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgZS50YXJnZXQuZGlzYWJsZWQgPSB0cnVlO1xuICAgICAgdGhpcy53aXRoaW5Pd25lcnMoZS50YXJnZXQsICh2aWV3KSA9PiB7XG4gICAgICAgIGpzX2RlZmF1bHQuZXhlYyhlLCBcInN1Ym1pdFwiLCBwaHhFdmVudCwgdmlldywgZS50YXJnZXQsIFtcbiAgICAgICAgICBcInB1c2hcIixcbiAgICAgICAgICB7IHN1Ym1pdHRlcjogZS5zdWJtaXR0ZXIgfVxuICAgICAgICBdKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIGZvciAoY29uc3QgdHlwZSBvZiBbXCJjaGFuZ2VcIiwgXCJpbnB1dFwiXSkge1xuICAgICAgdGhpcy5vbih0eXBlLCAoZSkgPT4ge1xuICAgICAgICBpZiAoIWRvbV9kZWZhdWx0LmlzRm9ybUFzc29jaWF0ZWQoZS50YXJnZXQpKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChlIGluc3RhbmNlb2YgQ3VzdG9tRXZlbnQgJiYgZS50YXJnZXQuZm9ybSA9PT0gdm9pZCAwKSB7XG4gICAgICAgICAgaWYgKGUuZGV0YWlsICYmIGUuZGV0YWlsLmRpc3BhdGNoZXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgYGRpc3BhdGNoaW5nIGEgY3VzdG9tICR7dHlwZX0gZXZlbnQgaXMgb25seSBzdXBwb3J0ZWQgb24gaW5wdXQgZWxlbWVudHMgaW5zaWRlIGEgZm9ybWBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbnB1dCA9IGUudGFyZ2V0O1xuICAgICAgICBjb25zdCBwaHhDaGFuZ2UgPSB0aGlzLmJpbmRpbmcoXCJjaGFuZ2VcIik7XG4gICAgICAgIGlmICh0aGlzLmJsb2NrUGh4Q2hhbmdlV2hpbGVDb21wb3NpbmcgJiYgZSBpbnN0YW5jZW9mIElucHV0RXZlbnQgJiYgZS5pc0NvbXBvc2luZykge1xuICAgICAgICAgIGNvbnN0IGtleSA9IGBjb21wb3NpdGlvbi1saXN0ZW5lci0ke3R5cGV9YDtcbiAgICAgICAgICBpZiAoIWRvbV9kZWZhdWx0LnByaXZhdGUoaW5wdXQsIGtleSkpIHtcbiAgICAgICAgICAgIGRvbV9kZWZhdWx0LnB1dFByaXZhdGUoaW5wdXQsIGtleSwgdHJ1ZSk7XG4gICAgICAgICAgICBpbnB1dC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICBcImNvbXBvc2l0aW9uZW5kXCIsXG4gICAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICBpbnB1dC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCh0eXBlLCB7IGJ1YmJsZXM6IHRydWUgfSkpO1xuICAgICAgICAgICAgICAgIGRvbV9kZWZhdWx0LmRlbGV0ZVByaXZhdGUoaW5wdXQsIGtleSk7XG4gICAgICAgICAgICAgI
1H0sXG4gICAgICAgICAgICAgIHsgb25jZTogdHJ1ZSB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaW5wdXRFdmVudCA9IGlucHV0LmdldEF0dHJpYnV0ZShwaHhDaGFuZ2UpO1xuICAgICAgICBjb25zdCBmb3JtRXZlbnQgPSBpbnB1dC5mb3JtICYmIGlucHV0LmZvcm0uZ2V0QXR0cmlidXRlKHBoeENoYW5nZSk7XG4gICAgICAgIGNvbnN0IHBoeEV2ZW50ID0gaW5wdXRFdmVudCB8fCBmb3JtRXZlbnQ7XG4gICAgICAgIGlmICghcGh4RXZlbnQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlucHV0LnR5cGUgPT09IFwibnVtYmVyXCIgJiYgaW5wdXQudmFsaWRpdHkgJiYgaW5wdXQudmFsaWRpdHkuYmFkSW5wdXQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGlzcGF0Y2hlciA9IGlucHV0RXZlbnQgPyBpbnB1dCA6IGlucHV0LmZvcm07XG4gICAgICAgIGNvbnN0IGN1cnJlbnRJdGVyYXRpb25zID0gaXRlcmF0aW9ucztcbiAgICAgICAgaXRlcmF0aW9ucysrO1xuICAgICAgICBjb25zdCB7IGF0LCB0eXBlOiBsYXN0VHlwZSB9ID0gZG9tX2RlZmF1bHQucHJpdmF0ZShpbnB1dCwgXCJwcmV2LWl0ZXJhdGlvblwiKSB8fCB7fTtcbiAgICAgICAgaWYgKGF0ID09PSBjdXJyZW50SXRlcmF0aW9ucyAtIDEgJiYgdHlwZSA9PT0gXCJjaGFuZ2VcIiAmJiBsYXN0VHlwZSA9PT0gXCJpbnB1dFwiKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGRvbV9kZWZhdWx0LnB1dFByaXZhdGUoaW5wdXQsIFwicHJldi1pdGVyYXRpb25cIiwge1xuICAgICAgICAgIGF0OiBjdXJyZW50SXRlcmF0aW9ucyxcbiAgICAgICAgICB0eXBlXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRlYm91bmNlKGlucHV0LCBlLCB0eXBlLCAoKSA9PiB7XG4gICAgICAgICAgdGhpcy53aXRoaW5Pd25lcnMoZGlzcGF0Y2hlciwgKHZpZXcpID0+IHtcbiAgICAgICAgICAgIGRvbV9kZWZhdWx0LnB1dFByaXZhdGUoaW5wdXQsIFBIWF9IQVNfRk9DVVNFRCwgdHJ1ZSk7XG4gICAgICAgICAgICBqc19kZWZhdWx0LmV4ZWMoZSwgXCJjaGFuZ2VcIiwgcGh4RXZlbnQsIHZpZXcsIGlucHV0LCBbXG4gICAgICAgICAgICAgIFwicHVzaFwiLFxuICAgICAgICAgICAgICB7IF90YXJnZXQ6IGlucHV0Lm5hbWUsIGRpc3BhdGNoZXIgfVxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMub24oXCJyZXNldFwiLCAoZSkgPT4ge1xuICAgICAgY29uc3QgZm9ybSA9IGUudGFyZ2V0O1xuICAgICAgZG9tX2RlZmF1bHQucmVzZXRGb3JtKGZvcm0pO1xuICAgICAgY29uc3QgaW5wdXQgPSBBcnJheS5mcm9tKGZvcm0uZWxlbWVudHMpLmZpbmQoXG4gICAgICAgIChlbCkgPT4gXCJ0eXBlXCIgaW4gZWwgJiYgZWwudHlwZSA9PT0gXCJyZXNldFwiXG4gICAgICApO1xuICAgICAgaWYgKGlucHV0KSB7XG4gICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgIGlucHV0LmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgICBuZXcgRXZlbnQoXCJpbnB1dFwiLCB7IGJ1YmJsZXM6IHRydWUsIGNhbmNlbGFibG
1U6IGZhbHNlIH0pXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBkZWJvdW5jZShlbCwgZXZlbnQsIGV2ZW50VHlwZSwgY2FsbGJhY2spIHtcbiAgICBpZiAoZXZlbnRUeXBlID09PSBcImJsdXJcIiB8fCBldmVudFR5cGUgPT09IFwiZm9jdXNvdXRcIikge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfVxuICAgIGNvbnN0IHBoeERlYm91bmNlID0gdGhpcy5iaW5kaW5nKFBIWF9ERUJPVU5DRSk7XG4gICAgY29uc3QgcGh4VGhyb3R0bGUgPSB0aGlzLmJpbmRpbmcoUEhYX1RIUk9UVExFKTtcbiAgICBjb25zdCBkZWZhdWx0RGVib3VuY2UgPSB0aGlzLmRlZmF1bHRzLmRlYm91bmNlLnRvU3RyaW5nKCk7XG4gICAgY29uc3QgZGVmYXVsdFRocm90dGxlID0gdGhpcy5kZWZhdWx0cy50aHJvdHRsZS50b1N0cmluZygpO1xuICAgIHRoaXMud2l0aGluT3duZXJzKGVsLCAodmlldykgPT4ge1xuICAgICAgY29uc3QgYXN5bmNGaWx0ZXIgPSAoKSA9PiAhdmlldy5pc0Rlc3Ryb3llZCgpICYmIGRvY3VtZW50LmJvZHkuY29udGFpbnMoZWwpO1xuICAgICAgZG9tX2RlZmF1bHQuZGVib3VuY2UoXG4gICAgICAgIGVsLFxuICAgICAgICBldmVudCxcbiAgICAgICAgcGh4RGVib3VuY2UsXG4gICAgICAgIGRlZmF1bHREZWJvdW5jZSxcbiAgICAgICAgcGh4VGhyb3R0bGUsXG4gICAgICAgIGRlZmF1bHRUaHJvdHRsZSxcbiAgICAgICAgYXN5bmNGaWx0ZXIsXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgc2lsZW5jZUV2ZW50cyhjYWxsYmFjaykge1xuICAgIHRoaXMuc2lsZW5jZWQgPSB0cnVlO1xuICAgIGNhbGxiYWNrKCk7XG4gICAgdGhpcy5zaWxlbmNlZCA9IGZhbHNlO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgb24oZXZlbnQsIGNhbGxiYWNrKSB7XG4gICAgdGhpcy5ib3VuZEV2ZW50TmFtZXMuYWRkKGV2ZW50KTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgKGUpID0+IHtcbiAgICAgIGlmICghdGhpcy5zaWxlbmNlZCkge1xuICAgICAgICBjYWxsYmFjayhlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIGpzUXVlcnlTZWxlY3RvckFsbChzb3VyY2VFbCwgcXVlcnksIGRlZmF1bHRRdWVyeSkge1xuICAgIGNvbnN0IGFsbCA9IHRoaXMuZG9tQ2FsbGJhY2tzLmpzUXVlcnlTZWxlY3RvckFsbDtcbiAgICByZXR1cm4gYWxsID8gYWxsKHNvdXJjZUVsLCBxdWVyeSwgZGVmYXVsdFF1ZXJ5KSA6IGRlZmF1bHRRdWVyeSgpO1xuICB9XG59O1xudmFyIFRyYW5zaXRpb25TZXQgPSBjbGFzcyB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMudHJhbnNpdGlvbnMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpO1xuICAgIHRoaXMucHJvbWlzZXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpO1xuICAgIHRoaXMucGVuZGluZ09wcyA9IFtdO1xuICB9XG4gIHJlc2V0KCkge1xuICAgIHRoaXMudHJhbnNpdGlvbnMuZm9yRWFjaCgodGltZXIpID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICB0aGlzLnRyYW5zaXRpb25zLmRlbGV0ZSh0aW1lcik7XG4gICAgfSk7XG4gICAgdGhpcy5wcm9taXNlcy5jbGVhcigpO1xuICAgIHRoaXMuZmx1c2hQZW5kaW5nT3BzKCk7XG4gIH1cbiAgYWZ0ZXIoY2FsbGJhY2spIHtcbiAgICBpZiAodGhpcy5zaXplKCkgPT09IDApIHtcbiAgICAgIGNhbGxiYWNrKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHVzaFBlbmRpbmdPcChjYWxsYmFjayk7XG4gICAgfVxuICB9XG4gIGFkZFRyYW5zaXRpb24odGltZSwgb25TdGFydCwgb25Eb25lKSB7XG4gICAgb25TdGFydCgpO1xuICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnRyYW5zaXRpb25zLmRlbGV0ZSh0aW1lcik7XG4gICAgICBvbkRvbmUoKTtcbiAgICAgIHRoaXMuZmx1c2hQZW5kaW5nT3BzKCk7XG4gICAgfSwgdGltZSk7XG4gICAgdGhpcy50cmFuc2l0aW9ucy5hZGQodGltZXIpO1xuICB9XG4gIGFkZEFzeW5jVHJhbnNpdGlvbihwcm9taXNlKSB7XG4gICAgdGhpcy5wcm9taXNlcy5hZGQocHJvbWlzZSk7XG4gICAgcHJvbWlzZS50aGVuKCgpID0+IHtcbiAgICAgIHRoaXMucHJvbWlzZXMuZGVsZXRlKHByb21pc2UpO1xuICAgICAgdGhpcy5mbHVzaFBlbmRpbmdPcHMoKTtcbiAgICB9KTtcbiAgfVxuICBwdXNoUGVuZGluZ09wKG9wKSB7XG4gICAgdGhpcy5wZW5kaW5nT3BzLnB1c2gob3ApO1xuICB9XG4gIHNpemUoKSB7XG4gICAgcmV0dXJuIHRoaXMudHJhbnNpdGlvbnMuc2l6ZSArIHRoaXMucHJvbWlzZXMuc2l6ZTtcbiAgfVxuICBmbHVzaFBlbmRpbmdPcHMoKSB7XG4gICAgaWYgKHRoaXMuc2l6ZSgpID4gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBvcCA9IHRoaXMucGVuZGluZ09wcy5zaGlmdCgpO1xuICAgIGlmIChvcCkge1xuICAgICAgb3AoKTtcbiAgICAgIHRoaXMuZmx1c2hQZW5kaW5nT3BzKCk7XG4gICAgfVxuICB9XG59O1xuXG4vLyBqcy9waG9lbml4X2xpdmVfdmlldy9pbmRleC50c1xuZnVuY3Rpb24gY3JlYXRlSG9vayhlbCwgY2FsbGJhY2tzKSB7XG4gIGxldCBleGlzdGluZ0hvb2sgPSBkb21fZGVmYXVsdC5nZXRDdXN0b21FbEhvb2soZWwpO1xuICBpZiAoZXhpc3RpbmdIb29rKSB7XG4gICAgcmV0dXJuIGV4aXN0aW5nSG9vaztcbiAgfVxuICBpZiAoIWVsLmhhc0F0dHJpYnV0ZShcImlkXCIpKSB7XG4gICAgbG9nRXJyb3IoXG4gICAgICBcIkVsZW1lbnRzIHBhc3NlZCB0byBjcmVhdGVIb29rIG5lZWQgdG8gaGF2ZSBhIHVuaXF1ZSBpZCBhdHRyaWJ1dGVcIixcbiAgICAgIGVsXG4gICAgKTtcbiAgfVxuICBsZXQgaG9vayA9IG5ldyBWaWV3SG9vayhWaWV3LmNsb3Nlc3RWaWV3KGVsKSwgZWwsIGNhbGxiYWNrcyk7XG4gIGRvbV9kZWZhdWx0LnB1dEN1c3RvbUVsSG9vayhlbCwgaG9vayk7XG4gIHJldHVybiBob29rO1xufVxuZnVuY3Rpb24gZ2V0RmlsZVVSTEZvclVwbG9hZChpbnB1dCwgdXBsb2FkUmVmKSB7XG4gIHJldHVybi
1BMaXZlVXBsb2FkZXIuZ2V0RW50cnlEYXRhVVJMKGlucHV0LCB1cGxvYWRSZWYpO1xufVxuZXhwb3J0IHtcbiAgTGl2ZVNvY2tldCxcbiAgVmlld0hvb2ssXG4gIGNyZWF0ZUhvb2ssXG4gIGdldEZpbGVVUkxGb3JVcGxvYWQsXG4gIGlzVXNlZElucHV0XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGhvZW5peF9saXZlX3ZpZXcuZXNtLmpzLm1hcFxuIiwiZnVuY3Rpb24gbyhlLHQpe2xldCBpO3JldHVybiguLi5zKT0+e2NsZWFyVGltZW91dChpKSxpPXNldFRpbWVvdXQoKCk9PntlLmFwcGx5KHRoaXMscyl9LHQpfX1leHBvcnQgZGVmYXVsdHtMaXZlU2VsZWN0Ont0ZXh0SW5wdXQoKXtyZXR1cm4gdGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiaW5wdXRbdHlwZT10ZXh0XVwiKX0sZGVib3VuY2VNc2VjKCl7cmV0dXJuIHBhcnNlSW50KHRoaXMuZWwuZGF0YXNldC5kZWJvdW5jZSl9LHVwZGF0ZU1pbkxlbigpe3JldHVybiBwYXJzZUludCh0aGlzLmVsLmRhdGFzZXQudXBkYXRlTWluTGVuKX0sbWF5YmVTdHlsZUNsZWFyQnV0dG9ucygpe2NvbnN0IGU9dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiYnV0dG9uLmxzLWNsZWFyLWJ1dHRvblwiKTtlJiYodGhpcy50ZXh0SW5wdXQoKS5wYXJlbnRFbGVtZW50LnN0eWxlLnBvc2l0aW9uPVwicmVsYXRpdmVcIix0aGlzLnRleHRJbnB1dCgpLnBhcmVudEVsZW1lbnQuc3R5bGUuZGlzcGxheT1cImZsZXhcIix0aGlzLnRleHRJbnB1dCgpLnBhcmVudEVsZW1lbnQuc3R5bGUuYWxpZ25JdGVtcz1cImNlbnRlclwiLGUuc3R5bGUubWluSGVpZ2h0PVwiMjBweFwiLGUuc3R5bGUubWluV2lkdGg9XCIyMHB4XCIsZS5zdHlsZS5wb3NpdGlvbj1cImFic29sdXRlXCIsZS5zdHlsZS5yaWdodD1cIjVweFwiLGUuc3R5bGUuZGlzcGxheT1cImJsb2NrXCIpLHRoaXMuZWwucXVlcnlTZWxlY3RvckFsbChcImJ1dHRvbi5scy1jbGVhci10YWctYnV0dG9uXCIpLmZvckVhY2godD0+e3Quc3R5bGUubWluSGVpZ2h0PVwiMjBweFwiLHQuc3R5bGUubWluV2lkdGg9XCIyMHB4XCJ9KX0scHVzaEV2ZW50VG9QYXJlbnQoZSx0KXtjb25zdCBpPXRoaXMuZWwuZGF0YXNldC5waHhUYXJnZXQ7aT90aGlzLnB1c2hFdmVudFRvKGksZSx0KTp0aGlzLnB1c2hFdmVudChlLHQpfSxhdHRhY2hEb21FdmVudEhhbmRsZXJzKCl7dGhpcy50ZXh0SW5wdXQoKS5vbmtleWRvd249dD0+e3QuY29kZT09PVwiRW50ZXJcIiYmdC5wcmV2ZW50RGVmYXVsdCgpLHRoaXMucHVzaEV2ZW50VG8odGhpcy5lbCxcImtleWRvd25cIix7a2V5OnQuY29kZX0pfSx0aGlzLmNoYW5nZUV2ZW50cz1vKCh0LGkscyk9Pnt0aGlzLnB1c2hFdmVudFRvKHRoaXMuZWwsXCJjaGFuZ2VcIix7dGV4dDpzfSksdGhpcy5wdXNoRXZlbnRUb1BhcmVudChcImxpdmVfc2VsZWN0X2NoYW5nZVwiLHtpZDp0aGlzLmVsLmlkLGZpZWxkOmksdGV4dDpzfSl9LHRoaXMuZGVib3VuY2VNc2VjKCkpLHRoaXMudGV4dElucHV0KCkub25pbnB1dD10PT57Y29uc3QgaT10LnRhcmdldC52YWx1ZS50cmltKCkscz10aGlzLmVsLmRhdGFzZXQuZmllbGQ7aS5sZW5ndGg+PXRoaXMudXBkYXRlTWluTGVuKCk/dGhpcy5jaGFuZ2VFdmVudHModGhpcy5lbC5pZCxzLGkpOnRoaXMucHVzaEV2ZW50VG8odGhpcy5lbCxcIm9wdGlvbnNfY2xlYXJcIix7fSl9O2NvbnN0IGU9dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwidWxcIik7ZSYmKGUub25tb3VzZWRvd249dD0+e2NvbnN0IGk9dC50YXJnZXQuY2xvc2VzdChcImRpdltkYXRhLWlkeF1cIik7aSYmKHRoaXMucHVzaEV2ZW50VG8odGhpcy5lbCxcIm9wdGlvbl9jbGlja1wiLHtpZHg6aS5kYXRhc2V0LmlkeH0pLHQucHJldmVudERlZmF1bHQoKSl9KSx0aGlzLmVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCJidXR0b25bZGF0YS1pZHhdXCIpLmZvckVhY2godD0+e3Qub25jbGljaz1pPT57dGhpcy5wdXNoRXZlbnRUbyh0aGlzLmVsLFwib3B0aW9uX3JlbW92ZVwiLHtpZHg6dC5kYXRhc2V0LmlkeH0pfX0pfSxzZXRJbnB1dFZhbHVlKGUpe3RoaXMudGV4dElucHV0KCkudmFsdWU9ZX0saW5wdXRFdmVudChlLHQpe2NvbnN0IGk9dD09PVwic2luZ2xlXCI/XCJpbnB1dC5zaW5nbGUtbW9kZVwiOmUubGVuZ3RoPT09MD9cImlucHV0W2RhdGEtbGl2ZS1zZWxlY3QtZW1wdHldXCI6XCJpbnB1dFt0eXBlPWhpZGRlbl1cIjt0aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoaSkuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJpbnB1dFwiLHtidWJibGVzOiEwfSkpfSxtb3VudGVkKCl7dGhpcy5tYXliZVN0eWxlQ2xlYXJCdXR0b25zKCksdGhpcy5oYW5kbGVFdmVudChcInNlbGVjdFwiLCh7aWQ6ZSxzZWxlY3Rpb246dCxtb2RlOmksY3VycmVudF90ZXh0OnMsaW5wdXRfZXZlbnQ6bCxwYXJlbnRfZXZlbnQ6bn0pPT57dGhpcy5lbC5pZD09PWUmJih0aGlzLnNlbGVjdGlvbj10LHMhPW51bGwmJnRoaXMuc2V0SW5wdXRWYWx1ZShzKSxsJiZ0aGlzLmlucHV0RXZlbnQodCxpKSxuJiZ0aGlzLnB1c2hFdmVudFRvUGFyZW50KG4se2lkOmV9KSl9KSx0aGlzLmhhbmRsZUV2ZW50KFwic2Nyb2xsX3RvX29wdGlvblwiLCh7aWQ6ZSxpZHg6dH0pPT57aWYodGhpcy5lbC5pZD09PWUpe2NvbnN0IGk9dGhpcy5lbC5xdWVyeVNlbGVjdG9yKGBkaXZbZGF0YS1pZHg9XCIke3R9XCJdYCk7aSYmaS5zY3JvbGxJbnRvVmlldyh7YmxvY2s6XCJuZWFyZXN0XCIsYmVoYXZpb3I6XCJpbnN0YW50XCIsY29udGFpbmVyOlwibmVhcmVzdFwifSl9fSksdGhpcy5hdHRhY2hEb21FdmVudEhhbmRsZXJzKCl9LHVwZGF0ZWQoKXt0aGlzLm1heWJlU3R5bGVDbGVhckJ1dHRvbnMoKSx0aGlzLmF0dGFjaERvbUV2ZW50SGFuZGxlcnMoKX0scmVjb25uZWN0ZWQoKXt0aGlzLnNlbGVjdGlvbiYmdGhpcy5zZWxlY3Rpb24ubGVuZ3RoPjAmJnRoaXMucHVzaEV2ZW50VG8odGhpcy5lbCxcInNlbGVjdGlvbl9yZWNvdmVyeVwiLHRoaXMuc2VsZWN0aW9uKX19fTtcbiIsIi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9zY2hlZHVsZXIuanNcbnZhciBmbHVzaFBlbmRpbmcgPSBmYWxzZTtcbnZhciBmbHVzaGluZyA9IGZhbHNlO1xudmFyIHF1ZXVlID0gW107XG52YXIgbGFzdEZsdXNoZWRJbmRleCA9IC0xO1xuZnVuY3Rpb24gc2NoZWR1bGVyKGNhbGxiYWNrKSB7XG4gIHF1ZXVlSm9iKGNhbGxiYWNrKTtcbn1cbmZ1bmN0aW9uIHF1ZXVlSm9iKGpvYikge1xuICBpZiAoIXF1ZXVlLmluY2x1ZGVzKGpvYikpXG4gICAgcXVldWUucHVzaChqb2IpO1xuICBxdWV1ZUZsdXNoKCk7XG59XG5mdW5jdGlvbiBkZXF1ZXVlSm9iKGpvYikge1xuICBsZXQgaW5kZXggPSBxdWV1ZS5pbmRleE9mKGpvYik7XG4gIGlmIChpbmRleCAhPT0gLTEgJiYgaW5kZXggPiBsYXN0Rmx1c2hlZEluZGV4KVxuICAgIHF1ZXVlLnNwbGljZShpbmRleCwgMSk7XG59XG5mdW5jdGlvbiBxdWV1ZUZsdXNoKCkge1xuICBpZiAoIWZsdXNoaW5nICYmICFmbHVzaFBlbmRpbmcpIHtcbiAgICBmbHVzaFBlbmRpbmcgPSB0cnVlO1xuICAgIHF1ZXVlTWljcm90YXNrKGZsdXNoSm9icyk7XG4gIH1cbn1cbmZ1bmN0aW9uIGZsdXNoSm9icygpIHtcbiAgZmx1c2hQZW5kaW5nID0gZmFsc2U7XG4gIGZsdXNoaW5nID0gdHJ1ZTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBxdWV1ZS5sZW5ndGg7IGkrKykge1xuICAgIHF1ZXVlW2ldKCk7XG4gICAgbGFzdEZsdXNoZWRJbmRleCA9IG
1k7XG4gIH1cbiAgcXVldWUubGVuZ3RoID0gMDtcbiAgbGFzdEZsdXNoZWRJbmRleCA9IC0xO1xuICBmbHVzaGluZyA9IGZhbHNlO1xufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvcmVhY3Rpdml0eS5qc1xudmFyIHJlYWN0aXZlO1xudmFyIGVmZmVjdDtcbnZhciByZWxlYXNlO1xudmFyIHJhdztcbnZhciBzaG91bGRTY2hlZHVsZSA9IHRydWU7XG5mdW5jdGlvbiBkaXNhYmxlRWZmZWN0U2NoZWR1bGluZyhjYWxsYmFjaykge1xuICBzaG91bGRTY2hlZHVsZSA9IGZhbHNlO1xuICBjYWxsYmFjaygpO1xuICBzaG91bGRTY2hlZHVsZSA9IHRydWU7XG59XG5mdW5jdGlvbiBzZXRSZWFjdGl2aXR5RW5naW5lKGVuZ2luZSkge1xuICByZWFjdGl2ZSA9IGVuZ2luZS5yZWFjdGl2ZTtcbiAgcmVsZWFzZSA9IGVuZ2luZS5yZWxlYXNlO1xuICBlZmZlY3QgPSAoY2FsbGJhY2spID0+IGVuZ2luZS5lZmZlY3QoY2FsbGJhY2ssIHtzY2hlZHVsZXI6ICh0YXNrKSA9PiB7XG4gICAgaWYgKHNob3VsZFNjaGVkdWxlKSB7XG4gICAgICBzY2hlZHVsZXIodGFzayk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRhc2soKTtcbiAgICB9XG4gIH19KTtcbiAgcmF3ID0gZW5naW5lLnJhdztcbn1cbmZ1bmN0aW9uIG92ZXJyaWRlRWZmZWN0KG92ZXJyaWRlKSB7XG4gIGVmZmVjdCA9IG92ZXJyaWRlO1xufVxuZnVuY3Rpb24gZWxlbWVudEJvdW5kRWZmZWN0KGVsKSB7XG4gIGxldCBjbGVhbnVwMiA9ICgpID0+IHtcbiAgfTtcbiAgbGV0IHdyYXBwZWRFZmZlY3QgPSAoY2FsbGJhY2spID0+IHtcbiAgICBsZXQgZWZmZWN0UmVmZXJlbmNlID0gZWZmZWN0KGNhbGxiYWNrKTtcbiAgICBpZiAoIWVsLl94X2VmZmVjdHMpIHtcbiAgICAgIGVsLl94X2VmZmVjdHMgPSBuZXcgU2V0KCk7XG4gICAgICBlbC5feF9ydW5FZmZlY3RzID0gKCkgPT4ge1xuICAgICAgICBlbC5feF9lZmZlY3RzLmZvckVhY2goKGkpID0+IGkoKSk7XG4gICAgICB9O1xuICAgIH1cbiAgICBlbC5feF9lZmZlY3RzLmFkZChlZmZlY3RSZWZlcmVuY2UpO1xuICAgIGNsZWFudXAyID0gKCkgPT4ge1xuICAgICAgaWYgKGVmZmVjdFJlZmVyZW5jZSA9PT0gdm9pZCAwKVxuICAgICAgICByZXR1cm47XG4gICAgICBlbC5feF9lZmZlY3RzLmRlbGV0ZShlZmZlY3RSZWZlcmVuY2UpO1xuICAgICAgcmVsZWFzZShlZmZlY3RSZWZlcmVuY2UpO1xuICAgIH07XG4gICAgcmV0dXJuIGVmZmVjdFJlZmVyZW5jZTtcbiAgfTtcbiAgcmV0dXJuIFt3cmFwcGVkRWZmZWN0LCAoKSA9PiB7XG4gICAgY2xlYW51cDIoKTtcbiAgfV07XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9tdXRhdGlvbi5qc1xudmFyIG9uQXR0cmlidXRlQWRkZWRzID0gW107XG52YXIgb25FbFJlbW92ZWRzID0gW107XG52YXIgb25FbEFkZGVkcyA9IFtdO1xuZnVuY3Rpb24gb25FbEFkZGVkKGNhbGxiYWNrKSB7XG4gIG9uRWxBZGRlZHMucHVzaChjYWxsYmFjayk7XG59XG5mdW5jdGlvbiBvbkVsUmVtb3ZlZChlbCwgY2FsbGJhY2spIHtcbiAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgaWYgKCFlbC5feF9jbGVhbnVwcylcbiAgICAgIGVsLl94X2NsZWFudXBzID0gW107XG4gICAgZWwuX3hfY2xlYW51cHMucHVzaChjYWxsYmFjayk7XG4gIH0gZWxzZSB7XG4gICAgY2FsbGJhY2sgPSBlbDtcbiAgICBvbkVsUmVtb3ZlZHMucHVzaChjYWxsYmFjayk7XG4gIH1cbn1cbmZ1bmN0aW9uIG9uQXR0cmlidXRlc0FkZGVkKGNhbGxiYWNrKSB7XG4gIG9uQXR0cmlidXRlQWRkZWRzLnB1c2goY2FsbGJhY2spO1xufVxuZnVuY3Rpb24gb25BdHRyaWJ1dGVSZW1vdmVkKGVsLCBuYW1lLCBjYWxsYmFjaykge1xuICBpZiAoIWVsLl94X2F0dHJpYnV0ZUNsZWFudXBzKVxuICAgIGVsLl94X2F0dHJpYnV0ZUNsZWFudXBzID0ge307XG4gIGlmICghZWwuX3hfYXR0cmlidXRlQ2xlYW51cHNbbmFtZV0pXG4gICAgZWwuX3hfYXR0cmlidXRlQ2xlYW51cHNbbmFtZV0gPSBbXTtcbiAgZWwuX3hfYXR0cmlidXRlQ2xlYW51cHNbbmFtZV0ucHVzaChjYWxsYmFjayk7XG59XG5mdW5jdGlvbiBjbGVhbnVwQXR0cmlidXRlcyhlbCwgbmFtZXMpIHtcbiAgaWYgKCFlbC5feF9hdHRyaWJ1dGVDbGVhbnVwcylcbiAgICByZXR1cm47XG4gIE9iamVjdC5lbnRyaWVzKGVsLl94X2F0dHJpYnV0ZUNsZWFudXBzKS5mb3JFYWNoKChbbmFtZSwgdmFsdWVdKSA9PiB7XG4gICAgaWYgKG5hbWVzID09PSB2b2lkIDAgfHwgbmFtZXMuaW5jbHVkZXMobmFtZSkpIHtcbiAgICAgIHZhbHVlLmZvckVhY2goKGkpID0+IGkoKSk7XG4gICAgICBkZWxldGUgZWwuX3hfYXR0cmlidXRlQ2xlYW51cHNbbmFtZV07XG4gICAgfVxuICB9KTtcbn1cbnZhciBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKG9uTXV0YXRlKTtcbnZhciBjdXJyZW50bHlPYnNlcnZpbmcgPSBmYWxzZTtcbmZ1bmN0aW9uIHN0YXJ0T2JzZXJ2aW5nTXV0YXRpb25zKCkge1xuICBvYnNlcnZlci5vYnNlcnZlKGRvY3VtZW50LCB7c3VidHJlZTogdHJ1ZSwgY2hpbGRMaXN0OiB0cnVlLCBhdHRyaWJ1dGVzOiB0cnVlLCBhdHRyaWJ1dGVPbGRWYWx1ZTogdHJ1ZX0pO1xuICBjdXJyZW50bHlPYnNlcnZpbmcgPSB0cnVlO1xufVxuZnVuY3Rpb24gc3RvcE9ic2VydmluZ011dGF0aW9ucygpIHtcbiAgZmx1c2hPYnNlcnZlcigpO1xuICBvYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gIGN1cnJlbnRseU9ic2VydmluZyA9IGZhbHNlO1xufVxudmFyIHJlY29yZFF1ZXVlID0gW107XG52YXIgd2lsbFByb2Nlc3NSZWNvcmRRdWV1ZSA9IGZhbHNlO1xuZnVuY3Rpb24gZmx1c2hPYnNlcnZlcigpIHtcbiAgcmVjb3JkUXVldWUgPSByZWNvcmRRdWV1ZS5jb25jYXQob2JzZXJ2ZXIudGFrZVJlY29yZHMoKSk7XG4gIGlmIChyZWNvcmRRdWV1ZS5sZW5ndGggJiYgIXdpbGxQcm9jZXNzUmVjb3JkUXVldWUpIHtcbiAgICB3aWxsUHJvY2Vzc1JlY29yZFF1ZXVlID0gdHJ1ZTtcbiAgICBxdWV1ZU1pY3JvdGFzaygoKSA9PiB7XG4gICAgICBwcm9jZXNzUmVjb3JkUXVldWUoKTtcbiAgICAgIHdpbGxQcm9jZXNzUmVjb3JkUXVldWUgPSBmYWxzZTtcbiAgICB9KTtcbiAgfVxufVxuZnVuY3Rpb24gcHJvY2Vzc1JlY29yZFF1ZXVlKCkge1xuICBvbk11dGF0ZShyZWNvcmRRdWV1ZSk7XG4gIHJlY29yZFF1ZXVlLmxlbmd0aCA9IDA7XG59XG5mdW5jdGlvbiBtdXRhdGVEb20oY2FsbGJhY2spIHtcbiAgaWYgKCFjdXJyZW50bHlPYnNlcnZpbmcpXG4gICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gIHN0b3BPYnNlcnZpbmdNdXRhdGlvbnMoKTtcbiAgbGV0IHJlc3VsdCA9IGNhbGxiYWNrKCk7XG4gIHN0YXJ0T2JzZXJ2aW5nTXV0YXRpb25zKCk7XG4gIHJldHVybi
1ByZXN1bHQ7XG59XG52YXIgaXNDb2xsZWN0aW5nID0gZmFsc2U7XG52YXIgZGVmZXJyZWRNdXRhdGlvbnMgPSBbXTtcbmZ1bmN0aW9uIGRlZmVyTXV0YXRpb25zKCkge1xuICBpc0NvbGxlY3RpbmcgPSB0cnVlO1xufVxuZnVuY3Rpb24gZmx1c2hBbmRTdG9wRGVmZXJyaW5nTXV0YXRpb25zKCkge1xuICBpc0NvbGxlY3RpbmcgPSBmYWxzZTtcbiAgb25NdXRhdGUoZGVmZXJyZWRNdXRhdGlvbnMpO1xuICBkZWZlcnJlZE11dGF0aW9ucyA9IFtdO1xufVxuZnVuY3Rpb24gb25NdXRhdGUobXV0YXRpb25zKSB7XG4gIGlmIChpc0NvbGxlY3RpbmcpIHtcbiAgICBkZWZlcnJlZE11dGF0aW9ucyA9IGRlZmVycmVkTXV0YXRpb25zLmNvbmNhdChtdXRhdGlvbnMpO1xuICAgIHJldHVybjtcbiAgfVxuICBsZXQgYWRkZWROb2RlcyA9IFtdO1xuICBsZXQgcmVtb3ZlZE5vZGVzID0gW107XG4gIGxldCBhZGRlZEF0dHJpYnV0ZXMgPSBuZXcgTWFwKCk7XG4gIGxldCByZW1vdmVkQXR0cmlidXRlcyA9IG5ldyBNYXAoKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBtdXRhdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAobXV0YXRpb25zW2ldLnRhcmdldC5feF9pZ25vcmVNdXRhdGlvbk9ic2VydmVyKVxuICAgICAgY29udGludWU7XG4gICAgaWYgKG11dGF0aW9uc1tpXS50eXBlID09PSBcImNoaWxkTGlzdFwiKSB7XG4gICAgICBtdXRhdGlvbnNbaV0uYWRkZWROb2Rlcy5mb3JFYWNoKChub2RlKSA9PiBub2RlLm5vZGVUeXBlID09PSAxICYmIGFkZGVkTm9kZXMucHVzaChub2RlKSk7XG4gICAgICBtdXRhdGlvbnNbaV0ucmVtb3ZlZE5vZGVzLmZvckVhY2goKG5vZGUpID0+IG5vZGUubm9kZVR5cGUgPT09IDEgJiYgcmVtb3ZlZE5vZGVzLnB1c2gobm9kZSkpO1xuICAgIH1cbiAgICBpZiAobXV0YXRpb25zW2ldLnR5cGUgPT09IFwiYXR0cmlidXRlc1wiKSB7XG4gICAgICBsZXQgZWwgPSBtdXRhdGlvbnNbaV0udGFyZ2V0O1xuICAgICAgbGV0IG5hbWUgPSBtdXRhdGlvbnNbaV0uYXR0cmlidXRlTmFtZTtcbiAgICAgIGxldCBvbGRWYWx1ZSA9IG11dGF0aW9uc1tpXS5vbGRWYWx1ZTtcbiAgICAgIGxldCBhZGQyID0gKCkgPT4ge1xuICAgICAgICBpZiAoIWFkZGVkQXR0cmlidXRlcy5oYXMoZWwpKVxuICAgICAgICAgIGFkZGVkQXR0cmlidXRlcy5zZXQoZWwsIFtdKTtcbiAgICAgICAgYWRkZWRBdHRyaWJ1dGVzLmdldChlbCkucHVzaCh7bmFtZSwgdmFsdWU6IGVsLmdldEF0dHJpYnV0ZShuYW1lKX0pO1xuICAgICAgfTtcbiAgICAgIGxldCByZW1vdmUgPSAoKSA9PiB7XG4gICAgICAgIGlmICghcmVtb3ZlZEF0dHJpYnV0ZXMuaGFzKGVsKSlcbiAgICAgICAgICByZW1vdmVkQXR0cmlidXRlcy5zZXQoZWwsIFtdKTtcbiAgICAgICAgcmVtb3ZlZEF0dHJpYnV0ZXMuZ2V0KGVsKS5wdXNoKG5hbWUpO1xuICAgICAgfTtcbiAgICAgIGlmIChlbC5oYXNBdHRyaWJ1dGUobmFtZSkgJiYgb2xkVmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgYWRkMigpO1xuICAgICAgfSBlbHNlIGlmIChlbC5oYXNBdHRyaWJ1dGUobmFtZSkpIHtcbiAgICAgICAgcmVtb3ZlKCk7XG4gICAgICAgIGFkZDIoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlbW92ZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZW1vdmVkQXR0cmlidXRlcy5mb3JFYWNoKChhdHRycywgZWwpID0+IHtcbiAgICBjbGVhbnVwQXR0cmlidXRlcyhlbCwgYXR0cnMpO1xuICB9KTtcbiAgYWRkZWRBdHRyaWJ1dGVzLmZvckVhY2goKGF0dHJzLCBlbCkgPT4ge1xuICAgIG9uQXR0cmlidXRlQWRkZWRzLmZvckVhY2goKGkpID0+IGkoZWwsIGF0dHJzKSk7XG4gIH0pO1xuICBmb3IgKGxldCBub2RlIG9mIHJlbW92ZWROb2Rlcykge1xuICAgIGlmIChhZGRlZE5vZGVzLmluY2x1ZGVzKG5vZGUpKVxuICAgICAgY29udGludWU7XG4gICAgb25FbFJlbW92ZWRzLmZvckVhY2goKGkpID0+IGkobm9kZSkpO1xuICAgIGlmIChub2RlLl94X2NsZWFudXBzKSB7XG4gICAgICB3aGlsZSAobm9kZS5feF9jbGVhbnVwcy5sZW5ndGgpXG4gICAgICAgIG5vZGUuX3hfY2xlYW51cHMucG9wKCkoKTtcbiAgICB9XG4gIH1cbiAgYWRkZWROb2Rlcy5mb3JFYWNoKChub2RlKSA9PiB7XG4gICAgbm9kZS5feF9pZ25vcmVTZWxmID0gdHJ1ZTtcbiAgICBub2RlLl94X2lnbm9yZSA9IHRydWU7XG4gIH0pO1xuICBmb3IgKGxldCBub2RlIG9mIGFkZGVkTm9kZXMpIHtcbiAgICBpZiAocmVtb3ZlZE5vZGVzLmluY2x1ZGVzKG5vZGUpKVxuICAgICAgY29udGludWU7XG4gICAgaWYgKCFub2RlLmlzQ29ubmVjdGVkKVxuICAgICAgY29udGludWU7XG4gICAgZGVsZXRlIG5vZGUuX3hfaWdub3JlU2VsZjtcbiAgICBkZWxldGUgbm9kZS5feF9pZ25vcmU7XG4gICAgb25FbEFkZGVkcy5mb3JFYWNoKChpKSA9PiBpKG5vZGUpKTtcbiAgICBub2RlLl94X2lnbm9yZSA9IHRydWU7XG4gICAgbm9kZS5feF9pZ25vcmVTZWxmID0gdHJ1ZTtcbiAgfVxuICBhZGRlZE5vZGVzLmZvckVhY2goKG5vZGUpID0+IHtcbiAgICBkZWxldGUgbm9kZS5feF9pZ25vcmVTZWxmO1xuICAgIGRlbGV0ZSBub2RlLl94X2lnbm9yZTtcbiAgfSk7XG4gIGFkZGVkTm9kZXMgPSBudWxsO1xuICByZW1vdmVkTm9kZXMgPSBudWxsO1xuICBhZGRlZEF0dHJpYnV0ZXMgPSBudWxsO1xuICByZW1vdmVkQXR0cmlidXRlcyA9IG51bGw7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9zY29wZS5qc1xuZnVuY3Rpb24gc2NvcGUobm9kZSkge1xuICByZXR1cm4gbWVyZ2VQcm94aWVzKGNsb3Nlc3REYXRhU3RhY2sobm9kZSkpO1xufVxuZnVuY3Rpb24gYWRkU2NvcGVUb05vZGUobm9kZSwgZGF0YTIsIHJlZmVyZW5jZU5vZGUpIHtcbiAgbm9kZS5feF9kYXRhU3RhY2sgPSBbZGF0YTIsIC4uLmNsb3Nlc3REYXRhU3RhY2socmVmZXJlbmNlTm9kZSB8fCBub2RlKV07XG4gIHJldHVybiAoKSA9PiB7XG4gICAgbm9kZS5feF9kYXRhU3RhY2sgPSBub2RlLl94X2RhdGFTdGFjay5maWx0ZXIoKGkpID0+IGkgIT09IGRhdGEyKTtcbiAgfTtcbn1cbmZ1bmN0aW9uIGNsb3Nlc3REYXRhU3RhY2sobm9kZSkge1xuICBpZiAobm9kZS5feF9kYXRhU3RhY2spXG4gICAgcmV0dXJuIG5vZGUuX3hfZGF0YVN0YWNrO1xuICBpZiAodHlwZW9mIFNoYWRvd1Jvb3QgPT09IFwiZnVuY3Rpb25cIiAmJiBub2RlIGluc3RhbmNlb2YgU2hhZG93Um9vdCkge1xuICAgIHJldHVybi
1BjbG9zZXN0RGF0YVN0YWNrKG5vZGUuaG9zdCk7XG4gIH1cbiAgaWYgKCFub2RlLnBhcmVudE5vZGUpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgcmV0dXJuIGNsb3Nlc3REYXRhU3RhY2sobm9kZS5wYXJlbnROb2RlKTtcbn1cbmZ1bmN0aW9uIG1lcmdlUHJveGllcyhvYmplY3RzKSB7XG4gIGxldCB0aGlzUHJveHkgPSBuZXcgUHJveHkoe30sIHtcbiAgICBvd25LZXlzOiAoKSA9PiB7XG4gICAgICByZXR1cm4gQXJyYXkuZnJvbShuZXcgU2V0KG9iamVjdHMuZmxhdE1hcCgoaSkgPT4gT2JqZWN0LmtleXMoaSkpKSk7XG4gICAgfSxcbiAgICBoYXM6ICh0YXJnZXQsIG5hbWUpID0+IHtcbiAgICAgIHJldHVybiBvYmplY3RzLnNvbWUoKG9iaikgPT4gb2JqLmhhc093blByb3BlcnR5KG5hbWUpKTtcbiAgICB9LFxuICAgIGdldDogKHRhcmdldCwgbmFtZSkgPT4ge1xuICAgICAgcmV0dXJuIChvYmplY3RzLmZpbmQoKG9iaikgPT4ge1xuICAgICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICAgICAgbGV0IGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwgbmFtZSk7XG4gICAgICAgICAgaWYgKGRlc2NyaXB0b3IuZ2V0ICYmIGRlc2NyaXB0b3IuZ2V0Ll94X2FscmVhZHlCb3VuZCB8fCBkZXNjcmlwdG9yLnNldCAmJiBkZXNjcmlwdG9yLnNldC5feF9hbHJlYWR5Qm91bmQpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoKGRlc2NyaXB0b3IuZ2V0IHx8IGRlc2NyaXB0b3Iuc2V0KSAmJiBkZXNjcmlwdG9yLmVudW1lcmFibGUpIHtcbiAgICAgICAgICAgIGxldCBnZXR0ZXIgPSBkZXNjcmlwdG9yLmdldDtcbiAgICAgICAgICAgIGxldCBzZXR0ZXIgPSBkZXNjcmlwdG9yLnNldDtcbiAgICAgICAgICAgIGxldCBwcm9wZXJ0eSA9IGRlc2NyaXB0b3I7XG4gICAgICAgICAgICBnZXR0ZXIgPSBnZXR0ZXIgJiYgZ2V0dGVyLmJpbmQodGhpc1Byb3h5KTtcbiAgICAgICAgICAgIHNldHRlciA9IHNldHRlciAmJiBzZXR0ZXIuYmluZCh0aGlzUHJveHkpO1xuICAgICAgICAgICAgaWYgKGdldHRlcilcbiAgICAgICAgICAgICAgZ2V0dGVyLl94X2FscmVhZHlCb3VuZCA9IHRydWU7XG4gICAgICAgICAgICBpZiAoc2V0dGVyKVxuICAgICAgICAgICAgICBzZXR0ZXIuX3hfYWxyZWFkeUJvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIG5hbWUsIHtcbiAgICAgICAgICAgICAgLi4ucHJvcGVydHksXG4gICAgICAgICAgICAgIGdldDogZ2V0dGVyLFxuICAgICAgICAgICAgICBzZXQ6IHNldHRlclxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0pIHx8IHt9KVtuYW1lXTtcbiAgICB9LFxuICAgIHNldDogKHRhcmdldCwgbmFtZSwgdmFsdWUpID0+IHtcbiAgICAgIGxldCBjbG9zZXN0T2JqZWN0V2l0aEtleSA9IG9iamVjdHMuZmluZCgob2JqKSA9PiBvYmouaGFzT3duUHJvcGVydHkobmFtZSkpO1xuICAgICAgaWYgKGNsb3Nlc3RPYmplY3RXaXRoS2V5KSB7XG4gICAgICAgIGNsb3Nlc3RPYmplY3RXaXRoS2V5W25hbWVdID0gdmFsdWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvYmplY3RzW29iamVjdHMubGVuZ3RoIC0gMV1bbmFtZV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiB0aGlzUHJveHk7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9pbnRlcmNlcHRvci5qc1xuZnVuY3Rpb24gaW5pdEludGVyY2VwdG9ycyhkYXRhMikge1xuICBsZXQgaXNPYmplY3QyID0gKHZhbCkgPT4gdHlwZW9mIHZhbCA9PT0gXCJvYmplY3RcIiAmJiAhQXJyYXkuaXNBcnJheSh2YWwpICYmIHZhbCAhPT0gbnVsbDtcbiAgbGV0IHJlY3Vyc2UgPSAob2JqLCBiYXNlUGF0aCA9IFwiXCIpID0+IHtcbiAgICBPYmplY3QuZW50cmllcyhPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhvYmopKS5mb3JFYWNoKChba2V5LCB7dmFsdWUsIGVudW1lcmFibGV9XSkgPT4ge1xuICAgICAgaWYgKGVudW1lcmFibGUgPT09IGZhbHNlIHx8IHZhbHVlID09PSB2b2lkIDApXG4gICAgICAgIHJldHVybjtcbiAgICAgIGxldCBwYXRoID0gYmFzZVBhdGggPT09IFwiXCIgPyBrZXkgOiBgJHtiYXNlUGF0aH0uJHtrZXl9YDtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgIT09IG51bGwgJiYgdmFsdWUuX3hfaW50ZXJjZXB0b3IpIHtcbiAgICAgICAgb2JqW2tleV0gPSB2YWx1ZS5pbml0aWFsaXplKGRhdGEyLCBwYXRoLCBrZXkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGlzT2JqZWN0Mih2YWx1ZSkgJiYgdmFsdWUgIT09IG9iaiAmJiAhKHZhbHVlIGluc3RhbmNlb2YgRWxlbWVudCkpIHtcbiAgICAgICAgICByZWN1cnNlKHZhbHVlLCBwYXRoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9O1xuICByZXR1cm4gcmVjdXJzZShkYXRhMik7XG59XG5mdW5jdGlvbiBpbnRlcmNlcHRvcihjYWxsYmFjaywgbXV0YXRlT2JqID0gKCkgPT4ge1xufSkge1xuICBsZXQgb2JqID0ge1xuICAgIGluaXRpYWxWYWx1ZTogdm9pZCAwLFxuICAgIF94X2ludGVyY2VwdG9yOiB0cnVlLFxuICAgIGluaXRpYWxpemUoZGF0YTIsIHBhdGgsIGtleSkge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKHRoaXMuaW5pdGlhbFZhbHVlLCAoKSA9PiBnZXQoZGF0YTIsIHBhdGgpLCAodmFsdWUpID0+IHNldChkYXRhMiwgcGF0aCwgdmFsdWUpLCBwYXRoLCBrZXkpO1xuICAgIH1cbiAgfTtcbiAgbXV0YXRlT2JqKG9iaik7XG4gIHJldHVybiAoaW5pdGlhbFZhbHVlKSA9PiB7XG4gICAgaWYgKHR5cGVvZiBpbml0aWFsVmFsdWUgPT09IFwib2JqZWN0XCIgJiYgaW5pdGlhbFZhbHVlICE9PSBudWxsICYmIGluaXRpYWxWYWx1ZS5feF9pbnRlcmNlcHRvcikge1xuICAgICAgbGV0IGluaXRpYWxpemUgPSBvYmouaW5pdGlhbGl6ZS5iaW5kKG9iaik7XG4gICAgICBvYmouaW5pdGlhbGl6ZSA9IChkYXRhMiwgcGF0aCwga2V5KSA9PiB7XG4gICAgICAgIGxldCBpbm5lclZhbHVlID0gaW5pdGlhbFZhbHVlLmluaXRpYWxpemUoZGF0YTIsIHBhdGgsIGtleSk7XG4gICAgICAgIG9iai5pbml0aWFsVmFsdWUgPSBpbm5lclZhbHVlO1xuICAgICAgICByZXR1cm4gaW5pdGlhbGl6ZShkYXRhMiwgcGF0aCwga2V5KTtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIG9iai5pbml0aWFsVmFsdWUgPSBpbml0aWFsVmFsdWU7XG4gICAgfVxuICAgIHJldHVybi
1BvYmo7XG4gIH07XG59XG5mdW5jdGlvbiBnZXQob2JqLCBwYXRoKSB7XG4gIHJldHVybiBwYXRoLnNwbGl0KFwiLlwiKS5yZWR1Y2UoKGNhcnJ5LCBzZWdtZW50KSA9PiBjYXJyeVtzZWdtZW50XSwgb2JqKTtcbn1cbmZ1bmN0aW9uIHNldChvYmosIHBhdGgsIHZhbHVlKSB7XG4gIGlmICh0eXBlb2YgcGF0aCA9PT0gXCJzdHJpbmdcIilcbiAgICBwYXRoID0gcGF0aC5zcGxpdChcIi5cIik7XG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMSlcbiAgICBvYmpbcGF0aFswXV0gPSB2YWx1ZTtcbiAgZWxzZSBpZiAocGF0aC5sZW5ndGggPT09IDApXG4gICAgdGhyb3cgZXJyb3I7XG4gIGVsc2Uge1xuICAgIGlmIChvYmpbcGF0aFswXV0pXG4gICAgICByZXR1cm4gc2V0KG9ialtwYXRoWzBdXSwgcGF0aC5zbGljZSgxKSwgdmFsdWUpO1xuICAgIGVsc2Uge1xuICAgICAgb2JqW3BhdGhbMF1dID0ge307XG4gICAgICByZXR1cm4gc2V0KG9ialtwYXRoWzBdXSwgcGF0aC5zbGljZSgxKSwgdmFsdWUpO1xuICAgIH1cbiAgfVxufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvbWFnaWNzLmpzXG52YXIgbWFnaWNzID0ge307XG5mdW5jdGlvbiBtYWdpYyhuYW1lLCBjYWxsYmFjaykge1xuICBtYWdpY3NbbmFtZV0gPSBjYWxsYmFjaztcbn1cbmZ1bmN0aW9uIGluamVjdE1hZ2ljcyhvYmosIGVsKSB7XG4gIE9iamVjdC5lbnRyaWVzKG1hZ2ljcykuZm9yRWFjaCgoW25hbWUsIGNhbGxiYWNrXSkgPT4ge1xuICAgIGxldCBtZW1vaXplZFV0aWxpdGllcyA9IG51bGw7XG4gICAgZnVuY3Rpb24gZ2V0VXRpbGl0aWVzKCkge1xuICAgICAgaWYgKG1lbW9pemVkVXRpbGl0aWVzKSB7XG4gICAgICAgIHJldHVybiBtZW1vaXplZFV0aWxpdGllcztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxldCBbdXRpbGl0aWVzLCBjbGVhbnVwMl0gPSBnZXRFbGVtZW50Qm91bmRVdGlsaXRpZXMoZWwpO1xuICAgICAgICBtZW1vaXplZFV0aWxpdGllcyA9IHtpbnRlcmNlcHRvciwgLi4udXRpbGl0aWVzfTtcbiAgICAgICAgb25FbFJlbW92ZWQoZWwsIGNsZWFudXAyKTtcbiAgICAgICAgcmV0dXJuIG1lbW9pemVkVXRpbGl0aWVzO1xuICAgICAgfVxuICAgIH1cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBgJCR7bmFtZX1gLCB7XG4gICAgICBnZXQoKSB7XG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlbCwgZ2V0VXRpbGl0aWVzKCkpO1xuICAgICAgfSxcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlXG4gICAgfSk7XG4gIH0pO1xuICByZXR1cm4gb2JqO1xufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvdXRpbHMvZXJyb3IuanNcbmZ1bmN0aW9uIHRyeUNhdGNoKGVsLCBleHByZXNzaW9uLCBjYWxsYmFjaywgLi4uYXJncykge1xuICB0cnkge1xuICAgIHJldHVybiBjYWxsYmFjayguLi5hcmdzKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGhhbmRsZUVycm9yKGUsIGVsLCBleHByZXNzaW9uKTtcbiAgfVxufVxuZnVuY3Rpb24gaGFuZGxlRXJyb3IoZXJyb3IyLCBlbCwgZXhwcmVzc2lvbiA9IHZvaWQgMCkge1xuICBPYmplY3QuYXNzaWduKGVycm9yMiwge2VsLCBleHByZXNzaW9ufSk7XG4gIGNvbnNvbGUud2FybihgQWxwaW5lIEV4cHJlc3Npb24gRXJyb3I6ICR7ZXJyb3IyLm1lc3NhZ2V9XG5cbiR7ZXhwcmVzc2lvbiA/ICdFeHByZXNzaW9uOiBcIicgKyBleHByZXNzaW9uICsgJ1wiXFxuXFxuJyA6IFwiXCJ9YCwgZWwpO1xuICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICB0aHJvdyBlcnJvcjI7XG4gIH0sIDApO1xufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvZXZhbHVhdG9yLmpzXG52YXIgc2hvdWxkQXV0b0V2YWx1YXRlRnVuY3Rpb25zID0gdHJ1ZTtcbmZ1bmN0aW9uIGRvbnRBdXRvRXZhbHVhdGVGdW5jdGlvbnMoY2FsbGJhY2spIHtcbiAgbGV0IGNhY2hlID0gc2hvdWxkQXV0b0V2YWx1YXRlRnVuY3Rpb25zO1xuICBzaG91bGRBdXRvRXZhbHVhdGVGdW5jdGlvbnMgPSBmYWxzZTtcbiAgbGV0IHJlc3VsdCA9IGNhbGxiYWNrKCk7XG4gIHNob3VsZEF1dG9FdmFsdWF0ZUZ1bmN0aW9ucyA9IGNhY2hlO1xuICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gZXZhbHVhdGUoZWwsIGV4cHJlc3Npb24sIGV4dHJhcyA9IHt9KSB7XG4gIGxldCByZXN1bHQ7XG4gIGV2YWx1YXRlTGF0ZXIoZWwsIGV4cHJlc3Npb24pKCh2YWx1ZSkgPT4gcmVzdWx0ID0gdmFsdWUsIGV4dHJhcyk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBldmFsdWF0ZUxhdGVyKC4uLmFyZ3MpIHtcbiAgcmV0dXJuIHRoZUV2YWx1YXRvckZ1bmN0aW9uKC4uLmFyZ3MpO1xufVxudmFyIHRoZUV2YWx1YXRvckZ1bmN0aW9uID0gbm9ybWFsRXZhbHVhdG9yO1xuZnVuY3Rpb24gc2V0RXZhbHVhdG9yKG5ld0V2YWx1YXRvcikge1xuICB0aGVFdmFsdWF0b3JGdW5jdGlvbiA9IG5ld0V2YWx1YXRvcjtcbn1cbmZ1bmN0aW9uIG5vcm1hbEV2YWx1YXRvcihlbCwgZXhwcmVzc2lvbikge1xuICBsZXQgb3ZlcnJpZGRlbk1hZ2ljcyA9IHt9O1xuICBpbmplY3RNYWdpY3Mob3ZlcnJpZGRlbk1hZ2ljcywgZWwpO1xuICBsZXQgZGF0YVN0YWNrID0gW292ZXJyaWRkZW5NYWdpY3MsIC4uLmNsb3Nlc3REYXRhU3RhY2soZWwpXTtcbiAgbGV0IGV2YWx1YXRvciA9IHR5cGVvZiBleHByZXNzaW9uID09PSBcImZ1bmN0aW9uXCIgPyBnZW5lcmF0ZUV2YWx1YXRvckZyb21GdW5jdGlvbihkYXRhU3RhY2ssIGV4cHJlc3Npb24pIDogZ2VuZXJhdGVFdmFsdWF0b3JGcm9tU3RyaW5nKGRhdGFTdGFjaywgZXhwcmVzc2lvbiwgZWwpO1xuICByZXR1cm4gdHJ5Q2F0Y2guYmluZChudWxsLCBlbCwgZXhwcmVzc2lvbiwgZXZhbHVhdG9yKTtcbn1cbmZ1bmN0aW9uIGdlbmVyYXRlRXZhbHVhdG9yRnJvbUZ1bmN0aW9uKGRhdGFTdGFjaywgZnVuYykge1xuICByZXR1cm4gKHJlY2VpdmVyID0gKCkgPT4ge1xuICB9LCB7c2NvcGU6IHNjb3BlMiA9IHt9LCBwYXJhbXMgPSBbXX0gPSB7fSkgPT4ge1xuICAgIGxldCByZXN1bHQgPSBmdW5jLmFwcGx5KG1lcmdlUHJveGllcyhbc2NvcGUyLCAuLi5kYXRhU3RhY2tdKSwgcGFyYW1zKTtcbiAgICBydW5JZlR5cGVPZkZ1bmN0aW9uKHJlY2VpdmVyLCByZXN1bHQpO1xuICB9O1xufVxudmFyIGV2YWx1YXRvck1lbW8gPSB7fTtcbmZ1bmN0aW9uIGdlbmVyYXRlRnVuY3Rpb25Gcm9tU3RyaW5nKGV4cHJlc3Npb24sIGVsKSB7XG4gIGlmIChldmFsdWF0b3JNZW1vW2V4cHJlc3Npb25dKSB7XG4gICAgcmV0dXJuIGV2YWx1YXRvck1lbW9bZXhwcmVzc2lvbl07XG4gIH1cbiAgbGV0IEFzeW5jRnVuY3Rpb24gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoYXN5bmMgZnVuY3Rpb24oKSB7XG4gIH0pLmNvbnN0cnVjdG9yO1xuICBsZXQgcmlnaHRTaWRlU2FmZUV4cHJl
1c3Npb24gPSAvXltcXG5cXHNdKmlmLipcXCguKlxcKS8udGVzdChleHByZXNzaW9uKSB8fCAvXihsZXR8Y29uc3QpXFxzLy50ZXN0KGV4cHJlc3Npb24pID8gYChhc3luYygpPT57ICR7ZXhwcmVzc2lvbn0gfSkoKWAgOiBleHByZXNzaW9uO1xuICBjb25zdCBzYWZlQXN5bmNGdW5jdGlvbiA9ICgpID0+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIG5ldyBBc3luY0Z1bmN0aW9uKFtcIl9fc2VsZlwiLCBcInNjb3BlXCJdLCBgd2l0aCAoc2NvcGUpIHsgX19zZWxmLnJlc3VsdCA9ICR7cmlnaHRTaWRlU2FmZUV4cHJlc3Npb259IH07IF9fc2VsZi5maW5pc2hlZCA9IHRydWU7IHJldHVybiBfX3NlbGYucmVzdWx0O2ApO1xuICAgIH0gY2F0Y2ggKGVycm9yMikge1xuICAgICAgaGFuZGxlRXJyb3IoZXJyb3IyLCBlbCwgZXhwcmVzc2lvbik7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICB9O1xuICBsZXQgZnVuYyA9IHNhZmVBc3luY0Z1bmN0aW9uKCk7XG4gIGV2YWx1YXRvck1lbW9bZXhwcmVzc2lvbl0gPSBmdW5jO1xuICByZXR1cm4gZnVuYztcbn1cbmZ1bmN0aW9uIGdlbmVyYXRlRXZhbHVhdG9yRnJvbVN0cmluZyhkYXRhU3RhY2ssIGV4cHJlc3Npb24sIGVsKSB7XG4gIGxldCBmdW5jID0gZ2VuZXJhdGVGdW5jdGlvbkZyb21TdHJpbmcoZXhwcmVzc2lvbiwgZWwpO1xuICByZXR1cm4gKHJlY2VpdmVyID0gKCkgPT4ge1xuICB9LCB7c2NvcGU6IHNjb3BlMiA9IHt9LCBwYXJhbXMgPSBbXX0gPSB7fSkgPT4ge1xuICAgIGZ1bmMucmVzdWx0ID0gdm9pZCAwO1xuICAgIGZ1bmMuZmluaXNoZWQgPSBmYWxzZTtcbiAgICBsZXQgY29tcGxldGVTY29wZSA9IG1lcmdlUHJveGllcyhbc2NvcGUyLCAuLi5kYXRhU3RhY2tdKTtcbiAgICBpZiAodHlwZW9mIGZ1bmMgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgbGV0IHByb21pc2UgPSBmdW5jKGZ1bmMsIGNvbXBsZXRlU2NvcGUpLmNhdGNoKChlcnJvcjIpID0+IGhhbmRsZUVycm9yKGVycm9yMiwgZWwsIGV4cHJlc3Npb24pKTtcbiAgICAgIGlmIChmdW5jLmZpbmlzaGVkKSB7XG4gICAgICAgIHJ1bklmVHlwZU9mRnVuY3Rpb24ocmVjZWl2ZXIsIGZ1bmMucmVzdWx0LCBjb21wbGV0ZVNjb3BlLCBwYXJhbXMsIGVsKTtcbiAgICAgICAgZnVuYy5yZXN1bHQgPSB2b2lkIDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwcm9taXNlLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgICAgIHJ1bklmVHlwZU9mRnVuY3Rpb24ocmVjZWl2ZXIsIHJlc3VsdCwgY29tcGxldGVTY29wZSwgcGFyYW1zLCBlbCk7XG4gICAgICAgIH0pLmNhdGNoKChlcnJvcjIpID0+IGhhbmRsZUVycm9yKGVycm9yMiwgZWwsIGV4cHJlc3Npb24pKS5maW5hbGx5KCgpID0+IGZ1bmMucmVzdWx0ID0gdm9pZCAwKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG59XG5mdW5jdGlvbiBydW5JZlR5cGVPZkZ1bmN0aW9uKHJlY2VpdmVyLCB2YWx1ZSwgc2NvcGUyLCBwYXJhbXMsIGVsKSB7XG4gIGlmIChzaG91bGRBdXRvRXZhbHVhdGVGdW5jdGlvbnMgJiYgdHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICBsZXQgcmVzdWx0ID0gdmFsdWUuYXBwbHkoc2NvcGUyLCBwYXJhbXMpO1xuICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICByZXN1bHQudGhlbigoaSkgPT4gcnVuSWZUeXBlT2ZGdW5jdGlvbihyZWNlaXZlciwgaSwgc2NvcGUyLCBwYXJhbXMpKS5jYXRjaCgoZXJyb3IyKSA9PiBoYW5kbGVFcnJvcihlcnJvcjIsIGVsLCB2YWx1ZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZWNlaXZlcihyZXN1bHQpO1xuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgdmFsdWUudGhlbigoaSkgPT4gcmVjZWl2ZXIoaSkpO1xuICB9IGVsc2Uge1xuICAgIHJlY2VpdmVyKHZhbHVlKTtcbiAgfVxufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvZGlyZWN0aXZlcy5qc1xudmFyIHByZWZpeEFzU3RyaW5nID0gXCJ4LVwiO1xuZnVuY3Rpb24gcHJlZml4KHN1YmplY3QgPSBcIlwiKSB7XG4gIHJldHVybiBwcmVmaXhBc1N0cmluZyArIHN1YmplY3Q7XG59XG5mdW5jdGlvbiBzZXRQcmVmaXgobmV3UHJlZml4KSB7XG4gIHByZWZpeEFzU3RyaW5nID0gbmV3UHJlZml4O1xufVxudmFyIGRpcmVjdGl2ZUhhbmRsZXJzID0ge307XG5mdW5jdGlvbiBkaXJlY3RpdmUobmFtZSwgY2FsbGJhY2spIHtcbiAgZGlyZWN0aXZlSGFuZGxlcnNbbmFtZV0gPSBjYWxsYmFjaztcbiAgcmV0dXJuIHtcbiAgICBiZWZvcmUoZGlyZWN0aXZlMikge1xuICAgICAgaWYgKCFkaXJlY3RpdmVIYW5kbGVyc1tkaXJlY3RpdmUyXSkge1xuICAgICAgICBjb25zb2xlLndhcm4oXCJDYW5ub3QgZmluZCBkaXJlY3RpdmUgYCR7ZGlyZWN0aXZlfWAuIGAke25hbWV9YCB3aWxsIHVzZSB0aGUgZGVmYXVsdCBvcmRlciBvZiBleGVjdXRpb25cIik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBvcyA9IGRpcmVjdGl2ZU9yZGVyLmluZGV4T2YoZGlyZWN0aXZlMik7XG4gICAgICBkaXJlY3RpdmVPcmRlci5zcGxpY2UocG9zID49IDAgPyBwb3MgOiBkaXJlY3RpdmVPcmRlci5pbmRleE9mKFwiREVGQVVMVFwiKSwgMCwgbmFtZSk7XG4gICAgfVxuICB9O1xufVxuZnVuY3Rpb24gZGlyZWN0aXZlcyhlbCwgYXR0cmlidXRlcywgb3JpZ2luYWxBdHRyaWJ1dGVPdmVycmlkZSkge1xuICBhdHRyaWJ1dGVzID0gQXJyYXkuZnJvbShhdHRyaWJ1dGVzKTtcbiAgaWYgKGVsLl94X3ZpcnR1YWxEaXJlY3RpdmVzKSB7XG4gICAgbGV0IHZBdHRyaWJ1dGVzID0gT2JqZWN0LmVud
1HJpZXMoZWwuX3hfdmlydHVhbERpcmVjdGl2ZXMpLm1hcCgoW25hbWUsIHZhbHVlXSkgPT4gKHtuYW1lLCB2YWx1ZX0pKTtcbiAgICBsZXQgc3RhdGljQXR0cmlidXRlcyA9IGF0dHJpYnV0ZXNPbmx5KHZBdHRyaWJ1dGVzKTtcbiAgICB2QXR0cmlidXRlcyA9IHZBdHRyaWJ1dGVzLm1hcCgoYXR0cmlidXRlKSA9PiB7XG4gICAgICBpZiAoc3RhdGljQXR0cmlidXRlcy5maW5kKChhdHRyKSA9PiBhdHRyLm5hbWUgPT09IGF0dHJpYnV0ZS5uYW1lKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIG5hbWU6IGB4LWJpbmQ6JHthdHRyaWJ1dGUubmFtZX1gLFxuICAgICAgICAgIHZhbHVlOiBgXCIke2F0dHJpYnV0ZS52YWx1ZX1cImBcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhdHRyaWJ1dGU7XG4gICAgfSk7XG4gICAgYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXMuY29uY2F0KHZBdHRyaWJ1dGVzKTtcbiAgfVxuICBsZXQgdHJhbnNmb3JtZWRBdHRyaWJ1dGVNYXAgPSB7fTtcbiAgbGV0IGRpcmVjdGl2ZXMyID0gYXR0cmlidXRlcy5tYXAodG9UcmFuc2Zvcm1lZEF0dHJpYnV0ZXMoKG5ld05hbWUsIG9sZE5hbWUpID0+IHRyYW5zZm9ybWVkQXR0cmlidXRlTWFwW25ld05hbWVdID0gb2xkTmFtZSkpLmZpbHRlcihvdXROb25BbHBpbmVBdHRyaWJ1dGVzKS5tYXAodG9QYXJzZWREaXJlY3RpdmVzKHRyYW5zZm9ybWVkQXR0cmlidXRlTWFwLCBvcmlnaW5hbEF0dHJpYnV0ZU92ZXJyaWRlKSkuc29ydChieVByaW9yaXR5KTtcbiAgcmV0dXJuIGRpcmVjdGl2ZXMyLm1hcCgoZGlyZWN0aXZlMikgPT4ge1xuICAgIHJldHVybiBnZXREaXJlY3RpdmVIYW5kbGVyKGVsLCBkaXJlY3RpdmUyKTtcbiAgfSk7XG59XG5mdW5jdGlvbiBhdHRyaWJ1dGVzT25seShhdHRyaWJ1dGVzKSB7XG4gIHJldHVybiBBcnJheS5mcm9tKGF0dHJpYnV0ZXMpLm1hcCh0b1RyYW5zZm9ybWVkQXR0cmlidXRlcygpKS5maWx0ZXIoKGF0dHIpID0+ICFvdXROb25BbHBpbmVBdHRyaWJ1dGVzKGF0dHIpKTtcbn1cbnZhciBpc0RlZmVycmluZ0hhbmRsZXJzID0gZmFsc2U7XG52YXIgZGlyZWN0aXZlSGFuZGxlclN0YWNrcyA9IG5ldyBNYXAoKTtcbnZhciBjdXJyZW50SGFuZGxlclN0YWNrS2V5ID0gU3ltYm9sKCk7XG5mdW5jdGlvbiBkZWZlckhhbmRsaW5nRGlyZWN0aXZlcyhjYWxsYmFjaykge1xuICBpc0RlZmVycmluZ0hhbmRsZXJzID0gdHJ1ZTtcbiAgbGV0IGtleSA9IFN5bWJvbCgpO1xuICBjdXJyZW50SGFuZGxlclN0YWNrS2V5ID0ga2V5O1xuICBkaXJlY3RpdmVIYW5kbGVyU3RhY2tzLnNldChrZXksIFtdKTtcbiAgbGV0IGZsdXNoSGFuZGxlcnMgPSAoKSA9PiB7XG4gICAgd2hpbGUgKGRpcmVjdGl2ZUhhbmRsZXJTdGFja3MuZ2V0KGtleSkubGVuZ3RoKVxuICAgICAgZGlyZWN0aXZlSGFuZGxlclN0YWNrcy5nZXQoa2V5KS5zaGlmdCgpKCk7XG4gICAgZGlyZWN0aXZlSGFuZGxlclN0YWNrcy5kZWxldGUoa2V5KTtcbiAgfTtcbiAgbGV0IHN0b3BEZWZlcnJpbmcgPSAoKSA9PiB7XG4gICAgaXNEZWZlcnJpbmdIYW5kbGVycyA9IGZhbHNlO1xuICAgIGZsdXNoSGFuZGxlcnMoKTtcbiAgfTtcbiAgY2FsbGJhY2soZmx1c2hIYW5kbGVycyk7XG4gIHN0b3BEZWZlcnJpbmcoKTtcbn1cbmZ1bmN0aW9uIGdldEVsZW1lbnRCb3VuZFV0aWxpdGllcyhlbCkge1xuICBsZXQgY2xlYW51cHMgPSBbXTtcbiAgbGV0IGNsZWFudXAyID0gKGNhbGxiYWNrKSA9PiBjbGVhbnVwcy5wdXNoKGNhbGxiYWNrKTtcbiAgbGV0IFtlZmZlY3QzLCBjbGVhbnVwRWZmZWN0XSA9IGVsZW1lbnRCb3VuZEVmZmVjdChlbCk7XG4gIGNsZWFudXBzLnB1c2goY2xlYW51cEVmZmVjdCk7XG4gIGxldCB1dGlsaXRpZXMgPSB7XG4gICAgQWxwaW5lOiBhbHBpbmVfZGVmYXVsdCxcbiAgICBlZmZlY3Q6IGVmZmVjdDMsXG4gICAgY2xlYW51cDogY2xlYW51cDIsXG4gICAgZXZhbHVhdGVMYXRlcjogZXZhbHVhdGVMYXRlci5iaW5kKGV2YWx1YXRlTGF0ZXIsIGVsKSxcbiAgICBldmFsdWF0ZTogZXZhbHVhdGUuYmluZChldmFsdWF0ZSwgZWwpXG4gIH07XG4gIGxldCBkb0NsZWFudXAgPSAoKSA9PiBjbGVhbnVwcy5mb3JFYWNoKChpKSA9PiBpKCkpO1xuICByZXR1cm4gW3V0aWxpdGllcywgZG9DbGVhbnVwXTtcbn1cbmZ1bmN0aW9uIGdldERpcmVjdGl2ZUhhbmRsZXIoZWwsIGRpcmVjdGl2ZTIpIHtcbiAgbGV0IG5vb3AgPSAoKSA9PiB7XG4gIH07XG4gIGxldCBoYW5kbGVyNCA9IGRpcmVjdGl2ZUhhbmRsZXJzW2RpcmVjdGl2ZTIudHlwZV0gfHwgbm9vcDtcbiAgbGV0IFt1dGlsaXRpZXMsIGNsZWFudXAyXSA9IGdldEVsZW1lbnRCb3VuZFV0aWxpdGllcyhlbCk7XG4gIG9uQXR0cmlidXRlUmVtb3ZlZChlbCwgZGlyZWN0aXZlMi5vcmlnaW5hbCwgY2xlYW51cDIpO1xuICBsZXQgZnVsbEhhbmRsZXIgPSAoKSA9PiB7XG4gICAgaWYgKGVsLl94X2lnbm9yZSB8fCBlbC5feF9pZ25vcmVTZWxmKVxuICAgICAgcmV0dXJuO1xuICAgIGhhbmRsZXI0LmlubGluZSAmJiBoYW5kbGVyNC5pbmxpbmUoZWwsIGRpcmVjdGl2ZTIsIHV0aWxpdGllcyk7XG4gICAgaGFuZGxlcjQgPSBoYW5kbGVyNC5iaW5kKGhhbmRsZXI0LCBlbCwgZGlyZWN0aXZlMiwgdXRpbGl0aWVzKTtcbiAgICBpc0RlZmVycmluZ0hhbmRsZXJzID8gZGlyZWN0aXZlSGFuZGxlclN0YWNrcy5nZXQoY3VycmVudEhhbmRsZXJTdGFja0tleSkucHVzaChoYW5kbGVyNCkgOiBoYW5kbGVyNCgpO1xuICB9O1xuICBmdWxsSGFuZGxlci5ydW5DbGVhbnVwcyA9IGNsZWFudXAyO1xuICByZXR1cm4gZnVsbEhhbmRsZXI7XG59XG52YXIgc3RhcnRpbmdXaXRoID0gKHN1YmplY3QsIHJlcGxhY2VtZW50KSA9PiAoe25hbWUsIHZhbHVlfSkgPT4ge1xuICBpZiAobmFtZS5zdGFydHNXaXRoKHN1YmplY3QpKVxuICAgIG5hbWUgPSBuYW1lLnJlcGxhY2Uoc3ViamVjdCwgcmVwbGFjZW1lbnQpO1xuICByZXR1cm4ge25hbWUsIHZhbHVlfTtcbn07XG52YXIgaW50byA9IChpKSA9PiBpO1xuZnVuY3Rpb24gdG9UcmFuc2Zvcm1lZEF0dHJpYnV0ZXMoY2FsbGJhY2sgPSAoKSA9PiB7XG59KSB7XG4gIHJldHVybiAoe25hbWUsIHZhbHVlfSkgPT4ge1xuICAgIGxldCB7bmFtZTogbmV3TmFtZSwgdmFsdWU6IG5ld1ZhbHVlfSA9IGF0dHJpYnV0ZVRyYW5zZm9ybWVycy5yZWR1Y2UoKGNhcnJ5LCB0cmFuc2Zvcm0pID0+IHtcbiAgICAgIHJldHVybi
1B0cmFuc2Zvcm0oY2FycnkpO1xuICAgIH0sIHtuYW1lLCB2YWx1ZX0pO1xuICAgIGlmIChuZXdOYW1lICE9PSBuYW1lKVxuICAgICAgY2FsbGJhY2sobmV3TmFtZSwgbmFtZSk7XG4gICAgcmV0dXJuIHtuYW1lOiBuZXdOYW1lLCB2YWx1ZTogbmV3VmFsdWV9O1xuICB9O1xufVxudmFyIGF0dHJpYnV0ZVRyYW5zZm9ybWVycyA9IFtdO1xuZnVuY3Rpb24gbWFwQXR0cmlidXRlcyhjYWxsYmFjaykge1xuICBhdHRyaWJ1dGVUcmFuc2Zvcm1lcnMucHVzaChjYWxsYmFjayk7XG59XG5mdW5jdGlvbiBvdXROb25BbHBpbmVBdHRyaWJ1dGVzKHtuYW1lfSkge1xuICByZXR1cm4gYWxwaW5lQXR0cmlidXRlUmVnZXgoKS50ZXN0KG5hbWUpO1xufVxudmFyIGFscGluZUF0dHJpYnV0ZVJlZ2V4ID0gKCkgPT4gbmV3IFJlZ0V4cChgXiR7cHJlZml4QXNTdHJpbmd9KFteOl4uXSspXFxcXGJgKTtcbmZ1bmN0aW9uIHRvUGFyc2VkRGlyZWN0aXZlcyh0cmFuc2Zvcm1lZEF0dHJpYnV0ZU1hcCwgb3JpZ2luYWxBdHRyaWJ1dGVPdmVycmlkZSkge1xuICByZXR1cm4gKHtuYW1lLCB2YWx1ZX0pID0+IHtcbiAgICBsZXQgdHlwZU1hdGNoID0gbmFtZS5tYXRjaChhbHBpbmVBdHRyaWJ1dGVSZWdleCgpKTtcbiAgICBsZXQgdmFsdWVNYXRjaCA9IG5hbWUubWF0Y2goLzooW2EtekEtWjAtOVxcLTpdKykvKTtcbiAgICBsZXQgbW9kaWZpZXJzID0gbmFtZS5tYXRjaCgvXFwuW14uXFxdXSsoPz1bXlxcXV0qJCkvZykgfHwgW107XG4gICAgbGV0IG9yaWdpbmFsID0gb3JpZ2luYWxBdHRyaWJ1dGVPdmVycmlkZSB8fCB0cmFuc2Zvcm1lZEF0dHJpYnV0ZU1hcFtuYW1lXSB8fCBuYW1lO1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiB0eXBlTWF0Y2ggPyB0eXBlTWF0Y2hbMV0gOiBudWxsLFxuICAgICAgdmFsdWU6IHZhbHVlTWF0Y2ggPyB2YWx1ZU1hdGNoWzFdIDogbnVsbCxcbiAgICAgIG1vZGlmaWVyczogbW9kaWZpZXJzLm1hcCgoaSkgPT4gaS5yZXBsYWNlKFwiLlwiLCBcIlwiKSksXG4gICAgICBleHByZXNzaW9uOiB2YWx1ZSxcbiAgICAgIG9yaWdpbmFsXG4gICAgfTtcbiAgfTtcbn1cbnZhciBERUZBVUxUID0gXCJERUZBVUxUXCI7XG52YXIgZGlyZWN0aXZlT3JkZXIgPSBbXG4gIFwiaWdub3JlXCIsXG4gIFwicmVmXCIsXG4gIFwiZGF0YVwiLFxuICBcImlkXCIsXG4gIFwiYmluZFwiLFxuICBcImluaXRcIixcbiAgXCJmb3JcIixcbiAgXCJtb2RlbFwiLFxuICBcIm1vZGVsYWJsZVwiLFxuICBcInRyYW5zaXRpb25cIixcbiAgXCJzaG93XCIsXG4gIFwiaWZcIixcbiAgREVGQVVMVCxcbiAgXCJ0ZWxlcG9ydFwiXG5dO1xuZnVuY3Rpb24gYnlQcmlvcml0eShhLCBiKSB7XG4gIGxldCB0eXBlQSA9IGRpcmVjdGl2ZU9yZGVyLmluZGV4T2YoYS50eXBlKSA9PT0gLTEgPyBERUZBVUxUIDogYS50eXBlO1xuICBsZXQgdHlwZUIgPSBkaXJlY3RpdmVPcmRlci5pbmRleE9mKGIudHlwZSkgPT09IC0xID8gREVGQVVMVCA6IGIudHlwZTtcbiAgcmV0dXJuIGRpcmVjdGl2ZU9yZGVyLmluZGV4T2YodHlwZUEpIC0gZGlyZWN0aXZlT3JkZXIuaW5kZXhPZih0eXBlQik7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy91dGlscy9kaXNwYXRjaC5qc1xuZnVuY3Rpb24gZGlzcGF0Y2goZWwsIG5hbWUsIGRldGFpbCA9IHt9KSB7XG4gIGVsLmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KG5hbWUsIHtcbiAgICBkZXRhaWwsXG4gICAgYnViYmxlczogdHJ1ZSxcbiAgICBjb21wb3NlZDogdHJ1ZSxcbiAgICBjYW5jZWxhYmxlOiB0cnVlXG4gIH0pKTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL3V0aWxzL3dhbGsuanNcbmZ1bmN0aW9uIHdhbGsoZWwsIGNhbGxiYWNrKSB7XG4gIGlmICh0eXBlb2YgU2hhZG93Um9vdCA9PT0gXCJmdW5jdGlvblwiICYmIGVsIGluc3RhbmNlb2YgU2hhZG93Um9vdCkge1xuICAgIEFycmF5LmZyb20oZWwuY2hpbGRyZW4pLmZvckVhY2goKGVsMikgPT4gd2FsayhlbDIsIGNhbGxiYWNrKSk7XG4gICAgcmV0dXJuO1xuICB9XG4gIGxldCBza2lwID0gZmFsc2U7XG4gIGNhbGxiYWNrKGVsLCAoKSA9PiBza2lwID0gdHJ1ZSk7XG4gIGlmIChza2lwKVxuICAgIHJldHVybjtcbiAgbGV0IG5vZGUgPSBlbC5maXJzdEVsZW1lbnRDaGlsZDtcbiAgd2hpbGUgKG5vZGUpIHtcbiAgICB3YWxrKG5vZGUsIGNhbGxiYWNrLCBmYWxzZSk7XG4gICAgbm9kZSA9IG5vZGUubmV4dEVsZW1lbnRTaWJsaW5nO1xuICB9XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy91dGlscy93YXJuLmpzXG5mdW5jdGlvbiB3YXJuKG1lc3NhZ2UsIC4uLmFyZ3MpIHtcbiAgY29uc29sZS53YXJuKGBBbHBpbmUgV2FybmluZzogJHttZXNzYWdlfWAsIC4uLmFyZ3MpO1xufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvbGlmZWN5Y2xlLmpzXG52YXIgc3RhcnRlZCA9IGZhbHNlO1xuZnVuY3Rpb24gc3RhcnQoKSB7XG4gIGlmIChzdGFydGVkKVxuICAgIHdhcm4oXCJBbHBpbmUgaGFzIGFscmVhZHkgYmVlbiBpbml0aWFsaXplZCBvbiB0aGlzIHBhZ2UuIENhbGxpbmcgQWxwaW5lLnN0YXJ0KCkgbW9yZSB0aGFuIG9uY2UgY2FuIGNhdXNlIHByb2JsZW1zLlwiKTtcbiAgc3RhcnRlZCA9IHRydWU7XG4gIGlmICghZG9jdW1lbnQuYm9keSlcbiAgICB3YXJuKFwiVW5hYmxlIHRvIGluaXRpYWxpemUuIFRyeWluZyB0byBsb2FkIEFscGluZSBiZWZvcmUgYDxib2R5PmAgaXMgYXZhaWxhYmxlLiBEaWQgeW91IGZvcmdldCB0byBhZGQgYGRlZmVyYCBpbiBBbHBpbmUncyBgPHNjcmlwdD5gIHRhZz9cIik7XG4gIGRpc3BhdGNoKGRvY3VtZW50LCBcImFscGluZTppbml0XCIpO1xuICBkaXNwYXRjaChkb2N1bWVudCwgXCJhbHBpbmU6aW5pdGlhbGl6aW5nXCIpO1xuICBzdGFydE9ic2VydmluZ011dGF0aW9ucygpO1xuICBvbkVsQWRkZWQoKGVsKSA9PiBpbml0VHJlZShlbCwgd2FsaykpO1xuICBvbkVsUmVtb3ZlZCgoZWwpID0+IGRlc3Ryb3lUcmVlKGVsKSk7XG4gIG9uQXR0cmlidXRlc0FkZGVkKChlbCwgYXR0cnMpID0+IHtcbiAgICBkaXJlY3RpdmVzKGVsLCBhdHRycykuZm9yRWFjaCgoaGFuZGxlKSA9PiBoYW5kbGUoKSk7XG4gIH0pO1xuICBsZXQgb3V0TmVzdGVkQ29tcG9uZW50cyA9IChlbCkgPT4gIWNsb3Nlc3RSb290KGVsLnBhcmVudEVsZW1lbnQsIHRydWUpO1xuICBBcnJheS5mcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYWxsU2VsZWN0b3JzKCkpKS5maWx0ZXIob3V0TmVzdGVkQ29tcG9uZW50cykuZm9yRWFjaCgoZWwpID0+IHtcbiAgICBpbml0VHJlZShlbCk7XG4gIH0pO1xuICBkaXNwYXRjaChkb2N1bWVudCwgXCJhbHBpbmU6aW5pdGlhbGl6ZWRcIik7XG59XG52YXIgcm9vdFNlbGVjdG9yQ2FsbGJhY2tzID0gW107XG52YXIgaW5pdFNlbGVjdG9yQ2FsbGJhY2tzID0gW107XG5mdW5jdGlvbiByb290U2VsZWN0b3JzKCkge1xuICByZXR1cm4gcm9vdFNlbGVjdG9yQ2FsbGJhY2tzLm1hcCgoZm4pID0+IGZuKCkpO1xufVxuZnVuY3Rpb24gYWxsU2VsZWN0b3JzKCkge1xuICByZXR1cm4gcm9vdFNlbGVjdG9yQ2FsbGJhY2tzLmNvbmNhdChpbml0U2VsZWN0b3JDYWxsYmFja3MpLm1hcCgoZm4pID0+IGZuKCkpO1xufVxuZnVuY3Rpb24gYWRkUm9vdFNlbGVjdG9yKHNlbGVjdG9yQ2FsbGJhY2spIHtcbiAgcm9vdFNlbGVjdG9yQ2FsbGJhY2tzLnB1c2goc2VsZWN0b3JDYWxsYmFjayk7XG59XG5mdW5jdGlvbiBhZGRJbml0U2VsZWN0b3Ioc2VsZWN0b3JDYWxsYmFjaykge1xuICBpbml0U2VsZWN0b3JDYWxsYmFja3MucHVzaChzZWxlY3RvckNhbGxiYWNrKTtcbn1cbmZ1bmN0aW9uIGNsb3Nlc3RSb290KGVsLCBpbmNsdWRlSW5pdFNlbGVjdG9ycyA9IGZhbHNlKSB7XG4gIHJldHVybi
1BmaW5kQ2xvc2VzdChlbCwgKGVsZW1lbnQpID0+IHtcbiAgICBjb25zdCBzZWxlY3RvcnMgPSBpbmNsdWRlSW5pdFNlbGVjdG9ycyA/IGFsbFNlbGVjdG9ycygpIDogcm9vdFNlbGVjdG9ycygpO1xuICAgIGlmIChzZWxlY3RvcnMuc29tZSgoc2VsZWN0b3IpID0+IGVsZW1lbnQubWF0Y2hlcyhzZWxlY3RvcikpKVxuICAgICAgcmV0dXJuIHRydWU7XG4gIH0pO1xufVxuZnVuY3Rpb24gZmluZENsb3Nlc3QoZWwsIGNhbGxiYWNrKSB7XG4gIGlmICghZWwpXG4gICAgcmV0dXJuO1xuICBpZiAoY2FsbGJhY2soZWwpKVxuICAgIHJldHVybiBlbDtcbiAgaWYgKGVsLl94X3RlbGVwb3J0QmFjaylcbiAgICBlbCA9IGVsLl94X3RlbGVwb3J0QmFjaztcbiAgaWYgKCFlbC5wYXJlbnRFbGVtZW50KVxuICAgIHJldHVybjtcbiAgcmV0dXJuIGZpbmRDbG9zZXN0KGVsLnBhcmVudEVsZW1lbnQsIGNhbGxiYWNrKTtcbn1cbmZ1bmN0aW9uIGlzUm9vdChlbCkge1xuICByZXR1cm4gcm9vdFNlbGVjdG9ycygpLnNvbWUoKHNlbGVjdG9yKSA9PiBlbC5tYXRjaGVzKHNlbGVjdG9yKSk7XG59XG52YXIgaW5pdEludGVyY2VwdG9yczIgPSBbXTtcbmZ1bmN0aW9uIGludGVyY2VwdEluaXQoY2FsbGJhY2spIHtcbiAgaW5pdEludGVyY2VwdG9yczIucHVzaChjYWxsYmFjayk7XG59XG5mdW5jdGlvbiBpbml0VHJlZShlbCwgd2Fsa2VyID0gd2FsaywgaW50ZXJjZXB0ID0gKCkgPT4ge1xufSkge1xuICBkZWZlckhhbmRsaW5nRGlyZWN0aXZlcygoKSA9PiB7XG4gICAgd2Fsa2VyKGVsLCAoZWwyLCBza2lwKSA9PiB7XG4gICAgICBpbnRlcmNlcHQoZWwyLCBza2lwKTtcbiAgICAgIGluaXRJbnRlcmNlcHRvcnMyLmZvckVhY2goKGkpID0+IGkoZWwyLCBza2lwKSk7XG4gICAgICBkaXJlY3RpdmVzKGVsMiwgZWwyLmF0dHJpYnV0ZXMpLmZvckVhY2goKGhhbmRsZSkgPT4gaGFuZGxlKCkpO1xuICAgICAgZWwyLl94X2lnbm9yZSAmJiBza2lwKCk7XG4gICAgfSk7XG4gIH0pO1xufVxuZnVuY3Rpb24gZGVzdHJveVRyZWUocm9vdCkge1xuICB3YWxrKHJvb3QsIChlbCkgPT4gY2xlYW51cEF0dHJpYnV0ZXMoZWwpKTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL25leHRUaWNrLmpzXG52YXIgdGlja1N0YWNrID0gW107XG52YXIgaXNIb2xkaW5nID0gZmFsc2U7XG5mdW5jdGlvbiBuZXh0VGljayhjYWxsYmFjayA9ICgpID0+IHtcbn0pIHtcbiAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xuICAgIGlzSG9sZGluZyB8fCBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHJlbGVhc2VOZXh0VGlja3MoKTtcbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzKSA9PiB7XG4gICAgdGlja1N0YWNrLnB1c2goKCkgPT4ge1xuICAgICAgY2FsbGJhY2soKTtcbiAgICAgIHJlcygpO1xuICAgIH0pO1xuICB9KTtcbn1cbmZ1bmN0aW9uIHJlbGVhc2VOZXh0VGlja3MoKSB7XG4gIGlzSG9sZGluZyA9IGZhbHNlO1xuICB3aGlsZSAodGlja1N0YWNrLmxlbmd0aClcbiAgICB0aWNrU3RhY2suc2hpZnQoKSgpO1xufVxuZnVuY3Rpb24gaG9sZE5leHRUaWNrcygpIHtcbiAgaXNIb2xkaW5nID0gdHJ1ZTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL3V0aWxzL2NsYXNzZXMuanNcbmZ1bmN0aW9uIHNldENsYXNzZXMoZWwsIHZhbHVlKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHJldHVybiBzZXRDbGFzc2VzRnJvbVN0cmluZyhlbCwgdmFsdWUuam9pbihcIiBcIikpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiB2YWx1ZSAhPT0gbnVsbCkge1xuICAgIHJldHVybiBzZXRDbGFzc2VzRnJvbU9iamVjdChlbCwgdmFsdWUpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgcmV0dXJuIHNldENsYXNzZXMoZWwsIHZhbHVlKCkpO1xuICB9XG4gIHJldHVybiBzZXRDbGFzc2VzRnJvbVN0cmluZyhlbCwgdmFsdWUpO1xufVxuZnVuY3Rpb24gc2V0Q2xhc3Nlc0Zyb21TdHJpbmcoZWwsIGNsYXNzU3RyaW5nKSB7XG4gIGxldCBzcGxpdCA9IChjbGFzc1N0cmluZzIpID0+IGNsYXNzU3RyaW5nMi5zcGxpdChcIiBcIikuZmlsdGVyKEJvb2xlYW4pO1xuICBsZXQgbWlzc2luZ0NsYXNzZXMgPSAoY2xhc3NTdHJpbmcyKSA9PiBjbGFzc1N0cmluZzIuc3BsaXQoXCIgXCIpLmZpbHRlcigoaSkgPT4gIWVsLmNsYXNzTGlzdC5jb250YWlucyhpKSkuZmlsdGVyKEJvb2xlYW4pO1xuICBsZXQgYWRkQ2xhc3Nlc0FuZFJldHVyblVuZG8gPSAoY2xhc3NlcykgPT4ge1xuICAgIGVsLmNsYXNzTGlzdC5hZGQoLi4uY2xhc3Nlcyk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGVsLmNsYXNzTGlzdC5yZW1vdmUoLi4uY2xhc3Nlcyk7XG4gICAgfTtcbiAgfTtcbiAgY2xhc3NTdHJpbmcgPSBjbGFzc1N0cmluZyA9PT0gdHJ1ZSA/IGNsYXNzU3RyaW5nID0gXCJcIiA6IGNsYXNzU3RyaW5nIHx8IFwiXCI7XG4gIHJldHVybiBhZGRDbGFzc2VzQW5kUmV0dXJuVW5kbyhtaXNzaW5nQ2xhc3NlcyhjbGFzc1N0cmluZykpO1xufVxuZnVuY3Rpb24gc2V0Q2xhc3Nlc0Zyb21PYmplY3QoZWwsIGNsYXNzT2JqZWN0KSB7XG4gIGxldCBzcGxpdCA9IChjbGFzc1N0cmluZykgPT4gY2xhc3NTdHJpbmcuc3BsaXQoXCIgXCIpLmZpbHRlcihCb29sZWFuKTtcbiAgbGV0IGZvckFkZCA9IE9iamVjdC5lbnRyaWVzKGNsYXNzT2JqZWN0KS5mbGF0TWFwKChbY2xhc3NTdHJpbmcsIGJvb2xdKSA9PiBib29sID8gc3BsaXQoY2xhc3NTdHJpbmcpIDogZmFsc2UpLmZpbHRlcihCb29sZWFuKTtcbiAgbGV0IGZvclJlbW92ZSA9IE9iamVjdC5lbnRyaWVzKGNsYXNzT2JqZWN0KS5mbGF0TWFwKChbY2xhc3NTdHJpbmcsIGJvb2xdKSA9PiAhYm9vbCA/IHNwbGl0KGNsYXNzU3RyaW5nKSA6IGZhbHNlKS5maWx0ZXIoQm9vbGVhbik7XG4gIGxldCBhZGRlZCA9IFtdO1xuICBsZXQgcmVtb3ZlZCA9IFtdO1xuICBmb3JSZW1vdmUuZm9yRWFjaCgoaSkgPT4ge1xuICAgIGlmIChlbC5jbGFzc0xpc3QuY29udGFpbnMoaSkpIHtcbiAgICAgIGVsLmNsYXNzTGlzdC5yZW1vdmUoaSk7XG4gICAgICByZW1vdmVkLnB1c2goaSk7XG4gICAgfVxuICB9KTtcbiAgZm9yQWRkLmZvckVhY2goKGkpID0+IHtcbiAgICBpZiAoIWVsLmNsYXNzTGlzdC5jb250YWlucyhpKSkge1xuICAgICAgZWwuY2xhc3NMaXN0LmFkZChpKTtcbiAgICAgIGFkZGVkLnB1c2goaSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuICgpID0+IHtcbiAgICByZW1vdmVkLmZvckVhY2goKGkpID0+IGVsLmNsYXNzTGlzdC5hZGQoaSkpO1xuICAgIGFkZGVkLmZvckVhY2goKGkpID0+IGVsLmNsYXNzTGlzdC5yZW1vdmUoaSkpO1xuICB9O1xufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvdXRpbHMvc3R5bGVzLmpzXG5mdW5jdGlvbiBzZXRTdHlsZXMoZWwsIHZhbHVlKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgIT09IG51bGwpIHtcbiAgICByZXR1cm4gc2V0U3R5bGVzRnJvbU9iamVjdChlbCwgdmFsdWUpO1xuICB9XG4gI
1HJldHVybiBzZXRTdHlsZXNGcm9tU3RyaW5nKGVsLCB2YWx1ZSk7XG59XG5mdW5jdGlvbiBzZXRTdHlsZXNGcm9tT2JqZWN0KGVsLCB2YWx1ZSkge1xuICBsZXQgcHJldmlvdXNTdHlsZXMgPSB7fTtcbiAgT2JqZWN0LmVudHJpZXModmFsdWUpLmZvckVhY2goKFtrZXksIHZhbHVlMl0pID0+IHtcbiAgICBwcmV2aW91c1N0eWxlc1trZXldID0gZWwuc3R5bGVba2V5XTtcbiAgICBpZiAoIWtleS5zdGFydHNXaXRoKFwiLS1cIikpIHtcbiAgICAgIGtleSA9IGtlYmFiQ2FzZShrZXkpO1xuICAgIH1cbiAgICBlbC5zdHlsZS5zZXRQcm9wZXJ0eShrZXksIHZhbHVlMik7XG4gIH0pO1xuICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICBpZiAoZWwuc3R5bGUubGVuZ3RoID09PSAwKSB7XG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoXCJzdHlsZVwiKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gKCkgPT4ge1xuICAgIHNldFN0eWxlcyhlbCwgcHJldmlvdXNTdHlsZXMpO1xuICB9O1xufVxuZnVuY3Rpb24gc2V0U3R5bGVzRnJvbVN0cmluZyhlbCwgdmFsdWUpIHtcbiAgbGV0IGNhY2hlID0gZWwuZ2V0QXR0cmlidXRlKFwic3R5bGVcIiwgdmFsdWUpO1xuICBlbC5zZXRBdHRyaWJ1dGUoXCJzdHlsZVwiLCB2YWx1ZSk7XG4gIHJldHVybiAoKSA9PiB7XG4gICAgZWwuc2V0QXR0cmlidXRlKFwic3R5bGVcIiwgY2FjaGUgfHwgXCJcIik7XG4gIH07XG59XG5mdW5jdGlvbiBrZWJhYkNhc2Uoc3ViamVjdCkge1xuICByZXR1cm4gc3ViamVjdC5yZXBsYWNlKC8oW2Etel0pKFtBLVpdKS9nLCBcIiQxLSQyXCIpLnRvTG93ZXJDYXNlKCk7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy91dGlscy9vbmNlLmpzXG5mdW5jdGlvbiBvbmNlKGNhbGxiYWNrLCBmYWxsYmFjayA9ICgpID0+IHtcbn0pIHtcbiAgbGV0IGNhbGxlZCA9IGZhbHNlO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgaWYgKCFjYWxsZWQpIHtcbiAgICAgIGNhbGxlZCA9IHRydWU7XG4gICAgICBjYWxsYmFjay5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmYWxsYmFjay5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2RpcmVjdGl2ZXMveC10cmFuc2l0aW9uLmpzXG5kaXJlY3RpdmUoXCJ0cmFuc2l0aW9uXCIsIChlbCwge3ZhbHVlLCBtb2RpZmllcnMsIGV4cHJlc3Npb259LCB7ZXZhbHVhdGU6IGV2YWx1YXRlMn0pID0+IHtcbiAgaWYgKHR5cGVvZiBleHByZXNzaW9uID09PSBcImZ1bmN0aW9uXCIpXG4gICAgZXhwcmVzc2lvbiA9IGV2YWx1YXRlMihleHByZXNzaW9uKTtcbiAgaWYgKGV4cHJlc3Npb24gPT09IGZhbHNlKVxuICAgIHJldHVybjtcbiAgaWYgKCFleHByZXNzaW9uIHx8IHR5cGVvZiBleHByZXNzaW9uID09PSBcImJvb2xlYW5cIikge1xuICAgIHJlZ2lzdGVyVHJhbnNpdGlvbnNGcm9tSGVscGVyKGVsLCBtb2RpZmllcnMsIHZhbHVlKTtcbiAgfSBlbHNlIHtcbiAgICByZWdpc3RlclRyYW5zaXRpb25zRnJvbUNsYXNzU3RyaW5nKGVsLCBleHByZXNzaW9uLCB2YWx1ZSk7XG4gIH1cbn0pO1xuZnVuY3Rpb24gcmVnaXN0ZXJUcmFuc2l0aW9uc0Zyb21DbGFzc1N0cmluZyhlbCwgY2xhc3NTdHJpbmcsIHN0YWdlKSB7XG4gIHJlZ2lzdGVyVHJhbnNpdGlvbk9iamVjdChlbCwgc2V0Q2xhc3NlcywgXCJcIik7XG4gIGxldCBkaXJlY3RpdmVTdG9yYWdlTWFwID0ge1xuICAgIGVudGVyOiAoY2xhc3NlcykgPT4ge1xuICAgICAgZWwuX3hfdHJhbnNpdGlvbi5lbnRlci5kdXJpbmcgPSBjbGFzc2VzO1xuICAgIH0sXG4gICAgXCJlbnRlci1zdGFydFwiOiAoY2xhc3NlcykgPT4ge1xuICAgICAgZWwuX3hfdHJhbnNpdGlvbi5lbnRlci5zdGFydCA9IGNsYXNzZXM7XG4gICAgfSxcbiAgICBcImVudGVyLWVuZFwiOiAoY2xhc3NlcykgPT4ge1xuICAgICAgZWwuX3hfdHJhbnNpdGlvbi5lbnRlci5lbmQgPSBjbGFzc2VzO1xuICAgIH0sXG4gICAgbGVhdmU6IChjbGFzc2VzKSA9PiB7XG4gICAgICBlbC5feF90cmFuc2l0aW9uLmxlYXZlLmR1cmluZyA9IGNsYXNzZXM7XG4gICAgfSxcbiAgICBcImxlYXZlLXN0YXJ0XCI6IChjbGFzc2VzKSA9PiB7XG4gICAgICBlbC5feF90cmFuc2l0aW9uLmxlYXZlLnN0YXJ0ID0gY2xhc3NlcztcbiAgICB9LFxuICAgIFwibGVhdmUtZW5kXCI6IChjbGFzc2VzKSA9PiB7XG4gICAgICBlbC5feF90cmFuc2l0aW9uLmxlYXZlLmVuZCA9IGNsYXNzZXM7XG4gICAgfVxuICB9O1xuICBkaXJlY3RpdmVTdG9yYWdlTWFwW3N0YWdlXShjbGFzc1N0cmluZyk7XG59XG5mdW5jdGlvbiByZWdpc3RlclRyYW5zaXRpb25zRnJvbUhlbHBlcihlbCwgbW9kaWZpZXJzLCBzdGFnZSkge1xuICByZWdpc3RlclRyYW5zaXRpb25PYmplY3QoZWwsIHNldFN0eWxlcyk7XG4gIGxldCBkb2VzbnRTcGVjaWZ5ID0gIW1vZGlmaWVycy5pbmNsdWRlcyhcImluXCIpICYmICFtb2RpZmllcnMuaW5jbHVkZXMoXCJvdXRcIikgJiYgIXN0YWdlO1xuICBsZXQgdHJhbnNpdGlvbmluZ0luID0gZG9lc250U3BlY2lmeSB8fCBtb2RpZmllcnMuaW5jbHVkZXMoXCJpblwiKSB8fCBbXCJlbnRlclwiXS5pbmNsdWRlcyhzdGFnZSk7XG4gIGxldCB0cmFuc2l0aW9uaW5nT3V0ID0gZG9lc250U3BlY2lmeSB8fCBtb2RpZmllcnMuaW5jbHVkZXMoXCJvdXRcIikgfHwgW1wibGVhdmVcIl0uaW5jbHVkZXMoc3RhZ2UpO1xuICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwiaW5cIikgJiYgIWRvZXNudFNwZWNpZnkpIHtcbiAgICBtb2RpZmllcnMgPSBtb2RpZmllcnMuZmlsdGVyKChpLCBpbmRleCkgPT4gaW5kZXggPCBtb2RpZmllcnMuaW5kZXhPZihcIm91dFwiKSk7XG4gIH1cbiAgaWYgKG1vZGlmaWVycy5pbmNsdWRlcyhcIm91dFwiKSAmJiAhZG9lc250U3BlY2lmeSkge1xuICAgIG1vZGlmaWVycyA9IG1vZGlmaWVycy5maWx0ZXIoKGksIGluZGV4KSA9PiBpbmRleCA+IG1vZGlmaWVycy5pbmRleE9mKFwib3V0XCIpKTtcbiAgfVxuICBsZXQgd2FudHNBbGwgPSAhbW9kaWZpZXJzLmluY2x1ZGVzKFwib3BhY2l0eVwiKSAmJiAhbW9kaWZpZXJzLmluY2x1ZGVzKFwic2NhbGVcIik7XG4gIGxldCB3YW50c09wYWNpdHkgPSB3YW50c0FsbCB8fCBtb2RpZmllcnMuaW5jbHVkZXMoXCJvcGFjaXR5XCIpO1xuICBsZXQgd2FudHNTY2FsZSA9IHdhbnRzQWxsIHx8IG1vZGlmaWVycy5pbmNsdWRlcyhcInNjYWxlXCIpO1xuICBsZXQgb3BhY2l0eVZhbHVlID0gd2FudHNPcGFjaXR5ID8gMCA6IDE7XG4gIGxldCBzY2FsZVZhbHVlID0gd2FudHNTY2FsZSA/IG1vZGlmaWVyVmFsdWUobW9kaWZpZXJzLCBcInNjYWxlXCIsIDk1KSAvIDEwMCA6IDE7XG4gIGxldCBkZWxheSA9IG1vZGlmaWVyVmFsdWUobW9kaWZpZXJzLCBcImRlbGF5XCIsIDApIC8gMWUzO1xuICBsZXQgb3JpZ2luID0gbW9kaWZpZXJWYWx1ZShtb2RpZmllcnMsIFwib3JpZ2luXCIsIFwiY2VudGVyXCIpO1xuICBsZXQgcHJvcGVydHkgPSBcIm9wYWNpdHksIHRyYW5zZm9ybVwiO1xuICBsZXQgZHVyYXRpb25JbiA9IG1vZGlmaWVyVmFsdWUobW9kaWZpZXJzLCBcImR1cmF0aW9uXCIsIDE1MCkgLyAxZTM7XG4gIGxldCBkdXJhdGlvbk91dCA9IG1vZGlmaWVyVmFsdWUobW9kaWZpZXJzLCBcImR1cmF0aW9uXCIsIDc1KSAvIDFlMztcbiAgbGV0IGVhc2luZyA9IGBjdWJpYy1iZXppZXIoMC40LCAwLjAsIDAuMiwgMSlgO1xuICBpZiAodHJhbnNpdGlvbmluZ0luKSB7XG4gICAgZWwuX3hfdHJhbnNpdGlvbi5lbnRlci5kdXJpbmcgPSB7XG4gICAgICB0cmFuc2Zvcm1PcmlnaW46IG9yaWdpbixcbiAgICAgIHRyYW5zaXRpb25EZWxheTogYCR7ZGVsYXl9c2AsXG4gICAgICB0cmFuc2l0aW9uUHJvcGVydHk6IHByb3BlcnR5LFxuICAgICAgdHJhbnNpdGlvbkR1cmF0aW9uOiBgJHtkdXJhdGlvbklufXNgLFxuICAgICAgdHJhbnNpdGlvblRpbWluZ0Z1bmN0aW9uOiBlYXNpbmdcbiAgICB9O1xuICAgIGVsLl94X3RyYW5zaXRpb24uZW50ZXIuc3RhcnQgPSB7XG4gICAgICBvcGFjaXR5OiBvcGFjaXR5VmFsdWUsXG4gICAgICB0cmFuc2Zvcm06IGBzY2FsZSgke3NjYWxlVmFsdWV9KWBcbiAgICB9O1xuICAgIGVsLl94X3RyYW5zaXRpb24uZW50ZXIuZW5kID0ge1xuICAgICAgb3BhY2l0eTogMSxcbiAgICAgIHRyYW5zZm9ybTogYHNjYWxlKDEpYFxuICAgIH07XG4gIH1cbiAgaWYgKHRyYW5zaXRpb25pbmdPdXQpIHtcbiAgICBlbC5feF90cmFuc2l0aW9uLmxlYXZlLmR1cmluZyA9IHtcbiAgICAgIHRyYW5zZm9ybU9yaWdpbjogb3JpZ2luLFxuICAgICAgdHJhbnNpdGlvbkRlbGF5OiBgJHtkZWxheX1zYCxcbiAgICAgIHRyYW5zaXRpb25Qcm9wZXJ0eTogcHJvcGVydHksXG4gICAgICB0cmFuc2l0aW9uRHVyYXRpb246IGAke2R1cmF0aW9uT3V0fXNgLFxuICAgICAgdHJhbnNpdGlvblRpbWluZ0Z1bmN0aW9uOiBlYXNpbmdcbiAgICB9O1xuICAgIGVsLl94X3RyYW5zaXRpb24ubGVhdmUuc3RhcnQgPSB7XG4gICAgICBvcGFjaXR5OiAxLFxuICAgICAgdHJhbnNmb3JtOiBgc2NhbGUoMSlgXG4gICAgfTtcbiAgICBlbC5feF90cmFuc2l0aW9uLmxlYXZlLmVuZCA9IHtcbiAgICAgIG9wYWNpdHk6IG9wYWNpdHlWYWx1ZSxcbiAgICAgIHRyYW5zZm9ybTogYHNjYWxlKCR7c2NhbGVWYWx1ZX0pYFxuICAgIH07XG4gIH1cbn1cbmZ1bmN0aW9uIHJlZ2lzdGVyVHJhbnNpdGlvbk9iamVjdChlbCwgc2V0RnVuY3Rpb24sIGRlZmF1bHRWYWx1ZSA9IHt9KSB7XG4gIGlmICghZWwuX3hfdHJhbnNpdGlvbilcbiAgICBlbC5feF90cmFuc2l0aW9uID0ge1xuICAgICAgZW50ZXI6IHtkdXJpbmc6IGRlZmF1bHRWYWx1ZSwgc3RhcnQ6IGRlZmF1bHRWYWx1ZSwgZW5kOiBkZWZhdWx0VmFsdWV9LFxuICAgICAgbGVhdmU6IHtkdXJpbmc6IGRlZmF1bHRWYWx1ZSwgc3RhcnQ6IGRlZmF1bHRWYWx1ZSwgZW5kOiBkZWZhdWx0VmFsdWV9LFxuICAgICAgaW4oYmVmb3JlID0gKCkgPT4ge1xuICAgICAgfSwgYWZ0ZXIgPSAoKSA9PiB7XG4gICAgICB9KSB7XG4gICAgICAgI
1HRyYW5zaXRpb24oZWwsIHNldEZ1bmN0aW9uLCB7XG4gICAgICAgICAgZHVyaW5nOiB0aGlzLmVudGVyLmR1cmluZyxcbiAgICAgICAgICBzdGFydDogdGhpcy5lbnRlci5zdGFydCxcbiAgICAgICAgICBlbmQ6IHRoaXMuZW50ZXIuZW5kXG4gICAgICAgIH0sIGJlZm9yZSwgYWZ0ZXIpO1xuICAgICAgfSxcbiAgICAgIG91dChiZWZvcmUgPSAoKSA9PiB7XG4gICAgICB9LCBhZnRlciA9ICgpID0+IHtcbiAgICAgIH0pIHtcbiAgICAgICAgdHJhbnNpdGlvbihlbCwgc2V0RnVuY3Rpb24sIHtcbiAgICAgICAgICBkdXJpbmc6IHRoaXMubGVhdmUuZHVyaW5nLFxuICAgICAgICAgIHN0YXJ0OiB0aGlzLmxlYXZlLnN0YXJ0LFxuICAgICAgICAgIGVuZDogdGhpcy5sZWF2ZS5lbmRcbiAgICAgICAgfSwgYmVmb3JlLCBhZnRlcik7XG4gICAgICB9XG4gICAgfTtcbn1cbndpbmRvdy5FbGVtZW50LnByb3RvdHlwZS5feF90b2dnbGVBbmRDYXNjYWRlV2l0aFRyYW5zaXRpb25zID0gZnVuY3Rpb24oZWwsIHZhbHVlLCBzaG93LCBoaWRlKSB7XG4gIGNvbnN0IG5leHRUaWNrMiA9IGRvY3VtZW50LnZpc2liaWxpdHlTdGF0ZSA9PT0gXCJ2aXNpYmxlXCIgPyByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgOiBzZXRUaW1lb3V0O1xuICBsZXQgY2xpY2tBd2F5Q29tcGF0aWJsZVNob3cgPSAoKSA9PiBuZXh0VGljazIoc2hvdyk7XG4gIGlmICh2YWx1ZSkge1xuICAgIGlmIChlbC5feF90cmFuc2l0aW9uICYmIChlbC5feF90cmFuc2l0aW9uLmVudGVyIHx8IGVsLl94X3RyYW5zaXRpb24ubGVhdmUpKSB7XG4gICAgICBlbC5feF90cmFuc2l0aW9uLmVudGVyICYmIChPYmplY3QuZW50cmllcyhlbC5feF90cmFuc2l0aW9uLmVudGVyLmR1cmluZykubGVuZ3RoIHx8IE9iamVjdC5lbnRyaWVzKGVsLl94X3RyYW5zaXRpb24uZW50ZXIuc3RhcnQpLmxlbmd0aCB8fCBPYmplY3QuZW50cmllcyhlbC5feF90cmFuc2l0aW9uLmVudGVyLmVuZCkubGVuZ3RoKSA/IGVsLl94X3RyYW5zaXRpb24uaW4oc2hvdykgOiBjbGlja0F3YXlDb21wYXRpYmxlU2hvdygpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbC5feF90cmFuc2l0aW9uID8gZWwuX3hfdHJhbnNpdGlvbi5pbihzaG93KSA6IGNsaWNrQXdheUNvbXBhdGlibGVTaG93KCk7XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuICBlbC5feF9oaWRlUHJvbWlzZSA9IGVsLl94X3RyYW5zaXRpb24gPyBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgZWwuX3hfdHJhbnNpdGlvbi5vdXQoKCkgPT4ge1xuICAgIH0sICgpID0+IHJlc29sdmUoaGlkZSkpO1xuICAgIGVsLl94X3RyYW5zaXRpb25pbmcuYmVmb3JlQ2FuY2VsKCgpID0+IHJlamVjdCh7aXNGcm9tQ2FuY2VsbGVkVHJhbnNpdGlvbjogdHJ1ZX0pKTtcbiAgfSkgOiBQcm9taXNlLnJlc29sdmUoaGlkZSk7XG4gIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICBsZXQgY2xvc2VzdCA9IGNsb3Nlc3RIaWRlKGVsKTtcbiAgICBpZiAoY2xvc2VzdCkge1xuICAgICAgaWYgKCFjbG9zZXN0Ll94X2hpZGVDaGlsZHJlbilcbiAgICAgICAgY2xvc2VzdC5feF9oaWRlQ2hpbGRyZW4gPSBbXTtcbiAgICAgIGNsb3Nlc3QuX3hfaGlkZUNoaWxkcmVuLnB1c2goZWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXh0VGljazIoKCkgPT4ge1xuICAgICAgICBsZXQgaGlkZUFmdGVyQ2hpbGRyZW4gPSAoZWwyKSA9PiB7XG4gICAgICAgICAgbGV0IGNhcnJ5ID0gUHJvbWlzZS5hbGwoW1xuICAgICAgICAgICAgZWwyLl94X2hpZGVQcm9taXNlLFxuICAgICAgICAgICAgLi4uKGVsMi5feF9oaWRlQ2hpbGRyZW4gfHwgW10pLm1hcChoaWRlQWZ0ZXJDaGlsZHJlbilcbiAgICAgICAgICBdKS50aGVuKChbaV0pID0+IGkoKSk7XG4gICAgICAgICAgZGVsZXRlIGVsMi5feF9oaWRlUHJvbWlzZTtcbiAgICAgICAgICBkZWxldGUgZWwyLl94X2hpZGVDaGlsZHJlbjtcbiAgICAgICAgICByZXR1cm4gY2Fycnk7XG4gICAgICAgIH07XG4gICAgICAgIGhpZGVBZnRlckNoaWxkcmVuKGVsKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgIGlmICghZS5pc0Zyb21DYW5jZWxsZWRUcmFuc2l0aW9uKVxuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xufTtcbmZ1bmN0aW9uIGNsb3Nlc3RIaWRlKGVsKSB7XG4gIGxldCBwYXJlbnQgPSBlbC5wYXJlbnROb2RlO1xuICBpZiAoIXBhcmVudClcbiAgICByZXR1cm47XG4gIHJldHVybiBwYXJlbnQuX3hfaGlkZVByb21pc2UgPyBwYXJlbnQgOiBjbG9zZXN0SGlkZShwYXJlbnQpO1xufVxuZnVuY3Rpb24gdHJhbnNpdGlvbihlbCwgc2V0RnVuY3Rpb24sIHtkdXJpbmcsIHN0YXJ0OiBzdGFydDIsIGVuZH0gPSB7fSwgYmVmb3JlID0gKCkgPT4ge1xufSwgYWZ0ZXIgPSAoKSA9PiB7XG59KSB7XG4gIGlmIChlbC5feF90cmFuc2l0aW9uaW5nKVxuICAgIGVsLl94X3RyYW5zaXRpb25pbmcuY2FuY2VsKCk7XG4gIGlmIChPYmplY3Qua2V5cyhkdXJpbmcpLmxlbmd0aCA9PT0gMCAmJiBPYmplY3Qua2V5cyhzdGFydDIpLmxlbmd0aCA9PT0gMCAmJiBPYmplY3Qua2V5cyhlbmQpLmxlbmd0aCA9PT0gMCkge1xuICAgIGJlZm9yZSgpO1xuICAgIGFmdGVyKCk7XG4gICAgcmV0dXJuO1xuICB9XG4gIGxldCB1bmRvU3RhcnQsIHVuZG9EdXJpbmcsIHVuZG9FbmQ7XG4gIHBlcmZvcm1UcmFuc2l0aW9uKGVsLCB7XG4gICAgc3RhcnQoKSB7XG4gICAgICB1bmRvU3RhcnQgPSBzZXRGdW5jdGlvbihlbCwgc3RhcnQyKTtcbiAgICB9LFxuICAgIGR1cmluZygpIHtcbiAgICAgIHVuZG9EdXJpbmcgPSBzZXRGdW5jdGlvbihlbCwgZHVyaW5nKTtcbiAgICB9LFxuICAgIGJlZm9yZSxcbiAgICBlbmQoKSB7XG4gICAgICB1bmRvU3RhcnQoKTtcbiAgICAgIHVuZG9FbmQgPSBzZXRGdW5jdGlvbihlbCwgZW5kKTtcbiAgICB9LFxuICAgIGFmdGVyLFxuICAgIGNsZWFudXAoKSB7XG4gICAgICB1bmRvRHVyaW5nKCk7XG4gICAgICB1bmRvRW5kKCk7XG4gICAgfVxuICB9KTtcbn1cbmZ1bmN0aW9uIHBlcmZvcm1UcmFuc2l0aW9uKGVsLCBzdGFnZXMpIHtcbiAgbGV0IGludGVycnVwdGVkLCByZWFjaGVkQmVmb3JlLCByZWFjaGVkRW5kO1xuICBsZXQgZmluaXNoID0gb25jZSgoKSA9PiB7XG4gICAgbXV0YXRlRG9tKCgpID0+IHtcbiAgICAgIGludGVycnVwdGVkID0gdHJ1ZTtcbiAgICAgIGlmICghcmVhY2hlZEJlZm9yZSlcbiAgICAgICAgc3RhZ2VzLmJlZm9yZSgpO1xuICAgICAgaWYgKCFyZWFjaGVkRW5kKSB7XG4gICAgICAgI
1HN0YWdlcy5lbmQoKTtcbiAgICAgICAgcmVsZWFzZU5leHRUaWNrcygpO1xuICAgICAgfVxuICAgICAgc3RhZ2VzLmFmdGVyKCk7XG4gICAgICBpZiAoZWwuaXNDb25uZWN0ZWQpXG4gICAgICAgIHN0YWdlcy5jbGVhbnVwKCk7XG4gICAgICBkZWxldGUgZWwuX3hfdHJhbnNpdGlvbmluZztcbiAgICB9KTtcbiAgfSk7XG4gIGVsLl94X3RyYW5zaXRpb25pbmcgPSB7XG4gICAgYmVmb3JlQ2FuY2VsczogW10sXG4gICAgYmVmb3JlQ2FuY2VsKGNhbGxiYWNrKSB7XG4gICAgICB0aGlzLmJlZm9yZUNhbmNlbHMucHVzaChjYWxsYmFjayk7XG4gICAgfSxcbiAgICBjYW5jZWw6IG9uY2UoZnVuY3Rpb24oKSB7XG4gICAgICB3aGlsZSAodGhpcy5iZWZvcmVDYW5jZWxzLmxlbmd0aCkge1xuICAgICAgICB0aGlzLmJlZm9yZUNhbmNlbHMuc2hpZnQoKSgpO1xuICAgICAgfVxuICAgICAgO1xuICAgICAgZmluaXNoKCk7XG4gICAgfSksXG4gICAgZmluaXNoXG4gIH07XG4gIG11dGF0ZURvbSgoKSA9PiB7XG4gICAgc3RhZ2VzLnN0YXJ0KCk7XG4gICAgc3RhZ2VzLmR1cmluZygpO1xuICB9KTtcbiAgaG9sZE5leHRUaWNrcygpO1xuICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgIGlmIChpbnRlcnJ1cHRlZClcbiAgICAgIHJldHVybjtcbiAgICBsZXQgZHVyYXRpb24gPSBOdW1iZXIoZ2V0Q29tcHV0ZWRTdHlsZShlbCkudHJhbnNpdGlvbkR1cmF0aW9uLnJlcGxhY2UoLywuKi8sIFwiXCIpLnJlcGxhY2UoXCJzXCIsIFwiXCIpKSAqIDFlMztcbiAgICBsZXQgZGVsYXkgPSBOdW1iZXIoZ2V0Q29tcHV0ZWRTdHlsZShlbCkudHJhbnNpdGlvbkRlbGF5LnJlcGxhY2UoLywuKi8sIFwiXCIpLnJlcGxhY2UoXCJzXCIsIFwiXCIpKSAqIDFlMztcbiAgICBpZiAoZHVyYXRpb24gPT09IDApXG4gICAgICBkdXJhdGlvbiA9IE51bWJlcihnZXRDb21wdXRlZFN0eWxlKGVsKS5hbmltYXRpb25EdXJhdGlvbi5yZXBsYWNlKFwic1wiLCBcIlwiKSkgKiAxZTM7XG4gICAgbXV0YXRlRG9tKCgpID0+IHtcbiAgICAgIHN0YWdlcy5iZWZvcmUoKTtcbiAgICB9KTtcbiAgICByZWFjaGVkQmVmb3JlID0gdHJ1ZTtcbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgaWYgKGludGVycnVwdGVkKVxuICAgICAgICByZXR1cm47XG4gICAgICBtdXRhdGVEb20oKCkgPT4ge1xuICAgICAgICBzdGFnZXMuZW5kKCk7XG4gICAgICB9KTtcbiAgICAgIHJlbGVhc2VOZXh0VGlja3MoKTtcbiAgICAgIHNldFRpbWVvdXQoZWwuX3hfdHJhbnNpdGlvbmluZy5maW5pc2gsIGR1cmF0aW9uICsgZGVsYXkpO1xuICAgICAgcmVhY2hlZEVuZCA9IHRydWU7XG4gICAgfSk7XG4gIH0pO1xufVxuZnVuY3Rpb24gbW9kaWZpZXJWYWx1ZShtb2RpZmllcnMsIGtleSwgZmFsbGJhY2spIHtcbiAgaWYgKG1vZGlmaWVycy5pbmRleE9mKGtleSkgPT09IC0xKVxuICAgIHJldHVybiBmYWxsYmFjaztcbiAgY29uc3QgcmF3VmFsdWUgPSBtb2RpZmllcnNbbW9kaWZpZXJzLmluZGV4T2Yoa2V5KSArIDFdO1xuICBpZiAoIXJhd1ZhbHVlKVxuICAgIHJldHVybiBmYWxsYmFjaztcbiAgaWYgKGtleSA9PT0gXCJzY2FsZVwiKSB7XG4gICAgaWYgKGlzTmFOKHJhd1ZhbHVlKSlcbiAgICAgIHJldHVybiBmYWxsYmFjaztcbiAgfVxuICBpZiAoa2V5ID09PSBcImR1cmF0aW9uXCIgfHwga2V5ID09PSBcImRlbGF5XCIpIHtcbiAgICBsZXQgbWF0Y2ggPSByYXdWYWx1ZS5tYXRjaCgvKFswLTldKyltcy8pO1xuICAgIGlmIChtYXRjaClcbiAgICAgIHJldHVybiBtYXRjaFsxXTtcbiAgfVxuICBpZiAoa2V5ID09PSBcIm9yaWdpblwiKSB7XG4gICAgaWYgKFtcInRvcFwiLCBcInJpZ2h0XCIsIFwibGVmdFwiLCBcImNlbnRlclwiLCBcImJvdHRvbVwiXS5pbmNsdWRlcyhtb2RpZmllcnNbbW9kaWZpZXJzLmluZGV4T2Yoa2V5KSArIDJdKSkge1xuICAgICAgcmV0dXJuIFtyYXdWYWx1ZSwgbW9kaWZpZXJzW21vZGlmaWVycy5pbmRleE9mKGtleSkgKyAyXV0uam9pbihcIiBcIik7XG4gICAgfVxuICB9XG4gIHJldHVybiByYXdWYWx1ZTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2Nsb25lLmpzXG52YXIgaXNDbG9uaW5nID0gZmFsc2U7XG5mdW5jdGlvbiBza2lwRHVyaW5nQ2xvbmUoY2FsbGJhY2ssIGZhbGxiYWNrID0gKCkgPT4ge1xufSkge1xuICByZXR1cm4gKC4uLmFyZ3MpID0+IGlzQ2xvbmluZyA/IGZhbGxiYWNrKC4uLmFyZ3MpIDogY2FsbGJhY2soLi4uYXJncyk7XG59XG5mdW5jdGlvbiBvbmx5RHVyaW5nQ2xvbmUoY2FsbGJhY2spIHtcbiAgcmV0dXJuICguLi5hcmdzKSA9PiBpc0Nsb25pbmcgJiYgY2FsbGJhY2soLi4uYXJncyk7XG59XG5mdW5jdGlvbiBjbG9uZShvbGRFbCwgbmV3RWwpIHtcbiAgaWYgKCFuZXdFbC5feF9kYXRhU3RhY2spXG4gICAgbmV3RWwuX3hfZGF0YVN0YWNrID0gb2xkRWwuX3hfZGF0YVN0YWNrO1xuICBpc0Nsb25pbmcgPSB0cnVlO1xuICBkb250UmVnaXN0ZXJSZWFjdGl2ZVNpZGVFZmZlY3RzKCgpID0+IHtcbiAgICBjbG9uZVRyZWUobmV3RWwpO1xuICB9KTtcbiAgaXNDbG9uaW5nID0gZmFsc2U7XG59XG5mdW5jdGlvbiBjbG9uZVRyZWUoZWwpIHtcbiAgbGV0IGhhc1J1blRocm91Z2hGaXJzdEVsID0gZmFsc2U7XG4gIGxldCBzaGFsbG93V2Fsa2VyID0gKGVsMiwgY2FsbGJhY2spID0+IHtcbiAgICB3YWxrKGVsMiwgKGVsMywgc2tpcCkgPT4ge1xuICAgICAgaWYgKGhhc1J1blRocm91Z2hGaXJzdEVsICYmIGlzUm9vdChlbDMpKVxuICAgICAgICByZXR1cm4gc2tpcCgpO1xuICAgICAgaGFzUnVuVGhyb3VnaEZpcnN0RWwgPSB0cnVlO1xuICAgICAgY2FsbGJhY2soZWwzLCBza2lwKTtcbiAgICB9KTtcbiAgfTtcbiAgaW5pdFRyZWUoZWwsIHNoYWxsb3dXYWxrZXIpO1xufVxuZnVuY3Rpb24gZG9udFJlZ2lzdGVyUmVhY3RpdmVTaWRlRWZmZWN0cyhjYWxsYmFjaykge1xuICBsZXQgY2FjaGUgPSBlZmZlY3Q7XG4gIG92ZXJyaWRlRWZmZWN0KChjYWxsYmFjazIsIGVsKSA9PiB7XG4gICAgbGV0IHN0b3JlZEVmZmVjdCA9IGNhY2hlKGNhbGxiYWNrMik7XG4gICAgcmVsZWFzZShzdG9yZWRFZmZlY3QpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgfTtcbiAgfSk7XG4gIGNhbGxiYWNrKCk7XG4gIG92ZXJyaWRlRWZmZWN0KGNhY2hlKTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL3V0aWxzL2JpbmQuanNcbmZ1bmN0aW9uIGJpbmQoZWwsIG5hbW
1UsIHZhbHVlLCBtb2RpZmllcnMgPSBbXSkge1xuICBpZiAoIWVsLl94X2JpbmRpbmdzKVxuICAgIGVsLl94X2JpbmRpbmdzID0gcmVhY3RpdmUoe30pO1xuICBlbC5feF9iaW5kaW5nc1tuYW1lXSA9IHZhbHVlO1xuICBuYW1lID0gbW9kaWZpZXJzLmluY2x1ZGVzKFwiY2FtZWxcIikgPyBjYW1lbENhc2UobmFtZSkgOiBuYW1lO1xuICBzd2l0Y2ggKG5hbWUpIHtcbiAgICBjYXNlIFwidmFsdWVcIjpcbiAgICAgIGJpbmRJbnB1dFZhbHVlKGVsLCB2YWx1ZSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIFwic3R5bGVcIjpcbiAgICAgIGJpbmRTdHlsZXMoZWwsIHZhbHVlKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgXCJjbGFzc1wiOlxuICAgICAgYmluZENsYXNzZXMoZWwsIHZhbHVlKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgXCJzZWxlY3RlZFwiOlxuICAgIGNhc2UgXCJjaGVja2VkXCI6XG4gICAgICBiaW5kQXR0cmlidXRlQW5kUHJvcGVydHkoZWwsIG5hbWUsIHZhbHVlKTtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBiaW5kQXR0cmlidXRlKGVsLCBuYW1lLCB2YWx1ZSk7XG4gICAgICBicmVhaztcbiAgfVxufVxuZnVuY3Rpb24gYmluZElucHV0VmFsdWUoZWwsIHZhbHVlKSB7XG4gIGlmIChlbC50eXBlID09PSBcInJhZGlvXCIpIHtcbiAgICBpZiAoZWwuYXR0cmlidXRlcy52YWx1ZSA9PT0gdm9pZCAwKSB7XG4gICAgICBlbC52YWx1ZSA9IHZhbHVlO1xuICAgIH1cbiAgICBpZiAod2luZG93LmZyb21Nb2RlbCkge1xuICAgICAgZWwuY2hlY2tlZCA9IGNoZWNrZWRBdHRyTG9vc2VDb21wYXJlKGVsLnZhbHVlLCB2YWx1ZSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGVsLnR5cGUgPT09IFwiY2hlY2tib3hcIikge1xuICAgIGlmIChOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKSkge1xuICAgICAgZWwudmFsdWUgPSB2YWx1ZTtcbiAgICB9IGVsc2UgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKSAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdHlwZW9mIHZhbHVlICE9PSBcImJvb2xlYW5cIiAmJiAhW251bGwsIHZvaWQgMF0uaW5jbHVkZXModmFsdWUpKSB7XG4gICAgICBlbC52YWx1ZSA9IFN0cmluZyh2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICBlbC5jaGVja2VkID0gdmFsdWUuc29tZSgodmFsKSA9PiBjaGVja2VkQXR0ckxvb3NlQ29tcGFyZSh2YWwsIGVsLnZhbHVlKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbC5jaGVja2VkID0gISF2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAoZWwudGFnTmFtZSA9PT0gXCJTRUxFQ1RcIikge1xuICAgIHVwZGF0ZVNlbGVjdChlbCwgdmFsdWUpO1xuICB9IGVsc2Uge1xuICAgIGlmIChlbC52YWx1ZSA9PT0gdmFsdWUpXG4gICAgICByZXR1cm47XG4gICAgZWwudmFsdWUgPSB2YWx1ZTtcbiAgfVxufVxuZnVuY3Rpb24gYmluZENsYXNzZXMoZWwsIHZhbHVlKSB7XG4gIGlmIChlbC5feF91bmRvQWRkZWRDbGFzc2VzKVxuICAgIGVsLl94X3VuZG9BZGRlZENsYXNzZXMoKTtcbiAgZWwuX3hfdW5kb0FkZGVkQ2xhc3NlcyA9IHNldENsYXNzZXMoZWwsIHZhbHVlKTtcbn1cbmZ1bmN0aW9uIGJpbmRTdHlsZXMoZWwsIHZhbHVlKSB7XG4gIGlmIChlbC5feF91bmRvQWRkZWRTdHlsZXMpXG4gICAgZWwuX3hfdW5kb0FkZGVkU3R5bGVzKCk7XG4gIGVsLl94X3VuZG9BZGRlZFN0eWxlcyA9IHNldFN0eWxlcyhlbCwgdmFsdWUpO1xufVxuZnVuY3Rpb24gYmluZEF0dHJpYnV0ZUFuZFByb3BlcnR5KGVsLCBuYW1lLCB2YWx1ZSkge1xuICBiaW5kQXR0cmlidXRlKGVsLCBuYW1lLCB2YWx1ZSk7XG4gIHNldFByb3BlcnR5SWZDaGFuZ2VkKGVsLCBuYW1lLCB2YWx1ZSk7XG59XG5mdW5jdGlvbiBiaW5kQXR0cmlidXRlKGVsLCBuYW1lLCB2YWx1ZSkge1xuICBpZiAoW251bGwsIHZvaWQgMCwgZmFsc2VdLmluY2x1ZGVzKHZhbHVlKSAmJiBhdHRyaWJ1dGVTaG91bGRudEJlUHJlc2VydmVkSWZGYWxzeShuYW1lKSkge1xuICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgfSBlbHNlIHtcbiAgICBpZiAoaXNCb29sZWFuQXR0cihuYW1lKSlcbiAgICAgIHZhbHVlID0gbmFtZTtcbiAgICBzZXRJZkNoYW5nZWQoZWwsIG5hbW
1UsIHZhbHVlKTtcbiAgfVxufVxuZnVuY3Rpb24gc2V0SWZDaGFuZ2VkKGVsLCBhdHRyTmFtZSwgdmFsdWUpIHtcbiAgaWYgKGVsLmdldEF0dHJpYnV0ZShhdHRyTmFtZSkgIT0gdmFsdWUpIHtcbiAgICBlbC5zZXRBdHRyaWJ1dGUoYXR0ck5hbWUsIHZhbHVlKTtcbiAgfVxufVxuZnVuY3Rpb24gc2V0UHJvcGVydHlJZkNoYW5nZWQoZWwsIHByb3BOYW1lLCB2YWx1ZSkge1xuICBpZiAoZWxbcHJvcE5hbWVdICE9PSB2YWx1ZSkge1xuICAgIGVsW3Byb3BOYW1lXSA9IHZhbHVlO1xuICB9XG59XG5mdW5jdGlvbiB1cGRhdGVTZWxlY3QoZWwsIHZhbHVlKSB7XG4gIGNvbnN0IGFycmF5V3JhcHBlZFZhbHVlID0gW10uY29uY2F0KHZhbHVlKS5tYXAoKHZhbHVlMikgPT4ge1xuICAgIHJldHVybiB2YWx1ZTIgKyBcIlwiO1xuICB9KTtcbiAgQXJyYXkuZnJvbShlbC5vcHRpb25zKS5mb3JFYWNoKChvcHRpb24pID0+IHtcbiAgICBvcHRpb24uc2VsZWN0ZWQgPSBhcnJheVdyYXBwZWRWYWx1ZS5pbmNsdWRlcyhvcHRpb24udmFsdWUpO1xuICB9KTtcbn1cbmZ1bmN0aW9uIGNhbWVsQ2FzZShzdWJqZWN0KSB7XG4gIHJldHVybiBzdWJqZWN0LnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvLShcXHcpL2csIChtYXRjaCwgY2hhcikgPT4gY2hhci50b1VwcGVyQ2FzZSgpKTtcbn1cbmZ1bmN0aW9uIGNoZWNrZWRBdHRyTG9vc2VDb21wYXJlKHZhbHVlQSwgdmFsdWVCKSB7XG4gIHJldHVybiB2YWx1ZUEgPT0gdmFsdWVCO1xufVxuZnVuY3Rpb24gaXNCb29sZWFuQXR0cihhdHRyTmFtZSkge1xuICBjb25zdCBib29sZWFuQXR0cmlidXRlcyA9IFtcbiAgICBcImRpc2FibGVkXCIsXG4gICAgXCJjaGVja2VkXCIsXG4gICAgXCJyZXF1aXJlZFwiLFxuICAgIFwicmVhZG9ubHlcIixcbiAgICBcImhpZGRlblwiLFxuICAgIFwib3BlblwiLFxuICAgIFwic2VsZWN0ZWRcIixcbiAgICBcImF1dG9mb2N1c1wiLFxuICAgIFwiaXRlbXNjb3BlXCIsXG4gICAgXCJtdWx0aXBsZVwiLFxuICAgIFwibm92YWxpZGF0ZVwiLFxuICAgIFwiYWxsb3dmdWxsc2NyZWVuXCIsXG4gICAgXCJhbGxvd3BheW1lbnRyZXF1ZXN0XCIsXG4gICAgXCJmb3Jtbm92YWxpZGF0ZVwiLFxuICAgIFwiYXV0b3BsYXlcIixcbiAgICBcImNvbnRyb2xzXCIsXG4gICAgXCJsb29wXCIsXG4gICAgXCJtdXRlZFwiLFxuICAgIFwicGxheXNpbmxpbmVcIixcbiAgICBcImRlZmF1bHRcIixcbiAgICBcImlzbWFwXCIsXG4gICAgXCJyZXZlcnNlZFwiLFxuICAgIFwiYXN5bmNcIixcbiAgICBcImRlZmVyXCIsXG4gICAgXCJub21vZHVsZVwiXG4gIF07XG4gIHJldHVybiBib29sZWFuQXR0cmlidXRlcy5pbmNsdWRlcyhhdHRyTmFtZSk7XG59XG5mdW5jdGlvbiBhdHRyaWJ1dGVTaG91bGRudEJlUHJlc2VydmVkSWZGYWxzeShuYW1lKSB7XG4gIHJldHVybiAhW1wiYXJpYS1wcmVzc2VkXCIsIFwiYXJpYS1jaGVja2VkXCIsIFwiYXJpYS1leHBhbmRlZFwiLCBcImFyaWEtc2VsZWN0ZWRcIl0uaW5jbHVkZXMobmFtZSk7XG59XG5mdW5jdGlvbiBnZXRCaW5kaW5nKGVsLCBuYW1lLCBmYWxsYmFjaykge1xuICBpZiAoZWwuX3hfYmluZGluZ3MgJiYgZWwuX3hfYmluZGluZ3NbbmFtZV0gIT09IHZvaWQgMClcbiAgICByZXR1cm4gZWwuX3hfYmluZGluZ3NbbmFtZV07XG4gIHJldHVybiBnZXRBdHRyaWJ1dGVCaW5kaW5nKGVsLCBuYW1lLCBmYWxsYmFjayk7XG59XG5mdW5jdGlvbiBleHRyYWN0UHJvcChlbCwgbmFtZSwgZmFsbGJhY2ssIGV4dHJhY3QgPSB0cnVlKSB7XG4gIGlmIChlbC5feF9iaW5kaW5ncyAmJiBlbC5feF9iaW5kaW5nc1tuYW1lXSAhPT0gdm9pZCAwKVxuICAgIHJldHVybiBlbC5feF9iaW5kaW5nc1tuYW1lXTtcbiAgaWYgKGVsLl94X2lubGluZUJpbmRpbmdzICYmIGVsLl94X2lubGluZUJpbmRpbmdzW25hbWVdICE9PSB2b2lkIDApIHtcbiAgICBsZXQgYmluZGluZyA9IGVsLl94X2lubGluZUJpbmRpbmdzW25hbWVdO1xuICAgIGJpbmRpbmcuZXh0cmFjdCA9IGV4dHJhY3Q7XG4gICAgcmV0dXJuIGRvbnRBdXRvRXZhbHVhdGVGdW5jdGlvbnMoKCkgPT4ge1xuICAgICAgcmV0dXJuIGV2YWx1YXRlKGVsLCBiaW5kaW5nLmV4cHJlc3Npb24pO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBnZXRBdHRyaWJ1dGVCaW5kaW5nKGVsLCBuYW1lLCBmYWxsYmFjayk7XG59XG5mdW5jdGlvbiBnZXRBdHRyaWJ1dGVCaW5kaW5nKGVsLCBuYW1lLCBmYWxsYmFjaykge1xuICBsZXQgYXR0ciA9IGVsLmdldEF0dHJpYnV0ZShuYW1lKTtcbiAgaWYgKGF0dHIgPT09IG51bGwpXG4gICAgcmV0dXJuIHR5cGVvZiBmYWxsYmFjayA9PT0gXCJmdW5jdGlvblwiID8gZmFsbGJhY2soKSA6IGZhbGxiYWNrO1xuICBpZiAoYXR0ciA9PT0gXCJcIilcbiAgICByZXR1cm4gdHJ1ZTtcbiAgaWYgKGlzQm9vbGVhbkF0dHIobmFtZSkpIHtcbiAgICByZXR1cm4gISFbbmFtZSwgXCJ0cnVlXCJdLmluY2x1ZGVzKGF0dHIpO1xuICB9XG4gIHJldHVybiBhdHRyO1xufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvdXRpbHMvZGVib3VuY2UuanNcbmZ1bmN0aW9uIGRlYm91bmNlKGZ1bmMsIHdhaXQpIHtcbiAgdmFyIHRpbWVvdXQ7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgY29udGV4dCA9IHRoaXMsIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgdmFyIGxhdGVyID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aW1lb3V0ID0gbnVsbDtcbiAgICAgIGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gICAgfTtcbiAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgdGltZW91dCA9IHNldFRpbWVvdXQobGF0ZXIsIHdhaXQpO1xuICB9O1xufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvdXRpbHMvdGhyb3R0bGUuanNcbmZ1bmN0aW9uIHRocm90dGxlKGZ1bmMsIGxpbWl0KSB7XG4gIGxldCBpblRocm90dGxlO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgbGV0IGNvbnRleHQgPSB0aGlzLCBhcmdzID0gYXJndW1lbnRzO1xuICAgIGlmICghaW5UaHJvdHRsZSkge1xuICAgICAgZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgIGluVGhyb3R0bGUgPSB0cnVlO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiBpblRocm90dGxlID0gZmFsc2UsIGxpbWl0KTtcbiAgICB9XG4gI
1H07XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9wbHVnaW4uanNcbmZ1bmN0aW9uIHBsdWdpbihjYWxsYmFjaykge1xuICBsZXQgY2FsbGJhY2tzID0gQXJyYXkuaXNBcnJheShjYWxsYmFjaykgPyBjYWxsYmFjayA6IFtjYWxsYmFja107XG4gIGNhbGxiYWNrcy5mb3JFYWNoKChpKSA9PiBpKGFscGluZV9kZWZhdWx0KSk7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9zdG9yZS5qc1xudmFyIHN0b3JlcyA9IHt9O1xudmFyIGlzUmVhY3RpdmUgPSBmYWxzZTtcbmZ1bmN0aW9uIHN0b3JlKG5hbWUsIHZhbHVlKSB7XG4gIGlmICghaXNSZWFjdGl2ZSkge1xuICAgIHN0b3JlcyA9IHJlYWN0aXZlKHN0b3Jlcyk7XG4gICAgaXNSZWFjdGl2ZSA9IHRydWU7XG4gIH1cbiAgaWYgKHZhbHVlID09PSB2b2lkIDApIHtcbiAgICByZXR1cm4gc3RvcmVzW25hbWVdO1xuICB9XG4gIHN0b3Jlc1tuYW1lXSA9IHZhbHVlO1xuICBpZiAodHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmIHZhbHVlICE9PSBudWxsICYmIHZhbHVlLmhhc093blByb3BlcnR5KFwiaW5pdFwiKSAmJiB0eXBlb2YgdmFsdWUuaW5pdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgc3RvcmVzW25hbWVdLmluaXQoKTtcbiAgfVxuICBpbml0SW50ZXJjZXB0b3JzKHN0b3Jlc1tuYW1lXSk7XG59XG5mdW5jdGlvbiBnZXRTdG9yZXMoKSB7XG4gIHJldHVybiBzdG9yZXM7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9iaW5kcy5qc1xudmFyIGJpbmRzID0ge307XG5mdW5jdGlvbiBiaW5kMihuYW1lLCBiaW5kaW5ncykge1xuICBsZXQgZ2V0QmluZGluZ3MgPSB0eXBlb2YgYmluZGluZ3MgIT09IFwiZnVuY3Rpb25cIiA/ICgpID0+IGJpbmRpbmdzIDogYmluZGluZ3M7XG4gIGlmIChuYW1lIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgIGFwcGx5QmluZGluZ3NPYmplY3QobmFtZSwgZ2V0QmluZGluZ3MoKSk7XG4gIH0gZWxzZSB7XG4gICAgYmluZHNbbmFtZV0gPSBnZXRCaW5kaW5ncztcbiAgfVxufVxuZnVuY3Rpb24gaW5qZWN0QmluZGluZ1Byb3ZpZGVycyhvYmopIHtcbiAgT2JqZWN0LmVud
1HJpZXMoYmluZHMpLmZvckVhY2goKFtuYW1lLCBjYWxsYmFja10pID0+IHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBuYW1lLCB7XG4gICAgICBnZXQoKSB7XG4gICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgIHJldHVybiBjYWxsYmFjayguLi5hcmdzKTtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBvYmo7XG59XG5mdW5jdGlvbiBhcHBseUJpbmRpbmdzT2JqZWN0KGVsLCBvYmosIG9yaWdpbmFsKSB7XG4gIGxldCBjbGVhbnVwUnVubmVycyA9IFtdO1xuICB3aGlsZSAoY2xlYW51cFJ1bm5lcnMubGVuZ3RoKVxuICAgIGNsZWFudXBSdW5uZXJzLnBvcCgpKCk7XG4gIGxldCBhdHRyaWJ1dGVzID0gT2JqZWN0LmVudHJpZXMob2JqKS5tYXAoKFtuYW1lLCB2YWx1ZV0pID0+ICh7bmFtZSwgdmFsdWV9KSk7XG4gIGxldCBzdGF0aWNBdHRyaWJ1dGVzID0gYXR0cmlidXRlc09ubHkoYXR0cmlidXRlcyk7XG4gIGF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzLm1hcCgoYXR0cmlidXRlKSA9PiB7XG4gICAgaWYgKHN0YXRpY0F0dHJpYnV0ZXMuZmluZCgoYXR0cikgPT4gYXR0ci5uYW1lID09PSBhdHRyaWJ1dGUubmFtZSkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5hbWU6IGB4LWJpbmQ6JHthdHRyaWJ1dGUubmFtZX1gLFxuICAgICAgICB2YWx1ZTogYFwiJHthdHRyaWJ1dGUudmFsdWV9XCJgXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gYXR0cmlidXRlO1xuICB9KTtcbiAgZGlyZWN0aXZlcyhlbCwgYXR0cmlidXRlcywgb3JpZ2luYWwpLm1hcCgoaGFuZGxlKSA9PiB7XG4gICAgY2xlYW51cFJ1bm5lcnMucHVzaChoYW5kbGUucnVuQ2xlYW51cHMpO1xuICAgIGhhbmRsZSgpO1xuICB9KTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2RhdGFzLmpzXG52YXIgZGF0YXMgPSB7fTtcbmZ1bmN0aW9uIGRhdGEobmFtZSwgY2FsbGJhY2spIHtcbiAgZGF0YXNbbmFtZV0gPSBjYWxsYmFjaztcbn1cbmZ1bmN0aW9uIGluamVjdERhdGFQcm92aWRlcnMob2JqLCBjb250ZXh0KSB7XG4gIE9iamVjdC5lbnRyaWVzKGRhdGFzKS5mb3JFYWNoKChbbmFtZSwgY2FsbGJhY2tdKSA9PiB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwgbmFtZSwge1xuICAgICAgZ2V0KCkge1xuICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2suYmluZChjb250ZXh0KSguLi5hcmdzKTtcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZVxuICAgIH0pO1xuICB9KTtcbiAgcmV0dXJuIG9iajtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2FscGluZS5qc1xudmFyIEFscGluZSA9IHtcbiAgZ2V0IHJlYWN0aXZlKCkge1xuICAgIHJldHVybiByZWFjdGl2ZTtcbiAgfSxcbiAgZ2V0IHJlbGVhc2UoKSB7XG4gICAgcmV0dXJuIHJlbGVhc2U7XG4gIH0sXG4gIGdldCBlZmZlY3QoKSB7XG4gICAgcmV0dXJuIGVmZmVjdDtcbiAgfSxcbiAgZ2V0IHJhdygpIHtcbiAgICByZXR1cm4gcmF3O1xuICB9LFxuICB2ZXJzaW9uOiBcIjMuMTIuM1wiLFxuICBmbHVzaEFuZFN0b3BEZWZlcnJpbmdNdXRhdGlvbnMsXG4gIGRvbnRBdXRvRXZhbHVhdGVGdW5jdGlvbnMsXG4gIGRpc2FibGVFZmZlY3RTY2hlZHVsaW5nLFxuICBzdGFydE9ic2VydmluZ011dGF0aW9ucyxcbiAgc3RvcE9ic2VydmluZ011dGF0aW9ucyxcbiAgc2V0UmVhY3Rpdml0eUVuZ2luZSxcbiAgY2xvc2VzdERhdGFTdGFjayxcbiAgc2tpcER1cmluZ0Nsb25lLFxuICBvbmx5RHVyaW5nQ2xvbmUsXG4gIGFkZFJvb3RTZWxlY3RvcixcbiAgYWRkSW5pdFNlbGVjdG9yLFxuICBhZGRTY29wZVRvTm9kZSxcbiAgZGVmZXJNdXRhdGlvbnMsXG4gIG1hcEF0dHJpYnV0ZXMsXG4gIGV2YWx1YXRlTGF0ZXIsXG4gIGludGVyY2VwdEluaXQsXG4gIHNldEV2YWx1YXRvcixcbiAgbWVyZ2VQcm94aWVzLFxuICBleHRyYWN0UHJvcCxcbiAgZmluZENsb3Nlc3QsXG4gIGNsb3Nlc3RSb290LFxuICBkZXN0cm95VHJlZSxcbiAgaW50ZXJjZXB0b3IsXG4gIHRyYW5zaXRpb24sXG4gIHNldFN0eWxlcyxcbiAgbXV0YXRlRG9tLFxuICBkaXJlY3RpdmUsXG4gIHRocm90dGxlLFxuICBkZWJvdW5jZSxcbiAgZXZhbHVhdGUsXG4gIGluaXRUcmVlLFxuICBuZXh0VGljayxcbiAgcHJlZml4ZWQ6IHByZWZpeCxcbiAgcHJlZml4OiBzZXRQcmVmaXgsXG4gIHBsdWdpbixcbiAgbWFnaWMsXG4gIHN0b3JlLFxuICBzdGFydCxcbiAgY2xvbmUsXG4gIGJvdW5kOiBnZXRCaW5kaW5nLFxuICAkZGF0YTogc2NvcGUsXG4gIHdhbGssXG4gIGRhdGEsXG4gIGJpbmQ6IGJpbmQyXG59O1xudmFyIGFscGluZV9kZWZhdWx0ID0gQWxwaW5lO1xuXG4vLyBub2RlX21vZHVsZXMvQHZ1ZS9zaGFyZWQvZGlzdC9zaGFyZWQuZXNtLWJ1bmRsZXIuanNcbmZ1bmN0aW9uIG1ha2VNYXAoc3RyLCBleHBlY3RzTG93ZXJDYXNlKSB7XG4gIGNvbnN0IG1hcCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIGNvbnN0IGxpc3QgPSBzdHIuc3BsaXQoXCIsXCIpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICBtYXBbbGlzdFtpXV0gPSB0cnVlO1xuICB9XG4gIHJldHVybiBleHBlY3RzTG93ZXJDYXNlID8gKHZhbCkgPT4gISFtYXBbdmFsLnRvTG93ZXJDYXNlKCldIDogKHZhbCkgPT4gISFtYXBbdmFsXTtcbn1cbnZhciBQYXRjaEZsYWdOYW1lcyA9IHtcbiAgWzFdOiBgVEVYVGAsXG4gIFsyXTogYENMQVNTYCxcbiAgWzRdOiBgU1RZTEVgLFxuICBbOF06IGBQUk9QU2AsXG4gIFsxNl06IGBGVUxMX1BST1BTYCxcbiAgWzMyXTogYEhZRFJBVEVfRVZFTlRTYCxcbiAgWzY0XTogYFNUQUJMRV9GUkFHTUVOVGAsXG4gIFsxMjhdOiBgS0VZRURfRlJBR01FTlRgLFxuICBbMjU2XTogYFVOS0VZRURfRlJBR01FTlRgLFxuICBbNTEyXTogYE5FRURfUEFUQ0hgLFxuICBbMTAyNF06IGBEWU5BTUlDX1NMT1RTYCxcbiAgWzIwNDhdOiBgREVWX1JPT1RfRlJBR01FTlRgLFxuICBbLTFdOiBgSE9JU1RFRGAsXG4gIFstMl06IGBCQUlMYFxufTtcbnZhciBzbG90RmxhZ3NUZXh0ID0ge1xuICBbMV06IFwiU1RBQkxFXCIsXG4gIFsyXTogXCJEWU5BTUlDXCIsXG4gIFszXTogXCJGT1JXQVJERURcIlxufTtcbnZhciBzcGVjaWFsQm9vbGVhbkF0dHJzID0gYGl0ZW1zY29wZSxhbGxvd2Z1bGxzY3JlZW4sZm9ybW5vdmFsaWRhdGUsaXNtYXAsbm9tb2R1bGUsbm92YWxpZGF0ZSxyZWFkb25seWA7XG52YXIgaXNCb29sZWFuQXR0cjIgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcChzcGVjaWFsQm9vbGVhbkF0dHJzICsgYCxhc3luYyxhdXRvZm9jdXMsYXV0b3BsYXksY29udHJvbHMsZGVmYXVsdCxkZWZlcixkaXNhYmxlZCxoaWRkZW4sbG9vcCxvcGVuLHJlcXVpcmVkLHJldmVyc2VkLHNjb3BlZCxzZWFtbGVzcyxjaGVja2VkLG11dGVkLG11bHRpcGxlLHNlbGVjdGVkYCk7XG52YXIgRU1QVFlfT0JKID0gdHJ1ZSA/IE9iamVjdC5mcmVlemUoe30pIDoge307XG52YXIgRU1QVFlfQVJSID0gdHJ1ZSA/IE9iamVjdC5mcmVlemUoW10pIDogW107XG52YXIgZXh0ZW5kID0gT2JqZWN0LmFzc2lnbjtcbnZhciBoYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgaGFzT3duID0gKHZhbCwga2V5KSA9PiBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbCwga2V5KTtcbnZhciBpc0FycmF
15ID0gQXJyYXkuaXNBcnJheTtcbnZhciBpc01hcCA9ICh2YWwpID0+IHRvVHlwZVN0cmluZyh2YWwpID09PSBcIltvYmplY3QgTWFwXVwiO1xudmFyIGlzU3RyaW5nID0gKHZhbCkgPT4gdHlwZW9mIHZhbCA9PT0gXCJzdHJpbmdcIjtcbnZhciBpc1N5bWJvbCA9ICh2YWwpID0+IHR5cGVvZiB2YWwgPT09IFwic3ltYm9sXCI7XG52YXIgaXNPYmplY3QgPSAodmFsKSA9PiB2YWwgIT09IG51bGwgJiYgdHlwZW9mIHZhbCA9PT0gXCJvYmplY3RcIjtcbnZhciBvYmplY3RUb1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgdG9UeXBlU3RyaW5nID0gKHZhbHVlKSA9PiBvYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTtcbnZhciB0b1Jhd1R5cGUgPSAodmFsdWUpID0+IHtcbiAgcmV0dXJuIHRvVHlwZVN0cmluZyh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xufTtcbnZhciBpc0ludGVnZXJLZXkgPSAoa2V5KSA9PiBpc1N0cmluZyhrZXkpICYmIGtleSAhPT0gXCJOYU5cIiAmJiBrZXlbMF0gIT09IFwiLVwiICYmIFwiXCIgKyBwYXJzZUludChrZXksIDEwKSA9PT0ga2V5O1xudmFyIGNhY2hlU3RyaW5nRnVuY3Rpb24gPSAoZm4pID0+IHtcbiAgY29uc3QgY2FjaGUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICByZXR1cm4gKHN0cikgPT4ge1xuICAgIGNvbnN0IGhpdCA9IGNhY2hlW3N0cl07XG4gICAgcmV0dXJuIGhpdCB8fCAoY2FjaGVbc3RyXSA9IGZuKHN0cikpO1xuICB9O1xufTtcbnZhciBjYW1lbGl6ZVJFID0gLy0oXFx3KS9nO1xudmFyIGNhbWVsaXplID0gY2FjaGVTdHJpbmdGdW5jdGlvbigoc3RyKSA9PiB7XG4gIHJldHVybiBzdHIucmVwbGFjZShjYW1lbGl6ZVJFLCAoXywgYykgPT4gYyA/IGMudG9VcHBlckNhc2UoKSA6IFwiXCIpO1xufSk7XG52YXIgaHlwaGVuYXRlUkUgPSAvXFxCKFtBLVpdKS9nO1xudmFyIGh5cGhlbmF0ZSA9IGNhY2hlU3RyaW5nRnVuY3Rpb24oKHN0cikgPT4gc3RyLnJlcGxhY2UoaHlwaGVuYXRlUkUsIFwiLSQxXCIpLnRvTG93ZXJDYXNlKCkpO1xudmFyIGNhcGl0YWxpemUgPSBjYWNoZVN0cmluZ0Z1bmN0aW9uKChzdHIpID0+IHN0ci5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHN0ci5zbGljZSgxKSk7XG52YXIgdG9IYW5kbGVyS2V5ID0gY2FjaGVTdHJpbmdGdW5jdGlvbigoc3RyKSA9PiBzdHIgPyBgb24ke2NhcGl0YWxpemUoc3RyKX1gIDogYGApO1xudmFyIGhhc0NoYW5nZWQgPSAodmFsdWUsIG9sZFZhbHVlKSA9PiB2YWx1ZSAhPT0gb2xkVmFsdWUgJiYgKHZhbHVlID09PSB2YWx1ZSB8fCBvbGRWYWx1ZSA9PT0gb2xkVmFsdWUpO1xuXG4vLyBub2RlX21vZHVsZXMvQHZ1ZS9yZWFjdGl2aXR5L2Rpc3QvcmVhY3Rpdml0eS5lc20tYnVuZGxlci5qc1xudmFyIHRhcmdldE1hcCA9IG5ldyBXZWFrTWFwKCk7XG52YXIgZWZmZWN0U3RhY2sgPSBbXTtcbnZhciBhY3RpdmVFZmZlY3Q7XG52YXIgSVRFUkFURV9LRVkgPSBTeW1ib2wodHJ1ZSA/IFwiaXRlcmF0ZVwiIDogXCJcIik7XG52YXIgTUFQX0tFWV9JVEVSQVRFX0tFWSA9IFN5bWJvbCh0cnVlID8gXCJNYXAga2V5IGl0ZXJhdGVcIiA6IFwiXCIpO1xuZnVuY3Rpb24gaXNFZmZlY3QoZm4pIHtcbiAgcmV0dXJuIGZuICYmIGZuLl9pc0VmZmVjdCA9PT0gdHJ1ZTtcbn1cbmZ1bmN0aW9uIGVmZmVjdDIoZm4sIG9wdGlvbnMgPSBFTVBUWV9PQkopIHtcbiAgaWYgKGlzRWZmZWN0KGZuKSkge1xuICAgIGZuID0gZm4ucmF3O1xuICB9XG4gIGNvbnN0IGVmZmVjdDMgPSBjcmVhdGVSZWFjdGl2ZUVmZmVjdChmbiwgb3B0aW9ucyk7XG4gIGlmICghb3B0aW9ucy5sYXp5KSB7XG4gICAgZWZmZWN0MygpO1xuICB9XG4gIHJldHVybiBlZmZlY3QzO1xufVxuZnVuY3Rpb24gc3RvcChlZmZlY3QzKSB7XG4gIGlmIChlZmZlY3QzLmFjdGl2ZSkge1xuICAgIGNsZWFudXAoZWZmZWN0Myk7XG4gICAgaWYgKGVmZmVjdDMub3B0aW9ucy5vblN0b3ApIHtcbiAgICAgIGVmZmVjdDMub3B0aW9ucy5vblN0b3AoKTtcbiAgICB9XG4gICAgZWZmZWN0My5hY3RpdmUgPSBmYWxzZTtcbiAgfVxufVxudmFyIHVpZCA9IDA7XG5mdW5jdGlvbiBjcmVhdGVSZWFjdGl2ZUVmZmVjdChmbiwgb3B0aW9ucykge1xuICBjb25zdCBlZmZlY3QzID0gZnVuY3Rpb24gcmVhY3RpdmVFZmZlY3QoKSB7XG4gICAgaWYgKCFlZmZlY3QzLmFjdGl2ZSkge1xuICAgICAgcmV0dXJuIGZuKCk7XG4gICAgfVxuICAgIGlmICghZWZmZWN0U3RhY2suaW5jbHVkZXMoZWZmZWN0MykpIHtcbiAgICAgIGNsZWFudXAoZWZmZWN0Myk7XG4gICAgICB0cnkge1xuICAgICAgICBlbmFibGVUcmFja2luZygpO1xuICAgICAgICBlZmZlY3RTdGFjay5wdXNoKGVmZmVjdDMpO1xuICAgICAgICBhY3RpdmVFZmZlY3QgPSBlZmZlY3QzO1xuICAgICAgICByZXR1cm4gZm4oKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGVmZmVjdFN0YWNrLnBvcCgpO1xuICAgICAgICByZXNldFRyYWNraW5nKCk7XG4gICAgICAgIGFjdGl2ZUVmZmVjdCA9IGVmZmVjdFN0YWNrW2VmZmVjdFN0YWNrLmxlbmd0aCAtIDFdO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgZWZmZWN0My5pZCA9IHVpZCsrO1xuICBlZmZlY3QzLmFsbG93UmVjdXJzZSA9ICEhb3B0aW9ucy5hbGxvd1JlY3Vyc2U7XG4gIGVmZmVjdDMuX2lzRWZmZWN0ID0gdHJ1ZTtcbiAgZWZmZWN0My5hY3RpdmUgPSB0cnVlO1xuICBlZmZlY3QzLnJhdyA9IGZuO1xuICBlZmZlY3QzLmRlcHMgPSBbXTtcbiAgZWZmZWN0My5vcHRpb25zID0gb3B0aW9ucztcbiAgcmV0dXJuIGVmZmVjdDM7XG59XG5mdW5jdGlvbiBjbGVhbnVwKGVmZmVjdDMpIHtcbiAgY29uc3Qge2RlcHN9ID0gZWZmZWN0MztcbiAgaWYgKGRlcHMubGVuZ3RoKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkZXBzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBkZXBzW2ldLmRlbGV0ZShlZmZlY3QzKTtcbiAgICB9XG4gICAgZGVwcy5sZW5ndGggPSAwO1xuICB9XG59XG52YXIgc2hvdWxkVHJhY2sgPSB0cnVlO1xudmFyIHRyYWNrU3RhY2sgPSBbXTtcbmZ1bmN0aW9uIHBhdXNlVHJhY2tpbmcoKSB7XG4gIHRyYWNrU3RhY2sucHVzaChzaG91bGRUcmFjayk7XG4gIHNob3VsZFRyYWNrID0gZmFsc2U7XG59XG5mdW5jdGlvbiBlbmFibGVUcmFja2luZygpIHtcbiAgdHJhY2tTdGFjay5wdXNoKHNob3VsZFRyYWNrKTtcbiAgc2hvdWxkVHJhY2sgPSB0cnVlO1xufVxuZnVuY3Rpb24gcmVzZXRUcmFja2luZygpIHtcbiAgY29uc3QgbGFzdCA9IHRyYWNrU3RhY2sucG9wKCk7XG4gIHNob3VsZFRyYWNrID0gbGFzdCA9PT0gdm9pZCAwID8gdHJ1ZSA6IGxhc3Q7XG59XG5mdW5jdGlvbiB0cmFjayh0YXJnZXQsIHR5cGUsIGtleSkge1xuICBpZiAoIXNob3VsZFRyYWNrIHx8IGFjdGl2ZUVmZmVjdCA9PT0gdm9pZCAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGxldCBkZXBzTWFwID0gdGFyZ2V0TWFwLmdldCh0YXJnZXQpO1xuICBpZiAoIWRlcHNNYXApIHtcbiAgICB0YXJnZXRNYXAuc2V0KHRhcmdldCwgZGVwc01hcCA9IG5ldyBNYXAoKSk7XG4gIH1cbiAgbGV0IGRlcCA9IGRlcHNNYXAuZ2V0KGtleSk7XG4gIGlmICghZGVwKSB7XG4gICAgZGVwc01hcC5zZXQoa2V5LCBkZXAgPSBuZXcgU2V0KCkpO1xuICB9XG4gIGlmICghZGVwLmhhcyhhY3RpdmVFZmZlY3QpKSB7XG4gICAgZGVwLmFkZChhY3RpdmVFZmZlY3QpO1xuICAgIGFjdGl2ZUVmZmVjdC5kZXBzLnB1c2goZGVwKTtcbiAgICBpZiAoYWN0aXZlRWZmZWN0Lm9wdGlvbnMub25UcmFjaykge1xuICAgICAgYWN0aXZlRWZmZWN0Lm9wdGlvbnMub25UcmFjayh7XG4gICAgICAgIGVmZmVjdDogYWN0aXZlRWZmZWN0LFxuICAgICAgICB0YXJnZXQsXG4gICAgICAgI
1HR5cGUsXG4gICAgICAgIGtleVxuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiB0cmlnZ2VyKHRhcmdldCwgdHlwZSwga2V5LCBuZXdWYWx1ZSwgb2xkVmFsdWUsIG9sZFRhcmdldCkge1xuICBjb25zdCBkZXBzTWFwID0gdGFyZ2V0TWFwLmdldCh0YXJnZXQpO1xuICBpZiAoIWRlcHNNYXApIHtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3QgZWZmZWN0cyA9IG5ldyBTZXQoKTtcbiAgY29uc3QgYWRkMiA9IChlZmZlY3RzVG9BZGQpID0+IHtcbiAgICBpZiAoZWZmZWN0c1RvQWRkKSB7XG4gICAgICBlZmZlY3RzVG9BZGQuZm9yRWFjaCgoZWZmZWN0MykgPT4ge1xuICAgICAgICBpZiAoZWZmZWN0MyAhPT0gYWN0aXZlRWZmZWN0IHx8IGVmZmVjdDMuYWxsb3dSZWN1cnNlKSB7XG4gICAgICAgICAgZWZmZWN0cy5hZGQoZWZmZWN0Myk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcbiAgaWYgKHR5cGUgPT09IFwiY2xlYXJcIikge1xuICAgIGRlcHNNYXAuZm9yRWFjaChhZGQyKTtcbiAgfSBlbHNlIGlmIChrZXkgPT09IFwibGVuZ3RoXCIgJiYgaXNBcnJheSh0YXJnZXQpKSB7XG4gICAgZGVwc01hcC5mb3JFYWNoKChkZXAsIGtleTIpID0+IHtcbiAgICAgIGlmIChrZXkyID09PSBcImxlbmd0aFwiIHx8IGtleTIgPj0gbmV3VmFsdWUpIHtcbiAgICAgICAgYWRkMihkZXApO1xuICAgICAgfVxuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGlmIChrZXkgIT09IHZvaWQgMCkge1xuICAgICAgYWRkMihkZXBzTWFwLmdldChrZXkpKTtcbiAgICB9XG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlIFwiYWRkXCI6XG4gICAgICAgIGlmICghaXNBcnJheSh0YXJnZXQpKSB7XG4gICAgICAgICAgYWRkMihkZXBzTWFwLmdldChJVEVSQVRFX0tFWSkpO1xuICAgICAgICAgIGlmIChpc01hcCh0YXJnZXQpKSB7XG4gICAgICAgICAgICBhZGQyKGRlcHNNYXAuZ2V0KE1BUF9LRVlfSVRFUkFURV9LRVkpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoaXNJbnRlZ2VyS2V5KGtleSkpIHtcbiAgICAgICAgICBhZGQyKGRlcHNNYXAuZ2V0KFwibGVuZ3RoXCIpKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJkZWxldGVcIjpcbiAgICAgICAgaWYgKCFpc0FycmF5KHRhcmdldCkpIHtcbiAgICAgICAgICBhZGQyKGRlcHNNYXAuZ2V0KElURVJBVEVfS0VZKSk7XG4gICAgICAgICAgaWYgKGlzTWFwKHRhcmdldCkpIHtcbiAgICAgICAgICAgIGFkZDIoZGVwc01hcC5nZXQoTUFQX0tFWV9JVEVSQVRFX0tFWSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJzZXRcIjpcbiAgICAgICAgaWYgKGlzTWFwKHRhcmdldCkpIHtcbiAgICAgICAgICBhZGQyKGRlcHNNYXAuZ2V0KElURVJBVEVfS0VZKSk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGNvbnN0IHJ1biA9IChlZmZlY3QzKSA9PiB7XG4gICAgaWYgKGVmZmVjdDMub3B0aW9ucy5vblRyaWdnZXIpIHtcbiAgICAgIGVmZmVjdDMub3B0aW9ucy5vblRyaWdnZXIoe1xuICAgICAgICBlZmZlY3Q6IGVmZmVjdDMsXG4gICAgICAgIHRhcmdldCxcbiAgICAgICAga2V5LFxuICAgICAgICB0eXBlLFxuICAgICAgICBuZXdWYWx1ZSxcbiAgICAgICAgb2xkVmFsdWUsXG4gICAgICAgIG9sZFRhcmdldFxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChlZmZlY3QzLm9wdGlvbnMuc2NoZWR1bGVyKSB7XG4gICAgICBlZmZlY3QzLm9wdGlvbnMuc2NoZWR1bGVyKGVmZmVjdDMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlZmZlY3QzKCk7XG4gICAgfVxuICB9O1xuICBlZmZlY3RzLmZvckVhY2gocnVuKTtcbn1cbnZhciBpc05vblRyYWNrYWJsZUtleXMgPSAvKiBAX19QVVJFX18gKi8gbWFrZU1hcChgX19wcm90b19fLF9fdl9pc1JlZixfX2lzVnVlYCk7XG52YXIgYnVpbHRJblN5bWJvbHMgPSBuZXcgU2V0KE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKFN5bWJvbCkubWFwKChrZXkpID0+IFN5bWJvbFtrZXldKS5maWx0ZXIoaXNTeW1ib2wpKTtcbnZhciBnZXQyID0gLyogQF9fUFVSRV9fICovIGNyZWF0ZUdldHRlcigpO1xudmFyIHNoYWxsb3dHZXQgPSAvKiBAX19QVVJFX18gKi8gY3JlYXRlR2V0dGVyKGZhbHNlLCB0cnVlKTtcbnZhciByZWFkb25seUdldCA9IC8qIEBfX1BVUkVfXyAqLyBjcmVhdGVHZXR0ZXIodHJ1ZSk7XG52YXIgc2hhbGxvd1JlYWRvbmx5R2V0ID0gLyogQF9fUFVSRV9fICovIGNyZWF0ZUdldHRlcih0cnVlLCB0cnVlKTtcbnZhciBhcnJheUluc3RydW1lbnRhdGlvbnMgPSB7fTtcbltcImluY2x1ZGVzXCIsIFwiaW5kZXhPZlwiLCBcImxhc3RJbmRleE9mXCJdLmZvckVhY2goKGtleSkgPT4ge1xuICBjb25zdCBtZXRob2QgPSBBcnJheS5wcm90b3R5cGVba2V5XTtcbiAgYXJyYXlJbnN0cnVtZW50YXRpb25zW2tleV0gPSBmdW5jdGlvbiguLi5hcmdzKSB7XG4gICAgY29uc3QgYXJyID0gdG9SYXcodGhpcyk7XG4gICAgZm9yIChsZXQgaSA9IDAsIGwgPSB0aGlzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgdHJhY2soYXJyLCBcImdldFwiLCBpICsgXCJcIik7XG4gICAgfVxuICAgIGNvbnN0IHJlcyA9IG1ldGhvZC5hcHBseShhcnIsIGFyZ3MpO1xuICAgIGlmIChyZXMgPT09IC0xIHx8IHJlcyA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybiBtZXRob2QuYXBwbHkoYXJyLCBhcmdzLm1hcCh0b1JhdykpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcmVzO1xuICAgIH1cbiAgfTtcbn0pO1xuW1wicHVzaFwiLCBcInBvcFwiLCBcInNoaWZ0XCIsIFwidW5zaGlmdFwiLCBcInNwbGljZVwiXS5mb3JFYWNoKChrZXkpID0+IHtcbiAgY29uc3QgbWV0aG9kID0gQXJyYXkucHJvdG90eXBlW2tleV07XG4gIGFycmF5SW5zdHJ1bWVudGF0aW9uc1trZXldID0gZnVuY3Rpb24oLi4uYXJncykge1xuICAgIHBhdXNlVHJhY2tpbmcoKTtcbiAgICBjb25zdCByZXMgPSBtZXRob2QuYXBwbHkodGhpcywgYXJncyk7XG4gICAgcmVzZXRUcmFja2luZygpO1xuICAgIHJldHVybiByZXM7XG4gIH07XG59KTtcbmZ1bmN0aW9uIGNyZWF0ZUdldHRlcihpc1JlYWRvbmx5ID0gZmFsc2UsIHNoYWxsb3cgPSBmYWxzZSkge1xuICByZXR1cm4gZnVuY3Rpb24gZ2V0Myh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpIHtcbiAgICBpZiAoa2V5ID09PSBcIl9fdl9pc1JlYWN0aXZlXCIpIHtcbiAgICAgIHJldHVybiAhaXNSZWFkb25seTtcbiAgICB9IGVsc2UgaWYgKGtleSA9PT0gXCJfX3ZfaXNSZWFkb25seVwiKSB7XG4gICAgICByZXR1cm4gaXNSZWFkb25seTtcbiAgICB9IGVsc2UgaWYgKGtleSA9PT0gXCJfX3ZfcmF3XCIgJiYgcmVjZWl2ZXIgPT09IChpc1JlYWRvbmx5ID8gc2hhbGxvdyA/IHNoYWxsb3dSZWFkb25seU1hcCA6IHJlYWRvbmx5TWFwIDogc2hhbGxvdyA/IHNoYWxsb3dSZWFjdGl2ZU1hcCA6IHJlYWN0aXZlTWFwKS5nZXQodGFyZ2V0KSkge1xuICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG4gICAgY29uc3QgdGFyZ2V0SXNBcnJheSA9IGlzQXJyYXkodGFyZ2V0KTtcbiAgICBpZiAoIWlzUmVhZG9ubHkgJiYgdGFyZ2V0SXNBcnJheSAmJiBoYXNPd24oYXJyYXlJbnN0cnVtZW50YXRpb25zLCBrZXkpKSB7XG4gICAgICByZXR1cm4gUmVmbGVjdC5nZXQoYXJyYXlJbnN0cnVtZW50YXRpb25zLCBrZXksIHJlY2VpdmVyKTtcbiAgICB9XG4gICAgY29uc3QgcmVzID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBrZXksIHJlY2VpdmVyKTtcbiAgICBpZiAoaXNTeW1ib2woa2V5KSA/IGJ1aWx0SW5TeW1ib2xzLmhhcyhrZXkpIDogaXNOb25UcmFja2FibGVLZXlzKGtleSkpIHtcbiAgICAgIHJldHVybi
1ByZXM7XG4gICAgfVxuICAgIGlmICghaXNSZWFkb25seSkge1xuICAgICAgdHJhY2sodGFyZ2V0LCBcImdldFwiLCBrZXkpO1xuICAgIH1cbiAgICBpZiAoc2hhbGxvdykge1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG4gICAgaWYgKGlzUmVmKHJlcykpIHtcbiAgICAgIGNvbnN0IHNob3VsZFVud3JhcCA9ICF0YXJnZXRJc0FycmF5IHx8ICFpc0ludGVnZXJLZXkoa2V5KTtcbiAgICAgIHJldHVybiBzaG91bGRVbndyYXAgPyByZXMudmFsdWUgOiByZXM7XG4gICAgfVxuICAgIGlmIChpc09iamVjdChyZXMpKSB7XG4gICAgICByZXR1cm4gaXNSZWFkb25seSA/IHJlYWRvbmx5KHJlcykgOiByZWFjdGl2ZTIocmVzKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfTtcbn1cbnZhciBzZXQyID0gLyogQF9fUFVSRV9fICovIGNyZWF0ZVNldHRlcigpO1xudmFyIHNoYWxsb3dTZXQgPSAvKiBAX19QVVJFX18gKi8gY3JlYXRlU2V0dGVyKHRydWUpO1xuZnVuY3Rpb24gY3JlYXRlU2V0dGVyKHNoYWxsb3cgPSBmYWxzZSkge1xuICByZXR1cm4gZnVuY3Rpb24gc2V0Myh0YXJnZXQsIGtleSwgdmFsdWUsIHJlY2VpdmVyKSB7XG4gICAgbGV0IG9sZFZhbHVlID0gdGFyZ2V0W2tleV07XG4gICAgaWYgKCFzaGFsbG93KSB7XG4gICAgICB2YWx1ZSA9IHRvUmF3KHZhbHVlKTtcbiAgICAgIG9sZFZhbHVlID0gdG9SYXcob2xkVmFsdWUpO1xuICAgICAgaWYgKCFpc0FycmF5KHRhcmdldCkgJiYgaXNSZWYob2xkVmFsdWUpICYmICFpc1JlZih2YWx1ZSkpIHtcbiAgICAgICAgb2xkVmFsdWUudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGhhZEtleSA9IGlzQXJyYXkodGFyZ2V0KSAmJiBpc0ludGVnZXJLZXkoa2V5KSA/IE51bWJlcihrZXkpIDwgdGFyZ2V0Lmxlbmd0aCA6IGhhc093bih0YXJnZXQsIGtleSk7XG4gICAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5zZXQodGFyZ2V0LCBrZXksIHZhbHVlLCByZWNlaXZlcik7XG4gICAgaWYgKHRhcmdldCA9PT0gdG9SYXcocmVjZWl2ZXIpKSB7XG4gICAgICBpZiAoIWhhZEtleSkge1xuICAgICAgICB0cmlnZ2VyKHRhcmdldCwgXCJhZGRcIiwga2V5LCB2YWx1ZSk7XG4gICAgICB9IGVsc2UgaWYgKGhhc0NoYW5nZWQodmFsdWUsIG9sZFZhbHVlKSkge1xuICAgICAgICB0cmlnZ2VyKHRhcmdldCwgXCJzZXRcIiwga2V5LCB2YWx1ZSwgb2xkVmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xufVxuZnVuY3Rpb24gZGVsZXRlUHJvcGVydHkodGFyZ2V0LCBrZXkpIHtcbiAgY29uc3QgaGFkS2V5ID0gaGFzT3duKHRhcmdldCwga2V5KTtcbiAgY29uc3Qgb2xkVmFsdWUgPSB0YXJnZXRba2V5XTtcbiAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5kZWxldGVQcm9wZXJ0eSh0YXJnZXQsIGtleSk7XG4gIGlmIChyZXN1bHQgJiYgaGFkS2V5KSB7XG4gICAgdHJpZ2dlcih0YXJnZXQsIFwiZGVsZXRlXCIsIGtleSwgdm9pZCAwLCBvbGRWYWx1ZSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIGhhcyh0YXJnZXQsIGtleSkge1xuICBjb25zdCByZXN1bHQgPSBSZWZsZWN0Lmhhcyh0YXJnZXQsIGtleSk7XG4gIGlmICghaXNTeW1ib2woa2V5KSB8fCAhYnVpbHRJblN5bWJvbHMuaGFzKGtleSkpIHtcbiAgICB0cmFjayh0YXJnZXQsIFwiaGFzXCIsIGtleSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIG93bktleXModGFyZ2V0KSB7XG4gIHRyYWNrKHRhcmdldCwgXCJpdGVyYXRlXCIsIGlzQXJyYXkodGFyZ2V0KSA/IFwibGVuZ3RoXCIgOiBJVEVSQVRFX0tFWSk7XG4gIHJldHVybiBSZWZsZWN0Lm93bktleXModGFyZ2V0KTtcbn1cbnZhciBtdXRhYmxlSGFuZGxlcnMgPSB7XG4gIGdldDogZ2V0MixcbiAgc2V0OiBzZXQyLFxuICBkZWxldGVQcm9wZXJ0eSxcbiAgaGFzLFxuICBvd25LZXlzXG59O1xudmFyIHJlYWRvbmx5SGFuZGxlcnMgPSB7XG4gIGdldDogcmVhZG9ubHlHZXQsXG4gIHNldCh0YXJnZXQsIGtleSkge1xuICAgIGlmICh0cnVlKSB7XG4gICAgICBjb25zb2xlLndhcm4oYFNldCBvcGVyYXRpb24gb24ga2V5IFwiJHtTdHJpbmcoa2V5KX1cIiBmYWlsZWQ6IHRhcmdldCBpcyByZWFkb25seS5gLCB0YXJnZXQpO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSxcbiAgZGVsZXRlUHJvcGVydHkodGFyZ2V0LCBrZXkpIHtcbiAgICBpZiAodHJ1ZSkge1xuICAgICAgY29uc29sZS53YXJuKGBEZWxldGUgb3BlcmF0aW9uIG9uIGtleSBcIiR7U3RyaW5nKGtleSl9XCIgZmFpbGVkOiB0YXJnZXQgaXMgcmVhZG9ubHkuYCwgdGFyZ2V0KTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn07XG52YXIgc2hhbGxvd1JlYWN0aXZlSGFuZGxlcnMgPSBleHRlbmQoe30sIG11dGFibGVIYW5kbGVycywge1xuICBnZXQ6IHNoYWxsb3dHZXQsXG4gIHNldDogc2hhbGxvd1NldFxufSk7XG52YXIgc2hhbGxvd1JlYWRvbmx5SGFuZGxlcnMgPSBleHRlbmQoe30sIHJlYWRvbmx5SGFuZGxlcnMsIHtcbiAgZ2V0OiBzaGFsbG93UmVhZG9ubHlHZXRcbn0pO1xudmFyIHRvUmVhY3RpdmUgPSAodmFsdWUpID0+IGlzT2JqZWN0KHZhbHVlKSA/IHJlYWN0aXZlMih2YWx1ZSkgOiB2YWx1ZTtcbnZhciB0b1JlYWRvbmx5ID0gKHZhbHVlKSA9PiBpc09iamVjdCh2YWx1ZSkgPyByZWFkb25seSh2YWx1ZSkgOiB2YWx1ZTtcbnZhciB0b1NoYWxsb3cgPSAodmFsdWUpID0+IHZhbHVlO1xudmFyIGdldFByb3RvID0gKHYpID0+IFJlZmxlY3QuZ2V0UHJvdG90eXBlT2Yodik7XG5mdW5jdGlvbiBnZXQkMSh0YXJnZXQsIGtleSwgaXNSZWFkb25seSA9IGZhbHNlLCBpc1NoYWxsb3cgPSBmYWxzZSkge1xuICB0YXJnZXQgPSB0YXJnZXRbXCJfX3ZfcmF3XCJdO1xuICBjb25zdCByYXdUYXJnZXQgPSB0b1Jhdyh0YXJnZXQpO1xuICBjb25zdCByYXdLZXkgPSB0b1JhdyhrZXkpO1xuICBpZiAoa2V5ICE9PSByYXdLZXkpIHtcbiAgICAhaXNSZWFkb25seSAmJiB0cmFjayhyYXdUYXJnZXQsIFwiZ2V0XCIsIGtleSk7XG4gIH1cbiAgIWlzUmVhZG9ubHkgJiYgdHJhY2socmF3VGFyZ2V0LCBcImdldFwiLCByYXdLZXkpO1xuICBjb25zdCB7aGFzOiBoYXMyfSA9IGdldFByb3RvKHJhd1RhcmdldCk7XG4gIGNvbnN0IHdyYXAgPSBpc1NoYWxsb3cgPyB0b1NoYWxsb3cgOiBpc1JlYWRvbmx5ID8gdG9SZWFkb25seSA6IHRvUmVhY3RpdmU7XG4gIGlmIChoYXMyLmNhbGwocmF3VGFyZ2V0LCBrZXkpKSB7XG4gICAgcmV0dXJuIHdyYXAodGFyZ2V0LmdldChrZXkpKTtcbiAgfSBlbHNlIGlmIChoYXMyLmNhbGwocmF3VGFyZ2V0LCByYXdLZXkpKSB7XG4gICAgcmV0dXJuIHdyYXAodGFyZ2V0LmdldChyYXdLZXkpKTtcbiAgfSBlbHNlIGlmICh0YXJnZXQgIT09IHJhd1RhcmdldCkge1xuICAgIHRhcmdldC5nZXQoa2V5KTtcbiAgfVxufVxuZnVuY3Rpb24gaGFzJDEoa2V5LCBpc1JlYWRvbmx5ID0gZmFsc2UpIHtcbiAgY29uc3QgdGFyZ2V0ID0gdGhpc1tcIl9fdl9yYXdcIl07XG4gIGNvbnN0IHJhd1RhcmdldCA9IHRvUmF3KHRhcmdldCk7XG4gIGNvbnN0IHJhd0tleSA9IHRvUmF3KGtleSk7XG4gIGlmIChrZXkgIT09IHJhd0tleSkge1xuICAgICFpc1JlYWRvbmx5ICYmIHRyYWNrKHJhd1RhcmdldCwgXCJoYXNcIiwga2V5KTtcbiAgfVxuICAhaXNSZWFkb25seSAmJiB0cmFjayhyYXdUYXJnZXQsIFwiaGFzXCIsIHJhd0tleSk7XG4gIHJldHVybi
1BrZXkgPT09IHJhd0tleSA/IHRhcmdldC5oYXMoa2V5KSA6IHRhcmdldC5oYXMoa2V5KSB8fCB0YXJnZXQuaGFzKHJhd0tleSk7XG59XG5mdW5jdGlvbiBzaXplKHRhcmdldCwgaXNSZWFkb25seSA9IGZhbHNlKSB7XG4gIHRhcmdldCA9IHRhcmdldFtcIl9fdl9yYXdcIl07XG4gICFpc1JlYWRvbmx5ICYmIHRyYWNrKHRvUmF3KHRhcmdldCksIFwiaXRlcmF0ZVwiLCBJVEVSQVRFX0tFWSk7XG4gIHJldHVybiBSZWZsZWN0LmdldCh0YXJnZXQsIFwic2l6ZVwiLCB0YXJnZXQpO1xufVxuZnVuY3Rpb24gYWRkKHZhbHVlKSB7XG4gIHZhbHVlID0gdG9SYXcodmFsdWUpO1xuICBjb25zdCB0YXJnZXQgPSB0b1Jhdyh0aGlzKTtcbiAgY29uc3QgcHJvdG8gPSBnZXRQcm90byh0YXJnZXQpO1xuICBjb25zdCBoYWRLZXkgPSBwcm90by5oYXMuY2FsbCh0YXJnZXQsIHZhbHVlKTtcbiAgaWYgKCFoYWRLZXkpIHtcbiAgICB0YXJnZXQuYWRkKHZhbHVlKTtcbiAgICB0cmlnZ2VyKHRhcmdldCwgXCJhZGRcIiwgdmFsdWUsIHZhbHVlKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn1cbmZ1bmN0aW9uIHNldCQxKGtleSwgdmFsdWUpIHtcbiAgdmFsdWUgPSB0b1Jhdyh2YWx1ZSk7XG4gIGNvbnN0IHRhcmdldCA9IHRvUmF3KHRoaXMpO1xuICBjb25zdCB7aGFzOiBoYXMyLCBnZXQ6IGdldDN9ID0gZ2V0UHJvdG8odGFyZ2V0KTtcbiAgbGV0IGhhZEtleSA9IGhhczIuY2FsbCh0YXJnZXQsIGtleSk7XG4gIGlmICghaGFkS2V5KSB7XG4gICAga2V5ID0gdG9SYXcoa2V5KTtcbiAgICBoYWRLZXkgPSBoYXMyLmNhbGwodGFyZ2V0LCBrZXkpO1xuICB9IGVsc2UgaWYgKHRydWUpIHtcbiAgICBjaGVja0lkZW50aXR5S2V5cyh0YXJnZXQsIGhhczIsIGtleSk7XG4gIH1cbiAgY29uc3Qgb2xkVmFsdWUgPSBnZXQzLmNhbGwodGFyZ2V0LCBrZXkpO1xuICB0YXJnZXQuc2V0KGtleSwgdmFsdWUpO1xuICBpZiAoIWhhZEtleSkge1xuICAgIHRyaWdnZXIodGFyZ2V0LCBcImFkZFwiLCBrZXksIHZhbHVlKTtcbiAgfSBlbHNlIGlmIChoYXNDaGFuZ2VkKHZhbHVlLCBvbGRWYWx1ZSkpIHtcbiAgICB0cmlnZ2VyKHRhcmdldCwgXCJzZXRcIiwga2V5LCB2YWx1ZSwgb2xkVmFsdWUpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufVxuZnVuY3Rpb24gZGVsZXRlRW50cnkoa2V5KSB7XG4gIGNvbnN0IHRhcmdldCA9IHRvUmF3KHRoaXMpO1xuICBjb25zdCB7aGFzOiBoYXMyLCBnZXQ6IGdldDN9ID0gZ2V0UHJvdG8odGFyZ2V0KTtcbiAgbGV0IGhhZEtleSA9IGhhczIuY2FsbCh0YXJnZXQsIGtleSk7XG4gIGlmICghaGFkS2V5KSB7XG4gICAga2V5ID0gdG9SYXcoa2V5KTtcbiAgICBoYWRLZXkgPSBoYXMyLmNhbGwodGFyZ2V0LCBrZXkpO1xuICB9IGVsc2UgaWYgKHRydWUpIHtcbiAgICBjaGVja0lkZW50aXR5S2V5cyh0YXJnZXQsIGhhczIsIGtleSk7XG4gIH1cbiAgY29uc3Qgb2xkVmFsdWUgPSBnZXQzID8gZ2V0My5jYWxsKHRhcmdldCwga2V5KSA6IHZvaWQgMDtcbiAgY29uc3QgcmVzdWx0ID0gdGFyZ2V0LmRlbGV0ZShrZXkpO1xuICBpZiAoaGFkS2V5KSB7XG4gICAgdHJpZ2dlcih0YXJnZXQsIFwiZGVsZXRlXCIsIGtleSwgdm9pZCAwLCBvbGRWYWx1ZSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIGNsZWFyKCkge1xuICBjb25zdCB0YXJnZXQgPSB0b1Jhdyh0aGlzKTtcbiAgY29uc3QgaGFkSXRlbXMgPSB0YXJnZXQuc2l6ZSAhPT0gMDtcbiAgY29uc3Qgb2xkVGFyZ2V0ID0gdHJ1ZSA/IGlzTWFwKHRhcmdldCkgPyBuZXcgTWFwKHRhcmdldCkgOiBuZXcgU2V0KHRhcmdldCkgOiB2b2lkIDA7XG4gIGNvbnN0IHJlc3VsdCA9IHRhcmdldC5jbGVhcigpO1xuICBpZiAoaGFkSXRlbXMpIHtcbiAgICB0cmlnZ2VyKHRhcmdldCwgXCJjbGVhclwiLCB2b2lkIDAsIHZvaWQgMCwgb2xkVGFyZ2V0KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gY3JlYXRlRm9yRWFjaChpc1JlYWRvbmx5LCBpc1NoYWxsb3cpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGZvckVhY2goY2FsbGJhY2ssIHRoaXNBcmcpIHtcbiAgICBjb25zdCBvYnNlcnZlZCA9IHRoaXM7XG4gICAgY29uc3QgdGFyZ2V0ID0gb2JzZXJ2ZWRbXCJfX3ZfcmF3XCJdO1xuICAgIGNvbnN0IHJhd1RhcmdldCA9IHRvUmF3KHRhcmdldCk7XG4gICAgY29uc3Qgd3JhcCA9IGlzU2hhbGxvdyA/IHRvU2hhbGxvdyA6IGlzUmVhZG9ubHkgPyB0b1JlYWRvbmx5IDogdG9SZWFjdGl2ZTtcbiAgICAhaXNSZWFkb25seSAmJiB0cmFjayhyYXdUYXJnZXQsIFwiaXRlcmF0ZVwiLCBJVEVSQVRFX0tFWSk7XG4gICAgcmV0dXJuIHRhcmdldC5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICByZXR1cm4gY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB3cmFwKHZhbHVlKSwgd3JhcChrZXkpLCBvYnNlcnZlZCk7XG4gICAgfSk7XG4gIH07XG59XG5mdW5jdGlvbiBjcmVhdGVJdGVyYWJsZU1ldGhvZChtZXRob2QsIGlzUmVhZG9ubHksIGlzU2hhbGxvdykge1xuICByZXR1cm4gZnVuY3Rpb24oLi4uYXJncykge1xuICAgIGNvbnN0IHRhcmdldCA9IHRoaXNbXCJfX3ZfcmF3XCJdO1xuICAgIGNvbnN0IHJhd1RhcmdldCA9IHRvUmF3KHRhcmdldCk7XG4gICAgY29uc3QgdGFyZ2V0SXNNYXAgPSBpc01hcChyYXdUYXJnZXQpO1xuICAgIGNvbnN0IGlzUGFpciA9IG1ldGhvZCA9PT0gXCJlbnRyaWVzXCIgfHwgbWV0aG9kID09PSBTeW1ib2wuaXRlcmF0b3IgJiYgdGFyZ2V0SXNNYXA7XG4gICAgY29uc3QgaXNLZXlPbmx5ID0gbWV0aG9kID09PSBcImtleXNcIiAmJiB0YXJnZXRJc01hcDtcbiAgICBjb25zdCBpbm5lckl0ZXJhdG9yID0gdGFyZ2V0W21ldGhvZF0oLi4uYXJncyk7XG4gICAgY29uc3Qgd3JhcCA9IGlzU2hhbGxvdyA/IHRvU2hhbGxvdyA6IGlzUmVhZG9ubHkgPyB0b1JlYWRvbmx5IDogdG9SZWFjdGl2ZTtcbiAgICAhaXNSZWFkb25seSAmJiB0cmFjayhyYXdUYXJnZXQsIFwiaXRlcmF0ZVwiLCBpc0tleU9ubHkgPyBNQVBfS0VZX0lURVJBVEVfS0VZIDogSVRFUkFURV9LRVkpO1xuICAgIHJldHVybiB7XG4gICAgICBuZXh0KCkge1xuICAgICAgICBjb25zdCB7dmFsdWUsIGRvbmV9ID0gaW5uZXJJdGVyYXRvci5uZXh0KCk7XG4gICAgICAgI
1HJldHVybiBkb25lID8ge3ZhbHVlLCBkb25lfSA6IHtcbiAgICAgICAgICB2YWx1ZTogaXNQYWlyID8gW3dyYXAodmFsdWVbMF0pLCB3cmFwKHZhbHVlWzFdKV0gOiB3cmFwKHZhbHVlKSxcbiAgICAgICAgICBkb25lXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgICAgW1N5bWJvbC5pdGVyYXRvcl0oKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgIH07XG4gIH07XG59XG5mdW5jdGlvbiBjcmVhdGVSZWFkb25seU1ldGhvZCh0eXBlKSB7XG4gIHJldHVybiBmdW5jdGlvbiguLi5hcmdzKSB7XG4gICAgaWYgKHRydWUpIHtcbiAgICAgIGNvbnN0IGtleSA9IGFyZ3NbMF0gPyBgb24ga2V5IFwiJHthcmdzWzBdfVwiIGAgOiBgYDtcbiAgICAgIGNvbnNvbGUud2FybihgJHtjYXBpdGFsaXplKHR5cGUpfSBvcGVyYXRpb24gJHtrZXl9ZmFpbGVkOiB0YXJnZXQgaXMgcmVhZG9ubHkuYCwgdG9SYXcodGhpcykpO1xuICAgIH1cbiAgICByZXR1cm4gdHlwZSA9PT0gXCJkZWxldGVcIiA/IGZhbHNlIDogdGhpcztcbiAgfTtcbn1cbnZhciBtdXRhYmxlSW5zdHJ1bWVudGF0aW9ucyA9IHtcbiAgZ2V0KGtleSkge1xuICAgIHJldHVybiBnZXQkMSh0aGlzLCBrZXkpO1xuICB9LFxuICBnZXQgc2l6ZSgpIHtcbiAgICByZXR1cm4gc2l6ZSh0aGlzKTtcbiAgfSxcbiAgaGFzOiBoYXMkMSxcbiAgYWRkLFxuICBzZXQ6IHNldCQxLFxuICBkZWxldGU6IGRlbGV0ZUVudHJ5LFxuICBjbGVhcixcbiAgZm9yRWFjaDogY3JlYXRlRm9yRWFjaChmYWxzZSwgZmFsc2UpXG59O1xudmFyIHNoYWxsb3dJbnN0cnVtZW50YXRpb25zID0ge1xuICBnZXQoa2V5KSB7XG4gICAgcmV0dXJuIGdldCQxKHRoaXMsIGtleSwgZmFsc2UsIHRydWUpO1xuICB9LFxuICBnZXQgc2l6ZSgpIHtcbiAgICByZXR1cm4gc2l6ZSh0aGlzKTtcbiAgfSxcbiAgaGFzOiBoYXMkMSxcbiAgYWRkLFxuICBzZXQ6IHNldCQxLFxuICBkZWxldGU6IGRlbGV0ZUVudHJ5LFxuICBjbGVhcixcbiAgZm9yRWFjaDogY3JlYXRlRm9yRWFjaChmYWxzZSwgdHJ1ZSlcbn07XG52YXIgcmVhZG9ubHlJbnN0cnVtZW50YXRpb25zID0ge1xuICBnZXQoa2V5KSB7XG4gICAgcmV0dXJuIGdldCQxKHRoaXMsIGtleSwgdHJ1ZSk7XG4gIH0sXG4gIGdldCBzaXplKCkge1xuICAgIHJldHVybiBzaXplKHRoaXMsIHRydWUpO1xuICB9LFxuICBoYXMoa2V5KSB7XG4gICAgcmV0dXJuIGhhcyQxLmNhbGwodGhpcywga2V5LCB0cnVlKTtcbiAgfSxcbiAgYWRkOiBjcmVhdGVSZWFkb25seU1ldGhvZChcImFkZFwiKSxcbiAgc2V0OiBjcmVhdGVSZWFkb25seU1ldGhvZChcInNldFwiKSxcbiAgZGVsZXRlOiBjcmVhdGVSZWFkb25seU1ldGhvZChcImRlbGV0ZVwiKSxcbiAgY2xlYXI6IGNyZWF0ZVJlYWRvbmx5TWV0aG9kKFwiY2xlYXJcIiksXG4gIGZvckVhY2g6IGNyZWF0ZUZvckVhY2godHJ1ZSwgZmFsc2UpXG59O1xudmFyIHNoYWxsb3dSZWFkb25seUluc3RydW1lbnRhdGlvbnMgPSB7XG4gIGdldChrZXkpIHtcbiAgICByZXR1cm4gZ2V0JDEodGhpcywga2V5LCB0cnVlLCB0cnVlKTtcbiAgfSxcbiAgZ2V0IHNpemUoKSB7XG4gICAgcmV0dXJuIHNpemUodGhpcywgdHJ1ZSk7XG4gIH0sXG4gIGhhcyhrZXkpIHtcbiAgICByZXR1cm4gaGFzJDEuY2FsbCh0aGlzLCBrZXksIHRydWUpO1xuICB9LFxuICBhZGQ6IGNyZWF0ZVJlYWRvbmx5TWV0aG9kKFwiYWRkXCIpLFxuICBzZXQ6IGNyZWF0ZVJlYWRvbmx5TWV0aG9kKFwic2V0XCIpLFxuICBkZWxldGU6IGNyZWF0ZVJlYWRvbmx5TWV0aG9kKFwiZGVsZXRlXCIpLFxuICBjbGVhcjogY3JlYXRlUmVhZG9ubHlNZXRob2QoXCJjbGVhclwiKSxcbiAgZm9yRWFjaDogY3JlYXRlRm9yRWFjaCh0cnVlLCB0cnVlKVxufTtcbnZhciBpdGVyYXRvck1ldGhvZHMgPSBbXCJrZXlzXCIsIFwidmFsdWVzXCIsIFwiZW50cmllc1wiLCBTeW1ib2wuaXRlcmF0b3JdO1xuaXRlcmF0b3JNZXRob2RzLmZvckVhY2goKG1ldGhvZCkgPT4ge1xuICBtdXRhYmxlSW5zdHJ1bWVudGF0aW9uc1ttZXRob2RdID0gY3JlYXRlSXRlcmFibGVNZXRob2QobWV0aG9kLCBmYWxzZSwgZmFsc2UpO1xuICByZWFkb25seUluc3RydW1lbnRhdGlvbnNbbWV0aG9kXSA9IGNyZWF0ZUl0ZXJhYmxlTWV0aG9kKG1ldGhvZCwgdHJ1ZSwgZmFsc2UpO1xuICBzaGFsbG93SW5zdHJ1bWVudGF0aW9uc1ttZXRob2RdID0gY3JlYXRlSXRlcmFibGVNZXRob2QobWV0aG9kLCBmYWxzZSwgdHJ1ZSk7XG4gIHNoYWxsb3dSZWFkb25seUluc3RydW1lbnRhdGlvbnNbbWV0aG9kXSA9IGNyZWF0ZUl0ZXJhYmxlTWV0aG9kKG1ldGhvZCwgdHJ1ZSwgdHJ1ZSk7XG59KTtcbmZ1bmN0aW9uIGNyZWF0ZUluc3RydW1lbnRhdGlvbkdldHRlcihpc1JlYWRvbmx5LCBzaGFsbG93KSB7XG4gIGNvbnN0IGluc3RydW1lbnRhdGlvbnMgPSBzaGFsbG93ID8gaXNSZWFkb25seSA/IHNoYWxsb3dSZWFkb25seUluc3RydW1lbnRhdGlvbnMgOiBzaGFsbG93SW5zdHJ1bWVudGF0aW9ucyA6IGlzUmVhZG9ubHkgPyByZWFkb25seUluc3RydW1lbnRhdGlvbnMgOiBtdXRhYmxlSW5zdHJ1bWVudGF0aW9ucztcbiAgcmV0dXJuICh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpID0+IHtcbiAgICBpZiAoa2V5ID09PSBcIl9fdl9pc1JlYWN0aXZlXCIpIHtcbiAgICAgIHJldHVybiAhaXNSZWFkb25seTtcbiAgICB9IGVsc2UgaWYgKGtleSA9PT0gXCJfX3ZfaXNSZWFkb25seVwiKSB7XG4gICAgICByZXR1cm4gaXNSZWFkb25seTtcbiAgICB9IGVsc2UgaWYgKGtleSA9PT0gXCJfX3ZfcmF3XCIpIHtcbiAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuICAgIHJldHVybiBSZWZsZWN0LmdldChoYXNPd24oaW5zdHJ1bWVudGF0aW9ucywga2V5KSAmJiBrZXkgaW4gdGFyZ2V0ID8gaW5zdHJ1bWVudGF0aW9ucyA6IHRhcmdldCwga2V5LCByZWNlaXZlcik7XG4gIH07XG59XG52YXIgbXV0YWJsZUNvbGxlY3Rpb25IYW5kbGVycyA9IHtcbiAgZ2V0OiBjcmVhdGVJbnN0cnVtZW50YXRpb25HZXR0ZXIoZmFsc2UsIGZhbHNlKVxufTtcbnZhciBzaGFsbG93Q29sbGVjdGlvbkhhbmRsZXJzID0ge1xuICBnZXQ6IGNyZWF0ZUluc3RydW1lbnRhdGlvbkdldHRlcihmYWxzZSwgdHJ1ZSlcbn07XG52YXIgcmVhZG9ubHlDb2xsZWN0aW9uSGFuZGxlcnMgPSB7XG4gIGdldDogY3JlYXRlSW5zdHJ1bWVudGF0aW9uR2V0dGVyKHRydWUsIGZhbHNlKVxufTtcbnZhciBzaGFsbG93UmVhZG9ubHlDb2xsZWN0aW9uSGFuZGxlcnMgPSB7XG4gIGdldDogY3JlYXRlSW5zdHJ1bWVudGF0aW9uR2V0dGVyKHRydWUsIHRydWUpXG59O1xuZnVuY3Rpb24gY2hlY2tJZGVudGl0eUtleXModGFyZ2V0LCBoYXMyLCBrZXkpIHtcbiAgY29uc3QgcmF3S2V5ID0gdG9SYXcoa2V5KTtcbiAgaWYgKHJhd0tleSAhPT0ga2V5ICYmIGhhczIuY2FsbCh0YXJnZXQsIHJhd0tleSkpIHtcbiAgICBjb25zdCB0eXBlID0gdG9SYXdUeXBlKHRhcmdldCk7XG4gICAgY29uc29sZS53YXJuKGBSZWFjdGl2ZSAke3R5cGV9IGNvbnRhaW5zIGJvdGggdGhlIHJhdyBhbmQgcmVhY3RpdmUgdmVyc2lvbnMgb2YgdGhlIHNhbWUgb2JqZWN0JHt0eXBlID09PSBgTWFwYCA/IGAgYXMga2V5c2AgOiBgYH0sIHdoaWNoIGNhbiBsZWFkIHRvIGluY29uc2lzdGVuY2llcy4gQXZvaWQgZGlmZmVyZW50aWF0aW5nIGJldHdlZW4gdGhlIHJhdyBhbmQgcmVhY3RpdmUgdmVyc2lvbnMgb2YgYW4gb2JqZWN0IGFuZCBvbmx5IHVzZSB0aGUgcmVhY3RpdmUgdmVyc2lvbiBpZiBwb3NzaWJsZS5gKTtcbiAgfVxufVxudmFyIHJlYWN0aXZlTWFwID0gbmV3IFdlYWtNYXAoKTtcbnZhciBzaGFsbG93UmVhY3RpdmVNYXAgPSBuZXcgV2Vha01hcCgpO1xudmFyIHJlYWRvbmx5TWFwID0gbmV3IFdlYWtNYXAoKTtcbnZhciBzaGFsbG93UmVhZG9ubHlNYXAgPSBuZXcgV2Vha01hcCgpO1xuZnVuY3Rpb24gdGFyZ2V0VHlwZU1hcChyYXdUeXBlKSB7XG4gIHN3aXRjaCAocmF3VHlwZSkge1xuICAgIGNhc2UgXCJPYmplY3RcIjpcbiAgICBjYXNlIFwiQXJyYXlcIjpcbiAgICAgIHJldHVybiAxO1xuICAgIGNhc2UgXCJNYXBcIjpcbiAgICBjYXNlIFwiU2V0XCI6XG4gICAgY2FzZSBcIldlYWtNYXBcIjpcbiAgICBjYXNlIFwiV2Vha1NldFwiOlxuICAgICAgcmV0dXJuIDI7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiAwO1xuICB9XG59XG5mdW5jdGlvbiBnZXRUYXJnZXRUeXBlKHZhbHVlKSB7XG4gIHJldHVybi
1B2YWx1ZVtcIl9fdl9za2lwXCJdIHx8ICFPYmplY3QuaXNFeHRlbnNpYmxlKHZhbHVlKSA/IDAgOiB0YXJnZXRUeXBlTWFwKHRvUmF3VHlwZSh2YWx1ZSkpO1xufVxuZnVuY3Rpb24gcmVhY3RpdmUyKHRhcmdldCkge1xuICBpZiAodGFyZ2V0ICYmIHRhcmdldFtcIl9fdl9pc1JlYWRvbmx5XCJdKSB7XG4gICAgcmV0dXJuIHRhcmdldDtcbiAgfVxuICByZXR1cm4gY3JlYXRlUmVhY3RpdmVPYmplY3QodGFyZ2V0LCBmYWxzZSwgbXV0YWJsZUhhbmRsZXJzLCBtdXRhYmxlQ29sbGVjdGlvbkhhbmRsZXJzLCByZWFjdGl2ZU1hcCk7XG59XG5mdW5jdGlvbiByZWFkb25seSh0YXJnZXQpIHtcbiAgcmV0dXJuIGNyZWF0ZVJlYWN0aXZlT2JqZWN0KHRhcmdldCwgdHJ1ZSwgcmVhZG9ubHlIYW5kbGVycywgcmVhZG9ubHlDb2xsZWN0aW9uSGFuZGxlcnMsIHJlYWRvbmx5TWFwKTtcbn1cbmZ1bmN0aW9uIGNyZWF0ZVJlYWN0aXZlT2JqZWN0KHRhcmdldCwgaXNSZWFkb25seSwgYmFzZUhhbmRsZXJzLCBjb2xsZWN0aW9uSGFuZGxlcnMsIHByb3h5TWFwKSB7XG4gIGlmICghaXNPYmplY3QodGFyZ2V0KSkge1xuICAgIGlmICh0cnVlKSB7XG4gICAgICBjb25zb2xlLndhcm4oYHZhbHVlIGNhbm5vdCBiZSBtYWRlIHJlYWN0aXZlOiAke1N0cmluZyh0YXJnZXQpfWApO1xuICAgIH1cbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9XG4gIGlmICh0YXJnZXRbXCJfX3ZfcmF3XCJdICYmICEoaXNSZWFkb25seSAmJiB0YXJnZXRbXCJfX3ZfaXNSZWFjdGl2ZVwiXSkpIHtcbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9XG4gIGNvbnN0IGV4aXN0aW5nUHJveHkgPSBwcm94eU1hcC5nZXQodGFyZ2V0KTtcbiAgaWYgKGV4aXN0aW5nUHJveHkpIHtcbiAgICByZXR1cm4gZXhpc3RpbmdQcm94eTtcbiAgfVxuICBjb25zdCB0YXJnZXRUeXBlID0gZ2V0VGFyZ2V0VHlwZSh0YXJnZXQpO1xuICBpZiAodGFyZ2V0VHlwZSA9PT0gMCkge1xuICAgIHJldHVybiB0YXJnZXQ7XG4gIH1cbiAgY29uc3QgcHJveHkgPSBuZXcgUHJveHkodGFyZ2V0LCB0YXJnZXRUeXBlID09PSAyID8gY29sbGVjdGlvbkhhbmRsZXJzIDogYmFzZUhhbmRsZXJzKTtcbiAgcHJveHlNYXAuc2V0KHRhcmdldCwgcHJveHkpO1xuICByZXR1cm4gcHJveHk7XG59XG5mdW5jdGlvbiB0b1JhdyhvYnNlcnZlZCkge1xuICByZXR1cm4gb2JzZXJ2ZWQgJiYgdG9SYXcob2JzZXJ2ZWRbXCJfX3ZfcmF3XCJdKSB8fCBvYnNlcnZlZDtcbn1cbmZ1bmN0aW9uIGlzUmVmKHIpIHtcbiAgcmV0dXJuIEJvb2xlYW4ociAmJiByLl9fdl9pc1JlZiA9PT0gdHJ1ZSk7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9tYWdpY3MvJG5leHRUaWNrLmpzXG5tYWdpYyhcIm5leHRUaWNrXCIsICgpID0+IG5leHRUaWNrKTtcblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL21hZ2ljcy8kZGlzcGF0Y2guanNcbm1hZ2ljKFwiZGlzcGF0Y2hcIiwgKGVsKSA9PiBkaXNwYXRjaC5iaW5kKGRpc3BhdGNoLCBlbCkpO1xuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvbWFnaWNzLyR3YXRjaC5qc1xubWFnaWMoXCJ3YXRjaFwiLCAoZWwsIHtldmFsdWF0ZUxhdGVyOiBldmFsdWF0ZUxhdGVyMiwgZWZmZWN0OiBlZmZlY3QzfSkgPT4gKGtleSwgY2FsbGJhY2spID0+IHtcbiAgbGV0IGV2YWx1YXRlMiA9IGV2YWx1YXRlTGF0ZXIyKGtleSk7XG4gIGxldCBmaXJzdFRpbWUgPSB0cnVlO1xuICBsZXQgb2xkVmFsdWU7XG4gIGxldCBlZmZlY3RSZWZlcmVuY2UgPSBlZmZlY3QzKCgpID0+IGV2YWx1YXRlMigodmFsdWUpID0+IHtcbiAgICBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG4gICAgaWYgKCFmaXJzdFRpbWUpIHtcbiAgICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICAgICAgY2FsbGJhY2sodmFsdWUsIG9sZFZhbHVlKTtcbiAgICAgICAgb2xkVmFsdWUgPSB2YWx1ZTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBvbGRWYWx1ZSA9IHZhbHVlO1xuICAgIH1cbiAgICBmaXJzdFRpbWUgPSBmYWxzZTtcbiAgfSkpO1xuICBlbC5feF9lZmZlY3RzLmRlbGV0ZShlZmZlY3RSZWZlcmVuY2UpO1xufSk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9tYWdpY3MvJHN0b3JlLmpzXG5tYWdpYyhcInN0b3JlXCIsIGdldFN0b3Jlcyk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9tYWdpY3MvJGRhdGEuanNcbm1hZ2ljKFwiZGF0YVwiLCAoZWwpID0+IHNjb3BlKGVsKSk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9tYWdpY3MvJHJvb3QuanNcbm1hZ2ljKFwicm9vdFwiLCAoZWwpID0+IGNsb3Nlc3RSb290KGVsKSk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9tYWdpY3MvJHJlZnMuanNcbm1hZ2ljKFwicmVmc1wiLCAoZWwpID0+IHtcbiAgaWYgKGVsLl94X3JlZnNfcHJveHkpXG4gICAgcmV0dXJuIGVsLl94X3JlZnNfcHJveHk7XG4gIGVsLl94X3JlZnNfcHJveHkgPSBtZXJnZVByb3hpZXMoZ2V0QXJyYXlPZlJlZk9iamVjdChlbCkpO1xuICByZXR1cm4gZWwuX3hfcmVmc19wcm94eTtcbn0pO1xuZnVuY3Rpb24gZ2V0QXJyYXlPZlJlZk9iamVjdChlbCkge1xuICBsZXQgcmVmT2JqZWN0cyA9IFtdO1xuICBsZXQgY3VycmVudEVsID0gZWw7XG4gIHdoaWxlIChjdXJyZW50RWwpIHtcbiAgICBpZiAoY3VycmVudEVsLl94X3JlZnMpXG4gICAgICByZWZPYmplY3RzLnB1c2goY3VycmVudEVsLl94X3JlZnMpO1xuICAgIGN1cnJlbnRFbCA9IGN1cnJlbnRFbC5wYXJlbnROb2RlO1xuICB9XG4gIHJldHVybiByZWZPYmplY3RzO1xufVxuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvaWRzLmpzXG52YXIgZ2xvYmFsSWRNZW1vID0ge307XG5mdW5jdGlvbiBmaW5kQW5kSW5jcmVtZW50SWQobmFtZSkge1xuICBpZiAoIWdsb2JhbElkTWVtb1tuYW1lXSlcbiAgICBnbG9iYWxJZE1lbW9bbmFtZV0gPSAwO1xuICByZXR1cm4gKytnbG9iYWxJZE1lbW9bbmFtZV07XG59XG5mdW5jdGlvbiBjbG9zZXN0SWRSb290KGVsLCBuYW1lKSB7XG4gIHJldHVybiBmaW5kQ2xvc2VzdChlbCwgKGVsZW1lbnQpID0+IHtcbiAgICBpZiAoZWxlbWVudC5feF9pZHMgJiYgZWxlbWVudC5feF9pZHNbbmFtZV0pXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgfSk7XG59XG5mdW5jdGlvbiBzZXRJZFJvb3QoZWwsIG5hbW
1UpIHtcbiAgaWYgKCFlbC5feF9pZHMpXG4gICAgZWwuX3hfaWRzID0ge307XG4gIGlmICghZWwuX3hfaWRzW25hbWVdKVxuICAgIGVsLl94X2lkc1tuYW1lXSA9IGZpbmRBbmRJbmNyZW1lbnRJZChuYW1lKTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL21hZ2ljcy8kaWQuanNcbm1hZ2ljKFwiaWRcIiwgKGVsKSA9PiAobmFtZSwga2V5ID0gbnVsbCkgPT4ge1xuICBsZXQgcm9vdCA9IGNsb3Nlc3RJZFJvb3QoZWwsIG5hbWUpO1xuICBsZXQgaWQgPSByb290ID8gcm9vdC5feF9pZHNbbmFtZV0gOiBmaW5kQW5kSW5jcmVtZW50SWQobmFtZSk7XG4gIHJldHVybiBrZXkgPyBgJHtuYW1lfS0ke2lkfS0ke2tleX1gIDogYCR7bmFtZX0tJHtpZH1gO1xufSk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9tYWdpY3MvJGVsLmpzXG5tYWdpYyhcImVsXCIsIChlbCkgPT4gZWwpO1xuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvbWFnaWNzL2luZGV4LmpzXG53YXJuTWlzc2luZ1BsdWdpbk1hZ2ljKFwiRm9jdXNcIiwgXCJmb2N1c1wiLCBcImZvY3VzXCIpO1xud2Fybk1pc3NpbmdQbHVnaW5NYWdpYyhcIlBlcnNpc3RcIiwgXCJwZXJzaXN0XCIsIFwicGVyc2lzdFwiKTtcbmZ1bmN0aW9uIHdhcm5NaXNzaW5nUGx1Z2luTWFnaWMobmFtZSwgbWFnaWNOYW1lLCBzbHVnKSB7XG4gIG1hZ2ljKG1hZ2ljTmFtZSwgKGVsKSA9PiB3YXJuKGBZb3UgY2FuJ3QgdXNlIFskJHtkaXJlY3RpdmVOYW1lfV0gd2l0aG91dCBmaXJzdCBpbnN0YWxsaW5nIHRoZSBcIiR7bmFtZX1cIiBwbHVnaW4gaGVyZTogaHR0cHM6Ly9hbHBpbmVqcy5kZXYvcGx1Z2lucy8ke3NsdWd9YCwgZWwpKTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2VudGFuZ2xlLmpzXG5mdW5jdGlvbiBlbnRhbmdsZSh7Z2V0OiBvdXRlckdldCwgc2V0OiBvdXRlclNldH0sIHtnZXQ6IGlubmVyR2V0LCBzZXQ6IGlubmVyU2V0fSkge1xuICBsZXQgZmlyc3RSdW4gPSB0cnVlO1xuICBsZXQgb3V0ZXJIYXNoLCBpbm5lckhhc2gsIG91dGVySGFzaExhdGVzdCwgaW5uZXJIYXNoTGF0ZXN0O1xuICBsZXQgcmVmZXJlbmNlID0gZWZmZWN0KCgpID0+IHtcbiAgICBsZXQgb3V0ZXIsIGlubmVyO1xuICAgIGlmIChmaXJzdFJ1bikge1xuICAgICAgb3V0ZXIgPSBvdXRlckdldCgpO1xuICAgICAgaW5uZXJTZXQob3V0ZXIpO1xuICAgICAgaW5uZXIgPSBpbm5lckdldCgpO1xuICAgICAgZmlyc3RSdW4gPSBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0ZXIgPSBvdXRlckdldCgpO1xuICAgICAgaW5uZXIgPSBpbm5lckdldCgpO1xuICAgICAgb3V0ZXJIYXNoTGF0ZXN0ID0gSlNPTi5zdHJpbmdpZnkob3V0ZXIpO1xuICAgICAgaW5uZXJIYXNoTGF0ZXN0ID0gSlNPTi5zdHJpbmdpZnkoaW5uZXIpO1xuICAgICAgaWYgKG91dGVySGFzaExhdGVzdCAhPT0gb3V0ZXJIYXNoKSB7XG4gICAgICAgIGlubmVyID0gaW5uZXJHZXQoKTtcbiAgICAgICAgaW5uZXJTZXQob3V0ZXIpO1xuICAgICAgICBpbm5lciA9IG91dGVyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0ZXJTZXQoaW5uZXIpO1xuICAgICAgICBvdXRlciA9IGlubmVyO1xuICAgICAgfVxuICAgIH1cbiAgICBvdXRlckhhc2ggPSBKU09OLnN0cmluZ2lmeShvdXRlcik7XG4gICAgaW5uZXJIYXNoID0gSlNPTi5zdHJpbmdpZnkoaW5uZXIpO1xuICB9KTtcbiAgcmV0dXJuICgpID0+IHtcbiAgICByZWxlYXNlKHJlZmVyZW5jZSk7XG4gIH07XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL3gtbW9kZWxhYmxlLmpzXG5kaXJlY3RpdmUoXCJtb2RlbGFibGVcIiwgKGVsLCB7ZXhwcmVzc2lvbn0sIHtlZmZlY3Q6IGVmZmVjdDMsIGV2YWx1YXRlTGF0ZXI6IGV2YWx1YXRlTGF0ZXIyLCBjbGVhbnVwOiBjbGVhbnVwMn0pID0+IHtcbiAgbGV0IGZ1bmMgPSBldmFsdWF0ZUxhdGVyMihleHByZXNzaW9uKTtcbiAgbGV0IGlubmVyR2V0ID0gKCkgPT4ge1xuICAgIGxldCByZXN1bHQ7XG4gICAgZnVuYygoaSkgPT4gcmVzdWx0ID0gaSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcbiAgbGV0IGV2YWx1YXRlSW5uZXJTZXQgPSBldmFsdWF0ZUxhdGVyMihgJHtleHByZXNzaW9ufSA9IF9fcGxhY2Vob2xkZXJgKTtcbiAgbGV0IGlubmVyU2V0ID0gKHZhbCkgPT4gZXZhbHVhdGVJbm5lclNldCgoKSA9PiB7XG4gIH0sIHtzY29wZToge19fcGxhY2Vob2xkZXI6IHZhbH19KTtcbiAgbGV0IGluaXRpYWxWYWx1ZSA9IGlubmVyR2V0KCk7XG4gIGlubmVyU2V0KGluaXRpYWxWYWx1ZSk7XG4gIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICBpZiAoIWVsLl94X21vZGVsKVxuICAgICAgcmV0dXJuO1xuICAgIGVsLl94X3JlbW92ZU1vZGVsTGlzdGVuZXJzW1wiZGVmYXVsdFwiXSgpO1xuICAgIGxldCBvdXRlckdldCA9IGVsLl94X21vZGVsLmdldDtcbiAgICBsZXQgb3V0ZXJTZXQgPSBlbC5feF9tb2RlbC5zZXQ7XG4gICAgbGV0IHJlbGVhc2VFbnRhbmdsZW1lbnQgPSBlbnRhbmdsZSh7XG4gICAgICBnZXQoKSB7XG4gICAgICAgIHJldHVybiBvdXRlckdldCgpO1xuICAgICAgfSxcbiAgICAgIHNldCh2YWx1ZSkge1xuICAgICAgICBvdXRlclNldCh2YWx1ZSk7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAgZ2V0KCkge1xuICAgICAgICByZXR1cm4gaW5uZXJHZXQoKTtcbiAgICAgIH0sXG4gICAgICBzZXQodmFsdWUpIHtcbiAgICAgICAgaW5uZXJTZXQodmFsdWUpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGNsZWFudXAyKHJlbGVhc2VFbnRhbmdsZW1lbnQpO1xuICB9KTtcbn0pO1xuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvZGlyZWN0aXZlcy94LXRlbGVwb3J0LmpzXG52YXIgdGVsZXBvcnRDb250YWluZXJEdXJpbmdDbG9uZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5kaXJlY3RpdmUoXCJ0ZWxlcG9ydFwiLCAoZWwsIHttb2RpZmllcnMsIGV4cHJlc3Npb259LCB7Y2xlYW51cDogY2xlYW51cDJ9KSA9PiB7XG4gIGlmIChlbC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgIT09IFwidGVtcGxhdGVcIilcbiAgICB3YXJuKFwieC10ZWxlcG9ydCBjYW4gb25seSBiZSB1c2VkIG9uIGEgPHRlbXBsYXRlPiB0YWdcIiwgZWwpO1xuICBsZXQgdGFyZ2V0ID0gc2tpcER1cmluZ0Nsb25lKCgpID0+IHtcbiAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihleHByZXNzaW9uKTtcbiAgfSwgKCkgPT4ge1xuICAgIHJldHVybi
1B0ZWxlcG9ydENvbnRhaW5lckR1cmluZ0Nsb25lO1xuICB9KSgpO1xuICBpZiAoIXRhcmdldClcbiAgICB3YXJuKGBDYW5ub3QgZmluZCB4LXRlbGVwb3J0IGVsZW1lbnQgZm9yIHNlbGVjdG9yOiBcIiR7ZXhwcmVzc2lvbn1cImApO1xuICBsZXQgY2xvbmUyID0gZWwuY29udGVudC5jbG9uZU5vZGUodHJ1ZSkuZmlyc3RFbGVtZW50Q2hpbGQ7XG4gIGVsLl94X3RlbGVwb3J0ID0gY2xvbmUyO1xuICBjbG9uZTIuX3hfdGVsZXBvcnRCYWNrID0gZWw7XG4gIGlmIChlbC5feF9mb3J3YXJkRXZlbnRzKSB7XG4gICAgZWwuX3hfZm9yd2FyZEV2ZW50cy5mb3JFYWNoKChldmVudE5hbWUpID0+IHtcbiAgICAgIGNsb25lMi5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgKGUpID0+IHtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgZWwuZGlzcGF0Y2hFdmVudChuZXcgZS5jb25zdHJ1Y3RvcihlLnR5cGUsIGUpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIGFkZFNjb3BlVG9Ob2RlKGNsb25lMiwge30sIGVsKTtcbiAgbXV0YXRlRG9tKCgpID0+IHtcbiAgICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwicHJlcGVuZFwiKSkge1xuICAgICAgdGFyZ2V0LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGNsb25lMiwgdGFyZ2V0KTtcbiAgICB9IGVsc2UgaWYgKG1vZGlmaWVycy5pbmNsdWRlcyhcImFwcGVuZFwiKSkge1xuICAgICAgdGFyZ2V0LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGNsb25lMiwgdGFyZ2V0Lm5leHRTaWJsaW5nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGFyZ2V0LmFwcGVuZENoaWxkKGNsb25lMik7XG4gICAgfVxuICAgIGluaXRUcmVlKGNsb25lMik7XG4gICAgY2xvbmUyLl94X2lnbm9yZSA9IHRydWU7XG4gIH0pO1xuICBjbGVhbnVwMigoKSA9PiBjbG9uZTIucmVtb3ZlKCkpO1xufSk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL3gtaWdub3JlLmpzXG52YXIgaGFuZGxlciA9ICgpID0+IHtcbn07XG5oYW5kbGVyLmlubGluZSA9IChlbCwge21vZGlmaWVyc30sIHtjbGVhbnVwOiBjbGVhbnVwMn0pID0+IHtcbiAgbW9kaWZpZXJzLmluY2x1ZGVzKFwic2VsZlwiKSA/IGVsLl94X2lnbm9yZVNlbGYgPSB0cnVlIDogZWwuX3hfaWdub3JlID0gdHJ1ZTtcbiAgY2xlYW51cDIoKCkgPT4ge1xuICAgIG1vZGlmaWVycy5pbmNsdWRlcyhcInNlbGZcIikgPyBkZWxldGUgZWwuX3hfaWdub3JlU2VsZiA6IGRlbGV0ZSBlbC5feF9pZ25vcmU7XG4gIH0pO1xufTtcbmRpcmVjdGl2ZShcImlnbm9yZVwiLCBoYW5kbGVyKTtcblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2RpcmVjdGl2ZXMveC1lZmZlY3QuanNcbmRpcmVjdGl2ZShcImVmZmVjdFwiLCAoZWwsIHtleHByZXNzaW9ufSwge2VmZmVjdDogZWZmZWN0M30pID0+IGVmZmVjdDMoZXZhbHVhdGVMYXRlcihlbCwgZXhwcmVzc2lvbikpKTtcblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL3V0aWxzL29uLmpzXG5mdW5jdGlvbiBvbihlbCwgZXZlbnQsIG1vZGlmaWVycywgY2FsbGJhY2spIHtcbiAgbGV0IGxpc3RlbmVyVGFyZ2V0ID0gZWw7XG4gIGxldCBoYW5kbGVyNCA9IChlKSA9PiBjYWxsYmFjayhlKTtcbiAgbGV0IG9wdGlvbnMgPSB7fTtcbiAgbGV0IHdyYXBIYW5kbGVyID0gKGNhbGxiYWNrMiwgd3JhcHBlcikgPT4gKGUpID0+IHdyYXBwZXIoY2FsbGJhY2syLCBlKTtcbiAgaWYgKG1vZGlmaWVycy5pbmNsdWRlcyhcImRvdFwiKSlcbiAgICBldmVudCA9IGRvdFN5bnRheChldmVudCk7XG4gIGlmIChtb2RpZmllcnMuaW5jbHVkZXMoXCJjYW1lbFwiKSlcbiAgICBldmVudCA9IGNhbWVsQ2FzZTIoZXZlbnQpO1xuICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwicGFzc2l2ZVwiKSlcbiAgICBvcHRpb25zLnBhc3NpdmUgPSB0cnVlO1xuICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwiY2FwdHVyZVwiKSlcbiAgICBvcHRpb25zLmNhcHR1cmUgPSB0cnVlO1xuICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwid2luZG93XCIpKVxuICAgIGxpc3RlbmVyVGFyZ2V0ID0gd2luZG93O1xuICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwiZG9jdW1lbnRcIikpXG4gICAgbGlzdGVuZXJUYXJnZXQgPSBkb2N1bWVudDtcbiAgaWYgKG1vZGlmaWVycy5pbmNsdWRlcyhcImRlYm91bmNlXCIpKSB7XG4gICAgbGV0IG5leHRNb2RpZmllciA9IG1vZGlmaWVyc1ttb2RpZmllcnMuaW5kZXhPZihcImRlYm91bmNlXCIpICsgMV0gfHwgXCJpbnZhbGlkLXdhaXRcIjtcbiAgICBsZXQgd2FpdCA9IGlzTnVtZXJpYyhuZXh0TW9kaWZpZXIuc3BsaXQoXCJtc1wiKVswXSkgPyBOdW1iZXIobmV4dE1vZGlmaWVyLnNwbGl0KFwibXNcIilbMF0pIDogMjUwO1xuICAgIGhhbmRsZXI0ID0gZGVib3VuY2UoaGFuZGxlcjQsIHdhaXQpO1xuICB9XG4gIGlmIChtb2RpZmllcnMuaW5jbHVkZXMoXCJ0aHJvdHRsZVwiKSkge1xuICAgIGxldCBuZXh0TW9kaWZpZXIgPSBtb2RpZmllcnNbbW9kaWZpZXJzLmluZGV4T2YoXCJ0aHJvdHRsZVwiKSArIDFdIHx8IFwiaW52YWxpZC13YWl0XCI7XG4gICAgbGV0IHdhaXQgPSBpc051bWVyaWMobmV4dE1vZGlmaWVyLnNwbGl0KFwibXNcIilbMF0pID8gTnVtYmVyKG5leHRNb2RpZmllci5zcGxpdChcIm1zXCIpWzBdKSA6IDI1MDtcbiAgICBoYW5kbGVyNCA9IHRocm90dGxlKGhhbmRsZXI0LCB3YWl0KTtcbiAgfVxuICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwicHJldmVudFwiKSlcbiAgICBoYW5kbGVyNCA9IHdyYXBIYW5kbGVyKGhhbmRsZXI0LCAobmV4dCwgZSkgPT4ge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgbmV4dChlKTtcbiAgICB9KTtcbiAgaWYgKG1vZGlmaWVycy5pbmNsdWRlcyhcInN0b3BcIikpXG4gICAgaGFuZGxlcjQgPSB3cmFwSGFuZGxlcihoYW5kbGVyNCwgKG5leHQsIGUpID0+IHtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBuZXh0KGUpO1xuICAgIH0pO1xuICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwic2VsZlwiKSlcbiAgICBoYW5kbGVyNCA9IHdyYXBIYW5kbGVyKGhhbmRsZXI0LCAobmV4dCwgZSkgPT4ge1xuICAgICAgZS50YXJnZXQgPT09IGVsICYmIG5leHQoZSk7XG4gICAgfSk7XG4gIGlmIChtb2RpZmllcnMuaW5jbHVkZXMoXCJhd2F5XCIpIHx8IG1vZGlmaWVycy5pbmNsdWRlcyhcIm91dHNpZGVcIikpIHtcbiAgICBsaXN0ZW5lclRhcmdldCA9IGRvY3VtZW50O1xuICAgIGhhbmRsZXI0ID0gd3JhcEhhbmRsZXIoaGFuZGxlcjQsIChuZXh0LCBlKSA9PiB7XG4gICAgICBpZiAoZWwuY29udGFpbnMoZS50YXJnZXQpKVxuICAgICAgICByZXR1cm47XG4gICAgICBpZiAoZS50YXJnZXQuaXNDb25uZWN0ZWQgPT09IGZhbHNlKVxuICAgICAgICByZXR1cm47XG4gICAgICBpZiAoZWwub2Zmc2V0V2lkdGggPCAxICYmIGVsLm9mZnNldEhlaWdodCA8IDEpXG4gICAgICAgI
1HJldHVybjtcbiAgICAgIGlmIChlbC5feF9pc1Nob3duID09PSBmYWxzZSlcbiAgICAgICAgcmV0dXJuO1xuICAgICAgbmV4dChlKTtcbiAgICB9KTtcbiAgfVxuICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwib25jZVwiKSkge1xuICAgIGhhbmRsZXI0ID0gd3JhcEhhbmRsZXIoaGFuZGxlcjQsIChuZXh0LCBlKSA9PiB7XG4gICAgICBuZXh0KGUpO1xuICAgICAgbGlzdGVuZXJUYXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudCwgaGFuZGxlcjQsIG9wdGlvbnMpO1xuICAgIH0pO1xuICB9XG4gIGhhbmRsZXI0ID0gd3JhcEhhbmRsZXIoaGFuZGxlcjQsIChuZXh0LCBlKSA9PiB7XG4gICAgaWYgKGlzS2V5RXZlbnQoZXZlbnQpKSB7XG4gICAgICBpZiAoaXNMaXN0ZW5pbmdGb3JBU3BlY2lmaWNLZXlUaGF0SGFzbnRCZWVuUHJlc3NlZChlLCBtb2RpZmllcnMpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gICAgbmV4dChlKTtcbiAgfSk7XG4gIGxpc3RlbmVyVGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIGhhbmRsZXI0LCBvcHRpb25zKTtcbiAgcmV0dXJuICgpID0+IHtcbiAgICBsaXN0ZW5lclRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50LCBoYW5kbGVyNCwgb3B0aW9ucyk7XG4gIH07XG59XG5mdW5jdGlvbiBkb3RTeW50YXgoc3ViamVjdCkge1xuICByZXR1cm4gc3ViamVjdC5yZXBsYWNlKC8tL2csIFwiLlwiKTtcbn1cbmZ1bmN0aW9uIGNhbWVsQ2FzZTIoc3ViamVjdCkge1xuICByZXR1cm4gc3ViamVjdC50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoLy0oXFx3KS9nLCAobWF0Y2gsIGNoYXIpID0+IGNoYXIudG9VcHBlckNhc2UoKSk7XG59XG5mdW5jdGlvbiBpc051bWVyaWMoc3ViamVjdCkge1xuICByZXR1cm4gIUFycmF5LmlzQXJyYXkoc3ViamVjdCkgJiYgIWlzTmFOKHN1YmplY3QpO1xufVxuZnVuY3Rpb24ga2ViYWJDYXNlMihzdWJqZWN0KSB7XG4gIGlmIChbXCIgXCIsIFwiX1wiXS5pbmNsdWRlcyhzdWJqZWN0KSlcbiAgICByZXR1cm4gc3ViamVjdDtcbiAgcmV0dXJuIHN1YmplY3QucmVwbGFjZSgvKFthLXpdKShbQS1aXSkvZywgXCIkMS0kMlwiKS5yZXBsYWNlKC9bX1xcc10vLCBcIi1cIikudG9Mb3dlckNhc2UoKTtcbn1cbmZ1bmN0aW9uIGlzS2V5RXZlbnQoZXZlbnQpIHtcbiAgcmV0dXJuIFtcImtleWRvd25cIiwgXCJrZXl1cFwiXS5pbmNsdWRlcyhldmVudCk7XG59XG5mdW5jdGlvbiBpc0xpc3RlbmluZ0ZvckFTcGVjaWZpY0tleVRoYXRIYXNudEJlZW5QcmVzc2VkKGUsIG1vZGlmaWVycykge1xuICBsZXQga2V5TW9kaWZpZXJzID0gbW9kaWZpZXJzLmZpbHRlcigoaSkgPT4ge1xuICAgIHJldHVybiAhW1wid2luZG93XCIsIFwiZG9jdW1lbnRcIiwgXCJwcmV2ZW50XCIsIFwic3RvcFwiLCBcIm9uY2VcIiwgXCJjYXB0dXJlXCJdLmluY2x1ZGVzKGkpO1xuICB9KTtcbiAgaWYgKGtleU1vZGlmaWVycy5pbmNsdWRlcyhcImRlYm91bmNlXCIpKSB7XG4gICAgbGV0IGRlYm91bmNlSW5kZXggPSBrZXlNb2RpZmllcnMuaW5kZXhPZihcImRlYm91bmNlXCIpO1xuICAgIGtleU1vZGlmaWVycy5zcGxpY2UoZGVib3VuY2VJbmRleCwgaXNOdW1lcmljKChrZXlNb2RpZmllcnNbZGVib3VuY2VJbmRleCArIDFdIHx8IFwiaW52YWxpZC13YWl0XCIpLnNwbGl0KFwibXNcIilbMF0pID8gMiA6IDEpO1xuICB9XG4gIGlmIChrZXlNb2RpZmllcnMuaW5jbHVkZXMoXCJ0aHJvdHRsZVwiKSkge1xuICAgIGxldCBkZWJvdW5jZUluZGV4ID0ga2V5TW9kaWZpZXJzLmluZGV4T2YoXCJ0aHJvdHRsZVwiKTtcbiAgICBrZXlNb2RpZmllcnMuc3BsaWNlKGRlYm91bmNlSW5kZXgsIGlzTnVtZXJpYygoa2V5TW9kaWZpZXJzW2RlYm91bmNlSW5kZXggKyAxXSB8fCBcImludmFsaWQtd2FpdFwiKS5zcGxpdChcIm1zXCIpWzBdKSA/IDIgOiAxKTtcbiAgfVxuICBpZiAoa2V5TW9kaWZpZXJzLmxlbmd0aCA9PT0gMClcbiAgICByZXR1cm4gZmFsc2U7XG4gIGlmIChrZXlNb2RpZmllcnMubGVuZ3RoID09PSAxICYmIGtleVRvTW9kaWZpZXJzKGUua2V5KS5pbmNsdWRlcyhrZXlNb2RpZmllcnNbMF0pKVxuICAgIHJldHVybiBmYWxzZTtcbiAgY29uc3Qgc3lzdGVtS2V5TW9kaWZpZXJzID0gW1wiY3RybFwiLCBcInNoaWZ0XCIsIFwiYWx0XCIsIFwibWV0YVwiLCBcImNtZFwiLCBcInN1cGVyXCJdO1xuICBjb25zdCBzZWxlY3RlZFN5c3RlbUtleU1vZGlmaWVycyA9IHN5c3RlbUtleU1vZGlmaWVycy5maWx0ZXIoKG1vZGlmaWVyKSA9PiBrZXlNb2RpZmllcnMuaW5jbHVkZXMobW9kaWZpZXIpKTtcbiAga2V5TW9kaWZpZXJzID0ga2V5TW9kaWZpZXJzLmZpbHRlcigoaSkgPT4gIXNlbGVjdGVkU3lzdGVtS2V5TW9kaWZpZXJzLmluY2x1ZGVzKGkpKTtcbiAgaWYgKHNlbGVjdGVkU3lzdGVtS2V5TW9kaWZpZXJzLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBhY3RpdmVseVByZXNzZWRLZXlNb2RpZmllcnMgPSBzZWxlY3RlZFN5c3RlbUtleU1vZGlmaWVycy5maWx0ZXIoKG1vZGlmaWVyKSA9PiB7XG4gICAgICBpZiAobW9kaWZpZXIgPT09IFwiY21kXCIgfHwgbW9kaWZpZXIgPT09IFwic3VwZXJcIilcbiAgICAgICAgbW9kaWZpZXIgPSBcIm1ldGFcIjtcbiAgICAgIHJldHVybiBlW2Ake21vZGlmaWVyfUtleWBdO1xuICAgIH0pO1xuICAgIGlmIChhY3RpdmVseVByZXNzZWRLZXlNb2RpZmllcnMubGVuZ3RoID09PSBzZWxlY3RlZFN5c3RlbUtleU1vZGlmaWVycy5sZW5ndGgpIHtcbiAgICAgIGlmIChrZXlUb01vZGlmaWVycyhlLmtleSkuaW5jbHVkZXMoa2V5TW9kaWZpZXJzWzBdKSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIGtleVRvTW9kaWZpZXJzKGtleSkge1xuICBpZiAoIWtleSlcbiAgICByZXR1cm4gW107XG4gIGtleSA9IGtlYmFiQ2FzZTIoa2V5KTtcbiAgbGV0IG1vZGlmaWVyVG9LZXlNYXAgPSB7XG4gICAgY3RybDogXCJjb250cm9sXCIsXG4gICAgc2xhc2g6IFwiL1wiLFxuICAgIHNwYWNlOiBcIiBcIixcbiAgICBzcGFjZWJhcjogXCIgXCIsXG4gICAgY21kOiBcIm1ldGFcIixcbiAgICBlc2M6IFwiZXNjYXBlXCIsXG4gICAgdXA6IFwiYXJyb3ctdXBcIixcbiAgICBkb3duOiBcImFycm93LWRvd25cIixcbiAgICBsZWZ0OiBcImFycm93LWxlZnRcIixcbiAgICByaWdodDogXCJhcnJvdy1yaWdodFwiLFxuICAgIHBlcmlvZDogXCIuXCIsXG4gICAgZXF1YWw6IFwiPVwiLFxuICAgIG1pbnVzOiBcIi1cIixcbiAgICB1bmRlcnNjb3JlOiBcIl9cIlxuICB9O1xuICBtb2RpZmllclRvS2V5TWFwW2tleV0gPSBrZXk7XG4gIHJldHVybi
1BPYmplY3Qua2V5cyhtb2RpZmllclRvS2V5TWFwKS5tYXAoKG1vZGlmaWVyKSA9PiB7XG4gICAgaWYgKG1vZGlmaWVyVG9LZXlNYXBbbW9kaWZpZXJdID09PSBrZXkpXG4gICAgICByZXR1cm4gbW9kaWZpZXI7XG4gIH0pLmZpbHRlcigobW9kaWZpZXIpID0+IG1vZGlmaWVyKTtcbn1cblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2RpcmVjdGl2ZXMveC1tb2RlbC5qc1xuZGlyZWN0aXZlKFwibW9kZWxcIiwgKGVsLCB7bW9kaWZpZXJzLCBleHByZXNzaW9ufSwge2VmZmVjdDogZWZmZWN0MywgY2xlYW51cDogY2xlYW51cDJ9KSA9PiB7XG4gIGxldCBzY29wZVRhcmdldCA9IGVsO1xuICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwicGFyZW50XCIpKSB7XG4gICAgc2NvcGVUYXJnZXQgPSBlbC5wYXJlbnROb2RlO1xuICB9XG4gIGxldCBldmFsdWF0ZUdldCA9IGV2YWx1YXRlTGF0ZXIoc2NvcGVUYXJnZXQsIGV4cHJlc3Npb24pO1xuICBsZXQgZXZhbHVhdGVTZXQ7XG4gIGlmICh0eXBlb2YgZXhwcmVzc2lvbiA9PT0gXCJzdHJpbmdcIikge1xuICAgIGV2YWx1YXRlU2V0ID0gZXZhbHVhdGVMYXRlcihzY29wZVRhcmdldCwgYCR7ZXhwcmVzc2lvbn0gPSBfX3BsYWNlaG9sZGVyYCk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGV4cHJlc3Npb24gPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgZXhwcmVzc2lvbigpID09PSBcInN0cmluZ1wiKSB7XG4gICAgZXZhbHVhdGVTZXQgPSBldmFsdWF0ZUxhdGVyKHNjb3BlVGFyZ2V0LCBgJHtleHByZXNzaW9uKCl9ID0gX19wbGFjZWhvbGRlcmApO1xuICB9IGVsc2Uge1xuICAgIGV2YWx1YXRlU2V0ID0gKCkgPT4ge1xuICAgIH07XG4gIH1cbiAgbGV0IGdldFZhbHVlID0gKCkgPT4ge1xuICAgIGxldCByZXN1bHQ7XG4gICAgZXZhbHVhdGVHZXQoKHZhbHVlKSA9PiByZXN1bHQgPSB2YWx1ZSk7XG4gICAgcmV0dXJuIGlzR2V0dGVyU2V0dGVyKHJlc3VsdCkgPyByZXN1bHQuZ2V0KCkgOiByZXN1bHQ7XG4gIH07XG4gIGxldCBzZXRWYWx1ZSA9ICh2YWx1ZSkgPT4ge1xuICAgIGxldCByZXN1bHQ7XG4gICAgZXZhbHVhdGVHZXQoKHZhbHVlMikgPT4gcmVzdWx0ID0gdmFsdWUyKTtcbiAgICBpZiAoaXNHZXR0ZXJTZXR0ZXIocmVzdWx0KSkge1xuICAgICAgcmVzdWx0LnNldCh2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV2YWx1YXRlU2V0KCgpID0+IHtcbiAgICAgIH0sIHtcbiAgICAgICAgc2NvcGU6IHtfX3BsYWNlaG9sZG
1VyOiB2YWx1ZX1cbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcbiAgaWYgKHR5cGVvZiBleHByZXNzaW9uID09PSBcInN0cmluZ1wiICYmIGVsLnR5cGUgPT09IFwicmFkaW9cIikge1xuICAgIG11dGF0ZURvbSgoKSA9PiB7XG4gICAgICBpZiAoIWVsLmhhc0F0dHJpYnV0ZShcIm5hbWVcIikpXG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZShcIm5hbWVcIiwgZXhwcmVzc2lvbik7XG4gICAgfSk7XG4gIH1cbiAgdmFyIGV2ZW50ID0gZWwudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSBcInNlbGVjdFwiIHx8IFtcImNoZWNrYm94XCIsIFwicmFkaW9cIl0uaW5jbHVkZXMoZWwudHlwZSkgfHwgbW9kaWZpZXJzLmluY2x1ZGVzKFwibGF6eVwiKSA/IFwiY2hhbmdlXCIgOiBcImlucHV0XCI7XG4gIGxldCByZW1vdmVMaXN0ZW5lciA9IGlzQ2xvbmluZyA/ICgpID0+IHtcbiAgfSA6IG9uKGVsLCBldmVudCwgbW9kaWZpZXJzLCAoZSkgPT4ge1xuICAgIHNldFZhbHVlKGdldElucHV0VmFsdWUoZWwsIG1vZGlmaWVycywgZSwgZ2V0VmFsdWUoKSkpO1xuICB9KTtcbiAgaWYgKG1vZGlmaWVycy5pbmNsdWRlcyhcImZpbGxcIikgJiYgW251bGwsIFwiXCJdLmluY2x1ZGVzKGdldFZhbHVlKCkpKSB7XG4gICAgZWwuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoZXZlbnQsIHt9KSk7XG4gIH1cbiAgaWYgKCFlbC5feF9yZW1vdmVNb2RlbExpc3RlbmVycylcbiAgICBlbC5feF9yZW1vdmVNb2RlbExpc3RlbmVycyA9IHt9O1xuICBlbC5feF9yZW1vdmVNb2RlbExpc3RlbmVyc1tcImRlZmF1bHRcIl0gPSByZW1vdmVMaXN0ZW5lcjtcbiAgY2xlYW51cDIoKCkgPT4gZWwuX3hfcmVtb3ZlTW9kZWxMaXN0ZW5lcnNbXCJkZWZhdWx0XCJdKCkpO1xuICBpZiAoZWwuZm9ybSkge1xuICAgIGxldCByZW1vdmVSZXNldExpc3RlbmVyID0gb24oZWwuZm9ybSwgXCJyZXNldFwiLCBbXSwgKGUpID0+IHtcbiAgICAgIG5leHRUaWNrKCgpID0+IGVsLl94X21vZGVsICYmIGVsLl94X21vZGVsLnNldChlbC52YWx1ZSkpO1xuICAgIH0pO1xuICAgIGNsZWFudXAyKCgpID0+IHJlbW92ZVJlc2V0TGlzdGVuZXIoKSk7XG4gIH1cbiAgZWwuX3hfbW9kZWwgPSB7XG4gICAgZ2V0KCkge1xuICAgICAgcmV0dXJuIGdldFZhbHVlKCk7XG4gICAgfSxcbiAgICBzZXQodmFsdWUpIHtcbiAgICAgIHNldFZhbHVlKHZhbHVlKTtcbiAgICB9XG4gIH07XG4gIGVsLl94X2ZvcmNlTW9kZWxVcGRhdGUgPSAodmFsdWUpID0+IHtcbiAgICB2YWx1ZSA9IHZhbHVlID09PSB2b2lkIDAgPyBnZXRWYWx1ZSgpIDogdmFsdWU7XG4gICAgaWYgKHZhbHVlID09PSB2b2lkIDAgJiYgdHlwZW9mIGV4cHJlc3Npb24gPT09IFwic3RyaW5nXCIgJiYgZXhwcmVzc2lvbi5tYXRjaCgvXFwuLykpXG4gICAgICB2YWx1ZSA9IFwiXCI7XG4gICAgd2luZG93LmZyb21Nb2RlbCA9IHRydWU7XG4gICAgbXV0YXRlRG9tKCgpID0+IGJpbmQoZWwsIFwidmFsdWVcIiwgdmFsdWUpKTtcbiAgICBkZWxldGUgd2luZG93LmZyb21Nb2RlbDtcbiAgfTtcbiAgZWZmZWN0MygoKSA9PiB7XG4gICAgbGV0IHZhbHVlID0gZ2V0VmFsdWUoKTtcbiAgICBpZiAobW9kaWZpZXJzLmluY2x1ZGVzKFwidW5pbnRydXNpdmVcIikgJiYgZG9jdW1lbnQuYWN0aXZlRWxlbWVudC5pc1NhbWVOb2RlKGVsKSlcbiAgICAgIHJldHVybjtcbiAgICBlbC5feF9mb3JjZU1vZGVsVXBkYXRlKHZhbHVlKTtcbiAgfSk7XG59KTtcbmZ1bmN0aW9uIGdldElucHV0VmFsdWUoZWwsIG1vZGlmaWVycywgZXZlbnQsIGN1cnJlbnRWYWx1ZSkge1xuICByZXR1cm4gbXV0YXRlRG9tKCgpID0+IHtcbiAgICBpZiAoZXZlbnQgaW5zdGFuY2VvZiBDdXN0b21FdmVudCAmJiBldmVudC5kZXRhaWwgIT09IHZvaWQgMClcbiAgICAgIHJldHVybiBldmVudC5kZXRhaWwgPz8gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIGVsc2UgaWYgKGVsLnR5cGUgPT09IFwiY2hlY2tib3hcIikge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY3VycmVudFZhbHVlKSkge1xuICAgICAgICBsZXQgbmV3VmFsdWUgPSBtb2RpZmllcnMuaW5jbHVkZXMoXCJudW1iZXJcIikgPyBzYWZlUGFyc2VOdW1iZXIoZXZlbnQudGFyZ2V0LnZhbHVlKSA6IGV2ZW50LnRhcmdldC52YWx1ZTtcbiAgICAgICAgcmV0dXJuIGV2ZW50LnRhcmdldC5jaGVja2VkID8gY3VycmVudFZhbHVlLmNvbmNhdChbbmV3VmFsdWVdKSA6IGN1cnJlbnRWYWx1ZS5maWx0ZXIoKGVsMikgPT4gIWNoZWNrZWRBdHRyTG9vc2VDb21wYXJlMihlbDIsIG5ld1ZhbHVlKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZXZlbnQudGFyZ2V0LmNoZWNrZWQ7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChlbC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwic2VsZWN0XCIgJiYgZWwubXVsdGlwbGUpIHtcbiAgICAgIHJldHVybiBtb2RpZmllcnMuaW5jbHVkZXMoXCJudW1iZXJcIikgPyBBcnJheS5mcm9tKGV2ZW50LnRhcmdldC5zZWxlY3RlZE9wdGlvbnMpLm1hcCgob3B0aW9uKSA9PiB7XG4gICAgICAgIGxldCByYXdWYWx1ZSA9IG9wdGlvbi52YWx1ZSB8fCBvcHRpb24udGV4dDtcbiAgICAgICAgcmV0dXJuIHNhZmVQYXJzZU51bWJlcihyYXdWYWx1ZSk7XG4gICAgICB9KSA6IEFycmF5LmZyb20oZXZlbnQudGFyZ2V0LnNlbGVjdGVkT3B0aW9ucykubWFwKChvcHRpb24pID0+IHtcbiAgICAgICAgcmV0dXJuIG9wdGlvbi52YWx1ZSB8fCBvcHRpb24udGV4dDtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgcmF3VmFsdWUgPSBldmVudC50YXJnZXQudmFsdWU7XG4gICAgICByZXR1cm4gbW9kaWZpZXJzLmluY2x1ZGVzKFwibnVtYmVyXCIpID8gc2FmZVBhcnNlTnVtYmVyKHJhd1ZhbHVlKSA6IG1vZGlmaWVycy5pbmNsdWRlcyhcInRyaW1cIikgPyByYXdWYWx1ZS50cmltKCkgOiByYXdWYWx1ZTtcbiAgICB9XG4gIH0pO1xufVxuZnVuY3Rpb24gc2FmZVBhcnNlTnVtYmVyKHJhd1ZhbHVlKSB7XG4gIGxldCBudW1iZXIgPSByYXdWYWx1ZSA/IHBhcnNlRmxvYXQocmF3VmFsdWUpIDogbnVsbDtcbiAgcmV0dXJuIGlzTnVtZXJpYzIobnVtYmVyKSA/IG51bWJlciA6IHJhd1ZhbHVlO1xufVxuZnVuY3Rpb24gY2hlY2tlZEF0dHJMb29zZUNvbXBhcmUyKHZhbHVlQSwgdmFsdWVCKSB7XG4gIHJldHVybi
1B2YWx1ZUEgPT0gdmFsdWVCO1xufVxuZnVuY3Rpb24gaXNOdW1lcmljMihzdWJqZWN0KSB7XG4gIHJldHVybiAhQXJyYXkuaXNBcnJheShzdWJqZWN0KSAmJiAhaXNOYU4oc3ViamVjdCk7XG59XG5mdW5jdGlvbiBpc0dldHRlclNldHRlcih2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgIT09IG51bGwgJiYgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiB2YWx1ZS5nZXQgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgdmFsdWUuc2V0ID09PSBcImZ1bmN0aW9uXCI7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL3gtY2xvYWsuanNcbmRpcmVjdGl2ZShcImNsb2FrXCIsIChlbCkgPT4gcXVldWVNaWNyb3Rhc2soKCkgPT4gbXV0YXRlRG9tKCgpID0+IGVsLnJlbW92ZUF0dHJpYnV0ZShwcmVmaXgoXCJjbG9ha1wiKSkpKSk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL3gtaW5pdC5qc1xuYWRkSW5pdFNlbGVjdG9yKCgpID0+IGBbJHtwcmVmaXgoXCJpbml0XCIpfV1gKTtcbmRpcmVjdGl2ZShcImluaXRcIiwgc2tpcER1cmluZ0Nsb25lKChlbCwge2V4cHJlc3Npb259LCB7ZXZhbHVhdGU6IGV2YWx1YXRlMn0pID0+IHtcbiAgaWYgKHR5cGVvZiBleHByZXNzaW9uID09PSBcInN0cmluZ1wiKSB7XG4gICAgcmV0dXJuICEhZXhwcmVzc2lvbi50cmltKCkgJiYgZXZhbHVhdGUyKGV4cHJlc3Npb24sIHt9LCBmYWxzZSk7XG4gIH1cbiAgcmV0dXJuIGV2YWx1YXRlMihleHByZXNzaW9uLCB7fSwgZmFsc2UpO1xufSkpO1xuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9zcmMvZGlyZWN0aXZlcy94LXRleHQuanNcbmRpcmVjdGl2ZShcInRleHRcIiwgKGVsLCB7ZXhwcmVzc2lvbn0sIHtlZmZlY3Q6IGVmZmVjdDMsIGV2YWx1YXRlTGF0ZXI6IGV2YWx1YXRlTGF0ZXIyfSkgPT4ge1xuICBsZXQgZXZhbHVhdGUyID0gZXZhbHVhdGVMYXRlcjIoZXhwcmVzc2lvbik7XG4gIGVmZmVjdDMoKCkgPT4ge1xuICAgIGV2YWx1YXRlMigodmFsdWUpID0+IHtcbiAgICAgIG11dGF0ZURvbSgoKSA9PiB7XG4gICAgICAgIGVsLnRleHRDb250ZW50ID0gdmFsdWU7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2RpcmVjdGl2ZXMveC1odG1sLmpzXG5kaXJlY3RpdmUoXCJodG1sXCIsIChlbCwge2V4cHJlc3Npb259LCB7ZWZmZWN0OiBlZmZlY3QzLCBldmFsdWF0ZUxhdGVyOiBldmFsdWF0ZUxhdGVyMn0pID0+IHtcbiAgbGV0IGV2YWx1YXRlMiA9IGV2YWx1YXRlTGF0ZXIyKGV4cHJlc3Npb24pO1xuICBlZmZlY3QzKCgpID0+IHtcbiAgICBldmFsdWF0ZTIoKHZhbHVlKSA9PiB7XG4gICAgICBtdXRhdGVEb20oKCkgPT4ge1xuICAgICAgICBlbC5pbm5lckhUTUwgPSB2YWx1ZTtcbiAgICAgICAgZWwuX3hfaWdub3JlU2VsZiA9IHRydWU7XG4gICAgICAgIGluaXRUcmVlKGVsKTtcbiAgICAgICAgZGVsZXRlIGVsLl94X2lnbm9yZVNlbGY7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2RpcmVjdGl2ZXMveC1iaW5kLmpzXG5tYXBBdHRyaWJ1dGVzKHN0YXJ0aW5nV2l0aChcIjpcIiwgaW50byhwcmVmaXgoXCJiaW5kOlwiKSkpKTtcbnZhciBoYW5kbGVyMiA9IChlbCwge3ZhbHVlLCBtb2RpZmllcnMsIGV4cHJlc3Npb24sIG9yaWdpbmFsfSwge2VmZmVjdDogZWZmZWN0M30pID0+IHtcbiAgaWYgKCF2YWx1ZSkge1xuICAgIGxldCBiaW5kaW5nUHJvdmlkZXJzID0ge307XG4gICAgaW5qZWN0QmluZGluZ1Byb3ZpZGVycyhiaW5kaW5nUHJvdmlkZXJzKTtcbiAgICBsZXQgZ2V0QmluZGluZ3MgPSBldmFsdWF0ZUxhdGVyKGVsLCBleHByZXNzaW9uKTtcbiAgICBnZXRCaW5kaW5ncygoYmluZGluZ3MpID0+IHtcbiAgICAgIGFwcGx5QmluZGluZ3NPYmplY3QoZWwsIGJpbmRpbmdzLCBvcmlnaW5hbCk7XG4gICAgfSwge3Njb3BlOiBiaW5kaW5nUHJvdmlkZXJzfSk7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmICh2YWx1ZSA9PT0gXCJrZXlcIilcbiAgICByZXR1cm4gc3RvcmVLZXlGb3JYRm9yKGVsLCBleHByZXNzaW9uKTtcbiAgaWYgKGVsLl94X2lubGluZUJpbmRpbmdzICYmIGVsLl94X2lubGluZUJpbmRpbmdzW3ZhbHVlXSAmJiBlbC5feF9pbmxpbmVCaW5kaW5nc1t2YWx1ZV0uZXh0cmFjdCkge1xuICAgIHJldHVybjtcbiAgfVxuICBsZXQgZXZhbHVhdGUyID0gZXZhbHVhdGVMYXRlcihlbCwgZXhwcmVzc2lvbik7XG4gIGVmZmVjdDMoKCkgPT4gZXZhbHVhdGUyKChyZXN1bHQpID0+IHtcbiAgICBpZiAocmVzdWx0ID09PSB2b2lkIDAgJiYgdHlwZW9mIGV4cHJlc3Npb24gPT09IFwic3RyaW5nXCIgJiYgZXhwcmVzc2lvbi5tYXRjaCgvXFwuLykpIHtcbiAgICAgIHJlc3VsdCA9IFwiXCI7XG4gICAgfVxuICAgIG11dGF0ZURvbSgoKSA9PiBiaW5kKGVsLCB2YWx1ZSwgcmVzdWx0LCBtb2RpZmllcnMpKTtcbiAgfSkpO1xufTtcbmhhbmRsZXIyLmlubGluZSA9IChlbCwge3ZhbHVlLCBtb2RpZmllcnMsIGV4cHJlc3Npb259KSA9PiB7XG4gIGlmICghdmFsdWUpXG4gICAgcmV0dXJuO1xuICBpZiAoIWVsLl94X2lubGluZUJpbmRpbmdzKVxuICAgIGVsLl94X2lubGluZUJpbmRpbmdzID0ge307XG4gIGVsLl94X2lubGluZUJpbmRpbmdzW3ZhbHVlXSA9IHtleHByZXNzaW9uLCBleHRyYWN0OiBmYWxzZX07XG59O1xuZGlyZWN0aXZlKFwiYmluZFwiLCBoYW5kbGVyMik7XG5mdW5jdGlvbiBzdG9yZUtleUZvclhGb3IoZWwsIGV4cHJlc3Npb24pIHtcbiAgZWwuX3hfa2V5RXhwcmVzc2lvbiA9IGV4cHJlc3Npb247XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL3gtZGF0YS5qc1xuYWRkUm9vdFNlbGVjdG9yKCgpID0+IGBbJHtwcmVmaXgoXCJkYXRhXCIpfV1gKTtcbmRpcmVjdGl2ZShcImRhdGFcIiwgc2tpcER1cmluZ0Nsb25lKChlbCwge2V4cHJlc3Npb259LCB7Y2xlYW51cDogY2xlYW51cDJ9KSA9PiB7XG4gIGV4cHJlc3Npb24gPSBleHByZXNzaW9uID09PSBcIlwiID8gXCJ7fVwiIDogZXhwcmVzc2lvbjtcbiAgbGV0IG1hZ2ljQ29udGV4dCA9IHt9O1xuICBpbmplY3RNYWdpY3MobWFnaWNDb250ZXh0LCBlbCk7XG4gIGxldCBkYXRhUHJvdmlkZXJDb250ZXh0ID0ge307XG4gIGluamVjdERhdGFQcm92aWRlcnMoZGF0YVByb3ZpZGVyQ29udGV4dCwgbWFnaWNDb250ZXh0KTtcbiAgbGV0IGRhdGEyID0gZXZhbHVhdGUoZWwsIGV4cHJlc3Npb24sIHtzY29wZTogZGF0YVByb3ZpZGVyQ29udGV4dH0pO1xuICBpZiAoZGF0YTIgPT09IHZvaWQgMCB8fCBkYXRhMiA9PT0gdHJ1ZSlcbiAgICBkYXRhMiA9IHt9O1xuICBpbmplY3RNYWdpY3MoZGF0YTIsIGVsKTtcbiAgbGV0IHJlYWN0aXZlRGF0YSA9IHJlYWN0aXZlKGRhdGEyKTtcbiAgaW5pdEludGVyY2VwdG9ycyhyZWFjdGl2ZURhdGEpO1xuICBsZXQgdW5kbyA9IGFkZFNjb3BlVG9Ob2RlKGVsLCByZWFjdGl2ZURhdGEpO1xuICByZWFjdGl2ZURhdGFbXCJpbml0XCJdICYmIGV2YWx1YXRlKGVsLCByZWFjdGl2ZURhdGFbXCJpbml0XCJdKTtcbiAgY2xlYW51cDIoKCkgPT4ge1xuICAgIHJlYWN0aXZlRGF0YVtcImRlc3Ryb3lcIl0gJiYgZXZhbHVhdGUoZWwsIHJlYWN0aXZlRGF0YVtcImRlc3Ryb3lcIl0pO1xuICAgIHVuZG8oKTtcbiAgfSk7XG59KSk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL3gtc2hvdy5qc1xuZGlyZWN0aXZlKFwic2hvd1wiLCAoZWwsIHttb2RpZmllcnMsIGV4cHJlc3Npb259LCB7ZWZmZWN0OiBlZmZlY3QzfSkgPT4ge1xuICBsZXQgZXZhbHVhdGUyID0gZXZhbHVhdGVMYXRlcihlbCwgZXhwcmVzc2lvbik7XG4gIGlmICghZWwuX3hfZG9IaWRlKVxuICAgIGVsLl94X2RvSGlkZSA9ICgpID0+IHtcbiAgICAgIG11dGF0ZURvbSgoKSA9PiB7XG4gICAgICAgIGVsLnN0eWxlLnNldFByb3BlcnR5KFwiZGlzcGxheVwiLCBcIm5vbmVcIiwgbW9kaWZpZXJzLmluY2x1ZGVzKFwiaW1wb3J0YW50XCIpID8gXCJpbXBvcnRhbnRcIiA6IHZvaWQgMCk7XG4gICAgICB9KTtcbiAgICB9O1xuICBpZiAoIWVsLl94X2RvU2hvdylcbiAgICBlbC5feF9kb1Nob3cgPSAoKSA9PiB7XG4gICAgICBtdXRhdGVEb20oKCkgPT4ge1xuICAgICAgICBpZiAoZWwuc3R5bGUubGVuZ3RoID09PSAxICYmIGVsLnN0eWxlLmRpc3BsYXkgPT09IFwibm9uZVwiKSB7XG4gICAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKFwic3R5bGVcIik7XG4gICAgICAgI
1H0gZWxzZSB7XG4gICAgICAgICAgZWwuc3R5bGUucmVtb3ZlUHJvcGVydHkoXCJkaXNwbGF5XCIpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuICBsZXQgaGlkZSA9ICgpID0+IHtcbiAgICBlbC5feF9kb0hpZGUoKTtcbiAgICBlbC5feF9pc1Nob3duID0gZmFsc2U7XG4gIH07XG4gIGxldCBzaG93ID0gKCkgPT4ge1xuICAgIGVsLl94X2RvU2hvdygpO1xuICAgIGVsLl94X2lzU2hvd24gPSB0cnVlO1xuICB9O1xuICBsZXQgY2xpY2tBd2F5Q29tcGF0aWJsZVNob3cgPSAoKSA9PiBzZXRUaW1lb3V0KHNob3cpO1xuICBsZXQgdG9nZ2xlID0gb25jZSgodmFsdWUpID0+IHZhbHVlID8gc2hvdygpIDogaGlkZSgpLCAodmFsdWUpID0+IHtcbiAgICBpZiAodHlwZW9mIGVsLl94X3RvZ2dsZUFuZENhc2NhZGVXaXRoVHJhbnNpdGlvbnMgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgZWwuX3hfdG9nZ2xlQW5kQ2FzY2FkZVdpdGhUcmFuc2l0aW9ucyhlbCwgdmFsdWUsIHNob3csIGhpZGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSA/IGNsaWNrQXdheUNvbXBhdGlibGVTaG93KCkgOiBoaWRlKCk7XG4gICAgfVxuICB9KTtcbiAgbGV0IG9sZFZhbHVlO1xuICBsZXQgZmlyc3RUaW1lID0gdHJ1ZTtcbiAgZWZmZWN0MygoKSA9PiBldmFsdWF0ZTIoKHZhbHVlKSA9PiB7XG4gICAgaWYgKCFmaXJzdFRpbWUgJiYgdmFsdWUgPT09IG9sZFZhbHVlKVxuICAgICAgcmV0dXJuO1xuICAgIGlmIChtb2RpZmllcnMuaW5jbHVkZXMoXCJpbW1lZGlhdGVcIikpXG4gICAgICB2YWx1ZSA/IGNsaWNrQXdheUNvbXBhdGlibGVTaG93KCkgOiBoaWRlKCk7XG4gICAgdG9nZ2xlKHZhbHVlKTtcbiAgICBvbGRWYWx1ZSA9IHZhbHVlO1xuICAgIGZpcnN0VGltZSA9IGZhbHNlO1xuICB9KSk7XG59KTtcblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2RpcmVjdGl2ZXMveC1mb3IuanNcbmRpcmVjdGl2ZShcImZvclwiLCAoZWwsIHtleHByZXNzaW9ufSwge2VmZmVjdDogZWZmZWN0MywgY2xlYW51cDogY2xlYW51cDJ9KSA9PiB7XG4gIGxldCBpdGVyYXRvck5hbWVzID0gcGFyc2VGb3JFeHByZXNzaW9uKGV4cHJlc3Npb24pO1xuICBsZXQgZXZhbHVhdGVJdGVtcyA9IGV2YWx1YXRlTGF0ZXIoZWwsIGl0ZXJhdG9yTmFtZXMuaXRlbXMpO1xuICBsZXQgZXZhbHVhdGVLZXkgPSBldmFsdWF0ZUxhdGVyKGVsLCBlbC5feF9rZXlFeHByZXNzaW9uIHx8IFwiaW5kZXhcIik7XG4gIGVsLl94X3ByZXZLZXlzID0gW107XG4gIGVsLl94X2xvb2t1cCA9IHt9O1xuICBlZmZlY3QzKCgpID0+IGxvb3AoZWwsIGl0ZXJhdG9yTmFtZXMsIGV2YWx1YXRlSXRlbXMsIGV2YWx1YXRlS2V5KSk7XG4gIGNsZWFudXAyKCgpID0+IHtcbiAgICBPYmplY3QudmFsdWVzKGVsLl94X2xvb2t1cCkuZm9yRWFjaCgoZWwyKSA9PiBlbDIucmVtb3ZlKCkpO1xuICAgIGRlbGV0ZSBlbC5feF9wcmV2S2V5cztcbiAgICBkZWxldGUgZWwuX3hfbG9va3VwO1xuICB9KTtcbn0pO1xuZnVuY3Rpb24gbG9vcChlbCwgaXRlcmF0b3JOYW1lcywgZXZhbHVhdGVJdGVtcywgZXZhbHVhdGVLZXkpIHtcbiAgbGV0IGlzT2JqZWN0MiA9IChpKSA9PiB0eXBlb2YgaSA9PT0gXCJvYmplY3RcIiAmJiAhQXJyYXkuaXNBcnJheShpKTtcbiAgbGV0IHRlbXBsYXRlRWwgPSBlbDtcbiAgZXZhbHVhdGVJdGVtcygoaXRlbXMpID0+IHtcbiAgICBpZiAoaXNOdW1lcmljMyhpdGVtcykgJiYgaXRlbXMgPj0gMCkge1xuICAgICAgaXRlbXMgPSBBcnJheS5mcm9tKEFycmF5KGl0ZW1zKS5rZXlzKCksIChpKSA9PiBpICsgMSk7XG4gICAgfVxuICAgIGlmIChpdGVtcyA9PT0gdm9pZCAwKVxuICAgICAgaXRlbXMgPSBbXTtcbiAgICBsZXQgbG9va3VwID0gZWwuX3hfbG9va3VwO1xuICAgIGxldCBwcmV2S2V5cyA9IGVsLl94X3ByZXZLZXlzO1xuICAgIGxldCBzY29wZXMgPSBbXTtcbiAgICBsZXQga2V5cyA9IFtdO1xuICAgIGlmIChpc09iamVjdDIoaXRlbXMpKSB7XG4gICAgICBpdGVtcyA9IE9iamVjdC5lbnRyaWVzKGl0ZW1zKS5tYXAoKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICBsZXQgc2NvcGUyID0gZ2V0SXRlcmF0aW9uU2NvcGVWYXJpYWJsZXMoaXRlcmF0b3JOYW1lcywgdmFsdWUsIGtleSwgaXRlbXMpO1xuICAgICAgICBldmFsdWF0ZUtleSgodmFsdWUyKSA9PiBrZXlzLnB1c2godmFsdWUyKSwge3Njb3BlOiB7aW5kZXg6IGtleSwgLi4uc2NvcGUyfX0pO1xuICAgICAgICBzY29wZXMucHVzaChzY29wZTIpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IHNjb3BlMiA9IGdldEl0ZXJhdGlvblNjb3BlVmFyaWFibGVzKGl0ZXJhdG9yTmFtZXMsIGl0ZW1zW2ldLCBpLCBpdGVtcyk7XG4gICAgICAgIGV2YWx1YXRlS2V5KCh2YWx1ZSkgPT4ga2V5cy5wdXNoKHZhbHVlKSwge3Njb3BlOiB7aW5kZXg6IGksIC4uLnNjb3BlMn19KTtcbiAgICAgICAgc2NvcGVzLnB1c2goc2NvcGUyKTtcbiAgICAgIH1cbiAgICB9XG4gICAgbGV0IGFkZHMgPSBbXTtcbiAgICBsZXQgbW92ZXMgPSBbXTtcbiAgICBsZXQgcmVtb3ZlcyA9IFtdO1xuICAgIGxldCBzYW1lcyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJldktleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBrZXkgPSBwcmV2S2V5c1tpXTtcbiAgICAgIGlmIChrZXlzLmluZGV4T2Yoa2V5KSA9PT0gLTEpXG4gICAgICAgIHJlbW92ZXMucHVzaChrZXkpO1xuICAgIH1cbiAgICBwcmV2S2V5cyA9IHByZXZLZXlzLmZpbHRlcigoa2V5KSA9PiAhcmVtb3Zlcy5pbmNsdWRlcyhrZXkpKTtcbiAgICBsZXQgbGFzdEtleSA9IFwidGVtcGxhdGVcIjtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBrZXkgPSBrZXlzW2ldO1xuICAgICAgbGV0IHByZXZJbmRleCA9IHByZXZLZXlzLmluZGV4T2Yoa2V5KTtcbiAgICAgIGlmIChwcmV2SW5kZXggPT09IC0xKSB7XG4gICAgICAgIHByZXZLZXlzLnNwbGljZShpLCAwLCBrZXkpO1xuICAgICAgICBhZGRzLnB1c2goW2xhc3RLZXksIGldKTtcbiAgICAgIH0gZWxzZSBpZiAocHJldkluZGV4ICE9PSBpKSB7XG4gICAgICAgIGxldCBrZXlJblNwb3QgPSBwcmV2S2V5cy5zcGxpY2UoaSwgMSlbMF07XG4gICAgICAgIGxldCBrZXlGb3JTcG90ID0gcHJldktleXMuc3BsaWNlKHByZXZJbmRleCAtIDEsIDEpWzBdO1xuICAgICAgICBwcmV2S2V5cy5zcGxpY2UoaSwgMCwga2V5Rm9yU3BvdCk7XG4gICAgICAgI
1HByZXZLZXlzLnNwbGljZShwcmV2SW5kZXgsIDAsIGtleUluU3BvdCk7XG4gICAgICAgIG1vdmVzLnB1c2goW2tleUluU3BvdCwga2V5Rm9yU3BvdF0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2FtZXMucHVzaChrZXkpO1xuICAgICAgfVxuICAgICAgbGFzdEtleSA9IGtleTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZW1vdmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQga2V5ID0gcmVtb3Zlc1tpXTtcbiAgICAgIGlmICghIWxvb2t1cFtrZXldLl94X2VmZmVjdHMpIHtcbiAgICAgICAgbG9va3VwW2tleV0uX3hfZWZmZWN0cy5mb3JFYWNoKGRlcXVldWVKb2IpO1xuICAgICAgfVxuICAgICAgbG9va3VwW2tleV0ucmVtb3ZlKCk7XG4gICAgICBsb29rdXBba2V5XSA9IG51bGw7XG4gICAgICBkZWxldGUgbG9va3VwW2tleV07XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbW92ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBba2V5SW5TcG90LCBrZXlGb3JTcG90XSA9IG1vdmVzW2ldO1xuICAgICAgbGV0IGVsSW5TcG90ID0gbG9va3VwW2tleUluU3BvdF07XG4gICAgICBsZXQgZWxGb3JTcG90ID0gbG9va3VwW2tleUZvclNwb3RdO1xuICAgICAgbGV0IG1hcmtlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICBtdXRhdGVEb20oKCkgPT4ge1xuICAgICAgICBpZiAoIWVsRm9yU3BvdClcbiAgICAgICAgICB3YXJuKGB4LWZvciBcIjprZXlcIiBpcyB1bmRlZmluZWQgb3IgaW52YWxpZGAsIHRlbXBsYXRlRWwpO1xuICAgICAgICBlbEZvclNwb3QuYWZ0ZXIobWFya2VyKTtcbiAgICAgICAgZWxJblNwb3QuYWZ0ZXIoZWxGb3JTcG90KTtcbiAgICAgICAgZWxGb3JTcG90Ll94X2N1cnJlbnRJZkVsICYmIGVsRm9yU3BvdC5hZnRlcihlbEZvclNwb3QuX3hfY3VycmVudElmRWwpO1xuICAgICAgICBtYXJrZXIuYmVmb3JlKGVsSW5TcG90KTtcbiAgICAgICAgZWxJblNwb3QuX3hfY3VycmVudElmRWwgJiYgZWxJblNwb3QuYWZ0ZXIoZWxJblNwb3QuX3hfY3VycmVudElmRWwpO1xuICAgICAgICBtYXJrZXIucmVtb3ZlKCk7XG4gICAgICB9KTtcbiAgICAgIGVsRm9yU3BvdC5feF9yZWZyZXNoWEZvclNjb3BlKHNjb3Blc1trZXlzLmluZGV4T2Yoa2V5Rm9yU3BvdCldKTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhZGRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQgW2xhc3RLZXkyLCBpbmRleF0gPSBhZGRzW2ldO1xuICAgICAgbGV0IGxhc3RFbCA9IGxhc3RLZXkyID09PSBcInRlbXBsYXRlXCIgPyB0ZW1wbGF0ZUVsIDogbG9va3VwW2xhc3RLZXkyXTtcbiAgICAgIGlmIChsYXN0RWwuX3hfY3VycmVudElmRWwpXG4gICAgICAgIGxhc3RFbCA9IGxhc3RFbC5feF9jdXJyZW50SWZFbDtcbiAgICAgIGxldCBzY29wZTIgPSBzY29wZXNbaW5kZXhdO1xuICAgICAgbGV0IGtleSA9IGtleXNbaW5kZXhdO1xuICAgICAgbGV0IGNsb25lMiA9IGRvY3VtZW50LmltcG9ydE5vZGUodGVtcGxhdGVFbC5jb250ZW50LCB0cnVlKS5maXJzdEVsZW1lbnRDaGlsZDtcbiAgICAgIGxldCByZWFjdGl2ZVNjb3BlID0gcmVhY3RpdmUoc2NvcGUyKTtcbiAgICAgIGFkZFNjb3BlVG9Ob2RlKGNsb25lMiwgcmVhY3RpdmVTY29wZSwgdGVtcGxhdGVFbCk7XG4gICAgICBjbG9uZTIuX3hfcmVmcmVzaFhGb3JTY29wZSA9IChuZXdTY29wZSkgPT4ge1xuICAgICAgICBPYmplY3QuZW50cmllcyhuZXdTY29wZSkuZm9yRWFjaCgoW2tleTIsIHZhbHVlXSkgPT4ge1xuICAgICAgICAgIHJlYWN0aXZlU2NvcGVba2V5Ml0gPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgICAgbXV0YXRlRG9tKCgpID0+IHtcbiAgICAgICAgbGFzdEVsLmFmdGVyKGNsb25lMik7XG4gICAgICAgIGluaXRUcmVlKGNsb25lMik7XG4gICAgICB9KTtcbiAgICAgIGlmICh0eXBlb2Yga2V5ID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIHdhcm4oXCJ4LWZvciBrZXkgY2Fubm90IGJlIGFuIG9iamVjdCwgaXQgbXVzdCBiZSBhIHN0cmluZyBvciBhbiBpbnRlZ2VyXCIsIHRlbXBsYXRlRWwpO1xuICAgICAgfVxuICAgICAgbG9va3VwW2tleV0gPSBjbG9uZTI7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxvb2t1cFtzYW1lc1tpXV0uX3hfcmVmcmVzaFhGb3JTY29wZShzY29wZXNba2V5cy5pbmRleE9mKHNhbWVzW2ldKV0pO1xuICAgIH1cbiAgICB0ZW1wbGF0ZUVsLl94X3ByZXZLZXlzID0ga2V5cztcbiAgfSk7XG59XG5mdW5jdGlvbiBwYXJzZUZvckV4cHJlc3Npb24oZXhwcmVzc2lvbikge1xuICBsZXQgZm9ySXRlcmF0b3JSRSA9IC8sKFteLFxcfVxcXV0qKSg/OiwoW14sXFx9XFxdXSopKT8kLztcbiAgbGV0IHN0cmlwUGFyZW5zUkUgPSAvXlxccypcXCh8XFwpXFxzKiQvZztcbiAgbGV0IGZvckFsaWFzUkUgPSAvKFtcXHNcXFNdKj8pXFxzKyg/OmlufG9mKVxccysoW1xcc1xcU10qKS87XG4gIGxldCBpbk1hdGNoID0gZXhwcmVzc2lvbi5tYXRjaChmb3JBbGlhc1JFKTtcbiAgaWYgKCFpbk1hdGNoKVxuICAgIHJldHVybjtcbiAgbGV0IHJlcyA9IHt9O1xuICByZXMuaXRlbXMgPSBpbk1hdGNoWzJdLnRyaW0oKTtcbiAgbGV0IGl0ZW0gPSBpbk1hdGNoWzFdLnJlcGxhY2Uoc3RyaXBQYXJlbnNSRSwgXCJcIikudHJpbSgpO1xuICBsZXQgaXRlcmF0b3JNYXRjaCA9IGl0ZW0ubWF0Y2goZm9ySXRlcmF0b3JSRSk7XG4gIGlmIChpdGVyYXRvck1hdGNoKSB7XG4gICAgcmVzLml0ZW0gPSBpdGVtLnJlcGxhY2UoZm9ySXRlcmF0b3JSRSwgXCJcIikudHJpbSgpO1xuICAgIHJlcy5pbmRleCA9IGl0ZXJhdG9yTWF0Y2hbMV0udHJpbSgpO1xuICAgIGlmIChpdGVyYXRvck1hdGNoWzJdKSB7XG4gICAgICByZXMuY29sbGVjdGlvbiA9IGl0ZXJhdG9yTWF0Y2hbMl0udHJpbSgpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZXMuaXRlbSA9IGl0ZW07XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbmZ1bmN0aW9uIGdldEl0ZXJhdGlvblNjb3BlVmFyaWFibGVzKGl0ZXJhdG9yTmFtZXMsIGl0ZW0sIGluZGV4LCBpdGVtcykge1xuICBsZXQgc2NvcGVWYXJpYWJsZXMgPSB7fTtcbiAgaWYgKC9eXFxbLipcXF0kLy50ZXN0KGl0ZXJhdG9yTmFtZXMuaXRlbSkgJiYgQXJyYXkuaXNBcnJheShpdGVtKSkge1xuICAgIGxldCBuYW1lcyA9IGl0ZXJhdG9yTmFtZXMuaXRlbS5yZXBsYWNlKFwiW1wiLCBcIlwiKS5yZXBsYWNlKFwiXVwiLCBcIlwiKS5zcGxpdChcIixcIikubWFwKChpKSA9PiBpLnRyaW0oKSk7XG4gICAgbmFtZXMuZm9yRWFjaCgobmFtZSwgaSkgPT4ge1xuICAgICAgc2NvcGVWYXJpYWJsZXNbbmFtZV0gPSBpdGVtW2ldO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKC9eXFx7LipcXH0kLy50ZXN0KGl0ZXJhdG9yTmFtZXMuaXRlbSkgJiYgIUFycmF5LmlzQXJyYXkoaXRlbSkgJiYgdHlwZW9mIGl0ZW0gPT09IFwib2JqZWN0XCIpIHtcbiAgICBsZXQgbmFtZXMgPSBpdGVyYXRvck5hbWVzLml0ZW0ucmVwbGFjZShcIntcIiwgXCJcIikucmVwbGFjZShcIn1cIiwgXCJcIikuc3BsaXQoXCIsXCIpLm1hcCgoaSkgPT4gaS50cmltKCkpO1xuICAgIG5hbWVzLmZvckVhY2goKG5hbWUpID0+IHtcbiAgICAgIHNjb3BlVmFyaWFibGVzW25hbWVdID0gaXRlbVtuYW1lXTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBzY29wZVZhcmlhYmxlc1tpdGVyYXRvck5hbWVzLml0ZW1dID0gaXRlbTtcbiAgfVxuICBpZiAoaXRlcmF0b3JOYW1lcy5pbmRleClcbiAgICBzY29wZVZhcmlhYmxlc1tpdGVyYXRvck5hbWVzLmluZGV4XSA9IGluZGV4O1xuICBpZiAoaXRlcmF0b3JOYW1lcy5jb2xsZWN0aW9uKVxuICAgIHNjb3BlVmFyaWFibGVzW2l0ZXJhdG9yTmFtZXMuY29sbGVjdGlvbl0gPSBpdGVtcztcbiAgcmV0dXJuIHNjb3BlVmFyaWFibGVzO1xufVxuZnVuY3Rpb24gaXNOdW1lcmljMyhzdWJqZWN0KSB7XG4gIHJldHVybiAhQXJyYXkuaXNBcnJheShzdWJqZWN0KSAmJiAhaXNOYU4oc3ViamVjdCk7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL3gtcmVmLmpzXG5mdW5jdGlvbiBoYW5kbGVyMygpIHtcbn1cbmhhbmRsZXIzLmlubGluZSA9IChlbCwge2V4cHJlc3Npb259LCB7Y2xlYW51cDogY2xlYW51cDJ9KSA9PiB7XG4gIGxldCByb290ID0gY2xvc2VzdFJvb3QoZWwpO1xuICBpZiAoIXJvb3QuX3hfcmVmcylcbiAgICByb290Ll94X3JlZnMgPSB7fTtcbiAgcm9vdC5feF9yZWZzW2V4cHJlc3Npb25dID0gZWw7XG4gIGNsZWFudXAyKCgpID0+IGRlbGV0ZSByb290Ll94X3JlZnNbZXhwcmVzc2lvbl0pO1xufTtcbmRpcmVjdGl2ZShcInJlZlwiLCBoYW5kbGVyMyk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL3gtaWYuanNcbmRpcmVjdGl2ZShcImlmXCIsIChlbCwge2V4cHJlc3Npb259LCB7ZWZmZWN0OiBlZmZlY3QzLCBjbGVhbnVwOiBjbGVhbnVwMn0pID0+IHtcbiAgbGV0IGV2YWx1YXRlMiA9IGV2YWx1YXRlTGF0ZXIoZWwsIGV4cHJlc3Npb24pO1xuICBsZXQgc2hvdyA9ICgpID0+IHtcbiAgICBpZiAoZWwuX3hfY3VycmVudElmRWwpXG4gICAgICByZXR1cm4gZWwuX3hfY3VycmVudElmRWw7XG4gICAgbGV0IGNsb25lMiA9IGVsLmNvbnRlbnQuY2xvbmVOb2RlKHRydWUpLmZpcnN0RWxlbWVudENoaWxkO1xuICAgIGFkZFNjb3BlVG9Ob2RlKGNsb25lMiwge30sIGVsKTtcbiAgICBtdXRhdGVEb20oKCkgPT4ge1xuICAgICAgZWwuYWZ0ZXIoY2xvbmUyKTtcbiAgICAgIGluaXRUcmVlKGNsb25lMik7XG4gICAgfSk7XG4gICAgZWwuX3hfY3VycmVudElmRWwgPSBjbG9uZTI7XG4gICAgZWwuX3hfdW5kb0lmID0gKCkgPT4ge1xuICAgICAgd2FsayhjbG9uZTIsIChub2RlKSA9PiB7XG4gICAgICAgIGlmICghIW5vZGUuX3hfZWZmZWN0cykge1xuICAgICAgICAgIG5vZGUuX3hfZWZmZWN0cy5mb3JFYWNoKGRlcXVldWVKb2IpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGNsb25lMi5yZW1vdmUoKTtcbiAgICAgIGRlbGV0ZSBlbC5feF9jdXJyZW50SWZFbDtcbiAgICB9O1xuICAgIHJldHVybi
1BjbG9uZTI7XG4gIH07XG4gIGxldCBoaWRlID0gKCkgPT4ge1xuICAgIGlmICghZWwuX3hfdW5kb0lmKVxuICAgICAgcmV0dXJuO1xuICAgIGVsLl94X3VuZG9JZigpO1xuICAgIGRlbGV0ZSBlbC5feF91bmRvSWY7XG4gIH07XG4gIGVmZmVjdDMoKCkgPT4gZXZhbHVhdGUyKCh2YWx1ZSkgPT4ge1xuICAgIHZhbHVlID8gc2hvdygpIDogaGlkZSgpO1xuICB9KSk7XG4gIGNsZWFudXAyKCgpID0+IGVsLl94X3VuZG9JZiAmJiBlbC5feF91bmRvSWYoKSk7XG59KTtcblxuLy8gcGFja2FnZXMvYWxwaW5lanMvc3JjL2RpcmVjdGl2ZXMveC1pZC5qc1xuZGlyZWN0aXZlKFwiaWRcIiwgKGVsLCB7ZXhwcmVzc2lvbn0sIHtldmFsdWF0ZTogZXZhbHVhdGUyfSkgPT4ge1xuICBsZXQgbmFtZXMgPSBldmFsdWF0ZTIoZXhwcmVzc2lvbik7XG4gIG5hbWVzLmZvckVhY2goKG5hbWUpID0+IHNldElkUm9vdChlbCwgbmFtZSkpO1xufSk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL3gtb24uanNcbm1hcEF0dHJpYnV0ZXMoc3RhcnRpbmdXaXRoKFwiQFwiLCBpbnRvKHByZWZpeChcIm9uOlwiKSkpKTtcbmRpcmVjdGl2ZShcIm9uXCIsIHNraXBEdXJpbmdDbG9uZSgoZWwsIHt2YWx1ZSwgbW9kaWZpZXJzLCBleHByZXNzaW9ufSwge2NsZWFudXA6IGNsZWFudXAyfSkgPT4ge1xuICBsZXQgZXZhbHVhdGUyID0gZXhwcmVzc2lvbiA/IGV2YWx1YXRlTGF0ZXIoZWwsIGV4cHJlc3Npb24pIDogKCkgPT4ge1xuICB9O1xuICBpZiAoZWwudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSBcInRlbXBsYXRlXCIpIHtcbiAgICBpZiAoIWVsLl94X2ZvcndhcmRFdmVudHMpXG4gICAgICBlbC5feF9mb3J3YXJkRXZlbnRzID0gW107XG4gICAgaWYgKCFlbC5feF9mb3J3YXJkRXZlbnRzLmluY2x1ZGVzKHZhbHVlKSlcbiAgICAgIGVsLl94X2ZvcndhcmRFdmVudHMucHVzaCh2YWx1ZSk7XG4gIH1cbiAgbGV0IHJlbW92ZUxpc3RlbmVyID0gb24oZWwsIHZhbHVlLCBtb2RpZmllcnMsIChlKSA9PiB7XG4gICAgZXZhbHVhdGUyKCgpID0+IHtcbiAgICB9LCB7c2NvcGU6IHskZXZlbnQ6IGV9LCBwYXJhbXM6IFtlXX0pO1xuICB9KTtcbiAgY2xlYW51cDIoKCkgPT4gcmVtb3ZlTGlzdGVuZXIoKSk7XG59KSk7XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9kaXJlY3RpdmVzL2luZGV4LmpzXG53YXJuTWlzc2luZ1BsdWdpbkRpcmVjdGl2ZShcIkNvbGxhcHNlXCIsIFwiY29sbGFwc2VcIiwgXCJjb2xsYXBzZVwiKTtcbndhcm5NaXNzaW5nUGx1Z2luRGlyZWN0aXZlKFwiSW50ZXJzZWN0XCIsIFwiaW50ZXJzZWN0XCIsIFwiaW50ZXJzZWN0XCIpO1xud2Fybk1pc3NpbmdQbHVnaW5EaXJlY3RpdmUoXCJGb2N1c1wiLCBcInRyYXBcIiwgXCJmb2N1c1wiKTtcbndhcm5NaXNzaW5nUGx1Z2luRGlyZWN0aXZlKFwiTWFza1wiLCBcIm1hc2tcIiwgXCJtYXNrXCIpO1xuZnVuY3Rpb24gd2Fybk1pc3NpbmdQbHVnaW5EaXJlY3RpdmUobmFtZSwgZGlyZWN0aXZlTmFtZTIsIHNsdWcpIHtcbiAgZGlyZWN0aXZlKGRpcmVjdGl2ZU5hbWUyLCAoZWwpID0+IHdhcm4oYFlvdSBjYW4ndCB1c2UgW3gtJHtkaXJlY3RpdmVOYW1lMn1dIHdpdGhvdXQgZmlyc3QgaW5zdGFsbGluZyB0aGUgXCIke25hbWV9XCIgcGx1Z2luIGhlcmU6IGh0dHBzOi8vYWxwaW5lanMuZGV2L3BsdWdpbnMvJHtzbHVnfWAsIGVsKSk7XG59XG5cbi8vIHBhY2thZ2VzL2FscGluZWpzL3NyYy9pbmRleC5qc1xuYWxwaW5lX2RlZmF1bHQuc2V0RXZhbHVhdG9yKG5vcm1hbEV2YWx1YXRvcik7XG5hbHBpbmVfZGVmYXVsdC5zZXRSZWFjdGl2aXR5RW5naW5lKHtyZWFjdGl2ZTogcmVhY3RpdmUyLCBlZmZlY3Q6IGVmZmVjdDIsIHJlbGVhc2U6IHN0b3AsIHJhdzogdG9SYXd9KTtcbnZhciBzcmNfZGVmYXVsdCA9IGFscGluZV9kZWZhdWx0O1xuXG4vLyBwYWNrYWdlcy9hbHBpbmVqcy9idWlsZHMvbW9kdWxlLmpzXG52YXIgbW9kdWxlX2RlZmF1bHQgPSBzcmNfZGVmYXVsdDtcbmV4cG9ydCB7XG4gIG1vZHVsZV9kZWZhdWx0IGFzIGRlZmF1bHRcbn07XG4iLCIvLyBJbXBvcnQgZGVwZW5kZW5jaWVzXG4vL1xuLy8gSWYgeW91IG5vIGxvbmdlciB3YW50IHRvIHVzZSBhIGRlcGVuZGVuY3ksIHJlbWVtYmVyXG4vLyB0byBhbHNvIHJlbW92ZSBpdHMgcGF0aCBmcm9tIFwiY29uZmlnLnBhdGhzLndhdGNoZWRcIi5cbmltcG9ydCBjc3MgZnJvbSBcIi4uL2Nzcy9hcHAuc2Nzc1wiXG5cbmltcG9ydCB7dmlzaWJsZSwgbW9zdHJhciwgb2N1bHRhciwgbWVkaWRhc30gZnJvbSBcIi4vYmFzaWNvc1wiXG5pbXBvcnQgXCJwaG9lbml4X2h0bWxcIlxuaW1wb3J0IFwiLi4vdmVuZG9yL2pxdWVyeS5zbHVnZ2VyXCJcbmltcG9ydCBcIi4vcHVibGlcIlxuaW1wb3J0IHtjYW1iaW9fYXBhbmhvc30gZnJvbSBcIi4vcHVibGlcIlxuaW1wb3J0IFwiLi9mb3JtdWxhcmlvc1wiXG4vL2ltcG9ydCBwb3N0c2NyaWJlIGZyb20gJ3Bvc3RzY3JpYmUnXG5pbXBvcnQgcG9zdHNjcmliZSBmcm9tICcuLi92ZW5kb3IvcG9zdHNjcmliZS5taW4nXG4vL2ltcG9ydCBwb3N0Y3JpYmUgZnJvbSAnLi4vdmVuZG9yL3Bvc3RzY3JpYmUnXG4vL2ltcG9ydCBzb2NrZXQgZnJvbSBcIi4vc29ja2V0XCJcbmltcG9ydCB7U29ja2V0fSBmcm9tIFwicGhvZW5peFwiXG5pbXBvcnQgTlByb2dyZXNzIGZyb20gXCJucHJvZ3Jlc3NcIlxuaW1wb3J0IHtMaXZlU29ja2V0fSBmcm9tIFwicGhvZW5peF9saXZlX3ZpZXdcIlxuXG5pbXBvcnQgTGl2ZVNlbGVjdCBmcm9tIFwibGl2ZV9zZWxlY3RcIlxuXG5jb25zdCB1c2VyQWdlbnQgPSBuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCk7XG5jb25zdCBodW1hbiA9IHVzZXJBZ2VudC5pbmNsdWRlcyhcImJvdFwiKSA/IGZhbHNlIDogdHJ1ZSBcblxuLy9pbXBvcnQgJ2FscGluZWpzJztcbmltcG9ydCBBbHBpbmUgZnJvbSAnYWxwaW5lanMnXG53aW5kb3cuQWxwaW5lID0gQWxwaW5lXG5BbHBpbmUuc3RhcnQoKVxuXG5sZXQgY3NyZlRva2VuID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIm1ldGFbbmFtZT0nY3NyZi10b2tlbiddXCIpLmdldEF0dHJpYnV0ZShcImNvbnRlbn
1RcIilcblxuLy8gTk9USUZJQ0FDSU9ORVMgLy9cblxuY29uc3QgYXBwbGljYXRpb25TZXJ2ZXJQdWJsaWNLZXkgPSBcIkJHMkZ2YVd1cmxDWFhleUVONlIwbXVRdWhyQmdpbWk3UXZOamNGSU9vQ045d3llUUpOeFNrRmx1bkF2NjJXc1c3MkpwZURnYkxsRnlWOFA2Wm9ndkVBVVwiXG5cbmxldCBwdXNoQnV0dG9uID0gbnVsbDtcbmxldCBjYW5hbGVzRGl2ID0gbnVsbDtcblxubGV0IGlzU3Vic2NyaWJlZCA9IGZhbHNlO1xubGV0IHN3UmVnaXN0cmF0aW9uID0gbnVsbDtcblxuZnVuY3Rpb24gdXJsQjY0VG9VaW50OEFycmF5KGJhc2U2NFN0cmluZykge1xuICBjb25zdCBwYWRkaW5nID0gJz0nLnJlcGVhdCgoNCAtIGJhc2U2NFN0cmluZy5sZW5ndGggJSA0KSAlIDQpO1xuICBjb25zdCBiYXNlNjQgPSAoYmFzZTY0U3RyaW5nICsgcGFkZGluZylcbiAgICAucmVwbGFjZSgvXFwtL2csICcrJylcbiAgICAucmVwbGFjZSgvXy9nLCAnLycpO1xuXG4gIGNvbnN0IHJhd0RhdGEgPSB3aW5kb3cuYXRvYihiYXNlNjQpO1xuICBjb25zdCBvdXRwdXRBcnJheSA9IG5ldyBVaW50OEFycmF5KHJhd0RhdGEubGVuZ3RoKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHJhd0RhdGEubGVuZ3RoOyArK2kpIHtcbiAgICBvdXRwdXRBcnJheVtpXSA9IHJhd0RhdGEuY2hhckNvZGVBdChpKTtcbiAgfVxuICByZXR1cm4gb3V0cHV0QXJyYXk7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUJ0bigpIHtcbiAgaWYgKE5vdGlmaWNhdGlvbi5wZXJtaXNzaW9uID09PSAnZGVuaWVkJykge1xuICAgIHB1c2hCdXR0b24udGV4dENvbnRlbnQgPSAnTm90aWZpY2FjaW9uZXMgUHVzaCBCbG9xdWVhZGFzLic7XG4gICAgcHVzaEJ1dHRvbi5kaXNhYmxlZCA9IHRydWU7XG4gICAgdXBkYXRlU3Vic2NyaXB0aW9uT25TZXJ2ZXIobnVsbCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGlzU3Vic2NyaWJlZCkge1xuICAgIHB1c2hCdXR0b24udGV4dENvbnRlbnQgPSAnRGVzYWN0aXZhciBOb3RpZmljYWNpb25lcyBQdXNoJztcbiAgfSBlbHNlIHtcbiAgICBwdXNoQnV0dG9uLnRleHRDb250ZW50ID0gJ0FjdGl2YXIgTm90aWZpY2FjaW9uZXMgUHVzaCc7XG4gIH1cblxuICBwdXNoQnV0dG9uLmRpc2FibGVkID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVN1YnNjcmlwdGlvbk9uU2VydmVyKHN1YnNjcmlwdGlvbiwgaW5pY2lhbCkge1xuICB2YXIgY2FuYWxlcyA9IHJhZGlvQ2FuYWxlcygpO1xuICAgIGlmIChpbmljaWFsKSAge1xuICAgIGNhbmFsZXMgPSBbXCJwZXRpY2lvbl9pbmljaWFsXCJdOyBcbiAgICB9XG4gIGlmIChzdWJzY3JpcHRpb24pIHtcbiAgICBzZW5kU3Vic2NyaXB0aW9uVG9CYWNrRW5kKHN1YnNjcmlwdGlvbiwgY2FuYWxlcylcbiAgfVxuICBcbiAgY29uc3Qgc3Vic2NyaXB0aW9uSnNvbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5qcy1zdWJzY3JpcHRpb24tanNvbicpO1xuICBjb25zdCBzdWJzY3JpcHRpb25EZXRhaWxzID1cbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuanMtc3Vic2NyaXB0aW9uLWRldGFpbHMnKTtcblxuICBpZiAoc3Vic2NyaXB0aW9uKSB7XG4gICAgc3Vic2NyaXB0aW9uSnNvbi50ZXh0Q29udGVudCA9IEpTT04uc3RyaW5naWZ5KHN1YnNjcmlwdGlvbik7XG4gICAgc3Vic2NyaXB0aW9uRGV0YWlscy5jbGFzc0xpc3QucmVtb3ZlKCdpcy1pbnZpc2libGUnKTtcbiAgfSBlbHNlIHtcbiAgICBzdWJzY3JpcHRpb25EZXRhaWxzLmNsYXNzTGlzdC5hZGQoJ2lzLWludmlzaWJsZScpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHN1YnNjcmliZVVzZXIoKSB7XG4gIGNvbnN0IGFwcGxpY2F0aW9uU2VydmVyS2V5ID0gdXJsQjY0VG9VaW50OEFycmF5KGFwcGxpY2F0aW9uU2VydmVydWJsaWNLZXkpO1xuICBzd1JlZ2lzdHJhdGlvbi5wdXNoTWFuYWdlci5zdWJzY3JpYmUoe1xuICAgIHVzZXJWaXNpYmxlT25seTogdHJ1ZSxcbiAgICBhcHBsaWNhdGlvblNlcnZlcktleTogYXBwbGljYXRpb25TZXJ2ZXJLZXlcbiAgfSlcbiAgLnRoZW4oZnVuY3Rpb24oc3Vic2NyaXB0aW9uKSB7XG4gICAgdXBkYXRlU3Vic2NyaXB0aW9uT25TZXJ2ZXIoc3Vic2NyaXB0aW9uKTtcbiAgICBpc1N1YnNjcmliZWQgPSB0cnVlO1xuICAgIHVwZGF0ZUJ0bigpO1xuICB9KVxuICAuY2F0Y2goZnVuY3Rpb24oZXJyKSB7XG4gICAgdXBkYXRlQnRuKCk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiB1bnN1YnNjcmliZVVzZXIoKSB7XG4gIHN3UmVnaXN0cmF0aW9uLnB1c2hNYW5hZ2VyLmdldFN1YnNjcmlwdGlvbigpXG4gIC50aGVuKGZ1bmN0aW9uKHN1YnNjcmlwdGlvbikge1xuICAgIGlmIChzdWJzY3JpcHRpb24pIHtcbiAgICAgIGRlbGV0ZVN1YnNjcmlwdGlvbkJhY2tFbmQoc3Vic2NyaXB0aW9uKTtcbiAgICAgIHJldHVybiBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH0pXG4gIC5jYXRjaChmdW5jdGlvbihlcnJvcikge1xuICAgIGNvbnNvbGUubG9nKCdFcnJvciB1bnN1YnNjcmliaW5nJywgZXJyb3IpO1xuICB9KVxuICAudGhlbihmdW5jdGlvbihzdWJzY3JpcHRpb24pIHtcbiAgICB1cGRhdGVTdWJzY3JpcHRpb25PblNlcnZlcihudWxsKTtcblxuICAgIGNvbnNvbGUubG9nKCdVc2VyIGlzIHVuc3Vic2NyaWJlZC4nKTtcbiAgICBpc1N1YnNjcmliZWQgPSBmYWxzZTtcblxuICAgIHVwZGF0ZUJ0bigpO1xuICAgIC8vdXBkYXRlQ2FuYWxlcyhbXSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBpbml0aWFsaXplTm90aWZpY2F0aW9uc1VJKGhvb2spIHtcbiAgcHVzaEJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgIHB1c2hCdXR0b24uZGlzYWJsZWQgPSB0cnVlO1xuICAgIGlmIChpc1N1YnNjcmliZWQpIHtcbiAgICAgIGhvb2sucHVzaEV2ZW50KFwic3VzY3JpdG9cIiwge1wic3VzY3JpdG9cIjogXCJzdXNjcml0b1wifSlcbiAgICAgIHVuc3Vic2NyaWJlVXNlcigpO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIGhvb2sucHVzaEV2ZW50KFwic3VzY3JpdG9cIiwge1wic3VzY3JpdG9cIjogXCJub19zdXNjcml0b1wifSlcbiAgICAgIHN1YnNjcmliZVVzZXIoKTtcbiAgICB9XG4gI
1H0pO1xuXG4gIC8vIFNldCB0aGUgaW5pdGlhbCBzdWJzY3JpcHRpb24gdmFsdWVcbiAgc3dSZWdpc3RyYXRpb24ucHVzaE1hbmFnZXIuZ2V0U3Vic2NyaXB0aW9uKClcbiAgLnRoZW4oZnVuY3Rpb24oc3Vic2NyaXB0aW9uKSB7XG4gICAgaXNTdWJzY3JpYmVkID0gIShzdWJzY3JpcHRpb24gPT09IG51bGwpO1xuXG4gICAgdXBkYXRlU3Vic2NyaXB0aW9uT25TZXJ2ZXIoc3Vic2NyaXB0aW9uLCBcImluaWNpYWxcIik7XG5cbiAgICB1cGRhdGVCdG4oKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHNlbmRTdWJzY3JpcHRpb25Ub0JhY2tFbmQoc3Vic2NyaXB0aW9uLCBjYW5hbGVzKSB7XG4gIHN1YnNjcmlwdGlvbiA9IHtcInN1c2NyaXBjaW9uX3B1c2hcIjogc3Vic2NyaXB0aW9uLCBcImNhbmFsZXNcIjogY2FuYWxlc31cbiAgcmV0dXJuIGZldGNoKCcvYXBpL3N1c2NyaXBjaW9uZXNwdXNoLycsIHtcbiAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICBoZWFkZXJzOiB7XG4gICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgIH0sXG4gICAgYm9keTogSlNPTi5zdHJpbmdpZnkoc3Vic2NyaXB0aW9uKSxcbiAgfSlcbiAgICAudGhlbihmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdCYWQgc3RhdHVzIGNvZGUgZnJvbSBzZXJ2ZXIuJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xuICAgIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKHJlc3BvbnNlRGF0YSkge1xuICAgICAgaWYgKCEocmVzcG9uc2VEYXRhLmRhdGEgJiYgcmVzcG9uc2VEYXRhLmRhdGEuc3VjY2VzcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdCYWQgcmVzcG9uc2UgZnJvbSBzZXJ2ZXIuJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmxvZyhyZXNwb25zZURhdGEuZGF0YSk7XG4gICAgICB1cGRhdGVDYW5hbGVzKHJlc3BvbnNlRGF0YS5kYXRhW1wiY2FuYWxlc1wiXSwgcmVzcG9uc2VEYXRhLmRhdGFbXCJzdXNjcmlwY2lvbmVzXCJdKTtcbiAgICAgIH1cbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gZGVsZXRlU3Vic2NyaXB0aW9uQmFja0VuZChzdWJzY3JpcHRpb24pIHtcbiAgY29uc3QgZW5kcG9pbnQgPSBlbmNvZGVVUklDb21wb25lbnQoc3Vic2NyaXB0aW9uLmVuZHBvaW50KVxuICByZXR1cm4gZmV0Y2goJy9hcGkvc3VzY3JpcGNpb25lc3B1c2gvJyArIGVuZHBvaW50LCB7XG4gICAgbWV0aG9kOiAnREVMRVRFJyxcbiAgICBoZWFkZXJzOiB7XG4gICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgIH1cbiAgfSlcbiAgICAudGhlbihmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdCYWQgc3RhdHVzIGNvZGUgZnJvbSBzZXJ2ZXIuJyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XG4gICAgfSlcbiAgICAudGhlbihmdW5jdGlvbiAocmVzcG9uc2VEYXRhKSB7XG4gICAgICBpZiAoIShyZXNwb25zZURhdGEuZGF0YSAmJiByZXNwb25zZURhdGEuZGF0YS5zdWNjZXNzKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0JhZCByZXNwb25zZSBmcm9tIHNlcnZlci4nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICB1cGRhdGVDYW5hbGVzKFtdKTtcbiAgICAgIH1cbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlQ2FuYWxlcyhjYW5hbGVzLCBjYW5hbGVzX2FjdGl2b3MpIHtcbiAgY2FuYWxlc0Rpdi5pbm5lckhUTUwgPSBcIlwiO1xuICBmb3IgKGNvbnN0IGNhbmFsIG9mIGNhbmFsZXMpIHtcbiAgICAgY3JlYXRlQ2FuYWwoY2FuYWwsIGNhbmFsZXNfYWN0aXZvcyk7XG4gIH1cbn0gXG5cbmZ1bmN0aW9uIGNyZWF0ZUNhbmFsKGNhbmFsLCBjYW5hbGVzX2FjdGl2b3MpIHtcbiAgdmFyIGFjdGl2byA9IGZhbHNlO1xuICBmb3IgKGNvbnN0IGNhbmFsX2FjdGl2byBvZiBjYW5hbGVzX2FjdGl2b3MpIHsgXG4gICAgaWYgKGNhbmFsX2FjdGl2byA9PSBjYW5hbC5pZCkgeyBcbiAgICAgIHZhciBhY3Rpdm8gPSB0cnVlOyBcbiAgICB9XG4gIH1cblxuICB2YXIgY2hlY2tlZCA9IFwiXCI7XG4gIGlmIChhY3Rpdm8pIHsgY2hlY2tlZCA9IFwiY2hlY2tlZFwiOyB9XG5cbiAgdmFyIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cbiAgdmFyIGxhYmVsX2wgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsYWJlbCcpO1xuICBsYWJlbF9sLmh0bWxGb3IgPSBjYW5hbC5pZDtcbiAgbGFiZWxfbC5pbm5lckhUTUwgPSBjYW5hbC5ub21icmU7ICAgIFxuICBkaXYuYXBwZW5kQ2hpbGQobGFiZWxfbCk7XG5cbiAgdmFyIHNwYW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKTtcbiAgc3Bhbi5jbGFzc0xpc3QuYWRkKCdja2J4LXN0eWxlLTEnKVxuXG4gIHZhciBidXR0b24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7XG4gIGJ1dHRvbi50eXBlID0gXCJjaGVja2JveFwiO1xuICBidXR0b24udmFsdWUgPSBjYW5hbC5pZDtcbiAgYnV0dG9uLmlkID0gY2FuYWwuaWQ7XG4gIGJ1dHRvbi5jaGVja2VkID0gY2hlY2tlZDtcbiAgc3Bhbi5hcHBlbmRDaGlsZChidXR0b24pO1xuXG4gIHZhciBsYWJlbF9jID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGFiZWwnKTtcbiAgbGFiZWxfYy5odG1sRm9yID0gY2FuYWwuaWQ7XG4gIHNwYW4uYXBwZW5kQ2hpbGQobGFiZWxfYyk7XG4gIGRpdi5hcHBlbmRDaGlsZChzcGFuKTtcblxuICBjYW5hbGVzRGl2LmFwcGVuZENoaWxkKGRpdik7XG5cbiAgYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIChldmVudCkgPT4ge1xuICBzdWJzY3JpYmVVc2VyKClcbiAgfSlcbn1cblxuZnVuY3Rpb24gcmFkaW9DYW5hbGVzKCkge1xuICBsZXQgYWN0aXZhZG9zID0gW107XG4gIGxldCBjaGVja2JveGVzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnaW5wdXQ6Y2hlY2tlZCcpO1xuICBjaGVja2JveGVzLmZvckVhY2goKGNoZWNrYm94KSA9PiB7XG4gICAgYWN0aXZhZG9zLnB1c2goY2hlY2tib3gudmFsdWUpO1xuICB9KTtcbiAgcmV0dXJuIGFjdGl2YWRvcztcbn1cblxuZnVuY3Rpb24gaGFuZGxlQ29ubmVjdGlvbigpIHtcbiAgaWYgKG5hdmlnYXRvci5vbkxpbmUpIHtcbiAgICBpc1JlYWNoYWJsZShnZXRTZXJ2ZXJVcmwoKSkudGhlbihmdW5jdGlvbihvbmxpbmUpIHtcbiAgICAgIGlmIChvbmxpbmUpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ29ubGluZScpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5sb2coJ25vIGNvbm5lY3Rpdml0eScpO1xuICAgICAgfVxuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUubG9nKCdvZmZsaW5lJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNSZWFjaGFibGUodXJsKSB7XG4gIHJldHVybi
1BmZXRjaCh1cmwsIHsgbWV0aG9kOiAnSEVBRCcsIG1vZGU6ICduby1jb3JzJyB9KVxuICAgIC50aGVuKGZ1bmN0aW9uKHJlc3ApIHtcbiAgICAgIHJldHVybiByZXNwICYmIChyZXNwLm9rIHx8IHJlc3AudHlwZSA9PT0gJ29wYXF1ZScpO1xuICAgIH0pXG4gICAgLmNhdGNoKGZ1bmN0aW9uKGVycikge1xuICAgICAgY29uc29sZS53YXJuKCdbY29ubiB0ZXN0IGZhaWx1cmVdOicsIGVycik7XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldFNlcnZlclVybCgpIHtcbiAgcmV0dXJuICB3aW5kb3cubG9jYXRpb24ub3JpZ2luO1xufVxuXG4vLyBGSU4gTk9USUZJQ0FDSU9ORVNcblxuY29uc3Qgc3VtbWVyTm90ZU1pbiA9IHtcbiAgc3R5bGVXaXRoU3BhbjogZmFsc2UsXG4gIGxhbmc6ICdlcy1FUycsXG4gIGhlaWdodDogNDAwLFxuICBkaWFsb2dzRmFkZTogdHJ1ZSAgLFxuICB0b29sYmFyOiBbXG4gICAgWydzdHlsZScsIFsnaXRhbGljJywgJ3VuZGVybGluZScsICdjbGVhciddXSxcbiAgICBbJ2luc2VydCcsIFsnbGluaycsICd1bmxpbmsnXV0sXG4gIF0sXG4gIGNsZWFuZXI6e1xuICAgIG5vdFRpbWU6IDUwMCwgLy8gVGltZSB0byBkaXNwbGF5IE5vdGlmaWNhdGlvbnMuXG4gICAgYWN0aW9uOiAnYm90aCcsIC8vIGJvdGh8YnV0dG9ufHBhc3RlICdidXR0b24nIG9ubHkgY2xlYW5zIHZpYSB0b29sYmFyIGJ1dHRvbiwgJ3Bhc3RlJyBvbmx5IGNsZWFuIHdoZW4gcGFzdGluZyBjb250ZW50LCBib3RoIGRvZXMgYm90aCBvcHRpb25zLlxuICAgIG5ld2xpbmU6ICc8YnI+JywgLy8gU3VtbWVybm90ZSdzIGRlZmF1bHQgaXMgdG8gdXNlICc8cD48YnI+PC9wPidcbiAgICBub3RTdHlsZTogJ3Bvc2l0aW9uOmFic29sdXRlO3RvcDowO2xlZnQ6MDtyaWdodDowJywgLy8gUG9zaXRpb24gb2YgTm90aWZpY2F0aW9uXG4gICAgaWNvbjogJzxpIGNsYXNzPVwibm90ZS1pY29uXCI+W3hdPC9pPicsXG4gICAga2VlcEh0bWw6IHRydWUsIC8vIFJlbW92ZSBhbGwgSHRtbCBmb3JtYXRzXG4gICAga2VlcENsYXNzZXM6IGZhbHNlLCAvLyBSZW1vdmUgQ2xhc3Nlc1xuICAgIGtlZXBPbmx5VGFnczogWyc8YnI+JywnPGE+JywnPHA+J10sIC8vIElmIGtlZXBIdG1sIGlzIHRydWUsIHJlbW92ZSBhbGwgdGFncyBleGNlcHQgdGhlc2VcbiAgICBiYWRUYWdzOiBbJ3N0eWxlJywgJ3NjcmlwdCcsICdhcHBsZXQnLCAnZW1iZWQnLCAnbm9mcmFtZXMnLCAnbm9zY3JpcHQnLCAnaHRtbCddLCAvLyBSZW1vdmUgZnVsbCB0YWdzIHdpdGggY29udGVudHNcbiAgICBrZWVwVGFnQ29udGVudHM6IFsnc3BhbicsJ2ZvbnQnLCdzdHJvbmcnXSwgLy8gUmVtb3ZlIGZ1bGwgdGFncyB3aXRoIGNvbnRlbnRzXG4gICAgYmFkQXR0cmlidXRlczogWydkaXInLCdpZCcsJ3N0eWxlJywgJ3N0YXJ0JywnbmFtZScsJ2NsYXNzJywnYWxpZ24nLCdvbnRvdWNoc3RhcnQnLCdzaXplJywnZmFjZScsICdsYW5nJ10gLy8gUmVtb3ZlIGF0dHJpYnV0ZXMgZnJvbSByZW1haW5pbmcgdGFnc1xuICB9LFxufTtcbmNvbnN0IHN1bW1lck5vdGVDb25mID0ge1xuICBzdHlsZVdpdGhTcGFuOiBmYWxzZSxcbiAgbGFuZzogJ2VzLUVTJyxcbiAgaGVpZ2h0OiA0MDAsXG4gIGRpYWxvZ3NGYWRlOiB0cnVlICAsXG4gIHRvb2xiYXI6IFtcbiAgICBbJ3N0eWxlJywgWydib2xkJywgJ2l0YWxpYycsICd1bmRlcmxpbmUnLCAnY2xlYXInXV0sXG4gICAgWydmb250JywgWydzdHJpa2V0aHJvdWdoJywgJ3N1cGVyc2NyaXB0JywgJ3N1YnNjcmlwdCddXSxcbiAgICBbJ3BhcmEnLCBbJ3VsJywgJ29sJywgJ3BhcmFncmFwaCddXSxcbiAgICBbJ2xpbmsnLFsnc3R5bGUnXV0sXG4gICAgWydpbnNlcnQnLCBbJ2xpbmsnLCAndW5saW5rJ11dLFxuICAgIFsnc2FsdG8nLCBbJ2FydGljdWxvJywnZm90bycsJ2NvZGlnbycsJ2RvY3VtZW50bycsICdib3JyYXInXV0sXG4gICAgWyd2aWV3JyxbJ2NvZGV2aWV3J11dLFxuICAgIFsnaW5zZXJ0JywgWyd0ZW1wbGF0ZSddXVxuICBdLFxuICBwb3BvdmVyOiB7XG4gICAgaW1hZ2U6IFtcbiAgICAgIFsnY3VzdG9tJywgWydpbWFnZUF0dHJpYnV0ZXMnLCdjYXB0aW9uSXQnXV0sXG4gICAgICBbJ2ltYWdlc2l6ZScsIFsnaW1hZ2VTaXplMTAwJywgJ2ltYWdlU2l6ZTUwJywgJ2ltYWdlU2l6ZTI1J11dLFxuICAgICAgWydmbG9hdCcsIFsnZmxvYXRMZWZ0JywgJ2Zsb2F0UmlnaHQnLCAnZmxvYXROb25lJ11dLFxuICAgICAgWydyZW1vdmUnLCBbJ3JlbW92ZU1lZGlhJ11dXG4gICAgXSxcbiAgfSxcbiAgaW1hZ2VBdHRyaWJ1dGVzOntcbiAgICBpbWFnZURpYWxvZ0xheW91dDonZGVmYXVsdCcsIC8vIGRlZmF1bHR8aG9yaXpvbn
1RhbFxuICAgIGljb246JzxpIGNsYXNzPVwibm90ZS1pY29uLXBlbmNpbFwiLz4nLFxuICAgIHJlbW92ZUVtcHR5OmZhbHNlIC8vIHRydWUgPSByZW1vdmUgYXR0cmlidXRlcyB8IGZhbHNlID0gbGVhdmUgZW1wdHkgaWYgcHJlc2VudFxuICB9LFxuICBkaXNwbGF5RmllbGRzOntcbiAgICBpbWFnZUJhc2ljOnRydWUsICAvLyBzaG93L2hpZGUgVGl0bGUsIFNvdXJjZSwgQWx0IGZpZWxkc1xuICAgIGltYWdlRXh0cmE6dHJ1ZSwgLy8gc2hvdy9oaWRlIEFsdCwgQ2xhc3MsIFN0eWxlLCBSb2xlIGZpZWxkc1xuICAgIGxpbmtCYXNpYzp0cnVlLCAgIC8vIHNob3cvaGlkZSBVUkwgYW5kIFRhcmdldCBmaWVsZHMgZm9yIGxpbmtcbiAgICBsaW5rRXh0cmE6ZmFsc2UgICAvLyBzaG93L2hpZGUgQ2xhc3MsIFJlbCwgUm9sZSBmaWVsZHMgZm9yIGxpbmtcbiAgfSxcbiAgY2FwdGlvbkl0OntcbiAgICBpY29uOic8aSBjbGFzcz1cIm5vdGUtaWNvbi1wZW5jaWxcIn0vPicsIC8vIExlYXZlIGVtcHR5IG9yIGRvbid0IHNldCBmb3IgZGVmYXVsdCBJY29uLlxuICAgIGZpZ3VyZUNsYXNzOidmaWd1cmUtaW50ZXJuYScsXG4gICAgZmlnY2FwdGlvbkNsYXNzOidwaWUnLFxuICB9LFxuICBjbGVhbmVyOntcbiAgICBub3RUaW1lOiA1MDAsIC8vIFRpbWUgdG8gZGlzcGxheSBOb3RpZmljYXRpb25zLlxuICAgIGFjdGlvbjogJ2JvdGgnLCAvLyBib3RofGJ1dHRvbnxwYXN0ZSAnYnV0dG9uJyBvbmx5IGNsZWFucyB2aWEgdG9vbGJhciBidXR0b24sICdwYXN0ZScgb25seSBjbGVhbiB3aGVuIHBhc3RpbmcgY29udGVudCwgYm90aCBkb2VzIGJvdGggb3B0aW9ucy5cbiAgICBuZXdsaW5lOiAnPGJyPicsIC8vIFN1bW1lcm5vdGUncyBkZWZhdWx0IGlzIHRvIHVzZSAnPHA+PGJyPjwvcD4nXG4gICAgbm90U3R5bGU6ICdwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtsZWZ0OjA7cmlnaHQ6MCcsIC8vIFBvc2l0aW9uIG9mIE5vdGlmaWNhdGlvblxuICAgIGljb246ICc8aSBjbGFzcz1cIm5vdGUtaWNvblwiPlt4XTwvaT4nLFxuICAgIGtlZXBIdG1sOiB0cnVlLCAvLyBSZW1vdmUgYWxsIEh0bWwgZm9ybWF0c1xuICAgIGtlZXBDbGFzc2VzOiBmYWxzZSwgLy8gUmVtb3ZlIENsYXNzZXNcbiAgICBrZWVwT25seVRhZ3M6IFsnPGJyPicsJzxhPicsJzxwPiddLCAvLyBJZiBrZWVwSHRtbCBpcyB0cnVlLCByZW1vdmUgYWxsIHRhZ3MgZXhjZXB0IHRoZXNlXG4gICAgYmFkVGFnczogWydzdHlsZScsICdzY3JpcHQnLCAnYXBwbGV0JywgJ2VtYmVkJywgJ25vZnJhbWVzJywgJ25vc2NyaXB0JywgJ2h0bWwnXSwgLy8gUmVtb3ZlIGZ1bGwgdGFncyB3aXRoIGNvbnRlbnRzXG4gICAga2VlcFRhZ0NvbnRlbnRzOiBbJ3NwYW4nLCdmb250Jywnc3Ryb25nJ10sIC8vIFJlbW92ZSBmdWxsIHRhZ3Mgd2l0aCBjb250ZW50c1xuICAgIGJhZEF0dHJpYnV0ZXM6IFsnZGlyJywnaWQnLCdzdHlsZScsICdzdGFydCcsJ25hbWUnLCdjbGFzcycsJ2FsaWduJywnb250b3VjaHN0YXJ0Jywnc2l6ZScsJ2ZhY2UnLCAnbGFuZyddIC8vIFJlbW92ZSBhdHRyaWJ1dGVzIGZyb20gcmVtYWluaW5nIHRhZ3NcbiAgfSxcbiAgdGVtcGxhdGU6IHtcbiAgICBwYXRoOiAnL2pzL3N1bW1lcm5vdGUvdHBscycsXG4gICAgbGlzdDoge1xuICAgICAgJ3JlY3VhZHJvX2dlbmVyaWNvJzogJ1JlY3VhZHJvIGdlbsOpcmljbycsXG4gICAgICAncmVjdWFkcm9fZGNoYSc6ICdSZWN1YWRybyBkZXJlY2hvJyxcbiAgICAgICdyZWN1YWRyb19penEnOiAnUmVjdWFkcm8gaXpxdWllcmRvJyxcbiAgICAgICdyZWN1YWRybyc6ICdSZWN1YWRybyBcImFudGlndW9cIidcbiAgICB9XG4gIH1cbn07XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicGh4OnF1aXRhci1ib2R5LW92ZXJmbG93c1wiLCAoZSkgPT4ge1xuICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiYm9keVwiKS5jbGFzc0xpc3QucmVtb3ZlKFwib3ZlcmZsb3dcIik7XG59KVxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJhcnRpY3VsaXN0YTpsaW1waWFyX3VybFwiLCAoZSkgPT4ge1xuICBoaXN0b3J5LnJlcGxhY2VTdGF0ZSgnJywgZG9jdW1lbnQudGl0bGUsIHdpbmRvdy5sb2NhdGlvbi5ocmVmLnNwbGl0KCcjJylbMF0pOyBcbn0pO1xud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJhcnRpY3VsaXN0YTptZW51XCIsIChlKSA9PiB7XG4gIHZhciB3ID0gd2luZG93LmlubmVyV2lkdGhcbiAgICB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGhcbiAgICB8fCBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoO1xuICBpZiAodyA+IDc2OCAmJiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjbWVudS1idXItY29udGVuZWRvcicpKXtcbiAgICB2YXIgbWVudV9hZG1pbiA9IDA7XG4gICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNtZW51LWFkbWluJykpe1xuICAgICAgbWVudV9hZG1pbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNtZW51LWFkbWluJykub2Zmc2V0SGVpZ2h0O1xuICAgIH1cbiAgICB2YXIgcHVibGkgPSAwO1xuICAgIGlmICh2aXNpYmxlKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwdWJsaS1jYWJlY2VyYScpKSl7XG4gICAgICB2Y
1XIge2JvdHRvbX0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHVibGktY2FiZWNlcmEnKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgICAgaWYgKGJvdHRvbSA+IDEpe1xuICAgICAgICBwdWJsaSA9IGJvdHRvbTtcbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIG1lbnVfYXJyaWJhID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI21lbnUtYXJyaWJhJykub2Zmc2V0SGVpZ2h0IC0gMTtcbiAgICB2YXIgYWJham8gPSBtZW51X2FycmliYSArIG1lbnVfYWRtaW4gKyBwdWJsaVxuXG4gICAgY29uc3QgbWVudV8xID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI21lbnUtYnVyLWNvbnRlbmVkb3InKTtcbiAgICBtZW51XzEuc3R5bGUudG9wID0gYCR7bWVudV9hcnJpYmF9cHhgO1xuICAgIG1lbnVfMS5zdHlsZS5oZWlnaHQgPSBgY2FsYygxMDB2aCAtICR7YWJham99cHgpYDtcblxuXG4gICAgY29uc3QgbWVudV9zZWNjaW9uZXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubWVudS1zZWNjaW9uZXMnKTtcbiAgICBjb25zdCBtZW51X3NlY2Npb25lc19jb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcIm1lbnUtc2VjY2lvbmVzLWVzY3JpdG9yaW9cIilcbiAgICBtZW51X3NlY2Npb25lc19jb250YWluZXIuYXBwZW5kQ2hpbGQobWVudV9zZWNjaW9uZXMpO1xuXG4gICAgY29uc3QgbWVudV9zZWNjaW9uZXNfaCA9IG1lbnVfc2VjY2lvbmVzLm9mZnNldEhlaWdodCAvIDI7XG4gICAgdmFyIHt0b3B9ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNlY2Npb25lcycpLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG5cbiAgICBtZW51X3NlY2Npb25lc19jb250YWluZXIuc3R5bGUudG9wID0gYCR7dG9wIC0gKG1lbnVfc2VjY2lvbmVzX2gpfXB4YDtcblxuICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjbWVudS1wZXJzb25hbC1jb250ZW5lZG9yJykpe1xuICAgICAgY29uc3QgbWVudV8yID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI21lbnUtcGVyc29uYWwtY29udGVuZWRvcicpO1xuICAgICAgbWVudV8yLnN0eWxlLnRvcCA9IGAke21lbnVfYXJyaWJhfXB4YDtcbiAgICAgIG1lbnVfMi5zdHlsZS5oZWlnaHQgPSBgY2FsYygxMDB2aCAtICR7YWJham99cHgpYDtcbiAgICB9XG4gIH1cbiAgaWYgKHcgPCA3NjggJiYgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI21lbnUtYnVyLWNvbnRlbmVkb3InKSl7XG4gICAgY29uc3QgbWVudV9zZWNjaW9uZXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubWVudS1zZWNjaW9uZXMnKTtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcIm1lbnUtc2VjY2lvbmVzLW1vdmlsXCIpXG4gICAgICAuYXBwZW5kQ2hpbGQobWVudV9zZWNjaW9uZXMpO1xuICB9XG59KTtcblxuLy8gQmFzZSBBVURJT1MgXG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicGh4OmNhbWJpYXItc2VsZWNjaW9uXCIsIChlKSA9PiB7XG4gIGlmIChhdWRpby5wYXVzZWQpIHtcbiAgICBsaXZlU29ja2V0Lmhvb2tzLkF1ZGlvUGxheWVyLmRhdG9zX2F1ZGlvKCk7IFxuICB9O1xufSlcbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicGh4OnBsYXktc2VsZWNjaW9uXCIsIChlKSA9PiB7XG4gIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInNlbGVjY2lvbmFyXCIpKSB7XG4gICAgbGl2ZVNvY2tldC5ob29rcy5BdWRpb1NlbGVjY2lvbmFyLm1vdW50ZWQoKTtcbiAgfVxuICBhdWRpb19vcmlnZW4gPSBcInJlY29tZW5kYWNpb25cIjtcbiAgbGl2ZVNvY2tldC5ob29rcy5BdWRpb1BsYXllci5hdWRpb19yZXByb2R1Y2lyKCk7IFxufSlcblxuZnVuY3Rpb24gc2VndW5kb3NfYV9zdHJpbmcocykge1xuICBpZiAocyA9PT0gXCJ1bmRlZmluZWRcIiB8fCBzID09IDAgfHwgaXNOYU4ocykpIHJldHVybiBcIjAwOjAwXCI7XG4gIGNvbnN0IGggPSBNYXRoLmZsb29yKHMgLyAzNjAwKVxuICBjb25zdCBtID0gTWF0aC5mbG9vcigocyAlIDM2MDApIC8gNjApXG4gIHMgPSBzICUgNjA7XG4gIHMgPSBwYXJzZUludChzKTtcbiAgcmV0dXJuIFtoLCBtID4gOSA/IG0gOiBoID8gJzAnICsgbSA6IG0gfHwgJzAnLCBzID4gOSA/IHMgOiAnMCcgKyBzXVxuICAgIC5maWx0ZXIoYSA9PiBhKVxuICAgIC5qb2luKCc6Jylcbn1cbnZhciByYWRpb2JvdF9hcGkgPSBcIndzczovL3JhZGlvLnJhZGlvYm90Lm9yZy9hcGkvbGl2ZS9ub3dwbGF5aW5nL3dlYnNvY2tldFwiXG52YXIgc29ja2V0X3JhZGlvX2JvdCA9IGZhbHNlXG5cbmxldCBhdWRpbyA9IGZhbHNlXG5sZXQgYXVkaW9fb3JpZ2VuID0gXCJyZWNvbWVuZGFjaW9uXCJcbnZhciBhdWRpb19wcm9ncmVzbyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwcm9ncmVzby1hdWRpbycpO1xudmFyIGF1ZGlvX21vbWVudG8gPSAwO1xudmFyIGF1ZGlvX3Bvc2l0aW9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNhdWRpby1wb3NpdGlvblwiKTtcblxuY29uc3QgaG9va3MgPSB7XG4gIFRyYWNrRXZlbnQ6ICB7XG4gICAgbW91bnRlZCgpIHtcbiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZSkgPT4ge1xuICAgICAgICBpZiAodGhpcy5saXZlU29ja2V0LmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhlLnRhcmdldCk7XG4gICAgICAgICAgY29uc3QgZWwgPSBlLnRhcmdldC5jbG9zZXN0KFwiW2lkXVwiKVxuICAgICAgICAgIGNvbnNvbGUubG9nKGVsKTtcblxuICAgICAgICAgIHRoaXMucHVzaEV2ZW50KFwidHJhY2tfZXZlbnRcIiwge1xuICAgICAgICAgICAgdGFnOiBlLnRhcmdldC50YWdOYW1lLFxuICAgICAgICAgICAgaWQ6IGVsLmlkLFxuICAgICAgICAgICAgcGF0aDogbG9jYXRpb24ucGF0aG5hbWVcbiAgICAgICAgICB9KS5jYXRjaCgoKSA9PiB7fSlcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9LFxuICAgIGRlc3Ryb3llZCgpIHtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCB0aGlzLmNsaWNrSGFuZGxlcilcbiAgICB9XG4gIH0sXG4gIFNjcm9sbFRvSW5pY2lvOiB7XG4gICAgdXBkYXRlZCgpIHtcbiAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJsaXN0YS1pbmljaW9cIilcbiAgICAgIGlmIChlbCkge1xuICAgICAgICAvL2VsLnNjcm9sbEludG9WaWV3KHsgYmVoYXZpb3I6IFwic21vb3RoXCIgfSlcbiAgICAgICAgY29uc3QgeSA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcCArIHdpbmRvdy5zY3JvbGxZIC0gMTAwXG5cbiAgICAgICAgd2luZG93LnNjcm9sbFRvKHtcbiAgICAgICAgICB0b3A6IHksXG4gICAgICAgICAgYmVoYXZpb3I6IFwic21vb3RoXCJcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9XG4gI
1H0sXG4gIE1hbnRlbmVyU2Nyb2xsOiB7XG4gICAgbW91bnRlZCgpIHtcbiAgICAgIHRoaXMuc2Nyb2xsWCA9IHdpbmRvdy5zY3JvbGxYO1xuICAgICAgdGhpcy5zY3JvbGxZID0gd2luZG93LnNjcm9sbFk7XG4gICAgfSxcbiAgICB1cGRhdGVkKCkge1xuICAgICAgaWYgKHRoaXMuc2Nyb2xsWCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgd2luZG93LnNjcm9sbFRvKHRoaXMuc2Nyb2xsWCwgdGhpcy5zY3JvbGxZKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICB0aGlzLnNjcm9sbFggPSB3aW5kb3cuc2Nyb2xsWDtcbiAgICAgIHRoaXMuc2Nyb2xsWSA9IHdpbmRvdy5zY3JvbGxZO1xuICAgIH1cbiAgfSxcbiAgRWxlY2Npb25lc0NoYXJ0OiB7XG4gICAgbW91bnRlZCgpIHtcbiAgICAgIHRoaXMuY2FyZ2FyRDMoKTtcbiAgICB9LFxuICAgIGNhcmdhckQzKCkge1xuICAgICAgaWYgKHR5cGVvZiBkMyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhpcy5pbmljaWFsaXphcigpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBcbiAgICAgIGNvbnN0IHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuICAgICAgc2NyaXB0LnNyYyA9ICdodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9kMy82LjAuMC9kMy5taW4uanMnO1xuICAgICAgc2NyaXB0LmludGVncml0eSA9ICdzaGE1MTItOXVKQjZabUwyVWhCa1FIMlgxQitsYkVGSUR0bGF1TzBmUFVwMFJkbzZUejIxYTFhd2dTRCtGZlN5a3ZkK2dEM2M4V1Fyd1dlYUVnTWtQc0RlcDNQOHc9PSc7XG4gICAgICBzY3JpcHQuY3Jvc3
1NPcmlnaW4gPSAnYW5vbnltb3VzJztcbiAgICAgIHNjcmlwdC5yZWZlcnJlclBvbGljeSA9ICduby1yZWZlcnJlcic7XG4gICAgICBcbiAgICAgIHNjcmlwdC5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgIC8vIEZhbGxiYWNrOiBhc2VndXJhciBxdWUgRDMgZXN0w6kgZGlzcG9uaWJsZVxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuaW5pY2lhbGl6YXIoKSwgNTApO1xuICAgICAgfTtcbiAgICAgIFxuICAgICAgLy8gRmFsbGJhY2sgc2kgb25sb2FkIG5vIGZ1bmNpb25hXG4gICAgICBzY3JpcHQub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmluaWNpYWxpemFyKCksIDUwMCk7XG4gICAgICB9O1xuICAgICAgXG4gICAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHNjcmlwdCk7XG4gICAgfSxcbiAgICBpbmljaWFsaXphcigpIHtcbiAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgIGRhdGE6IEpTT04ucGFyc2UodGhpcy5lbC5kYXRhc2V0LmRhdG9zIHx8ICd7fScpLFxuICAgICAgICBhbmhvOiB0aGlzLmVsLmRhdGFzZXQuYW5obyxcbiAgICAgICAgdGVycml0b3JpbzogdGhpcy5lbC5kYXRhc2V0LnRlcnJpdG9yaW8sXG4gICAgICAgIGRhdG9zQ29uc3VsdGE6IEpTT04ucGFyc2UodGhpcy5lbC5kYXRhc2V0LmRhdG9zQ29uc3VsdGEgfHwgJ3t9JylcbiAgICAgIH07XG4gICAgICB0aGlzLmRyYXdfYWxsKCk7XG4gICAgfSxcbiAgICB1cGRhdGVkKCkge1xuICAgICAgdGhpcy5zdGF0ZS5hbmhvID0gdGhpcy5lbC5kYXRhc2V0LmFuaG87XG4gICAgICB0aGlzLnN0YXRlLnRlcnJpdG9yaW8gPSB0aGlzLmVsLmRhdGFzZXQudGVycml0b3JpbztcbiAgICAgIHRoaXMuZHJhd19hbGwoKTtcbiAgICB9LFxuICAgIGdldFNpemUoaWQpIHtcbiAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICAgICAgaWYgKCFlbCB8fCAhZWwuY2xpZW50V2lkdGgpIHJldHVybiBudWxsO1xuICAgICAgcmV0dXJuIHsgd2lkdGg6IGVsLmNsaWVudFdpZHRoLCBoZWlnaHQ6IGVsLmNsaWVudFdpZHRoLzk1MCoyNTAgfTtcbiAgICB9LFxuICAgIHJlc3BvbnNpdmVmeShzdmcpIHtcbiAgICAgIGNvbnN0IGMgPSBkMy5zZWxlY3Qoc3ZnLm5vZGUoKS5wYXJlbnROb2RlKTtcbiAgICAgIGNvbnN0IHcgPSBwYXJzZUludChzdmcuc3R5bGUoXCJ3aWR0aFwiKSk7XG4gICAgICBjb25zdCBoID0gcGFyc2VJbnQoc3ZnLnN0eWxlKFwiaGVpZ2h0XCIpKTtcbiAgICAgIHN2Zy5hdHRyKFwidmlld0JveFwiLCBgMCAwICR7d30gJHtofWApLmF0dHIoXCJwcmVzZXJ2ZUFzcGVjdFJhdGlvXCIsIFwieE1pbllNaWQgbWVldFwiKTtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicmVzaXplXCIsICgpID0+IHtcbiAgICAgICAgY29uc3QgbncgPSBwYXJzZUludChjLnN0eWxlKFwid2lkdGhcIikpO1xuICAgICAgICBzdmcuYXR0cihcIndpZHRoXCIsIG53KS5hdHRyKFwiaGVpZ2h0XCIsIE1hdGgucm91bmQobncqaC93KSk7XG4gICAgICB9KTtcbiAgICB9LFxuICAgIGNyZWF0ZVN2ZyhpZCwgdywgaCkge1xuICAgICAgY29uc3QgYyA9IGQzLnNlbGVjdCgnIycraWQpOyBjLnNlbGVjdEFsbCgnKicpLnJlbW92ZSgpO1xuICAgICAgcmV0dXJuIGMuYXBwZW5kKCdzdmcnKS5hdHRyKCd3aWR0aCcsIHcpLmF0dHIoJ2hlaWdodCcsIGgpLmNhbGwodGhpcy5yZXNwb25zaXZlZnkpLmFwcGVuZCgnZycpO1xuICAgIH0sXG4gICAgY3JlYXRlRGF0b3NTdmcod2lkdGgsIGhlaWdodCl7XG4gICAgICB2Y
1XIgc2l6ZSA9IDE2O1xuICAgICAgaWYgKHdpZHRoPCA2MDApe3NpemUgPSAxM31cbiAgICAgIGlmICh3aWR0aDwgNTUwKXtzaXplID0gMTJ9XG4gICAgICBpZiAod2lkdGg8IDUwMCl7c2l6ZSA9IDEyfVxuICAgICAgaWYgKHdpZHRoPCA0NTApe3NpemUgPSAxMX1cbiAgICAgIGlmICh3aWR0aDwgNDAwKXtzaXplID0gMTB9XG4gICAgICBjb25zdCBjPWQzLnNlbGVjdCgnI2RhdG9zJyk7IGMuc2VsZWN0QWxsKCcqJykucmVtb3ZlKCk7XG4gICAgICByZXR1cm4gYy5hcHBlbmQoJ3N2ZycpLmF0dHIoJ3dpZHRoJyx3aWR0aCkuYXR0cignaGVpZ2h0JyxoZWlnaHQpXG4gICAgICAgIC5jYWxsKHRoaXMucmVzcG9uc2l2ZWZ5KS5hcHBlbmQoJ2cnKVxuICAgICAgICAuYXR0cignZm9udC1mYW1pbHknLCdzYW5zLXNlcmlmJykuYXR0cignZm9udC1zaXplJyxzaXplKS5hdHRyKCd0ZXh0LWFuY2hvcicsJ21pZGRsZScpO1xuICAgIH0sXG4gICAgY3JlYXRlU2NhbGVzKGRhdGEsIHcsIGgpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHg6IGQzLnNjYWxlQmFuZCgpLmRvbWFpbihkYXRhLm1hcChkID0+IGQuc2lnbGFzKSkucmFuZ2UoWzAsIHddKS5wYWRkaW5nKDAuMDUpLFxuICAgICAgICB5OiBkMy5zY2FsZUxpbmVhcigpLmRvbWFpbihbMCwgZDMubWF4KGRhdGEsIGQgPT4gZC5wZXJjZW50LzEwMCldKS5uaWNlKCkucmFuZ2UoW2gsIDBdKVxuICAgICAgfTtcbiAgICB9LFxuICAgIGNyZWF0ZVlTY2FsZUdsb2JhbChkYXRhLCBoZWlnaHQpIHtcbiAgICAgIHJldHVybiBkMy5zY2FsZUxpbmVhcigpLmRvbWFpbihbMCwgZDMubWF4KGRhdGEsIGQgPT4gZC5wZXJjZW50LzEwMCldKS5yYW5nZShbaGVpZ2h0LCAwXSkubmljZSgpO1xuICAgIH0sXG4gICAgZHJhd0JhcnMoc3ZnLCBkYXRhLCBzaXplLCBmcmFjLCB5U2NhbGVHbG9iYWwsIGlkKXtcbiAgICAgIGxldCBkID0gZGF0YTtcbiAgICAgIGlmKGZyYWM9PT0xKSBkID0gZGF0YS5zbGljZSgwLDUpO1xuICAgICAgaWYoZnJhYz09PTIpIGQgPSBkYXRhLnNsaWNlKDUpO1xuICAgICAgY29uc3QgcyA9IHRoaXMuY3JlYXRlU2NhbGVzKGQsIHNpemUud2lkdGgsIHNpemUuaGVpZ2h0KTtcbiAgICAgIGNvbnN0IGFuaG9fYWN0dWFsID0gdGhpcy5zdGF0ZS5kYXRvc0NvbnN1bHRhLmFuaG9fYWN0dWFsIHx8ICcyMDI2JztcbiAgICAgIGNvbnN0IGFuaG9fYW50ZXJpb3IgPSB0aGlzLnN0YXRlLmRhdG9zQ29uc3VsdGEuYW5ob19hbnRlcmlvciB8fCAnMjAyMic7XG4gICAgICBpZiAoaWQgIT09ICdncmFmaWNhXzInKSB7XG4gICAgICAgIHN2Zy5hcHBlbmQoJ3RleHQnKS5hdHRyKCd4Jywgc2l6ZS53aWR0aC0xMCkuYXR0cigneScsIDQwKVxuICAgICAgICAgICAuYXR0cigndGV4dC1hbmNob3InLCdlbmQnKS5hdHRyKCdmb250LXNpemUnLDMyKS5hdHRyKCdmb250LXdlaWdodCcsJ2JvbGQnKVxuICAgICAgICAgICAudGV4dCh0aGlzLnN0YXRlLmFuaG89PT0nZWxlY2Npb25lc19hY3R1YWxlcyc/YW5ob19hY3R1YWw6YW5ob19hbnRlcmlvcik7XG4gICAgICB9XG4gICAgICBjb25zdCBnID0gc3ZnLnNlbGVjdEFsbCgnLmJhcicpLmRhdGEoZCkuZW50ZXIoKS5hcHBlbmQoJ2cnKTtcbiAgICAgIGcuYXBwZW5kKCdyZWN0JykuYXR0cignY2xhc3MnLCdiYXInKS5hdHRyKCd4Jyx4PT5zLngoeC5zaWdsYXMpKS5hdHRyKCd5Jyx5U2NhbGVHbG9iYWwoMCkpXG4gICAgICAgIC5hdHRyKCd3aWR0aCcscy54LmJhbmR3aWR0aCgpKS5hdHRyKCdoZWlnaHQnLHNpemUuaGVpZ2h0IC0geVNjYWxlR2xvYmFsKDApKVxuICAgICAgICAuYXR0cignZmlsbCcseD0+dGhpcy5jb2xvcih0aGlzLnNpZ2xhKHguc2lnbGFzKSkpLm9uKCdtb3VzZW92ZXInLHRoaXMuc2hvd1Rvb2x0aXApLm9uKCdtb3VzZW91dCcsdGhpcy5oaWRlVG9vbHRpcClcbiAgICAgICAgLnRyYW5zaXRpb24oKS5kdXJhdGlvbig4MDApLmF0dHIoJ3knLHg9PnlTY2FsZUdsb2JhbCh4LnBlcmNlbnQvMTAwKSlcbiAgICAgICAgLmF0dHIoJ2hlaWdodCcseD0+c2l6ZS5oZWlnaHQgLSB5U2NhbGVHbG9iYWwoeC5wZXJjZW50LzEwMCkpO1xuICAgICAgZy5hcHBlbmQoJ3RleHQnKS5hdHRyKCd4Jyx4PT5zLngoeC5zaWdsYXMpK3MueC5iYW5kd2lkdGgoKS8yKS5hdHRyKCd5Jyx4PT55U2NhbGVHbG9iYWwoNCkpXG4gICAgICAgIC5hdHRyKCd0ZXh0LWFuY2hvcicsJ21pZGRsZScpLmF0dHIoJ2ZvbnQtd2VpZ2h0JywnYm9sZCcpLmF0dHIoJ2ZvbnQtc2l6ZScsMjYpXG4gICAgICAgIC5hdHRyKCdmaWxsJywgZCA9PiAoZC5wZXJjZW50PjY1MCk/XCIjZmZmXCI6XCIjMDAwXCIpLnRleHQoeD0+eC5lc2Nhbmhvcyk7XG4gICAgfSxcbiAgICBkcmF3UGllKGlkLCBkYXRhLCBmcmFjKXtcbiAgICAgIGNvbnN0IHNpemUgPSB0aGlzLmdldFNpemUoaWQpO1xuICAgICAgaWYoIXNpemUpIHJldHVybjtcbiAgICAgIGxldCBkID0gZGF0YTtcbiAgICAgIGNvbnN0IHRvdGFsVm90ZXMgPSBkMy5zdW0oZCwgeD0+eC52b3Rvcyk7XG4gICAgICBpZihmcmFjPT09MSkgZD1kYXRhLnNsaWNlKDAsNSk7XG4gICAgICBpZihmcmFjPT09MikgZD1kYXRhLnNsaWNlKDUpO1xuICAgICAgY29uc3Qgc3ZnID0gdGhpcy5jcmVhdGVTdmcoaWQsIHNpemUud2lkdGgsIDEwMCk7XG4gICAgICBjb25zdCBzID0gdGhpcy5jcmVhdGVTY2FsZXMoZCwgc2l6ZS53aWR0aCwgMTAwKTtcbiAgICAgIGNvbnN0IGcgPSBzdmcuc2VsZWN0QWxsKCdnLnBhcnRpZG8nKS5kYXRhKGQpLmVudGVyKCkuYXBwZW5kKCdnJykuYXR0cignY2xhc3MnLCdwYXJ0aWRvJylcbiAgICAgICAgICAuYXR0cigndHJhbnNmb3JtJyx4PT5gdHJhbnNsYXRlKCR7cy54KHguc2lnbGFzKStzLnguYmFuZHdpZHRoKCkvMn0sMClgKTtcbiAgICAgIGcuYXBwZW5kKCd0ZXh0JykuYXR0cigneScsMjApLmF0dHIoJ2ZvbnQtc2l6ZScsMTQpLmF0dHIoJ3RleHQtYW5jaG9yJywnbWlkZGxlJykuYXR0cignZm9udC13ZWlnaHQnLCdib2xkJykudGV4dCh4PT50aGlzLnNpZ2xhKHguc2lnbGFzKSk7XG4gICAgICBnLmFwcGVuZCgndGV4dCcpLmF0dHIoJ3knLDQwKS5hdHRyKCdmb250LXNpemUnLDEzKS5hdHRyKCdmb250LXdlaWdodCcsJ2JvbGQnKS5hdHRyKCd0ZXh0LWFuY2hvcicsJ21pZGRsZScpLnRleHQoeD0+KCh4LnZvdG9zL3RvdGFsVm90ZXMpKjEwMCkudG9GaXhlZCgxKSsnJScpO1xuICAgICAgZy5hcHBlbmQoJ3RleHQnKS5hdHRyKCd5Jyw1OCkuYXR0cignZm9udC1zaXplJywxMSkuYXR0cignZmlsbCcsJyM1NTUnKS5hdHRyKCd0ZXh0LWFuY2hvcicsJ21pZGRsZScpLnRleHQoeD0+eC52b3Rvcy50b0xvY2FsZVN0cmluZygnZXMtRVMnKSk7XG4gICAgfSxcbiAgICBkcmF3X2RhdG9zKCl7XG4gICAgICBpZighdGhpcy5zdGF0ZS5kYXRhPy5bdGhpcy5zdGF0ZS5hbmhvXT8uW3RoaXMuc3RhdGUudGVycml0b3Jpb10gfHwgIXRoaXMuc3RhdGUuZGF0YT8uZWxlY2Npb25lc19hbnRlcmlvcmVzPy5bdGhpcy5zdGF0ZS50ZXJyaXRvcmlvXSkgcmV0dXJuO1xuICAgICAgY29uc3Qgc2l6ZSA9IHRoaXMuZ2V0U2l6ZSgnZGF0b3MnKTsgaWYoIXNpemUpIHJldHVybjtcbiAgICAgIGNvbnN0IHN2ZyA9IHRoaXMuY3JlYXRlRGF0b3NTdmcoc2l6ZS53aWR0aCwgMTIwKTtcbiAgICAgIGNvbnN0IGQyNiA9IHRoaXMuc3RhdGUuZGF0YS5lbGVjY2lvbmVzX2FjdHVhbGVzW3RoaXMuc3RhdGUudGVycml0b3Jpb10uZ2VuZXJhbDtcbiAgICAgIGNvbnN0IGQyMyA9IHRoaXMuc3RhdGUuZGF0YS5lbGVjY2lvbmVzX2FudGVyaW9yZXNbdGhpcy5zdGF0ZS50ZXJyaXRvcmlvXS5nZW5lcmFsO1xuICAgICAgY29uc3QgY29scz02OyBjb25zdCBjb2xXPXNpemUud2lkdGgvY29sczsgY29uc3QgeD1pPT5jb2xXKmkrY29sVy8yO1xuICAgICAgY29uc3QgeTE9MzAseTI9NjUseTM9OTU7XG4gICAgICBjb25zdCBhbmhvX2FjdHVhbCA9IHRoaXMuc3RhdGUuZGF0b3NDb25zdWx0YS5hbmhvX2FjdHVhbDtcbiAgICAgIGNvbnN0IGFuaG9fYW50ZXJpb3IgPSB0aGlzLnN0YXRlLmRhdG9zQ29uc3VsdGEuYW5ob19hbnRlcmlvcjtcbiAgICAgIHN2Zy5hcHBlbmQoJ3JlY3QnKS5hdHRyKCd4JywwKS5hdHRyKCd5Jyx5Mi0xOCkuYXR0cignd2lk
1dGgnLHNpemUud2lkdGgpLmF0dHIoJ2hlaWdodCcsMjgpLmF0dHIoJ2ZpbGwnLCcjZWVlJyk7XG4gICAgICBzdmcuYXBwZW5kKCdyZWN0JykuYXR0cigneCcsMCkuYXR0cigneScseTMtMTgpLmF0dHIoJ3dpZHRoJyxzaXplLndpZHRoKS5hdHRyKCdoZWlnaHQnLDI4KS5hdHRyKCdmaWxsJywnI2VlZScpO1xuICAgICAgc3ZnLmFwcGVuZCgndGV4dCcpLmF0dHIoJ3gnLHgoMCkpLmF0dHIoJ3knLHkxKS5hdHRyKCdmb250LXdlaWdodCcsJ2JvbGQnKS50ZXh0KCcnKTtcbiAgICAgIHN2Zy5hcHBlbmQoJ3RleHQnKS5hdHRyKCd4Jyx4KDEpKS5hdHRyKCd5Jyx5MSkudGV4dCgnRXNjcnV0YWRvJyk7XG4gICAgICBzdmcuYXBwZW5kKCd0ZXh0JykuYXR0cigneCcseCgyKSkuYXR0cigneScseTEpLnRleHQoJ0Fic3RlbmNpw7NuJyk7XG4gICAgICBzdmcuYXBwZW5kKCd0ZXh0JykuYXR0cigneCcseCgzKSkuYXR0cigneScseTEpLnRleHQoJ0JsYW5jbycpO1xuICAgICAgc3ZnLmFwcGVuZCgndGV4dCcpLmF0dHIoJ3gnLHgoNCkpLmF0dHIoJ3knLHkxKS50ZXh0KCdOdWxvcycpO1xuICAgICAgc3ZnLmFwcGVuZCgndGV4dCcpLmF0dHIoJ3gnLHgoNSkpLmF0dHIoJ3knLHkxKS50ZXh0KCdFc2Nhw7FvcycpO1xuICAgICAgc3ZnLmFwcGVuZCgndGV4dCcpLmF0dHIoJ3gnLHgoMCkpLmF0dHIoJ3knLHkyKS5hdHRyKCdmb250LXdlaWdodCcsJ2JvbGQnKS50ZXh0KGFuaG9fYWN0dWFsKTtcbiAgICAgIHN2Zy5hcHBlbmQoJ3RleHQnKS5hdHRyKCd4Jyx4KDEpKS5hdHRyKCd5Jyx5MikudGV4dChkMjYucGVyY2VudF9lc2NydXRhZG8udG9GaXhlZCgyKSsnICUnKTtcbiAgICAgIHN2Zy5hcHBlbmQoJ3RleHQnKS5hdHRyKCd4Jyx4KDIpKS5hdHRyKCd5Jyx5MikudGV4dChkMjYucGVyY2VudF9hYnN0ZW5jaW9uLnRvRml4ZWQoMikrJyAlJyk7XG4gICAgICBzdmcuYXBwZW5kKCd0ZXh0JykuYXR0cigneCcseCgzKSkuYXR0cigneScseTIpLnRleHQoZDI2LnBlcmNlbnRfYmxhbmNvLnRvRml4ZWQoMikrJyAlJyk7XG4gICAgICBzdmcuYXBwZW5kKCd0ZXh0JykuYXR0cigneCcseCg0KSkuYXR0cigneScseTIpLnRleHQoZDI2LnBlcmNlbnRfbnVsb3MudG9GaXhlZCgyKSsnICUnKTtcbiAgICAgIHN2Zy5hcHBlbmQoJ3RleHQnKS5hdHRyKCd4Jyx4KDUpKS5hdHRyKCd5Jyx5MikudGV4dChkMjYuZXNjYW5ob3MpO1xuICAgICAgc3ZnLmFwcGVuZCgndGV4dCcpLmF0dHIoJ3gnLHgoMCkpLmF0dHIoJ3knLHkzKS5hdHRyKCdmb250LXdlaWdodCcsJ2JvbGQnKS50ZXh0KGFuaG9fYW50ZXJpb3IpO1xuICAgICAgc3ZnLmFwcGVuZCgndGV4dCcpLmF0dHIoJ3gnLHgoMSkpLmF0dHIoJ3knLHkzKS50ZXh0KCcxMDAuMDAgJScpO1xuICAgICAgc3ZnLmFwcGVuZCgndGV4dCcpLmF0dHIoJ3gnLHgoMikpLmF0dHIoJ3knLHkzKS50ZXh0KGQyMy5wZXJjZW50X2Fic3RlbmNpb24udG9GaXhlZCgyKSsnICUnKTtcbiAgICAgIHN2Zy5hcHBlbmQoJ3RleHQnKS5hdHRyKCd4Jyx4KDMpKS5hdHRyKCd5Jyx5MykudGV4dChkMjMucGVyY2VudF9ibGFuY28udG9GaXhlZCgyKSsnICUnKTtcbiAgICAgIHN2Zy5hcHBlbmQoJ3RleHQnKS5hdHRyKCd4Jyx4KDQpKS5hdHRyKCd5Jyx5MykudGV4dChkMjMucGVyY2VudF9udWxvcy50b0ZpeGVkKDIpKycgJScpO1xuICAgICAgc3ZnLmFwcGVuZCgndGV4dCcpLmF0dHIoJ3gnLHgoNSkpLmF0dHIoJ3knLHkzKS50ZXh0KGQyMy5lc2Nhbmhvcyk7XG4gICAgfSxcbiAgICBzaG93VG9vbHRpcChlLCBkKXtcbiAgICAgIGNvbnN0IHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndG9vbHRpcCcpO1xuICAgICAgY29uc3QgciA9IGUudGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgdC50ZXh0Q29udGVudCA9IGQuc2lnbGFzO1xuICAgICAgdC5zdHlsZS5sZWZ0ID0gci5sZWZ0K3Iud2lkdGgvMisncHgnO1xuICAgICAgdC5zdHlsZS50b3AgPSByLnRvcC0zMCsncHgnO1xuICAgICAgdC5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7XG4gICAgfSxcbiAgICBoaWRlVG9vbHRpcCgpe1xuICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rvb2x0aXAnKS5jbGFzc0xpc3QucmVtb3ZlKCdzaG93Jyk7XG4gICAgfSxcbiAgICBkcmF3X2FsbCgpe1xuICAgICAgY29uc3QgZGF0YSA9IHRoaXMuc3RhdGUuZGF0YT8uW3RoaXMuc3RhdGUuYW5ob10/Llt0aGlzLnN0YXRlLnRlcnJpdG9yaW9dPy5yZWN1ZW50b19wYXJ0aWRvcztcbiAgICAgIHRoaXMuZHJhd19kYXRvcygpO1xuICAgICAgaWYoIWRhdGEgfHwgIWRhdGEubGVuZ3RoIHx8IGRhdGFbMF0uY29kaWdvID09IFwiMDAwMFwiKXtcbiAgICAgICAgY29uc3QgYW5ob19hY3R1YWwgPSB0aGlzLnN0YXRlLmRhdG9zQ29uc3VsdGEuYW5ob19hY3R1YWwgfHwgJzIwMjYnO1xuICAgICAgICBjb25zdCBhbmhvX2FudGVyaW9yID0gdGhpcy5zdGF0ZS5kYXRvc0NvbnN1bHRhLmFuaG9fYW50ZXJpb3IgfHwgJzIwMjInO1xuICAgICAgICBjb25zdCBhbmhvID0gdGhpcy5zdGF0ZS5hbmhvID09PSAnZWxlY2Npb25lc19hY3R1YWxlcycgPyBhbmhvX2FjdHVhbCA6IGFuaG9fYW50ZXJpb3I7XG4gICAgICAgIFxuICAgICAgICBbJ2dyYWZpY2EnLCAnZ3JhZmljYV8xJywgJ2dyYWZpY2FfMiddLmZvckVhY2goKGlkKSA9PiB7XG4gICAgICAgICAgY29uc3QgcyA9IHRoaXMuZ2V0U2l6ZShpZCk7IGlmKCFzKSByZXR1cm47XG4gICAgICAgICAgY29uc3Qgc3ZnID0gdGhpcy5jcmVhdGVTdmcoaWQsIHMud2lkdGgsIHMuaGVpZ2h0KTtcbiAgICAgICAgICBzdmcuYXBwZW5kKCd0ZXh0JylcbiAgICAgICAgICAgIC5hdHRyKCd4Jywgcy53aWR0aC8yKVxuICAgICAgICAgICAgLmF0dHIoJ3knLCBzLmhlaWdodC8yKVxuICAgICAgICAgICAgLmF0dHIoJ3RleHQtYW5jaG9yJywgJ21pZGRsZScpXG4gICAgICAgICAgICAuYXR0cignZm9udC1zaXplJywgMjQpXG4gICAgICAgICAgICAuYXR0cignZm9udC13ZWlnaHQnLCAnYm9sZCcpXG4gICAgICAgICAgICAuYXR0cignZmlsbCcsICcjNjY2JylcbiAgICAgICAgICAgIC50ZXh0KGBTSU4gREFUT1MgJHthbmhvfWApO1xuICAgICAgICB9KTtcbiAgICAgICAgWydwaWUnLCAncGllXzEnLCAncGllXzInXS5mb3JFYWNoKChpZCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHMgPSB0aGlzLmdldFNpemUoaWQpOyBpZighcykgcmV0dXJuO1xuICAgICAgICAgIGNvbnN0IHN2ZyA9IHRoaXMuY3JlYXRlU3ZnKGlkLCBzLndpZHRoLCAxMDApO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICBcbiAgICAgIFsnZ3JhZmljYScsICdncmFmaWNhXzEnLCAnZ3JhZmljYV8yJ10uZm9yRWFjaCgoaWQsIGkpID0+IHtcbiAgICAgICAgY29uc3QgcyA9IHRoaXMuZ2V0U2l6ZShpZCk7IGlmKCFzKSByZXR1cm47XG4gICAgICAgIGNvbnN0IHlTY2FsZUdsb2JhbCA9IHRoaXMuY3JlYXRlWVNjYWxlR2xvYmFsKGRhdGEsIHMuaGVpZ2h0KTtcbiAgICAgICAgdGhpcy5kcmF3QmFycy
1h0aGlzLmNyZWF0ZVN2ZyhpZCwgcy53aWR0aCwgcy5oZWlnaHQpLCBkYXRhLCBzLCBpLCB5U2NhbGVHbG9iYWwsIGlkKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5kcmF3UGllKCdwaWUnLCBkYXRhLCAwKTtcbiAgICAgIHRoaXMuZHJhd1BpZSgncGllXzEnLCBkYXRhLCAxKTtcbiAgICAgIHRoaXMuZHJhd1BpZSgncGllXzInLCBkYXRhLCAyKTtcbiAgICB9LFxuICAgIGNvbG9yKHBhcnRpZG8pe1xuICAgICAgY29uc3QgY29sb3JlcyA9IHsgXG4gICAgICAgIFwiUFNPRVwiOlwiI2RjMDYxMlwiLFxuICAgICAgICBcIlBTT0UtQVwiOlwiI2RjMDYxMlwiLFxuICAgICAgICBcIlBQXCI6XCIjMDE1NDlmXCIsXG4gICAgICAgIFwiVk9YXCI6XCIjNTNkNDAzXCIsXG4gICAgICAgIFwiQUhPUkEgUkVQw5pCTElDQVNcIjpcIiNmN2I5M2ZcIixcbiAgICAgICAgXCJBSE9SQSBSRVDDmkJMSUNBUyAoRVJDLUVIIEJJTERVLUJORy1BUkEgTcOJUylcIjpcIiNmN2I5M2ZcIixcbiAgICAgICAgXCJKVU5UU1wiOlwiIzAwQjRDNFwiLFxuICAgICAgICBcIkpVTlRTLVVFXCI6XCIjMDBCNEM0XCIsXG4gICAgICAgIFwiQ0VVU1wiOlwiIzI5N2Y0MVwiLFxuICAgICAgICBcIlBPREVNT1NcIjpcIiM3MjE1NmVcIixcbiAgICAgICAgXCJQT0RFTU9TLUlVXCI6XCIjNzIxNTZlXCIsXG4gICAgICAgIFwiUE9ERU1PUyBBTElBWkEgVkVSREVcIjpcIiM3MjE1NmVcIixcbiAgICAgICAgXCJQT0RFTU9TIC1BVlwiOlwiIzcyMTU2ZVwiLFxuICAgICAgICBcIlAtSVUtQVZcIjpcIiM3MjE1NmVcIixcbiAgICAgICAgXCJTVU1BUlwiOlwiI0JCMjY0OVwiLFxuICAgICAgICBcIkNzXCI6XCIjZmY2NDE5XCIsXG4gICAgICAgIFwiUy5BLkwuRlwiOlwiIzlGQTJCMlwiLFxuICAgICAgICBcIlNBTEZcIjpcIiM5RkEyQjJcIixcbiAgICAgICAgXCJQQUNNQVwiOlwiIzAwZDA4NFwiLFxuICAgICAgICBcIlBvckFcIjogXCIjZjhjNTY1XCIsXG4gICAgICAgIFwiQURFTEFOVEUgQU5EQUxVQ8ONQVwiOiBcIiMwMDkwNzZcIixcbiAgICAgICAgXCJBQVwiOiBcIiMwMDkwNzZcIixcbiAgICAgICAgfTtcbiAgICAgIHJldHVybiBjb2xvcmVzW3BhcnRpZG9dIHx8ICcjJytNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkqTWF0aC5wb3coMiwzMileMHhmZmZmZmYpLnRvU3RyaW5nKDE2KS5zdWJzdHIoLTYpO1xuICAgIH0sXG4gICAgc2lnbGEocGFydGlkbyl7XG4gICAgICBjb25zdCBzaWdsYXMgPSB7IFxuICAgICAgICBcIlAuUy5PLkUuXCI6XCJQU09FXCIsXG4gICAgICAgIFwiUEFSVElETyBBVVTDk05PTU9TXCI6XCJQQVwiLFxuICAgICAgICBcIlJFQ09SVEVTIENFUk9cIjpcIlJDXCIsXG4gICAgICAgIFwiQURFTEFOVEUgQU5EQUxVQ8ONQS1BTkRBTFVDSVNUQVNcIjogXCJBQS1BXCIsXG4gICAgICAgIFwiQURFTEFOVEUgQU5EQUxVQ8ONQS1BTkRBTFVDSVNUQVNcIjogXCJBQS1BXCIsXG4gICAgICAgIFwiQU5EQUxVQ0lTVEFTLVBBXCI6IFwiQS1QQVwiLFxuICAgICAgICBcIkFOREFMVUNJU1RBUyAtIFBBXCI6IFwiQS1QQVwiLFxuICAgICAgICBcIkFERUxBTlRFIEFOREFMVUPDjUFcIjogXCJBQVwiLFxuICAgICAgICBcIkFIT1JBIFJFUMOaQkxJQ0FTXCI6XCJBLlIuXCIsXCJBR1JVUEFDScOTTiBERSBFTEVDVE9SRVMgU0UgQUNBQsOTIExBIEZJRVNUQVwiOlwiQS5FLlMuQS5GXCIsXG4gICAgICAgIFwiQUhPUkEgUkVQw5pCTElDQVMgKEVSQy1FSCBCSUxEVS1CTkctQVJBIE3DiVMpXCI6XCJBLlIuXCIsXCJQT0RFTU9TIEFMSUFOWkEgVkVSREVcIjpcIlAtQVZcIixcIlBPREVNT1MgLUFWXCI6XCJQLUFWXCIsXG4gICAgICAgIFwiUE9ERU1PUy1JVS1BVlwiOlwiUC1JVS1BVlwiLFwiQ09BTElDScOTTiBBUkFHT05FU0FcIjpcIkNBXCIsXCJJVS0gTU9WSU1JRU5UTyBTVU1BUlwiOlwiSVUtTVNcIixcIkVTQ0HDkU9TIEVOIEJMQU5DT1wiOlwiRUJcIixcbiAgICAgICAgXCJNVU5ETytKVVNUT1wiOlwiTStKXCIsXCJFU1BBw5FBIFZBQ0lBREFcIjpcIkUuVi5cIixcIkNTLVTDmiBBUkFHw5NOXCI6XCJDUy1UVVwiLFwiRkUgZGUgbGFzIEpPTlNcIjpcIkZFIEpvbnNcIixcbiAgICAgICAgXCJQQ0FTLVRDLVJlY29ydGVzIENlcm9cIjpcIlBDQVMtVEMtUkNcIlxuICAgICAgfTtcbiAgICAgIHJldHVybiBzaWdsYXNbcGFydGlkb10gfHwgcGFydGlkbztcbiAgICB9LFxuICB9LFxuICBGbG93Q3VycmVudDoge1xuICAgIG1vdW50ZWQoKSB7XG4gICAgICB0aGlzLmVsLnN0eWxlLnRyYW5zaXRpb24gPSBcInRyYW5zZm9ybSAxLjJzIGVhc2UtaW4tb3V0LCBmaWxsIDAuOHNcIlxuICAgIH0sXG4gICAgdXBkYXRlZCgpIHtcbiAgICAgIGxldCB4ID0gcGFyc2VGbG9hdCh0aGlzLmVsLmRhdGFzZXQueClcbiAgICAgIGxldCB5ID0gcGFyc2VGbG9hdCh0aGlzLmVsLmRhdGFzZXQueSlcblxuICAgICAgLy8gZWZlY3RvIEJlemllci1saWtlOiBsaWdlcmEgY3VydmEgZW4gbW92aW1pZW50b1xuICAgICAgbGV0IGN4ID0geCArIChNYXRoLnJhbmRvbSgpLTAuNSkqMjBcbiAgICAgIGxldCBjeSA9IHkgKyAoTWF0aC5yYW5kb20oKS0wLjUpKjEwXG4gICAgICB0aGlzLmVsLnNldEF0dHJpYnV0ZShcInhcIiwgY3gpXG4gICAgICB0aGlzLmVsLnNldEF0dHJpYnV0ZShcInlcIiwgY3kpXG4gICAgfVxuICB9LFxuXG4gIEhvcml6b250YWxTY3JvbGw6IHtcbiAgICBtb3VudGVkKCkge1xuICAgICAgaWYgKHdpbmRvdy5pbm5lcldpZHRoID4gNzY4KSByZXR1cm47IC8vIOKdjCBObyBoYWNlciBuYWRhIGVuIGVzY3JpdG9yaW9cbiAgICAgIGNvbnN0IGlkID1gIyR7dGhpcy5lbC5kYXRhc2V0LmlkfWA7XG5cbiAgICAgIGNvbnN0IGVsID0gdGhpcy5lbFxuICAgICAgbGV0IGF0RW5kID0gZmFsc2VcblxuICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHNjcm9sbExlZnQgPSBlbC5zY3JvbGxMZWZ0XG4gICAgICAgIGNvbnN0IHNjcm9sbFdpZHR
1oID0gZWwuc2Nyb2xsV2lkdGhcbiAgICAgICAgY29uc3QgY2xpZW50V2lkdGggPSBlbC5jbGllbnRXaWR0aFxuXG4gICAgICAgIGlmIChzY3JvbGxMZWZ0ICsgY2xpZW50V2lkdGggPj0gc2Nyb2xsV2lkdGggLSAgIDApIHtcbiAgICAgICAgICBpZiAoIWF0RW5kKSB7XG4gICAgICAgICAgICB0aGlzLnB1c2hFdmVudFRvKGlkLCBcInNjcm9sbF9lbmRcIilcbiAgICAgICAgICAgIGF0RW5kID0gdHJ1ZVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhdEVuZCA9IGZhbHNlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9LFxuICBDYXJydXNlbFRyYWNrOiB7XG4gICAgbW91bnRlZCgpIHtcbiAgICAgIHRoaXMucGFnZSA9IHBhcnNlSW50KHRoaXMuZWwuZGF0YXNldC5wYWdlKVxuICAgIH0sXG4gICAgdXBkYXRlZCgpIHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBwYXJzZUludCh0aGlzLmVsLmRhdGFzZXQucGFnZSlcbiAgICAgIGNvbnN0IHBlclBhZ2UgPSBwYXJzZUludCh0aGlzLmVsLmRhdGFzZXQucGVyUGFnZSlcblxuICAgICAgY29uc3QgZWxlbWVudG8gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndHJhY2stc29jaWFzLW9waW5pb24nKSB8fCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndHJhY2stcmVsYWNpb25hZGFzLWxpdmUnKS5wYXJlbnROb2RlOyBcbiAgICAgIGNvbnN0IGFuY2hvX3RvdGFsX3Zpc2libGUgPSBlbGVtZW50by5vZmZzZXRXaWR0aDsgXG5cbiAgICAgIC8vY29uc3Qgb2Zmc2V0ID0gLXBhZ2UgKiBwZXJQYWdlICogaXRlbVdpZHRoXG4gICAgICBjb25zdCBvZmZzZXQgPSAtcGFnZSAqIGFuY2hvX3RvdGFsX3Zpc2libGVcbiAgICAgIGNvbnN0IHRyYWNrID0gdGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiLml0ZW1zLXRyYWNrXCIpXG5cbiAgICAgIHRoaXMucGFnZSA9IHBhZ2VcblxuICAgICAgaWYgKHRyYWNrKSB7XG4gICAgICAgIGlmICh3aW5kb3cuaW5uZXJXaWR0aCA8PSA3NjgpIHJldHVybjsgLy8g4p2MIE5vIGhhY2VyIG5hZGEgZW4gbW92aWwgIFxuICAgICAgICB0cmFjay5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlWCgke29mZnNldH1weClgXG4gICAgICB9XG4gICAgfVxuICB9LFxuICBMYXp5TG9hZEFkOiB7XG4gICAgbW91bnRlZCgpIHtcbiAgICAgIHZhciBtb2R1bG9fcHVibGkgPSB0aGlzLmVsLmRhdGFzZXQubmFtZVxuICAgICAgbGV0IGFscmVhZHlUcmlnZ2VyZWQgPSBmYWxzZVxuXG4gICAgICBjb25zdCBoYW5kbGVWaXNpYmxlID0gKCkgPT4ge1xuICAgICAgICAvL2lmIChhbHJlYWR5VHJpZ2dlcmVkKSByZXR1cm5cbiAgICAgICAgYWxyZWFkeVRyaWdnZXJlZCA9IHRydWVcblxuICAgICAgICAvLyBWZXJpZmljYXIgbG9ja3MgeSBlc3RhZG8gZGUgYWN0dWFsaXphY2nDs24gZGUgY29udGVuaWRvXG4gICAgICAgIGlmIChwdWJsaV9sb2NrIHx8IGNvbnRlbmlkb3VwZGF0aW5nKSB7XG4gICAgICAgICAgaWYgKCFwdWJsaV9wZW5kaWVudGVzLmluY2x1ZGVzKG1vZHVsb19wdWJsaSkpIHtcbiAgICAgICAgICAgIHB1YmxpX3BlbmRpZW50ZXMucHVzaChtb2R1bG9fcHVibGkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB2Y
1XIgc2x1ZzEgPSBcIlwiO1xuICAgICAgICB2YXIgc2x1ZzIgPSBcIlwiO1xuICAgICAgICB2YXIgbG9jID0gbG9jYXRpb24ucGF0aG5hbWUuc3BsaXQoJy8nKS5zbGljZSgxKTtcbiAgICAgICAgaWYobG9jWzBdKSB7IHNsdWcxID0gbG9jWzBdIH1cbiAgICAgICAgaWYobG9jWzFdKSB7IHNsdWcyID0gbG9jWzFdIH1cbiAgICAgICAgaWYobG9jWzBdID09IFwic2luLXB1YmxpY2FyXCIpIHsgc2x1ZzEgPSBsb2NbMV07IHNsdWcyID0gbG9jWzJdfSBcblxuICAgICAgICB2YXIgbm9kbyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwibm9kby1jb250ZW5pZG9cIilcbiAgICAgICAgaWYgKG5vZG8pIHsgbm9kbyA9IG5vZG8uZ2V0QXR0cmlidXRlKCdkYXRhLW5vZG8nKSB9XG5cbiAgICAgICAgdGhpcy5wdXNoRXZlbnRUbyh0aGlzLmVsLCBcImFkX3Zpc2libGVcIiwgeyBcbiAgICAgICAgICBtb2R1bG86IG1vZHVsb19wdWJsaSxcbiAgICAgICAgICBzbHVnMTogc2x1ZzEsXG4gICAgICAgICAgc2x1ZzI6IHNsdWcyLFxuICAgICAgICAgIG1vYmlsOiAod2luZG93LmlubmVyV2lkdGggPiA3NjcpID8gZmFsc2UgOiB0cnVlLFxuICAgICAgICAgIG5vZG86IG5vZG8sXG4gICAgICAgICAgaXA6IGRvY3VtZW50LmJvZHkuZ2V0QXR0cmlidXRlKCdkYXRhLWlwJyksXG4gICAgICAgIH0pXG5cbiAgICAgICAgb2JzZXJ2ZXIuZGlzY29ubmVjdCgpXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChbZW50cnldKSA9PiB7XG4gICAgICAgIGlmIChlbnRyeS5pc0ludGVyc2VjdGluZyB8fCBlbnRyeS5pbnRlcnNlY3Rpb25SYXRpbyA+IDApIHtcbiAgICAgICAgICBoYW5kbGVWaXNpYmxlKClcbiAgICAgICAgfVxuICAgICAgfSwgeyByb290TWFyZ2luOiBcIjIwMHB4XCIgfSlcblxuICAgICAgb2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsKTtcblxuICAgICAgLy8gY29tcHJvYmFjacOzbiBpbmljaWFsXG4gICAgICBjb25zdCByZWN0ID0gdGhpcy5lbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgICAgY29uc3QgaW5WaWV3ID0gcmVjdC50b3AgPCB3aW5kb3cuaW5uZXJIZWlnaHQgJiYgcmVjdC5ib3R0b20gPiAwXG5cbiAgICAgIGlmIChpblZpZXcpIHtcbiAgICAgICAgaGFuZGxlVmlzaWJsZSgpXG4gICAgICB9XG5cbiAgICAgIHRoaXMuaGFuZGxlRXZlbnQoYHVwZGF0ZV9hZF8ke21vZHVsb19wdWJsaX1gLCAoYW51bmNpbykgPT4ge1xuICAgICAgICBpZiAodGhpcy5lbC5kYXRhc2V0Lm5hbWUgPT0gYW51bmNpby5tb2R1bG8pe1xuICAgICAgICAgIHZhciBtb2JpbCA9ICh3aW5kb3cuaW5uZXJXaWR0aCAgPiA3NjcpID8gZmFsc2UgOiB0cnVlO1xuXG4gICAgICAgICAgbGV0IG1vZHVsbyA9IHRoaXMuZWw7XG4gICAgICAgICAgaWYgKCFtb2R1bG8pIHJldHVybjtcblxuICAgICAgICAgIC8vIDEuIEHDsWFkaXIgY2xhc2Ugc2Vnw7puIGVsIHRpcG8gZGUgYW51bmNpb1xuICAgICAgICAgIGlmIChhbnVuY2lvLm1hcXVldGFjaW9uICYmIGFudW5jaW8ubWFxdWV0YWNpb24ubm9fcHVibGljaWRhZCA9PT0gXCJub19wdWJsaWNpZGFkXCIpIHtcbiAgICAgICAgICAgIG1vZHVsby5jbGFzc0xpc3QuYWRkKCdibG9xdWUtYWN0aXZvJyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG1vZHVsby5jbGFzc0xpc3QuYWRkKCdhbnVuY2lvLWFjdGl2bycpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIDIuIFZhY2lhciBlbCBjb250ZW5pZG8gZGVsIG3Ds2R1bG9cbiAgICAgICAgICBtb2R1bG8uaW5uZXJIVE1MID0gXCJcIjtcblxuICAgICAgICAgIC8vIDMuIEF0cmlidXRvIFwicGh4LXVwZGF0ZVwiXG4gICAgICAgICAgbW9kdWxvLnNldEF0dHJpYnV0ZSgncGh4LXVwZGF0ZScsICdpZ25vcmUnKTtcblxuICAgICAgICAgIC8vIDQuIFNpIGhheSBzY3JpcHQsIHVzYXIgcG9zdHNjcmliZSAoc2kgZXN0w6EgZGlzcG9uaWJsZSlcbiAgICAgICAgICBpZiAoYW51bmNpby5zY3JpcHQgJiYgYW51bmNpby5zY3JpcHQubGVuZ3RoID4gMTApIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcG9zdHNjcmliZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHBvc3RzY3JpYmUobW9kdWxvLCBhbnVuY2lvLnNjcmlwdCwge1xuICAgICAgICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdBZCBmYWlsZWQgdG8gbG9hZDonLCBlKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJFcnJvciBhbCBpbnNlcnRhciBzY3JpcHRcIik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUud2FybihcInBvc3RzY3JpYmUgbm8gZXN0w6EgZGVmaW5pZG9cIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gNS4gU2kgaGF5IEhUTUwgcGVyc29uYWxpemFkb1xuICAgICAgICAgICAgaWYgKGFudW5jaW8uaHRtbCAmJiBhbnVuY2lvLmh0bWwubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgICAgZGl2LmNsYXNzTGlzdC5hZGQoJ2h0bWwtYW51bicpO1xuICAgICAgICAgICAgICBkaXYuaW5uZXJIVE1MID0gYW51bmNpby5odG1sO1xuICAgICAgICAgICAgICBtb2R1bG8uYXBwZW5kQ2hpbGQoZGl2KTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gNi4gU2kgbm8gaGF5IEhUTUwgbmkgc2NyaXB0LCBjb25zdHJ1aXIgZW5sYWNlIGRlIGFudW5jaW9cbiAgICAgICAgICAgICAgY29uc3QgcmVkaXJlY2Npb24gPSBhbnVuY2lvLnVybF9yZWRpcmVjY2lvbiB8fCBcImZhbHNlXCI7XG4gICAgICAgICAgICAgIGNvbnN0IGEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgICAgICAgICAgIGEuZGF0YXNldC5hbnVuID0gYW51bmNpby5pZDtcbiAgICAgICAgICAgICAgYS5kYXRhc2V0LmNsaWNrID0gcmVkaXJlY2Npb247XG4gICAgICAgICAgICAgIGEuaHJlZiA9IGAvaXJfYW51bmNpby8ke2FudW5jaW8uaWR9LyR7bW9iaWx9YDtcbiAgICAgICAgICAgICAgYS50YXJnZXQgPSBcIl9ibGFua1wiO1xuICAgICAgICAgICAgICBhLnNldEF0dHJpYnV0ZSgnYXJpYS1sYWJlbCcsICdwdWJsaWNpZGFkJyk7XG4gICAgICAgICAgICAgIGEuY2xhc3NMaXN0LmFkZCgnYW51bmNpby1saW5rJyk7XG4gICAgICAgICAgICAgIG1vZHVsby5hcHBlbmRDaGlsZChhKTtcblxuICAgICAgICAgICAgICAvLyA3LiBJbWFnZW4gbyB2aWRlb1xuICAgICAgICAgICAgICBpZiAoYW51bmNpby5pbWFnZW4pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBleHQgPSBhbnVuY2lvLmltYWdlbi5zcGxpdCgnLicpLnBvcCgpLnNwbGl0KCc/Jykuc2hpZnQoKTtcbiAgICAgICAgICAgICAgICBpZiAoZXh0ID09PSBcIm1wNFwiKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCB2aWRlbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAgICAgICAgICAgICAgICB2aWRlby5jbGFzc0xpc3QuYWRkKCduby1tZXAnKTtcbiAgICAgICAgICAgICAgICAgI
1HZpZGVvLmF1dG9wbGF5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgIHZpZGVvLm11dGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgIHZpZGVvLmxvb3AgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgdmlkZW8uc3JjID0gYW51bmNpby5pbWFnZW47XG4gICAgICAgICAgICAgICAgICB2aWRlby5hbHQgPSBhLnRpdHVsbztcbiAgICAgICAgICAgICAgICAgIGEuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBpbWcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgICAgICAgICAgICAgICAgIGltZy5zcmMgPSBhbnVuY2lvLmltYWdlbjtcbiAgICAgICAgICAgICAgICAgIGltZy5hbHQgPSBhbnVuY2lvLnRpdHVsbztcbiAgICAgICAgICAgICAgICAgIGEuYXBwZW5kQ2hpbGQoaW1nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyA4LiBQw614ZWwgZGUgaW1wcmVzacOzblxuICAgICAgICAgICAgICBpZiAoYW51bmNpby51cmxfaW1wcmVzaW9uKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGl4ZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgICAgICAgICAgICAgICBwaXhlbC5jbGFzc0xpc3QuYWRkKCd0cmFuc3BhcmVudCcpO1xuICAgICAgICAgICAgICAgIHBpeGVsLnNyYyA9IGFudW5jaW8udXJsX2ltcHJlc2lvbi5yZXBsYWNlKFwiW3RpbWVzdGFtcF1cIiwgK25ldyBEYXRlKCkpO1xuICAgICAgICAgICAgICAgIHBpeGVsLmFsdCA9IFwiQWR2ZXJ0aXNtZW50XCI7XG4gICAgICAgICAgICAgICAgcGl4ZWwuYm9yZGVyID0gXCIwXCI7XG4gICAgICAgICAgICAgICAgcGl4ZWwuaGVpZ2h0ID0gMTtcbiAgICAgICAgICAgICAgICBwaXhlbC53aWR0aCA9IDE7XG4gICAgICAgICAgICAgICAgYS5hcHBlbmRDaGlsZChwaXhlbCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgLy90aGlzLmVsLmlubmVySFRNTCA9IGRhdGEuY29udGVudDtcbiAgICAgICAgfVxuICAgICAgICBwb3B1cCgpO1xuICAgICAgfSlcbiAgICB9XG4gIH0sXG4gIE1hcExpYnJlRm9ybU1hcDoge1xuICAgIG1vdW50ZWQoKSB7XG4gICAgICBpZiAoIXdpbmRvdy5tYXBsaWJyZWdsKSB7XG4gICAgICAgIFByb21pc2UuYWxsKFtcbiAgICAgICAgICB0aGlzLmxvYWRDU1MoXCJodHRwczovL3VucGtnLmNvbS9tYXBsaWJyZS1nbEAzLjMuMS9kaXN0L21hcGxpYnJlLWdsLmNzc1wiKSxcbiAgICAgICAgICB0aGlzLmxvYWRKUyhcImh0dHBzOi8vdW5wa2cuY29tL21hcGxpYnJlLWdsQDMuMy4xL2Rpc3QvbWFwbGlicmUtZ2wuanNcIilcbiAgICAgICAgXSlcbiAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLmluaXRNYXAoKSlcbiAgICAgICAgICAuY2F0Y2goKGVycikgPT4gY29uc29sZS5lcnJvcihcIkVycm9yIGxvYWRpbmcgTWFwTGlicmU6XCIsIGVycikpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5pbml0TWFwKCk7XG4gICAgICB9XG4gICAgfSxcbiAgICB1cGRhdGVkKCkge1xuICAgICAgICB0aGlzLmluaXRNYXAoKTtcbiAgICB9LFxuXG4gICAgbG9hZENTUyh1cmwpIHtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBsaW5rW2hyZWY9XCIke3VybH1cIl1gKSkgcmV0dXJuIHJlc29sdmUoKTtcblxuICAgICAgICBjb25zdCBsaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImxpbmtcIik7XG4gICAgICAgIGxpbmsucmVsID0gXCJzdHlsZXNoZWV0XCI7XG4gICAgICAgIGxpbmsuaHJlZiA9IHVybDtcbiAgICAgICAgbGluay5vbmxvYWQgPSByZXNvbHZlO1xuICAgICAgICBsaW5rLm9uZXJyb3IgPSByZWplY3Q7XG4gICAgICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQobGluayk7XG4gICAgICB9KTtcbiAgICB9LFxuICAgIGxvYWRKUyh1cmwpIHtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBzY3JpcHRbc3JjPVwiJHt1cmx9XCJdYCkpIHJldHVybiByZXNvbHZlKCk7XG5cbiAgICAgICAgY29uc3Qgc2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNjcmlwdFwiKTtcbiAgICAgICAgc2NyaXB0LnNyYyA9IHVybDtcbiAgICAgICAgc2NyaXB0LmlkID0gXCJJRF9tYXBfc2NyaXB0XCI7XG4gICAgICAgIHNjcmlwdC5hc3luYyA9IHRydWU7XG4gICAgICAgIHNjcmlwdC5vbmxvYWQgPSByZXNvbHZlO1xuICAgICAgICBzY3JpcHQub25lcnJvciA9IHJlamVjdDtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChzY3JpcHQpO1xuICAgICAgfSk7XG4gICAgfSxcblxuICAgIGluaXRNYXAoKSB7XG5cbiAgICAgIGNvbnN0IGxhdCA9IHBhcnNlRmxvYXQodGhpcy5lbC5kYXRhc2V0LmxhdCkgfHwgMDtcbiAgICAgIGNvbnN0IGxuZyA9IHBhcnNlRmxvYXQodGhpcy5lbC5kYXRhc2V0LmxuZykgfHwgMDtcbiAgICAgIGNvbnN0IHpvb20gPSBwYXJzZUZsb2F0KHRoaXMuZWwuZGF0YXNldC56b29tKSB8fCAyO1xuXG4gICAgICB0aGlzLm1hcCA9IG5ldyBtYXBsaWJyZWdsLk1hcCh7XG4gICAgICAgIGNvbnRhaW5lcjogdGhpcy5lbCxcbiAgICAgICAgc3R5bGU6IFwiaHR0cHM6Ly9kZW1vdGlsZXMubWFwbGlicmUub3JnL3N0eWxlLmpzb25cIixcbiAgICAgICAgc3R5bGU6IFwiaHR0cHM6Ly9kZW1vdGlsZXMubWFwbGlicmUub3JnL3N0eWxlcy9vc20tYnJpZ2h0LWdsLXN0eWxlL3R5bGUuanNvblwiLFxuICAgICAgICBzdHlsZTogXCJodHRwczovL3RpbGVzLnN0YWRpYW1hcHMuY29tL3N0eWxlcy9vc21fYnJpZ2h0Lmpzb25cIixcbiAgICAgICAgY2VudGVyOiBbbG5nLCBsYXRdLFxuICAgICAgICB6b29tOiB6b29tXG4gICAgICB9KTtcblxuICAgICAgdGhpcy5tYXAuYWRkQ29udHJvbChuZXcgbWFwbGlicmVnbC5OYXZpZ2F0aW9uQ29udHJvbCgpKTtcblxuICAgICAgLy8g8J+ntyBDcmVhciBtYXJjYWRvciBpbmljaWFsXG4gICAgICB0aGlzLm1hcmtlciA9IG5ldyBtYXBsaWJyZWdsLk1hcmtlcih7IGRyYWdnYWJsZTogdHJ1ZSB9KVxuICAgICAgICAuc2V0TG5nTGF0KFtsbmcsIGxhdF0pXG4gICAgICAgIC5hZGRUbyh0aGlzLm1hcCk7XG5cbiAgICAgIC8vIPCfm7DvuI8gQWN0dWFsaXphciBtYXJjYWRvciB5IGVudmlhciBldmVudG8gY3VhbmRvIHNlIG11ZXZlIG8gaGFjZSB6b29tXG4gICAgICB0aGlzLm1hcC5vbihcIm1vdmVlbmRcIiwgKCkgPT4gdGhpcy5oYW5kbGVNYXBNb3ZlKCkpO1xuICAgICAgdGhpcy5tYXAub24oXCJ6b29tZW5kXCIsICgpID0+IHRoaXMuaGFuZGxlTWFwTW92ZSgpKTtcbiAgICAgIHRoaXMubWFwLm9uKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICAgICAgY29uc3QgeyBsbmcsIGxhdCB9ID0gZS5sbmdMYXQ7XG4gICAgICAgI
1HRoaXMubWFya2VyLnNldExuZ0xhdChbbG5nLCBsYXRdKTtcblxuICAgICAgICAvLyBFbWl0aXIgZXZlbnRvIGEgTGl2ZVZpZXcgc2kgbG8gZGVzZWFzXG4gICAgICAgIHRoaXMucHVzaEV2ZW50KFwibWFwX21vdmVkXCIsIHtcbiAgICAgICAgICBsYXQsXG4gICAgICAgICAgbG5nLFxuICAgICAgICAgIHpvb206IE1hdGgucm91bmQodGhpcy5tYXAuZ2V0Wm9vbSgpKVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBoYW5kbGVNYXBNb3ZlKCkge1xuICAgICAgY29uc3QgY2VudGVyID0gdGhpcy5tYXAuZ2V0Q2VudGVyKCk7XG4gICAgICBjb25zdCB6b29tID0gdGhpcy5tYXAuZ2V0Wm9vbSgpO1xuXG4gICAgICAvLyBNb3ZlciBlbCBtYXJjYWRvciBhbCBudWV2byBjZW50cm9cbiAgICAgIHRoaXMubWFya2VyLnNldExuZ0xhdChjZW50ZXIpO1xuXG4gICAgICAvLyBFbWl0aXIgZXZlbnRvIGEgTGl2ZVZpZXdcbiAgICAgIHRoaXMucHVzaEV2ZW50KFwibWFwX21vdmVkXCIsIHtcbiAgICAgICAgbGF0OiBjZW50ZXIubGF0LFxuICAgICAgICBsbmc6IGNlbnRlci5sbmcsXG4gICAgICAgIHpvb206IE1hdGgucm91bmQoem9vbSlcbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcbiAgVGFiSGlnaGxpZ2h0OiB7XG4gICAgbW91bnRlZCgpIHtcbiAgICAgIHRoaXMuc3RhcnRCbGlua2luZygpXG4gICAgfSxcbiAgICB1cGRhdGVkKCkge1xuICAgICAgdGhpcy5zdGFydEJsaW5raW5nKClcbiAgICB9LFxuICAgIGRlc3Ryb3llZCgpIHtcbiAgICAgIC8vIExpbXBpZXphIGRlIHNlZ3VyaWRhZFxuICAgICAgaWYgKHRoaXMuYmxpbmtJbnRlcnZhbCkge1xuICAgICAgICBjbGVhckludGVydmFsKHRoaXMuYmxpbmtJbnRlcnZhbClcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgc3RhcnRCbGlua2luZygpIHtcbiAgICAgIGlmIChkb2N1bWVudC5oYXNGb2N1cygpKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgbGV0IG9yaWdpbmFsVGl0bGUgPSBkb2N1bWVudC50aXRsZVxuICAgICAgbGV0IG5ld1RpdGxlID0gdGhpcy5lbC5kYXRhc2V0LnRpdGxlIHx8IFwiTnVldmEgYWN0dWFsaXphY2nDs25cIlxuXG4gICAgICAvLyBMaW1waWEgY3VhbHF1aWVyIGludGVydmFsbyBhbnRlcmlvclxuICAgICAgaWYgKHRoaXMuYmxpbmtJbnRlcnZhbCkge1xuICAgICAgICBjbGVhckludGVydmFsKHRoaXMuYmxpbmtJbnRlcnZhbClcbiAgICAgIH1cblxuICAgICAgY29uc3QgYmxpbmsgPSAoKSA9PiB7XG4gICAgICAgIGRvY3VtZW50LnRpdGxlID0gZG9jdW1lbnQudGl0bGUgPT09IG9yaWdpbmFsVGl0bGUgPyBuZXdUaXRsZSA6IG9yaWdpbmFsVGl0bGVcbiAgICAgIH1cblxuICAgICAgdGhpcy5ibGlua0ludGVydmFsID0gc2V0SW50ZXJ2YWwoYmxpbmssIDEwMDApXG5cbiAgICAgIC8vIERldGVuZXIgY3VhbmRvIHNlIHZ1ZWx2ZSBhIGVuZm9jYXIgbGEgcGVzdGHDsWFcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiZm9jdXNcIiwgKCkgPT4ge1xuICAgICAgICBjbGVhckludGVydmFsKHRoaXMuYmxpbmtJbnRlcnZhbClcbiAgICAgICAgZG9jdW1lbnQudGl0bGUgPSBvcmlnaW5hbFRpdGxlXG4gICAgICB9LCB7IG9uY2U6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIENvb3JkaW5hQ29udGVuaWRvOiB7XG4gICAgbW91bnRlZCgpIHtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdjb250ZW5pZG8tYWN0dWFsaXphbmRvJywgKCkgPT4ge1xuICAgICAgICBjb250ZW5pZG91cGRhdGluZyA9IHRydWU7XG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2NvbnRlbmlkby1lc3RhYmlsaXphZG8nLCAoKSA9PiB7XG4gICAgICAgIGNvbnRlbmlkb3VwZGF0aW5nID0gZmFsc2U7XG4gICAgICAgIC8vIFJlYW51ZGFyIHByb2Nlc2FtaWVudG8gZGUgcHVibGljaWRhZCBkZXNwdcOpcyBkZSBicmV2ZSBkZWxheVxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBpZiAoIXB1YmxpX2xvY2spIHtcbiAgICAgICAgICAgIHJldWJpY2FyX3B1Ymxpcyh0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sIDIwMCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0sXG4gIExhenlSZWxhY2lvbmFkYXM6IHtcbiAgICBtb3VudGVkKCkge1xuICAgICAgY29uc3Qgb2JzZXJ2ZXIgPSBuZXcgSW50ZXJzZWN0aW9uT2JzZXJ2ZXIoKGVudHJpZXMsIG9ic2VydmVyKSA9PiB7XG4gICAgICAgIGVudHJpZXMuZm9yRWFjaChlbnRyeSA9PiB7XG4gICAgICAgICAgaWYgKGVudHJ5LmlzSW50ZXJzZWN0aW5nIHx8IGVudHJ5LmludGVyc2VjdGlvblJhdGlvID4gMCApIHtcbiAgICAgICAgICAgIC8vY29uc29sZS5sb2coXCJSRUxBQ0lPTkFEQVNcIik7XG4gICAgICAgICAgICAvLyBOb3RpZmljYXIgaW5pY2lvIGRlIGFjdHVhbGl6YWNpw7NuIGRlIGNvbnRlbmlkb1xuICAgICAgICAgICAgd2luZG93LmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KCdjb250ZW5pZG8tYWN0dWFsaXphbmRvJykpO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICB0aGlzLnB1c2hFdmVudChcImNhcmdhci1yZWxhY2lvbmFkYXNcIilcbiAgICAgICAgICAgIHRoaXMucHVzaEV2ZW50KFwiY2FyZ2FyLXBvcnRhZGlsbGFcIilcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLy8gTm90aWZpY2FyIGZpbiBkZSBhY3R1YWxpemFjacOzbiBkZXNwdcOpcyBkZSBwcm9jZXNhbWllbnRvXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgd2luZG93LmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KCdjb250ZW5pZG8tZXN0YWJpbGl6YWRvJykpO1xuICAgICAgICAgICAgfSwgMzAwKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgb2JzZXJ2ZXIudW5vYnNlcnZlKGVudHJ5LnRhcmdldCkgLy8gU29sbyB1bmEgdmV6XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfSwge1xuICAgICAgICByb290OiBudWxsLFxuICAgICAgICByb290TWFyZ2luOiBcIjE1MHB4XCIsIC8vIDEwMHB4IGFudGVzIGRlIGVudHJhciBlb
1iB2aXN0YVxuICAgICAgICB0aHJlc2hvbGQ6IDAuMDFcbiAgICAgIH0pXG5cbiAgICAgIG9ic2VydmVyLm9ic2VydmUodGhpcy5lbClcbiAgICB9LFxuICAgIHVwZGF0ZWQoKSB7XG4gICAgICBhcGFuaG9zX3B1YmxpX2Jsb3F1ZV90ZW1hKCk7XG4gICAgfVxuICB9LFxuICBMYXp5UG9ydGFkaWxsYToge1xuICAgIG1vdW50ZWQoKSB7XG4gICAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBJbnRlcnNlY3Rpb25PYnNlcnZlcigoZW50cmllcywgb2JzZXJ2ZXIpID0+IHtcbiAgICAgICAgZW50cmllcy5mb3JFYWNoKGVudHJ5ID0+IHtcbiAgICAgICAgICBpZiAoZW50cnkuaXNJbnRlcnNlY3RpbmcgfHwgZW50cnkuaW50ZXJzZWN0aW9uUmF0aW8gPiAwICkge1xuICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcIlBPUlRBRElMTEFcIik7XG4gICAgICAgICAgICBvYnNlcnZlci51bm9ic2VydmUoZW50cnkudGFyZ2V0KSAvLyBTb2xvIHVuYSB2ZXpcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICB9LCB7XG4gICAgICAgIHJvb3Q6IG51bGwsXG4gICAgICAgIHJvb3RNYXJnaW46IFwiMTUwcHhcIiwgLy8gMTAwcHggYW50ZXMgZGUgZW50cmFyIGVuIHZpc3RhXG4gICAgICAgIHRocmVzaG9sZDogMC4wMVxuICAgICAgfSlcblxuICAgICAgb2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsKVxuICAgIH1cbiAgfSxcbiAgTWVudVBvc2ljaW9uOiB7XG4gICAgbW91bnRlZCgpIHtcbiAgICAgIGFqdXN0ZV9tZW51X21vdmlsKClcbiAgICB9LFxuICAgIHVwZGF0ZWQoKSB7XG4gICAgICBhanVzdGVfbWVudV9tb3ZpbCgpXG4gICAgfSxcbiAgfSxcbiAgQXV0b0NsZWFyRmxhc2g6IHtcbiAgICBtb3VudGVkKCkge1xuICAgICAgbGV0IGlnbm9yZWRJRHMgPSBbXCJjbGllbnQtZXJyb3JcIiwgXCJzZXJ2ZXItZXJyb3JcIl07XG4gICAgICBpZiAoaWdub3JlZElEcy5pbmNsdWRlcyh0aGlzLmVsLmlkKSkgcmV0dXJuO1xuXG4gICAgICBsZXQgaGlkZUVsZW1lbnRBZnRlciA9IDMwMDA7IC8vIG1zXG4gICAgICBsZXQgY2xlYXJGbGFzaEFmdGVyID0gaGlkZUVsZW1lbnRBZnRlciArIDUwMDsgLy8gbXNcblxuICAgICAgLy8gZmlyc3QgaGlkZSB0aGUgZWxlbWVudFxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuZWwuc3R5bGUub3BhY2l0eSA9IDA7XG4gICAgICB9LCBoaWRlRWxlbWVudEFmdGVyKTtcblxuICAgICAgLy8gdGhlbiBjbGVhciB0aGUgZmxhc2hcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLnB1c2hFdmVudChcImx2OmNsZWFyLWZsYXNoXCIpO1xuICAgICAgfSwgY2xlYXJGbGFzaEFmdGVyKTtcbiAgICB9LFxuICB9LFxuICBBcGFuaG9Dcm9wOiB7XG4gICAgbW91bnRlZCgpe1xuICAgICAgYXBhbmhvX2Nyb3AoKTtcbiAgICAgIGNvbnNvbGUubG9nKFwiQ1JPUFwiKTtcbiAgICB9LFxuICAgIHVwZGF0ZWQoKXtcbiAgICAgIGFwYW5ob19jcm9wKCk7XG4gICAgICBjb25zb2xlLmxvZyhcIkNST1BcIik7XG4gICAgfSxcbiAgICBiZWZvcmVVcGRhdGUoKSB7XG4gICAgfSxcbiAgICBkZXN0cm95ZWQoKSB7XG4gICAgfSxcbiAgICBkaXNjb25uZWN0ZWQoKSB7XG4gICAgfSxcbiAgICByZWNvbm5lY3RlZCgpIHtcbiAgICB9LFxuICB9LFxuICBBcGFuaG9zQXJ0aWN1bG86IHtcbiAgICBtb3VudGVkKCl7XG4gICAgICBlamVjdXRhZG9zX2VtYmViaWRvcyA9IGZhbHNlO1xuICAgICAgcmV1YmljYXJfcmVzdW1lbmVzX2FydGljdWxvKCk7XG4gICAgICBsYW56YXJfY29kaWdvc19lbWJlYmlkb3MoKTtcbiAgICAgIGFwYW5ob3NfaW1hZ2VuZXNfYXJ0aWN1bG9zKCk7XG4gICAgICAvL3JldWJpY2FyX3B1YmxpcygpO1xuICAgICAgZXNwZXJhckhhc3RhUXVlRXhpc3RhQWx0dXJhTGltaXRhZG9zKCgpID0+IHtcbiAgICAgICAgZWplY3V0YWRvc19saW1pdGFkb3MgPSBmYWxzZTtcbiAgICAgICAgbGltaXRhZG9zKCk7XG4gICAgICB9KTtcbiAgICAgIGNvcGlhcl9hY29ydGFkb3MoKTtcbiAgICAgIGxhbnphcl9zY3JpcHRzKCk7XG4gICAgICBzY3JvbGxfaW50b19pZCgpXG4gICAgICBkb2
1N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsIHByb2Nlc3NTY3JvbGwpO1xuICAgIH0sXG4gICAgdXBkYXRlZCgpe1xuICAgIC8vY29uc29sZS5sb2coXCJBcnRpY3VsbyBVUERBVEVEXCIpXG4gICAgICBlamVjdXRhZG9zX2VtYmViaWRvcyA9IGZhbHNlO1xuICAgICAgYXBhbmhvc19pbWFnZW5lc19hcnRpY3Vsb3MoKTtcbiAgICAgIC8vbGFuemFyX2NvZGlnb3NfZW1iZWJpZG9zKCk7XG4gICAgICByZXViaWNhcl9yZXN1bWVuZXNfYXJ0aWN1bG8oKTtcbiAgICAgIC8vcmV1YmljYXJfcHVibGlzKHRydWUpO1xuICAgICAgbGFuemFyX3NjcmlwdHMoKTtcbiAgICAgIGVqZWN1dGFkb3NfZW1iZWJpZG9zID0gdHJ1ZTtcbiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgcHJvY2Vzc1Njcm9sbCk7XG4gICAgICBlc3BlcmFySGFzdGFRdWVFeGlzdGFBbHR1cmFMaW1pdGFkb3MoKCkgPT4ge1xuICAgICAgICBlamVjdXRhZG9zX2xpbWl0YWRvcyA9IGZhbHNlO1xuICAgICAgICBsaW1pdGFkb3MoKTtcbiAgICAgIH0pO1xuICAgICAgYXBhbmhvc19wdWJsaV9ibG9xdWVfdGVtYSgpXG5cbiAgICB9LFxuICB9LFxuICBBcGFuaG9zQ29tZW50YXJpb3M6IHtcbiAgICBtb3VudGVkKCl7XG4gICAgfSxcbiAgICB1cGRhdGVkKCl7XG4gICAgICByZWNvcnRhcl9jb21lbnRhcmlvcygpO1xuICAgICAgc2Nyb2xsX2ludG9faWQodHJ1ZSlcbiAgICB9LFxuICB9LFxuICBTd2lwZXJHYWxlcmlhczoge1xuICAgIHVwZGF0ZWQoKXtcbiAgICAgIHN3aXBlcl9nYWxlcmlhKCk7XG4gICAgICBzd2lwZXJfZ2FsZXJpYV9tb2RhbCgpO1xuICAgIH0sXG4gICAgbW91bnRlZCgpe1xuICAgICAgc3dpcGVyX2dhbGVyaWEoKTtcbiAgICAgIHN3aXBlcl9nYWxlcmlhX21vZGFsKCk7XG4gICAgfSxcbiAgfSxcbiAgQm9ycmFyVG9vbHRpcHM6IHtcbiAgICB1cGRhdGVkKCl7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnRlbXB0b29sdGlwJykuc3R5bGUuZGlzcGxheSA9ICdub25lJ1xuICAgICAgfSwgMTUwMCk7IFxuICAgIH0sXG4gICAgbW91bnRlZCgpe1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy50ZW1wdG9vbHRpcCcpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSdcbiAgICAgIH0sIDE1MDApOyBcbiAgICB9LFxuICB9LFxuICBFZGl0b3JTb2NpYXM6IHtcbiAgICB1cGRhdGVkKCl7XG4gICAgICAkKCcuc3VtbWVybm90ZScpLnN1bW1lcm5vdGUoJ2Rlc3Ryb3knKTtcbiAgICAgICQoJy5zdW1tZXJub3RlJykuc3VtbWVybm90ZShzdW1tZXJOb3RlTWluKTtcbiAgICB9LFxuICAgIG1vdW50ZWQoKXtcbiAgICAgICQoJy5zdW1tZXJub3RlJykuc3VtbWVybm90ZSgnZGVzdHJveScpO1xuICAgICAgJCgnLnN1bW1lcm5vdGUnKS5zdW1tZXJub3RlKHN1bW1lck5vdGVNaW4pO1xuICAgIH1cbiAgfSxcbiAgRWRpdG9yOiB7XG4gICAgdXBkYXRlZCgpe1xuICAgICAgJCgnLnN1bW1lcm5vdGUnKS5zdW1tZXJub3RlKCdkZXN0cm95Jyk7XG4gICAgICAkKCcuc3VtbWVybm90ZScpLnN1bW1lcm5vdGUoc3VtbWVyTm90ZUNvbmYpO1xuICAgIH0sXG4gICAgbW91bnRlZCgpe1xuICAgICAgJCgnLnN1bW1lcm5vdGUnKS5zdW1tZXJub3RlKCdkZXN0cm95Jyk7XG4gICAgICAkKCcuc3VtbWVybm90ZScpLnN1bW1lcm5vdGUoc3VtbWVyTm90ZUNvbmYpO1xuICAgIH1cbiAgfSxcbiAgRWRpdG9yTWluaW1vOiB7XG4gICAgbW91bnRlZCgpe1xuICAgICAgdGhpcy5pbml0U3VtbWVyTm90ZSgpO1xuICAgIH0sXG4gICAgdXBkYXRlZCgpe1xuICAgICAgdGhpcy5pbml0U3VtbWVyTm90ZSgpO1xuICAgIH0sXG4gICAgZGVzdHJveWVkKCl7XG4gICAgICB0aGlzLmRlc3Ryb3lTdW1tZXJOb3RlKCk7XG4gICAgfSxcbiAgICBpbml0U3VtbWVyTm90ZSgpe1xuICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZWwucXVlcnlTZWxlY3RvcignLnN1bW1lcm5vdGUnKTtcbiAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgIGxldCBjb250ZW5pZG8gPSAnJztcbiAgICAgICAgaWYgKCQoZWxlbWVudCkuZGF0YSgnc3VtbWVybm90ZScpKSB7XG4gICAgICAgICAgY29udGVuaWRvID0gJChlbGVtZW50KS5zdW1tZXJub3RlKCdjb2RlJyk7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgICQoZWxlbWVudCkuc3VtbWVybm90ZSgnZGVzdHJveScpO1xuICAgICAgICAkKGVsZW1lbnQpLnN1bW1lcm5vdGUoc3VtbWVyTm90ZU1pbik7XG4gICAgICAgIFxuICAgICAgICBpZiAoY29udGVuaWRvKSB7XG4gICAgICAgICAgJChlbGVtZW50KS5zdW1tZXJub3RlKCdjb2RlJywgY29udGVuaWRvKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgZGVzdHJveVN1bW1lck5vdGUoKXtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoJy5zdW1tZXJub3RlJyk7XG4gICAgICBpZiAoZWxlbWVudCAmJiAkKGVsZW1lbnQpLmRhdGEoJ3N1bW1lcm5vdGUnKSkge1xuICAgICAgICAkKGVsZW1lbnQpLnN1bW1lcm5vdGUoJ2Rlc3Ryb3knKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIE5vdGlmaWNhY2lvbmVzOiB7XG4gICAgbW91bnRlZCgpIHtcbiAgICAgIGNvbnN0IGhvb2sgPSB0aGlzOyBcbiAgICAgIHB1c2hCdXR0b24gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuanMtcHVzaC1idG4nKTtcbiAgICAgIGNhbmFsZXNEaXYgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuY2FuYWxlcycpO1xuICAgICAgaWYgKCdzZXJ2aWNlV29ya2VyJyBpbiBuYXZpZ2F0b3IgJiYgJ1B1c2hNYW5hZ2VyJyBpbiB3aW5kb3cpIHtcbiAgICAgICAgbmF2aWdhdG9yLnNlcnZpY2VXb3JrZXIucmVnaXN0ZXIoJy9zdy5qcycpXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uKHN3UmVnKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ1NlcnZpY2UgV29ya2VyIHJlZ2lzdHJhZG8nKTtcbiAgICAgICAgICBzd1JlZ2lzdHJhdGlvbiA9IHN3UmVnO1xuXG4gICAgICAgICAgaW5pdGlhbGl6ZU5vdGlmaWNhdGlvbnNVSShob29rKTtcblxuICAgICAgICAgI
1HN3UmVnaXN0cmF0aW9uLnB1c2hNYW5hZ2VyLmdldFN1YnNjcmlwdGlvbigpXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbihzdWJzY3JpcHRpb24pIHtcbiAgICAgICAgICAgICAgaG9vay5wdXNoRXZlbnQoXCJzdXNjcml0b1wiLCBzdWJzY3JpcHRpb24pXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZnVuY3Rpb24oZXJyb3IpIHtcbiAgICAgICAgICAvL2NvbnNvbGUuZXJyb3IoJ1NlcnZpY2UgV29ya2VyIEVycm9yJywgZXJyb3IpO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1NlcnZpY2UgV29ya2VyIEVycm9yJyApO1xuICAgICAgICAgIGNvbnNvbGUubG9nKGVycm9yLm1lc3NhZ2UpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKGVycm9yLm5hbWUpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKGVycm9yLnN0YWNrKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS5sb2coXCJOTyBzb3BvcnRhZG9cIik7XG4gICAgICB9XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignb25saW5lJywgaGFuZGxlQ29ubmVjdGlvbik7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignb2ZmbGluZScsIGhhbmRsZUNvbm5lY3Rpb24pO1xuICAgIC8qXG4gICAgICBjb25zb2xlLmxvZyhOb3RpZmljYXRpb24pO1xuICAgICAgaWYoTm90aWZpY2F0aW9uLnBlcm1pc3Npb24gPT09IFwiZGVmYXVsdFwiKSB7XG4gICAgICBjb25zb2xlLmxvZyhcInBlcm1pc28/Pz9cIik7XG5cbiAgICAgICAgTm90aWZpY2F0aW9uLnJlcXVlc3RQZXJtaXNzaW9uKCk7XG4gICAgICAgLy9zd1JlZ2lzdHJhdGlvbi5wdXNoTWFuYWdlci5nZXRTdWJzY3JpcHRpb24oKVxuICAgICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKFwicGVybWlzbyBzaS4uLi4uPz8/XCIpO1xuXG4gICAgICB9XG4gICAgKi9cbiAgICB9XG4gIH0sXG4gIENvb2tpZUhvb2s6IHtcbiAgICBtb3VudGVkKCkge1xuICAgICAgdGhpcy5oYW5kbGVFdmVudCgnY29va2llX3BvcnRhZGEnLCBhc3luYyAocGFyYW1zKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgZmV0Y2goJ2FwaS9jb29raWVfcG9ydGFkYScsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ3Bvc3QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkocGFyYW1zKSxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBjYXRjaChlcnIpIHtcbiAgICAgICAgICBhbGVydChlcnIubWVzc2FnZSA/PyBcIkFuIGVycm9yIG9jY3VycmVkXCIpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH0sICBcbiAgQXVkaW9SYWRpb1NlbGVjY2lvbmFyOiB7XG4gICAgZGVzdHJveWVkKCkge1xuICAgIH0sXG4gICAgbW91bnRlZCgpe1xuICAgICAgLy9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcmVwcm9kdWN0b3JfcmFkaW8nKS5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZvXCIpXG4gICAgICBhdWRpb19vcmlnZW4gPSBcImRpcmVjdG9cIjtcbiAgICAgIGlmIChhdWRpby5wYXVzZWQpIHtcbiAgICAgICAgbGl2ZVNvY2tldC5ob29rcy5BdWRpb1BsYXllci5kYXRvc19hdWRpbygpOyBcbiAgICAgIH07XG4gICAgICB0aGlzLmFuaGFkaXJfZXZlbnRvcygpXG4gICAgfSxcbiAgICBhbmhhZGlyX2V2ZW50b3MoKXtcbiAgICAgIHZhciB2aWV3cG9ydFdpZHRoID0gd2luZG93LmlubmVyV2lkdGggfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoO1xuICAgICAgaWYgKHZpZXdwb3J0V2lkdGggIDwgIDc2OSkge1xuICAgICAgICB2Y
1XIgaG95ID0gbmV3IERhdGUoKS5nZXREYXkoKSBcbiAgICAgICAgdGhpcy50b2dnbGVEYXkoaG95KVxuICAgICAgfVxuICAgIH0sXG4gICAgdG9nZ2xlRGF5KGRheSkge1xuICAgICAgdmFyIGRheXMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImRheXNcIik7XG4gICAgICB2YXIgZ3JpZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiZ3JpZFwiKTtcbiAgICAgIHZhciBsYWJlbHMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFwiZGF5XCIpXG4gICAgICBzd2l0Y2ggKGRheSl7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICBncmlkLnN0eWxlLnNldFByb3BlcnR5KFwiZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zXCIsXG4gICAgICAgICAgICBcIjNlbSAxMHB4IGNhbGMoMTAwJSAtIDNlbSAtIDEwcHgpIHJlcGVhdCg2LCAwKVwiKVxuICAgICAgICAgIGRheXMuc3R5bGUuc2V0UHJvcGVydHkoXCJncmlkLXRlbXBsYXRlLWNvbHVtbnNcIixcbiAgICAgICAgICAgIFwiM2VtIDEwcHggY2FsYygxMDAlIC0gM2VtIC0gMTBweCkgcmVwZWF0KDYsIDApXCIpXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICBkYXlzLnN0eWxlLnNldFByb3BlcnR5KFwiZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zXCIsXG4gICAgICAgICAgICBcIjNlbSAxMHB4IDAgY2FsYygxMDAlIC0gM2VtIC0gMTBweCkgMCAwIDAgMCAwXCIpXG4gICAgICAgICAgZ3JpZC5zdHlsZS5zZXRQcm9wZXJ0eShcImdyaWQtdGVtcGxhdGUtY29sdW1uc1wiLFxuICAgICAgICAgICAgXCIzZW0gMTBweCAwIGNhbGMoMTAwJSAtIDNlbSAtIDEwcHgpIDAgMCAwIDAgMFwiKVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgZGF5cy5zdHlsZS5zZXRQcm9wZXJ0eShcImdyaWQtdGVtcGxhdGUtY29sdW1uc1wiLFxuICAgICAgICAgICAgXCIzZW0gMTBweCAwIDAgY2FsYygxMDAlIC0gM2VtIC0gMTBweCkgMCAwIDAgMFwiKVxuICAgICAgICAgIGdyaWQuc3R5bGUuc2V0UHJvcGVydHkoXCJncmlkLXRlbXBsYXRlLWNvbHVtbnNcIixcbiAgICAgICAgICAgIFwiM2VtIDEwcHggMCAwIGNhbGMoMTAwJSAtIDNlbSAtIDEwcHgpIDAgMCAwIDBcIilcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIGRheXMuc3R5bGUuc2V0UHJvcGVydHkoXCJncmlkLXRlbXBsYXRlLWNvbHVtbnNcIixcbiAgICAgICAgICAgIFwiM2VtIDEwcHggMCAwIDAgY2FsYygxMDAlIC0gM2VtIC0gMTBweCkgMCAwIDBcIilcbiAgICAgICAgICBncmlkLnN0eWxlLnNldFByb3BlcnR5KFwiZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zXCIsXG4gICAgICAgICAgICBcIjNlbSAxMHB4IDAgMCAwIGNhbGMoMTAwJSAtIDNlbSAtIDEwcHgpIDAgMCAwXCIpXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgNTpcbiAgICAgICAgICBkYXlzLnN0eWxlLnNldFByb3BlcnR5KFwiZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zXCIsXG4gICAgICAgICAgICBcIjNlbSAxMHB4IDAgMCAwIDAgY2FsYygxMDAlIC0gM2VtIC0gMTBweCkgMCAwXCIpXG4gICAgICAgICAgZ3JpZC5zdHlsZS5zZXRQcm9wZXJ0eShcImdyaWQtdGVtcGxhdGUtY29sdW1uc1wiLFxuICAgICAgICAgICAgXCIzZW0gMTBweCAwIDAgMCAwIGNhbGMoMTAwJSAtIDNlbSAtIDEwcHgpIDAgMFwiKVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgZGF5cy5zdHlsZS5zZXRQcm9wZXJ0eShcImdyaWQtdGVtcGxhdGUtY29sdW1uc1wiLFxuICAgICAgICAgICAgXCIzZW0gMTBweCAwIDAgMCAwIDAgY2FsYygxMDAlIC0gM2VtIC0gMTBweCkgMFwiKVxuICAgICAgICAgIGdyaWQuc3R5bGUuc2V0UHJvcGVydHkoXCJncmlkLXRlbXBsYXRlLWNvbHVtbnNcIixcbiAgICAgICAgICAgIFwiM2VtIDEwcHggMCAwIDAgMCAwIGNhbGMoMTAwJSAtIDNlbSAtIDEwcHgpIDBcIilcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBkYXlzLnN0eWxlLnNldFByb3BlcnR5KFwiZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zXCIsXG4gICAgICAgICAgICBcIjNlbSAxMHB4ICByZXBlYXQoNiwgMCkgY2FsYygxMDAlIC0gM2VtIC0gMTBweClcIilcbiAgICAgICAgICBncmlkLnN0eWxlLnNldFByb3BlcnR5KFwiZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zXCIsXG4gICAgICAgICAgICBcIjNlbSAxMHB4ICByZXBlYXQoNiwgMCkgY2FsYygxMDAlIC0gM2VtIC0gMTBweClcIilcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGFiZWxzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxhYmVsc1tpXS5zdHlsZS5zZXRQcm9wZXJ0eShcImhlaWdodFwiLCBcIjBweFwiKVxuICAgICAgICBsYWJlbHNbaV0uc3R5bGUuc2V0UHJvcGVydHkoXCJ2aXNpYmlsaXR5XCIsIFwiaGlkZGVuXCIpXG4gICAgICB9XG4gICAgICBsYWJlbHNbZGF5LTFdLnN0eWxlLnNldFByb3BlcnR5KFwiaGVpZ2h0XCIsIFwiYXV0b1wiKVxuICAgICAgbGFiZWxzW2RheS0xXS5zdHlsZS5zZXRQcm9wZXJ0eShcInZpc2liaWxpdHlcIiwgXCJ2aXNpYmxlXCIpXG4gICAgfVxuICB9LFxuICBMaXN0YWRvUmFkaW86IHtcbiAgICBtb3VudGVkKCl7XG4gICAgICB2Y
1XIgdyA9IHdpbmRvdy5pbm5lcldpZHRoXG4gICAgICAgIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aFxuICAgICAgICB8fCBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoO1xuXG4gICAgICBpZih3ID4gNzY4KXtcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3JlcHJvZHVjdG9yX3JhZGlvJykuY2xhc3NMaXN0LmFkZChcImFjdGl2b1wiKVxuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LmFkZChcInJhZGlvXCIpXG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5jbGFzc0xpc3QuYWRkKFwib3ZlcmZsb3dfbVwiKVxuICAgICAgfVxuICAgIH0sXG4gIH0sXG4gIEF1ZGlvU2VsZWNjaW9uYXI6IHtcbiAgICBkaXNjb25uZWN0ZWQoKSB7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcmVwcm9kdWN0b3JfcmFkaW8nKS5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZvXCIpXG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LnJlbW92ZShcInJhZGlvXCIpXG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LnJlbW92ZShcIm92ZXJmbG93X21cIilcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5wbGF5LXBvZGNhc3QnKS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUgJztcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5jbGFzc0xpc3QucmVtb3ZlKFwib3ZlcmZsb3dcIilcbiAgICAgIGlmIChhdWRpby5wYXVzZWQpIHtcbiAgICAgICAgYXVkaW9fb3JpZ2VuID0gXCJyZWNvbWVuZGFjaW9uXCI7XG4gICAgICAgIGxpdmVTb2NrZXQuaG9va3MuQXVkaW9QbGF5ZXIuZGF0b3NfYXVkaW8oKTsgXG4gICAgICB9XG4gICAgfSxcbiAgICBkZXN0cm95ZWQoKSB7XG4gICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcmVwcm9kdWN0b3JfcmFkaW8nKS5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZvXCIpXG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LnJlbW92ZShcInJhZGlvXCIpXG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LnJlbW92ZShcIm92ZXJmbG93X21cIilcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5wbGF5LXBvZGNhc3QnKS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUgJztcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5jbGFzc0xpc3QucmVtb3ZlKFwib3ZlcmZsb3dcIilcbiAgICAgIGlmIChhdWRpby5wYXVzZWQpIHtcbiAgICAgICAgYXVkaW9fb3JpZ2VuID0gXCJyZWNvbWVuZGFjaW9uXCI7XG4gICAgICAgIGxpdmVTb2NrZXQuaG9va3MuQXVkaW9QbGF5ZXIuZGF0b3NfYXVkaW8oKTsgXG4gICAgICB9XG4gICAgfSxcbiAgICB1cGRhdGVkKCl7XG4gICAgfSxcbiAgICBtb3VudGVkKCl7XG4gICAgICBjb25zdCB1YSA9IG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKTtcbiAgICAgIGNvbnN0IGlzVGVsZWdyYW0gPSB1YS5pbmNsdWRlcygndGVsZWdyYW0nKTtcbiAgICAgIGNvbnN0IGlzTW92aWxlU2FmYXJpID0gdWEuaW5jbHVkZXMoJ21vYmlsZSBzYWZhcmknKTtcblxuICAgICAgYXVkaW9fb3JpZ2VuID0gXCJwb2RjYXN0XCI7XG5cbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5wb2RjYXN0LXRpdHVsbycpLmlubmVyVGV4dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhdWRpby10aXR1bG8nKS5pbm5lclRleHQ7XG4gICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGxheS1wb2RjYXN0Jykuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGxheS1wb2RjYXN0JykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZXZlbnQpID0+IHsgdGhpcy5zZWxlY2Npb25hcigpOyB9KTtcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwicG9kY2FzdC1yYWRpby1ib3RcIikuc3JjID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzZWxlY2Npb25hclwiKS5zcmM7XG5cbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNyZXByb2R1Y3Rvcl9yYWRpbycpLmNsYXNzTGlzdC5hZGQoXCJhY3Rpdm9cIilcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5jbGFzc0xpc3QuYWRkKFwicmFkaW9cIilcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5jbGFzc0xpc3QuYWRkKFwib3ZlcmZsb3dfbVwiKVxuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYm9keScpLmNsYXNzTGlzdC5yZW1vdmUoXCJvdmVyZmxvd1wiKVxuXG4gICAgICBpZiAoYXVkaW8ucGF1c2VkKSB7XG4gICAgICAgIGxpdmVTb2NrZXQuaG9va3MuQXVkaW9QbGF5ZXIuZGF0b3NfYXVkaW8oKTsgXG4gICAgICB9XG5cbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNyZXByb2R1Y3Rvcl9yYWRpbycpLmNsYXNzTGlzdC5hZGQoXCJhY3Rpdm9cIilcbiAgICB9LFxuICAgIHNlbGVjY2lvbmFyKCkge1xuICAgICAgYXVkaW9fb3JpZ2VuID0gXCJwb2RjYXN0XCI7XG4gICAgICBsaXZlU29ja2V0Lmhvb2tzLkF1ZGlvUGxheWVyLmF1ZGlvX3JlcHJvZHVjaXIoKTsgXG4gICAgfSxcbiAgfSxcbiAgQXVkaW9QbGF5ZXI6IHtcbiAgICBtb3VudGVkKCl7XG4gICAgICAvL3BhcmEgcXVlIG5vIHNlIGN1ZWxxdWUgZWwgVGVsZWdyYW0uLi5cbiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ2aXNpYmlsaXR5Y2hhbmdlXCIsICgpID0+IHtcbiAgICAgICAgaWYgKGRvY3VtZW50LmhpZGRlbikge1xuICAgICAgICAgIHdpbmRvdy5hdWRpb1BsYXlpbmdPbkhpZGUgPSBhdWRpbyAmJiAhYXVkaW8ucGF1c2VkO1xuICAgICAgICB9IGVsc2UgaWYgKHdpbmRvdy5hdWRpb1BsYXlpbmdPbkhpZGUgJiYgYXVkaW8gJiYgYXVkaW8ucGF1c2VkKSB7XG4gICAgICAgICAgYXVkaW8ucGxheSgpLmNhdGNoKCgpID0+IHt9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGxheS1idXR0b24ucGxheScpXG4gICAgICAuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZXZlbnQpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuaXNSZXN0cmljdGVkRW52KCkpIHtcbiAgICAgICAgICB0aGlzLm1vc3RyYXJBdmlzb1NhbGlkYSgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYXVkaW9fb3JpZ2VuID09IFwicG9kY2FzdFwiIHx8IGF1ZGlvX29yaWdlbiA9PSBcInJlY29tZW5kYWNpb25cIikge1xuICAgICAgICAgIHRoaXMuYXVkaW9fcmVwcm9kdWNpcigpOyBcbiAgICAgICAgfSBlbHNlICB7XG4gICAgICAgICAgdGhpcy5wbGF5X2RpcmVjdG8oKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5wbGF5LWRpcmVjdG8nKVxuICAgICAgLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2ZW50KSA9PiB7IHRoaXMucGxheV9kaXJlY3RvKCk7IH0pO1xuXG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGxheS1idXR0b24ucGF1c2UnKVxuICAgICAgLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2ZW50KSA9PiB7IHRoaXMucGF1c2FyKCk7IH0pO1xuXG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubXV0ZS1idXR0b24ubXV0ZScpXG4gICAgICAuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZXZlbnQpID0+IHsgdGhpcy5tdXRlYXIoKTsgfSk7XG5cbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5tdXRlLWJ1dHRvbi51bm11dGUnKVxuICAgICAgLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2ZW50KSA9PiB7IHRoaXMudW5tdXRlYXIoKTsgfSk7XG5cbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5oYWNpYS1hdHJhcycpXG4gICAgICAgIC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIChldmVudCkgPT4geyB0aGlzLnBvc2ljaW9uKC0xMCk7IH0pO1xuXG4gICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcuaGFjaWEtZGVsYW50ZScpXG4gICAgICAgIC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIChldmVudCkgPT4geyB0aGlzLnBvc2ljaW9uKDEwKTsgfSk7XG5cbiAgICAgIGF1ZGlvX3Bvc2l0aW9uXG4gICAgICAgIC5hZGRFdmVudExpc3RlbmVyKFwiY2hhbmdlXCIsIChldmVudCkgPT4gIHtcbiAgICAgICAgYXVkaW8uY3VycmVudFRpbWUgPSBhdWRpb19wb3NpdGlvbi52YWx1ZTtcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm1vbWVudG8nKS5pbm5lclRleHQgPVxuICAgICAgICAgIHNlZ3VuZG9zX2Ffc3RyaW5nKGF1ZGlvLmN1cnJlbnRUaW1lKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5kYXRvc19hdWRpbygpO1xuICAgIH0sXG4gICAgaXNUZWxlZ3JhbSgpIHtcbiAgICAgIGNvbnN0IHVhID0gbmF2aWdhdG9yLnVzZXJBZ2VudCB8fCBcIlwiO1xuICAgICAgcmV0dXJuIC9UZWxlZ3JhbS9pLnRlc3QodWEpO1xuICAgIH0sXG4gICAgaXNXZWJWaWV3KCkge1xuICAgICAgY29uc3QgdWEgPSBuYXZpZ2F0b3IudXNlckFnZW50IHx8IFwiXCI7XG5cbiAgICAgIC8vIEFuZHJvaWQgV2ViVmlldyB0w61waWNvXG4gICAgICBjb25zdCBpc0FuZHJvaWRXZWJWaWV3ID0gL3d2fFdlYlZpZXcvaS50ZXN0KHVhKTtcblxuICAgICAgLy8gaU9TIFdlYlZpZXcgKG5vIFNhZmFyaSlcbiAgICAgIGNvbnN0IGlzSU9TV2ViVmlldyA9IC9pUGhvbmV8aVBhZC8udGVzdCh1YSkgJiYgIS9TYWZhcmkvaS50ZXN0KHVhKTtcblxuICAgICAgcmV0dXJuIGlzQW5kcm9pZFdlYlZpZXcgfHwgaXNJT1NXZWJWaWV3O1xuICAgIH0sXG4gICAgaXNSZXN0cmljdGVkRW52KCkge1xuICAgICAgLy9yZXR1cm4gdHJ1ZTtcbiAgICAgIHJldHVybiB0aGlzLmlzVGVsZWdyYW0oKSB8fCB0aGlzLmlzV2ViVmlldygpO1xuICAgIH0sXG4gICAgbW9zdHJhckF2aXNvU2FsaWRhKCkge1xuICAgICAgY29uc3QgbW9kYWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImF2aXNvLXRlbGVncmFtXCIpO1xuICAgICAgY29uc3QgbGluayA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYWJyaXItbmF2ZWdhZG9yXCIpO1xuXG4gICAgICAvLyBVUkwgYWN0dWFsXG4gICAgICBsaW5rLmhyZWYgPSB3aW5kb3cubG9jYXRpb24uaHJlZjtcblxuICAgICAgbW9kYWwuY2xhc3NMaXN0LnJlbW92ZShcImhpZGRlblwiKTtcblxuICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzZWd1aXItYXF1aVwiKVxuICAgICAgICAub25jbGljayA9ICgpID0+IHtcbiAgICAgICAgICBtb2RhbC5jbGFzc0xpc3QuYWRkKFwiaGlkZGVuXCIpO1xuXG4gICAgICAgICAgaWYgKGF1ZGlvX29yaWdlbiA9PSBcInBvZGNhc3RcIiB8fCBhdWRpb19vcmlnZW4gPT0gXCJyZWNvbWVuZGFjaW9uXCIpIHtcbiAgICAgICAgICAgIHRoaXMuYXVkaW9fcmVwcm9kdWNpcigpOyBcbiAgICAgICAgICB9IGVsc2UgIHtcbiAgICAgICAgICAgIHRoaXMucGxheV9kaXJlY3RvKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0sXG4gICAgYXVkaW9fcmVwcm9kdWNpcigpIHtcbiAgICAgIC8vIGVzdGFkbyBhY3R1YWwgYW50ZXMgZGUgY3VhbHF1aWVyIGNhbWJpb1xuICAgICAgbGV0IGlzUmVzdW1lID0gYXVkaW8gJiYgYXVkaW8uc3JjICYmIGF1ZGlvLnBhdXNlZCAmJiBhdWRpby5jdXJyZW50VGltZSA+IDA7XG5cbiAgICAgIGF1ZGlvLnBhdXNlKCk7XG4gICAgICBpZiAoYXVkaW9fb3JpZ2VuID09IFwicG9kY2FzdFwiIHx8IGF1ZGlvX29yaWdlbiA9PSBcInJlY29tZW5kYWNpb25cIikge1xuICAgICAgICB0aGlzLmNlcnJhcl9kYXRvc19kaXJlY3RvKCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFNvbG8gbGxhbWFyIGEgZGF0b3NfYXVkaW8oKSBwYXJhIG51ZXZhcyBzZWxlY2Npb25lc1xuICAgICAgaWYgKCFpc1Jlc3VtZSkge1xuICAgICAgICB0aGlzLmRhdG9zX2F1ZGlvKCk7XG4gICAgICB9IFxuXG4gICAgICAvLyBhc2VndXJhcm5vcyBxdWUgbGEgZHVyYWNpw7NuIGVzdMOpIGRpc3BvbmlibGVcbiAgICAgIGlmIChhdWRpby5kdXJhdGlvbikge1xuICAgICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcudGllbXBvJykuaW5uZXJUZXh0ID0gc2VndW5kb3NfYV9zdHJpbmcoYXVkaW8uZHVyYXRpb24pO1xuICAgICAgYXVkaW9fcG9zaXRpb24uc2V0QXR0cmlidXRlKFwibWF4XCIsIGF1ZGlvLmR1cmF0aW9uKTtcbiAgICAgIH1cblxuICAgICAgYXVkaW8ucGxheSgpO1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmNvbl9zb25pZG8nKS5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5wbGF5LWJ1dHRvbi5wbGF5Jykuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5wbGF5LWJ1dHRvbi5wYXVzZScpLnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lLWJsb2NrJztcbiAgICB9LFxuICAgIHBsYXlfZGlyZWN0bygpIHtcbiAgICAgIGF1ZGlvX29yaWdlbiA9IFwiZGlyZWN0b1wiO1xuICAgICAgdGhpcy5hdWRpb19yZXByb2R1Y2lyKCk7XG4gICAgfSxcbiAgICBwYXVzYXIoKSB7XG4gICAgICBhdWRpby5wYXVzZSgpO1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBsYXktYnV0dG9uLnBsYXknKS5zdHlsZS5kaXNwbGF5ID0gJ2lubGluZS1ibG9jayc7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGxheS1idXR0b24ucGF1c2UnKS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmNvbl9zb25pZG8nKS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIH0sXG4gICAgbXV0ZWFyKCkge1xuICAgICAgYXVkaW8udm9sdW1lID0gMDtcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5tdXRlLWJ1dHRvbi51bm11dGUnKS5zdHlsZS5kaXNwbGF5ID0gJ2lubGluZS1ibG9jayc7XG4gICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcubXV0ZS1idXR0b24ubXV0ZScpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuY29uX3NvbmlkbycpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgfSxcbiAgICB1bm11dGVhcigpIHtcbiAgICAgIC8vYXVkaW8udm9sdW1lID0gdGhpcy5yYW5nZS52YWx1ZS8xMDA7XG4gICAgICBhdWRpby52b2x1bWUgPSA1MC8xMDA7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubXV0ZS1idXR0b24ubXV0ZScpLnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lLWJsb2NrJ1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm11dGUtYnV0dG9uLnVubXV0ZScpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuY29uX3NvbmlkbycpLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgIH0sXG4gICAgZGF0b3NfYXVkaW8oKSB7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcmVwcm9kdWN0b3JfcmFkaW8nKS5jbGFzc0xpc3QuYWRkKGF1ZGlvX29yaWdlbik7XG4gICAgICBzd2l0Y2goYXVkaW9fb3JpZ2VuKSB7XG4gICAgICAgIGNhc2UgXCJyZWNvbWVuZGFjaW9uXCI6XG4gICAgICAgICAgYXVkaW8gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInNlbGVjY2lvbi1yYWRpb1wiKTtcbiAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubW9kbycpLmlubmVyVGV4dCA9IFwiUmVjb21lbmRhY2nDs25cIjtcbiAgICAgICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc29uYW5kbzEnKS5pbm5lclRleHQgPSBcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zZWxlY2Npb24tdGl0dWxvJykuaW5uZXJUZXh0O1xuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zb25hbmRvMicpLmlubmVyVGV4dCA9IFxuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNlbGVjY2lvbi10ZW1hJykuaW5uZXJUZXh0O1xuICAgICAgICAgIHRoaXMuY29udHJvbF90aWVtcG8oKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJwb2RjYXN0XCI6XG4gICAgICAgICAgYXVkaW8gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInBvZGNhc3QtcmFkaW8tYm90XCIpO1xuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5tb2RvJykuaW5uZXJUZXh0ID0gXCJQb2RjYXN0XCI7XG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNvbmFuZG8xJykuaW5uZXJUZXh0ID0gXG4gICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXVkaW8tdGl0dWxvJykuaW5uZXJUZXh0O1xuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zb25hbmRvMicpLmlubmVyVGV4dCA9IFxuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2F1ZGlvLXRlbWEnKS5pbm5lclRleHQ7XG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI1JhZGlvQm90IC5pbWFnZW4nKS5pbm5lckhUTUwgPSBcIlwiO1xuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNSYWRpb0JvdCAuaW1hZ2VuJylcbiAgICAgICAgICAgIC5hcHBlbmRDaGlsZChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYXJ0aWN1bG8tY29udGVuaWRvIC5jYWJlY2VyYSAucmVzcG9uc2l2ZWx5LWxhenknKS5jbG9uZU5vZGUodHJ1ZSkpO1xuICAgICAgICAgIHRoaXMuY29udHJvbF90aWVtcG8oKTtcblxuXG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBvZGNhc3QtdGl0dWxvJykuaW5uZXJUZXh0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2F1ZGlvLXRpdHVsbycpLmlubmVyVGV4dDtcbiAgICAgICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGxheS1wb2RjYXN0Jykuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBsYXktcG9kY2FzdCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2ZW50KSA9PiB7IHRoaXMuc2VsZWNjaW9uYXIoKTsgfSk7XG4gICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJwb2RjYXN0LXJhZGlvLWJvdFwiKS5zcmMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInNlbGVjY2lvbmFyXCIpLnNyYztcblxuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNyZXByb2R1Y3Rvcl9yYWRpbycpLmNsYXNzTGlzdC5hZGQoXCJhY3Rpdm9cIilcbiAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LmFkZChcInJhZGlvXCIpXG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYm9keScpLmNsYXNzTGlzdC5hZGQoXCJvdmVyZmxvd19tXCIpXG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYm9keScpLmNsYXNzTGlzdC5yZW1vdmUoXCJvdmVyZmxvd1wiKVxuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNyZXByb2R1Y3Rvcl9yYWRpbycpLmNsYXNzTGlzdC5hZGQoXCJhY3Rpdm9cIilcblxuICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDogXG4gICAgICAgICAgLy9hdWRpbyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiZGlyZWN0by1yYWRpby1ib3RcIik7XG4gICAgICAgICAgLy9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubW9kbycpLmlubmVyVGV4dCA9IFwiUmFkaW8gMjRoXCI7XG4gICAgICAgICAgLy9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc29uYW5kbzEnKS5pbm5lclRleHQgPSBcIlwiO1xuICAgICAgICAgIC8vZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNvbmFuZG8yJykuaW5uZXJUZXh0ID0gXCJcIjtcbi8vXG4gICAgICAgICAgYXVkaW8gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInNlbGVjY2lvbi1yYWRpb1wiKTtcbiAgICAgICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcubW9kbycpLmlubmVyVGV4dCA9IFwiUmVjb21lbmRhY2nDs25cIjtcbiAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc29uYW5kbzEnKS5pbm5lclRleHQgPSBcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zZWxlY2Npb24tdGl0dWxvJykuaW5uZXJUZXh0O1xuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zb25hbmRvMicpLmlubmVyVGV4dCA9IFxuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNlbGVjY2lvbi10ZW1hJykuaW5uZXJUZXh0O1xuICAgICAgICAgIHRoaXMuY29udHJvbF90aWVtcG8oKTtcbiAgICAgIH1cblxuICAgIH0sXG4gICAgZGF0b3NfZGlyZWN0bygpe1xuICAgICAgc29ja2V0X3JhZGlvX2JvdCA9IG5ldyBXZWJTb2NrZXQocmFkaW9ib3RfYXBpKTtcbiAgICAgIHNvY2tldF9yYWRpb19ib3Qub25vcGVuID0gZnVuY3Rpb24oZSkge1xuICAgICAgICBzb2NrZXRfcmFkaW9fYm90LnNlbmQoSlNPTi5zdHJpbmdpZnkoe1wic3Vic1wiOiB7XCJzdGF0aW9uOnNhbHRvXCI6IHt9fX0pKTtcbiAgICAgIH07XG5cbiAgICAgIHNvY2tldF9yYWRpb19ib3Qub25tZXNzYWdlID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IEpTT04ucGFyc2UoZXZlbnQuZGF0YSk7XG4gICAgICAgIGNvbnN0IG5wID0gZGF0YT8ucHViPy5kYXRhPy5ucCB8fCBudWxsO1xuICAgICAgICBpZiAobnApIHtcbiAgICAgICAgICBhdWRpb19tb21lbnRvID0gbnAubm93X3BsYXlpbmcuZWxhcHNlZCAvIG5wLm5vd19wbGF5aW5nLmR1cmF0aW9uICogMTAwICsgXCIlXCJcbiAgICAgICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc29uYW5kbzEnKS5pbm5lclRleHQgPSBcbiAgICAgICAgICAgIG5wLm5vd19wbGF5aW5nLnBsYXlsaXN0LnNwbGl0KFwiIC0gXCIpWzFdIHx8IFwiQ29udGludWlkYWRcIjtcbiAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc29uYW5kbzInKS5pbm5lclRleHQgPSBcbiAgICAgICAgICAgIG5wLm5vd19wbGF5aW5nLnNvbmcudGV4dCArIFwiIHwgXCI7XG4gICAgICAgICAgYXVkaW9fcHJvZ3Jlc28uc3R5bGUuc2V0UHJvcGVydHkoXCItLXByb2dyZXNvXCIsIGF1ZGlvX21vbWVudG8pO1xuICAgICAgICAgIGF1ZGlvX3Bvc2l0aW9uLnZhbHVlID0gbnAubm93X3BsYXlpbmcuZWxhcHNlZDtcbiAgICAgICAgICBhdWRpb19wb3NpdGlvbi5zZXRBdHRyaWJ1dGUoXCJtYXhcIiwgbnAubm93X3BsYXlpbmcuZHVyYXRpb24pXG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnRpZW1wbycpLmlubmVyVGV4dCA9XG4gICAgICAgICAgICBzZWd1bmRvc19hX3N0cmluZyhucC5ub3dfcGxheWluZy5kdXJhdGlvbik7XG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm1vbWVudG8nKS5pbm5lclRleHQgPVxuICAgICAgICAgICAgc2VndW5kb3NfYV9zdHJpbmcobnAubm93X3BsYXlpbmcuZWxhcHNlZCk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfSxcbiAgICBjZXJyYXJfZGF0b3NfZGlyZWN0bygpIHtcbiAgICAgIGlmKHNvY2tldF9yYWRpb19ib3QucmVhZHlTdGF0ZSA9PSBXZWJTb2NrZXQuT1BFTilcbiAgICAgIHNvY2tldF9yYWRpb19ib3QuY2xvc2UoKTtcbiAgICB9LFxuICAgIGNvbnRyb2xfdGllbXBvKCkge1xuICAgICAgLypcbiAgICAgIGF1ZGlvLm9ubG9hZGVkbWV0YWRhdGEgPSBmdW5jdGlvbihlKSB7XG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy50aWVtcG8nKS5pbm5lclRleHQgPVxuICAgICAgICAgIHNlZ3VuZG9zX2Ffc3RyaW5nKGF1ZGlvLmR1cmF0aW9uKTtcbiAgICAgICAgYXVkaW9fcG9zaXRpb24uc2V0QXR0cmlidXRlKFwibWF4XCIsIGF1ZGlvLmR1cmF0aW9uKVxuICAgICAgfTtcbiAgICAgIGF1ZGlvX21vbWVudG8gPSAwO1xuICAgICAgYXVkaW8uYWRkRXZlbnRMaXN0ZW5lcigndGltZXVwZGF0ZScsICgpID0+IHtcbiAgICAgICAgLy8gYWN0dWFsaXphciBwcm9ncmVzbyBVSVxuICAgICAgICBhdWRpb19wb3NpdGlvbi52YWx1ZSA9IGF1ZGlvLmN1cnJlbnRUaW1lO1xuICAgICAgICBhdWRpb19tb21lbnRvID0gYXVkaW8uY3VycmVudFRpbWUgLyBhdWRpby5kdXJhdGlvbiAqIDEwMCArIFwiJVwiO1xuICAgICAgICBhdWRpb19wcm9ncmVzby5zdHlsZS5zZXRQcm9wZXJ0eShcIi0tcHJvZ3Jlc29cIiwgYXVkaW9fbW9tZW50byk7XG4gICAgICB9KTtcbiAgICAgICovXG4gICAgICBpZiAoYXVkaW8uZHVyYXRpb24pIHtcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnRpZW1wbycpLmlubmVyVGV4dCA9IHNlZ3VuZG9zX2Ffc3RyaW5nKGF1ZGlvLmR1cmF0aW9uKTtcbiAgICAgIGF1ZGlvX3Bvc2l0aW9uLnNldEF0dHJpYnV0ZShcIm1heFwiLCBhdWRpby5kdXJhdGlvbik7XG4gICAgICB9XG4gICAgICBzZXRJbnRlcnZhbCgoKSA9PiB7IFxuICAgICAgICBpZiAoIWF1ZGlvLnBhdXNlZCAmJiBhdWRpby5kdXJhdGlvbikge1xuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5tb21lbnRvJykuaW5uZXJUZXh0ID1cbiAgICAgICAgICAgIHNlZ3VuZG9zX2Ffc3RyaW5nKGF1ZGlvLmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICBhdWRpb19tb21lbnRvID0gYXVkaW8uY3VycmVudFRpbWUgLyBhdWRpby5kdXJhdGlvbiAqIDEwMCArIFwiJVwiO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm1vbWVudG8nKS5pbm5lclRleHQgPSBcIjAwOjAwXCJcbiAgICAgICAgICAvL2F1ZGlvX21vbWVudG8gPSAwXG4gICAgICAgIH1cbiAgICAgICAgYXVkaW9fcG9zaXRpb24udmFsdWUgPSBhdWRpby5jdXJyZW50VGltZTtcbiAgICAgICAgYXVkaW9fcHJvZ3Jlc28uc3R5bGUuc2V0UHJvcGVydHkoXCItLXByb2dyZXNvXCIsIGF1ZGlvX21vbWVudG8pO1xuICAgICAgfSwgMTAwMCk7IFxuICAgIH0sXG4gICAgcG9zaWNpb24odCkge1xuICAgICAgIGF1ZGlvLmN1cnJlbnRUaW1lID0gYXVkaW8uY3VycmVudFRpbWUgKyB0O1xuICAgIH0sXG4gIH0sXG4gIFZpZHN0YWNrSG9vazoge1xuICAgIG1vdW50ZWQoKSB7XG4gICAgICBsZXQgY3VycmVudEVsID0gdGhpcy5lbDtcbiAgICAgIC8vY29uc29sZS5sb2coXCJWaWRzdGFja0hvb2sgbW91bnRlZFwiKTtcbiAgICAgIHZhciBwbGF5ZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdtZWRpYS1wbGF5ZXInKTtcbiAgICAgIC8vY29uc29sZS5sb2cocGxheWVyKTsgICAgICAgICAgICAgIFxuICAgIH0sXG4gICAgYmVmb3JlVXBkYXRlKCkge30sXG4gICAgdXBkYXRlZCgpIHtcbiAgICAgICAgLy9jb25zb2xlLmxvZyhcIlZpZHN0YWNrSG9vayB1cGRhdGVkXCIpO1xuICAgIH0sXG4gICAgZGVzdHJveWVkKCkge30sXG4gICAgZGlzY29ubmVjdGVkKCkge30sXG4gICAgcmVjb25uZWN0ZWQoKSB7fSxcbiAgfSxcbiAgLi4uTGl2ZVNlbGVjdFxufVxubGV0IGxpdmVTb2NrZXQgPSBuZXcgTGl2ZVNvY2tldCgnL2xpdmUnLCBTb2NrZXQsIHtcbiAgaG9va3MsXG4gIGRvbToge1xuICAgIC8vIG1ha2UgTGl2ZVZpZXcgd29yayBuaWNlbHkgd2l0aCBhbHBpbmVqc1xuICAgIG9uQmVmb3JlRWxVcGRhdGVkKGZyb20sIHRvKSB7XG4gICAgICAvL2lmIChmcm9tLl9feCkge1xuICAgICAgaWYgKGZyb20uX3hfZGF0YVN0YWNrKSB7XG4gICAgICAgIC8vd2luZG93LkFscGluZS5jbG9uZShmcm9tLl9feCwgdG8pO1xuICAgICAgICB3aW5kb3cuQWxwaW5lLmNsb25lKGZyb20sIHRvKTtcbiAgICAgIH1cbiAgICB9LFxuICB9LFxuICBwYXJhbXM6IHtfY3NyZl90b2tlbjogY3NyZlRva2VufSxcbn0pO1xuXG5mdW5jdGlvbiBlc3BlcmFySGFzdGFRdWVFeGlzdGFBbHR1cmFMaW1pdGFkb3MoY2FsbGJhY2spIHtcbiAgY29uc3QgY2hlY2sgPSAoKSA9PiB7XG4gICAgY29uc3QgZWxlbXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmxpbWl0YWRvXCIpO1xuXG4gICAgaWYgKCFlbGVtcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybi
1ByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoY2hlY2spO1xuICAgIH1cblxuICAgIC8vIEVzcGVyYXIgYSBxdWUgc2Nyb2xsSGVpZ2h0IHkgY2xpZW50SGVpZ2h0IHNlYW4gPiAwXG4gICAgY29uc3QgbGlzdG8gPSBbLi4uZWxlbXNdLmV2ZXJ5KGVsID0+IGVsLnNjcm9sbEhlaWdodCA+IDAgJiYgZWwuY2xpZW50SGVpZ2h0ID4gMCk7XG5cbiAgICBpZiAobGlzdG8pIHtcbiAgICAgIGNhbGxiYWNrKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShjaGVjayk7XG4gICAgfVxuICB9O1xuICBjaGVjaygpO1xufVxuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInBoeDpwYWdlLWxvYWRpbmctc3RhcnRcIiwgXG4gIGZ1bmN0aW9uKGluZm8peyBcbiAgICBOUHJvZ3Jlc3Muc3RhcnQoKTtcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiYm9keVwiKS5jbGFzc0xpc3QucmVtb3ZlKFwib3ZlcmZsb3dcIik7XG4gICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjbWVudS1idXItY29udGVuZWRvclwiKSl7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI21lbnUtYnVyLWNvbnRlbmVkb3JcIikuY2xhc3NMaXN0LnJlbW92ZShcImFjdGl2b1wiKTtcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjbWVudS1idXItY29udGVuZWRvclwiKS5jbGFzc0xpc3QucmVtb3ZlKFwic2Nyb2xsLW9mZlwiKTtcbiAgICB9XG4gICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjbWVudS1wZXJzb25hbC1jb250ZW5lZG9yXCIpKXtcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjbWVudS1wZXJzb25hbC1jb250ZW5lZG9yXCIpLmNsYXNzTGlzdC5yZW1vdmUoXCJhY3Rpdm9cIik7XG4gICAgfVxuICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI21lbnUtYWRtaW5cIikpe1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNtZW51LWFkbWluXCIpLmNsYXNzTGlzdC5yZW1vdmUoXCJhY3Rpdm9cIik7XG4gICAgfVxuICB9KVxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJwaHg6cGFnZS1sb2FkaW5nLXN0b3BcIiwgXG4gIGZ1bmN0aW9uKGluZm8peyBcbiAgICAvL2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJib2R5XCIpLmNsYXNzTGlzdC5yZW1vdmUoXCJvdmVyZmxvd19tXCIpO1xuICAgIC8vZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImJvZHlcIikuY2xhc3NMaXN0LnJlbW92ZShcInJhZGlvXCIpO1xuICAgIFxuICAgIG1vZHVsb3NfcHVibGkgPSBtb2R1bG9zX3B1YmxpX2luaWNpYWxlcztcbiAgICBjYW1iaW8oKTtcbiAgICBjYW1iaW9fYXBhbmhvcygpO1xuICAgIGFwYW5ob3NfaW1hZ2VuZXNfYXJ0aWN1bG9zKCk7XG4gICAgYXBhbmhvX2Nyb3AoKTtcbiAgICByZXViaWNhcl9wdWJsaXModHJ1ZSk7XG4gICAgTlByb2dyZXNzLmRvbmUoKTtcbiAgICByZXNwb25zaXZlbHlMYXp5LnJ1bigpO1xuICAgIHViaWNhY2lvbl9iYW5kYV9pbmZlcmlvcigpO1xuXG4gICAgc2Nyb2xsSGFuZGxlcigpO1xuICAgIGlmICgkKCcudHdpdHRlci10d2VldCcpLmxlbmd0aCkge1xuICAgICAgLy8kLmdldFNjcmlwdCgnLy9wbGF0Zm9ybS50d2l0dGVyLmNvbS93aWRnZXRzLmpzJyxmdW5jdGlvbigpe30pO1xuICAgIH07XG5cbiAgICBzY3JvbGxfaW50byA9IHRydWU7XG4gICAgLy9zY3JvbGxfaW50b19pZCgpXG4gIH1cbilcblxudmFyIHNjcm9sbF9pbnRvID0gdHJ1ZTtcbmZ1bmN0aW9uIHNjcm9sbF9pbnRvX2lkKHBhcmFyID0gZmFsc2Upe1xuICBpZihwYXJhcil7XG4gICAgaWYodHJ1ZSB8fCBzY3JvbGxfaW50byA9PT0gdHJ1ZSkge1xuICAgICAgdmFyIGlkID0gd2luZG93LmxvY2F0aW9uLmhhc2guc3Vic3RyaW5nKDEpO1xuICAgICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKSl7XG4gICAgICAgIGlmKGlkLmluY2x1ZGVzKFwiY29tZW50YXJpb1wiKSl7XG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYm9keScpLmNsYXNzTGlzdC5hZGQoXCJvdmVyZmxvd1wiKVxuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNjb21lbnRhcmlvcycpLmNsYXNzTGlzdC5hZGQoXCJhY3Rpdm9cIilcbiAgICAgICAgfVxuICAgICAgICBkb2
1N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuc2Nyb2xsSW50b1ZpZXcoeyBiZWhhdmlvcjogJ3Ntb290aCcgfSk7XG4gICAgICB9XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LnJlbW92ZShcIm92ZXJmbG93LWhpZGRlblwiKVxuICAgICAgLy9oaXN0b3J5LnJlcGxhY2VTdGF0ZShudWxsLCBudWxsLCAnICcpO1xuICAgICAgLy9oaXN0b3J5LnJlcGxhY2VTdGF0ZSgnJywgZG9jdW1lbnQudGl0bGUsIHdpbmRvdy5sb2NhdGlvbi5ocmVmLnNwbGl0KCcjJylbMF0pOyBcbiAgICAgIHNjcm9sbF9pbnRvID0gZmFsc2VcbiAgICB9XG4gIH1cbn1cbi8vIGNvbm5lY3QgaWYgdGhlcmUgYXJlIGFueSBMaXZlVmlld3Mgb24gdGhlIHBhZ2VcbmxpdmVTb2NrZXQuY29ubmVjdCgpXG5cbi8vIGV4cG9zZSBsaXZlU29ja2V0IG9uIHdpbmRvdyBmb3Igd2ViIGNvbnNvbGUgZGVidWcgbG9ncyBhbmQgbGF0ZW5jeSBzaW11bGF0aW9uOlxuLy8gPj4gbGl2ZVNvY2tldC5lbmFibGVEZWJ1ZygpXG4vL2xpdmVTb2NrZXQuZW5hYmxlRGVidWcoKVxuLy8gPj4gbGl2ZVNvY2tldC5lbmFibGVMYXRlbmN5U2ltKDEwMDApICAvLyBlbmFibGVkIGZvciBkdXJhdGlvbiBvZiBicm93c2VyIHNlc3Npb25cbi8vID4+IGxpdmVTb2NrZXQuZGlzYWJsZUxhdGVuY3lTaW0oKVxud2luZG93LmxpdmVTb2NrZXQgPSBsaXZlU29ja2V0XG4vL2NvbnNvbGUubG9nKGxpdmVTb2NrZXQpXG5cbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCBmdW5jdGlvbiAoKSB7XG4gIC8vYXBhbmhvc19pbWFnZW5lc19hcnRpY3Vsb3MoKTtcbiAgLy9yZXViaWNhcl9wdWJsaXMoKTsgLy9ldml0YW1vcyBwZWRpciBsYXRlcmFsZXMgYWwgcHJpbmNpcGlvXG4gIGNhbWJpb19hcGFuaG9zKCk7XG4gIC8vc29jaWFsKCk7XG4gIGFwYW5ob3NfbWVudXMoKTtcbiAgLy90cmlnZ2Vyc19tZW51c19tb2IoKTtcbiAgc2Nyb2xsSGFuZGxlcigpO1xuICAvL2xlY3R1cmFzX2N1ZW50ZW8oKTtcbiAgLy9zZXRJbnRlcnZhbChmdW5jdGlvbigpIHtyZXNwb25zaXZlbHlMYXp5LnJ1bigpOyBhcGFuaG9zX2ltYWdlbmVzX2FydGljdWxvcygpfSwgMzAwKTtcbiAgc2V0SW50ZXJ2YWwoZnVuY3Rpb24oKSB7cmVzcG9uc2l2ZWx5TGF6eS5ydW4oKX0sIDMwMCk7XG4gIHNldEludGVydmFsKGZ1bmN0aW9uKCkge3Njcm9sbEhhbmRsZXIoKX0sIDUwMCk7XG5cbiAgdmFyIHN3ID0gdHJ1ZTtcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgZnVuY3Rpb24oKSB7XG4gICAgaWYgKHN3KSB7XG4gICAgICBzdyA9IGZhbHNlO1xuICAgICAgc2V0VGltZW91dChcbiAgICAgICAgZnVuY3Rpb24oKXtcbiAgICAgICAgICBzY3JvbGxIYW5kbGVyKCk7IFxuICAgICAgICAgIHN3ID0gdHJ1ZVxuICAgICAgICB9LCAzMDApO1xuICAgIH1cbiAgfSk7XG4gIGlmICh0eXBlb2YgICQoJy5saW5rcGRmJykuZmFuY3lib3ggPT09IFwiZnVuY3Rpb25cIikgeyBcbiAgICAkKFwiLmxpbmtwZGZcIikuZmFuY3lib3goe1xuICAgICAgdHlwZTogXCJpZnJhbWVcIlxuICAgIH0pOyBcbiAgfSBcbiAgaWYgKCQoJy5hcnRpY3Vsby5zaG93IC50d2l0dGVyLXR3ZWV0JykubGVuZ3RoIHx8ICQoJy5hcnRpY3Vsby5zZWFyY2ggLnR3aXR0ZXItdHdlZXQnKS5sZW5ndGgpe1xuICAgIC8vJC5nZXRTY3JpcHQoJy8vcGxhdGZvcm0udHdpdHRlci5jb20vd2lkZ2V0cy5qcycsZnVuY3Rpb24oKXt9KTtcbiAgfVxufSwgZmFsc2UpO1xuXG5jb25zdCBvblNjcm9sbFN0b3AgPSBjYWxsYmFjayA9PiB7XG4gIGxldCBpc1Njcm9sbGluZztcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgJ3Njcm9sbCcsXG4gICAgZSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQoaXNTY3JvbGxpbmcpO1xuICAgICAgaXNTY3JvbGxpbmcgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgIH0sIDc1MCk7XG4gICAgfSxcbiAgICBmYWxzZVxuICApO1xufTtcblxub25TY3JvbGxTdG9wKCgpID0+IHtcbiAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIuYmFuZGEtcG9ydGFkYVwiKSl7XG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5iYW5kYS1wb3J0YWRhXCIpLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCJcbiAgfSBcbn0pXG5cbmZ1bmN0aW9uIHNjcm9sbEhhbmRsZXIoKXtcbiAgc3ViaXJfb19iYWphcigpO1xuICAvL3NvY2lhbCgpO1xuICBoZWFkZXJfZW5fc3RpY2t5KCk7XG4gIHZlcl9iYXJyYV9wcm9ncmVzbygpO1xuICBhcGFuaG9zX21lbnVzKCk7XG4gIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiYm9keTpub3QoLmZvcm11bGFyaW8pOm5vdCguZWRpdClcIikpe1xuICAgICAgY29tcHJvYmFyX3B1YmxpX3Zpc2libGUoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBhanVzdGVfbWVudV9tb3ZpbCgpe1xuICB2YXIgcG9zaWNpb24gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI01lbnVQb3NpY2lvblwiKTtcbiAgcG9zaWNpb24gPSBcIi5tZW51X3pvbmFfc29jaWFzX21vYmlsIC5tX1wiICsgcG9zaWNpb24uZGF0YXNldC5wb3NpY2lvbjtcbiAgdmFyIG0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHBvc2ljaW9uKTtcbiAgaWYgKG0gJiYgIW0uY2xhc3NMaXN0LmNvbnRhaW5zKFwiYWN0aXZvXCIpKXtcbiAgICBtLmNsYXNzTGlzdC5hZGQoXCJhY3Rpdm9cIik7XG4gICAgbS5zY3JvbGxMZWZ0ID0gMjA7XG4gICAgdmFyIHggPSBtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLng7XG4gICAgaWYgKHg+MSl7XG4gICAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLm1lbnVfem9uYV9zb2NpYXNfbW9iaWwgLm1lbnVfY29udGFpbmVyXCIpLnNjcm9sbExlZnQgPSB4O1xuICAgIH1cbiAgfVxufVxuXG4vLyBQVUJMSVxudmFyIGV4dHJhXzEgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYXJ0aWN1bG8tY29udGVuaWRvIC5jb2wtZXh0cmEgLnB1YmxpY2lkYWRlcycpO1xudmFyIGV4dHJhXzIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucG9ydGFkYS1wb3J0YWRpbGxhIC5jb2wtZXh0cmEnKTtcblxudmFyIGxhdGVyYWxfMSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNsYXRlcmFsLTEtY29udGFpbmVyJyk7XG52YXIgbGF0ZXJhbF8yID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2xhdGVyYWwtMi1jb250YWluZXInKTtcbnZhciBsYXRlcmFsXzMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjbGF0ZXJhbC0zLWNvbnRhaW5lcicpO1xudmFyIGxhdGVyYWxfNCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNsYXRlcmFsLTQtY29udGFpbmVyJyk7XG52YXIgbGF0ZXJhbF81ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2xhdGVyYWwtNS1jb250YWluZXInKTtcblxuZnVuY3Rpb24gYWN0dWFsaXphcl9ibG9xdWVzX2FudW5jaW9zKCl7XG4gIGV4dHJhXzEgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYXJ0aWN1bG8tY29udGVuaWRvIC5jb2wtZXh0cmEgLnB1YmxpY2lkYWRlcycpO1xuICBleHRyYV8yID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBvcnRhZGEtcG9ydGFkaWxsYSAuY29sLWV4dHJhJyk7XG5cbiAgbGF0ZXJhbF8xID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2xhdGVyYWwtMS1jb250YWluZXInKTtcbiAgbGF0ZXJhbF8yID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2xhdGVyYWwtMi1jb250YWluZXInKTtcbiAgbGF0ZXJhbF8zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2xhdGVyYWwtMy1jb250YWluZXInKTtcbiAgbGF0ZXJhbF80ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2xhdGVyYWwtNC1jb250YWluZXInKTtcbiAgbGF0ZXJhbF81ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2xhdGVyYWwtNS1jb250YWluZXInKTtcbiAgbGF0ZXJhbF81ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2xhdGVyYWwtNS1jb250YWluZXInKTtcbn1cblxudmFyIGFudW5jaW9zX3JldWJpY2FyID0gW1xuICBcImxhdGVyYWwtMVwiLFwibGF0ZXJhbC0yXCIsXCJjZW50cmFsLWdyYW5kZVwiLFxuICBcIm9waW5pb24tMVwiLFwib3Bpbmlvbi0yXCIsXCJvcGluaW9uLTNcIixcbiAgXCJsYXRlcmFsLTNcIixcImxhdGVyYWwtNFwiLFwiY2VudHJhbC1ncmFuZGUtMlwiLFxuICBcImJham8tMVwiLFwiYmFqby0yXCIsXCJiYWpvLTNcIixcImxhdGVyYWwtNVwiXG5dO1xuXG5mdW5jdGlvbiByZXViaWNhcl9wdWJsaXNfZXNjcml0b3Jpbygpe1xuICB2YXIgbGF0ZXJhbF8xX3AgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImxhdGVyYWwtMVwiKTtcbiAgdmFyIGxhdGVyYWxfMl9wID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJsYXRlcmFsLTJcIik7XG4gIHZhciBsYXRlcmFsXzNfcCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwibGF0ZXJhbC0zXCIpO1xuICB2YXIgbGF0ZXJhbF80X3AgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImxhdGVyYWwtNFwiKTtcbiAgdmFyIGxhdGVyYWxfNV9wID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJsYXRlcmFsLTVcIik7XG4gIGxhdGVyYWxfMSAhPSBudWxsICYmIGxhdGVyYWxfMV9wICE9IG51bGwgPyBsYXRlcmFsXzEuYXBwZW5kQ2hpbGQobGF0ZXJhbF8xX3ApOiBmYWxzZTtcbiAgbGF0ZXJhbF8yICE9IG51bGwgJiYgbGF0ZXJhbF8yX3AgIT0gbnVsbCA/IGxhdGVyYWxfMi5hcHBlbmRDaGlsZChsYXRlcmFsXzJfcCk6IGZhbHNlO1xuICBsYXRlcmFsXzMgIT0gbnVsbCAmJiBsYXRlcmFsXzNfcCAhPSBudWxsID8gbGF0ZXJhbF8zLmFwcGVuZENoaWxkKGxhdGVyYWxfM19wKTogZmFsc2U7XG4gIGxhdGVyYWxfNCAhPSBudWxsICYmIGxhdGVyYWxfNF9wICE9IG51bGwgPyBsYXRlcmFsXzQuYXBwZW5kQ2hpbGQobGF0ZXJhbF80X3ApOiBmYWxzZTtcbiAgbGF0ZXJhbF81ICE9IG51bGwgJiYgbGF0ZXJhbF81X3AgIT0gbnVsbCA/IGxhdGVyYWxfNS5hcHBlbmRDaGlsZChsYXRlcmFsXzVfcCk6IGZhbHNlO1xuICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJhbnVuY2lvcy1vcGluaW9uXCIpKXtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImFudW5jaW9zLW9waW5pb25cIilcbiAgICAgIC5hcHBlbmRDaGlsZChkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcIm9waW5pb24tMVwiKSk7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJhbnVuY2lvcy1vcGluaW9uXCIpXG4gICAgICAuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJvcGluaW9uLTJcIikpO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYW51bmNpb3Mtb3BpbmlvblwiKVxuICAgICAgLmFwcGVuZENoaWxkKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwib3Bpbmlvbi0zXCIpKTtcbiAgfVxuICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJhbnVuY2lvcy1mb290ZXJcIikpe1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYW51bmNpb3MtZm9vdGVyXCIpXG4gICAgICAuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJiYWpvLTFcIikpO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYW51bmNpb3MtZm9vdGVyXCIpXG4gICAgICAuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJiYWpvLTJcIikpO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYW51bmNpb3MtZm9vdGVyXCIpXG4gICAgICAuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJiYWpvLTNcIikpO1xuICB9XG4gIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImNlbnRyYWwtZ3JhbmRlLWNvbnRhaW5lclwiKSl7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJ
1jZW50cmFsLWdyYW5kZS1jb250YWluZXJcIilcbiAgICAgIC5hcHBlbmRDaGlsZChkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImNlbnRyYWwtZ3JhbmRlXCIpKTtcbiAgfVxuICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJjZW50cmFsLWdyYW5kZS0yLWNvbnRhaW5lclwiKSl7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJjZW50cmFsLWdyYW5kZS0yLWNvbnRhaW5lclwiKVxuICAgICAgLmFwcGVuZENoaWxkKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiY2VudHJhbC1ncmFuZGUtMlwiKSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmV1YmljYXJfcHVibGlzX21vYmlsKCl7XG4gIHZhciBibG9xdWVzID0gZmFsc2VcbiAgdmFyIGNvbnRlbmlkbyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjYXJ0aWN1bG8tY29udGVuaWRvIC5jb2wtY29udGVuaWRvIC5hcnRpY3Vsby10ZXh0by1jb250ZW5pZG9cIik7XG4gIHZhciBjb2JlcnR1cmEgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmNvYmVydHVyYVwiKTtcbiAgLy92YXIgcG9ydGFkYSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJtYWluIC5wb3J0YWRhOm5vdCgucG9ydGFkYS1wb3J0YWRpbGxhKVwiKTtcbiAgdmFyIHBvcnRhZGEgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwibWFpbiAucG9ydGFkYVwiKTtcblxuICBpZiAoY29udGVuaWRvICYmIHBvcnRhZGEpe1xuICAgIGlmIChjb2JlcnR1cmEubGVuZ3RoPjApe1xuICAgICAgYmxvcXVlcyA9IFsuLi5jb250ZW5pZG8ucXVlcnlTZWxlY3RvckFsbChcIi5jb2JlcnR1cmFcIildLmNvbmNhdChbLi4ucG9ydGFkYS5xdWVyeVNlbGVjdG9yQWxsKFwiLnJlc3VtZW5cIildKVxuICAgIH0gZWxzZSB7XG4gICAgICBibG9xdWVzID0gXG4gICAgICAgIFsuLi5jb250ZW5pZG8ucXVlcnlTZWxlY3RvckFsbChcImRpdjpub3QoLnJlc3VtZW4pOm5vdChibG9ja3F1b3RlKSBwXCIpXVxuICAgICAgICAuY29uY2F0KFsuLi5wb3J0YWRhLnF1ZXJ5U2VsZWN0b3JBbGwoXCIucmVzdW1lblwiKV0pXG4gICAgfVxuICB9XG4gIGlmICghYmxvcXVlcyAmJiBwb3J0YWRhKSB7XG4gICAgIC8vYmxvcXVlcyA9IHBvcnRhZGEucXVlcnlTZWxlY3RvckFsbChcIi5ncmlkIC5jb2x1bW5hXCIpO1xuICAgIGlmICghIGJsb3F1ZXMpe1xuICAgICAgYmxvcXVlcyA9IHBvcnRhZGEucXVlcnlTZWxlY3RvckFsbChcIi5yZXN1bWVuXCIpO1xuICAgIH1cbiAgfVxuICBpZiAoYmxvcXVlcykge1xuICAgIC8vY29uc29sZS5sb2coYmxvcXVlcylcbiAgICBhbnVuY2lvc19yZXViaWNhci5mb3JFYWNoKGZ1bmN0aW9uKGVsZW0sIGluZGljZSwgYXJyYXkpIHtcbiAgICAgIGlmIChibG9xdWVzICYmIGJsb3F1ZXNbMSsyKmluZGljZV0gJiYgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxlbSkpe1xuICAgICAgICAvL2NvbnNvbGUubG9nKGluZGljZSlcbiAgICAgICAgLy9jb25zb2xlLmxvZyhibG9xdWVzW2luZGljZV0pXG4gICAgICAgIC8vY29uc29sZS5sb2coZWxlbSlcbiAgICAgICAgYmxvcXVlc1sxKzIqaW5kaWNlXS5pbnNlcnRBZGphY2VudEVsZW1lbnQoXCJhZnRlcmVuZFwiLGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW0pKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vY29uc29sZS5sb2coXCJETkQ/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/PycnJydcIilcbiAgICAgICAgLy9jb25zb2xlLmxvZyhlbGVtKVxufVxuICAgIH0pXG4gIH1cbn1cbi8vIFZhcmlhYmxlcyBkZSBjb29yZGluYWNpw7NuIGVudHJlIHB1YmxpY2lkYWQgeSBjb250ZW5pZG9cbnZhciBwdWJsaV9sb2NrID0gZmFsc2U7ICAgICAgICAgICAvLyBFdml0YSBtYW5pcHVsYWNpw7NuIHNpbXVsdMOhbmVhXG52YXIgcHVibGlfcGVuZGllbnRlcyA9IFtdOyAgICAgICAgLy8gQW51bmNpb3MgcGVuZGllbnRlcyBkZSBwcm9jZXNhclxudmFyIGNvbnRlbmlkb3VwZGF0aW5nID0gZmFsc2U7ICAgIC8vIEluZGljYSBhY3R1YWxpemFjacOzbiBkZSBjb250ZW5pZG8gTGl2ZVZpZXdcblxudmFyIHJldWJpY2FyX2xhc19wdWJsaXMgPSB0cnVlO1xuZnVuY3Rpb24gcmV1YmljYXJfcHVibGlzKGZvcnphciA9IGZhbHNlKXtcbiAgcmV1YmljYXJfbGFzX3B1YmxpcyA9IGZvcnphciA/IHRydWUgOiByZXViaWNhcl9sYXNfcHVibGlzO1xuICBcbiAgLy8gU2kgaGF5IGNvbnRlbmlkbyBhY3R1YWxpesOhbmRvc2UgeSBubyBlcyBmb3J6YWRvLCBwYXVzYXIgZWplY3VjacOzblxuICBpZiAoY29udGVuaWRvdXBkYXRpbmcgJiYgIWZvcnphcikgcmV0dXJuO1xuICBcbiAgaWYgKHJldWJpY2FyX2xhc19wdWJsaXMgPT09IHRydWUpe1xuICAgIC8vIEVzdGFibGVjZXIgbG9jayBwYXJhIGV2aXRhciBjb25mbGljdG8gY29uIExhenlMb2FkQWRcbiAgICBpZiAoIXB1YmxpX2xvY2spIHtcbiAgICAgIHB1YmxpX2xvY2sgPSB0cnVlO1xuICAgIH1cblxuICAgIGFjdHVhbGl6YXJfYmxvcXVlc19hbnVuY2lvcygpXG5cbiAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5hcnRpY3Vsby1jb250ZW5pZG9cIikpe1xuXG4gICAgICB2Y
1XIgYW51bmNpb19ncmFuZGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImNlbnRyYWwtZ3JhbmRlXCIpO1xuXG4gICAgICB2YXIgY29udGVuaWRvID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNhcnRpY3Vsby1jb250ZW5pZG8gLmNvbC1jb250ZW5pZG8gLmFydGljdWxvLXRleHRvLWNvbnRlbmlkb1wiKTtcbiAgICAgIHZhciBjb2JlcnR1cmEgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmNvYmVydHVyYVwiKTtcbiAgICAgIHZhciBibG9xdWVzID0gW11cbiAgICAgIGlmIChjb250ZW5pZG8pe1xuICAgICAgICBpZiAoY29iZXJ0dXJhLmxlbmd0aD4wKXtcbiAgICAgICAgICBibG9xdWVzID0gY29udGVuaWRvLnF1ZXJ5U2VsZWN0b3JBbGwoXCIuY29iZXJ0dXJhXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGJsb3F1ZXMgPSBjb250ZW5pZG8ucXVlcnlTZWxlY3RvckFsbChcImRpdjpub3QoLnJlc3VtZW4pOm5vdChibG9ja3F1b3RlKTpub3QoLnR3aXR0ZXItdHdlZXQpIHBcIik7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGJsb3F1ZSA9IE1hdGguY2VpbChibG9xdWVzLmxlbmd0aC8yKTsgXG4gICAgICAgIGlmIChibG9xdWVzLmxlbmd0aCA+IDEgJiYgYmxvcXVlID4gMyAmJiBhbnVuY2lvX2dyYW5kZSl7XG4gICAgICAgICAgYmxvcXVlc1tibG9xdWVdLmluc2VydEFkamFjZW50RWxlbWVudChcImFmdGVyZW5kXCIsYW51bmNpb19ncmFuZGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCQod2luZG93KS53aWR0aCgpPDc2Nyl7IFxuICAgICAgcmV1YmljYXJfcHVibGlzX21vYmlsKCkgXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldWJpY2FyX3B1Ymxpc19lc2NyaXRvcmlvKClcbiAgICB9XG5cbiAgICBpZiAoJCh3aW5kb3cpLndpZHRoKCk+MTAyNCAmJiAhZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5nYWxlcmlhX3RvZG9fYW5jaG9cIikpeyBcbiAgICAgIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXJ0aWN1bG8tY29udGVuaWRvJykpIHtcbiAgICAgICAgdmFyIGFydGljdWxvX3RleHRvcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNhcnRpY3Vsby10ZXh0b3MgLmNvbnRlbmlkbycpO1xuICAgICAgICBcbiAgICAgICAgdmFyIGFsdHVyYV9hcnRpY3VsbyA9IDA7XG4gICAgICAgIGlmIChhcnRpY3Vsb190ZXh0b3MpIHtcbiAgICAgICAgICBhbHR1cmFfYXJ0aWN1bG8gPSBhcnRpY3Vsb190ZXh0b3Muc2Nyb2xsSGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIHZhciBhbHR1cmFfaW5mbyA9IDA7XG4gICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuaW5mby1ibG9nJykpIHtcbiAgICAgICAgICBhbHR1cmFfaW5mbyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5pbmZvLWJsb2cnKS5zY3JvbGxIZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5pbmZvLXRlbWEnKSkge1xuICAgICAgICAgIGFsdHVyYV9pbmZvID0gYWx0dXJhX2luZm8gKyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuaW5mby10ZW1hJykuc2Nyb2xsSGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIHZhciBhbHR1cmEgPSBhbHR1cmFfYXJ0aWN1bG8gLSBhbHR1cmFfaW5mbztcbiAgICAgICAgLy92YXIgc3R5bGUgPSBcImhlaWdodDogXCIrYWx0dXJhK1wicHg7IG1heC1oZWlnaHQ6IFwiK2FsdHVyYStcInB4OyBtaW4taGVpZ2h0OiBcIithbHR1cmErXCJweFwiXG4gICAgICAgIC8vdmFyIHN0eWxlID0gXCJcIjtcbiAgICAgICAgXG4gICAgICAgIGlmKGV4dHJhXzEpe1xuICAgICAgICAgIC8vZXh0cmFfMS5zZXRBdHRyaWJ1dGUoXCJzdHlsZVwiLCBzdHlsZSk7XG4gICAgICAgICAgZXh0cmFfMS5zZXRBdHRyaWJ1dGUoXCJwaHgtdXBkYXRlXCIsIFwiaWdub3JlXCIpO1xuICAgICAgICAgIGlmKGV4dHJhXzIpe2V4dHJhXzIuc2V0QXR0cmlidXRlKFwicGh4LXVwZGF0ZVwiLCBcImlnbm9yZVwiKX07XG5cbiAgICAgICAgICBpZiAoYWx0dXJhIDw9IDMwMCl7XG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKFwibGF0LTBcIik7XG4gICAgICAgICAgICAvLyAwIGVuIGFydGljdWxvIC8gMCArIDJcbiAgICAgICAgICAgIC8vZXh0cmFfMS5yZW1vdmUoKTtcbiAgICAgICAgICAgIC8vZXh0cmFfMS5pbm5lckhUTUwgPSBcIlwiO1xuICAgICAgICAgICAgLy9pZihsYXRlcmFsXzQpeyBsYXRlcmFsXzQucmVwbGFjZVdpdGgobGF0ZXJhbF8xKX1cbiAgICAgICAgICAgIC8vaWYobGF0ZXJhbF81KXsgbGF0ZXJhbF81LnJlcGxhY2VXaXRoKGxhdGVyYWxfMil9XG4gICAgICAgICAgICBpZihsYXRlcmFsXzQgJiYgbGF0ZXJhbF8xKXsgbGF0ZXJhbF80LmFwcGVuZENoaWxkKGxhdGVyYWxfMS5jaGlsZHJlblswXS5jbG9uZU5vZGUodHJ1ZSkpOyB9XG4gICAgICAgICAgICBpZihsYXRlcmFsXzUgJiYgbGF0ZXJhbF8yKXsgbGF0ZXJhbF81LmFwcGVuZENoaWxkKGxhdGVyYWxfMi5jaGlsZHJlblswXS5jbG9uZU5vZGUodHJ1ZSkpOyB9XG4gICAgICAgICAgICBpZihsYXRlcmFsXzEpe1xuICAgICAgICAgICAgICBsYXRlcmFsXzEuY2xhc3NMaXN0LmFkZChcImhpZGRlblwiKTtcbiAgICAgICAgICAgICAgbGF0ZXJhbF8yLmNsYXNzTGlzdC5hZGQoXCJoaWRkZW5cIik7XG4gICAgICAgICAgICAgIGxhdGVyYWxfMy5jbGFzc0xpc3QuYWRkKFwiaGlkZGVuXCIpO1xuICAgICAgICAgICAgICBsYXRlcmFsXzQuY2xhc3NMaXN0LmFkZChcImg1MFwiKTtcbiAgICAgICAgICAgICAgbGF0ZXJhbF81LmNsYXNzTGlzdC5hZGQoXCJoNTBcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChhbHR1cmEgPiAzMDAgJiYgYWx0dXJhIDwgMTAwMCl7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcImxhdC0xXCIpO1xuICAgICAgICAgICAgLy8gMSBlbiBhcnRpY3VsbyAvIDEgKyAyXG4gICAgICAgICAgICAvL2V4dHJhXzIucmVwbGFjZUNoaWxkKGxhdGVyYWxfMixsYXRlcmFsXzQpXG4gICAgICAgICAgICAvL2V4dHJhXzIucmVwbGFjZUNoaWxkKGxhdGVyYWxfMyxsYXRlcmFsXzUpXG4gICAgICAgICAgICBpZihsYXRlcmFsXzQgJiYgbGF0ZXJhbF8yKXsgbGF0ZXJhbF80LmFwcGVuZENoaWxkKGxhdGVyYWxfMi5jaGlsZHJlblswXS5jbG9uZU5vZGUodHJ1ZSkpOyB9XG4gICAgICAgICAgICBpZihsYXRlcmFsXzUgJiYgbGF0ZXJhbF8zKXsgbGF0ZXJhbF81LmFwcGVuZENoaWxkKGxhdGVyYWxfMy5jaGlsZHJlblswXS5jbG9uZU5vZGUodHJ1ZSkpOyB9XG4gICAgICAgICAgICBpZihsYXRlcmFsXzEpe1xuICAgICAgICAgICAgICBsYXRlcmFsXzEuY2xhc3NMaXN0LmFkZChcImgxMDBcIik7XG4gICAgICAgICAgICAgIGxhdGVyYWxfMi5jbGFzc0xpc3QuYWRkKFwiaGlkZGVuXCIpO1xuICAgICAgICAgICAgICBsYXRlcmFsXzMuY2xhc3NMaXN0LmFkZChcImhpZGRlblwiKTtcbiAgICAgICAgICAgICAgaWYobGF0ZXJhbF80KXtsYXRlcmFsXzQuY2xhc3NMaXN0LmFkZChcImg1MFwiKX07XG4gICAgICAgICAgICAgIGlmKGxhdGVyYWxfNSl7bGF0ZXJhbF81LmNsYXNzTGlzdC5hZGQoXCJoNTBcIil9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgI
1H0gZWxzZSBpZiAoYWx0dXJhID49IDEwMDAgJiYgYWx0dXJhIDwgMjUwMCl7XG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKFwibGF0LTJcIik7XG4gICAgICAgICAgICAvLyAyIGVuIGFydGljdWxvIC8gMiArIDJcbiAgICAgICAgICAgIC8vaWYobGF0ZXJhbF80ICYmIGxhdGVyYWxfMyl7IGxhdGVyYWxfNC5yZXBsYWNlV2l0aChsYXRlcmFsXzMpfVxuICAgICAgICAgICAgaWYobGF0ZXJhbF81ICYmIGxhdGVyYWxfNCl7IGxhdGVyYWxfNS5hcHBlbmRDaGlsZChsYXRlcmFsXzQuY2hpbGRyZW5bMF0uY2xvbmVOb2RlKHRydWUpKTsgfVxuICAgICAgICAgICAgaWYobGF0ZXJhbF80ICYmIGxhdGVyYWxfMyl7IGxhdGVyYWxfNC5hcHBlbmRDaGlsZChsYXRlcmFsXzMuY2hpbGRyZW5bMF0uY2xvbmVOb2RlKHRydWUpKTsgfVxuICAgICAgICAgICAgLy9pZihsYXRlcmFsXzUpe2xhdGVyYWxfNS5yZW1vdmUoKX1cbiAgICAgICAgICAgIGxhdGVyYWxfMS5jbGFzc0xpc3QuYWRkKFwiaDUwXCIpO1xuICAgICAgICAgICAgbGF0ZXJhbF8yLmNsYXNzTGlzdC5hZGQoXCJoNTBcIik7XG4gICAgICAgICAgICBpZihsYXRlcmFsXzMpe2xhdGVyYWxfMy5jbGFzc0xpc3QuYWRkKFwiaGlkZGVuXCIpfTtcbiAgICAgICAgICAgIGlmKGxhdGVyYWxfNCAmJiBsYXRlcmFsXzUpe2xhdGVyYWxfNC5jbGFzc0xpc3QuYWRkKFwiaDUwXCIpfTtcbiAgICAgICAgICAgIGlmKGxhdGVyYWxfNSl7bGF0ZXJhbF81LmNsYXNzTGlzdC5hZGQoXCJoNTBcIil9O1xuICAgICAgICAgIH0gZWxzZSBpZiAoYWx0dXJhID49IDI1MDApe1xuICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcImxhdC0zXCIpO1xuICAgICAgICAgICAgLy8gMyBlbiBhcnRpY3VsbyB0b2RvIC8gMyArIDJcbiAgICAgICAgICAgIGxhdGVyYWxfMS5jbGFzc0xpc3QuYWRkKFwiaDMzXCIpO1xuICAgICAgICAgICAgbGF0ZXJhbF8yLmNsYXNzTGlzdC5hZGQoXCJoMzNcIik7XG4gICAgICAgICAgICBsYXRlcmFsXzMuY2xhc3NMaXN0LmFkZChcImgzM1wiKTtcbiAgICAgICAgICAgIGlmKGxhdGVyYWxfNCl7bGF0ZXJhbF80LmNsYXNzTGlzdC5hZGQoXCJoNTBcIil9O1xuICAgICAgICAgICAgaWYobGF0ZXJhbF81KXtsYXRlcmFsXzUuY2xhc3NMaXN0LmFkZChcImg1MFwiKX07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXJ0aWN1bG8tY29udGVuaWRvJykpIHtcbiAgICAgICAgLy92YXIgc3R5bGUgPSBcIlwiXG4gICAgICAgIGlmKGV4dHJhXzEpe1xuICAgICAgICAgIC8vZXh0cmFfMS5zZXRBdHRyaWJ1dGUoXCJzdHlsZVwiLCBzdHlsZSk7XG4gICAgICAgICAgLy9leHRyYV8xLnNldEF0dHJpYnV0ZShcInBoeC11cGRhdGVcIiwgXCJpZ25vcmVcIik7XG4gICAgICAgICAgLy9leHRyYV8yLnNldEF0dHJpYnV0ZShcInBoeC11cGRhdGVcIiwgXCJpZ25vcmVcIik7XG4gICAgICAgICAgaWYobGF0ZXJhbF8xKXtcbiAgICAgICAgICAgIGxhdGVyYWxfMS5jbGFzc0xpc3QucmVtb3ZlKFwiaDMzXCIpO1xuICAgICAgICAgICAgbGF0ZXJhbF8xLmNsYXNzTGlzdC5yZW1vdmUoXCJoNTBcIik7XG4gICAgICAgICAgICBsYXRlcmFsXzEuY2xhc3NMaXN0LnJlbW92ZShcImgxMDBcIik7XG4gICAgICAgICAgICBsYXRlcmFsXzUuY2xhc3NMaXN0LnJlbW92ZShcImhpZGRlblwiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYobGF0ZXJhbF8yKXtcbiAgICAgICAgICAgIGxhdGVyYWxfMi5jbGFzc0xpc3QucmVtb3ZlKFwiaDMzXCIpO1xuICAgICAgICAgICAgbGF0ZXJhbF8yLmNsYXNzTGlzdC5yZW1vdmUoXCJoNTBcIik7XG4gICAgICAgICAgICBsYXRlcmFsXzUuY2xhc3NMaXN0LnJlbW92ZShcImhpZGRlblwiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYobGF0ZXJhbF8zKXtcbiAgICAgICAgICAgIGxhdGVyYWxfMy5jbGFzc0xpc3QucmVtb3ZlKFwiaDMzXCIpO1xuICAgICAgICAgICAgbGF0ZXJhbF8zLmNsYXNzTGlzdC5yZW1vdmUoXCJoNTBcIik7XG4gICAgICAgICAgICBsYXRlcmFsXzUuY2xhc3NMaXN0LnJlbW92ZShcImhpZGRlblwiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYobGF0ZXJhbF80KXtcbiAgICAgICAgICAgIGxhdGVyYWxfNC5jbGFzc0xpc3QucmVtb3ZlKFwiaDUwXCIpO1xuICAgICAgICAgICAgbGF0ZXJhbF81LmNsYXNzTGlzdC5yZW1vdmUoXCJoaWRkZW5cIik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmKGxhdGVyYWxfNSl7XG4gICAgICAgICAgICBsYXRlcmFsXzUuY2xhc3NMaXN0LnJlbW92ZShcImg1MFwiKTtcbiAgICAgICAgICAgIGxhdGVyYWxfNS5jbGFzc0xpc3QucmVtb3ZlKFwiaGlkZGVuXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvL2NvbnNvbGUubG9nKFwiUmV1YmljYWRhcyBwdWJsaXNcIilcbiAgICByZXViaWNhcl9sYXNfcHVibGlzID0gZmFsc2VcbiAgXG4gICAgLy8gTGliZXJhciBsb2NrIHkgcHJvY2VzYXIgYW51bmNpb3MgcGVuZGllbnRlc1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgcHVibGlfbG9jayA9IGZhbHNlO1xuICAgICAgcHJvY2VzYXJfcHVibGlfcGVuZGllbnRlcygpO1xuICAgIH0sIDEwMCk7XG4gIH1cbn1cbmZ1bmN0aW9uIGFwYW5ob3NfcHVibGlfYmxvcXVlX3RlbWEoKXtcbiAgaWYgKCQod2luZG93KS53aWR0aCgpPjc2NyAmJiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLmluZm8tdGVtYVwiKSl7XG4gICAgbGV0IGggPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLmluZm8tdGVtYVwiKS5vZmZzZXRIZWlnaHRcbiAgICBsZXQgaDIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLnJlbGFjaW9uYWRhc1wiKS5vZmZzZXRIZWlnaHRcblxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIuaDEwMFwiKS5mb3JFYWNoKGVsID0+IHtcbiAgICAgIGVsLnN0eWxlLmhlaWdodD0gYGNhbGMoMTAwJSAtICR7aH1weCArICR7aDJ9cHgpYDtcbiAgICAgIGVsLnN0eWxlLm1pbkhlaWdodD0gYGNhbGMoMTAwJSAtICR7aH1weCArICR7aDJ9cHgpYDtcbiAgICAgIGVsLnN0eWxlLm1heEhlaWdodD0gYGNhbGMoMTAwJSAtICR7aH1weCArICR7aDJ9cHgpYDtcbiAgICB9KTtcbiAgfVxufVxuXG4vLyBGdW5jacOzbiBwYXJhIHByb2Nlc2FyIGFudW5jaW9zIHBlbmRpZW50ZXMgZGVzcHXDqXMgZGUgbGliZXJhciBsb2Nrc1xuZnVuY3Rpb24gcHJvY2VzYXJfcHVibGlfcGVuZGllbnRlcygpIHtcbiAgaWYgKHB1YmxpX3BlbmRpZW50ZXMubGVuZ3RoID09PSAwKSByZXR1cm47XG4gIFxuICAvL2NvbnNvbGUubG9nKFwiUHJvY2VzYW5kbyBwdWJsaWNpZGFkIHBlbmRpZW50ZTpcIiwgcHVibGlfcGVuZGllbnRlcyk7XG4gIFxuICB3aGlsZSAocHVibGlfcGVuZGllbnRlcy5sZW5ndGggPiAwKSB7XG4gICAgY29uc3QgbW9k
1dWxvID0gcHVibGlfcGVuZGllbnRlcy5zaGlmdCgpO1xuICAgIGNvbnN0IGVsZW1lbnRvID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihgW2RhdGEtbmFtZT1cIiR7bW9kdWxvfVwiXWApO1xuICAgIFxuICAgIGlmIChlbGVtZW50byAmJiAhZWxlbWVudG8uY2xhc3NMaXN0LmNvbnRhaW5zKCdhbnVuY2lvLWFjdGl2bycpKSB7XG4gICAgICAvLyBTaW11bGFyIGV2ZW50byBkZSBpbnRlcnNlY2Npw7NuIHBhcmEgcHJvY2VzYXIgZWwgYW51bmNpb1xuICAgICAgY29uc3QgZXZlbnQgPSBuZXcgRXZlbnQoJ2ludGVyc2VjdCcpO1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGV2ZW50LCAnaXNJbnRlcnNlY3RpbmcnLCB7IGdldDogKCkgPT4gdHJ1ZSB9KTtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShldmVudCwgJ2ludGVyc2VjdGlvblJhdGlvJywgeyBnZXQ6ICgpID0+IDEgfSk7XG4gICAgICBcbiAgICAgIC8vIERpc3BhcmFyIG1hbnVhbG1lbnRlIGVsIHByb2Nlc2FtaWVudG9cbiAgICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChbZW50cnldKSA9PiB7XG4gICAgICAgIGlmIChlbnRyeS5pc0ludGVyc2VjdGluZykge1xuICAgICAgICAgIGVsZW1lbnRvLmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KCdhZC12aXNpYmxlLXRyaWdnZXInLCB7XG4gICAgICAgICAgICBkZXRhaWw6IHsgbW9kdWxvOiBtb2R1bG8gfVxuICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBvYnNlcnZlci5vYnNlcnZlKGVsZW1lbnRvKTtcbiAgICAgIG9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIG1vZHVsb3NfcHVibGlfaW5pY2lhbGVzID0gW1wicG9wdXBcIiwgXCJmYWxkb25cIl1cblxudmFyIG1vZHVsb3NfcHVibGkgPSBtb2R1bG9zX3B1YmxpX2luaWNpYWxlcyBcblxuZnVuY3Rpb24gY29tcHJvYmFyX3B1YmxpX3Zpc2libGUoKXtcbiAgdmFyIHB1YmxpcyA9IFtdO1xuICB2YXIgbW9kdWxvcyA9IG1vZHVsb3NfcHVibGkuc2xpY2UoMCk7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtb2R1bG9zX3B1YmxpLmxlbmd0aDsgIGkrKyl7XG4gICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKG1vZHVsb3NfcHVibGlbaV0pIFxuICAgICAgJiYgdmlzaWJsZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZChtb2R1bG9zX3B1YmxpW2ldKSkpIHtcbiAgICAgIC8vY29uc29sZS5sb2coXCJWSVNJQkxFOiBcIisgbW9kdWxvc19wdWJsaVtpXSk7XG4gICAgICBwdWJsaXMucHVzaChtb2R1bG9zX3B1YmxpW2ldKTtcbiAgICAgIG1vZHVsb3MgPSBtb2R1bG9zLmZpbHRlcihpdGVtID0+IGl0ZW0gIT09IG1vZHVsb3NfcHVibGlbaV0pO1xuICAgIH1cbiAgfVxuICBpZiAocHVibGlzLmxlbmd0aD4wICl7XG4gICAgcGVkaXJfYW51bmNpb3MocHVibGlzKTsgXG4gICAgbW9kdWxvc19wdWJsaSA9IG1vZHVsb3M7XG4gIH1cbn1cblxuZnVuY3Rpb24gc29jaWFsKCl7XG4gIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29tcGFydGlyUHJpbmNpcGFsJykpIHtcbiAgICBpZiAodmlzaWJsZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29tcGFydGlyUHJpbmNpcGFsJykpIFxuICAgICAgfHwgdmlzaWJsZSgoZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5iYW5uZXItYmxvZ3NcIikpKSkge1xuICAgICAgb2N1bHRhcignLmZpam8gLmNvbXBhcnRpcicpO1xuICAgIH0gZWxzZSB7XG4gICAgICBtb3N0cmFyKCcuZmlqbyAuY29tcGFydGlyJyk7XG4gICAgfVxuICAgIGlmICghdmlzaWJsZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXJ0aWN1bG8tY29udGVuaWRvJykpKSB7XG4gICAgICBvY3VsdGFyKCcuZmlqbyAuY29tcGFydGlyJyk7XG4gICAgfSBcbiAgfSBcbn1cblxuZnVuY3Rpb24gdmVyX2JhcnJhX3Byb2dyZXNvKCl7XG4gIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXJ0aWN1bG8tY29udGVuaWRvJykpIHtcbiAgICBpZiAodmlzaWJsZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhZGVyJykpKSB7XG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmhlYWRlcicpLmNsYXNzTGlzdC5yZW1vdmUoJ2hlYWRlci1vdXQnKVxuICAgIH0gZWxzZSB7XG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmhlYWRlcicpLmNsYXNzTGlzdC5hZGQoJ2hlYWRlci1vdXQnKVxuICAgIH1cbiAgfSBcbn1cblxudmFyIHJlbSA9IGZ1bmN0aW9uIChjb3VudCkge1xuICB2YXIgdW5pdCA9ICQoJ2h0bWwnKS5jc3MoJ2ZvbnQtc2l6ZScpO1xuICBpZiAodHlwZW9mIGNvdW50ICE9PSAndW5kZWZpbmVkJyAmJiBjb3VudCA+IDApIHtcbiAgICByZXR1cm4gKHBhcnNlSW50KHVuaXQpICogY291bnQpO1xuICB9XG4gIGVsc2Uge1xuICAgIHJldHVybiBwYXJzZUludCh1bml0KTtcbiAgfVxufVxuXG52YXIgc2Nyb2xsUG9zID0gMDtcbnZhciBwYXJhciA9IDA7XG5mdW5jdGlvbiBzdWJpcl9vX2JhamFyKCkge1xuICB2YXIgYWN0dWFsID0gd2luZG93LnBhZ2VZT2Zmc2V0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxUb3AgfHwgMDtcbiAgdmFyIHN0aWNreV9hY3Rpdm8gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLnN0aWNreS1oZWFkZXJcIikgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLnN0aWNreS1oZWFkZXJcIikub2Zmc2V0SGVpZ2h0IDogMFxuICB2YXIgaCA9IHN0aWNreV9hY3Rpdm8gKyByZW0oMS4yNSkgXG4gIC8vY29uc29sZS5sb2coYWN0dWFsICtcIiBcIisgc2Nyb2xsUG9zICsgXCIgXCIgKyAoYWN0dWFsIC0gc2Nyb2xsUG9zKSlcbiAgdmFyIGRpZiA9IGFjdHVhbCAtIHNjcm9sbFBvc1xuICAvL2NvbnNvbGUubG9nKGRpZilcbiAgaWYgKGRpZiA8IC00MCkge1xuICAvL2lmIChkaWYgPCAtNDAgJiYgc3RpY2t5X2FjdGl2bykge1xuICAgIC8vY29uc29sZS5sb2coXCJVUFwiKVxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5jbGFzc0xpc3QuYWRkKCd1cCcpXG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYm9keScpLmNsYXNzTGlzdC5yZW1vdmUoJ2Rvd24nKVxuICAgIHBhcmFyID0gMDtcbiAgfSBlbHNlIGlmIChkaWYgPiA0MCApe1xuICAvL30gZWxzZSBpZiAoZGlmID4gNDAgfHwgc3RpY2t5X2FjdGl2byA9PSAwKXtcbiAgICAvL2NvbnNvbGUubG9nKFwiRE9XTlwiKVxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5jbGFzc0xpc3QuYWRkKCdkb3duJylcbiAgICBkb2
1N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LnJlbW92ZSgndXAnKVxuICAgIHBhcmFyID0gMDtcbiAgfSBlbHNlIHtcbiAgICBpZiAocGFyYXIgPT0gMikge1xuICAgICAgLy9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LmFkZCgndXAnKVxuICAgICAgLy9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuY2xhc3NMaXN0LnJlbW92ZSgnZG93bicpXG4gICAgfVxuICAgIHBhcmFyID0gcGFyYXIgKyAxO1xuICAgIC8vY29uc29sZS5sb2coXCJQQVJBXCIpXG4gIH1cblxuICB2YXIgdyA9IHdpbmRvdy5pbm5lcldpZHRoXG4gICAgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoXG4gICAgfHwgZG9jdW1lbnQuYm9keS5jbGllbnRXaWR0aDtcblxuICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi51cC1kb3duXCIpICYmIGRpZiA8IC00MCAmJiBzdGlja3lfYWN0aXZvKSB7XG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi51cC1kb3duXCIpLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCJcbiAgfSBlbHNlIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLnVwLWRvd25cIikgJiYgKGRpZiA+IDQwIHx8IHN0aWNreV9hY3Rpdm8gPT0gMCkpe1xuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIudXAtZG93blwiKS5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCJcbiAgfVxuXG4gIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLmJhbmRhLXBvcnRhZGFcIikpe1xuICAgIGlmIChzdGlja3lfYWN0aXZvID09IDApe1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5iYW5kYS1wb3J0YWRhXCIpLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCJcbiAgICB9IFxuICAgIGlmIChkaWYgPiA1MCApe1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5iYW5kYS1wb3J0YWRhXCIpLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIlxuICAgIH0gZWxzZSBpZiAoZGlmIDwgLTQwICYmIHN0aWNreV9hY3Rpdm8pIHtcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIuYmFuZGEtcG9ydGFkYVwiKS5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiXG4gICAgfVxuICB9XG5cbiAgaWYoZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNtZW51LWFycmliYSAuY2FiZWNlcmFkb2JsZVwiKSkge1xuICAgIHZhciBjYWJlY2VyYV8xID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5jYWJlY2VyYV9wb3J0YWRhIC5jYWJlY2VyYWRvYmxlXCIpXG4gICAgdmFyIGNhYmVjZXJhXzIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI21lbnUtYXJyaWJhIC5jYWJlY2VyYWRvYmxlXCIpXG4gICAgdmFyIGVzY29uZGlkYSAgPSBjYWJlY2VyYV8xLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmJvdHRvbSA8IC0xMDBcbiAgICBpZiAoY2FiZWNlcmFfMSAmJiBlc2NvbmRpZGEpIHtcbiAgICAgIGNhYmVjZXJhXzIuY2xhc3NMaXN0LmFkZChcInZpc2libGUtbG9nb1wiKVxuICAgIH0gZWxzZSAge1xuICAgICAgY2FiZWNlcmFfMi5jbGFzc0xpc3QucmVtb3ZlKFwidmlzaWJsZS1sb2dvXCIpXG4gICAgfVxuICB9XG5cbiAgaWYgKHcgPCA3NjkpIHtcbiAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi51cC1kb3duLWFydGljdWxvXCIpKXtcbiAgICAgIGlmICh2aXNpYmxlKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhcnRpY3Vsby10ZXh0b3MnKSkgXG4gICAgICAgICYmICF2aXNpYmxlKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjY29tcGFydGlyUHJpbmNpcGFsIC5jb21wYXJ0aXJcIikpKSB7XG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIuaGVhZGVyXCIpLmNsYXNzTGlzdC5hZGQoXCJ1cC1kb3duLWFjdGl2b1wiKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5oZWFkZXJcIikuY2xhc3NMaXN0LnJlbW92ZShcInVwLWRvd24tYWN0aXZvXCIpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIucHVibGktbGF0ZXJhbFwiKSkge1xuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIucHVibGktbGF0ZXJhbFwiKS5mb3JFYWNoKChsYXRlcmFsKSA9PiB7XG4gICAgICBsYXRlcmFsLnN0eWxlLnRvcCA9IGggKyBcInB4XCJcbiAgICB9KVxuICB9XG4gIHNjcm9sbFBvcyA9IGFjdHVhbCA8PSAwID8gMCA6IGFjdHVhbDtcbn07XG5cbmZ1bmN0aW9uICB1YmljYWNpb25fYmFuZGFfaW5mZXJpb3IoKSB7XG4gIHZhciB3aWR0aCA9ICQod2luZG93KS53aWR0aCgpO1xuICBjb25zdCBwb3J0YWRhX2JpID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBvcnRhZGFfYmknKTtcbiAgaWYgKHBvcnRhZGFfYmkgJiYgd2lkdGg8NzY4KXsgXG4gICAgdmFyIGxvYyA9IGxvY2F0aW9uLnBhdGhuYW1lLnNwbGl0KCcvJyk7XG4gICAgbG9jID0gbG9jLmpvaW4oXCIvXCIpO1xuICAgIGNvbnN0IGJvbGV0aW5lc19iaSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5ib2xldGluZXNfYmknKTtcbiAgICBjb25zdCBtaXNhbHRvX2JpID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm1pc2FsdG9fYmknKTtcbiAgICBjb25zdCBndWFyZGFkb3NfYmkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuZ3VhcmRhZG9zX2JpJyk7XG4gICAgc3dpdGNoKGxvYykge1xuICAgICAgY2FzZSBcIi9cIjpcbiAgICAgICAgcG9ydGFkYV9iaS5jbGFzc0xpc3QuYWRkKCdhY3RpdmEnKTtcbiAgICAgICAgYm9sZXRpbmVzX2JpICYmIGJvbGV0aW5lc19iaS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmEnKTtcbiAgICAgICAgbWlzYWx0b19iaSAmJiBtaXNhbHRvX2JpLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2YScpO1xuICAgICAgICBndWFyZGFkb3NfYmkgJiYgZ3VhcmRhZG9zX2JpLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2YScpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCIvem9uYS1zb2NpYXMvYm9sZXRpbmVzXCI6XG4gICAgICAgIHBvcnRhZGFfYmkuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZhJyk7XG4gICAgICAgIGJvbGV0aW5lc19iaSAmJiBib2xldGluZXNfYmkuY2xhc3NMaXN0LmFkZCgnYWN0aXZhJyk7XG4gICAgICAgIG1pc2FsdG9fYmkgJiYgbWlzYWx0b19iaS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmEnKTtcbiAgICAgICAgZ3VhcmRhZG9zX2JpICYmIGd1YXJkYWRvc19iaS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmEnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiL21pLXNhbHRvXCI6XG4gICAgICAgI
1HBvcnRhZGFfYmkuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZhJyk7XG4gICAgICAgIGJvbGV0aW5lc19iaSAmJiBib2xldGluZXNfYmkuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZhJyk7XG4gICAgICAgIG1pc2FsdG9fYmkgJiYgbWlzYWx0b19iaS5jbGFzc0xpc3QuYWRkKCdhY3RpdmEnKTtcbiAgICAgICAgZ3VhcmRhZG9zX2JpICYmIGd1YXJkYWRvc19iaS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmEnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiL3pvbmEtc29jaWFzL2FydGljdWxvcy1ndWFyZGFkb3NcIjpcbiAgICAgICAgcG9ydGFkYV9iaS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmEnKTtcbiAgICAgICAgYm9sZXRpbmVzX2JpICYmIGJvbGV0aW5lc19iaS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmEnKTtcbiAgICAgICAgbWlzYWx0b19iaSAmJiBtaXNhbHRvX2JpLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2YScpO1xuICAgICAgICBndWFyZGFkb3NfYmkgJiYgZ3VhcmRhZG9zX2JpLmNsYXNzTGlzdC5hZGQoJ2FjdGl2YScpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHBvcnRhZGFfYmkuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZhJyk7XG4gICAgICAgIGJvbGV0aW5lc19iaSAmJiBib2xldGluZXNfYmkuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZhJyk7XG4gICAgICAgIG1pc2FsdG9fYmkgJiYgbWlzYWx0b19iaS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmEnKTtcbiAgICAgICAgZ3VhcmRhZG9zX2JpICYmIGd1YXJkYWRvc19iaS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmEnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59O1xuZnVuY3Rpb24gcGVkaXJfYW51bmNpb3MobW9kdWxvcykge1xuICAvL2NvbnNvbGUubG9nKFwicGVkaXIgYW51bmNpb3NcIilcbiAgdmFyIHdpZHRoID0gJCh3aW5kb3cpLndpZHRoKCk7XG4gIGlmICh3aWR0aD43NjcpeyB2YXIgbW9iaWwgPSBmYWxzZTsgfSBlbHNlIHsgdmFyIG1vYmlsID0gdHJ1ZTsgfVxuICB2YXIgbG9jID0gbG9jYXRpb24ucGF0aG5hbWUuc3BsaXQoJy8nKS5zbGljZSgxKTtcbiAgY29uc3QgdWJpY2FjaW9uZXNfc2luX3B1YmxpID0gXG4gICAgW1xuICAgICAgXCJpbmZvXCIgLCBcbiAgICAgIFwibWktc2FsdG9cIiAsIFxuICAgICAgXCJ6b25hLXNvY2lhc1wiLCBcbiAgICAgIFwic3VzY3JpYmlyc2VcIiwgXG4gICAgICBcImZvcm11bGFyaW9cIiwgXG4gICAgICBcImN1ZW50YVwiLCBcbiAgICAgIFwiYXJlYS1wZXJzb25hbFwiLCBcbiAgICAgIFwiYWRtaW5cIlxuICAgIF1cbiAgaWYodWJpY2FjaW9uZXNfc2luX3B1YmxpLmluY2x1ZGVzKGxvY1swXSkgJiYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjY3NzX3pvbmFfc29jaWFzXCIpID09IG51bGwpKXtcbiAgICB2YXIgc3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xuICAgIHN0eWxlLnNldEF0dHJpYnV0ZShcImlkXCIsIFwiY3NzX3pvbmFfc29jaWFzXCIpO1xuICAgIHN0eWxlLnRleHRDb250ZW50ID0gYFxuICAgICAgI3B1YmxpLWNhYmVjZXJhLFxuICAgICAgLmFudW5jaW8ge1xuICAgICAgICBkaXNwbGF5OiBub25lICFpbXBvcnRhbnQ7XG4gICAgICB9XG4gICAgYDtcbiAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHN0eWxlKTtcbiAgICByZXR1cm4gdHJ1ZVxuICB9IGVsc2Uge1xuICAgIGlmICghdWJpY2FjaW9uZXNfc2luX3B1YmxpLmluY2x1ZGVzKGxvY1swXSkgJiYgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNjc3Nfem9uYV9zb2NpYXNcIikpIHtcbiAgICAgIHZhciBjc3MgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI2Nzc196b25hX3NvY2lhc1wiKTtcbiAgICAgIGNzcy5yZW1vdmUoKVxuICAgIH1cbiAgfVxuICB2YXIgc2x1ZyA9IFwiXCI7XG4gIGlmKGxvY1swXSkgeyBzbHVnID0gbG9jWzBdICsgJy8nfSBcbiAgaWYobG9jWzFdKSB7IHNsdWcgPSBzbHVnICsgbG9jWzFdICsgJy8nIH0gZWxzZSB7c2x1Z307XG4gIGlmKGxvY1swXSA9PSBcInNpbi1wdWJsaWNhclwiKSB7IHNsdWcgPSBsb2NbMV0gKyAnLycgKyBsb2NbMl19IFxuICB2YXIgbm9kbyA9ICQoJ2JvZHknKS5hdHRyKCdpZCcpO1xuICBpZighdWJpY2FjaW9uZXNfc2luX3B1YmxpLmluY2x1ZGVzKGxvY1swXSkpe1xuICAgICQoJ2JvZHknKS5hZGRDbGFzcygnd2FpdCcpO1xuICAgICQuYWpheCh7XG4gICAgICB1cmw6ICcvYXBpLycrIHNsdWcgKydhbnVuY2lvLycgKyBtb2R1bG9zICsgJy8nICsgbm9kbyArICcvJyArIG1vYmlsLFxuICAgICAgdHlwZSA6ICdHRVQnLFxuICAgICAgZGF0YVR5cGU6J2pzb24nLFxuICAgICAgc3VjY2VzcyA6IGZ1bmN0aW9uKGRhdGEpIHsgICAgICAgICAgICAgIFxuICAgICAgICAkKCdib2R5JykucmVtb3ZlQ2xhc3MoJ3dhaXQnKTtcbiAgICAgICAgbW9kdWxvcyA9IGRhdGEuZGF0YTtcbiAgICAgICAgJC5lYWNoKG1vZHVsb3MsZnVuY3Rpb24ocm93KXtcbiAgICAgICAgICB2Y
1XIgbW9kdWxvX3B1YmxpID0gbW9kdWxvc1tyb3ddLm1vZHVsbztcbiAgICAgICAgICB2YXIgbW9kdWxvID0gJChcIiNcIittb2R1bG9fcHVibGkpO1xuICAgICAgICAgIGlmIChtb2R1bG9zW3Jvd10ubWFxdWV0YWNpb24gJiYgbW9kdWxvc1tyb3ddLm1hcXVldGFjaW9uLm5vX3B1YmxpY2lkYWQgPT0gXCJub19wdWJsaWNpZGFkXCIpe1xuICAgICAgICAgICAgbW9kdWxvLmFkZENsYXNzKCdibG9xdWUtYWN0aXZvJyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG1vZHVsby5hZGRDbGFzcygnYW51bmNpby1hY3Rpdm8nKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbW9kdWxvLmVtcHR5KCk7XG4gICAgICAgICAgbW9kdWxvLmF0dHIoJ3BoeC11cGRhdGUnLFwiaWdub3JlXCIpXG4gICAgICAgICAgaWYgKG1vZHVsb3Nbcm93XS5zY3JpcHQgJiYgbW9kdWxvc1tyb3ddLnNjcmlwdC5sZW5ndGg+MTApe1xuICAgICAgICAgICAgLy8kKG1vZHVsb3Nbcm93XS5zY3JpcHQpLmFwcGVuZFRvKG1vZHVsbyk7XG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgJChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgIC8vICAgICAgICBjb25zb2xlLmxvZyhtb2R1bG9zW3Jvd10uc2NyaXB0KTtcbiAgICAgICAgICAgICAgcG9zdHNjcmliZShtb2R1bG8sbW9kdWxvc1tyb3ddLnNjcmlwdCk7XG4gICAgICAgICAgICAgIHRyeSB7IHBvc3RzY3JpYmUobW9kdWxvLG1vZHVsb3Nbcm93XS5zY3JpcHQpOyB9XG4gICAgICAgICAgICAgIGNhdGNoIChlcnIpIHsgY29uc29sZS5sb2coXCJFcnJvciBhbCBpbnNlcnRhciBzY3JpcHRcIik7fVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC8vZXZhbChtb2R1bG9zW3Jvd10uc2NyaXB0KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy9tb2R1bG8uYWRkQ2xhc3MoJ2FudW5jaW8tYWN0aXZvJyk7XG4gICAgICAgICAgICBpZiAobW9kdWxvc1tyb3ddLmh0bWwgJiYgbW9kdWxvc1tyb3ddLmh0bWwubGVuZ3RoPjEpe1xuICAgICAgICAgICAgICB2Y
1XIgZGl2ID0gXG4gICAgICAgICAgICAgICAgJCgnPGRpdi8+JykuYWRkQ2xhc3MoJ2h0bWwtYW51bicpXG4gICAgICAgICAgICAgICAgLmFwcGVuZFRvKG1vZHVsbyk7XG5cbiAgICAgICAgICAgICAgZGl2LmFwcGVuZChtb2R1bG9zW3Jvd10uaHRtbCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpZiAobW9kdWxvc1tyb3ddLnVybF9yZWRpcmVjY2lvbil7XG4gICAgICAgICAgICAgICAgdmFyIHJlZGlyZWNjaW9uID0gbW9kdWxvc1tyb3ddLnVybF9yZWRpcmVjY2lvbjtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVkaXJlY2Npb24gPSBcImZhbHNlXCIgXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdmFyIGEgPSAkKCc8YS8+JylcbiAgICAgICAgICAgICAgICAuYXR0cignZGF0YS1hbnVuJyxtb2R1bG9zW3Jvd10uaWQpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ2RhdGEtY2xpY2snLHJlZGlyZWNjaW9uKVxuICAgICAgICAgICAgICAgIC5hdHRyKCdocmVmJyxcIi9pcl9hbnVuY2lvL1wiK21vZHVsb3Nbcm93XS5pZCsnLycgKyBtb2JpbCwpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ3RhcmdldCcsJ19ibGFuaycpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ2FyaWEtbGFiZWwnLCdwdWJsaWNpZGFkJylcbiAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ2FudW5jaW8tbGluaycpXG4gICAgICAgICAgICAgICAgLmFwcGVuZFRvKG1vZHVsbyk7XG4gICAgICAgICAgICAgIGlmIChtb2R1bG9zW3Jvd10uaW1hZ2VuKXtcbiAgICAgICAgICAgICAgICBpZihtb2R1bG9zW3Jvd10uaW1hZ2VuLnNwbGl0KCcuJykucG9wKCkuc3BsaXQoJz8nKS5zaGlmdCgpID09IFwibXA0XCIpIHsgXG4gICAgICAgICAgICAgICAgICB2Y
1XIgdmlkZW8gPSBcbiAgICAgICAgICAgICAgICAgICAgJCgnPHZpZGVvLz4nKS5hZGRDbGFzcygnbm8tbWVwJylcbiAgICAgICAgICAgICAgICAgICAgLnByb3Aoe2F1dG9wbGF5OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBtdXRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgbG9vcDogdHJ1ZX0pXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCdzcmMnLG1vZHVsb3Nbcm93XS5pbWFnZW4pXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCdhbHQnLGRhdGEudGV4dG8pXG4gICAgICAgICAgICAgICAgICAgIC5hcHBlbmRUbyhhKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgeyBcbiAgICAgICAgICAgICAgICAgIHZhciBpbWcgPSAkKCc8aW1nLz4nKS5hZGRDbGFzcygnJylcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ3NyYycsbW9kdWxvc1tyb3ddLmltYWdlbilcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2FsdCcsZGF0YS50ZXh0bylcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2ZldGNocHJpb3JpdHknLCdoaWdodCcpXG4gICAgICAgICAgICAgICAgICAgIC5hcHBlbmRUbyhhKTtcbiAgICAgICAgICAgICAgICB9IFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChtb2R1bG9zW3Jvd10udXJsX2ltcHJlc2lvbil7XG4gICAgICAgICAgICAgICAgdmFyIHBpeGVsID0gXG4gICAgICAgICAgICAgICAgICAkKCc8aW1nLz4nKS5hZGRDbGFzcygndHJhbnNwYXJlbnQnKVxuICAgICAgICAgICAgICAgICAgLmF0dHIoJ3NyYycsbW9kdWxvc1tyb3ddLnVybF9pbXByZXNpb24ucmVwbGFjZShcIlt0aW1lc3RhbXBdXCIsICtuZXcgRGF0ZSkpXG4gICAgICAgICAgICAgICAgICAuYXR0cignYWx0JyxcIkFkdmVydGlzbWVudFwiKVxuICAgICAgICAgICAgICAgICAgLmF0dHIoJ2JvcmRlcicsXCIwXCIpXG4gICAgICAgICAgICAgICAgICAuYXR0cignaGVpZ2h0JyxcIjFcIilcbiAgICAgICAgICAgICAgICAgIC5hdHRyKCd3aWR0aCcsXCIxXCIpXG4gICAgICAgICAgICAgICAgICAuYXBwZW5kVG8oYSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBwb3B1cCgpO1xuICAgICAgfSxcbiAgICAgIGVycm9yIDogZnVuY3Rpb24ocmVxdWVzdCxlcnJvcilcbiAgICAgIHtcbiAgICAgICAgJCgnYm9keScpLnJlbW92ZUNsYXNzKCd3YWl0Jyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAkKGRvY3VtZW50KS5vbignY2xpY2snLCcuYW51bmNpby1saW5rJywgZnVuY3Rpb24oKSB7XG4gICAgdmFyIHVybCA9ICQodGhpcykuYXR0cihcImRhdGEtY2xpY2tcIik7XG4gICAgaWYgKHVybCAhPSBcImZhbHNlXCIpeyAkLmdldCh1cmwpOyB9XG4gIH0pO1xuXG59XG5cbmZ1bmN0aW9uIHBvcHVwKCkge1xuICBjb25zdCBwb3B1cCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwicG9wdXBcIik7XG4gIGlmIChwb3B1cCAmJiBwb3B1cC5jaGlsZHJlbi5sZW5ndGggIT09IDApIHtcbiAgICBzZXRUaW1lb3V0KFxuICAgICAgZnVuY3Rpb24oKXtcbiAgICAgICAgLy9jb25zdCBtb2RhbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwibW9kYWwtcG9wdXBcIik7XG4vL2lmIChtb2RhbCkge1xuICAgICAgICAvLyBNb3N0cmFyIGVsIG1vZGFsIG1hbnVhbG1lbnRlIChzaW4gQm9vdHN0cmFwKVxuLy8gICAgICAgIG1vZGFsLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7ICAgICAvLyBvIHVzYSBcImZsZXhcIiBzaSB0dSBDU1MgbG8gcmVxdWllcmVcbiAvLyAgICAgICBtb2RhbC5jbGFzc0xpc3QuYWRkKFwidmlzaWJsZVwiKTsgICAgLy8gb3BjaW9uYWwsIHBvciBzaSB0aWVuZXMgYW5pbWFjaW9uZXMgQ1NTXG4gLy8gICAgIH1cbiAgICAgICAgJCgnI21vZGFsLXBvcHVwJykubW9kYWwoJ3Nob3cnKTtcbiAgICAgICAgY29uc3QgZGF5cyA9IDE7XG4gICAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpO1xuICAgICAgICBkYXRlLnNldFRpbWUoZGF0ZS5nZXRUaW1lKCkgKyAoZGF5cyoyNCo2MCo2MCoxMDAwKSk7XG4gICAgICAgIGNvbnN0IGV4cGlyZXMgPSBcIjsgZXhwaXJlcz1cIiArIGRhdGUudG9VVENTdHJpbmcoKTtcbiAgICAgICAgY29uc3QgbmFtZSA9IFwiaGFiXCI7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gXCJzYWx0YXJpbmVzXCI7XG4gICAgICAgIGRvY3VtZW50LmNvb2tpZSA9IG5hbWUgKyBcIj1cIiArICh2YWx1ZSB8fCBcIlwiKSAgKyBleHBpcmVzICsgXCI7IHBhdGg9L1wiO1xuICAgICAgfSAsMTAwMDBcbiAgICApO1xuICAgIHBvcHVwLmlkID0gXCJwb3B1cE9GRlwiO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBlZGlyX2FydGljdWxvcyhub2RvLCB0aXBvKSB7XG4gICQoJ2JvZHknKS5hZGRDbGFzcygnd2FpdCcpO1xuICAkLmFqYXgoe1xuICAgIHVybDogJy9hcGkvbGlzdGFyLycgKyBub2RvICsgJy8nICsgdGlwbyxcbiAgICB0eXBlIDogJ0dFVCcsXG4gICAgZGF0YVR5cGU6J2pzb24nLFxuICAgIHN1Y2Nlc3MgOiBmdW5jdGlvbihkYXRhKSB7ICAgICAgICAgICAgICBcbiAgICAgICQoJ2JvZHknKS5yZW1vdmVDbGFzcygnd2FpdCcpO1xuICAgICAgZmFicmljYXJfbWVudV9zZWNjaW9uZXMoZGF0YS5kYXRhLCB0aXBvKTtcbiAgICB9LFxuICAgIGVycm9yIDogZnVuY3Rpb24ocmVxdWVzdCxlcnJvcikge1xuICAgICAgJCgnYm9keScpLnJlbW92ZUNsYXNzKCd3YWl0Jyk7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gYXBhbmhvc19tZW51cygpe1xuICB2YXIgdyA9IHdpbmRvdy5pbm5lcldpZHRoXG4gICAgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoXG4gICAgfHwgZG9jdW1lbnQuYm9keS5jbGllbnRXaWR0aDtcblxuICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJtZW51LWFkbWluXCIpICYmIHcgPiA3NjgpIHtcbiAgICBsZXQgaCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjbWVudS1hZG1pbiAuY29udGFpbmVyXCIpXG4gICAgICAuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAgIC5oZWlnaHQ7XG4gICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYW51bmNpby1jYWJlY2VyYVwiKSkge1xuICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJhbnVuY2lvLWNhYmVjZXJhXCIpXG4gICAgICAgIC5zdHlsZS5tYXJnaW5Ub3AgPSAgaDtcbiAgICB9XG4gICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJwdWJsaS1sYXRlcmFsXCIpKSB7XG4gICAgICBoID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5Q2xhc3NOYW1lKFwic2VndWltaWVudG9cIilcbiAgICAgICAgLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgICAgIC5oZWlnaHQgKyBoO1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIi5wdWJsaS1sYXRlcmFsXCIpLmZvckVhY2goKGxhdGVyYWwpID0+IHtcbiAgICAgICAgbGF0ZXJhbC5zdHlsZS50b3AgPSBoO1xuICAgICAgfSlcbiAgICB9XG4gI
1H1cbn1cblxuJChkb2N1bWVudCkub24oJ2NsaWNrJywnLmNvbXBhcnRpcl9saW5rJywgZnVuY3Rpb24oKSB7XG59KTtcbiQoZG9jdW1lbnQpLm9uKCdjbGljaycsJy5hbnVuY2lvIGEgb2ZmJywgZnVuY3Rpb24oKSB7XG4gIHZhciBkID0gJCh0aGlzKS5hdHRyKFwiZGF0YS1hbnVuXCIpO1xuICAkLmFqYXgoe1xuICAgIHVybDogJy9hcGkvYW51bmNpby9yZWRpcmVjY2lvbi8nICsgZCxcbiAgICB0eXBlIDogJ1BVVCcsXG4gICAgc3VjY2VzcyA6IGZ1bmN0aW9uKGRhdGEpIHsgICAgICAgICAgICAgIFxuICAgIH0sXG4gIH0pO1xufSk7XG5cbnZhciBzd2lwZXJfc2VjY2lvbiA9IFwiXCI7XG52YXIgd2lkdGggPSAkKHdpbmRvdykud2lkdGgoKTtcbmZ1bmN0aW9uIGNhbWJpbygpeyBcbiAgLy9zb2NpYWwoKTtcbiAgYXBhbmhvc19tZW51cygpO1xuICAvL3Njcm9sbEhhbmRsZXIoKTtcbiAgYXBhbmhvc19pbWFnZW5lc19hcnRpY3Vsb3MoKTtcbn1cbmZ1bmN0aW9uIGFwYW5ob19jcm9wKCl7XG4gIHZhciB3ID0gd2luZG93LmlubmVyV2lkdGhcbiAgICB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGhcbiAgICB8fCBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoO1xuICBpZiAodz43NjggJiYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJ0YWJsZS50YWJsZSAuY3JvcFwiKSB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwidGFibGUudGFibGUgLmNyb3AyXCIpKSkge1xuICAgIHZhciB0YWJsZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJ0YWJsZS50YWJsZVwiKTtcbiAgICB2YXIgY3JvcCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJ0YWJsZS50YWJsZSAuY3JvcFwiKTtcbiAgICB2YXIgY3JvcHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwidGFibGUudGFibGUgLmNyb3AyXCIpO1xuICAgIHZhciBjcm9wMSA9IGNyb3BzWzBdO1xuICAgIHZhciBjcm9wMiA9IGNyb3BzWzFdO1xuICAgIHZhciBhbmNob19jb250ZW5lZG9yXzAgPSB0YWJsZS5wYXJlbnROb2RlLm9mZnNldFdpZHRoO1xuXG4gICAgaWYoY3JvcCl7XG4gICAgICBjcm9wLnN0eWxlLm1heFdpZHRoID0gXCIxMDAlXCI7XG4gICAgICBjcm9wLnN0eWxlLndpZHRoID0gXCIxMDAlXCI7XG4gICAgfVxuICAgIGlmKGNyb3AyKXtcbiAgICAgIGNyb3AyLnN0eWxlLm1heFdpZHRoID0gXCIxMDAlXCI7XG4gICAgICBjcm9wMi5zdHlsZS53aWR0aCA9IFwiMTAwJVwiO1xuICAgIH1cblxuICAgIGNvbnNvbGUubG9nKGFuY2hvX2NvbnRlbmVkb3JfMClcbiAgICB2YXIgYW5jaG9fY29udGVuZWRvciA9IHRhYmxlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLng7XG4gICAgY29uc29sZS5sb2coYW5jaG9fY29udGVuZWRvcilcbiAgICB2YXIgYW5jaG9fdGFibGEgPSB0YWJsZS5vZmZzZXRXaWR0aDtcbiAgICBjb25zb2xlLmxvZyhhbmNob190YWJsYSlcblxuICAgIHZhciBhbmNob19jcm9wID0gMDtcbiAgICBpZihjcm9wKXtcbiAgICAgIGFuY2hvX2Nyb3AgPSBjcm9wLm9mZnNldFdpZHRoO1xuICAgIH1cbiAgICBpZihjcm9wMil7XG4gICAgICBhbmNob19jcm9wID0gY3JvcDIub2Zmc2V0V2lkdGggKyBjcm9wMS5vZmZzZXRXaWR0aCA7XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKGFuY2hvX2Nyb3ApXG4gICAgdmFyIG51ZXZvX2FuY2hvX2Nyb3AgPSBhbmNob19jb250ZW5lZG9yIC0gKGFuY2hvX3RhYmxhIC0gYW5jaG9fY3JvcCk7XG4gICAgY29uc29sZS5sb2cobnVldm9fYW5jaG9fY3JvcClcblxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJ0YWJsZS50YWJsZSAuY3JvcFwiKS5mb3JFYWNoKChjcm9wKSA9PntcbiAgICAgIGNyb3Auc3R5bGUubWF4V2lkdGggPSBgY2FsYygke251ZXZvX2FuY2hvX2Nyb3B9cHgpYDtcbiAgICAgIGNyb3Auc3R5bGUud2lkdGggPSBgY2FsYygke251ZXZvX2FuY2hvX2Nyb3B9cHggKWA7XG4gICAgfSlcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwidGFibGUudGFibGUgLmNyb3AyXCIpLmZvckVhY2goKGNyb3ApID0+e1xuICAgICAgY3JvcC5zdHlsZS5tYXhXaWR0aCA9IGBjYWxjKCR7bnVldm9fYW5jaG9fY3JvcC8yfXB4KWA7XG4gICAgICBjcm9wLnN0eWxlLndpZHRoID0gYGNhbGMoJHtudWV2b19hbmNob19jcm9wLzJ9cHggKWA7XG4gICAgfSlcbiAgICAgIHRhYmxlLnN0eWxlLm1heFdpZHRoID0gYGNhbGMoJHthbmNob19jb250ZW5lZG9yXzB9cHggLSAxLjVyZW0pYDtcbiAgICAgIHRhYmxlLnN0eWxlLndpZHRoID0gYGNhbGMoJHthbmNob19jb250ZW5lZG9yXzB9cHggLSAxLjVyZW0pYDtcbiAgfVxufVxuZnVuY3Rpb24gYXBhbmhvc19pbWFnZW5lc19hcnRpY3Vsb3MoKXtcbiAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIucmVhbCAudG9kby1lbC1hbmNob1wiKSkge1xuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIucmVhbCAudG9kby1lbC1hbmNob1wiKS5mb3JFYWNoKChpbWFnZW4pID0+IHtcbiAgICAgIHZhciBwcm9wID0gaW1hZ2VuLmdldEF0dHJpYnV0ZShcImRhdGEtcHJvcG9yY2lvblwiKSBcbiAgICAgIHZhciB3aWR0aCA9IGltYWdlbi5vZmZzZXRXaWR0aCBcbiAgICAgIGltYWdlbi5zdHlsZS5wYWRkaW5nQm90dG9tID0gcHJvcCp3aWR0aC8xMDAgKyBcInB4XCJcbiAgICAgIGltYWdlbi5zZXRBdHRyaWJ1dGUoJ3BoeC11cGRhdGUnLCdpZ25vcmUnKTtcbiAgICB9KVxuICB9XG5cbiAgdmFyIHcgPSB3aW5kb3cuaW5uZXJXaWR0aFxuICAgIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aFxuICAgIHx8IGRvY3VtZW50LmJvZHkuY2xpZW50V2lkdGg7XG5cbiAgaWYgKHcgPiA3NjgpIHtcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLnZlcnRpY2FsIGltZ1wiKS5mb3JFYWNoKChpbWFnZW4pID0+IHtcbiAgICAgIGltYWdlbi5wYXJlbnROb2RlLnN0eWxlLmNzc1RleHQgPSBcImNzc1RleHRcIixcIndpZHRoOiA3NSUgIWltcG9ydGFudDsgbWFyZ2luLXJpZ2h0OiAyLjVlbSAhaW1wb3J0YW50OyBtYXJnaW4tbGVmdDogLTM3JSAhaW1wb3J0YW50OyBmbG9hdDogbGVmdFwiO1xuICAgICAgLy9pbWFnZW4ubmV4dEVsZW1lbnRTaWJsaW5nLnN0eWxlLm1hcmdpbkxlZnQgPSBcIjUwJVwiO1xuICAgIH0pXG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIi5yZWFsIC52ZXJ0aWNhbCBpbWdcIikuZm9yRWFjaCgoaW1hZ2VuKSA9PiB7XG4gICAgICB2Y
1XIgcGFkZGluZ0JvdHRvbSA9IGltYWdlbi5wYXJlbnROb2RlLnN0eWxlLnBhZGRpbmdCb3R0b20qLjYzXG4gICAgICBpbWFnZW4ucGFyZW50Tm9kZS5zdHlsZS5jc3NUZXh0ID0gYHBhZGRpbmctYm90dG9tOiAke3BhZGRpbmdCb3R0b219OyBtYXJnaW46IDAgIWltcG9ydGFudDtgO1xuICAgICAgaW1hZ2VuLnBhcmVudE5vZGUucGFyZW50Tm9kZS5zdHlsZS5jc3NUZXh0ID0gXCJtYXJnaW46IDAgMCAwIC0zNyUgIWltcG9ydGFudDsgZmxvYXQ6IGxlZnQ7IGNsZWFyOiBib3RoOyBwYWRkaW5nOiAyLjVyZW0gMi41cmVtIDAgMFwiO1xuICAgICAgLy9pbWFnZW4ucGFyZW50Tm9kZS5wYXJlbnROb2RlLnF1ZXJ5U2VsZWN0b3JBbGwoXCIuZmlndXJlLWNhcHRpb25cIikuc3R5bGUucGFkZGluZ0xlZnQgPSBcIjUwJVwiO1xuICAgICAgaW1hZ2VuLnN0eWxlLm1hcmdpbkxlZnQgPSBcIjAgIWltcG9ydGFudFwiXG4gICAgICB2YXIgcHJvcCA9IGltYWdlbi5wYXJlbnROb2RlLmdldEF0dHJpYnV0ZShcImRhdGEtcHJvcG9yY2lvblwiKSBcbiAgICAgIHZhciB3aWR0aCA9IGltYWdlbi5wYXJlbnROb2RlLm9mZnNldFdpZHRoIFxuICAgICAgaW1hZ2VuLnBhcmVudE5vZGUuc3R5bGUucGFkZGluZ0JvdHRvbSA9IHByb3Aqd2lkdGgvMTAwICsgXCJweFwiXG4gICAgfSlcbiAgfSBlbHNlIHtcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLnZlcnRpY2FsIGltZ1wiKS5mb3JFYWNoKChpbWFnZW4pID0+IHtcbiAgICAgIGltYWdlbi5wYXJlbnROb2RlLnN0eWxlLmNzc1RleHQgPSBcImNzc1RleHRcIixcIlwiO1xuICAgIH0pXG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIi5yZWFsIC52ZXJ0aWNhbCBpbWdcIikuZm9yRWFjaCgoaW1hZ2VuKSA9PiB7XG4gICAgICB2Y
1XIgd2lkdGggPSBpbWFnZW4ucGFyZW50Tm9kZS5vZmZzZXRXaWR0aCBcbiAgICAgIHZhciBwcm9wID0gaW1hZ2VuLnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlKFwiZGF0YS1wcm9wb3JjaW9uXCIpIFxuICAgICAgdmFyIHBhZGRpbmdCb3R0b20gPSB3aWR0aCAqIHByb3BcbiAgICAgIGltYWdlbi5wYXJlbnROb2RlLnN0eWxlLmNzc1RleHQgPSBgcGFkZGluZy1ib3R0b206ICR7cGFkZGluZ0JvdHRvbX07IG1hcmdpbjogMCAhaW1wb3J0YW50O2A7XG4gICAgICBpbWFnZW4ucGFyZW50Tm9kZS5wYXJlbnROb2RlLnN0eWxlLmNzc1RleHQgPSBcIlwiO1xuICAgICAgaW1hZ2VuLnN0eWxlLm1hcmdpbkxlZnQgPSBcIjAgIWltcG9ydGFudFwiXG4gICAgICBpbWFnZW4ucGFyZW50Tm9kZS5zdHlsZS5wYWRkaW5nQm90dG9tID0gcHJvcCp3aWR0aC8xMDAgKyBcInB4XCJcbiAgfSlcbiAgfVxufVxuXG52YXIgZ2FsbGVyeVRvcCA9IHt9O1xudmFyIGdhbGxlcnlUaHVtYnMgPSB7fTtcbnZhciBnYWxsZXJ5VGh1bWJzRmFrZSA9IHt9O1xuXG5mdW5jdGlvbiBzd2lwZXJfZ2FsZXJpYSgpIHtcbiAgaWYgKCQoJy5nYWxsZXJ5LXRvcCcpLmxlbmd0aCkge1xuICAgIGdhbGxlcnlUb3AgPSBuZXcgU3dpcGVyKCcuZ2FsbGVyeS10b3AnLCB7XG4gICAgICBzbGlkZXNQZXJWaWV3OiAxLFxuICAgICAgc2xpZGVzUGVyR3JvdXA6IDEsXG4gICAgICBuZXh0QnV0dG9uOiAnLnN3aXBlci1idXR0b24tbmV4dCcsXG4gICAgICBwcmV2QnV0dG9uOiAnLnN3aXBlci1idXR0b24tcHJldicsXG4gICAgICBvblNsaWRlQ2hhbmdlU3RhcnQ6IGZ1bmN0aW9uKHN3aXApe1xuICAgICAgICBpZiAod2lkdGg+NzY4KXsgXG4gICAgICAgICAgdmFyIGluZGV4ID0gc3dpcC5hY3RpdmVJbmRleDtcbiAgICAgICAgICB2Y
1XIgYWN0aXZvID0gc3dpcC5zbGlkZXNbaW5kZXhdO1xuICAgICAgICAgIGdhbGxlcnlUaHVtYnMuc2xpZGVUbyhpbmRleCk7XG4gICAgICAgICAgZ2FsbGVyeVRodW1ic0Zha2Uuc2xpZGVUbyhpbmRleCk7XG4gICAgICAgICAgdmFyIHNlY2Npb24gPSBhY3Rpdm8uZ2V0QXR0cmlidXRlKCdkYXRhLXNlY2Npb24nKTtcbiAgICAgICAgICBpZiAoc2VjY2lvbiAhPSBzd2lwZXJfc2VjY2lvbikge1xuICAgICAgICAgICAgc3dpcGVyX3NlY2Npb24gPSBzZWNjaW9uO1xuICAgICAgICAgICAgdmFyIGlkX2xpbmsgPSAnI2FwYXJ0YWRvJytzZWNjaW9uO1xuICAgICAgICAgICAgdmFyIGlkX3RhYiA9ICcjYXBhcnRhZG8nK3NlY2Npb24rJy10YWInO1xuICAgICAgICAgICAgJCgnLnRhYmxpbmsnKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAkKCcudGFiLXBhbmUnKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAkKCcudGFiLXBhbmUnKS5yZW1vdmVDbGFzcygnc2hvdycpO1xuICAgICAgICAgICAgJChpZF9saW5rKS5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAkKGlkX3RhYikuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgJChpZF9saW5rKS5hZGRDbGFzcygnc2hvdycpO1xuICAgICAgICAgICAgJChpZF90YWIpLmFkZENsYXNzKCdzaG93Jyk7XG4gICAgICAgICAgICAkKGlkX3RhYikudGFiKCdzaG93Jyk7XG4gICAgICAgICAgfSAgICAgICAgIFxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKHdpZHRoPjc2OCl7IFxuICAgICAgZ2FsbGVyeVRodW1icyA9IG5ldyBTd2lwZXIoJy5nYWxsZXJ5LXRodW1icycsIHtcbiAgICAgICAgY2VudGVyZWRTbGlkZXM6IHRydWUsXG4gICAgICAgIHNsaWRlc1BlclZpZXc6IFwiYXV0b1wiLFxuICAgICAgICBzbGlkZXNQZXJHcm91cDogMSxcbiAgICAgICAgd2F0Y2hTbGlkZXNWaXNpYmlsaXR5OiB0cnVlLFxuICAgICAgICBjZW50ZXJlZFNsaWRlczogdHJ1ZSxcbiAgICAgICAgLy90b3VjaFJhdGlvOiAwLjIsXG4gICAgICAgIHNsaWRlVG9DbGlja2VkU2xpZGU6IHRydWUsXG4gICAgICAgIC8vcGFnaW5hdGlvbjogXCIuc3dpcGVyLXBhZ2luYXRpb25cIixcbiAgICAgICAgLy9uZXh0QnV0dG9uOiAnLnN3aXBlci1idXR0b24tbmV4dDInLFxuICAgICAgICAvL3ByZXZCdXR0b246ICcuc3dpcGVyLWJ1dHRvbi1wcmV2MicsXG4gICAgICAgIC8vcGFnaW5hdGlvbkNsaWNrYWJsZTogdHJ1ZSxcbiAgICAgICAgem9vbTogZmFsc2UsXG4gICAgICAgIGdyYWJDdXJzb3I6IHRydWUsXG4gICAgICAgIG9uU2xpZGVDaGFuZ2VTdGFydDogZnVuY3Rpb24oc3dpcCl7XG4gICAgICAgICAgdmFyIGluZGV4ID0gc3dpcC5hY3RpdmVJbmRleDtcbiAgICAgICAgICBnYWxsZXJ5VG9wLnNsaWRlVG8oaW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGdhbGxlcnlUaHVtYnNGYWtlID0gbmV3IFN3aXBlcignLmdhbGxlcnktdGh1bWJzLWZha2UnLCB7XG4gICAgICAgIHNsaWRlc1BlclZpZXc6IDcsXG4gICAgICAgIHNsaWRlc1Blckdyb3VwOiA3LFxuICAgICAgICBzbGlkZVRvQ2xpY2tlZFNsaWRlOiB0cnVlLFxuICAgICAgICBwYWdpbmF0aW9uOiBcIi5zd2lwZXItcGFnaW5hdGlvblwiLFxuICAgICAgICBuZXh0QnV0dG9uOiAnLnN3aXBlci1idXR0b24tbmV4dDInLFxuICAgICAgICBwcmV2QnV0dG9uOiAnLnN3aXBlci1idXR0b24tcHJldjInLFxuICAgICAgICBwYWdpbmF0aW9uQ2xpY2thYmxlOiB0cnVlLFxuICAgICAgICBvblNsaWRlQ2hhbmdlU3RhcnQ6IGZ1bmN0aW9uKHN3aXApe1xuICAgICAgICAgIHZhciBpbmRleCA9IHN3aXAuYWN0aXZlSW5kZXg7XG4gICAgICAgICAgZ2FsbGVyeVRvcC5zbGlkZVRvKGluZGV4KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGdhbGxlcnlUb3AucGFyYW1zLmNvbnRyb2wgPSBnYWxsZXJ5VGh1bWJzO1xuICAgICAgZ2FsbGVyeVRodW1icy5wYXJhbXMuY29udHJvbCA9IGdhbGxlcnlUb3A7XG4gICAgfVxuICB9XG4gIHZhciBhY2Nlc28gPSB0aGlzOyBcbiAgJChkb2N1bWVudCkub24oJ2NsaWNrJywnLnBlZGlyIC5hcnRpY3Vsby1yZXN1bWVuJywgcGVkaXJfYXJ0aWN1bG8pO1xuICAkKGRvY3VtZW50KS5vbignZGJsY2xpY2snLCcuZ2FsbGVyeS10aHVtYnMgLnN3aXBlci1zbGlkZS1hY3RpdmUnLCBwZWRpcl9hcnRpY3Vsbyk7XG4gICQoJ2FbZGF0YS10b2dnbGU9XCJ0YWJcIl0nKS5vbignc2hvd24uYnMudGFiJywgZnVuY3Rpb24gKGUpIHtcbiAgICBlLnRhcmdldCAvLyBuZXdseSBhY3RpdmF0ZWQgdGFiO1xuICAgIHZhciBpZCA9IGUudGFyZ2V0LmdldEF0dHJpYnV0ZSgnYXJpYS1jb250cm9scycpO1xuICAgIHZhciBpZF9hcnQgPSAkKCcjJytpZCsnIC5zd2lwZXItc2xpZGUnKS5maXJzdCgpLmF0dHIoJ2RhdGEtYXJ0aWN1bG8nKTtcbiAgICBlLnJlbGF0ZWRUYXJnZXQgLy8gcHJldmlvdXMgYWN0aXZlIHRhYlxuICAgIHZhciBpdGVtID0gJChcIi5nYWxsZXJ5LXRvcCAqW2RhdGEtYXJ0aWN1bG89XCIraWRfYXJ0K1wiXVwiKTtcbiAgICB2YXIgaW5kZXggPSAkKFwiLmdhbGxlcnktdG9wIC5hcnRpY3Vsby1yZXN1bWVuXCIpLmluZGV4KGl0ZW0pO1xuICAgIGlmIChpbmRleCA+IC0xICl7XG4gICAgICBnYWxsZXJ5VG9wLnNsaWRlVG8oaW5kZXgpO1xuICAgIH1cblxuICAgIHZhciBpZF9saW5rID0gJyMnK2lkO1xuICAgIHZhciBpZF90YWIgPSAnIycraWQrJy10YWInO1xuXG4gICAgJCgnLnRhYmxpbmsnKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgJCgnLnRhYi1wYW5lJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICQoJy50YWItcGFuZScpLnJlbW92ZUNsYXNzKCdzaG93Jyk7XG4gICAgJChpZF9saW5rKS5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgJChpZF90YWIpLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAkKGlkX2xpbmspLmFkZENsYXNzKCdzaG93Jyk7XG4gICAgJChpZF90YWIpLmFkZENsYXNzKCdzaG93Jyk7XG4gICAgJChpZF90YWIpLnRhYignc2hvdycpO1xuICB9KSBcbn1cbiQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgpIHtcbiAgaWYgKCQoJy5zd2lwZXItc29jaWFzJykubGVuZ3RoKSB7XG4gICAgdmFyIHN3aXBlciA9IG5ldyBTd2lwZXIoJy5zd2lwZXItc29jaWFzJywge1xuICAgICAgbmV4dEJ1dHRvbjogJy5zd2lwZXItYnV0dG9uLW5leHQnLFxuICAgICAgcHJldkJ1dHRvbjogJy5zd2lwZXItYnV0dG9uLXByZXYnLFxuICAgICAgcGFnaW5hdGlvbjogXCIuc3dpcGVyLXBhZ2luYXRpb25cIixcbiAgICAgIHNwYWNlQmV0d2VlbjogMCxcbiAgICAgIHNwZWVkOiA0MDAwLFxuICAgICAgbG9vcDogdHJ1ZSxcbiAgICAgIGF1dG9wbGF5OiB7XG4gICAgICAgIGRlbGF5OiA2MDAwLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufSk7XG5mdW5jdGlvbiBzd2lwZXJfZ2FsZXJpYV9tb2RhbCgpIHtcbiAgJChcIi5tb2RhbFwiKS5vbignc2hvdy5icy5tb2RhbCcsIGZ1bmN0aW9uKGUpIHtcbiAgICBzZXRUaW
11lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCQoJy5zd2lwZXItZ2FsZXJpYScpLmxlbmd0aCkge1xuICAgICAgICB2YXIgaW1nID0gJChlLnJlbGF0ZWRUYXJnZXQpLmF0dHIoXCJkYXRhLWltZ1wiKTtcbiAgICAgICAgdmFyIHN3aXBlciA9IG5ldyBTd2lwZXIoJy5zd2lwZXItZ2FsZXJpYScsIHtcbiAgICAgICAgICBpbml0aWFsU2xpZGU6IGltZyxcbiAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAxLFxuICAgICAgICAgIHNsaWRlc1Blckdyb3VwOiAxLFxuICAgICAgICAgIG5leHRCdXR0b246ICcuc3dpcGVyLWJ1dHRvbS1uZXh0JyxcbiAgICAgICAgICBwcmV2QnV0dG9uOiAnLnN3aXBlci1idXR0b20tcHJldicsXG4gICAgICAgICAgZWZmZWN0OiAnZmFkZScsXG4gICAgICAgICAgcGFnaW5hdGlvbjogJy5wYWdpbmF0aW9uJyxcbiAgICAgICAgICBwYWdpbmF0aW9uVHlwZTogJ2N1c3RvbScsXG4gICAgICAgICAgcGFnaW5hdGlvbkN1c3RvbVJlbmRlcjogZnVuY3Rpb24gKHN3aXBlciwgY3VycmVudCwgdG90YWwpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnQgKyAnLycgKyB0b3RhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSwgNTAwKTtcbiAgfSk7XG4gICQoZG9jdW1lbnQpLm9uKCdjbGljaycsJy5vY3VsdGFyLWluZm8nLCBmdW5jdGlvbigpIHtcbiAgICB2YXIgY29scyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5zd2lwZXItZ2FsZXJpYSAuaW5mbycpO1xuICAgIGZvciAodmFyIGMgPSAwOyBjIDwgIGNvbHMubGVuZ3RoOyArK2Mpe1xuICAgICAgY29sc1tjXS5jbGFzc0xpc3QudG9nZ2xlKCdvY3VsdG8nKTtcbiAgICB9XG4gIH0pO1xufTtcbmZ1bmN0aW9uIHBlZGlyX2FydGljdWxvKCkge1xuICB2YXIgaWQgPSAkKHRoaXMpLmF0dHIoXCJkYXRhLWFydGljdWxvXCIpO1xuICAkKCdib2R5JykuYWRkQ2xhc3MoJ3dhaXQnKTtcbiAgJC5hamF4KHtcbiAgICB1cmw6ICcvYXBpX3NlY3VyL2FydGljdWxvLycgKyBpZCxcbiAgICB0eXBlIDogJ0dFVCcsXG4gICAgZGF0YVR5cGU6J2pzb24nLFxuICAgIHN1Y2Nlc3MgOiBmdW5jdGlvbihkYXRhKSB7ICAgICAgICAgICAgICBcbiAgICAgICQoJ2JvZHknKS5yZW1vdmVDbGFzcygnd2FpdCcpO1xuICAgICAgdmFyIGFydGljdWxvID0gJCgnLmFydGljdWxvLWNvbXBsZXRvJyk7XG4gICAgICBhcnRpY3Vsby5odG1sKCcnKSA7XG4gICAgICBhcnRpY3Vsby5odG1sKGRhdGEuYXJ0aWN1bG8pIDtcbiAgICAgIGNhbWJpbygpO1xuICAgICAgJCgnaHRtbCwgYm9keScpLnN0b3AoKS5hbmltYXRlKHtcbiAgICAgICAgJ3Njcm9sbFRvcCc6IGFydGljdWxvXG4gICAgICAgIC5vZmZzZXQoKS50b3AgLSAkKFwiLnNlZ3VpbWllbnRvXCIpLmhlaWdodCgpIC0gMjVcbiAgICAgIH0sIDkwMCwgJ3N3aW5nJyk7XG4gICAgfSxcbiAgICBlcnJvciA6IGZ1bmN0aW9uKHJlcXVlc3QsZXJyb3IpIHtcbiAgICAgICQoJ2JvZHknKS5yZW1vdmVDbGFzcygnd2FpdCcpO1xuICAgIH1cbiAgfSk7XG4gIHZhciBpZF90YWIgPSAkKFwiI1RhYkNvbnRlbnQgKltkYXRhLWFydGljdWxvPVwiK2lkK1wiXVwiKVxuICAgIC5wYXJlbnQoKS5wYXJlbnQoKS5wYXJlbnQoKS5wYXJlbnQoKVxuICAgIC5hdHRyKFwiaWRcIik7XG4gIHZhciBpZF9saW5rID0gJyMnK2lkX3RhYjtcbiAgaWRfdGFiID0gJyMnK2lkX3RhYisnLXRhYic7XG4gICQoJy50YWJsaW5rJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAkKCcudGFiLXBhbmUnKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICQoJy50YWItcGFuZScpLnJlbW92ZUNsYXNzKCdzaG93Jyk7XG4gICQoaWRfbGluaykuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAkKGlkX3RhYikuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAkKGlkX2xpbmspLmFkZENsYXNzKCdzaG93Jyk7XG4gICQoaWRfdGFiKS5hZGRDbGFzcygnc2hvdycpO1xuICAkKGlkX3RhYikudGFiKCdzaG93Jyk7XG5cbiAgdmFyIGl0ZW0gPSAkKFwiLmdhbGxlcnktdG9wICpbZGF0YS1hcnRpY3Vsbz1cIitpZCtcIl1cIik7XG4gIHZhciBpbmRleCA9ICQoXCIuZ2FsbGVyeS10b3AgLmFydGljdWxvLXJlc3VtZW5cIikuaW5kZXgoaXRlbSk7XG4gIGdhbGxlcnlUb3Auc2xpZGVUbyhpbmRleCk7XG4gIGdhbGxlcnlUaHVtYnNGYWtlLnNsaWRlVG8oaW5kZXgpO1xufVxuJChkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24gKCkge1xuICBpZiAoJCgnLnN3aXBlci1lZGljaW9uLWltcHJlc2EnKS5sZW5ndGgpIHtcbiAgICB2YXIgc3dpcGVyID0gbmV3IFN3aXBlcignLnN3aXBlci1lZGljaW9uLWltcHJlc2EnLCB7XG4gICAgICBuZXh0QnV0dG9uOiAnLnN3aXBlci1lZC1uZXh0JyxcbiAgICAgIHByZXZCdXR0b246ICcuc3dpcGVyLWVkLXByZXYnLFxuICAgICAgc3BhY2VCZXR3ZWVuOiAwLFxuICAgICAgc2xpZGVzUGVyVmlldzogMSxcbiAgICAgIHNsaWRlc1Blckdyb3VwOiAxLFxuICAgIH0pO1xuICB9XG59KTtcbiQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgpIHtcbiAgdmFyIHdpZHRoID0gJCh3aW5kb3cpLndpZHRoKCk7XG4gIGlmICh3aWR0aDw3NjgpeyBcbiAgICBpZiAoJCgnLnJlbGFjaW9uYWRhcy1PRkYgLnJlc3VtZW4nKS5sZW5ndGggPjEpIHtcbiAgICAgIHZhciBzd2lwZXIgPSBuZXcgU3dpcGVyKCcucmVsYWNpb25hZGFzIC5jb2wtbWQtOScsIHtcbiAgICAgICAgc2xpZGVDbGFzczogXCJyZXN1bWVuXCIsXG4gICAgICAgIHdyYXBwZXJDbGFzczogXCJjYXJkLWRlY2stcG9ydGFkYVwiLFxuICAgICAgICBuZXh0QnV0dG9uOiAnLnN3aXBlci1udW1lcm9zLW5leHQnLFxuICAgICAgICBwcmV2QnV0dG9uOiAnLnN3aXBlci1udW1lcm9zLXByZXYnLFxuICAgICAgICBzbGlkZXNQZXJWaWV3OiAxLFxuICAgICAgICBzbGlkZXNQZXJHcm91cDogMSxcbiAgICAgIH0pO1xuICAgIH0gXG4gICAgaWYgKCQoJy5udW1lcm8gLnJlc3RvJykubGVuZ3RoIHx8ICQoJy5zd2lwZXItbnVtZXJvcycpLmxlbmd0aCkge1xuICAgICAgdmFyIHN3aXBlciA9IG5ldyBTd2lwZXIoJy5zd2lwZXItbnVtZXJvcycsIHtcbiAgICAgICAgbmV4dEJ1dHRvbjogJy5zd2lwZXItbnVtZXJvcy1uZXh0JyxcbiAgICAgICAgcHJldkJ1dHRvbjogJy5zd2lwZXItbnVtZXJvcy1wcmV2JyxcbiAgICAgICAgc2xpZGVzUGVyVmlldzogMSxcbiAgICAgICAgc2xpZGVzUGVyR3JvdXA6IDEsXG4gICAgICB9KTtcbiAgICB9IFxuXG4gIH1cbiAgaWYgKCQoJy5zd2lwZXItbGlicm9zJykubGVuZ3RoKSB7XG4gICAgdmFyIHN3aXBlciA9IG5ldyBTd2lwZXIoJy5zd2lwZXItbGlicm9zJywge1xuICAgICAgbmV4dEJ1dHRvbjogJy5zd2lwZXItbGlicm9zLW5leHQnLFxuICAgICAgcHJldkJ1dHRvbjogJy5zd2lwZXItbGlicm9zLXByZXYnLFxuICAgICAgc2xpZGVzUGVyVmlldzogNCxcbiAgICAgIHNsaWRlc1Blckdyb3VwOiA0LFxuICAgICAgYnJlYWtwb2ludHM6IHtcbiAgICAgICAgNzY4OntcbiAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAxLFxuICAgICAgICAgI
1HNsaWRlc1Blckdyb3VwOiAxLFxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn0pO1xuXG4vKlxuJChkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24oKXtcbiAgLy8gdG8gZmFkZSBpbiBvbiBwYWdlIGxvYWRcbiAgLy8gdG8gZmFkZSBvdXQgYmVmb3JlIHJlZGlyZWN0XG4gICQoJ2EnKS5jbGljayhmdW5jdGlvbihlKXtcbiAgICByZWRpcmVjdCA9ICQodGhpcykuYXR0cignaHJlZicpO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAkKCdib2R5JykuZmFkZU91dCg0MDAsIGZ1bmN0aW9uKCl7XG4gICAgICBkb2N1bWVudC5sb2NhdGlvbi5ocmVmID0gcmVkaXJlY3RcbiAgICB9KTtcbiAgfSk7XG59KVxuXG5cblxudmFyIHRvb2x0aXBzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnJlc3VtZW4nKTtcbmZvcih2YXIgaSA9IDA7IGkgPCB0b29sdGlwcy5sZW5ndGg7IGkrKykge1xuICB0b29sdGlwc1tpXS5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBmdW5jdGlvbiBmbihlKSB7XG4gICAgaWYgKGUudGFyZ2V0LmNsYXNzTGlzdC5jb250YWlucyhcImVudHJhZGlsbGFfaG92ZXJcIikpIHtcbiAgICB2YXIgdG9vbHRpcCA9IGUudGFyZ2V0LmNsYXNzTGlzdC5jb250YWlucyhcImVudHJhZGlsbGFfaG92ZXJcIikgP1xuICAgICAgZS50YXJnZXQgOlxuICAgICAgZS50YXJnZXQucXVlcnlTZWxlY3RvcignOnNjb3BlIC5lbnRyYWRpbGxhX2hvdmVyJyk7XG4gICAgdG9vbHRpcC5zdHlsZS5sZWZ0ID1cbiAgICAgIGUucGFnZVggKyB0b29sdGlwLmNsaWVudFdpZHRoICsgMTAgPFxuICAgICAgZG9jdW1lbnQuYm9keS5jbGllbnRXaWR0aCA/XG4gICAgICBlLnBhZ2VYICsgMTAgKyAncHgnIDpcbiAgICAgIGRvY3VtZW50LmJvZHkuY2xpZW50V2lkdGggKyA1IC0gdG9vbHRpcC5jbGllbnRXaWR0aCArICdweCc7XG4gICAgdG9vbHRpcC5zdHlsZS50b3AgPVxuICAgICAgZS5wYWdlWSArIHRvb2x0aXAuY2xpZW50SGVpZ2h0ICsgMTAgPFxuICAgICAgZG9jdW1lbnQuYm9keS5jbGllbnRIZWlnaHQgP1xuICAgICAgZS5wYWdlWSArIDEwICsgJ3B4JyA6IFxuICAgICAgZG9jdW1lbnQuYm9keS5jbGllbnRIZWlnaHQgKyA1IC0gdG9vbHRpcC5jbGllbnRIZWlnaHQgKyAncHgnO1xuICAgIH1cbiAgfSk7XG59XG4qL1xuLy9kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdET01Db250ZW50TG9hZGVkJywgZnVuY3Rpb24oKSB7XG5mdW5jdGlvbiByZWNvcnRhcl9jb21lbnRhcmlvcygpe1xuICB2YXIgbGlua0NsaWNrID0gZnVuY3Rpb24oZSkge1xuICAgIHZhciBtID0gZS5jdXJyZW50VGFyZ2V0O1xuICAgIGlmIChtLmNsYXNzTGlzdC5jb250YWlucygnbGVzcycpKSB7XG4gICAgICBtLmNsYXNzTGlzdC5yZW1vdmUoJ2xlc3MnKTtcbiAgICAgIG0uaW5uZXJIVE1MID0gbW9yZXRleHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIG0uY2xhc3NMaXN0LmFkZCgnbGVzcycpO1xuICAgICAgbS5pbm5lckhUTUwgPSBsZXNzdGV4dDtcbiAgICB9XG4gICAgbS5wYXJlbnROb2RlLmNsYXNzTGlzdC50b2dnbGUoJ3Zpc2libGUnKVxuICAgIC8vbS5wYXJlbnROb2RlLm5leHRTbGliaW5nLmNsYXNzTGlzdC50b2dnbGUoJ3Zpc2libGUnKVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbiAgdmFyIHNob3dDaGFyID0gMzAwOyBcbiAgdmFyIGVsbGlwc2VzdGV4dCA9IFwiLi4uXCI7XG4gIHZhciBtb3JldGV4dCA9IFwiPHN2ZyBjbGFzcz0naWNvbicgdGl0bGU9Jycgdmlld0JveD0nNzAwIDQwMCAgMTAwIDEwMCc+PHVzZSB4bGluazpocmVmPScjbWFzJz48L3VzZT48L3N2Zz5cIjtcbiAgdmFyIGxlc3N0ZXh0ID0gXCI8c3ZnIGNsYXNzPSdpY29uJyB0aXRsZT0nJyB2aWV3Qm94PSc0MDAgNzAw
1ICAxMDAgMTAwJz48dXNlIHhsaW5rOmhyZWY9JyNtZW5vcyc+PC91c2U+IDwvc3ZnPlwiO1xuICB2YXIgbW9yZXMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdjb3J0YXJfdGV4dG8nKTtcbiAgZm9yKHZhciBpID0gMDsgaSA8IG1vcmVzLmxlbmd0aDsgaSsrKXtcbiAgICB2YXIgY29udGVudCA9IG1vcmVzW2ldLmlubmVySFRNTDtcbiAgICBpZihjb250ZW50Lmxlbmd0aCA+IHNob3dDaGFyKSB7XG4gICAgICB2YXIgYyA9IGNvbnRlbnQuc3Vic3RyKDAsIHNob3dDaGFyKTtcbiAgICAgIHZhciBoID0gY29udGVudC5zdWJzdHIoc2hvd0NoYXIsIGNvbnRlbnQubGVuZ3RoIC0gc2hvd0NoYXIpOyBcbiAgICAgIHZhciBodG1sID0gJycgKyBjICsgJzxzcGFuIGNsYXNzPVwibW9yZWVsbGlwc2VzXCI+JytlbGxpcHNlc3RleHQrJyZuYnNwOzwvc3Bhbj48c3BhbiBjbGFzcz1cIm1vcmVjb250ZW50XCI+PHNwYW4+JyArIGggKyAnPC9zcGFuPjxhIGNsYXNzPVwibW9yZWxpbmtcIj4nK21vcmV0ZXh0Kyc8L2E+PC9zcGFuPic7XG4gICAgICBtb3Jlc1tpXS5pbm5lckhUTUwgPSBodG1sO1xuICAgIH1cbiAgfVxuICB2YXIgbW9yZWxpbmtzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnbW9yZWxpbmsnKTtcbiAgZm9yKHZhciBpID0gMDsgaSA8IG1vcmVsaW5rcy5sZW5ndGg7IGkrKyl7XG4gICAgbW9yZWxpbmtzW2ldLm9uY2xpY2sgPSBsaW5rQ2xpY2s7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29waWFyX2Fjb3J0YWRvcygpe1xuICB2YXIgY29waWFyX3R4dCA9IGZ1bmN0aW9uKGUpeyBcbiAgICB2YXIgZWwgPSBlLmN1cnJlbnRUYXJnZXQ7XG4gICAgdmFyIHRleHQgPSBlbC5nZXRBdHRyaWJ1dGUoXCJ0ZXh0b1wiKTtcbiAgICB2YXIgdGV4dEFyZWEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZXh0YXJlYScpO1xuICAgIHRleHRBcmVhLnNldEF0dHJpYnV0ZSgnc3R5bGUnLCd3aWR0aDoxcHg7Ym9yZGVyOjA7b3BhY2l0eTowOycpO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGV4dEFyZWEpO1xuICAgIHRleHRBcmVhLnZhbHVlID0gdGV4dDtcbiAgICB0ZXh0QXJlYS5zZWxlY3QoKTtcbiAgICBkb2N1bWVudC5leGVjQ29tbWFuZCgnY29weScpO1xuICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGV4dEFyZWEpO1xuICB9XG4gIHZhciBjb3BpYXIgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFwiY29waWFyXCIpXG4gIGZvcih2YXIgaSA9IDA7IGkgPCBjb3BpYXIubGVuZ3RoOyBpKyspe1xuICAgIGNvcGlhcltpXS5vbmNsaWNrID0gY29waWFyX3R4dDtcbiAgfVxuXG4gIHZhciBjb3BpYXJfYWNvcnRhZG8gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImNvcGlhcl9hY29ydGFkb1wiKTtcbiAgaWYgKGNvcGlhcl9hY29ydGFkbykge1xuICAgIGNvcGlhcl9hY29ydGFkby5vbmNsaWNrID0gZnVuY3Rpb24oKXtcbiAgICAgIHZhciB2YWxvciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhcnRpY3Vsb19hY29ydGFkbycpLnZhbHVlID8gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FydGljdWxvX2Fjb3J0YWRvJykudmFsdWUgOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXJ0aWN1bG9faWQnKS52YWx1ZTtcbiAgICAgIHZhciB0ZXh0QXJlYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RleHRhcmVhJyk7XG4gICAgICB0ZXh0QXJlYS5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywnd2lkdGg6MXB4O2JvcmRlcjowO29wYWNpdHk6MDsnKTtcbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGV4dEFyZWEpO1xuICAgICAgdGV4dEFyZWEudmFsdWUgPSBcImh0dHBzOi8vZWxzYWwudG8vXCIrdmFsb3I7XG4gICAgICB0ZXh0QXJlYS5zZWxlY3QoKTtcbiAgICAgIGRvY3VtZW50LmV4ZWNDb21tYW5kKCdjb3B5Jyk7XG4gICAgICBkb2
1N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKHRleHRBcmVhKTtcblxuICAgIH07XG4gIH1cbn1cblxuXG5cbnZhciBzZWd1bmRvcyA9IDA7XG52YXIgcmVsYWNpb25hZGFzID0gZmFsc2U7XG5mdW5jdGlvbiBwYWdpbmFfYWN0aXZhKCkge1xuICB2YXIgcmVwZXRpciA9IHRydWU7XG4gIGlmKGRvY3VtZW50LnZpc2liaWxpdHlTdGF0ZSA9PSBcInZpc2libGVcIikge1xuICAgIHNlZ3VuZG9zKys7XG4gIH1cbiAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJyZWxhY2lvbmFkYXNcIikubGVuZ3RoICYmIHZpc2libGUoZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcInJlbGFjaW9uYWRhc1wiKVswXSkpIHtcbiAgICByZWxhY2lvbmFkYXMgPSB0cnVlO1xuICB9XG4gIGlmIChzZWd1bmRvcyA+IDE1ICYmIHJlbGFjaW9uYWRhcyl7XG4gICAgLy8gYW5vdGFyXG4gICAgLy9jb25zb2xlLmxvZyhcImFub3RhclwiKVxuICAgIC8vYW5vdGFyX2xlY3R1cmEoKTtcbiAgICByZXBldGlyID0gZmFsc2U7XG4gIH1cbiAgaWYgKHJlcGV0aXIpIHtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7cGFnaW5hX2FjdGl2YSgpfSwgMTAwMClcbiAgfVxufVxuLy9wYWdpbmFfYWN0aXZhKClcblxuZnVuY3Rpb24gYW5vdGFyX2xlY3R1cmEoKSB7XG4gIGNvbnN0IGNzcmYgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdtZXRhW25hbWU9XCJjc3JmLXRva2VuXCJdJykuY29udGVudDtcbiAgY29uc3QgdXJsID0gXCIvYXJ0aWN1bG8vYW5vdGFyLzEyMjNcIlxuICBmZXRjaCh1cmwsIHsgbWV0aG9kOiBcIlBVVFwiLCBoZWFkZXJzOiB7ICd4LWNzcmYtdG9rZW4nOiBjc3JmIH0gfSk7XG59XG5cblxubGV0IHByb2Nlc3NTY3JvbGwgP
1SAoKSA9PiB7XG4gIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImFydGljdWxvLWNvbnRlbmlkb1wiICkpIHtcbiAgICBsZXQgZG9jRWxlbSA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgXG4gICAgICBkb2NCb2R5ID0gZG9jdW1lbnQuYm9keSxcbiAgICAgIHNjcm9sbFRvcCA9IGRvY0VsZW1bJ3Njcm9sbFRvcCddIHx8IGRvY0JvZHlbJ3Njcm9sbFRvcCddLFxuICAgICAgaGVhZGVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJoZWFkZXJcIilbMF0ub2Zmc2V0SGVpZ2h0LFxuICAgICAgaGFsZldpbmRvd0hlaWdodCA9IHdpbmRvdy5zY3JlZW4uaGVpZ2h0IC8gMyxcbiAgICAgIHNjcm9sbFN0b3AgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXJ0aWN1bG8tY29udGVuaWRvJykub2Zmc2V0SGVpZ2h0LFxuICAgICAgc2Nyb2xsQm90dG9tX29sZCA9IChkb2NFbGVtWydzY3JvbGxIZWlnaHQnXSB8fCBkb2NCb2R5WydzY3JvbGxIZWlnaHQnXSkgLSBzY3JvbGxTdG9wLCBcblxuICAgICAgc2Nyb2xsQm90dG9tID0gKHNjcm9sbFN0b3AgLSBoYWxmV2luZG93SGVpZ2h0KSwgXG4gICAgICBzY3JvbGxQZXJjZW50ID0gKHNjcm9sbFRvcCAtIGhlYWRlcikgLyBzY3JvbGxCb3R0b207XG4gICAgICBzY3JvbGxQZXJjZW50ID0gKHNjcm9sbFBlcmNlbnQgPCAwICkgPyAwIDogc2Nyb2xsUGVyY2VudDtcbiAgICAgIHNjcm9sbFBlcmNlbnQ9IHNjcm9sbFBlcmNlbnQgKiAxMDAgKyAnJSc7XG4gICAgXG4gICAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJwcm9ncmVzcy1iYXJcIikgJiYgc2Nyb2xsU3RvcCA+IDApIHtcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJwcm9ncmVzcy1iYXJcIikuc3R5bGUuc2V0UHJvcGVydHkoXCItLXNjcm9sbEFtb3VudFwiLCBzY3JvbGxQZXJjZW50KTsgXG4gICAgICB9XG4gIH1cbn1cblxuaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYXJ0aWN1bG8tY29udGVuaWRvXCIgKSkge1xuICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsIHByb2Nlc3NTY3JvbGwpO1xufVxuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInNjcm9sbF90b1wiLCAoZSkgPT4ge1xuICBlLnRhcmdldC5zY3JvbGxJbnRvVmlldygpO1xufSk7XG5cbmZ1bmN0aW9uIGhlYWRlcl9lbl9zdGlja3koKSB7XG4gIHZhciBzZW5zb3IgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLnN0aWNreS1zZW5zb3JcIilcbiAgdmFyIGhlYWRlciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJoZWFkZXJcIilcbiAgdmFyIGNvbnRlbmlkbyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjY29udGVuaWRvLXByaW5jaXBhbFwiKVxuICB2YXIgdGVtYSA9IGZhbHNlO1xuICBpZiggZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5udWJlLXRlbWFcIikpIHtcbiAgICBjb250ZW5pZG8gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLm51YmUtdGVtYVwiKVxuICAgIHRlbWEgPSB0cnVlO1xuICB9XG4gIGlmKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIuYXJ0aWN1bG8tY29udGVuaWRvXCIpKSB7XG4gICAgY29udGVuaWRvID0gZmFsc2VcbiAgfVxuICBpZihoZWFkZXIpe1xuICAgIHZhciBvYnNlcnZlciA9IG5ldyBJbnRlcnNlY3Rpb25PYnNlcnZlciggXG4gICAgICAoW2VdKSA9PiB7XG4gICAgICAgIGhlYWRlci5jbGFzc0xpc3QudG9nZ2xlKFwic3RpY2t5LWhlYWRlclwiLCBlLmludGVyc2VjdGlvblJhdGlvIDwgMSk7XG4gICAgICAgIHZhciB3ID0gd2luZG93LmlubmVyV2lkdGhcbiAgICAgICAgICB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGhcbiAgICAgICAgICB8fCBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoO1xuICAgICAgICBpZiggdyA8IDc2OCAmJiBjb250ZW5pZG8gJiYgZS5pbnRlcnNlY3Rpb25SYXRpbyA8IDEpe1xuICAgICAgICAgIGNvbnRlbmlkby5zdHlsZS5wYWRkaW5nVG9wID0gYCR7aGVhZGVyLmNsaWVudEhlaWdodH1weGA7XG4gICAgICAgIH0gZWxzZSBpZiAoY29udGVuaWRvICYmICF0ZW1hKXtcbiAgICAgICAgICBjb250ZW5pZG8uc3R5bGUucGFkZGluZ1RvcCA9ICAwO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgeyB0aHJlc2hvbGQ6IFsxXSB9XG4gICAgKTtcbiAgICBvYnNlcnZlci5vYnNlcnZlKHNlbnNvcik7XG5cbiAgfVxufVxuXG52YXIgcmV1YmljYXJfcmVzdW1lbmVzX2FydGljdWxvcyA9IGZhbHNlO1xuZnVuY3Rpb24gcmV1YmljYXJfcmVzdW1lbmVzX2FydGljdWxvKCl7XG4gIGlmKHJldWJpY2FyX3Jlc3VtZW5lc19hcnRpY3Vsb3MgPT09IGZhbHNlKXtcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdbZGF0YS1hcnRpY3Vsby1yZXN1bWVuXScpXG4gICAgICAuZm9yRWFjaCgocmVzdW1lbikgPT4geyBcbiAgICAgIHZhciBpZCA9IHJlc3VtZW4uZGF0YXNldC5hcnRpY3Vsb1Jlc3VtZW47XG4gICAgICB2Y
1XIgdWJpY2FjaW9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYHViaWNhY2lvbl9hcnRpY3Vsb18ke2lkfWApO1xuICAgICAgdmFyIGFydGljdWxvID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYG1vdmVyX3ViaWNhY2lvbl8ke2lkfWApO1xuICAgICAgdWJpY2FjaW9uLnJlcGxhY2VXaXRoKGFydGljdWxvKTtcbiAgICAgIHJldWJpY2FyX3Jlc3VtZW5lc19hcnRpY3Vsb3MgPSBmYWxzZVxuICAgIH0pO1xuICB9XG59XG5cbiAgXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignb3JpZW50YXRpb25jaGFuZ2UnLCBjYW1iaW9fbWVkaWRhcyk7XG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsIGNhbWJpb19tZWRpZGFzKTtcbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCBwdWJsaV92ZXJzaW9uKVxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIGNhbWJpb19tZWRpZGFzKTtcblxuZnVuY3Rpb24gY2FtYmlvX21lZGlkYXMoKXtcbiAgbWVkaWRhcygpXG4gIHB1YmxpX3ZlcnNpb25fY2FtYmlvKClcbiAgYXBhbmhvc19pbWFnZW5lc19hcnRpY3Vsb3MoKTtcbn1cblxudmFyIHB1YmxpX3ZlcnNpb25fYWN0dWFsID0gXCJcIjtcbmZ1bmN0aW9uIHB1YmxpX3ZlcnNpb24oKSB7XG4gIHZhciB3ID0gd2luZG93LmlubmVyV2lkdGhcbiAgICB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGhcbiAgICB8fCBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoO1xuICB3IDw9IDc2OCA/IHB1YmxpX3ZlcnNpb25fYWN0dWFsID0gXCJtb2JpbFwiIDogcHVibGlfdmVyc2lvbl9hY3R1YWwgPSBcImVzY3JpdG9yaW9cIlxufVxuZnVuY3Rpb24gcHVibGlfdmVyc2lvbl9jYW1iaW8oKSB7XG4gIHZhciBhbnRlcmlvciA9IHB1YmxpX3ZlcnNpb25fYWN0dWFsXG4gIHB1YmxpX3ZlcnNpb24oKVxuICBwdWJsaV92ZXJzaW9uX2FjdHVhbCA9PSBhbnRlcmlvciA/IHRydWUgOiByZXViaWNhcl9wdWJsaXModHJ1ZSlcbn1cblxuZnVuY3Rpb24gbGFuemFyX3NjcmlwdHMoKXtcbiAgbGFuemFyX2NvZGlnb3NfZW1iZWJpZG9zKClcbiAgLy9jb25zb2xlLmxvZyhcIkxBTlpBTkRPIFNDUklQVFNTU1NcIilcbiAgdmFyIGVudHJhZGlsbGEgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI2VudHJhZGlsbGEyXCIpO1xuICBpZiAoZW50cmFkaWxsYSl7XG4gICAgdmFyIGluZm9ncmFmaWEgPSBlbnRyYWRpbGxhLmlubmVySFRNTFxuXG4gICAgZW50cmFkaWxsYS5pbm5lckhUTUwgPSBcIlwiXG4gICAgaWYoaW5mb2dyYWZpYSkgcG9zdHNjcmliZShcIiNlbnRyYWRpbGxhMlwiLCBpbmZvZ3JhZmlhKVxuICB9XG5cbiAgdmFyIGZsb3VyaXNoID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5mbG91cmlzaC1lbWJlZFwiKTtcbiAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIuZmxvdXJpc2gtZW1iZWQgaWZyYW1lXCIpKXtcbiAgICBmbG91cmlzaCA9IGZhbHNlXG4gIH0gZWxzZSB7XG4gICAgZmxvdXJpc2ggPSBmbG91cmlzaFxuICB9XG4gIGlmIChmbG91cmlzaCl7XG4gICAgd2luZG93LkZsb3VyaXNoTG9hZGVkID0gbnVsbFxuICAgIGNvbnN0IHNjcmlwdF9mbG91cmlzaCA9IFwiPHNjcmlwdCBzcmM9J2h0dHBzOi8vcHVibGljLmZsb3VyaXNoLnN0dWRpby9yZXNvdXJjZXMvZW1iZWQuanMnPjwvc2NyaXB0PlwiO1xuICAgIHBvc3RzY3JpYmUoXCIjVWJpY2FjaW9uU2NyaXB0c1wiLCBzY3JpcHRfZmxvdXJpc2gpXG4gICAgLy9jb25zb2xlLmxvZyhcIiEhISEhISEhISEhISEhISEhISEhXCIpXG4gIH1cbn1cblxudmFyIGVqZWN1dGFkb3NfZW1iZWJpZG9zID0gZmFsc2U7XG5mdW5jdGlvbiBsYW56YXJfY29kaWdvc19lbWJlYmlkb3MoKXtcbiAgaWYoZWplY3V0YWRvc19lbWJlYmlkb3MgPT09IGZhbHNlKXtcbiAgICBlamVjdXRhZG9zX2VtYmViaWRvcyA9IHRydWVcbiAgICB2YXIgZW1iZWRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIi5lbWJlZF9kYXRhXCIpO1xuICAgIGZvcih2YXIgaSA9IDA7IGkgPCBlbWJlZHMubGVuZ3RoOyBpKyspe1xuICAgICAgdmFyIGVtYmVkID0gZW1iZWRzW2ldLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiY29kaWdvXCIpWzBdO1xuICAgICAgdmFyIGlkID0gZW1iZWRzW2ldLmdldEF0dHJpYnV0ZShcIm1vdmVfdG9cIilcbiAgICAgIC8vY29uc29sZS5sb2coXCJhcXVpIFwiKyBpZClcbiAgICAgIHZhciB0byA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTtcbiAgICAgIC8vY29uc29sZS5sb2codG8pXG4gICAgICAvL2NvbnNvbGUubG9nKGNvZGlnbylcbiAgICAgIHZhciBjb2RpZ28gPSBkZWNvZGVVUkkoZW1iZWQuZ2V0QXR0cmlidXRlKFwiY29kaWdvXCIpKVxuICAgICAgaWYgKHRvLmlubmVySFRNTCA9PT0gXCJcIil7XG4gICAgICAgIHRvLmlubmVySFRNTCA9IFwiPHNwYW4+PC9zcGFuPlwiXG4gICAgICAgIHBvc3RzY3JpYmUoXCIjXCIraWQsIGNvZGlnbylcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbnZhciBlamVjdXRhZG9zX2xpbWl0YWRvcyA9IGZhbHNlO1xuZnVuY3Rpb24gbGltaXRhZG9zKCl7XG4gIGlmKGVqZWN1dGFkb3NfbGltaXRhZG9zID09PSBmYWxzZSl7XG4gICAgZWplY3V0YWRvc19saW1pdGFkb3MgPSB0cnVlO1xuICAgIHZhciBsaW1pdGFkb3MgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmxpbWl0YWRvXCIpO1xuICAgIGxpbWl0YWRvcyA9IEFycmF5LmZyb20obGltaXRhZG9zKS5maWx0ZXIoZWwgPT4gIWVsLmNsb3Nlc3QoJy5zb2NpYXNfb3BpbmlvbicpKTtcblxuICAgIHZhciB3ID0gd2luZG93LmlubmVyV2lkdGhcbiAgICAgIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aFxuICAgICAgfHwgZG9jdW1lbnQuYm9keS5jbGllbnRXaWR0aDtcblxuICAgIGlmICh3ID4gNzY4KXtcbiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBsaW1pdGFkb3MubGVuZ3RoOyBpKyspe1xuICAgICAgICB2Y
1XIgbGltaXRhZG8gPSBsaW1pdGFkb3NbaV07XG4gICAgICAgIGxpbWl0YWRvLnBhcmVudE5vZGUuY2xhc3NMaXN0LmFkZChcImxpbWl0YXJcIilcbiAgICAgICAgaWYgKChsaW1pdGFkby5zY3JvbGxIZWlnaHQpID4gbGltaXRhZG8uY2xpZW50SGVpZ2h0IHx8IGxpbWl0YWRvLnNjcm9sbFdpZHRoID4gbGltaXRhZG8uY2xpZW50V2lkdGgpIHtcbiAgICAgICAgICBsaW1pdGFkby5wYXJlbnROb2RlLmNsYXNzTGlzdC5hZGQoXCJsaW1pdGFyXCIpO1xuICAgICAgICB9ZWxzZXtcbiAgICAgICAgICBsaW1pdGFkby5wYXJlbnROb2RlLmNsYXNzTGlzdC5yZW1vdmUoXCJsaW1pdGFyXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsaW1pdGFkby5zY3JvbGxIZWlnaHQgPj0gMzApIHtcbiAgICAgICAgICBsaW1pdGFkby5wYXJlbnROb2RlLmNsYXNzTGlzdC5hZGQoXCJsaW1pdGFyXCIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUlBO0FBSUE7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBRUE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7OztBQ2xEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFFQTtBQUNBLDRCQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBR0E7QUFJQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7Ozs7Ozs7QUMzSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU9BO0FBQ0E7Ozs7OztBQzluREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQ
1TtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ
1UNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO
10FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBT0E7QUFDQTs7O0FDM25PQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ
10E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Q
1UFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBOzs7QUNqa0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFJQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFVQTtBQUNBO0FBTUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFLQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFRQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQUE7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBR0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO
10FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQVdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBSUE7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBSUE7QUFDQTtBQUdBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///17\n')},587:()=>{eval("$(document).ready(function () {\n $(\"#articulo_user_id\").each(function () {\n $(this).select2();\n });\n});\n$('select#publicacion_digital_tema_id, select#articulo_publicacion_tema_id, select#publicacion_tema_id, select#articulo_tema_id, select#articulo_temas , select#tema_parents, select#foto_temas, select#multimedia_temas, select#galer
1ia_temas, select.temas').each(function () {\n $(this).select2({\n placeholder: 'Buscar temas',\n minimumInputLength: 3,\n allowClear: true,\n cache: true,\n ajax: {\n delay: 250,\n url: function (params) {\n return '/api/temas/' + params.term;\n },\n dataType: 'json',\n processResults: function (data, params) {\n return {\n results: data.data\n };\n }\n }\n });\n});\n$('select#search_foto_tema_id').each(function () {\n $(this).select2({\n placeholder: 'Buscar temas',\n minimumInputLength: 3,\n allowClear: true,\n cache: true,\n ajax: {\n delay: 250,\n url: function (params) {\n return '/api/temas/' + params.term + '/todos';\n },\n dataType: 'json',\n processResults: function (data, params) {\n return {\n results: data.data\n };\n }\n }\n });\n});\n$('select#articulo_autores, select#foto_autores, select#search_foto_autor_id, select#multimedia_autores, select#galeria_autores, select.autores').each(function () {\n $(this).select2({\n placeholder: 'Nombre a buscar',\n minimumInputLength: 3,\n allowClear: true,\n cache: true,\n ajax: {\n delay: 250,\n url: function (params) {\n return '/api/autores/' + params.term;\n },\n dataType: 'json',\n processResults: function (data, params) {\n return {\n results: data.data\n };\n }\n }\n });\n});\nfunction hacer_anuncios_seleccionable() {\n $('select.anuncios').each(function (i, sel) {\n anuncio_seleccionable(sel);\n });\n}\nfunction anuncio_seleccionable(sel) {\n $(sel).select2({\n placeholder: 'Nombre a buscar',\n minimumInputLength: 2,\n allowClear: true,\n cache: true,\n ajax: {\n delay: 250,\n url: function (params) {\n return '/api/anuncios/' + params.term;\n },\n dataType: 'json',\n processResults: function (data, params) {\n return {\n results: data.data\n };\n }\n }\n });\n $(sel).on('change', function () {\n var titulo = $(this).find('option:selected').text();\n $(this).parent().parent().find('.anuncio_t').val(titulo);\n });\n}\nhacer_anuncios_seleccionable();\nfunction fotos() {\n $('select#publicacion_foto_id, select#articulo_foto_id, select#articulo_foto_portada_id, select#doc_interno_foto_id, select#acceso_foto_id, select#formulario_fondo_id, select.foto').each(function () {\n $(this).select2({\n placeholder: 'Buscar foto',\n minimumInputLength: 3,\n allowClear: true,\n cache: true,\n ajax: {\n delay: 250,\n url: function (params) {\n return '/api/fotos/' + params.term;\n },\n dataType: 'json',\n processResults: function (data, params) {\n return {\n results: data.data\n };\n }\n }\n });\n });\n}\nfotos();
1\nfunction galerias() {\n $('select.galeria').each(function () {\n $(this).select2({\n placeholder: 'Buscar galerÃa',\n minimumInputLength: 3,\n allowClear: true,\n cache: true,\n ajax: {\n delay: 250,\n url: function (params) {\n return '/api/galerias/' + params.term;\n },\n dataType: 'json',\n processResults: function (data, params) {\n return {\n results: data.data\n };\n }\n }\n });\n });\n}\ngalerias();\nfunction multimedias() {\n $('select.multimedia').each(function () {\n $(this).select2({\n placeholder: 'Buscar multimedia',\n minimumInputLength: 3,\n allowClear: true,\n cache: true,\n ajax: {\n delay: 250,\n url: function (params) {\n return '/api/multimedia/' + params.term;\n },\n dataType: 'json',\n processResults: function (data, params) {\n return {\n results: data.data\n };\n }\n }\n });\n });\n}\nmultimedias();\n$('.articulo_s').each(function (i, sel) {\n articulo_seleccionable(sel);\n});\nfunction hacer_articulos_seleccionables() {\n $('.articulo_s').each(function (i, sel) {\n articulo_seleccionable(sel);\n });\n}\nfunction articulo_seleccionable(sel) {\n $(sel).select2({\n placeholder: 'Buscar artÃculo',\n minimumInputLength: 3,\n allowClear: true,\n cache: true,\n ajax: {\n delay: 250,\n url: function (params) {\n return '/api/articulos/' + params.term;\n },\n dataType: 'json',\n processResults: function (data, params) {\n return {\n results: data.data\n };\n }\n }\n });\n $(sel).on('change', function () {\n var titulo = $(this).find('option:selected').text();\n $(this).parent().parent().find('.articulo_t').val(titulo);\n });\n}\n;\n$('.articulo_s_todos').each(function (i, sel) {\n articulo_seleccionable_todos(sel);\n});\nfunction hacer_articulos_todos_seleccionables() {\n $('.articulo_s_todos').each(function (i, sel) {\n articulo_seleccionable_todos(sel);\n });\n}\nfunction articulo_seleccionable_todos(sel) {\n $(sel).select2({\n placeholder: 'Buscar artÃculo',\n minimumInputLength: 3,\n allowClear: true,\n cache: true,\n ajax: {\n delay: 250,\n url: function (params) {\n return '/api/articulos_todos/' + params.term;\n },\n dataType: 'json',\n processResults: function (data, params) {\n return {\n results: data.data\n };\n }\n }\n });\n $(sel).on('change', function () {\n var titulo = $(this).find('option:selected').text();\n $(this).parent().parent().find('.articulo_t').val(titulo);\n });\n}\n;\n$(document).on('click', '.anhadir_articulo_pub_digi', function (e) {\n e.preventDefault();\n let time = new Date().getTime();\n let template = $(this).data(\"template\");\n var tipo = $(this).parent().find(\".nombre\").find(\".atopame\").length;\n if (tipo > 0) {\n var id = $(this).parent().find(\".nombre\").find(\".atopame\").eq(0).attr(\"id\");\n id = id.split('_')[2];\n } else {\n var id = $(this).parent().find(\".nombre\").find(\".atopame2\").eq(0).attr(\"id\");\n id = id.split('_')[3];\n }\n var uniq_template = template.replace(/articulos\\]\\[0\\]/g, `articulos][${time}]`).replace(/colas\\]\\[0\\]/g, `colas][${id}]`).replace(/apartados\\]\\[0\\]/g, `apartados][${id}]`).replace(/articulos_0_/g, `articulos_${time}_`).replace(/colas_0_/g, `colas_${id}_`).replace(/apartados_0_/g, `apartados_${id}_`);\n var contenedor_original = this.parentNode.querySelector(\".entradas\").cloneNode(true);\n var articulos_original = contenedor_original.querySelectorAll(\"tr\");\n $(this).parent().find(\".entradas\").prepend(uniq_template);\n //$(this).parent().find(\".fila\").eq(0).before(uniq_template);\n hacer_articulos_seleccionables();\n hacer_articulos_todos_seleccionables();\n var ubicacion = $('#portada_ubicacion').val();\n $('.form-apartado-nuevo .portada_ubicacion').val(ubicacion);\n});\n// \n// Gestión de colas\n$(document).on('click', '.anhadir_articulo', function (e) {\n e.preventDefault();\n let time = new Date().getTime();\n let template = $(this).data(\"template\");\n var tipo = $(this).parent().find(\".nombre\").find(\".atopame\").length;\n if (tipo > 0) {\n var id = $(this).parent().find(\".nombre\").find(\".atopame\").eq(0).attr(\"id\");\n id = id.split('_')[2];\n } else {\n var id = $(this).parent().find(\".nombre\").find(\".atopame2\").eq(0).attr(\"id\");\n id = id.split('_')[3];\n }\n var uniq_template = template.replace(/articulos\\]\\[0\\]/g, `articulos][${time}]`).replace(/colas\\]\\[0\\]/g, `colas][${id}]`).replace(/apartados\\]\\[0\\]/g, `apartados][${id}]`).replace(/articulos_0_/g, `articulos_${time}_`).replace(/colas_0_/g, `colas_${id}_`).replace(/apartados_0_/g, `apartados_${id}_`);\n var contenedor_original = this.parentNode.querySelector(\".entradas\").cloneNode(true);\n var articulos_original = contenedor_original.querySelectorAll(\"tr\");\n var elemento = $(this).parent().find(\".entradas\").prepend(uniq_template);\n\n //$(this).parent().find(\".fila\").eq(0).before(uniq_template);\n hacer_articulos_seleccionables();\n hacer_articulos_todos_seleccionables();\n var ubicacion = $('#portada_ubicacion').val();\n $('.form-apartado-nuevo .portada_ubicacion').val(ubicacion);\n var contenedor = this.parentNode.querySelector(\".entradas\");\n var articulos = contenedor.querySelectorAll(\"tr\");\n contenedor.innerHTML = \"\";\n articulos = ordenar_array_con_fijos(articulos_original, articulos);\n articulos.forEach(function (e, i, a) {\n contenedor.appendChild(e);\n });\n normalizar_cola(contenedor);\n ordenar_cola(contenedor);\n normalizar_cola(contenedor);\n botones_arriba_abajo_colas();\n});\nfunction ordenar_array_con_fijos(original, nuevo) {\n var normales = [...nuevo].filter(e => !e.querySelector(\".chincheta .form-control\").checked);\n var normal_i = 0;\n var l = nuevo.length;\n nuevo = [];\n for (let i = 0; i < l;
1 i++) {\n if (original[i] && original[i].querySelector(\".chincheta .form-control\").checked) {\n nuevo[i] = original[i];\n } else {\n nuevo[i] = normales[normal_i];\n ++normal_i;\n }\n }\n return nuevo;\n}\nfunction ordenar_cola(contenedor) {\n var articulos = contenedor.querySelectorAll(\"tr\");\n articulos = Array.from(articulos).sort(function (a, b) {\n //if (a.querySelector(\".chincheta .form-control\").checked){return - 1};\n //if (b.querySelector(\".chincheta .form-control\").checked){return + 1};\n a = a.querySelector(\".orden .form-control\").value;\n b = b.querySelector(\".orden .form-control\").value;\n return a - b;\n });\n //.forEach(el =>{ contenedor.appendChild(el) })\n\n contenedor.innerHTML = \"\";\n articulos.forEach(function (e, i, a) {\n contenedor.appendChild(e);\n });\n}\nfunction normalizar_cola(contenedor) {\n var articulos = contenedor.querySelectorAll(\"tr\");\n articulos.forEach(function (e, i, a) {\n orden = e.querySelector(\".orden .form-control\");\n orden.value = (i + 1) * 10;\n });\n}\nvar arriba = function (event) {\n event.preventDefault();\n event.stopPropagation();\n var orden = this.parentNode.parentNode.querySelector(\".orden .form-control\");\n orden.value = parseInt(orden.value) - 15;\n var contenedor = this.parentNode.parentNode.parentNode;\n ordenar_cola(contenedor);\n normalizar_cola(contenedor);\n};\nvar abajo = function (event) {\n event.preventDefault();\n event.stopPropagation();\n var orden = this.parentNode.parentNode.querySelector(\".orden .form-control\");\n orden.value = parseInt(orden.value) + 15;\n var contenedor = this.parentNode.parentNode.parentNode;\n ordenar_cola(contenedor);\n normalizar_cola(contenedor);\n};\nfunction botones_arriba_abajo_colas() {\n var upButtons = document.querySelectorAll('.ordenar .up');\n var downButtons = document.querySelectorAll('.ordenar .down');\n for (var i = 0; i < upButtons.length; i++) {\n upButtons[i].removeEventListener('click', arriba);\n }\n for (var i = 0; i < downButtons.length; i++) {\n downButtons[i].removeEventListener('click', abajo);\n }\n for (var i = 0; i < upButtons.length; i++) {\n upButtons[i].addEventListener('click', arriba);\n }\n for (var i = 0; i < downButtons.length; i++) {\n downButtons[i].addEventListener('click', abajo);\n }\n}\nbotones_arriba_abajo_colas();\n$(document).on('click', '#anhadir_seccion', function (e) {\n e.preventDefault();\n let time = new Date().getTime();\n let template = $(this).data(\"template\");\n var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n $(this).parent().after(uniq_template);\n fotos();\n galerias();\n multimedias();\n});\n\n// Gestión de apartados pub digital\n$(document).on('click', '#anhadir_seccion_pub_dig', function (e) {\n e.preventDefault();\n let time = new Date().getTime();\n let template = $(this).data(\"template\");\n var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n $(this).before(uniq_template);\n});\n$(document).on('click', '#anhadir_apartado', function (e) {\n e.preventDefault();\n let time = new Date().getTime();\n let template = $(this).data(\"template\");\n var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n $(this).before(uniq_template);\n $('.summernote').summernote();\n fotos();\n hacer_articulos_todos_seleccionables();\n hacer_anuncios_seleccionable();\n});\n$(document).on('click', '#anhadir_foto_archivo', function (e) {\n e.preventDefault();\n let time = new Date().getTime();\n let template = $(this).data(\"template\");\n var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n $(this).parent().before(uniq_template);\n fotos();\n});\n// Secciones articulo\n$(document).on('click', '#anhadir_seccion_articulo', function (e) {\n e.preventDefault();\n let time = new Date().getTime();\n let template = $(this).data(\"template\");\n var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n //$(this).parent().before(uniq_template);\n $(this).before(uniq_template);\n $('.summernote').summernote();\n fotos();\n multimedias();\n galerias();\n});\n$(document).on('click', '#anhadir_traduccion', function (e) {\n e.preventDefault();\n let time = new Date().getTime();\n let template = $(this).data(\"template\");\n var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n $(this).parent().before(uniq_template);\n hacer_articulos_seleccionables();\n hacer_articulos_todos_seleccionables();\n});\n$(document).on('click', '#anhadir_link', function (e) {\n e.preventDefault();\n let time = new Date().getTime();\n let template = $(this).data(\"template\");\n var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n $(this).parent().before(uniq_template);\n});\n$(document).on('click', '#anhadir_menu', function (e) {\n e.preventDefault();\n let time = new Date().getTime();\n let template = $(this).data(\"template\");\n var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n $(this).parent().before(uniq_template);\n});\n$(document).on('click', '#anhadir_comentario', function (e) {\n e.preventDefault();\n let time = new Date().getTime();\n let template = $(this).data(\"template\");\n var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n $(this).parent().before(uniq_template);\n cambio();\n actualizarCSRF();\n});\n$(document).on('click', '.comentar-comentario', function (e) {\n var comentario_id = $(this).attr('data-comentario');\n e.preventDefault();\n let time = new Date().getTime();\n let template = $('#anhadir_comentario').data(\"template\");\n var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n $(\"#anhadir_comentario\").parent().before(uniq_template);\n $('#comentario_comentario_id').val(comentario_id);\n cambio();\n actualizarCSRF();\n});\n$(document).on('click', '#anhadir_tipo', function (e) {\n e.preventDefault();\n let time = new Date().getTime();\n let template = $(this).data(\"template\");\n var uniq_template = template.replace(/\\[0\\]/g, `[${time}]`);\n uniq_template = uniq_template.replace(/_0_/g, `_${time}_`);\n $(this).parent().before(uniq_template);\n $('.summernote').summernote();\n});\nfunction cambio() {\n if ($('#articulo-completo').length) {\n var token = $('#articulo-completo').attr(\"data-token\");\n $('#articulo-completo input[name=\"_csrf_token\"]').each(function () {\n $(this).val(token);\n });\n }\n}\n$(document).on('click', '.borrar_seccion', function (e) {\n e.preventDefault();\n $(this).parent().parent().remove();\n});\n$(document).on('click', '.anular-comentario', function (e) {\n $('.box').remove();\n});\nfunction ImagenUpdate(obj) {\n if (!window.FileReader) {} else {\n var reader = new FileReader();\n var target = null;\n reader.onload = function (e) {\n target = e.target || e.srcElement;\n $(obj).parent().parent().find(\".preview\").prop(\"src\", target.result);\n $(obj).parent().parent().find(\".preview\").removeClass(\"hidden\");\n };
1\n reader.readAsDataURL(obj.files[0]);\n }\n}\n;\n$(document).on('change', 'input.preview', function () {\n ImagenUpdate(this);\n});\n\n//wysiwyg\n$(document).ready(function () {\n if (typeof $('.summernote').summernote === \"function\") {\n $('.summernote').summernote({\n styleWithSpan: false,\n lang: 'es-ES',\n height: 400,\n dialogsFade: true,\n toolbar: [['style', ['bold', 'italic', 'underline', 'clear']], ['font', ['strikethrough', 'superscript', 'subscript']], ['para', ['ul', 'ol', 'paragraph']], ['link', ['style']], ['insert', ['picture', 'video', 'link', 'unlink']], ['salto', ['articulo', 'foto', 'codigo', 'borrar']], ['view', ['codeview']], ['insert', ['template']]],\n popover: {\n image: [['custom', ['imageAttributes', 'captionIt']], ['imagesize', ['imageSize100', 'imageSize50', 'imageSize25']], ['float', ['floatLeft', 'floatRight', 'floatNone']], ['remove', ['removeMedia']]]\n },\n imageAttributes: {\n imageDialogLayout: 'default',\n // default|horizontal\n icon: '<i class=\"note-icon-pencil\"/>',\n removeEmpty: false // true = remove attributes | false = leave empty if present\n },\n displayFields: {\n imageBasic: true,\n // show/hide Title, Source, Alt fields\n imageExtra: true,\n // show/hide Alt, Class, Style, Role fields\n linkBasic: true,\n // show/hide URL and Target fields for link\n linkExtra: false // show/hide Class, Rel, Role fields for link\n },\n captionIt: {\n icon: '<i class=\"note-icon-pencil\"}/>',\n // Leave empty or don't set for default Icon.\n figureClass: 'figure-interna',\n figcaptionClass: 'pie'\n },\n cleaner: {\n notTime: 500,\n // Time to display Notifications.\n action: 'both',\n // both|button|paste 'button' only cleans via toolbar button, 'paste' only clean when pasting content, both does both options.\n newline: '<br>',\n // Summernote's default is to use '<p><br></p>'\n notStyle: 'position:absolute;top:0;left:0;right:0',\n // Position of Notification\n icon: '<i class=\"note-icon\">[x]</i>',\n keepHtml: true,\n // Remove all Html formats\n keepClasses: false,\n // Remove Classes\n keepOnlyTags: ['<br>', '<a>', '<p>'],\n // If keepHtml is true, remove all tags except these\n badTags: ['style', 'script', 'applet', 'embed', 'noframes', 'n
1oscript', 'html'],\n // Remove full tags with contents\n badAttributes: ['dir', 'id', 'style', 'start', 'name', 'class', 'align', 'ontouchstart'] // Remove attributes from remaining tags\n },\n template: {\n path: '/js/summernote/tpls',\n list: {\n 'recuadro_generico': 'Recuadro genérico',\n 'recuadro_dcha': 'Recuadro derecho',\n 'recuadro_izq': 'Recuadro izquierdo',\n 'recuadro': 'Recuadro \"antiguo\"'\n }\n }\n });\n }\n});\n////\n\n;\n(function ($, window, document, undefined) {\n $.fn.doubleTapToGo = function (params) {\n if (!('ontouchstart' in window) && !navigator.msMaxTouchPoints && !navigator.userAgent.toLowerCase().match(/windows phone os 7/i)) return false;\n this.each(function () {\n var curItem = false;\n $(this).on('click', function (e) {\n var item = $(this);\n if (item[0] != curItem[0]) {\n e.preventDefault();\n curItem = item;\n }\n });\n $(document).on('click touchstart MSPointerDown', function (e) {\n var resetItem = true,\n parents = $(e.target).parents();\n for (var i = 0; i < parents.length; i++) if (parents[i] == curItem[0]) resetItem = false;\n if (resetItem) curItem = false;\n });\n });\n return this;\n };\n})(jQuery, window, document);\n$('.cambiarNodoPortada ul').doubleTapToGo();\n$(\".buscar\").hover(function () {\n $(this).find(\".form-control\").focus();\n});\n$(document).ready(function () {\n $('.index-listados').each(function () {\n var url = $(this).attr('data-path');\n var total = $('.index-listados .page-link').length - 1;\n $('.index-listados .page-link').each(function (i) {\n $(this).attr('href', $(this).attr('href').replace(/\\/\\w*\\?+/g, url + \"?\"));\n });\n if (total > 11) {\n var index = $('.index-listados .page-item').index($('.index-listados .page-item.active'));\n var medio = Math.round(total / 2);\n var c1 = Math.round(total / 4);\n var c2 = Math.round(total / 4 * 3);\n var i1 = index - 1;\n var i2 = index + 1;\n var array = [0, 1, total - 1, c1, medio, c2, i1, index, i2, total];\n $('.index-listados .page-item').each(function (i) {\n if ($.inArray(i, array) == -1) {\n $(this).remove();\n }\n });\n }\n });\n});\nfunction enviarContactoForm(data) {\n var XHR = new XMLHttpRequest();\n var FD = new FormData(document.getElementById('formularioContacto'));\n var csrf = document.querySelector(\"meta[name=csrf-token]\").content;\n //var formData = JSON.stringify(data);\n\n for (name in data) {\n FD.append(name, data[name]);\n }\n XHR.addEventListener('load', function (event) {\n alert('Yeah! Data sent and response loaded.');\n });\n XHR.addEventListener('error', function (event) {\n alert('Oops! Something went wrong.');\n });\n\n //XHR.open('POST', 'https://example.com/');\n XHR.open('POST', 'http://127.0.0.1:4000/');\n XHR.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\n XHR.setRequestHeader(\"X-CSRF-Token\", csrf);\n XHR.send(FD);\n //XHR.send( \"formulario=\"+formData );\n}\nfunction actualizarCSRF() {\n var csrf = document.querySelector('meta[name=\"csrf-token\"]').content;\n var inputs = document.querySelectorAll(\"input[name='_csrf_token']\");\n for (var i = 0; i < inputs.length; ++i) {\n inputs[i].value = csrf;\n }\n}\n$(document).ready(function () {\n actualizarCSRF();\n});\n$('#ComentariosCuenta').on('show.bs.modal', function (event) {\n var button = $(event.relatedTarget);\n var url = button.data('url');\n var modal = $(this);\n var q = modal.find('.con_redireccion');\n modal.find('.con_redireccion').attr(\"href\", \"/comentar\" + url);\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTg3LmpzIiwibmFtZXMiOlsiJCIsImRvY3VtZW50IiwicmVhZHkiLCJlYWNoIiwic2VsZWN0MiIsInBsYWNlaG9sZGVyIiwibWluaW11bUlucHV0TGVuZ3RoIiwiYWxsb3dDbGVhciIsImNhY2hlIiwiYWpheCIsImRlbGF5IiwidXJsIiwicGFyYW1zIiwidGVybSIsImRhdGFUeXBlIiwicHJvY2Vzc1Jlc3VsdHMiLCJkYXRhIiwicmVzdWx0cyIsImhhY2VyX2FudW5jaW9zX3NlbGVjY2lvbmFibGUiLCJpIiwic2VsIiwiYW51bmNpb19zZWxlY2Npb25hYmxlIiwib24iLCJ0aXR1bG8iLCJmaW5kIiwidGV4dCIsInBhcmVudCIsInZhbCIsImZvdG9zIiwiZ2FsZXJpYXMiLCJtdWx0aW1lZGlhcyIsImFydGljdWxvX3NlbGVjY2lvbmFibGUiLCJoYWNlcl9hcnRpY3Vsb3Nfc2VsZWNjaW9uYWJsZXMiLCJhcnRpY3Vsb19zZWxlY2Npb25hYmxlX3RvZG9zIiwiaGFjZXJfYXJ0aWN1bG9zX3RvZG9zX3NlbGVjY2lvbmFibGVzIiwiZSIsInByZXZlbn
1REZWZhdWx0IiwidGltZSIsIkRhdGUiLCJnZXRUaW1lIiwidGVtcGxhdGUiLCJ0aXBvIiwibGVuZ3RoIiwiaWQiLCJlcSIsImF0dHIiLCJzcGxpdCIsInVuaXFfdGVtcGxhdGUiLCJyZXBsYWNlIiwiY29udGVuZWRvcl9vcmlnaW5hbCIsInBhcmVudE5vZGUiLCJxdWVyeVNlbGVjdG9yIiwiY2xvbmVOb2RlIiwiYXJ0aWN1bG9zX29yaWdpbmFsIiwicXVlcnlTZWxlY3RvckFsbCIsInByZXBlbmQiLCJ1YmljYWNpb24iLCJlbGVtZW50byIsImNvbnRlbmVkb3IiLCJhcnRpY3Vsb3MiLCJpbm5lckhUTUwiLCJvcmRlbmFyX2FycmF5X2Nvbl9maWpvcyIsImZvckVhY2giLCJhIiwiYXBwZW5kQ2hpbGQiLCJub3JtYWxpemFyX2NvbGEiLCJvcmRlbmFyX2NvbGEiLCJib3RvbmVzX2FycmliYV9hYmFqb19jb2xhcyIsIm9yaWdpbmFsIiwibnVldm8iLCJub3JtYWxlcyIsImZpbHRlciIsImNoZWNrZWQiLCJub3JtYWxfaSIsImwiLCJBcnJheSIsImZyb20iLCJzb3J0IiwiYiIsInZhbHVlIiwib3JkZW4iLCJhcnJpYmEiLCJldmVudCIsInN0b3BQcm9wYWdhdGlvbiIsInBhcnNlSW50IiwiYWJham8iLCJ1cEJ1dHRvbnMiLCJkb3duQnV0dG9ucyIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJhZGRFdmVudExpc3RlbmVyIiwiYWZ0ZXIiLCJiZWZvcmUiLCJzdW1tZXJub3RlIiwiY2FtYmlvIiwiYWN0dWFsaXphckNTUkYiLCJjb21lbnRhcmlvX2lkIiwidG9rZW4iLCJyZW1vdmUiLCJJbWFnZW5VcGRhdGUiLCJvYmoiLCJ3aW5kb3ciLCJGaWxlUmVhZGVyIiwicmVhZGVyIiwidGFyZ2V0Iiwib25sb2FkIiwic3JjRWxlbWVudCIsInByb3AiLCJyZXN1bHQiLCJyZW1vdmVDbGFzcyIsInJlYWRBc0RhdGFVUkwiLCJmaWxlcyIsInN0eWxlV2l0aFNwYW4iLCJsYW5nIiwiaGVpZ2h0IiwiZGlhbG9nc0ZhZGUiLCJ0b29sYmFyIiwicG9wb3ZlciIsImltYWdlIiwiaW1hZ2VBdHRyaWJ1dGVzIiwiaW1hZ2VEaWFsb2dMYXlvdXQiLCJpY29uIiwicmVtb3ZlRW1wdHkiLCJkaXNwbGF5RmllbGRzIiwiaW1hZ2VCYXNpYyIsImltYWdlRXh0cmEiLCJsaW5rQmFzaWMiLCJsaW5rRXh0cmEiLCJjYXB0aW9uSXQiLCJmaWd1cmVDbGFzcyIsImZpZ2NhcHRpb25DbGFzcyIsImNsZWFuZXIiLCJub3RUaW1lIiwiYWN0aW9uIiwibmV3bGluZSIsIm5vdFN0eWxlIiwia2VlcEh0bWwiLCJrZWVwQ2xhc3NlcyIsImtlZXBPbmx5VGFncyIsImJhZFRhZ3MiLCJiYWRBdHRyaWJ1dGVzIiwicGF0aCIsImxpc3QiLCJ1bmRlZmluZWQiLCJmbiIsImRvdWJsZVRhcFRvR28iLCJuYXZpZ2F0b3IiLCJtc01heFRvdWNoUG9pbnRzIiwidXNlckFnZW50IiwidG9Mb3dlckNhc2UiLCJtYXRjaCIsImN1ckl0ZW0iLCJpdGVtIiwicmVzZXRJdGVtIiwicGFyZW50cyIsImpRdWVyeSIsImhvdmVyIiwiZm9jdXMiLCJ0b3RhbCIsImluZGV4IiwibWVkaW8iLCJNYXRoIiwicm91bmQiLCJjMSIsImMyIiwiaTEiLCJpMiIsImFycmF5IiwiaW5BcnJheSIsImVudmlhckNvbnRhY3RvRm9ybSIsIlhIUiIsIlhNTEh0dHBSZXF1
1ZXN0IiwiRkQiLCJGb3JtRGF0YSIsImdldEVsZW1lbnRCeUlkIiwiY3NyZiIsImNvbnRlbnQiLCJuYW1lIiwiYXBwZW5kIiwiYWxlcnQiLCJvcGVuIiwic2V0UmVxdWVzdEhlYWRlciIsInNlbmQiLCJpbnB1dHMiLCJidXR0b24iLCJyZWxhdGVkVGFyZ2V0IiwibW9kYWwiLCJxIl0sInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9qcy9mb3JtdWxhcmlvcy5qcz81ZTNlIl0sInNvdXJjZXNDb250ZW50IjpbIiQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uKCkge1xuICAkKFwiI2FydGljdWxvX3VzZXJfaWRcIikuZWFjaChmdW5jdGlvbigpIHtcbiAgICAkKHRoaXMpLnNlbGVjdDIoKTtcbiAgfSk7XG59KTtcbiQoJ3NlbGVjdCNwdWJsaWNhY2lvbl9kaWdpdGFsX3RlbWFfaWQsIHNlbGVjdCNhcnRpY3Vsb19wdWJsaWNhY2lvbl90ZW1hX2lkLCBzZWxlY3QjcHVibGljYWNpb25fdGVtYV9pZCwgc2VsZWN0I2FydGljdWxvX3RlbWFfaWQsIHNlbGVjdCNhcnRpY3Vsb190ZW1hcyAsIHNlbGVjdCN0ZW1hX3BhcmVudHMsIHNlbGVjdCNmb3RvX3RlbWFzLCBzZWxlY3QjbXVsdGltZWRpYV90ZW1hcywgc2VsZWN0I2dhbGVyaWFfdGVtYXMsIHNlbGVjdC50ZW1hcycpLmVhY2goZnVuY3Rpb24oKXtcbiAgJCh0aGlzKS5zZWxlY3QyKHtcbiAgICBwbGFjZWhvbGRlcjogJ0J1c2NhciB0ZW1hcycsXG4gICAgbWluaW11bUlucHV0TGVuZ3RoOiAzLCAgICAgICAgICAgIFxuICAgIGFsbG93Q2xlYXI6IHRydWUsXG4gICAgY2FjaGU6IHRydWUsXG4gICAgYWpheDoge1xuICAgICAgZGVsYXk6IDI1MCxcbiAgICAgIHVybDogIGZ1bmN0aW9uIChwYXJhbXMpIHtcbiAgICAgICAgcmV0dXJuICcvYXBpL3RlbWFzLycgKyBwYXJhbXMudGVybTtcbiAgICAgIH0sXG4gICAgICBkYXRhVHlwZTogJ2pzb24nLFxuICAgICAgcHJvY2Vzc1Jlc3VsdHM6IGZ1bmN0aW9uIChkYXRhLCBwYXJhbXMpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICByZXN1bHRzOiBkYXRhLmRhdGFcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSlcbn0pOyBcbiQoJ3NlbGVjdCNzZWFyY2hfZm90b190ZW1hX2lkJykuZWFjaChmdW5jdGlvbigpe1xuICAkKHRoaXMpLnNlbGVjdDIoe1xuICAgIHBsYWNlaG9sZGVyOiAnQnVzY2FyIHRlbWFzJyxcbiAgICBtaW5pbXVtSW5wdXRMZW5ndGg6IDMsICAgICAgICAgICAgXG4gICAgYWxsb3dDbGVhcjogdHJ1ZSxcbiAgICBjYWNoZTogdHJ1ZSxcbiAgICBhamF4OiB7XG4gICAgICBkZWxheTogMjUwLFxuICAgICAgdXJsOiAgZnVuY3Rpb24gKHBhcmFtcykge1xuICAgICAgICByZXR1cm4gJy9hcGkvdGVtYXMvJyArIHBhcmFtcy50ZXJtICsgJy90b2Rvcyc7XG4gICAgICB9LFxuICAgICAgZGF0YVR5cGU6ICdqc29uJyxcbiAgICAgIHByb2Nlc3NSZXN1bHRzOiBmdW5jdGlvbiAoZGF0YSwgcGFyYW1zKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcmVzdWx0czogZGF0YS5kYXRhXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0pXG59KTsgXG4kKCdzZWxlY3QjYXJ0aWN1bG9fYXV0b3Jlcywgc2VsZWN0I2ZvdG9fYXV0b3Jlcywgc2VsZWN0I3NlYXJjaF9mb3RvX2F1dG9yX2lkLCBzZWxlY3QjbXVsdGltZWRpYV9hdXRvcmVzLCBzZWxlY3QjZ2FsZXJpYV9hdXRvcmVzLCBzZWxlY3QuYXV0b3JlcycpLmVhY2goZnVuY3Rpb24oKXtcbiAgJCh0aGlzKS5zZWxlY3QyKHtcbiAgICBwbGFjZWhvbGRlcjogJ05vbWJyZSBhIGJ1c2NhcicsXG4gICAgbWluaW11bUlucHV0TGVuZ3RoOiAzLCAgICAgICAgICAgIFxuICAgIGFsbG93Q2xlYXI6IHRydWUsXG4gICAgY2FjaGU6IHRydWUsXG4gICAgYWpheDoge1xuICAgICAgZGVsYXk6IDI1MCxcbiAgICAgIHVybDogIGZ1bmN0aW9uIChwYXJhbXMpIHtcbiAgICAgICAgcmV0dXJuICcvYXBpL2F1dG9yZXMvJyArIHBhcmFtcy50ZXJtO1xuICAgICAgfSxcbiAgICAgIGRhdGFUeXBlOiAnanNvbicsXG4gICAgICBwcm9jZXNzUmVzdWx0czogZnVuY3Rpb24gKGRhdGEsIHBhcmFtcykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHJlc3VsdHM6IGRhdGEuZGF0YVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9KVxufSk7IFxuZnVuY3Rpb24gaGFjZXJfYW51bmNpb3Nfc2VsZWNjaW9uYWJsZSgpe1xuICAkKCdzZWxlY3QuYW51bmNpb3MnKS5lYWNoKGZ1bmN0aW9uKGksIHNlbCl7YW51bmNpb19zZWxlY2Npb25hYmxlKHNlbCl9KTtcbn1cbmZ1bmN0aW9uIGFudW5jaW9fc2VsZWNjaW9uYWJsZShzZWwpIHsgICBcbiAgICAkKHNlbCkuc2VsZWN0Mih7XG4gICAgICBwbGFjZWhvbGRlcjogJ05vbWJyZSBhIGJ1c2NhcicsXG4gICAgICBtaW5pbXVtSW5wdXRMZW5ndGg6IDIsICAgICAgICAgICAgXG4gICAgICBhbGxvd0NsZWFyOiB0cnVlLFxuICAgICAgY2FjaGU6IHRydWUsXG4gICAgICBhamF4OiB7XG4gICAgICAgIGRlbGF5OiAyNTAsXG4gICAgICAgIHVybDogIGZ1bmN0aW9uIChwYXJhbXMpIHtcbiAgICAgICAgICByZXR1cm4gJy9hcGkvYW51bmNpb3MvJyArIHBhcmFtcy50ZXJtO1xuICAgICAgICB9LFxuICAgICAgICBkYXRhVHlwZTogJ2pzb24nLFxuICAgICAgICBwcm9jZXNzUmVzdWx0czogZnVuY3Rpb24gKGRhdGEsIHBhcmFtcykge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZXN1bHRzOiBkYXRhLmRhdGFcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICAkKHNlbCkub24oJ2NoYW5nZScsKGZ1bmN0aW9uKCl7XG4gICAgICB2Y
1XIgdGl0dWxvID0gJCh0aGlzKS5maW5kKCdvcHRpb246c2VsZWN0ZWQnKS50ZXh0KCk7XG4gICAgICAkKHRoaXMpLnBhcmVudCgpLnBhcmVudCgpLmZpbmQoJy5hbnVuY2lvX3QnKS52YWwodGl0dWxvKTtcbiAgICB9KSk7XG59XG5oYWNlcl9hbnVuY2lvc19zZWxlY2Npb25hYmxlKCk7XG5mdW5jdGlvbiBmb3RvcygpIHsgICBcbiAgJCgnc2VsZWN0I3B1YmxpY2FjaW9uX2ZvdG9faWQsIHNlbGVjdCNhcnRpY3Vsb19mb3RvX2lkLCBzZWxlY3QjYXJ0aWN1bG9fZm90b19wb3J0YWRhX2lkLCBzZWxlY3QjZG9jX2ludGVybm9fZm90b19pZCwgc2VsZWN0I2FjY2Vzb19mb3RvX2lkLCBzZWxlY3QjZm9ybXVsYXJpb19mb25kb19pZCwgc2VsZWN0LmZvdG8nKS5lYWNoKGZ1bmN0aW9uKCl7XG4gICAgJCh0aGlzKS5zZWxlY3QyKHtcbiAgICAgIHBsYWNlaG9sZGVyOiAnQnVzY2FyIGZvdG8nLFxuICAgICAgbWluaW11bUlucHV0TGVuZ3RoOiAzLCAgICAgICAgICAgIFxuICAgICAgYWxsb3dDbGVhcjogdHJ1ZSxcbiAgICAgIGNhY2hlOiB0cnVlLFxuICAgICAgYWpheDoge1xuICAgICAgICBkZWxheTogMjUwLFxuICAgICAgICB1cmw6ICBmdW5jdGlvbiAocGFyYW1zKSB7XG4gICAgICAgICAgcmV0dXJuICcvYXBpL2ZvdG9zLycgKyBwYXJhbXMudGVybTtcbiAgICAgICAgfSxcbiAgICAgICAgZGF0YVR5cGU6ICdqc29uJyxcbiAgICAgICAgcHJvY2Vzc1Jlc3VsdHM6IGZ1bmN0aW9uIChkYXRhLCBwYXJhbXMpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVzdWx0czogZGF0YS5kYXRhXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSlcbiAgfSk7XG59XG5mb3RvcygpO1xuZnVuY3Rpb24gZ2FsZXJpYXMoKSB7ICAgXG4gICQoJ3NlbGVjdC5nYWxlcmlhJykuZWFjaChmdW5jdGlvbigpe1xuICAgICQodGhpcykuc2VsZWN0Mih7XG4gICAgICBwbGFjZWhvbGRlcjogJ0J1c2NhciBnYWxlcsOtYScsXG4gICAgICBtaW5pbXVtSW5wdXRMZW5ndGg6IDMsICAgICAgICAgICAgXG4gICAgICBhbGxvd0NsZWFyOiB0cnVlLFxuICAgICAgY2FjaGU6IHRydWUsXG4gICAgICBhamF4OiB7XG4gICAgICAgIGRlbGF5OiAyNTAsXG4gICAgICAgIHVybDogIGZ1bmN0aW9uIChwYXJhbXMpIHtcbiAgICAgICAgICByZXR1cm4gJy9hcGkvZ2FsZXJpYXMvJyArIHBhcmFtcy50ZXJtO1xuICAgICAgICB9LFxuICAgICAgICBkYXRhVHlwZTogJ2pzb24nLFxuICAgICAgICBwcm9jZXNzUmVzdWx0czogZnVuY3Rpb24gKGRhdGEsIHBhcmFtcykge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZXN1bHRzOiBkYXRhLmRhdGFcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KVxuICB9KTtcbn1cbmdhbGVyaWFzKCk7XG5cbmZ1bmN0aW9uIG11bHRpbWVkaWFzKCkgeyAgIFxuICAkKCdzZWxlY3QubXVsdGltZWRpYScpLmVhY2goZnVuY3Rpb24oKXtcbiAgICAkKHRoaXMpLnNlbGVjdDIoe1xuICAgICAgcGxhY2Vob2xkZXI6ICdCdXNjYXIgbXVsdGltZWRpYScsXG4gICAgICBtaW5pbXVtSW5wdXRMZW5ndGg6IDMsICAgICAgICAgICAgXG4gICAgICBhbGxvd0NsZWFyOiB0cnVlLFxuICAgICAgY2FjaGU6IHRydWUsXG4gICAgICBhamF4OiB7XG4gICAgICAgIGRlbGF5OiAyNTAsXG4gICAgICAgIHVybDogIGZ1bmN0aW9uIChwYXJhbXMpIHtcbiAgICAgICAgICByZXR1cm4gJy9hcGkvbXVsdGltZWRpYS8nICsgcGFyYW1zLnRlcm07XG4gICAgICAgIH0sXG4gICAgICAgIGRhdGFUeXBlOiAnanNvbicsXG4gICAgICAgIHByb2Nlc3NSZXN1bHRzOiBmdW5jdGlvbiAoZGF0YSwgcGFyYW1zKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlc3VsdHM6IGRhdGEuZGF0YVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG4gIH0pO1xufVxubXVsdGltZWRpYXMoKTtcblxuJCgnLmFydGljdWxvX3MnKS5lYWNoKGZ1bmN0aW9uKGksIHNlbCl7YXJ0aWN1bG9fc2VsZWNjaW9uYWJsZShzZWwpfSk7XG5mdW5jdGlvbiBoYWNlcl9hcnRpY3Vsb3Nfc2VsZWNjaW9uYWJsZXMoKXtcbiAgJCgnLmFydGljdWxvX3MnKS5lYWNoKGZ1bmN0aW9uKGksIHNlbCl7YXJ0aWN1bG9fc2VsZWNjaW9uYWJsZShzZWwpfSk7XG59XG5mdW5jdGlvbiBhcnRpY3Vsb19zZWxlY2Npb25hYmxlKHNlbCl7XG4gICQoc2VsKS5zZWxlY3QyKHtcbiAgICBwbGFjZWhvbGRlcjogJ0J1c2NhciBhcnTDrWN1bG8nLFxuICAgIG1pbmltdW1JbnB1dExlbmd0aDogMywgICAgICAgICAgICBcbiAgICBhbGxvd0NsZWFyOiB0cnVlLFxuICAgIGNhY2hlOiB0cnVlLFxuICAgIGFqYXg6IHtcbiAgICAgIGRlbGF5OiAyNTAsXG4gICAgICB1cmw6ICBmdW5jdGlvbiAocGFyYW1zKSB7XG4gICAgICAgIHJldHVybiAnL2FwaS9hcnRpY3Vsb3MvJyArIHBhcmFtcy50ZXJtO1xuICAgICAgfSxcbiAgICAgIGRhdGFUeXBlOiAnanNvbicsXG4gICAgICBwcm9jZXNzUmVzdWx0czogZnVuY3Rpb24gKGRhdGEsIHBhcmFtcykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHJlc3VsdHM6IGRhdGEuZGF0YVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgJChzZWwpLm9uKCdjaGFuZ2UnLChmdW5jdGlvbigpe1xuICAgIHZhciB0aXR1bG8gPSAkKHRoaXMpLmZpbmQoJ29wdGlvbjpzZWxlY3RlZCcpLnRleHQoKTtcbiAgICAkKHRoaXMpLnBhcmVudCgpLnBhcmVudCgpLmZpbmQoJy5hcnRpY3Vsb190JykudmFsKHRpdHVsbyk7XG4gIH0pKTtcbn07XG4kKCcuYXJ0aWN1bG9fc190b2RvcycpLmVhY2goZnVuY3Rpb24oaSwgc2VsKXthcnRpY3Vsb19zZWxlY2Npb25hYmxlX3RvZG9zKHNlbCl9KTtcbmZ1bmN0aW9uIGhhY2VyX2FydGljdWxvc190b2Rvc19zZWxlY2Npb25hYmxlcygpe1xuICAkKCcuYXJ0aWN1bG9fc190b2RvcycpLmVhY2goZnVuY3Rpb24oaSwgc2VsKXthcnRpY3Vsb19zZWxlY2Npb25hYmxlX3RvZG9zKHNlbCl9KTtcbn1cbmZ1bmN0aW9uIGFydGljdWxvX3NlbGVjY2lvbmFibGVfdG9kb3Moc2VsKXtcbiAgJChzZWwpLnNlbGVjdDIoe1xuICAgIHBsYWNlaG9sZG
1VyOiAnQnVzY2FyIGFydMOtY3VsbycsXG4gICAgbWluaW11bUlucHV0TGVuZ3RoOiAzLCAgICAgICAgICAgIFxuICAgIGFsbG93Q2xlYXI6IHRydWUsXG4gICAgY2FjaGU6IHRydWUsXG4gICAgYWpheDoge1xuICAgICAgZGVsYXk6IDI1MCxcbiAgICAgIHVybDogIGZ1bmN0aW9uIChwYXJhbXMpIHtcbiAgICAgICAgcmV0dXJuICcvYXBpL2FydGljdWxvc190b2Rvcy8nICsgcGFyYW1zLnRlcm07XG4gICAgICB9LFxuICAgICAgZGF0YVR5cGU6ICdqc29uJyxcbiAgICAgIHByb2Nlc3NSZXN1bHRzOiBmdW5jdGlvbiAoZGF0YSwgcGFyYW1zKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcmVzdWx0czogZGF0YS5kYXRhXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICAkKHNlbCkub24oJ2NoYW5nZScsKGZ1bmN0aW9uKCl7XG4gICAgdmFyIHRpdHVsbyA9ICQodGhpcykuZmluZCgnb3B0aW9uOnNlbGVjdGVkJykudGV4dCgpO1xuICAgICQodGhpcykucGFyZW50KCkucGFyZW50KCkuZmluZCgnLmFydGljdWxvX3QnKS52YWwodGl0dWxvKTtcbiAgfSkpO1xufTsgXG5cbiQoZG9jdW1lbnQpLm9uKCdjbGljaycsJy5hbmhhZGlyX2FydGljdWxvX3B1Yl9kaWdpJywgZnVuY3Rpb24oZSkge1xuICBlLnByZXZlbnREZWZhdWx0KCk7XG4gIGxldCB0aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIGxldCB0ZW1wbGF0ZSA9ICQodGhpcykuZGF0YShcInRlbXBsYXRlXCIpO1xuICB2YXIgdGlwbyA9ICQodGhpcykucGFyZW50KCkuZmluZChcIi5ub21icmVcIikuZmluZChcIi5hdG9wYW1lXCIpLmxlbmd0aDtcbiAgaWYgKHRpcG8gPiAwKSB7XG4gICAgdmFyIGlkID0gJCh0aGlzKS5wYXJlbnQoKVxuICAgICAgLmZpbmQoXCIubm9tYnJlXCIpLmZpbmQoXCIuYXRvcGFtZVwiKS5lcSgwKS5hdHRyKFwiaWRcIik7XG4gICAgaWQgPSBpZC5zcGxpdCgnXycpWzJdO1xuICB9ZWxzZXtcbiAgICB2YXIgaWQgPSAkKHRoaXMpLnBhcmVudCgpXG4gICAgICAuZmluZChcIi5ub21icmVcIikuZmluZChcIi5hdG9wYW1lMlwiKS5lcSgwKS5hdHRyKFwiaWRcIik7XG4gICAgaWQgPSBpZC5zcGxpdCgnXycpWzNdO1xuICB9XG4gIHZhciB1bmlxX3RlbXBsYXRlID0gdGVtcGxhdGVcbiAgICAucmVwbGFjZSgvYXJ0aWN1bG9zXFxdXFxbMFxcXS9nLCBgYXJ0aWN1bG9zXVske3RpbWV9XWApXG4gICAgLnJlcGxhY2UoL2NvbGFzXFxdXFxbMFxcXS9nLCBgY29sYXNdWyR7aWR9XWApXG4gICAgLnJlcGxhY2UoL2FwYXJ0YWRvc1xcXVxcWzBcXF0vZywgYGFwYXJ0YWRvc11bJHtpZH1dYClcbiAgICAucmVwbGFjZSgvYXJ0aWN1bG9zXzBfL2csIGBhcnRpY3Vsb3NfJHt0aW1lfV9gKVxuICAgIC5yZXBsYWNlKC9jb2xhc18wXy9nLCBgY29sYXNfJHtpZH1fYCkgXG4gICAgLnJlcGxhY2UoL2FwYXJ0YWRvc18wXy9nLCBgYXBhcnRhZG9zXyR7aWR9X2ApOyBcbiAgdmFyIGNvbnRlbmVkb3Jfb3JpZ2luYWwgPSB0aGlzLnBhcmVudE5vZGUucXVlcnlTZWxlY3RvcihcIi5lbnRyYWRhc1wiKS5jbG9uZU5vZGUodHJ1ZSk7XG4gIHZhciBhcnRpY3Vsb3Nfb3JpZ2luYWwgPSBjb250ZW5lZG9yX29yaWdpbmFsLnF1ZXJ5U2VsZWN0b3JBbGwoXCJ0clwiKTtcbiAgJCh0aGlzKS5wYXJlbnQoKS5maW5kKFwiLmVudHJhZGFzXCIpLnByZXBlbmQodW5pcV90ZW1wbGF0ZSk7XG4gIC8vJCh0aGlzKS5wYXJlbnQoKS5maW5kKFwiLmZpbGFcIikuZXEoMCkuYmVmb3JlKHVuaXFfdGVtcGxhdGUpO1xuICBoYWNlcl9hcnRpY3Vsb3Nfc2VsZWNjaW9uYWJsZXMoKTtcbiAgaGFjZXJfYXJ0aWN1bG9zX3RvZG9zX3NlbGVjY2lvbmFibGVzKCk7XG4gIHZhciB1YmljYWNpb24gPSAkKCcjcG9ydGFkYV91YmljYWNpb24nKS52YWwoKTtcbiAgJCgnLmZvcm0tYXBhcnRhZG8tbnVldm8gLnBvcnRhZGFfdWJpY2FjaW9uJykudmFsKHViaWNhY2lvbik7XG59KVxuLy8gXG4vLyBHZXN0acOzbiBkZSBjb2xhc1xuJChkb2N1bWVudCkub24oJ2NsaWNrJywnLmFuaGFkaXJfYXJ0aWN1bG8nLCBmdW5jdGlvbihlKSB7XG4gIGUucHJldmVudERlZmF1bHQoKTtcbiAgbGV0IHRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgbGV0IHRlbXBsYXRlID0gJCh0aGlzKS5kYXRhKFwidGVtcGxhdGVcIik7XG4gIHZhciB0aXBvID0gJCh0aGlzKS5wYXJlbnQoKS5maW5kKFwiLm5vbWJyZVwiKS5maW5kKFwiLmF0b3BhbWVcIikubGVuZ3RoO1xuICBpZiAodGlwbyA+IDApIHtcbiAgICB2YXIgaWQgPSAkKHRoaXMpLnBhcmVudCgpXG4gICAgICAuZmluZChcIi5ub21icmVcIikuZmluZChcIi5hdG9wYW1lXCIpLmVxKDApLmF0dHIoXCJpZFwiKTtcbiAgICBpZCA9IGlkLnNwbGl0KCdfJylbMl07XG4gIH1lbHNle1xuICAgIHZhciBpZCA9ICQodGhpcykucGFyZW50KClcbiAgICAgIC5maW5kKFwiLm5vbWJyZVwiKS5maW5kKFwiLmF0b3BhbWUyXCIpLmVxKDApLmF0dHIoXCJpZFwiKTtcbiAgICBpZCA9IGlkLnNwbGl0KCdfJylbM107XG4gIH1cbiAgdmFyIHVuaXFfdGVtcGxhdGUgPSB0ZW1wbGF0ZVxuICAgIC5yZXBsYWNlKC9hcnRpY3Vsb3NcXF1cXFswXFxdL2csIGBhcnRpY3Vsb3NdWyR7dGltZX1dYClcbiAgICAucmVwbGFjZSgvY29sYXNcXF1cXFswXFxdL2csIGBjb2xhc11bJHtpZH1dYClcbiAgICAucmVwbGFjZSgvYXBhcnRhZG9zXFxdXFxbMFxcXS9nLCBgYXBhcnRhZG9zXVske2lkfV1gKVxuICAgIC5yZXBsYWNlKC9hcnRpY3Vsb3NfMF8vZywgYGFydGljdWxvc18ke3RpbWV9X2ApXG4gICAgLnJlcGxhY2UoL2NvbGFzXzBfL2csIGBjb2xhc18ke2lkfV9gKSBcbiAgICAucmVwbGFjZSgvYXBhcnRhZG9zXzBfL2csIGBhcGFydGFkb3NfJHtpZH1fYCk7IFxuICB2YXIgY29udGVuZWRvcl9vcmlnaW5hbCA9IHRoaXMucGFyZW50Tm9kZS5xdWVyeVNlbGVjdG9yKFwiLmVud
1HJhZGFzXCIpLmNsb25lTm9kZSh0cnVlKTtcbiAgdmFyIGFydGljdWxvc19vcmlnaW5hbCA9IGNvbnRlbmVkb3Jfb3JpZ2luYWwucXVlcnlTZWxlY3RvckFsbChcInRyXCIpO1xuICB2YXIgZWxlbWVudG8gPSAkKHRoaXMpLnBhcmVudCgpLmZpbmQoXCIuZW50cmFkYXNcIikucHJlcGVuZCh1bmlxX3RlbXBsYXRlKTtcblxuICAvLyQodGhpcykucGFyZW50KCkuZmluZChcIi5maWxhXCIpLmVxKDApLmJlZm9yZSh1bmlxX3RlbXBsYXRlKTtcbiAgaGFjZXJfYXJ0aWN1bG9zX3NlbGVjY2lvbmFibGVzKCk7XG4gIGhhY2VyX2FydGljdWxvc190b2Rvc19zZWxlY2Npb25hYmxlcygpO1xuICB2YXIgdWJpY2FjaW9uID0gJCgnI3BvcnRhZGFfdWJpY2FjaW9uJykudmFsKCk7XG4gICQoJy5mb3JtLWFwYXJ0YWRvLW51ZXZvIC5wb3J0YWRhX3ViaWNhY2lvbicpLnZhbCh1YmljYWNpb24pO1xuICB2YXIgY29udGVuZWRvciA9IHRoaXMucGFyZW50Tm9kZS5xdWVyeVNlbGVjdG9yKFwiLmVudHJhZGFzXCIpO1xuICB2YXIgYXJ0aWN1bG9zID0gY29udGVuZWRvci5xdWVyeVNlbGVjdG9yQWxsKFwidHJcIik7XG4gIGNvbnRlbmVkb3IuaW5uZXJIVE1MID0gXCJcIlxuICBhcnRpY3Vsb3MgPSBvcmRlbmFyX2FycmF5X2Nvbl9maWpvcyhhcnRpY3Vsb3Nfb3JpZ2luYWwsIGFydGljdWxvcyk7XG4gIGFydGljdWxvcy5mb3JFYWNoKGZ1bmN0aW9uKGUsaSxhKXtcbiAgICAgY29udGVuZWRvci5hcHBlbmRDaGlsZChlKVxuICB9KVxuICBub3JtYWxpemFyX2NvbGEoY29udGVuZWRvcilcbiAgb3JkZW5hcl9jb2xhKGNvbnRlbmVkb3IpXG4gIG5vcm1hbGl6YXJfY29sYShjb250ZW5lZG9yKVxuICBib3RvbmVzX2FycmliYV9hYmFqb19jb2xhcygpO1xufSlcblxuZnVuY3Rpb24gb3JkZW5hcl9hcnJheV9jb25fZmlqb3Mob3JpZ2luYWwsIG51ZXZvKXtcbiAgdmFyIG5vcm1hbGVzID0gWy4uLm51ZXZvXS5maWx0ZXIoZSA9PiAhZS5xdWVyeVNlbGVjdG9yKFwiLmNoaW5jaGV0YSAuZm9ybS1jb250cm9sXCIpLmNoZWNrZWQpXG4gIHZhciBub3JtYWxfaSA9IDBcbiAgdmFyIGwgPSBudWV2by5sZW5ndGhcbiAgbnVldm8gPSBbXVxuICBmb3IgKGxldCBpID0gMDsgaSA8bDsgaSsrKSB7XG4gICAgaWYgKG9yaWdpbmFsW2ldIFxuICAgICAgICAmJiBvcmlnaW5hbFtpXS5xdWVyeVNlbGVjdG9yKFwiLmNoaW5jaGV0YSAuZm9ybS1jb250cm9sXCIpLmNoZWNrZWQpe1xuICAgICAgbnVldm9baV0gPSBvcmlnaW5hbFtpXVxuICAgIH0gZWxzZSB7XG4gICAgICBudWV2b1tpXSA9IG5vcm1hbGVzW25vcm1hbF9pXVxuICAgICAgKytub3JtYWxfaVxuICAgIH1cbiAgfVxuICByZXR1cm4gbnVldm87XG59XG5cbmZ1bmN0aW9uIG9yZGVuYXJfY29sYShjb250ZW5lZG9yKXtcbiAgdmFyIGFydGljdWxvcyA9IGNvbnRlbmVkb3IucXVlcnlTZWxlY3RvckFsbChcInRyXCIpO1xuICBhcnRpY3Vsb3MgPSBBcnJheS5mcm9tKGFydGljdWxvcykuc29ydChmdW5jdGlvbihhLGIpe1xuICAgIC8vaWYgKGEucXVlcnlTZWxlY3RvcihcIi5jaGluY2hldGEgLmZvcm0tY29udHJvbFwiKS5jaGVja2VkKXtyZXR1cm4gLSAxfTtcbiAgICAvL2lmIChiLnF1ZXJ5U2VsZWN0b3IoXCIuY2hpbmNoZXRhIC5mb3JtLWNvbnRyb2xcIikuY2hlY2tlZCl7cmV0dXJuICsgMX07XG4gICAgYSA9IGEucXVlcnlTZWxlY3RvcihcIi5vcmRlbiAuZm9ybS1jb250cm9sXCIpLnZhbHVlO1xuICAgIGIgPSBiLnF1ZXJ5U2VsZWN0b3IoXCIub3JkZW4gLmZvcm0tY29udHJvbFwiKS52YWx1ZTtcbiAgICByZXR1cm4gIGEgLSBiXG4gIH0pXG4gICAgLy8uZm9yRWFjaChlbCA9PnsgY29udGVuZWRvci5hcHBlbmRDaGlsZChlbCkgfSlcblxuICBjb250ZW5lZG9yLmlubmVySFRNTCA9IFwiXCJcbiAgYXJ0aWN1bG9zLmZvckVhY2goZnVuY3Rpb24oZSxpLGEpe1xuICAgICBjb250ZW5lZG9yLmFwcGVuZENoaWxkKGUpXG4gIH0pXG5cbn1cbmZ1bmN0aW9uIG5vcm1hbGl6YXJfY29sYShjb250ZW5lZG9yKXtcbiAgdmFyIGFydGljdWxvcyA9IGNvbnRlbmVkb3IucXVlcnlTZWxlY3RvckFsbChcInRyXCIpO1xuICBhcnRpY3Vsb3MuZm9yRWFjaChmdW5jdGlvbihlLGksYSl7XG4gICAgb3JkZW4gPSBlLnF1ZXJ5U2VsZWN0b3IoXCIub3JkZW4gLmZvcm0tY29udHJvbFwiKVxuICAgIG9yZGVuLnZhbHVlID0gKGkrMSkqMTA7XG4gIH0pO1xufVxudmFyIGFycmliYSA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgdmFyIG9yZGVuID0gdGhpcy5wYXJlbnROb2RlLnBhcmVudE5vZGUucXVlcnlTZWxlY3RvcihcIi5vcmRlbiAuZm9ybS1jb250cm9sXCIpIFxuICAgICAgb3JkZW4udmFsdWUgPSBwYXJzZUludChvcmRlbi52YWx1ZSkgLSAxNTtcbiAgICAgIHZhciBjb250ZW5lZG9yID0gdGhpcy5wYXJlbnROb2RlLnBhcmVudE5vZGUucGFyZW50Tm9kZTtcbiAgICAgIG9yZGVuYXJfY29sYShjb250ZW5lZG9yKVxuICAgICAgbm9ybWFsaXphcl9jb2xhKGNvbnRlbmVkb3IpXG5cbn1cbnZhciBhYmFqbyA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgdmFyIG9yZGVuID0gdGhpcy5wYXJlbnROb2RlLnBhcmVudE5vZGUucXVlcnlTZWxlY3RvcihcIi5vcmRlbiAuZm9ybS1jb250cm9sXCIpIFxuICAgICAgb3JkZW4udmFsdWUgPSBwYXJzZUludChvcmRlbi52YWx1ZSkgKyAxNTtcbiAgICAgIHZhciBjb250ZW5lZG9yID0gdGhpcy5wYXJlbnROb2RlLnBhcmVudE5vZGUucGFyZW50Tm9kZTtcbiAgICAgIG9yZGVuYXJfY29sYShjb250ZW5lZG9yKVxuICAgICAgbm9ybWFsaXphcl9jb2xhKGNvbnRlbmVkb3IpXG59XG5cbmZ1bmN0aW9uIGJvdG9uZXNfYXJyaWJhX2FiYWpvX2NvbGFzKCl7XG4gIHZhciB1cEJ1dHRvbnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcub3JkZW5hciAudXAnKTtcbiAgdmFyIGRvd25CdXR0b25zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLm9yZGVuYXIgLmRvd24nKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHVwQnV0dG9ucy5sZW5ndGg7IGkrKykge1xuICAgIHVwQnV0dG9uc1tpXS5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIGFycmliYSkgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGRvd25CdXR0b25zLmxlbmd0aDsgaSsrKSB7XG4gICAgZG93bkJ1dHRvbnNbaV0ucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhYmFqbykgfVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdXBCdXR0b25zLmxlbmd0aDsgaSsrKSB7XG4gICAgdXBCdXR0b25zW2ldLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXJyaWJhKTtcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGRvd25CdXR0b25zLmxlbmd0aDsgaSsrKSB7XG4gICAgZG93bkJ1dHRvbnNbaV0uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhYmFqbyk7XG4gIH1cbn1cbmJvdG9uZXNfYXJyaWJhX2FiYWpvX2NvbGFzKCk7XG4kKGRvY3VtZW50KS5vbignY2xpY2snLCcjYW5oYWRpcl9zZWNjaW9uJywgZnVuY3Rpb24oZSkge1xuICBlLnByZXZlbn
1REZWZhdWx0KCk7XG4gIGxldCB0aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIGxldCB0ZW1wbGF0ZSA9ICQodGhpcykuZGF0YShcInRlbXBsYXRlXCIpO1xuICB2YXIgdW5pcV90ZW1wbGF0ZSA9IHRlbXBsYXRlLnJlcGxhY2UoL1xcWzBcXF0vZywgYFske3RpbWV9XWApO1xuICB1bmlxX3RlbXBsYXRlID0gdW5pcV90ZW1wbGF0ZS5yZXBsYWNlKC9fMF8vZywgYF8ke3RpbWV9X2ApO1xuICAkKHRoaXMpLnBhcmVudCgpLmFmdGVyKHVuaXFfdGVtcGxhdGUpO1xuICBmb3RvcygpO1xuICBnYWxlcmlhcygpO1xuICBtdWx0aW1lZGlhcygpO1xufSlcblxuLy8gR2VzdGnDs24gZGUgYXBhcnRhZG9zIHB1YiBkaWdpdGFsXG4kKGRvY3VtZW50KS5vbignY2xpY2snLCcjYW5oYWRpcl9zZWNjaW9uX3B1Yl9kaWcnLCBmdW5jdGlvbihlKSB7XG4gIGUucHJldmVudERlZmF1bHQoKTtcbiAgbGV0IHRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgbGV0IHRlbXBsYXRlID0gJCh0aGlzKS5kYXRhKFwidGVtcGxhdGVcIik7XG4gIHZhciB1bmlxX3RlbXBsYXRlID0gdGVtcGxhdGUucmVwbGFjZSgvXFxbMFxcXS9nLCBgWyR7dGltZX1dYCk7XG4gIHVuaXFfdGVtcGxhdGUgPSB1bmlxX3RlbXBsYXRlLnJlcGxhY2UoL18wXy9nLCBgXyR7dGltZX1fYCk7XG4gICQodGhpcykuYmVmb3JlKHVuaXFfdGVtcGxhdGUpO1xufSlcbiQoZG9jdW1lbnQpLm9uKCdjbGljaycsJyNhbmhhZGlyX2FwYXJ0YWRvJywgZnVuY3Rpb24oZSkge1xuICBlLnByZXZlbnREZWZhdWx0KCk7XG4gIGxldCB0aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIGxldCB0ZW1wbGF0ZSA9ICQodGhpcykuZGF0YShcInRlbXBsYXRlXCIpO1xuICB2YXIgdW5pcV90ZW1wbGF0ZSA9IHRlbXBsYXRlLnJlcGxhY2UoL1xcWzBcXF0vZywgYFske3RpbWV9XWApO1xuICB1bmlxX3RlbXBsYXRlID0gdW5pcV90ZW1wbGF0ZS5yZXBsYWNlKC9fMF8vZywgYF8ke3RpbWV9X2ApO1xuICAkKHRoaXMpLmJlZm9yZSh1bmlxX3RlbXBsYXRlKTtcbiAgJCgnLnN1bW1lcm5vdGUnKS5zdW1tZXJub3RlKCk7XG4gIGZvdG9zKCk7XG4gIGhhY2VyX2FydGljdWxvc190b2Rvc19zZWxlY2Npb25hYmxlcygpO1xuICBoYWNlcl9hbnVuY2lvc19zZWxlY2Npb25hYmxlKCk7XG59KVxuJChkb2N1bWVudCkub24oJ2NsaWNrJywnI2FuaGFkaXJfZm90b19hcmNoaXZvJywgZnVuY3Rpb24oZSkge1xuICBlLnByZXZlbnREZWZhdWx0KCk7XG4gIGxldCB0aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIGxldCB0ZW1wbGF0ZSA9ICQodGhpcykuZGF0YShcInRlbXBsYXRlXCIpO1xuICB2YXIgdW5pcV90ZW1wbGF0ZSA9IHRlbXBsYXRlLnJlcGxhY2UoL1xcWzBcXF0vZywgYFske3RpbWV9XWApO1xuICB1bmlxX3RlbXBsYXRlID0gdW5pcV90ZW1wbGF0ZS5yZXBsYWNlKC9fMF8vZywgYF8ke3RpbWV9X2ApO1xuICAkKHRoaXMpLnBhcmVudCgpLmJlZm9yZSh1bmlxX3RlbXBsYXRlKTtcbiAgZm90b3MoKTtcbn0pXG4vLyBTZWNjaW9uZXMgYXJ0aWN1bG9cbiQoZG9jdW1lbnQpLm9uKCdjbGljaycsJyNhbmhhZGlyX3NlY2Npb25fYXJ0aWN1bG8nLCBmdW5jdGlvbihlKSB7XG4gIGUucHJldmVudERlZmF1bHQoKTtcbiAgbGV0IHRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgbGV0IHRlbXBsYXRlID0gJCh0aGlzKS5kYXRhKFwidGVtcGxhdGVcIik7XG4gIHZhciB1bmlxX3RlbXBsYXRlID0gdGVtcGxhdGUucmVwbGFjZSgvXFxbMFxcXS9nLCBgWyR7dGltZX1dYCk7XG4gIHVuaXFfdGVtcGxhdGUgPSB1bmlxX3RlbXBsYXRlLnJlcGxhY2UoL18wXy9nLCBgXyR7dGltZX1fYCk7XG4gIC8vJCh0aGlzKS5wYXJlbnQoKS5iZWZvcmUodW5pcV90ZW1wbGF0ZSk7XG4gICQodGhpcykuYmVmb3JlKHVuaXFfdGVtcGxhdGUpO1xuICAkKCcuc3VtbWVybm90ZScpLnN1bW1lcm5vdGUoKTtcbiAgZm90b3MoKTtcbiAgbXVsdGltZWRpYXMoKTtcbiAgZ2FsZXJpYXMoKTtcbn0pXG5cbiQoZG9jdW1lbnQpLm9uKCdjbGljaycsJyNhbmhhZGlyX3RyYWR1Y2Npb24nLCBmdW5jdGlvbihlKSB7XG4gIGUucHJldmVudERlZmF1bHQoKTtcbiAgbGV0IHRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgbGV0IHRlbXBsYXRlID0gJCh0aGlzKS5kYXRhKFwidGVtcGxhdGVcIik7XG4gIHZhciB1bmlxX3RlbXBsYXRlID0gdGVtcGxhdGUucmVwbGFjZSgvXFxbMFxcXS9nLCBgWyR7dGltZX1dYCk7XG4gIHVuaXFfdGVtcGxhdGUgPSB1bmlxX3RlbXBsYXRlLnJlcGxhY2UoL18wXy9nLCBgXyR7dGltZX1fYCk7XG4gICQodGhpcykucGFyZW50KCkuYmVmb3JlKHVuaXFfdGVtcGxhdGUpO1xuICBoYWNlcl9hcnRpY3Vsb3Nfc2VsZWNjaW9uYWJsZXMoKTtcbiAgaGFjZXJfYXJ0aWN1bG9zX3RvZG9zX3NlbGVjY2lvbmFibGVzKCk7XG59KVxuJChkb2N1bWVudCkub24oJ2NsaWNrJywnI2FuaGFkaXJfbGluaycsIGZ1bmN0aW9uKGUpIHtcbiAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICBsZXQgdGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICBsZXQgdGVtcGxhdGUgPSAkKHRoaXMpLmRhdGEoXCJ0ZW1wbGF0ZVwiKTtcbiAgdmFyIHVuaXFfdGVtcGxhdGUgPSB0ZW1wbGF0ZS5yZXBsYWNlKC9cXFswXFxdL2csIGBbJHt0aW1lfV1gKTtcbiAgdW5pcV90ZW1wbGF0ZSA9IHVuaXFfdGVtcGxhdGUucmVwbGFjZSgvXzBfL2csIGBfJHt0aW1lfV9gKTtcbiAgJCh0aGlzKS5wYXJlbnQoKS5iZWZvcmUodW5pcV90ZW1wbGF0ZSk7XG59KVxuJChkb2N1bWVudCkub24oJ2NsaWNrJywnI2FuaGFkaXJfbWVudScsIGZ1bmN0aW9uKGUpIHtcbiAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICBsZXQgdGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICBsZXQgdGVtcGxhdGUgPSAkKHRoaXMpLmRhdGEoXCJ0ZW1wbGF0ZVwiKTtcbiAgdmFyIHVuaXFfdGVtcGxhdGUgPSB0ZW1wbGF0ZS5yZXBsYWNlKC9cXFswXFxdL2csIGBbJHt0aW1lfV1gKTtcbiAgdW5pcV90ZW1wbGF0ZSA9IHVuaXFfdGVtcGxhdGUucmVwbGFjZSgvXzBfL2csIGBfJHt0aW1lfV9gKTtcbiAgJCh0aGlzKS5wYXJlbnQoKS5iZWZvcmUodW5pcV90ZW1wbGF0ZSk7XG59KVxuJChkb2N1bWVudCkub24oJ2NsaWNrJywnI2FuaGFkaXJfY29tZW50YXJpbycsIGZ1bmN0aW9uKGUpIHtcbiAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICBsZXQgdGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICBsZXQgdGVtcGxhdGUgPSAkKHRoaXMpLmRhdGEoXCJ0ZW1wbGF0ZVwiKTtcbiAgdmFyIHVuaXFfdGVtcGxhdGUgPSB0ZW1wbGF0ZS5yZXBsYWNlKC9cXFswXFxdL2csIGBbJHt0aW1lfV1gKTtcbiAgdW5pcV90ZW1wbGF0ZSA9IHVuaXFfdGVtcGxhdGUucmVwbGFjZSgvXzBfL2csIGBfJHt0aW1lfV9gKTtcbiAgJCh0aGlzKS5wYXJlbnQoKS5iZWZvcmUo
1dW5pcV90ZW1wbGF0ZSk7XG4gIGNhbWJpbygpO1xuICBhY3R1YWxpemFyQ1NSRigpO1xufSlcbiQoZG9jdW1lbnQpLm9uKCdjbGljaycsJy5jb21lbnRhci1jb21lbnRhcmlvJywgZnVuY3Rpb24oZSkge1xuICB2YXIgY29tZW50YXJpb19pZCA9ICQodGhpcykuYXR0cignZGF0YS1jb21lbnRhcmlvJyk7XG4gIGUucHJldmVudERlZmF1bHQoKTtcbiAgbGV0IHRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgbGV0IHRlbXBsYXRlID0gJCgnI2FuaGFkaXJfY29tZW50YXJpbycpLmRhdGEoXCJ0ZW1wbGF0ZVwiKTtcbiAgdmFyIHVuaXFfdGVtcGxhdGUgPSB0ZW1wbGF0ZS5yZXBsYWNlKC9cXFswXFxdL2csIGBbJHt0aW1lfV1gKTtcbiAgdW5pcV90ZW1wbGF0ZSA9IHVuaXFfdGVtcGxhdGUucmVwbGFjZSgvXzBfL2csIGBfJHt0aW1lfV9gKTtcbiAgJChcIiNhbmhhZGlyX2NvbWVudGFyaW9cIikucGFyZW50KCkuYmVmb3JlKHVuaXFfdGVtcGxhdGUpO1xuICAkKCcjY29tZW50YXJpb19jb21lbnRhcmlvX2lkJykudmFsKGNvbWVudGFyaW9faWQpO1xuICBjYW1iaW8oKTtcbiAgYWN0dWFsaXphckNTUkYoKTtcbn0pXG4kKGRvY3VtZW50KS5vbignY2xpY2snLCcjYW5oYWRpcl90aXBvJywgZnVuY3Rpb24oZSkge1xuICBlLnByZXZlbnREZWZhdWx0KCk7XG4gIGxldCB0aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIGxldCB0ZW1wbGF0ZSA9ICQodGhpcykuZGF0YShcInRlbXBsYXRlXCIpO1xuICB2YXIgdW5pcV90ZW1wbGF0ZSA9IHRlbXBsYXRlLnJlcGxhY2UoL1xcWzBcXF0vZywgYFske3RpbWV9XWApO1xuICB1bmlxX3RlbXBsYXRlID0gdW5pcV90ZW1wbGF0ZS5yZXBsYWNlKC9fMF8vZywgYF8ke3RpbWV9X2ApO1xuICAkKHRoaXMpLnBhcmVudCgpLmJlZm9yZSh1bmlxX3RlbXBsYXRlKTtcbiQoJy5zdW1tZXJub3RlJykuc3VtbWVybm90ZSgpO1xufSlcbmZ1bmN0aW9uIGNhbWJpbygpe1xuICBpZiAoJCgnI2FydGljdWxvLWNvbXBsZXRvJykubGVuZ3RoKSB7XG4gICAgdmFyIHRva2VuID0gJCgnI2FydGljdWxvLWNvbXBsZXRvJykuYXR0cihcImRhdGEtdG9rZW5cIik7XG4gICAgJCgnI2FydGljdWxvLWNvbXBsZXRvIGlucHV0W25hbWU9XCJfY3NyZl90b2tlblwiXScpLmVhY2goZnVuY3Rpb24oKXtcbiAgICAgICQodGhpcykudmFsKHRva2VuKTtcbiAgICB9KTtcbiAgfVxufVxuJChkb2N1bWVudCkub24oJ2NsaWNrJywnLmJvcnJhcl9zZWNjaW9uJywgZnVuY3Rpb24oZSkge1xuICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICQodGhpcykucGFyZW50KCkucGFyZW50KCkucmVtb3ZlKCk7XG59KVxuJChkb2N1bWVudCkub24oJ2NsaWNrJywnLmFudWxhci1jb21lbnRhcmlvJywgZnVuY3Rpb24oZSkge1xuICAkKCcuYm94JykucmVtb3ZlKCk7XG59KVxuXG5mdW5jdGlvbiBJbWFnZW5VcGRhdGUob2JqKSAge1xuICBpZighd2luZG93LkZpbGVSZWFkZXIpe1xuICB9IGVsc2Uge1xuICAgIHZhciByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuICAgIHZhciB0YXJnZXQgPSBudWxsO1xuICAgIHJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbihlKSB7XG4gICAgICB0YXJnZXQgPSAgZS50YXJnZXQgfHwgZS5zcmNFbGVtZW50O1xuICAgICAgJChvYmopLnBhcmVudCgpLnBhcmVudCgpLmZpbmQoXCIucHJldmlld1wiKS5wcm9wKFwic3JjXCIsIHRhcmdldC5yZXN1bHQpO1xuICAgICAgJChvYmopLnBhcmVudCgpLnBhcmVudCgpLmZpbmQoXCIucHJldmlld1wiKS5yZW1vdmVDbGFzcyhcImhpZGRlblwiKTtcbiAgICB9O1xuICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKG9iai5maWxlc1swXSk7XG4gIH1cbn07XG4kKGRvY3VtZW50KS5vbignY2hhbmdlJywnaW5wdXQucHJldmlldycsIGZ1bmN0aW9uKCkge0ltYWdlblVwZGF0ZSh0aGlzKTt9KTtcblxuLy93eXNpd3lnXG4kKGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbigpe1xuICBpZiAodHlwZW9mICAkKCcuc3VtbWVybm90ZScpLnN1bW1lcm5vdGUgPT09IFwiZnVuY3Rpb25cIikgeyBcbiAgJCgnLnN1bW1lcm5vdGUnKS5zdW1tZXJub3RlKHtcbiAgICBzdHlsZVdpdGhTcGFuOiBmYWxzZSxcbiAgICBsYW5nOiAnZXMtRVMnLFxuICAgIGhlaWdodDogNDAwLFxuICAgIGRpYWxvZ3NGYWRlOiB0cnVlICAsXG4gICAgdG9vbGJhcjogW1xuICAgICAgWydzdHlsZScsIFsnYm9sZCcsICdpdGFsaWMnLCAndW5kZXJsaW5lJywgJ2NsZWFyJ11dLFxuICAgICAgWydmb250JywgWydzdHJpa2V0aHJvdWdoJywgJ3N1cGVyc2NyaXB0JywgJ3N1YnNjcmlwdCddXSxcbiAgICAgIFsncGFyYScsIFsndWwnLCAnb2wnLCAncGFyYWdyYXBoJ11dLFxuICAgICAgWydsaW5rJyxbJ3N0eWxlJ11dLFxuICAgICAgWydpbnNlcnQnLCBbJ3BpY3R1cmUnLCd2aWRlbycsJ2xpbmsnLCAndW5saW5rJ11dLFxuICAgICAgWydzYWx0bycsIFsnYXJ0aWN1bG8nLCdmb3RvJywnY29kaWdvJywgJ2JvcnJhciddXSxcbiAgICAgIFsndmlldycsWydjb2RldmlldyddXSxcbiAgICAgIFsnaW5zZXJ0JywgWyd0ZW1wbGF0ZSddXVxuICAgIF0sXG4gICAgcG9wb3Zlcjoge1xuICAgICAgaW1hZ2U6IFtcbiAgICAgICAgWydjdXN0b20nLCBbJ2ltYWdlQXR0cmlidXRlcycsJ2NhcHRpb25JdCddXSxcbiAgICAgICAgWydpbWFnZXNpemUnLCBbJ2ltYWdlU2l6ZTEwMCcsICdpbWFnZVNpemU1MCcsICdpbWFnZVNpemUyNSddXSxcbiAgICAgICAgWydmbG9hdCcsIFsnZmxvYXRMZWZ0JywgJ2Zsb2F0UmlnaHQnLCAnZmxvYXROb25lJ11dLFxuICAgICAgICBbJ3JlbW92ZScsIFsncmVtb3ZlTWVkaWEnXV1cbiAgICAgIF0sXG4gICAgfSxcbiAgICBpbWFnZUF0dHJpYnV0ZXM6e1xuICAgICAgaW1hZ2VEaWFsb2dMYXlvdXQ6J2RlZmF1bHQnLCAvLyBkZWZhdWx0fGhvcml6b250YWxcbiAgICAgIGljb246JzxpIGNsYXNzPVwibm90ZS1pY29uLXBlbmNpbFwiLz4nLFxuICAgICAgcmVtb3ZlRW1wdHk6ZmFsc2UgLy8gdHJ1ZSA9IHJlbW92ZSBhdHRyaWJ1dGVzIHwgZmFsc2UgPSBsZWF2ZSBlbXB0eSBpZiBwcmVzZW50XG4gICAgfSxcbiAgICBkaXNwbGF5RmllbGRzOntcbiAgICAgIGltYWdlQmFzaWM6dHJ1ZSwgIC8vIHNob3cvaGlkZSBUaXRsZSwgU291cmNlLCBBbHQgZmllbGRzXG4gICAgICBpbWFnZUV4dHJhOnRydWUsIC8vIHNob3cvaGlkZSBBbHQsIENsYXNzLCBTdHlsZSwgUm9sZSBmaWVsZHNcbiAgICAgIGxpbmtCYXNpYzp0cnVlLCAgIC8vIHNob3cvaGlkZSBVUkwgYW5kIFRhcmdldCBmaWVsZHMgZm9yIGxpbmtcbiAgICAgIGxpbmtFeHRyYTpmYWxzZSAgIC8vIHNob3cvaGlkZSBDbGFzcywgUmVsLCBSb2xlIGZpZWxkcyBmb3IgbGlua1xuICAgIH0sXG4gICAgY2FwdGlvbkl0OntcbiAgICAgIGljb246JzxpIGNsYXNzPVwibm90ZS1pY29uLXBlbmNpbFwifS8+JywgLy8gTGVhdmUgZW1wdHkgb3IgZG9uJ3Qgc2V0IGZvciBkZWZhdWx0IEljb24uXG4gICAgICBmaWd1cmVDbGFzczonZmlndXJlLWludGVybmEnLFxuICAgICAgZmlnY2FwdGlvbkNsYXNzOidwaWUnLFxuICAgIH0sXG4gICAgY2xlYW5lcjp7XG4gICAgICBub3RUaW1lOiA1MDAsIC8vIFRpbWUgdG8gZGlzcGxheSBOb3RpZmljYXRpb25zLlxuICAgICAgYWN0aW9uOiAnYm90aCcsIC8vIGJvdGh8YnV0dG9ufHBhc3RlICdidXR0b24nIG9ubHkgY2xlYW5zIHZpYSB0b29sYmFyIGJ1dHRvbiwgJ3Bhc3RlJyBvbmx5IGNsZWFuIHdoZW4gcGFzdGluZyBjb250ZW50LCBib3RoIGRvZXMgYm90aCBvcHRpb25zLlxuICAgICAgbmV3bGluZTogJzxicj4nLCAvLyBTdW1tZXJub3RlJ3MgZGVmYXVsdCBpcyB0byB1c2UgJzxwPjxicj48L3A+J1xuICAgICAgbm90U3R5bGU6ICdwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtsZWZ0OjA7cmlnaHQ6MCcsIC8vIFBvc2l0aW9uIG9mIE5vdGlmaWNhdGlvblxuICAgICAgaWNvbjogJzxpIGNsYXNzPVwibm90ZS1pY29uXCI+W3hdPC9pPicsXG4gICAgICBrZWVwSHRtbDogdHJ1ZSwgLy8gUmVtb3ZlIGFsbCBIdG1sIGZvcm1hdHNcbiAgICAgIGtlZXBDbGFzc2VzOiBmYWxzZSwgLy8gUmVtb3ZlIENsYXNzZXNcbiAgICAgIGtlZXBPbmx5VGFnczogWyc8YnI+JywnPGE+JywnPHA+J10sIC8vIElmIGtlZXBIdG1sIGlzIHRydWUsIHJlbW92ZSBhbGwgdGFncyBleGNlcHQgdGhlc2VcbiAgICAgIGJhZFRhZ3M6IFsnc3R5bGUnLCAnc2NyaXB0JywgJ2FwcGxldCcsICdlbWJlZCcsICdub2ZyYW1lcycsICdub3NjcmlwdCcsICdodG1sJ10sIC8vIFJlbW92ZSBmdWxsIHRhZ3Mgd2l0aCBjb250ZW50c1xuICAgICAgYmFkQXR0cmlidXRlczogWydkaXInLCdpZCcsJ3N0eWxlJywgJ3N0YXJ0JywnbmFtZScsJ2NsYXNzJywnYWxpZ24nLCdvbnRvdWNoc3RhcnQnXSAvLyBSZW1vdmUgYXR0cmlidXRlcyBmcm9tIHJlbWFpbmluZyB0YWdzXG4gICAgfSxcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgcGF0aDogJy9qcy9zdW1tZXJub3RlL3RwbHMnLFxuICAgICAgbGlzdDoge1xuICAgICAgICAncmVjdWFkcm9fZ2VuZXJpY28nOiAnUmVjdWFkcm8gZ2Vuw6lyaWNvJyxcbiAgICAgICAgJ3JlY3VhZHJvX2RjaGEnOiAnUmVjdWFkcm8gZGVyZWNobycsXG4gICAgICAgICdyZWN1YWRyb19penEnOiAnUmVjdWFkcm8gaXpxdWllcmRvJyxcbiAgICAgICAgJ3JlY3VhZHJvJzogJ1JlY3VhZHJvIFwiYW50aWd1b1wiJ1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIH1cbn0pO1xuLy8vL1xuXG47KGZ1bmN0aW9uKCAkLCB3aW5kb3csIGRvY3VtZW50LCB1bmRlZmluZWQgKVxuICB7XG4gICAgJC5mbi5kb3VibGVUYXBUb0dvID0gZnVuY3Rpb24oIHBhcmFtcyApXG4gICAge1xuICAgICAgaWYoICEoICdvbnRvdWNoc3RhcnQnIGluIHdpbmRvdyApICYmXG4gICAgICAgIC
1FuYXZpZ2F0b3IubXNNYXhUb3VjaFBvaW50cyAmJlxuICAgICAgICAgICFuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkubWF0Y2goIC93aW5kb3dzIHBob25lIG9zIDcvaSApICkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICB0aGlzLmVhY2goIGZ1bmN0aW9uKClcbiAgICAgICAge1xuICAgICAgICAgIHZhciBjdXJJdGVtID0gZmFsc2U7XG5cbiAgICAgICAgICAkKCB0aGlzICkub24oICdjbGljaycsIGZ1bmN0aW9uKCBlIClcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdmFyIGl0ZW0gPSAkKCB0aGlzICk7XG4gICAgICAgICAgICAgIGlmKCBpdGVtWyAwIF0gIT0gY3VySXRlbVsgMCBdIClcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICBjdXJJdGVtID0gaXRlbTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAkKCBkb2N1bWVudCApLm9uKCAnY2xpY2sgdG91Y2hzdGFydCBNU1BvaW50ZXJEb3duJywgZnVuY3Rpb24oIGUgKVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB2YXIgcmVzZXRJdGVtID0gdHJ1ZSxcbiAgICAgICAgICAgICAgICBwYXJlbnRzXHQgID0gJCggZS50YXJnZXQgKS5wYXJlbnRzKCk7XG5cbiAgICAgICAgICAgICAgZm9yKCB2YXIgaSA9IDA7IGkgPCBwYXJlbnRzLmxlbmd0aDsgaSsrIClcbiAgICAgICAgICAgICAgICBpZiggcGFyZW50c1sgaSBdID09IGN1ckl0ZW1bIDAgXSApXG4gICAgICAgICAgICAgICAgcmVzZXRJdGVtID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgaWYoIHJlc2V0SXRlbSApXG4gICAgICAgICAgICAgICAgY3VySXRlbSA9IGZhbHNlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgfSkoIGpRdWVyeSwgd2luZG93LCBkb2N1bWVudCApO1xuJCggJy5jYW1iaWFyTm9kb1BvcnRhZGEgdWwnICkuZG91YmxlVGFwVG9HbygpO1xuXG4kKFwiLmJ1c2NhclwiKS5ob3ZlcihmdW5jdGlvbigpe1xuICAgICQodGhpcykuZmluZChcIi5mb3JtLWNvbnRyb2xcIikuZm9jdXMoKTtcbn0pO1xuXG4kKGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbigpIHtcbiAgJCgnLmluZGV4LWxpc3RhZG9zJykuZWFjaChcbiAgICBmdW5jdGlvbigpe1xuICAgICAgdmFyIHVybCA9ICQodGhpcykuYXR0cignZGF0YS1wYXRoJyk7XG4gICAgICB2Y
1XIgdG90YWwgPSAkKCcuaW5kZXgtbGlzdGFkb3MgLnBhZ2UtbGluaycpLmxlbmd0aCAtMTtcbiAgICAgICQoJy5pbmRleC1saXN0YWRvcyAucGFnZS1saW5rJykuZWFjaChcbiAgICAgICAgZnVuY3Rpb24oaSl7XG4gICAgICAgICAgJCh0aGlzKS5hdHRyKCdocmVmJywkKHRoaXMpLmF0dHIoJ2hyZWYnKS5yZXBsYWNlKC9cXC9cXHcqXFw/Ky9nLHVybCtcIj9cIikpO1xuICAgICAgICB9XG4gICAgICApO1xuICAgICAgaWYgKHRvdGFsPjExKXtcbiAgICAgICAgdmFyIGluZGV4ID0gJCgnLmluZGV4LWxpc3RhZG9zIC5wYWdlLWl0ZW0nKVxuICAgICAgICAgIC5pbmRleCgkKCcuaW5kZXgtbGlzdGFkb3MgLnBhZ2UtaXRlbS5hY3RpdmUnKSk7XG4gICAgICAgIHZhciBtZWRpbyA9IE1hdGgucm91bmQodG90YWwgLyAyKTtcbiAgICAgICAgdmFyIGMxID0gTWF0aC5yb3VuZCh0b3RhbCAvIDQpO1xuICAgICAgICB2YXIgYzIgPSBNYXRoLnJvdW5kKHRvdGFsIC8gNCozKTtcbiAgICAgICAgdmFyIGkxID0gaW5kZXggLSAxXG4gICAgICAgIHZhciBpMiA9IGluZGV4ICsgMTtcbiAgICAgICAgdmFyIGFycmF5ID0gWzAsMSx0b3RhbC0xLGMxLG1lZGlvLGMyLGkxLGluZGV4LGkyLHRvdGFsXTtcbiAgICAgICAgJCgnLmluZGV4LWxpc3RhZG9zIC5wYWdlLWl0ZW0nKS5lYWNoKFxuICAgICAgICAgIGZ1bmN0aW9uKGkpe1xuICAgICAgICAgICAgaWYoJC5pbkFycmF5KGksYXJyYXkpID09IC0xKXtcbiAgICAgICAgICAgICQodGhpcykucmVtb3ZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgKTtcbn0pO1xuZnVuY3Rpb24gZW52aWFyQ29udGFjdG9Gb3JtKGRhdGEpIHtcbiAgdmFyIFhIUiA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICB2YXIgRkQgID0gbmV3IEZvcm1EYXRhKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmb3JtdWxhcmlvQ29udGFjdG8nKSk7XG4gIHZhciBjc3JmID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIm1ldGFbbmFtZT1jc3JmLXRva2VuXVwiKS5jb250ZW50O1xuICAvL3ZhciBmb3JtRGF0YSA9IEpTT04uc3RyaW5naWZ5KGRhdGEpO1xuXG4gIGZvcihuYW1lIGluIGRhdGEpIHtcbiAgICBGRC5hcHBlbmQobmFtZSwgZGF0YVtuYW1lXSk7XG4gIH1cblxuICBYSFIuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgYWxlcnQoJ1llYWghIERhdGEgc2VudCBhbmQgcmVzcG9uc2UgbG9hZGVkLicpO1xuICB9KTtcbiAgWEhSLmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBhbGVydCgnT29wcyEgU29tZXRoaW5nIHdlbnQgd3JvbmcuJyk7XG4gIH0pO1xuXG4gIC8vWEhSLm9wZW4oJ1BPU1QnLCAnaHR0cHM6Ly9leGFtcGxlLmNvbS8nKTtcbiAgWEhSLm9wZW4oICdQT1NUJywgJ2h0dHA6Ly8xMjcuMC4wLjE6NDAwMC8nICk7XG4gIFhIUi5zZXRSZXF1ZXN0SGVhZGVyKCAnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcgKTtcbiAgWEhSLnNldFJlcXVlc3RIZWFkZXIoIFwiWC1DU1JGLVRva2VuXCIsIGNzcmYpO1xuICBYSFIuc2VuZChGRCk7XG4gIC8vWEhSLnNlbmQoIFwiZm9ybXVsYXJpbz1cIitmb3JtRGF0YSApO1xufVxuZnVuY3Rpb24gYWN0dWFsaXphckNTUkYoKXtcbiAgdmFyIGNzcmYgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdtZXRhW25hbWU9XCJjc3JmLXRva2VuXCJdJykuY29udGVudFxuICB2YXIgaW5wdXRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcImlucHV0W25hbWU9J19jc3JmX3Rva2VuJ11cIik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaW5wdXRzLmxlbmd0aDsgKytpKSB7XG4gICAgaW5wdXRzW2ldLnZhbHVlID0gY3NyZjtcbiAgfVxufVxuJChkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24oKSB7XG4gIGFjdHVhbGl6YXJDU1JGKCk7XG59KTtcbiQoJyNDb21lbnRhcmlvc0N1ZW50YScpLm9uKCdzaG93LmJzLm1vZGFsJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gIHZhciBidXR0b24gPSAkKGV2ZW50LnJlbGF0ZWRUYXJnZXQpO1xuICB2YXIgdXJsID0gYnV0dG9uLmRhdGEoJ3VybCcpO1xuICB2YXIgbW9kYWwgPSAkKHRoaXMpXG4gIHZhciBxID0gbW9kYWwuZmluZCgnLmNvbl9yZWRpcmVjY2lvbicpXG4gIG1vZGFsLmZpbmQoJy5jb25fcmVkaXJlY2Npb24nKS5hdHRyKFwiaHJlZlwiLCBcIi9jb21lbnRhclwiK3VybClcbn0pXG4iXSwibWFwcGluZ3MiOiJBQUFBQSxDQUFDLENBQUNDLFFBQVEsQ0FBQyxDQUFDQyxLQUFLLENBQUMsWUFBVztFQUMzQkYsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLENBQUNHLElBQUksQ0FBQyxZQUFXO0lBQ3JDSCxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUNJLE9BQU8sQ0FBQyxDQUFDO0VBQ25CLENBQUMsQ0FBQztBQUNKLENBQUMsQ0FBQztBQUNGSixDQUFDLENBQUMsMlBBQTJQLENBQUMsQ0FBQ0csSUFBSSxDQUFDLFlBQVU7RUFDNVFILENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQ0ksT0FBTyxDQUFDO0lBQ2RDLFdBQVcsRUFBRSxjQUFjO0lBQzNCQyxrQkFBa0IsRUFBRSxDQUFDO0lBQ3JCQyxVQUFVLEVBQUUsSUFBSTtJQUNoQkMsS0FBSyxFQUFFLElBQUk7SUFDWEMsSUFBSSxFQUFFO01BQ0pDLEtBQUssRUFBRSxHQUFHO01BQ1ZDLEdBQUcsRUFBRyxTQUFBQSxDQUFVQyxNQUFNLEVBQUU7UUFDdEIsT0FBTyxhQUFhLEd
1BQUdBLE1BQU0sQ0FBQ0MsSUFBSTtNQUNwQyxDQUFDO01BQ0RDLFFBQVEsRUFBRSxNQUFNO01BQ2hCQyxjQUFjLEVBQUUsU0FBQUEsQ0FBVUMsSUFBSSxFQUFFSixNQUFNLEVBQUU7UUFDdEMsT0FBTztVQUNMSyxPQUFPLEVBQUVELElBQUksQ0FBQ0E7UUFDaEIsQ0FBQztNQUNIO0lBQ0Y7RUFDRixDQUFDLENBQUM7QUFDSixDQUFDLENBQUM7QUFDRmhCLENBQUMsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDRyxJQUFJLENBQUMsWUFBVTtFQUM3Q0gsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDSSxPQUFPLENBQUM7SUFDZEMsV0FBVyxFQUFFLGNBQWM7SUFDM0JDLGtCQUFrQixFQUFFLENBQUM7SUFDckJDLFVBQVUsRUFBRSxJQUFJO0lBQ2hCQyxLQUFLLEVBQUUsSUFBSTtJQUNYQyxJQUFJLEVBQUU7TUFDSkMsS0FBSyxFQUFFLEdBQUc7TUFDVkMsR0FBRyxFQUFHLFNBQUFBLENBQVVDLE1BQU0sRUFBRTtRQUN0QixPQUFPLGFBQWEsR0FBR0EsTUFBTSxDQUFDQyxJQUFJLEdBQUcsUUFBUTtNQUMvQyxDQUFDO01BQ0RDLFFBQVEsRUFBRSxNQUFNO01BQ2hCQyxjQUFjLEVBQUUsU0FBQUEsQ0FBVUMsSUFBSSxFQUFFSixNQUFNLEVBQUU7UUFDdEMsT0FBTztVQUNMSyxPQUFPLEVBQUVELElBQUksQ0FBQ0E7UUFDaEIsQ0FBQztNQUNIO0lBQ0Y7RUFDRixDQUFDLENBQUM7QUFDSixDQUFDLENBQUM7QUFDRmhCLENBQUMsQ0FBQyw4SUFBOEksQ0FBQyxDQUFDRyxJQUFJLENBQUMsWUFBVTtFQUMvSkgsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDSSxPQUFPLENBQUM7SUFDZEMsV0FBVyxFQUFFLGlCQUFpQjtJQUM5QkMsa0JBQWtCLEVBQUUsQ0FBQztJQUNyQkMsVUFBVSxFQUFFLElBQUk7SUFDaEJDLEtBQUssRUFBRSxJQUFJO0lBQ1hDLElBQUksRUFBRTtNQUNKQyxLQUFLLEVBQUUsR0FBRztNQUNWQyxHQUFHLEVBQUcsU0FBQUEsQ0FBVUMsTUFBTSxFQUFFO1FBQ3RCLE9BQU8sZUFBZSxHQUFHQSxNQUFNLENBQUNDLElBQUk7TUFDdEMsQ0FBQztNQUNEQyxRQUFRLEVBQUUsTUFBTTtNQUNoQkMsY0FBYyxFQUFFLFNBQUFBLENBQVVDLElBQUksRUFBRUosTUFBTSxFQUFFO1FBQ3RDLE9BQU87VUFDTEssT0FBTyxFQUFFRCxJQUFJLENBQUNBO1FBQ2hCLENBQUM7TUFDSDtJQUNGO0VBQ0YsQ0FBQyxDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBQ0YsU0FBU0UsNEJBQTRCQSxDQUFBLEVBQUU7RUFDckNsQixDQUFDLENBQUMsaUJBQWlCLENBQUMsQ0FBQ0csSUFBSSxDQUFDLFVBQVNnQixDQUFDLEVBQUVDLEdBQUcsRUFBQztJQUFDQyxxQkFBcUIsQ0FBQ0QsR0FBRyxDQUFDO0VBQUEsQ0FBQyxDQUFDO0FBQ3pFO0FBQ0EsU0FBU0MscUJBQXFCQSxDQUFDRCxHQUFHLEVBQUU7RUFDaENwQixDQUFDLENBQUNvQixHQUFHLENBQUMsQ0FBQ2hCLE9BQU8sQ0FBQztJQUNiQyxXQUFXLEVBQUUsaUJBQWlCO0lBQzlCQyxrQkFBa0IsRUFBRSxDQUFDO0lBQ3JCQyxVQUFVLEVBQUUsSUFBSTtJQUNoQkMsS0FBSyxFQUFFLElBQUk7SUFDWEMsSUFBSSxFQUFFO01BQ0pDLEtBQUssRUFBRSxHQUFHO01BQ1ZDLEdBQUcsRUFBRyxTQUFBQSxDQUFVQyxNQUFNLEVBQUU7UUFDdEIsT0FBTyxnQkFBZ0IsR0FBR0EsTUFBTSxDQUFDQyxJQUFJO01BQ3ZDLENBQUM7TUFDREMsUUFBUSxFQUFFLE1BQU07TUFDaEJDLGNBQWMsRUFBRSxTQUFBQSxDQUFVQyxJQUFJLEVBQUVKLE1BQU0sRUFBRTtRQUN0QyxPQUFPO1VBQ0xLLE9BQU8sRUFBRUQsSUFBSSxDQUFDQTtRQUNoQixDQUFDO01BQ0g7SUFDRjtFQUNGLENBQUMsQ0FBQztFQUNGaEIsQ0FBQyxDQUFDb0IsR0FBRyxDQUFDLENBQUNFLEVBQUUsQ0FBQyxRQUFRLEVBQUUsWUFBVTtJQUM1QixJQUFJQyxNQUFNLEdBQUd2QixDQUFDLENBQUMsSUFBSSxDQUFDLENBQUN3QixJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQ0MsSUFBSSxDQUFDLENBQUM7SUFDbkR6QixDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMwQixNQUFNLENBQUMsQ0FBQyxDQUFDQSxNQUFNLENBQUMsQ0FBQyxDQUFDRixJQUFJLENBQUMsWUFBWSxDQUFDLENBQUNHLEdBQUcsQ0FBQ0osTUFBTSxDQUFDO0VBQzFELENBQUUsQ0FBQztBQUNQO0FBQ0FMLDRCQUE0QixDQUFDLENBQUM7QUFDOUIsU0FBU1UsS0FBS0EsQ0FBQSxFQUFHO0VBQ2Y1QixDQUFDLENBQUMsa0xBQWtMLENBQUMsQ0FBQ0csSUFBSSxDQUFDLFlBQVU7SUFDbk1ILENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQ0ksT0FBTyxDQUFDO01BQ2RDLFdBQVcsRUFBRSxhQUFhO01BQzFCQyxrQkFBa0IsRUFBRSxDQUFDO01BQ3JCQyxVQUFVLEVBQUUsSUFBSTtNQUNoQkMsS0FBSyxFQUFFLElBQUk7TUFDWEMsSUFBSSxFQUFFO1FBQ0pDLEtBQUssRUFBRSxHQUFHO1FBQ1ZDLEdBQUcsRUFBRyxTQUFBQSxDQUFVQyxNQUFNLEVBQUU7VUFDdEIsT0FBTyxhQUFhLEd
1BQUdBLE1BQU0sQ0FBQ0MsSUFBSTtRQUNwQyxDQUFDO1FBQ0RDLFFBQVEsRUFBRSxNQUFNO1FBQ2hCQyxjQUFjLEVBQUUsU0FBQUEsQ0FBVUMsSUFBSSxFQUFFSixNQUFNLEVBQUU7VUFDdEMsT0FBTztZQUNMSyxPQUFPLEVBQUVELElBQUksQ0FBQ0E7VUFDaEIsQ0FBQztRQUNIO01BQ0Y7SUFDRixDQUFDLENBQUM7RUFDSixDQUFDLENBQUM7QUFDSjtBQUNBWSxLQUFLLENBQUMsQ0FBQztBQUNQLFNBQVNDLFFBQVFBLENBQUEsRUFBRztFQUNsQjdCLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDRyxJQUFJLENBQUMsWUFBVTtJQUNqQ0gsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDSSxPQUFPLENBQUM7TUFDZEMsV0FBVyxFQUFFLGdCQUFnQjtNQUM3QkMsa0JBQWtCLEVBQUUsQ0FBQztNQUNyQkMsVUFBVSxFQUFFLElBQUk7TUFDaEJDLEtBQUssRUFBRSxJQUFJO01BQ1hDLElBQUksRUFBRTtRQUNKQyxLQUFLLEVBQUUsR0FBRztRQUNWQyxHQUFHLEVBQUcsU0FBQUEsQ0FBVUMsTUFBTSxFQUFFO1VBQ3RCLE9BQU8sZ0JBQWdCLEdBQUdBLE1BQU0sQ0FBQ0MsSUFBSTtRQUN2QyxDQUFDO1FBQ0RDLFFBQVEsRUFBRSxNQUFNO1FBQ2hCQyxjQUFjLEVBQUUsU0FBQUEsQ0FBVUMsSUFBSSxFQUFFSixNQUFNLEVBQUU7VUFDdEMsT0FBTztZQUNMSyxPQUFPLEVBQUVELElBQUksQ0FBQ0E7VUFDaEIsQ0FBQztRQUNIO01BQ0Y7SUFDRixDQUFDLENBQUM7RUFDSixDQUFDLENBQUM7QUFDSjtBQUNBYSxRQUFRLENBQUMsQ0FBQztBQUVWLFNBQVNDLFdBQVdBLENBQUEsRUFBRztFQUNyQjlCLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDRyxJQUFJLENBQUMsWUFBVTtJQUNwQ0gsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDSSxPQUFPLENBQUM7TUFDZEMsV0FBVyxFQUFFLG1CQUFtQjtNQUNoQ0Msa0JBQWtCLEVBQUUsQ0FBQztNQUNyQkMsVUFBVSxFQUFFLElBQUk7TUFDaEJDLEtBQUssRUFBRSxJQUFJO01BQ1hDLElBQUksRUFBRTtRQUNKQyxLQUFLLEVBQUUsR0FBRztRQUNWQyxHQUFHLEVBQUcsU0FBQUEsQ0FBVUMsTUFBTSxFQUFFO1VBQ3RCLE9BQU8sa0JBQWtCLEdBQUdBLE1BQU0sQ0FBQ0MsSUFBSTtRQUN6QyxDQUFDO1FBQ0RDLFFBQVEsRUFBRSxNQUFNO1FBQ2hCQyxjQUFjLEVBQUUsU0FBQUEsQ0FBVUMsSUFBSSxFQUFFSixNQUFNLEVBQUU7VUFDdEMsT0FBTztZQUNMSyxPQUFPLEVBQUVELElBQUksQ0FBQ0E7VUFDaEIsQ0FBQztRQUNIO01BQ0Y7SUFDRixDQUFDLENBQUM7RUFDSixDQUFDLENBQUM7QUFDSjtBQUNBYyxXQUFXLENBQUMsQ0FBQztBQUViOUIsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDRyxJQUFJLENBQUMsVUFBU2dCLENBQUMsRUFBRUMsR0FBRyxFQUFDO0VBQUNXLHNCQUFzQixDQUFDWCxHQUFHLENBQUM7QUFBQSxDQUFDLENBQUM7QUFDcEUsU0FBU1ksOEJBQThCQSxDQUFBLEVBQUU7RUFDdkNoQyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUNHLElBQUksQ0FBQyxVQUFTZ0IsQ0FBQyxFQUFFQyxHQUFHLEVBQUM7SUFBQ1csc0JBQXNCLENBQUNYLEdBQUcsQ0FBQztFQUFBLENBQUMsQ0FBQztBQUN0RTtBQUNBLFNBQVNXLHNCQUFzQkEsQ0FBQ1gsR0FBRyxFQUFDO0VBQ2xDcEIsQ0FBQyxDQUFDb0IsR0FBRyxDQUFDLENBQUNoQixPQUFPLENBQUM7SUFDYkMsV0FBVyxFQUFFLGlCQUFpQjtJQUM5QkMsa0JBQWtCLEVBQUUsQ0FBQztJQUNyQkMsVUFBVSxFQUFFLElBQUk7SUFDaEJDLEtBQUssRUFBRSxJQUFJO0lBQ1hDLElBQUksRUFBRTtNQUNKQyxLQUFLLEVBQUUsR0FBRztNQUNWQyxHQUFHLEVBQUcsU0FBQUEsQ0FBVUMsTUFBTSxFQUFFO1FBQ3RCLE9BQU8saUJBQWlCLEdBQUdBLE1BQU0sQ0FBQ0MsSUFBSTtNQUN4QyxDQUFDO01BQ0RDLFFBQVEsRUFBRSxNQUFNO01BQ2hCQyxjQUFjLEVBQUUsU0FBQUEsQ0FBVUMsSUFBSSxFQUFFSixNQUFNLEVBQUU7UUFDdEMsT0FBTztVQUNMSyxPQUFPLEVBQUVELElBQUksQ0FBQ0E7UUFDaEIsQ0FBQztNQUNIO0lBQ0Y7RUFDRixDQUFDLENBQUM7RUFDRmhCLENBQUMsQ0FBQ29CLEdBQUcsQ0FBQyxDQUFDRSxFQUFFLENBQUMsUUFBUSxFQUFFLFlBQVU7SUFDNUIsSUFBSUMsTUFBTSxHQUFHdkIsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDd0IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUNDLElBQUksQ0FBQyxDQUFDO0lBQ25EekIsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ0EsTUFBTSxDQUFDLENBQUMsQ0FBQ0YsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDRyxHQUFHLENBQUNKLE1BQU0sQ0FBQztFQUMzRCxDQUFFLENBQUM7QUFDTDtBQUFDO0FBQ0R2QixDQUFDLENBQUMsbUJBQW1CLENBQUMsQ0FBQ0csSUFBSSxDQUFDLFVBQVNnQixDQUFDLEVBQUVDLEdBQUcsRUFBQztFQUFDYSw0QkFBNEIsQ0FBQ2IsR0FBRyxDQUFDO0FBQUEsQ0FBQyxDQUFDO0FBQ2hGLFNBQVNjLG9DQUFvQ0EsQ0FBQSxFQUFFO0VBQzdDbEMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLENBQUNHLElBQUksQ0FBQyxVQUFTZ0IsQ0FBQyxFQUFFQyxHQUFHLEVBQUM7SUFBQ2EsNEJBQTRCLENBQUNiLEdBQUcsQ0FBQztFQUFBLENBQUMsQ0FBQztBQUNsRjtBQUNBLFNBQVNhLDRCQUE0QkEsQ0FBQ2IsR0FBRyxFQUFDO0VBQ3hDcEIsQ0FBQyxDQUFDb0IsR0FBRyxDQUFDLENBQUNoQixPQUFPLENBQUM7SUFDYkMsV0FBVyxFQUFFLGlCQUFpQjtJQUM5QkMsa0JBQWtCLEVBQUUsQ0FBQztJQUNyQkMsVUFBVSxFQUFFLElBQUk7SUFDaEJDLEtBQUssRUFBRSxJQUFJO0lBQ1hDLElBQUksRUFBRTtNQUNKQyxLQUFLLEVBQUUsR0FBRztNQUNWQyxHQUFHLEVBQUcsU0FBQUEsQ0FBVUMsTUFBTSxFQUFFO1FBQ3RCLE9BQU8sdUJBQXVCLEdBQUdBLE1BQU0sQ0FBQ0MsSUFBSTtNQUM5QyxDQUFDO01BQ0RDLFFBQVEsRUFBRSxNQUFNO01BQ2hCQyxjQUFjLEVBQUUsU0FBQUEsQ0FBVUMsSUFBSSxFQUFFSixNQUFNLEVBQUU7UUFDdEMsT0FBTztVQUNMSyxPQUFPLEVBQUVELElBQUksQ0FBQ0E7UUFDaEIsQ0FBQztNQUNIO0lBQ0Y7RUFDRixDQUFDLENBQUM7RUFDRmhCLENBQUMsQ0FBQ29CLEdBQUcsQ0FBQyxDQUFDRSxFQUFFLENBQUMsUUFBUSxFQUFFLFlBQVU7SUFDNUIsSUFBSUMsTUFBTSxHQUFHdkIsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDd0IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUNDLElBQUksQ0FBQyxDQUFDO0lBQ25EekIsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ0EsTUFBTSxDQUFDLENBQUMsQ0FBQ0YsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDRyxHQU
1FHLENBQUNKLE1BQU0sQ0FBQztFQUMzRCxDQUFFLENBQUM7QUFDTDtBQUFDO0FBRUR2QixDQUFDLENBQUNDLFFBQVEsQ0FBQyxDQUFDcUIsRUFBRSxDQUFDLE9BQU8sRUFBQyw0QkFBNEIsRUFBRSxVQUFTYSxDQUFDLEVBQUU7RUFDL0RBLENBQUMsQ0FBQ0MsY0FBYyxDQUFDLENBQUM7RUFDbEIsSUFBSUMsSUFBSSxHQUFHLElBQUlDLElBQUksQ0FBQyxDQUFDLENBQUNDLE9BQU8sQ0FBQyxDQUFDO0VBQy9CLElBQUlDLFFBQVEsR0FBR3hDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQ2dCLElBQUksQ0FBQyxVQUFVLENBQUM7RUFDdkMsSUFBSXlCLElBQUksR0FBR3pDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQzBCLE1BQU0sQ0FBQyxDQUFDLENBQUNGLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQ0EsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDa0IsTUFBTTtFQUNuRSxJQUFJRCxJQUFJLEdBQUcsQ0FBQyxFQUFFO0lBQ1osSUFBSUUsRUFBRSxHQUFHM0MsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FDdEJGLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQ0EsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDb0IsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDQyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBQ3BERixFQUFFLEdBQUdBLEVBQUUsQ0FBQ0csS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztFQUN2QixDQUFDLE1BQUk7SUFDSCxJQUFJSCxFQUFFLEdBQUczQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMwQixNQUFNLENBQUMsQ0FBQyxDQUN0QkYsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDQSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUNvQixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUNDLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDckRGLEVBQUUsR0FBR0EsRUFBRSxDQUFDRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0VBQ3ZCO0VBQ0EsSUFBSUMsYUFBYSxHQUFHUCxRQUFRLENBQ3pCUSxPQUFPLENBQUMsbUJBQW1CLEVBQUUsY0FBY1gsSUFBSSxHQUFHLENBQUMsQ0FDbkRXLE9BQU8sQ0FBQyxlQUFlLEVBQUUsVUFBVUwsRUFBRSxHQUFHLENBQUMsQ0FDekNLLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRSxjQUFjTCxFQUFFLEdBQUcsQ0FBQyxDQUNqREssT0FBTyxDQUFDLGVBQWUsRUFBRSxhQUFhWCxJQUFJLEdBQUcsQ0FBQyxDQUM5Q1csT0FBTyxDQUFDLFdBQVcsRUFBRSxTQUFTTCxFQUFFLEdBQUcsQ0FBQyxDQUNwQ0ssT0FBTyxDQUFDLGVBQWUsRUFBRSxhQUFhTCxFQUFFLEdBQUcsQ0FBQztFQUMvQyxJQUFJTSxtQkFBbUIsR0FBRyxJQUFJLENBQUNDLFVBQVUsQ0FBQ0MsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDQyxTQUFTLENBQUMsSUFBSSxDQUFDO0VBQ3BGLElBQUlDLGtCQUFrQixHQUFHSixtQkFBbUIsQ0FBQ0ssZ0JBQWdCLENBQUMsSUFBSSxDQUFDO0VBQ25FdEQsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ0YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDK0IsT0FBTyxDQUFDUixhQUFhLENBQUM7RUFDekQ7RUFDQWYsOEJBQThCLENBQUMsQ0FBQztFQUNoQ0Usb0NBQW9DLENBQUMsQ0FBQztFQUN0QyxJQUFJc0IsU0FBUyxHQUFHeEQsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLENBQUMyQixHQUFHLENBQUMsQ0FBQztFQUM3QzNCLENBQUMsQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDMkIsR0FBRyxDQUFDNkIsU0FBUyxDQUFDO0FBQzdELENBQUMsQ0FBQztBQUNGO0FBQ0E7QUFDQXhELENBQUMsQ0FBQ0MsUUFBUSxDQUFDLENBQUNxQixFQUFFLENBQUMsT0FBTyxFQUFDLG1CQUFtQixFQUFFLFVBQVNhLENBQUMsRUFBRTtFQUN0REEsQ0FBQyxDQUFDQyxjQUFjLENBQUMsQ0FBQztFQUNsQixJQUFJQyxJQUFJLEdBQUcsSUFBSUMsSUFBSSxDQUFDLENBQUMsQ0FBQ0MsT0FBTyxDQUFDLENBQUM7RUFDL0IsSUFBSUMsUUFBUSxHQUFHeEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUN2QyxJQUFJeUIsSUFBSSxHQUFHekMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ0YsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDQSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUNrQixNQUFNO0VBQ25FLElBQUlELElBQUksR0FBRyxDQUFDLEVBQUU7SUFDWixJQUFJRSxFQUFFLEdBQUczQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMwQixNQUFNLENBQUMsQ0FBQyxDQUN0QkYsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDQSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUNvQixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUNDLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDcERGLEVBQUUsR0FBR0EsRUFBRSxDQUFDRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0VBQ3ZCLENBQUMsTUFBSTtJQUNILElBQUlILEVBQUUsR0FBRzNDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQzBCLE1BQU0sQ0FBQyxDQUFDLENBQ3RCRixJQUFJLENBQUMsU0FBUyxDQUFDLENBQUNBLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQ29CLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQ0MsSUFBSSxDQUFDLElBQUksQ0FBQztJQUNyREYsRUFBRSxHQUFHQSxFQUFFLENBQUNHLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7RUFDdkI7RUFDQSxJQUFJQyxhQUFhLEdBQUdQLFFBQVEsQ0FDekJRLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRSxjQUFjWCxJQUFJLEdBQUcsQ0FBQyxDQUNuRFcsT0FBTyxDQUFDLGVBQWUsRUFBRSxVQUFVTCxFQUFFLEdBQUcsQ0FBQyxDQUN6Q0ssT0FBTyxDQUFDLG1CQUFtQixFQUFFLGNBQWNMLEVBQUUsR0FBRyxDQUFDLENBQ2pESyxPQUFPLENBQUMsZUFBZSxFQUFFLGFBQWFYLElBQUksR0FBRyxDQUFDLENBQzlDVyxPQUFPLENBQUMsV0FBVyxFQUFFLFNBQVNMLEVBQUUsR0FBRyxDQUFDLENBQ3BDSyxPQUFPLENBQUMsZUFBZSxFQUFFLGFBQWFMLEVBQUUsR0FBRyxDQUFDO0VBQy9DLElBQUlNLG1CQUFtQixHQUFHLElBQUksQ0FBQ0MsVUFBVSxDQUFDQyxhQUFhLENBQUMsV0FBVyxDQUFDLENBQUNDLFNBQVMsQ0FBQyxJQUFJLENBQUM7RUFDcEYsSUFBSUMsa0JBQWtCLEdBQUdKLG1CQUFtQixDQUFDSyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUM7RUFDbkUsSUFBSUcsUUFBUSxHQUFHekQsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ0YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDK0IsT0FBTyxDQUFDUixhQU
1FhLENBQUM7O0VBRXhFO0VBQ0FmLDhCQUE4QixDQUFDLENBQUM7RUFDaENFLG9DQUFvQyxDQUFDLENBQUM7RUFDdEMsSUFBSXNCLFNBQVMsR0FBR3hELENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDMkIsR0FBRyxDQUFDLENBQUM7RUFDN0MzQixDQUFDLENBQUMseUNBQXlDLENBQUMsQ0FBQzJCLEdBQUcsQ0FBQzZCLFNBQVMsQ0FBQztFQUMzRCxJQUFJRSxVQUFVLEdBQUcsSUFBSSxDQUFDUixVQUFVLENBQUNDLGFBQWEsQ0FBQyxXQUFXLENBQUM7RUFDM0QsSUFBSVEsU0FBUyxHQUFHRCxVQUFVLENBQUNKLGdCQUFnQixDQUFDLElBQUksQ0FBQztFQUNqREksVUFBVSxDQUFDRSxTQUFTLEdBQUcsRUFBRTtFQUN6QkQsU0FBUyxHQUFHRSx1QkFBdUIsQ0FBQ1Isa0JBQWtCLEVBQUVNLFNBQVMsQ0FBQztFQUNsRUEsU0FBUyxDQUFDRyxPQUFPLENBQUMsVUFBUzNCLENBQUMsRUFBQ2hCLENBQUMsRUFBQzRDLENBQUMsRUFBQztJQUM5QkwsVUFBVSxDQUFDTSxXQUFXLENBQUM3QixDQUFDLENBQUM7RUFDNUIsQ0FBQyxDQUFDO0VBQ0Y4QixlQUFlLENBQUNQLFVBQVUsQ0FBQztFQUMzQlEsWUFBWSxDQUFDUixVQUFVLENBQUM7RUFDeEJPLGVBQWUsQ0FBQ1AsVUFBVSxDQUFDO0VBQzNCUywwQkFBMEIsQ0FBQyxDQUFDO0FBQzlCLENBQUMsQ0FBQztBQUVGLFNBQVNOLHVCQUF1QkEsQ0FBQ08sUUFBUSxFQUFFQyxLQUFLLEVBQUM7RUFDL0MsSUFBSUMsUUFBUSxHQUFHLENBQUMsR0FBR0QsS0FBSyxDQUFDLENBQUNFLE1BQU0sQ0FBQ3BDLENBQUMsSUFBSSxDQUFDQSxDQUFDLENBQUNnQixhQUFhLENBQUMsMEJBQTBCLENBQUMsQ0FBQ3FCLE9BQU8sQ0FBQztFQUMzRixJQUFJQyxRQUFRLEdBQUcsQ0FBQztFQUNoQixJQUFJQyxDQUFDLEdBQUdMLEtBQUssQ0FBQzNCLE1BQU07RUFDcEIyQixLQUFLLEdBQUcsRUFBRTtFQUNWLEtBQUssSUFBSWxELENBQUMsR0FBRyxDQUFDLEVBQUVBLENBQUMsR0FBRXVELENBQUMsRUFBRXZELENBQUMsRUFBRSxFQUFFO0lBQ3pCLElBQUlpRCxRQUFRLENBQUNqRCxDQUFDLENBQUMsSUFDUmlELFFBQVEsQ0FBQ2pELENBQUMsQ0FBQyxDQUFDZ0MsYUFBYSxDQUFDLDBCQUEwQixDQUFDLENBQUNxQixPQUFPLEVBQUM7TUFDbkVILEtBQUssQ0FBQ2xELENBQUMsQ0FBQyxHQUFHaUQsUUFBUSxDQUFDakQsQ0FBQyxDQUFDO0lBQ3hCLENBQUMsTUFBTTtNQUNMa0QsS0FBSyxDQUFDbEQsQ0FBQyxDQUFDLEdBQUdtRCxRQUFRLENBQUNHLFFBQVEsQ0FBQztNQUM3QixFQUFFQSxRQUFRO0lBQ1o7RUFDRjtFQUNBLE9BQU9KLEtBQUs7QUFDZDtBQUVBLFNBQVNILFlBQVlBLENBQUNSLFVBQVUsRUFBQztFQUMvQixJQUFJQyxTQUFTLEdBQUdELFVBQVUsQ0FBQ0osZ0JBQWdCLENBQUMsSUFBSSxDQUFDO0VBQ2pESyxTQUFTLEdBQUdnQixLQUFLLENBQUNDLElBQUksQ0FBQ2pCLFNBQVMsQ0FBQyxDQUFDa0IsSUFBSSxDQUFDLFVBQVNkLENBQUMsRUFBQ2UsQ0FBQyxFQUFDO0lBQ2xEO0lBQ0E7SUFDQWYsQ0FBQyxHQUFHQSxDQUFDLENBQUNaLGFBQWEsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDNEIsS0FBSztJQUNqREQsQ0FBQyxHQUFHQSxDQUFDLENBQUMzQixhQUFhLENBQUMsc0JBQXNCLENBQUMsQ0FBQzRCLEtBQUs7SUFDakQsT0FBUWhCLENBQUMsR0FBR2UsQ0FBQztFQUNmLENBQUMsQ0FBQztFQUNBOztFQUVGcEIsVUFBVSxDQUFDRSxTQUFTLEdBQUcsRUFBRTtFQUN6QkQsU0FBUyxDQUFDRyxPQUFPLENBQUMsVUFBUzNCLENBQUMsRUFBQ2hCLENBQUMsRUFBQzRDLENBQUMsRUFBQztJQUM5QkwsVUFBVSxDQUFDTSxXQUFXLENBQUM3QixDQUFDLENBQUM7RUFDNUIsQ0FBQyxDQUFDO0FBRUo7QUFDQSxTQUFTOEIsZUFBZUEsQ0FBQ1AsVUFBVSxFQUFDO0VBQ2xDLElBQUlDLFNBQVMsR0FBR0QsVUFBVSxDQUFDSixnQkFBZ0IsQ0FBQyxJQUFJLENBQUM7RUFDakRLLFNBQVMsQ0FBQ0csT0FBTyxDQUFDLFVBQVMzQixDQUFDLEVBQUNoQixDQUFDLEVBQUM0QyxDQUFDLEVBQUM7SUFDL0JpQixLQUFLLEdBQUc3QyxDQUFDLENBQUNnQixhQUFhLENBQUMsc0JBQXNCLENBQUM7SUFDL0M2QixLQUFLLENBQUNELEtBQUssR0FBRyxDQUFDNUQsQ0FBQyxHQUFDLENBQUMsSUFBRSxFQUFFO0VBQ3hCLENBQUMsQ0FBQztBQUNKO0FBQ0EsSUFBSThELE1BQU0sR0FBRyxTQUFBQSxDQUFTQyxLQUFLLEVBQUM7RUFDMUJBLEtBQUssQ0FBQzlDLGNBQWMsQ0FBQyxDQUFDO0VBQ2xCOEMsS0FBSyxDQUFDQyxlQUFlLENBQUMsQ0FBQztFQUN2QixJQUFJSCxLQUFLLEdBQUcsSUFBSSxDQUFDOUIsVUFBVSxDQUFDQSxVQUFVLENBQUNDLGFBQWEsQ0FBQyxzQkFBc0IsQ0FBQztFQUM1RTZCLEtBQUssQ0FBQ0QsS0FBSyxHQUFHSyxRQUFRLENBQUNKLEtBQUssQ0FBQ0QsS0FBSyxDQUFDLEdBQUcsRUFBRTtFQUN4QyxJQUFJckIsVUFBVSxHQUFHLElBQUksQ0FBQ1IsVUFBVSxDQUFDQSxVQUFVLENBQUNBLFVBQVU7RUFDdERnQixZQUFZLENBQUNSLFVBQVUsQ0FBQztFQUN4Qk8sZUFBZSxDQUFDUCxVQUFVLENBQUM7QUFFakMsQ0FBQztBQUNELElBQUkyQixLQUFLLEdBQUcsU0FBQUEsQ0FBU0gsS0FBSyxFQUFDO0VBQ3pCQSxLQUFLLENBQUM5QyxjQUFjLENBQUMsQ0FBQztFQUNsQjhDLEtBQUssQ0FBQ0MsZUFBZSxDQUFDLENBQUM7RUFDdkIsSUFBSUgsS0FBSyxHQUFHLElBQUksQ0FBQzlCLFVBQVUsQ0FBQ0EsVUFBVSxDQUFDQyxhQUFhLENBQUMsc0JBQXNCLENBQUM7RUFDNUU2QixLQUFLLENBQUNELEtBQUssR0FBR0ssUUFBUSxDQUFDSixLQUFLLENBQUNELEtBQUssQ0FBQyxHQUFHLEVBQUU7RUFDeEMsSUFBSXJCLFVBQVUsR0FBRyxJQUFJLENBQUNSLFVBQVUsQ0FBQ0EsVUFBVSxDQUFDQSxVQUFVO0VBQ3REZ0IsWUFBWSxDQUFDUixVQUFVLENBQUM7RUFDeEJPLGVBQWUsQ0FBQ1AsVUFBVSxDQUFDO0FBQ2pDLENBQUM7QUFFRCxTQUFTUywwQkFBMEJBLENBQUEsRUFBRTtFQUNuQyxJQUFJbUIsU0FBUyxHQUFHckYsUUFBUSxDQUFDcUQsZ0JBQWdCLENBQUMsY0FBYyxDQUFDO0VBQ3pELElBQUlpQyxXQUFXLEdBQUd0RixRQUFRLENBQUNxRCxnQkFBZ0IsQ0FBQyxnQkFBZ0IsQ0FBQztFQUU3RCxLQUFLLElBQUluQyxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdtRSxTQUFTLENBQUM1QyxN
1QUFNLEVBQUV2QixDQUFDLEVBQUUsRUFBRTtJQUN6Q21FLFNBQVMsQ0FBQ25FLENBQUMsQ0FBQyxDQUFDcUUsbUJBQW1CLENBQUMsT0FBTyxFQUFFUCxNQUFNLENBQUM7RUFBQztFQUNwRCxLQUFLLElBQUk5RCxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdvRSxXQUFXLENBQUM3QyxNQUFNLEVBQUV2QixDQUFDLEVBQUUsRUFBRTtJQUMzQ29FLFdBQVcsQ0FBQ3BFLENBQUMsQ0FBQyxDQUFDcUUsbUJBQW1CLENBQUMsT0FBTyxFQUFFSCxLQUFLLENBQUM7RUFBQztFQUVyRCxLQUFLLElBQUlsRSxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdtRSxTQUFTLENBQUM1QyxNQUFNLEVBQUV2QixDQUFDLEVBQUUsRUFBRTtJQUN6Q21FLFNBQVMsQ0FBQ25FLENBQUMsQ0FBQyxDQUFDc0UsZ0JBQWdCLENBQUMsT0FBTyxFQUFFUixNQUFNLENBQUM7RUFDaEQ7RUFDQSxLQUFLLElBQUk5RCxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdvRSxXQUFXLENBQUM3QyxNQUFNLEVBQUV2QixDQUFDLEVBQUUsRUFBRTtJQUMzQ29FLFdBQVcsQ0FBQ3BFLENBQUMsQ0FBQyxDQUFDc0UsZ0JBQWdCLENBQUMsT0FBTyxFQUFFSixLQUFLLENBQUM7RUFDakQ7QUFDRjtBQUNBbEIsMEJBQTBCLENBQUMsQ0FBQztBQUM1Qm5FLENBQUMsQ0FBQ0MsUUFBUSxDQUFDLENBQUNxQixFQUFFLENBQUMsT0FBTyxFQUFDLGtCQUFrQixFQUFFLFVBQVNhLENBQUMsRUFBRTtFQUNyREEsQ0FBQyxDQUFDQyxjQUFjLENBQUMsQ0FBQztFQUNsQixJQUFJQyxJQUFJLEdBQUcsSUFBSUMsSUFBSSxDQUFDLENBQUMsQ0FBQ0MsT0FBTyxDQUFDLENBQUM7RUFDL0IsSUFBSUMsUUFBUSxHQUFHeEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUN2QyxJQUFJK0IsYUFBYSxHQUFHUCxRQUFRLENBQUNRLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSVgsSUFBSSxHQUFHLENBQUM7RUFDM0RVLGFBQWEsR0FBR0EsYUFBYSxDQUFDQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzFEckMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ2dFLEtBQUssQ0FBQzNDLGFBQWEsQ0FBQztFQUNyQ25CLEtBQUssQ0FBQyxDQUFDO0VBQ1BDLFFBQVEsQ0FBQyxDQUFDO0VBQ1ZDLFdBQVcsQ0FBQyxDQUFDO0FBQ2YsQ0FBQyxDQUFDOztBQUVGO0FBQ0E5QixDQUFDLENBQUNDLFFBQVEsQ0FBQyxDQUFDcUIsRUFBRSxDQUFDLE9BQU8sRUFBQywwQkFBMEIsRUFBRSxVQUFTYSxDQUFDLEVBQUU7RUFDN0RBLENBQUMsQ0FBQ0MsY0FBYyxDQUFDLENBQUM7RUFDbEIsSUFBSUMsSUFBSSxHQUFHLElBQUlDLElBQUksQ0FBQyxDQUFDLENBQUNDLE9BQU8sQ0FBQyxDQUFDO0VBQy9CLElBQUlDLFFBQVEsR0FBR3hDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQ2dCLElBQUksQ0FBQyxVQUFVLENBQUM7RUFDdkMsSUFBSStCLGFBQWEsR0FBR1AsUUFBUSxDQUFDUSxPQUFPLENBQUMsUUFBUSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzNEVSxhQUFhLEdBQUdBLGFBQWEsQ0FBQ0MsT0FBTyxDQUFDLE1BQU0sRUFBRSxJQUFJWCxJQUFJLEdBQUcsQ0FBQztFQUMxRHJDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQzJGLE1BQU0sQ0FBQzVDLGFBQWEsQ0FBQztBQUMvQixDQUFDLENBQUM7QUFDRi9DLENBQUMsQ0FBQ0MsUUFBUSxDQUFDLENBQUNxQixFQUFFLENBQUMsT0FBTyxFQUFDLG1CQUFtQixFQUFFLFVBQVNhLENBQUMsRUFBRTtFQUN0REEsQ0FBQyxDQUFDQyxjQUFjLENBQUMsQ0FBQztFQUNsQixJQUFJQyxJQUFJLEdBQUcsSUFBSUMsSUFBSSxDQUFDLENBQUMsQ0FBQ0MsT0FBTyxDQUFDLENBQUM7RUFDL0IsSUFBSUMsUUFBUSxHQUFHeEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUN2QyxJQUFJK0IsYUFBYSxHQUFHUCxRQUFRLENBQUNRLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSVgsSUFBSSxHQUFHLENBQUM7RUFDM0RVLGFBQWEsR0FBR0EsYUFBYSxDQUFDQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzFEckMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMkYsTUFBTSxDQUFDNUMsYUFBYSxDQUFDO0VBQzdCL0MsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDNEYsVUFBVSxDQUFDLENBQUM7RUFDN0JoRSxLQUFLLENBQUMsQ0FBQztFQUNQTSxvQ0FBb0MsQ0FBQyxDQUFDO0VBQ3RDaEIsNEJBQTRCLENBQUMsQ0FBQztBQUNoQyxDQUFDLENBQUM7QUFDRmxCLENBQUMsQ0FBQ0MsUUFBUSxDQUFDLENBQUNxQixFQUFFLENBQUMsT0FBTyxFQUFDLHVCQUF1QixFQUFFLFVBQVNhLENBQUMsRUFBRTtFQUMxREEsQ0FBQyxDQUFDQyxjQUFjLENBQUMsQ0FBQztFQUNsQixJQUFJQyxJQUFJLEdBQUcsSUFBSUMsSUFBSSxDQUFDLENBQUMsQ0FBQ0MsT0FBTyxDQUFDLENBQUM7RUFDL0IsSUFBSUMsUUFBUSxHQUFHeEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUN2QyxJQUFJK0IsYUFBYSxHQUFHUCxRQUFRLENBQUNRLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSVgsSUFBSSxHQUFHLENBQUM7RUFDM0RVLGFBQWEsR0FBR0EsYUFBYSxDQUFDQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzFEckMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ2lFLE1BQU0sQ0FBQzVDLGFBQWEsQ0FBQztFQUN0Q25CLEtBQUssQ0FBQyxDQUFDO0FBQ1QsQ0FBQyxDQUFDO0FBQ0Y7QUFDQTVCLENBQUMsQ0FBQ0MsUUFBUSxDQUFDLENBQUNxQixFQUFFLENBQUMsT0FBTyxFQUFDLDJCQUEyQixFQUFFLFVBQVNhLENBQUMsRUFBRTtFQUM5REEsQ0FBQyxDQUFDQyxjQUFjLENBQUMsQ0FBQztFQUNsQixJQUFJQyxJQUFJLEdBQUcsSUFBSUMsSUFBSSxDQUFDLENBQUMsQ0FBQ0MsT0FBTyxDQUFDLENBQUM7RUFDL0IsSUFBSUMsUUFBUSxHQUFHeEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUN2QyxJQUFJK0IsYUFBYSxHQUFHUCxRQUFRLENBQUNRLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSVgsSUFBSSxHQUFHLENBQUM7RUFDM0RVLGFBQWEsR0FBR0EsYUFBYSxDQUFDQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzFEO0VBQ0FyQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMyRixN
1QUFNLENBQUM1QyxhQUFhLENBQUM7RUFDN0IvQyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUM0RixVQUFVLENBQUMsQ0FBQztFQUM3QmhFLEtBQUssQ0FBQyxDQUFDO0VBQ1BFLFdBQVcsQ0FBQyxDQUFDO0VBQ2JELFFBQVEsQ0FBQyxDQUFDO0FBQ1osQ0FBQyxDQUFDO0FBRUY3QixDQUFDLENBQUNDLFFBQVEsQ0FBQyxDQUFDcUIsRUFBRSxDQUFDLE9BQU8sRUFBQyxxQkFBcUIsRUFBRSxVQUFTYSxDQUFDLEVBQUU7RUFDeERBLENBQUMsQ0FBQ0MsY0FBYyxDQUFDLENBQUM7RUFDbEIsSUFBSUMsSUFBSSxHQUFHLElBQUlDLElBQUksQ0FBQyxDQUFDLENBQUNDLE9BQU8sQ0FBQyxDQUFDO0VBQy9CLElBQUlDLFFBQVEsR0FBR3hDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQ2dCLElBQUksQ0FBQyxVQUFVLENBQUM7RUFDdkMsSUFBSStCLGFBQWEsR0FBR1AsUUFBUSxDQUFDUSxPQUFPLENBQUMsUUFBUSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzNEVSxhQUFhLEdBQUdBLGFBQWEsQ0FBQ0MsT0FBTyxDQUFDLE1BQU0sRUFBRSxJQUFJWCxJQUFJLEdBQUcsQ0FBQztFQUMxRHJDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQzBCLE1BQU0sQ0FBQyxDQUFDLENBQUNpRSxNQUFNLENBQUM1QyxhQUFhLENBQUM7RUFDdENmLDhCQUE4QixDQUFDLENBQUM7RUFDaENFLG9DQUFvQyxDQUFDLENBQUM7QUFDeEMsQ0FBQyxDQUFDO0FBQ0ZsQyxDQUFDLENBQUNDLFFBQVEsQ0FBQyxDQUFDcUIsRUFBRSxDQUFDLE9BQU8sRUFBQyxlQUFlLEVBQUUsVUFBU2EsQ0FBQyxFQUFFO0VBQ2xEQSxDQUFDLENBQUNDLGNBQWMsQ0FBQyxDQUFDO0VBQ2xCLElBQUlDLElBQUksR0FBRyxJQUFJQyxJQUFJLENBQUMsQ0FBQyxDQUFDQyxPQUFPLENBQUMsQ0FBQztFQUMvQixJQUFJQyxRQUFRLEdBQUd4QyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUNnQixJQUFJLENBQUMsVUFBVSxDQUFDO0VBQ3ZDLElBQUkrQixhQUFhLEdBQUdQLFFBQVEsQ0FBQ1EsT0FBTyxDQUFDLFFBQVEsRUFBRSxJQUFJWCxJQUFJLEdBQUcsQ0FBQztFQUMzRFUsYUFBYSxHQUFHQSxhQUFhLENBQUNDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsSUFBSVgsSUFBSSxHQUFHLENBQUM7RUFDMURyQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMwQixNQUFNLENBQUMsQ0FBQyxDQUFDaUUsTUFBTSxDQUFDNUMsYUFBYSxDQUFDO0FBQ3hDLENBQUMsQ0FBQztBQUNGL0MsQ0FBQyxDQUFDQyxRQUFRLENBQUMsQ0FBQ3FCLEVBQUUsQ0FBQyxPQUFPLEVBQUMsZUFBZSxFQUFFLFVBQVNhLENBQUMsRUFBRTtFQUNsREEsQ0FBQyxDQUFDQyxjQUFjLENBQUMsQ0FBQztFQUNsQixJQUFJQyxJQUFJLEdBQUcsSUFBSUMsSUFBSSxDQUFDLENBQUMsQ0FBQ0MsT0FBTyxDQUFDLENBQUM7RUFDL0IsSUFBSUMsUUFBUSxHQUFHeEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUN2QyxJQUFJK0IsYUFBYSxHQUFHUCxRQUFRLENBQUNRLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSVgsSUFBSSxHQUFHLENBQUM7RUFDM0RVLGFBQWEsR0FBR0EsYUFBYSxDQUFDQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzFEckMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ2lFLE1BQU0sQ0FBQzVDLGFBQWEsQ0FBQztBQUN4QyxDQUFDLENBQUM7QUFDRi9DLENBQUMsQ0FBQ0MsUUFBUSxDQUFDLENBQUNxQixFQUFFLENBQUMsT0FBTyxFQUFDLHFCQUFxQixFQUFFLFVBQVNhLENBQUMsRUFBRTtFQUN4REEsQ0FBQyxDQUFDQyxjQUFjLENBQUMsQ0FBQztFQUNsQixJQUFJQyxJQUFJLEdBQUcsSUFBSUMsSUFBSSxDQUFDLENBQUMsQ0FBQ0MsT0FBTyxDQUFDLENBQUM7RUFDL0IsSUFBSUMsUUFBUSxHQUFHeEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUN2QyxJQUFJK0IsYUFBYSxHQUFHUCxRQUFRLENBQUNRLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSVgsSUFBSSxHQUFHLENBQUM7RUFDM0RVLGFBQWEsR0FBR0EsYUFBYSxDQUFDQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzFEckMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ2lFLE1BQU0sQ0FBQzVDLGFBQWEsQ0FBQztFQUN0QzhDLE1BQU0sQ0FBQyxDQUFDO0VBQ1JDLGNBQWMsQ0FBQyxDQUFDO0FBQ2xCLENBQUMsQ0FBQztBQUNGOUYsQ0FBQyxDQUFDQyxRQUFRLENBQUMsQ0FBQ3FCLEVBQUUsQ0FBQyxPQUFPLEVBQUMsc0JBQXNCLEVBQUUsVUFBU2EsQ0FBQyxFQUFFO0VBQ3pELElBQUk0RCxhQUFhLEdBQUcvRixDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM2QyxJQUFJLENBQUMsaUJBQWlCLENBQUM7RUFDbkRWLENBQUMsQ0FBQ0MsY0FBYyxDQUFDLENBQUM7RUFDbEIsSUFBSUMsSUFBSSxHQUFHLElBQUlDLElBQUksQ0FBQyxDQUFDLENBQUNDLE9BQU8sQ0FBQyxDQUFDO0VBQy9CLElBQUlDLFFBQVEsR0FBR3hDLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUN4RCxJQUFJK0IsYUFBYSxHQUFHUCxRQUFRLENBQUNRLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSVgsSUFBSSxHQUFHLENBQUM7RUFDM0RVLGFBQWEsR0FBR0EsYUFBYSxDQUFDQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzFEckMsQ0FBQyxDQUFDLHFCQUFxQixDQUFDLENBQUMwQixNQUFNLENBQUMsQ0FBQyxDQUFDaUUsTUFBTSxDQUFDNUMsYUFBYSxDQUFDO0VBQ3ZEL0MsQ0FBQyxDQUFDLDJCQUEyQixDQUFDLENBQUMyQixHQUFHLENBQUNvRSxhQUFhLENBQUM7RUFDakRGLE1BQU0sQ0FBQyxDQUFDO0VBQ1JDLGNBQWMsQ0FBQyxDQUFDO0FBQ2xCLENBQUMsQ0FBQztBQUNGOUYsQ0FBQyxDQUFDQyxRQUFRLENBQUMsQ0FBQ3FCLEVBQUUsQ0FBQyxPQUFPLEVBQUMsZUFBZSxFQUFFLFVBQVNhLENBQUMsRUFBRTtFQUNsREEsQ0FBQyxDQUFDQyxjQUFjLENBQUMsQ0FBQztFQUNsQixJQUFJQyxJQUFJLEdBQUcsSUFBSUMsSUFBSSxDQUFDLENBQUMsQ0FBQ0MsT0FBTyxDQUFDLENBQUM7RUFDL0IsSUFBSUMsUUFBUSxHQUFHeEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUN2QyxJQUFJK0IsYUFBYSxHQUFHUCxRQUFRLENBQUNRLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSVgsSUFBSSxHQUFHLENBQUM7RUFDM0RVLGFBQWEsR0FBR0EsYUFBYSxDQUFDQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUlYLElBQUksR0FBRyxDQUFDO0VBQzFEckMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ2lFLE1BQU0sQ0FBQzVDLGFBQWEsQ0FBQztFQUN4Qy9DLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQzRGLFVBQVUsQ0FBQyxDQUFDO0FBQzdCLENBQUMsQ0FBQztBQUNGLFNBQVNDLE1BQU1BLENBQUEsRUFBRTtFQUNmLElBQUk3RixDQUFDLENBQUMsb0JBQW9CLENBQUMsQ0FBQzBDLE1BQU0sRUFBRTtJQUNsQyxJQUFJc0QsS0FBSyxHQUFHaEcsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLENBQUM2QyxJQUFJLENBQUMsWUFBWSxDQUFDO0lBQ3REN0MsQ0FBQyxDQUFDLDhDQUE4QyxDQUFDLENBQUNHLElBQUksQ0FBQyxZQUFVO01BQy9ESCxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMyQixHQUFHLENBQUNxRSxLQUFLLENBQUM7SUFDcEIsQ0FBQyxDQUFDO0VBQ0o7QUFDRjtBQUNBaEcsQ0FBQyxDQUFDQyxRQUFRLENBQUMsQ0FBQ3FCLEVBQUUsQ0FBQyxPQUFPLEVBQUMsaUJBQWlCLEVBQUUsVUFBU2EsQ0FBQyxFQUFFO0VBQ3BEQSxDQUFDLENBQUNDLGNBQWMsQ0FBQyxDQUFDO0VBQ2xCcEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDMEIsTUFBTSxDQUFDLENBQUMsQ0FBQ0EsTUFBTSxDQUFDLENBQUMsQ0FBQ3VFLE1BQU0sQ0FBQyxDQUFDO0FBQ3BDLENBQUMsQ0FBQztBQUNGakcsQ0FBQyxDQUFDQyxRQUFRLENBQUMsQ0FBQ3FCLEVBQUUsQ0FBQyxPQUFPLEVBQUMsb0JBQW9CLEVBQUUsVUFBU2EsQ0FBQyxFQUFFO0VBQ3ZEbkMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDaUcsTUFBTSxDQUFDLENBQUM7QUFDcEIsQ0FBQyxDQUFDO0FBRUYsU0FBU0MsWUFBWUEsQ0FBQ0MsR0FBRyxFQUFHO0VBQzFCLElBQUcsQ0FBQ0MsTUFBTSxDQUFDQyxVQUFVLEVBQUMsQ0FDdEIsQ0FBQyxNQUFNO0lBQ0wsSUFBSUMsTUFBTSxHQUFHLElBQUlELFVBQVUsQ0FBQyxDQUFDO0lBQzdCLElBQUlFLE1BQU0sR0FBRyxJQUFJO0lBQ2pCRCxNQUFNLENBQUNFLE1BQU0sR0FBRyxVQUFTckUsQ0FBQyxFQUFFO01BQzFCb0UsTUFBTSxHQUFJcEUsQ0FBQyxDQUFDb0UsTUFBTSxJQUFJcEUsQ0FBQyxDQUFDc0UsVUFBVTtNQUNsQ3pHLENBQUMsQ0FBQ21HLEdBQUcsQ0FBQyxDQUFDekUsTUFBTSxDQUFDLENBQUMsQ0FBQ0EsTUFBTSxDQUFDLENBQUMsQ0FBQ0YsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDa0YsSUFBSSxDQUFDLEtBQUssRUFBRUgsTUFBTSxDQUFDSSxNQUFNLENBQUM7T
1UFDcEUzRyxDQUFDLENBQUNtRyxHQUFHLENBQUMsQ0FBQ3pFLE1BQU0sQ0FBQyxDQUFDLENBQUNBLE1BQU0sQ0FBQyxDQUFDLENBQUNGLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQ29GLFdBQVcsQ0FBQyxRQUFRLENBQUM7SUFDakUsQ0FBQztJQUNETixNQUFNLENBQUNPLGFBQWEsQ0FBQ1YsR0FBRyxDQUFDVyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7RUFDcEM7QUFDRjtBQUFDO0FBQ0Q5RyxDQUFDLENBQUNDLFFBQVEsQ0FBQyxDQUFDcUIsRUFBRSxDQUFDLFFBQVEsRUFBQyxlQUFlLEVBQUUsWUFBVztFQUFDNEUsWUFBWSxDQUFDLElBQUksQ0FBQztBQUFDLENBQUMsQ0FBQzs7QUFFMUU7QUFDQWxHLENBQUMsQ0FBQ0MsUUFBUSxDQUFDLENBQUNDLEtBQUssQ0FBQyxZQUFVO0VBQzFCLElBQUksT0FBUUYsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDNEYsVUFBVSxLQUFLLFVBQVUsRUFBRTtJQUN4RDVGLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQzRGLFVBQVUsQ0FBQztNQUMxQm1CLGFBQWEsRUFBRSxLQUFLO01BQ3BCQyxJQUFJLEVBQUUsT0FBTztNQUNiQyxNQUFNLEVBQUUsR0FBRztNQUNYQyxXQUFXLEVBQUUsSUFBSTtNQUNqQkMsT0FBTyxFQUFFLENBQ1AsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQyxFQUNuRCxDQUFDLE1BQU0sRUFBRSxDQUFDLGVBQWUsRUFBRSxhQUFhLEVBQUUsV0FBVyxDQUFDLENBQUMsRUFDdkQsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDLEVBQ25DLENBQUMsTUFBTSxFQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsRUFDbEIsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxTQUFTLEVBQUMsT0FBTyxFQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQyxFQUNoRCxDQUFDLE9BQU8sRUFBRSxDQUFDLFVBQVUsRUFBQyxNQUFNLEVBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDLEVBQ2pELENBQUMsTUFBTSxFQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsRUFDckIsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUN6QjtNQUNEQyxPQUFPLEVBQUU7UUFDUEMsS0FBSyxFQUFFLENBQ0wsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxpQkFBaUIsRUFBQyxXQUFXLENBQUMsQ0FBQyxFQUMzQyxDQUFDLFdBQVcsRUFBRSxDQUFDLGNBQWMsRUFBRSxhQUFhLEVBQUUsYUFBYSxDQUFDLENBQUMsRUFDN0QsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxXQUFXLEVBQUUsWUFBWSxFQUFFLFdBQVcsQ0FBQyxDQUFDLEVBQ25ELENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLENBQUM7TUFFL0IsQ0FBQztNQUNEQyxlQUFlLEVBQUM7UUFDZEMsaUJBQWlCLEVBQUMsU0FBUztRQUFFO1FBQzdCQyxJQUFJLEVBQUMsK0JBQStCO1FBQ3BDQyxXQUFXLEVBQUMsS0FBSyxDQUFDO01BQ3BCLENBQUM7TUFDREMsYUFBYSxFQUFDO1FBQ1pDLFVBQVUsRUFBQyxJQUFJO1FBQUc7UUFDbEJDLFVBQVUsRUFBQyxJQUFJO1FBQUU7UUFDakJDLFNBQVMsRUFBQyxJQUFJO1FBQUk7UUFDbEJDLFNBQVMsRUFBQyxLQUFLLENBQUc7TUFDcEIsQ0FBQztNQUNEQyxTQUFTLEVBQUM7UUFDUlAsSUFBSSxFQUFDLGdDQUFnQztRQUFFO1FBQ3ZDUSxXQUFXLEVBQUMsZ0JBQWdCO1FBQzVCQyxlQUFlLEVBQUM7TUFDbEIsQ0FBQztNQUNEQyxPQUFPLEVBQUM7UUFDTkMsT0FBTyxFQUFFLEdBQUc7UUFBRTtRQUNkQyxNQUFNLEVBQUUsTUFBTTtRQUFFO1FBQ2hCQyxPQUFPLEVBQUUsTUFBTTtRQUFFO1FBQ2pCQyxRQUFRLEVBQUUsd0NBQXdDO1FBQUU7UUFDcERkLElBQUksRUFBRSw4QkFBOEI7UUFDcENlLFFBQVEsRUFBRSxJQUFJO1FBQUU7UUFDaEJDLFdBQVcsRUFBRSxLQUFLO1FBQUU7UUFDcEJDLFlBQVksRUFBRSxDQUFDLE1BQU0sRUFBQyxLQUFLLEVBQUMsS0FBSyxDQUFDO1FBQUU7UUFDcENDLE9BQU8sRUFBRSxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLE1BQU0sQ0FBQztRQUFFO1FBQ2pGQyxhQUFhLEVBQUUsQ0FBQyxLQUFLLEVBQUMsSUFBSSxFQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUMsTUFBTSxFQUFDLE9BQU8sRUFBQyxPQUFPLEVBQUMsY0FBYyxDQUFDLENBQUM7TUFDckYsQ0FBQztNQUNEbkcsUUFBUSxFQUFFO1FBQ1JvRyxJQUFJLEVBQUUscUJBQXFCO1FBQzNCQyxJQUFJLEVBQUU7VUFDSixtQkFBbUIsRUFBRSxtQkFBbUI7VUFDeEMsZUFBZSxFQUFFLGtCQUFrQjtVQUNuQyxjQUFjLEVBQUUsb0JBQW9CO1VBQ3BDLFVBQVUsRUFBRTtRQUNkO01BQ0Y7SUFDRixDQUFDLENBQUM7RUFDRjtBQUNGLENBQUMsQ0FBQztBQUNGOztBQUVBO0FBQUMsQ0FBQyxVQUFVN0ksQ0FBQyxFQUFFb0csTUFBTSxFQUFFbkcsUUFBUSxFQUFFNkksU0FBUyxFQUN4QztFQUNFOUksQ0FBQyxDQUFDK0ksRUFBRSxDQUFDQyxhQUFhLEdBQUcsVUFBVXBJLE1BQU0sRUFDckM7SUFDRSxJQUFJLEVBQUcsY0FBYyxJQUFJd0YsTUFBTSxDQUFFLElBQy9CLENBQUM2QyxTQUFTLENBQUNDLGdCQUFnQixJQUN6QixDQUFDRCxTQUFTLENBQUNFLFNBQVMsQ0FBQ0MsV0FBVyxDQUFDLENBQUMsQ0FBQ0MsS0FBSyxDQUFFLHFCQUFzQixDQUFDLEVBQUcsT0FBTyxLQUFLO0lBRXBGLElBQUksQ0FBQ2xKLElBQUksQ0FBRSxZQUNUO01BQ0UsSUFBSW1KLE9BQU8sR0FBRyxLQUFLO01BRW5CdEosQ0FBQyxDQUFFLElBQUssQ0FBQyxDQUFDc0IsRUFBRSxDQUFFLE9BQU8sRUFBRSxVQUFVYSxDQUFDLEVBQ2hDO1FBQ0UsSUFBSW9ILElBQUksR0FBR3ZKLENBQUMsQ0FBRSxJQUFLLENBQUM7UUFDcEIsSUFBSXVKLElBQUksQ0FBRSxDQUFDLENBQUUsSUFBSUQsT0FBTyxDQUFFLENBQUMsQ0FBRSxFQUM3QjtVQUNFbkgsQ0FBQyxDQUFDQyxjQUFjLENBQUMsQ0FBQztVQUNsQmtILE9BQU8sR0FBR0MsSUFBSTtRQUNoQjtNQUNGLENBQUMsQ0FBQztNQUVKdkosQ0FBQyxDQUFFQyxRQUFTLENBQUMsQ0FBQ3FCLEVBQUUsQ0FBRSxnQ0FBZ0MsRUFBRSxVQUFVYSxDQUFDLEVBQzdEO1FBQ0UsSUFBSXFILFNBQVMsR0FBRyxJQUFJO1VBQ2xCQyxPQUFPLEdBQUt6SixDQUFDLENBQUVtQyxDQUFDLENBQUNvRSxNQUFPLENBQUMsQ0FBQ2tELE9BQU8sQ0FBQyxDQUFDO1F
1BRXJDLEtBQUssSUFBSXRJLENBQUMsR0FBRyxDQUFDLEVBQUVBLENBQUMsR0FBR3NJLE9BQU8sQ0FBQy9HLE1BQU0sRUFBRXZCLENBQUMsRUFBRSxFQUNyQyxJQUFJc0ksT0FBTyxDQUFFdEksQ0FBQyxDQUFFLElBQUltSSxPQUFPLENBQUUsQ0FBQyxDQUFFLEVBQ2hDRSxTQUFTLEdBQUcsS0FBSztRQUVuQixJQUFJQSxTQUFTLEVBQ1hGLE9BQU8sR0FBRyxLQUFLO01BQ25CLENBQUMsQ0FBQztJQUNOLENBQUMsQ0FBQztJQUNKLE9BQU8sSUFBSTtFQUNiLENBQUM7QUFDSCxDQUFDLEVBQUdJLE1BQU0sRUFBRXRELE1BQU0sRUFBRW5HLFFBQVMsQ0FBQztBQUNoQ0QsQ0FBQyxDQUFFLHdCQUF5QixDQUFDLENBQUNnSixhQUFhLENBQUMsQ0FBQztBQUU3Q2hKLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQzJKLEtBQUssQ0FBQyxZQUFVO0VBQ3pCM0osQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDd0IsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDb0ksS0FBSyxDQUFDLENBQUM7QUFDekMsQ0FBQyxDQUFDO0FBRUY1SixDQUFDLENBQUNDLFFBQVEsQ0FBQyxDQUFDQyxLQUFLLENBQUMsWUFBVztFQUMzQkYsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUNHLElBQUksQ0FDdkIsWUFBVTtJQUNSLElBQUlRLEdBQUcsR0FBR1gsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDNkMsSUFBSSxDQUFDLFdBQVcsQ0FBQztJQUNuQyxJQUFJZ0gsS0FBSyxHQUFHN0osQ0FBQyxDQUFDLDRCQUE0QixDQUFDLENBQUMwQyxNQUFNLEdBQUUsQ0FBQztJQUNyRDFDLENBQUMsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDRyxJQUFJLENBQ2xDLFVBQVNnQixDQUFDLEVBQUM7TUFDVG5CLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQzZDLElBQUksQ0FBQyxNQUFNLEVBQUM3QyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM2QyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUNHLE9BQU8sQ0FBQyxXQUFXLEVBQUNyQyxHQUFHLEdBQUMsR0FBRyxDQUFDLENBQUM7SUFDeEUsQ0FDRixDQUFDO0lBQ0QsSUFBSWtKLEtBQUssR0FBQyxFQUFFLEVBQUM7TUFDWCxJQUFJQyxLQUFLLEdBQUc5SixDQUFDLENBQUMsNEJBQTRCLENBQUMsQ0FDeEM4SixLQUFLLENBQUM5SixDQUFDLENBQUMsbUNBQW1DLENBQUMsQ0FBQztNQUNoRCxJQUFJK0osS0FBSyxHQUFHQyxJQUFJLENBQUNDLEtBQUssQ0FBQ0osS0FBSyxHQUFHLENBQUMsQ0FBQztNQUNqQyxJQUFJSyxFQUFFLEdBQUdGLElBQUksQ0FBQ0MsS0FBSyxDQUFDSixLQUFLLEdBQUcsQ0FBQyxDQUFDO01BQzlCLElBQUlNLEVBQUUsR0FBR0gsSUFBSSxDQUFDQyxLQUFLLENBQUNKLEtBQUssR0FBRyxDQUFDLEdBQUMsQ0FBQyxDQUFDO01BQ2hDLElBQUlPLEVBQUUsR0FBR04sS0FBSyxHQUFHLENBQUM7TUFDbEIsSUFBSU8sRUFBRSxHQUFHUCxLQUFLLEdBQUcsQ0FBQztNQUNsQixJQUFJUSxLQUFLLEdBQUcsQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFDVCxLQUFLLEdBQUMsQ0FBQyxFQUFDSyxFQUFFLEVBQUNILEtBQUssRUFBQ0ksRUFBRSxFQUFDQyxFQUFFLEVBQUNOLEtBQUssRUFBQ08sRUFBRSxFQUFDUixLQUFLLENBQUM7TUFDdkQ3SixDQUFDLENBQUMsNEJBQTRCLENBQUMsQ0FBQ0csSUFBSSxDQUNsQyxVQUFTZ0IsQ0FBQyxFQUFDO1FBQ1QsSUFBR25CLENBQUMsQ0FBQ3VLLE9BQU8sQ0FBQ3BKLENBQUMsRUFBQ21KLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFDO1VBQzVCdEssQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDaUcsTUFBTSxDQUFDLENBQUM7UUFDaEI7TUFDRixDQUNGLENBQUM7SUFDSDtFQUNGLENBQ0YsQ0FBQztBQUNILENBQUMsQ0FBQztBQUNGLFNBQVN1RSxrQkFBa0JBLENBQUN4SixJQUFJLEVBQUU7RUFDaEMsSUFBSXlKLEdBQUcsR0FBRyxJQUFJQyxjQUFjLENBQUMsQ0FBQztFQUM5QixJQUFJQyxFQUFFLEdBQUksSUFBSUMsUUFBUSxDQUFDM0ssUUFBUSxDQUFDNEssY0FBYyxDQUFDLG9CQUFvQixDQUFDLENBQUM7RUFDckUsSUFBSUMsSUFBSSxHQUFHN0ssUUFBUSxDQUFDa0QsYUFBYSxDQUFDLHVCQUF1QixDQUFDLENBQUM0SCxPQUFPO0VBQ2xFOztFQUVBLEtBQUlDLElBQUksSUFBSWhLLElBQUksRUFBRTtJQUNoQjJKLEVBQUUsQ0FBQ00sTUFBTSxDQUFDRCxJQUFJLEVBQUVoSyxJQUFJLENBQUNnSyxJQUFJLENBQUMsQ0FBQztFQUM3QjtFQUVBUCxHQUFHLENBQUNoRixnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsVUFBU1AsS0FBSyxFQUFFO0lBQzNDZ0csS0FBSyxDQUFDLHNDQUFzQyxDQUFDO0VBQy9DLENBQUMsQ0FBQztFQUNGVCxHQUFHLENBQUNoRixnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsVUFBU1AsS0FBSyxFQUFFO0lBQzVDZ0csS0FBSyxDQUFDLDZCQUE2QixDQUFDO0VBQ3RDLENBQUMsQ0FBQzs7RUFFRjtFQUNBVCxHQUFHLENBQUNVLElBQUksQ0FBRSxNQUFNLEVBQUUsd0JBQXlCLENBQUM7RUFDNUNWLEdBQUcsQ0FBQ1csZ0JBQWdCLENBQUUsY0FBYyxFQUFFLG1DQUFvQyxDQUFDO0VBQzNFWCxHQUFHLENBQUNXLGdCQUFnQixDQUFFLGNBQWMsRUFBRU4sSUFBSSxDQUFDO0VBQzNDTCxHQUFHLENBQUNZLElBQUksQ0FBQ1YsRUFBRSxDQUFDO0VBQ1o7QUFDRjtBQUNBLFNBQVM3RSxjQUFjQSxDQUFBLEVBQUU7RUFDdkIsSUFBSWdGLElBQUksR0FBRzdLLFF
1BQVEsQ0FBQ2tELGFBQWEsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDNEgsT0FBTztFQUNwRSxJQUFJTyxNQUFNLEdBQUdyTCxRQUFRLENBQUNxRCxnQkFBZ0IsQ0FBQywyQkFBMkIsQ0FBQztFQUNuRSxLQUFLLElBQUluQyxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdtSyxNQUFNLENBQUM1SSxNQUFNLEVBQUUsRUFBRXZCLENBQUMsRUFBRTtJQUN0Q21LLE1BQU0sQ0FBQ25LLENBQUMsQ0FBQyxDQUFDNEQsS0FBSyxHQUFHK0YsSUFBSTtFQUN4QjtBQUNGO0FBQ0E5SyxDQUFDLENBQUNDLFFBQVEsQ0FBQyxDQUFDQyxLQUFLLENBQUMsWUFBVztFQUMzQjRGLGNBQWMsQ0FBQyxDQUFDO0FBQ2xCLENBQUMsQ0FBQztBQUNGOUYsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLENBQUNzQixFQUFFLENBQUMsZUFBZSxFQUFFLFVBQVU0RCxLQUFLLEVBQUU7RUFDM0QsSUFBSXFHLE1BQU0sR0FBR3ZMLENBQUMsQ0FBQ2tGLEtBQUssQ0FBQ3NHLGFBQWEsQ0FBQztFQUNuQyxJQUFJN0ssR0FBRyxHQUFHNEssTUFBTSxDQUFDdkssSUFBSSxDQUFDLEtBQUssQ0FBQztFQUM1QixJQUFJeUssS0FBSyxHQUFHekwsQ0FBQyxDQUFDLElBQUksQ0FBQztFQUNuQixJQUFJMEwsQ0FBQyxHQUFHRCxLQUFLLENBQUNqSyxJQUFJLENBQUMsa0JBQWtCLENBQUM7RUFDdENpSyxLQUFLLENBQUNqSyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQ3FCLElBQUksQ0FBQyxNQUFNLEVBQUUsV0FBVyxHQUFDbEMsR0FBRyxDQUFDO0FBQzlELENBQUMsQ0FBQyIsImlnbm9yZUxpc3QiOltdfQ==\n//# sourceURL=webpack-internal:///587\n")},70:(__unused_webpack_module,__unused_webpack_exports,__webpack_require__)=>{eval("/**\n * jQuery Slugger\n *\n * This project is used to be called jQuery Slugify until I discovered slugify is already taken in `npm`.\n *\n * v1.0.4\n *\n * @author John Lioneil Dionisio\n *\n * @param {Object} $\n * @param {Object} document\n * @return\n */\n(function ($, document) {\n 'use strict';\n\n var slugify = __webpack_require__(304);\n var slugSeparator = 'slug-separator';\n var Slugify = {\n init: function (options, elem) {\n var self = this;\n self.elem = elem;\n self.$elem = $(elem);\n self.options = $.extend({}, $.fn.slugger.options, options);\n self.sluggerElement = undefined == self.$elem.data('slugger') ? self.elem : self.$elem.data('slugger');\n self.options.target = \"\" == self.$elem.data('slugger') || undefined == self.$elem.data('slugger') ? self.options.target : self.$elem.data('slugger');\n self.options.separator = undefined == self.$elem.data(slugSeparator) ? self.options.separator : self.$elem.data(slugSeparator);\n self.$elem.on(self.options.bindToEvent, function (e) {\n var $string = $(this).val();\n $string = self.convert($string, self);\n $(self.options.target).val($string);\n if (self.options.debug) self.debug($string);\n });\n return true;\n },\n convert: function ($string, self) {\n self.options.beforeConvert(self);\n if (self.options.convertToLowerCase) {\n $string = $string.toLowerCase();\n }\n if (self.options.separator !== \" \") {\n $string = $string.replace(/ /g, this.options.separator);\n }\n if (!self.options.isUrlFriendly) {\n $string = $string.replace(/[^\\w-]+/g, '');\n }\n $string = slugify($string);\n self.options.afterConvert(self);\n return $string;\n },\n destroy: function () {\n this.destroy();\n this.element.unbind(this.eventNamespace);\n this.bindings.unbind(this.eventNamespace);\n },\n debug: function ($string) {\n console.log($string);\n }\n };\n $.fn.slugger = function (options, elem) {\n var slugger = Object.create(Slugify);\n return this.each(function () {\n slugger.init(options, this);\n });\n };\n $.fn.slugger.options = {\n bindToEvent: 'keypress keyup',\n target: '[name=slug]',\n separator: '-',\n convertToLowerCase: true,\n isUrlFriendly: true,\n beforeConvert: function (self) {},\n afterConvert: function (self) {},\n debug: false\n };\n jQuery('[data-slugger]').slugger();\n})(jQuery, document);//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzAuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi92ZW5kb3IvanF1ZXJ5LnNsdWdnZXIuanM/MjRhZiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGpRdWVyeSBTbHVnZ2VyXG4gKlxuICogVGhpcyBwcm9qZWN0IGlzIHVzZWQgdG8gYmUgY2FsbGVkIGpRdWVyeSBTbHVnaWZ5IHVudGlsIEkgZGlzY292ZXJlZCBzbHVnaWZ5IGlzIGFscmVhZHkgdGFrZW4gaW4gYG5wbWAuXG4gKlxuICogdjEuMC40XG4gKlxuICogQGF1dGhvciAgSm9obiBMaW9uZWlsIERpb25pc2lvXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSAkXG4gKiBAcGFyYW0gIHtPYmplY3R9IGRvY3VtZW50XG4gKiBAcmV0dXJuXG4gKi9cbihmdW5jdGlvbiAoJCwgZG9jdW1lbnQpIHtcblxuICAgICd1c2Ugc3RyaWN0JztcblxuICB2Y
1XIgc2x1Z2lmeSA9IHJlcXVpcmUoJ3NsdWdpZnknKVxuICAgIHZhciBzbHVnU2VwYXJhdG9yID0gJ3NsdWctc2VwYXJhdG9yJztcblxuXHR2YXIgU2x1Z2lmeSA9IHtcbiAgICAgICAgaW5pdDogZnVuY3Rpb24gKG9wdGlvbnMsIGVsZW0pIHtcbiAgICAgICAgXHR2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgICAgICBzZWxmLmVsZW0gPSBlbGVtO1xuICAgICAgICAgICAgc2VsZi4kZWxlbSA9ICQoZWxlbSk7XG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMgPSAkLmV4dGVuZCgge30sICQuZm4uc2x1Z2dlci5vcHRpb25zLCBvcHRpb25zICk7XG4gICAgICAgICAgICBzZWxmLnNsdWdnZXJFbGVtZW50ID0gdW5kZWZpbmVkID09IHNlbGYuJGVsZW0uZGF0YSgnc2x1Z2dlcicpID8gc2VsZi5lbGVtIDogc2VsZi4kZWxlbS5kYXRhKCdzbHVnZ2VyJyk7XG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMudGFyZ2V0ID0gXCJcIiA9PSBzZWxmLiRlbGVtLmRhdGEoJ3NsdWdnZXInKSB8fCB1bmRlZmluZWQgPT0gc2VsZi4kZWxlbS5kYXRhKCdzbHVnZ2VyJykgPyBzZWxmLm9wdGlvbnMudGFyZ2V0IDogc2VsZi4kZWxlbS5kYXRhKCdzbHVnZ2VyJyk7XG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMuc2VwYXJhdG9yID0gdW5kZWZpbmVkID09IHNlbGYuJGVsZW0uZGF0YShzbHVnU2VwYXJhdG9yKSA/IHNlbGYub3B0aW9ucy5zZXBhcmF0b3IgOiBzZWxmLiRlbGVtLmRhdGEoc2x1Z1NlcGFyYXRvcik7XG5cbiAgICAgICAgICAgIHNlbGYuJGVsZW0ub24oc2VsZi5vcHRpb25zLmJpbmRUb0V2ZW50LCBmdW5jdGlvbiAoZSkge1xuXHQgICAgICAgICAgICB2Y
1XIgJHN0cmluZyA9ICQodGhpcykudmFsKCk7XG5cdCAgICAgICAgICAgICRzdHJpbmcgPSBzZWxmLmNvbnZlcnQoJHN0cmluZywgc2VsZik7XG5cdCAgICAgICAgICAgICQoc2VsZi5vcHRpb25zLnRhcmdldCkudmFsKCRzdHJpbmcpO1xuXG5cdCAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuZGVidWcpIHNlbGYuZGVidWcoJHN0cmluZyk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICBcdHJldHVybiB0cnVlO1xuICAgICAgICB9LFxuXG4gICAgICAgIGNvbnZlcnQ6IGZ1bmN0aW9uICgkc3RyaW5nLCBzZWxmKSB7XG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMuYmVmb3JlQ29udmVydChzZWxmKTtcblxuICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5jb252ZXJ0VG9Mb3dlckNhc2UpIHtcbiAgICAgICAgICAgICAgICAkc3RyaW5nID0gJHN0cmluZy50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnNlcGFyYXRvciAhPT0gXCIgXCIpIHtcbiAgICAgICAgICAgIFx0JHN0cmluZyA9ICRzdHJpbmcucmVwbGFjZSgvIC9nLCB0aGlzLm9wdGlvbnMuc2VwYXJhdG9yKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFzZWxmLm9wdGlvbnMuaXNVcmxGcmllbmRseSkge1xuICAgICAgICAgICAgICAgICRzdHJpbmcgPSAkc3RyaW5nLnJlcGxhY2UoL1teXFx3LV0rL2csICcnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICRzdHJpbmcgPSBzbHVnaWZ5KCRzdHJpbmcpO1xuICAgICAgICAgICAgc2VsZi5vcHRpb25zLmFmdGVyQ29udmVydChzZWxmKTtcblxuICAgICAgICAgICAgcmV0dXJuICRzdHJpbmc7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZGVzdHJveTogZnVuY3Rpb24gKCkge1xuICAgICAgICBcdHRoaXMuZGVzdHJveSgpO1xuICAgICAgICBcdHRoaXMuZWxlbWVudC51bmJpbmQoIHRoaXMuZXZlbnROYW1lc3BhY2UgKVxuXHRcdCAgICB0aGlzLmJpbmRpbmdzLnVuYmluZCggdGhpcy5ldmVudE5hbWVzcGFjZSApO1xuICAgICAgICB9LFxuXG4gICAgICAgIGRlYnVnOiBmdW5jdGlvbiAoJHN0cmluZykge1xuICAgICAgICBcdGNvbnNvbGUubG9nKCRzdHJpbmcpO1xuICAgICAgICB9LFxuICAgIH07XG5cbiAgICAkLmZuLnNsdWdnZXIgPSBmdW5jdGlvbiAob3B0aW9ucywgZWxlbSkge1xuICAgICAgICB2Y
1XIgc2x1Z2dlciA9IE9iamVjdC5jcmVhdGUoU2x1Z2lmeSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2x1Z2dlci5pbml0KG9wdGlvbnMsIHRoaXMpO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgJC5mbi5zbHVnZ2VyLm9wdGlvbnMgPSB7XG4gICAgICAgIGJpbmRUb0V2ZW50OiAna2V5cHJlc3Mga2V5dXAnLFxuICAgICAgICB0YXJnZXQ6ICdbbmFtZT1zbHVnXScsXG4gICAgICAgIHNlcGFyYXRvcjogJy0nLFxuXG4gICAgICAgIGNvbnZlcnRUb0xvd2VyQ2FzZTogdHJ1ZSxcbiAgICAgICAgaXNVcmxGcmllbmRseTogdHJ1ZSxcblxuICAgICAgICBiZWZvcmVDb252ZXJ0OiBmdW5jdGlvbiAoc2VsZikge30sXG4gICAgICAgIGFmdGVyQ29udmVydDogZnVuY3Rpb24gKHNlbGYpIHt9LFxuXG4gICAgICAgIGRlYnVnOiBmYWxzZSxcbiAgICB9O1xuICAgIGpRdWVyeSgnW2RhdGEtc2x1Z2dlcl0nKS5zbHVnZ2VyKCk7XG5cbn0pKGpRdWVyeSwgZG9jdW1lbnQpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///70\n")},156:function(module){eval("/**\n * @file postscribe\n * @description Asynchronously write javascript, even with document.write.\n * @version v2.0.6\n * @see {@link https://krux.github.io/postscribe}\n * @license MIT\n * @author Derek Brans\n * @copyright 2016 Krux Digital, Inc\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n if (true) module.exports = factory();else {}\n})(this, function () {\n return /******/function (modules) {\n // webpackBootstrap\n /******/ // The module cache\n /******/\n var installedModules = {};\n /******/\n /******/ // The require function\n /******/\n function __nested_webpack_require_811__(moduleId) {\n /******/\n /******/ // Check if module is in cache\n /******/if (installedModules[moduleId]) /******/return installedModules[moduleId].exports;\n /******/\n /******/ // Create a new module (and put it into the cache)\n /******/\n var module = installedModules[moduleId] = {\n /******/exports: {},\n /******/id: moduleId,\n /******/loaded: false\n /******/\n };\n /******/\n /******/ // Execute the module function\n /******/\n modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_811__);\n /******/\n /******/ // Flag the module as loaded\n /******/\n module.loaded = true;\n /******/\n /******/ // Return the exports of the module\n /******/\n return module.exports;\n /******/\n }\n /******/\n /******/\n /******/ // expose the modules object (__webpack_modules__)\n /******/\n __nested_webpack_require_811__.m = modules;\n /******/\n /******/ // expose the module cache\n /******/\n __nested_webpack_require_811__.c = installedModules;\n /******/\n /******/ // __webpack_public_path__\n /******/\n __nested_webpack_require_811__.p = \"\";\n /******/\n /******/ // Load entry module and return exports\n /******/\n return __nested_webpack_require_811__(0);\n /******/\n }\n /************************************************************************/\n /******/([/* 0 */\n /***/function (module, exports, __nested_webpack_require_2283__) {\n 'use strict';\n\n var _postscribe = __nested_webpack_require_2283__(1);\n var _postscribe2 = _interopRequireDefault(_postscribe);\n function _interopRequireDefault(obj) {\n return obj && obj.__esModule ? obj : {\n 'default': obj\n };\n }\n module.exports = _postscribe2['default'];\n\n /***/\n }, /* 1 */\n /***/function (module, exports, __nested_webpack_require_2661__) {\n 'use strict';\n\n exports.__esModule = true;\n var _extends = Object.assign || function (target) {\n for (var i = 1; i < arguments.length;
1 i++) {\n var source = arguments[i];\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n };\n exports['default'] = postscribe;\n var _writeStream = __nested_webpack_require_2661__(2);\n var _writeStream2 = _interopRequireDefault(_writeStream);\n var _utils = __nested_webpack_require_2661__(4);\n var utils = _interopRequireWildcard(_utils);\n function _interopRequireWildcard(obj) {\n if (obj && obj.__esModule) {\n return obj;\n } else {\n var newObj = {};\n if (obj != null) {\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];\n }\n }\n newObj['default'] = obj;\n return newObj;\n }\n }\n function _interopRequireDefault(obj) {\n return obj && obj.__esModule ? obj : {\n 'default': obj\n };\n }\n\n /**\n * A function that intentionally does nothing.\n */\n function doNothing() {}\n\n /**\n * Available options and defaults.\n *\n * @type {Object}\n */\n var OPTIONS = {\n /**\n * Called when an async script has loaded.\n */\n afterAsync: doNothing,\n /**\n * Called immediately before removing from the write queue.\n */\n afterDequeue: doNothing,\n /**\n * Called sync after a stream's first thread release.\n */\n afterStreamStart: doNothing,\n /**\n * Called after writing buffered document.write calls.\n */\n afterWrite: doNothing,\n /**\n * Allows disabling the autoFix feature of prescribe\n */\n autoFix: true,\n /**\n * Called immediately before adding to the write queue.\n */\n beforeEnqueue: doNothing,\n /**\n * Called before writing a token.\n *\n * @param {Object} tok The token\n */\n beforeWriteToken: function beforeWriteToken(tok) {\n return tok;\n },\n /**\n * Called before writing buffered document.write calls.\n *\n * @param {String} str The string\n */\n beforeWrite: function beforeWrite(str) {\n return str;\n },\n /**\n * Called when evaluation is finished.\n */\n done: doNothing,\n /**\n * Called when a write results in an error.\n *\n * @param {Error} e The error\n */\n error: function error(e) {\n throw e;\n },\n /**\n * Whether to let scripts w/ async attribute set fall out of the queue.\n */\n releaseAsync: false\n };\n var nextId = 0;\n var queue = [];\n var active = null;\n function nextStream() {\n var args = queue.shift();\n if (args) {\n var options = utils.last(args);\n options.afterDequeue();\n args.stream = runStream.apply(undefined, args);\n options.afterStreamStart();\n }\n }\n function runStream(el, html, options) {\n active = new\n // Expose internal classes.\n _writeStream2['default'](el, options);\n\n // Identify this stream.\n active.id = nextId++;\n active.name = options.name || active.id;\n postscribe.streams[active.name] = active;\n\n // Override document.write.\n var doc = el.ownerDocument;\n var stash = {\n close: doc.close,\n open: doc.open,\n write: doc.write,\n writeln: doc.writeln\n };\n function _write(str) {\n str = options.beforeWrite(str);\n active.write(str);\n options.afterWrite(str);\n }\n _extends(doc, {\n close: doNothing,\n open: doNothing,\n write: function write() {\n for (var _len = arguments.length, str = Array(_len), _key = 0; _key < _len; _key++) {\n str[_key] = arguments[_key];\n }\n return _write(str.join(''));\n },\n writeln: function writeln() {\n for (var _len2 = arguments.length, str = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n str[_key2] = arguments[_key2];\n }\n return _write(str.join('') + '\\n');\n }\n });\n\n // Override window.onerror\n var oldOnError = active.win.onerror || doNothing;\n\n // This works together with the try/catch around WriteStream::insertScript\n // In modern browsers, exceptions in tag scripts go directly to top level\n active.win.onerror = function (msg, url, line) {\n options.error({\n msg: msg + ' - ' + url + ': ' + line\n });\n oldOnError.apply(active.win, [msg, url, line]);\n };\n\n // Write to the stream\n active.write(html, function () {\n // restore document.write\n _extends(doc, stash);\n\n // restore window.onerror\n active.win.onerror = oldOnError;\n options.done();\n active = null;\n nextStream();\n });\n return active;\n }\n function postscribe(el, html, options) {\n if (utils.isFunction(options)) {\n options = {\n done: options\n };\n } else if (options === 'clear') {\n queue = [];\n active = null;\n nextId = 0;\n return;\n }\n options = utils.defaults(options, OPTIONS);
1\n\n // id selector\n if (/^#/.test(el)) {\n el = window.document.getElementById(el.substr(1));\n } else {\n el = el.jquery ? el[0] : el;\n }\n var args = [el, html, options];\n el.postscribe = {\n cancel: function cancel() {\n if (args.stream) {\n args.stream.abort();\n } else {\n args[1] = doNothing;\n }\n }\n };\n options.beforeEnqueue(args);\n queue.push(args);\n if (!active) {\n nextStream();\n }\n return el.postscribe;\n }\n _extends(postscribe, {\n // Streams by name.\n streams: {},\n // Queue of streams.\n queue: queue,\n WriteStream: _writeStream2['default']\n });\n\n /***/\n }, /* 2 */\n /***/function (module, exports, __nested_webpack_require_8857__) {\n 'use strict';\n\n exports.__esModule = true;\n var _extends = Object.assign || function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n };\n var _prescribe = __nested_webpack_require_8857__(3);\n var _prescribe2 = _interopRequireDefault(_prescribe);\n var _utils = __nested_webpack_require_8857__(4);\n var utils = _interopRequireWildcard(_utils);\n function _interopRequireWildcard(obj) {\n if (obj && obj.__esModule) {\n return obj;\n } else {\n var newObj = {};\n if (obj != null) {\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];\n }\n }\n newObj['default'] = obj;\n return newObj;\n }\n }\n function _interopRequireDefault(obj) {\n return obj && obj.__esModule ? obj : {\n 'default': obj\n };\n }\n function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n }\n\n /**\n * Turn on to debug how each chunk affected the DOM.\n * @type {boolean}\n */\n var DEBUG_CHUNK = false;\n\n /**\n * Prefix for data attributes on DOM elements.\n * @type {string}
1\n */\n var BASEATTR = 'data-ps-';\n\n /**\n * ID for the style proxy\n * @type {string}\n */\n var PROXY_STYLE = 'ps-style';\n\n /**\n * ID for the script proxy\n * @type {string}\n */\n var PROXY_SCRIPT = 'ps-script';\n\n /**\n * Get data attributes\n *\n * @param {Object} el The DOM element.\n * @param {String} name The attribute name.\n * @returns {String}\n */\n function getData(el, name) {\n var attr = BASEATTR + name;\n var val = el.getAttribute(attr);\n\n // IE 8 returns a number if it's a number\n return !utils.existy(val) ? val : String(val);\n }\n\n /**\n * Set data attributes\n *\n * @param {Object} el The DOM element.\n * @param {String} name The attribute name.\n * @param {null|*} value The attribute value.\n */\n function setData(el, name) {\n var value = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];\n var attr = BASEATTR + name;\n if (utils.existy(value) && value !== '') {\n el.setAttribute(attr, value);\n } else {\n el.removeAttribute(attr);\n }\n }\n\n /**\n * Stream static html to an element, where \"static html\" denotes \"html\n * without scripts\".\n *\n * This class maintains a *history of writes devoid of any attributes* or\n * \"proxy history\".\n *\n * Injecting the proxy history into a temporary div has no side-effects,\n * other than to create proxy elements for previously written elements.\n *\n * Given the `staticHtml` of a new write, a `tempDiv`'s innerHTML is set to\n * `proxy_history + staticHtml`.\n * The *structure* of `tempDiv`'s contents, (i.e., the placement of new nodes\n * beside or inside of proxy elements), reflects the DOM structure that would\n * have resulted if all writes had been squashed into a single write.\n *\n * For each descendent `node` of `tempDiv` whose parentNode is a *proxy*,\n * `node` is appended to the corresponding *real* element within the DOM.\n *\n * Proxy elements are mapped to *actual* elements in the DOM by injecting a\n * `data-id` attribute into each start tag in `staticHtml`.\n *\n */\n\n var WriteStream = function () {\n /**\n * Constructor.\n *\n * @param {Object} root The root element\n * @param {?Object} options The options\n */\n\n function WriteStream(root) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n _classCallCheck(this, WriteStream);\n this.root = root;\n this.options = options;\n this.doc = root.ownerDocument;\n this.win = this.doc.defaultView || this.doc.parentWindow;\n this.parser = new _prescribe2['default']('', {\n autoFix: options.autoFix\n });\n\n // Actual elements by id.\n this.actuals = [root];\n\n // Embodies the \"structure\" of what's been written so far,\n // devoid of attributes.\n this.proxyHistory = '';\n\n // Create a proxy of the root element.\n this.proxyRoot = this.doc.createElement(root.nodeName);\n this.scriptStack = [];\n this.writeQueue = [];\n setData(this.proxyRoot, 'proxyof', 0);\n }\n\n /**\n * Writes the given strings.\n *\n * @param {...String} str The strings to write\n */\n\n WriteStream.prototype.write = function write() {\n var _writeQueue;\n (_writeQueue = this.writeQueue).push.apply(_writeQueue, arguments);\n\n // Process writes\n // When new script gets pushed or pending this will stop\n // because new writeQueue gets pushed\n while (!this.deferredRemote && this.writeQueue.length) {\n var arg = this.writeQueue.shift();\n if (utils.isFunction(arg)) {\n this._callFunction(arg);\n } else {\n this._writeImpl(arg);\n }\n }\n };\n\n /**\n * Calls the given function.\n *\n * @param {Function} fn The function to call\n * @private\n */\n\n WriteStream.prototype._callFunction = function _callFunction(fn) {\n var tok = {\n type: 'function',\n value: fn.name || fn.toString()\n };\n this._onScriptStart(tok);\n fn.call(this.win, this.doc);\n this._onScriptDone(tok);\n };\n\n /**\n * The write implementation\n *\n * @param {String} html The HTML to write.\n * @private\n */\n\n WriteStream.prototype._writeImpl = function _writeImpl(html) {\n this.parser.append(html);\n var tok = void 0;\n var script = void 0;\n var style = void 0;\n var tokens = [];\n\n // stop if we see a script token\n while ((tok = this.parser.readToken()) && !(script = utils.isScript(tok)) && !(style = utils.isStyle(tok))) {\n tok = this.options.beforeWriteToken(tok);\n if (tok) {\n tokens.push(tok);\n }\n }\n if (tokens.length > 0) {\n this._writeStaticTokens(tokens);\n }\n if (script) {\n this._handleScriptToken(tok);\n }\n if (style) {\n this._handleStyleToken(tok);\n }\n };\n\n /**\n * Write contiguous non-script tokens (a chunk)\n *\n * @param {Array<Object>} tokens The tokens\n * @returns {{tokens, raw, actual, proxy}|null}\n * @private\n */\n\n WriteStream.prototype._writeStaticTokens = function _writeStaticTokens(tokens) {\
1n var chunk = this._buildChunk(tokens);\n if (!chunk.actual) {\n // e.g., no tokens, or a noscript that got ignored\n return null;\n }\n chunk.html = this.proxyHistory + chunk.actual;\n this.proxyHistory += chunk.proxy;\n this.proxyRoot.innerHTML = chunk.html;\n if (DEBUG_CHUNK) {\n chunk.proxyInnerHTML = this.proxyRoot.innerHTML;\n }\n this._walkChunk();\n if (DEBUG_CHUNK) {\n chunk.actualInnerHTML = this.root.innerHTML;\n }\n return chunk;\n };\n\n /**\n * Build a chunk.\n *\n * @param {Array<Object>} tokens The tokens to use.\n * @returns {{tokens: *, raw: string, actual: string, proxy: string}}\n * @private\n */\n\n WriteStream.prototype._buildChunk = function _buildChunk(tokens) {\n var nextId = this.actuals.length;\n\n // The raw html of this chunk.\n var raw = [];\n\n // The html to create the nodes in the tokens (with id's injected).\n var actual = [];\n\n // Html that can later be used to proxy the nodes in the tokens.\n var proxy = [];\n var len = tokens.length;\n for (var i = 0; i < len; i++) {\n var tok = tokens[i];\n var tokenRaw = tok.toString();\n raw.push(tokenRaw);\n if (tok.attrs) {\n // tok.attrs <==> startTag or atomicTag or cursor\n // Ignore noscript tags. They are atomic, so we don't have to worry about children.\n if (!/^noscript$/i.test(tok.tagName)) {\n var id = nextId++;\n\n // Actual: inject id attribute: replace '>' at end of start tag with id attribute + '>'\n actual.push(tokenRaw.replace(/(\\/?>)/, ' ' + BASEATTR + 'id=' + id + ' $1'));\n\n // Don't proxy scripts: they have no bearing on DOM structure.\n if (tok.attrs.id !== PROXY_SCRIPT && tok.attrs.id !== PROXY_STYLE) {\n // Proxy: strip all attributes and inject proxyof attribute\n proxy.push(\n // ignore atomic tags (e.g., style): they have no \"structural\" effect\n tok.type === 'atomicTag' ? '' : '<' + tok.tagName + ' ' + BASEATTR + 'proxyof=' + id + (tok.unary ? ' />' : '>'));\n }\n }\n } else {\n // Visit any other type of token\n // Actual: append.\n actual.push(tokenRaw);\n\n // Proxy: append endTags. Ignore everything else.\n proxy.push(tok.type === 'endTag' ? tokenRaw : '');\n }\n }\n return {\n tokens: tokens,\n raw: raw.join(''),\n actual: actual.join(''),\n proxy: proxy.join('')\n };\n };\n\n /**\n * Walk the chunks.\n *\n * @private\n */\n\n WriteStream.prototype._walkChunk = function _walkChunk() {\n var node = void 0;\n var stack = [this.proxyRoot];\n\n // use shift/unshift so that children are walked in document order\n while (utils.existy(node = stack.shift())) {\n var isElement = node.nodeType === 1;\n var isProxy = isElement && getData(node, 'proxyof');\n\n // Ignore proxies\n if (!isProxy) {\n if (isElement) {\n // New actual element: register it and remove the the id attr.\n this.actuals[getData(node, 'id')] = node;\n setData(node, 'id');\n }\n\n // Is node's parent a proxy?\n var parentIsProxyOf = node.parentNode && getData(node.parentNode, 'proxyof');\n if (parentIsProxyOf) {\n // Move node under actual parent.\n this.actuals[parentIsProxyOf].appendChild(node);\n }\n }\n\n // prepend childNodes to stack\n stack.unshift.apply(stack, utils.toArray(node.childNodes));\n }\n };\n\n /**\n * Handles Script tokens\n *\n * @param {Object} tok The token\n */\n\n WriteStream.prototype._handleScriptToken = function _handleScriptToken(tok) {\n var _this = this;\n var remainder = this.parser.clear();\n if (remainder) {\n // Write remainder immediately behind this script.\n this.writeQueue.unshift(remainder);\n }\n tok.src = tok.attrs.src || tok.attrs.SRC;\n tok = this.options.beforeWriteToken(tok);\n if (!tok) {\n // User has removed this token\n return;\n }\n if (tok.src && this.scriptStack.length) {\n // Defer this script until scriptStack
1is empty.\n // Assumption 1: This script will not start executing until\n // scriptStack is empty.\n this.deferredRemote = tok;\n } else {\n this._onScriptStart(tok);\n }\n\n // Put the script node in the DOM.\n this._writeScriptToken(tok, function () {\n _this._onScriptDone(tok);\n });\n };\n\n /**\n * Handles style tokens\n *\n * @param {Object} tok The token\n */\n\n WriteStream.prototype._handleStyleToken = function _handleStyleToken(tok) {\n var remainder = this.parser.clear();\n if (remainder) {\n // Write remainder immediately behind this style.\n this.writeQueue.unshift(remainder);\n }\n tok.type = tok.attrs.type || tok.attrs.TYPE || 'text/css';\n tok = this.options.beforeWriteToken(tok);\n if (tok) {\n // Put the style node in the DOM.\n this._writeStyleToken(tok);\n }\n if (remainder) {\n this.write();\n }\n };\n\n /**\n * Build a style and insert it into the DOM.\n *\n * @param {Object} tok The token\n */\n\n WriteStream.prototype._writeStyleToken = function _writeStyleToken(tok) {\n var el = this._buildStyle(tok);\n this._insertCursor(el, PROXY_STYLE);\n\n // Set content\n if (tok.content) {\n if (el.styleSheet && !el.sheet) {\n el.styleSheet.cssText = tok.content;\n } else {\n el.appendChild(this.doc.createTextNode(tok.content));\n }\n }\n };\n\n /**\n * Build a style element from an atomic style token.\n *\n * @param {Object} tok The token\n * @returns {Element}\n */\n\n WriteStream.prototype._buildStyle = function _buildStyle(tok) {\n var el = this.doc.createElement(tok.tagName);\n el.setAttribute('type', tok.type);\n\n // Set attributes\n utils.eachKey(tok.attrs, function (name, value) {\n el.setAttribute(name, value);\n });\n return el;\n };\n\n /**\n * Append a span to the stream. That span will act as a cursor\n * (i.e. insertion point) for the element.\n *\n * @param {Object} el The element\n * @param {string} which The type of proxy element\n */\n\n WriteStream.prototype._insertCursor = function _insertCursor(el, which) {\n this._writeImpl('<span id=\"' + which + '\"/>');\n var cursor = this.doc.getElementById(which);\n if (cursor) {\n cursor.parentNode.replaceChild(el, cursor);\n }\n };\n\n /**\n * Called when a script is started.\n *\n * @param {Object} tok The token\n * @private\n */\n\n WriteStream.prototype._onScriptStart = function _onScriptStart(tok) {\n tok.outerWrites = this.writeQueue;\n this.writeQueue = [];\n this.scriptStack.unshift(tok);\n };\n\n /**\n * Called when a script is done.\n *\n * @param {Object} tok The token\n * @private\n */\n\n WriteStream.prototype._onScriptDone = function _onScriptDone(tok) {\n // Pop script and check nesting.\n if (tok !== this.scriptStack[0]) {\n this.options.error({\n message: 'Bad script nesting or script finished twice'\n });\n return;\n }\n this.scriptStack.shift();\n\n // Append outer writes to queue and process them.\n this.write.apply(this, tok.outerWrites);\n\n // Check for pending remote\n\n // Assumption 2: if remote_script1 writes remote_script2 then\n // the we notice remote_script1 finishes before remote_script2 starts.\n // I think this is equivalent to assumption 1\n if (!this.scriptStack.length && this.deferredRemote) {\n this._onScriptStart(this.deferredRemote);\n this.deferredRemote = null;\n }\n };\n\n /**\n * Build a script and insert it into the DOM.\n * Done is called once script has executed.\n *\n * @param {Object} tok The token\n * @param {Function} done The callback when complete\n */\n\n WriteStream.prototype._writeScriptToken = function _writeScriptToken(tok, done) {\n var el = this._buildScript(tok);\n var asyncRelease = this._shouldRelease(el);\n var afterAsync = this.options.afterAsync;\n if (tok.src) {\n // Fix for attribute \"SRC\" (capitalized). IE does not recognize it.\n el.src = tok.src;\n this._scriptLoadHandler(el, !asyncRelease ? function () {\n done();\n afterAsync();\n } : afterAsync);\n }\n try {\n this._insertCursor(el, PROXY_SCRIPT);\n if (!el.src || asyncRelease) {\n done();\n }\n } catch (e) {\n this.options.error(e);\n done();\n }\n };\n\n /**\n * Build a script element from an atomic script token.\n *\n * @param {Object} tok The token\n * @returns {Element}\n */\n\n WriteStream.prototype._buildScript = function _buildScript(tok) {\n var el = this.doc.createElement(tok.tagName);\n\n // Set attributes\n utils.eachKey(tok.attrs, function (name, value) {\n el.setAttribute(name, value);\n });\n\n // Set content\n if (tok.content) {\n el.text = tok.content;\n }\n return el;\n };\n\n /**\n * Setup the script load handler on an element.\n *\n * @param {Object} el The element\n * @param {Function} done The callback\n * @private\n */\n\n WriteStream.prototype._scriptLoadHandler = function _scriptLoadHandler(el, done) {\n function cleanup() {\
1n el = el.onload = el.onreadystatechange = el.onerror = null;\n }\n var error = this.options.error;\n function success() {\n cleanup();\n done();\n }\n function failure(err) {\n cleanup();\n error(err);\n done();\n }\n\n // Set handlers\n _extends(el, {\n onload: function onload() {\n return success();\n },\n onreadystatechange: function onreadystatechange() {\n if (/^(loaded|complete)$/.test(el.readyState)) {\n success();\n }\n },\n onerror: function onerror() {\n return failure({\n message: 'remote script failed ' + el.src\n });\n }\n });\n };\n\n /**\n * Determines whether to release.\n *\n * @param {Object} el The element\n * @returns {boolean}\n * @private\n */\n\n WriteStream.prototype._shouldRelease = function _shouldRelease(el) {\n var isScript = /^script$/i.test(el.nodeName);\n return !isScript || !!(this.options.releaseAsync && el.src && el.hasAttribute('async'));\n };\n return WriteStream;\n }();\n exports['default'] = WriteStream;\n\n /***/\n }, /* 3 */\n /***/function (module, exports, __webpack_require__) {\n /**\n * @file prescribe\n * @description Tiny, forgiving HTML parser\n * @version v1.1.1\n * @see {@link https://github.com/krux/prescribe/}\n * @license MIT\n * @author Derek Brans\n * @copyright 2016 Krux Digital, Inc\n */\n (function webpackUniversalModuleDefinition(root, factory) {\n if (true) module.exports = factory();else {}\n })(this, function () {\n return /******/function (modules) {\n // webpackBootstrap\n /******/ // The module cache\n /******/\n var installedModules = {};\n\n /******/ // The require function\n /******/\n function __nested_webpack_require_28271__(moduleId) {\n /******/ // Check if module is in cache\n /******/if (installedModules[moduleId]) /******/return installedModules[moduleId].exports;\n\n /******/ // Create a new module (and put it into the cache)\n /******/\n var module = installedModules[moduleId] = {\n /******/exports: {},\n /******/id: moduleId,\n /******/loaded: false\n /******/\n };\n\n /******/ // Execute the module function\n /******/\n modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_28271__);\n\n /******/ // Flag the module as loaded\n /******/\n module.loaded = true;\n\n /******/ // Return the exports of the module\n /******/\n return module.exports;\n /******/\n }\n\n /******/ // expose the modules object (__webpack_modules__)\n /******/\n __nested_webpack_require_28271__.m = modules;\n\n /******/ // expose the module cache\n /******/\n __nested_webpack_require_28271__.c = installedModules;\n\n /******/ // __webpack_public_path__\n /******/\n __nested_webpack_require_28271__.p = \"\";\n\n /******/ // Load entry module and return exports\n /******/\n return __nested_webpack_require_28271__(0);\n /******/\n }\n /************************************************************************/\n /******/([/* 0 */\n /***/function (module, exports, __nested_webpack_require_29763__) {\n 'use strict';\n\n var _HtmlParser = __nested_webpack_require_29763__(1);\n var _HtmlParser2 = _interopRequireDefault(_HtmlParser);\n function _interopRequireDefault(obj) {\n return obj && obj.__esModule ? obj : {\n 'default': obj\n };\n }\n module.exports = _HtmlParser2['default'];\n\n /***/\n }, /* 1 */\n /***/function (module, exports, __nested_webpack_require_30189__) {\n 'use strict';\n\n exports.__esModule = true;\n var _supports = __nested_webpack_require_30189__(2);\n var supports = _interopRequireWildcard(_supports);\n var _streamReaders = __nested_webpack_require_30189__(3);\n var streamReaders = _interopRequireWildcard(_streamReaders);\n var _fixedReadTokenFactory = __nested_webpack_require_30189__(6);\n var _fixedReadTokenFactory2 = _interopRequireDefault(_fixedReadTokenFactory);\n var _utils = __nested_webpack_require_30189__(5);\n function _interopRequireDefault(obj) {\n return obj && obj.__esModule ? obj : {\n 'default': obj\n };\n }\n function _interopRequireWildcard(obj) {\n if (obj && obj.__esModule) {\n return obj;\n } else {\n var newObj = {};\n if (obj != null) {\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];\n }\n }\n newObj['default'] = obj;\n return newObj;\n }\n }\n function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\
1n throw new TypeError(\"Cannot call a class as a function\");\n }\n }\n\n /**\n * Detection regular expressions.\n *\n * Order of detection matters: detection of one can only\n * succeed if detection of previous didn't\n \t\t * @type {Object}\n */\n var detect = {\n comment: /^\x3c!--/,\n endTag: /^<\\//,\n atomicTag: /^<\\s*(script|style|noscript|iframe|textarea)[\\s\\/>]/i,\n startTag: /^</,\n chars: /^[^<]/\n };\n\n /**\n * HtmlParser provides the capability to parse HTML and return tokens\n * representing the tags and content.\n */\n\n var HtmlParser = function () {\n /**\n * Constructor.\n *\n * @param {string} stream The initial parse stream contents.\n * @param {Object} options The options\n * @param {boolean} options.autoFix Set to true to automatically fix errors\n */\n\n function HtmlParser() {\n var _this = this;\n var stream = arguments.length <= 0 || arguments[0] === undefined ? '' : arguments[0];\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n _classCallCheck(this, HtmlParser);\n this.stream = stream;\n var fix = false;\n var fixedTokenOptions = {};\n for (var key in supports) {\n if (supports.hasOwnProperty(key)) {\n if (options.autoFix) {\n fixedTokenOptions[key + 'Fix'] = true; // !supports[key];\n }\n fix = fix || fixedTokenOptions[key + 'Fix'];\n }\n }\n if (fix) {\n this._readToken = (0, _fixedReadTokenFactory2['default'])(this, fixedTokenOptions, function () {\n return _this._readTokenImpl();\n });\n this._peekToken = (0, _fixedReadTokenFactory2['default'])(this, fixedTokenOptions, function () {\n return _this._peekTokenImpl();\n });\n } else {\n this._readToken = this._readTokenImpl;\n this._peekToken = this._peekTokenImpl;\n }\n }\n\n /**\n * Appends the given string to the parse stream.\n *\n * @param {string} str The string to append\n */\n\n HtmlParser.prototype.append = function append(str) {\n this.stream += str;\n };\n\n /**\n * Prepends the given string to the parse stream.\n *\n * @param {string} str The string to prepend\n */\n\n HtmlParser.prototype.prepend = function prepend(str) {\n this.stream = str + this.stream;\n };\n\n /**\n * The implementation of the token reading.\n *\n * @private\n * @returns {?Token}\n */\n\n HtmlParser.prototype._readTokenImpl = function _readTokenImpl() {\n var token = this._peekTokenImpl();\n if (token) {\n this.stream = this.stream.slice(token.length);\n return token;\n }\n };\n\n /**\n * The implementation of token peeking.\n *\n * @returns {?Token}\n */\n\n HtmlParser.prototype._peekTokenImpl = function _peekTokenImpl() {\n for (var type in detect) {\n if (detect.hasOwnProperty(type)) {\n if (detect[type].test(this.stream)) {\n var token = streamReaders[type](this.stream);\n if (token) {\n if (token.type === 'startTag' && /script|style/i.test(token.tagName)) {\n return null;\n } else {\n token.text = this.stream.substr(0, token.length);\n return token;\n }\n }\n }\n }\n }\n };\n\n /**\n * The public token peeking interface. Delegates to the basic token peeking\n * or a ver
1sion that performs fixups depending on the `autoFix` setting in\n * options.\n *\n * @returns {object}\n */\n\n HtmlParser.prototype.peekToken = function peekToken() {\n return this._peekToken();\n };\n\n /**\n * The public token reading interface. Delegates to the basic token reading\n * or a version that performs fixups depending on the `autoFix` setting in\n * options.\n *\n * @returns {object}\n */\n\n HtmlParser.prototype.readToken = function readToken() {\n return this._readToken();\n };\n\n /**\n * Read tokens and hand to the given handlers.\n *\n * @param {Object} handlers The handlers to use for the different tokens.\n */\n\n HtmlParser.prototype.readTokens = function readTokens(handlers) {\n var tok = void 0;\n while (tok = this.readToken()) {\n // continue until we get an explicit \"false\" return\n if (handlers[tok.type] && handlers[tok.type](tok) === false) {\n return;\n }\n }\n };\n\n /**\n * Clears the parse stream.\n *\n * @returns {string} The contents of the parse stream before clearing.\n */\n\n HtmlParser.prototype.clear = function clear() {\n var rest = this.stream;\n this.stream = '';\n return rest;\n };\n\n /**\n * Returns the rest of the parse stream.\n *\n * @returns {string} The contents of the parse stream.\n */\n\n HtmlParser.prototype.rest = function rest() {\n return this.stream;\n };\n return HtmlParser;\n }();\n exports['default'] = HtmlParser;\n HtmlParser.tokenToString = function (tok) {\n return tok.toString();\n };\n HtmlParser.escapeAttributes = function (attrs) {\n var escapedAttrs = {};\n for (var name in attrs) {\n if (attrs.hasOwnProperty(name)) {\n escapedAttrs[name] = (0, _utils.escapeQuotes)(attrs[name], null);\n }\n }\n return escapedAttrs;\n };\n HtmlParser.supports = supports;\n for (var key in supports) {\n if (supports.hasOwnProperty(key)) {\n HtmlParser.browserHasFlaw = HtmlParser.browserHasFlaw || !supports[key] && key;\n }\n }\n\n /***/\n }, /* 2 */\n /***/function (module, exports) {\n 'use strict';\n\n exports.__esModule = true;\n var tagSoup = false;\n var selfClose = false;\n var work = window.document.createElement('div');\n try {\n var html = '<P><I></P></I>';\n work.innerHTML = html;\n exports.tagSoup = tagSoup = work.innerHTML !== html;\n } catch (e) {\n exports.tagSoup = tagSoup = false;\n }\n try {\n work.innerHTML = '<P><i><P></P></i></P>';\n exports.selfClose = selfClose = work.childNodes.length === 2;\n } catch (e) {\n exports.selfClose = selfClose = false;\n }\n work = null;\n exports.tagSoup = tagSoup;\n exports.selfClose = selfClose;\n\n /***/\n }, /* 3 */\n /***/function (module, exports, __nested_webpack_require_38882__) {\n 'use strict';\n\n exports.__esModule = true;\n var _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol ? \"symbol\" : typeof obj;\n };\n exports.comment = comment;\n exports.chars = chars;\n exports.startTag = startTag;\n exports.atomicTag = atomicTag;\n exports.endTag = endTag;\n var _tokens = __nested_webpack_require_38882__(4);\n\n /**\n * Regular Expressions for parsing tags and attributes\n *\n * @type {Object}\n */\n var REGEXES = {\n startTag: /^<([\\-A-Za-z0-9_]+)((?:\\s+[\\w\\-]+(?:\\s*=?\\s*(?:(?
1:\"[^\"]*\")|(?:'[^']*')|[^>\\s]+))?)*)\\s*(\\/?)>/,\n endTag: /^<\\/([\\-A-Za-z0-9_]+)[^>]*>/,\n attr: /(?:([\\-A-Za-z0-9_]+)\\s*=\\s*(?:(?:\"((?:\\\\.|[^\"])*)\")|(?:'((?:\\\\.|[^'])*)')|([^>\\s]+)))|(?:([\\-A-Za-z0-9_]+)(\\s|$)+)/g,\n fillAttr: /^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noresize|noshade|nowrap|readonly|selected)$/i\n };\n\n /**\n * Reads a comment token\n *\n * @param {string} stream The input stream\n * @returns {CommentToken}\n */\n function comment(stream) {\n var index = stream.indexOf('--\x3e');\n if (index >= 0) {\n return new _tokens.CommentToken(stream.substr(4, index - 1), index + 3);\n }\n }\n\n /**\n * Reads non-tag characters.\n *\n * @param {string} stream The input stream\n * @returns {CharsToken}\n */\n function chars(stream) {\n var index = stream.indexOf('<');\n return new _tokens.CharsToken(index >= 0 ? index : stream.length);\n }\n\n /**\n * Reads start tag token.\n *\n * @param {string} stream The input stream\n * @returns {StartTagToken}\n */\n function startTag(stream) {\n var endTagIndex = stream.indexOf('>');\n if (endTagIndex !== -1) {\n var match = stream.match(REGEXES.startTag);\n if (match) {\n var _ret = function () {\n var attrs = {};\n var booleanAttrs = {};\n var rest = match[2];\n match[2].replace(REGEXES.attr, function (match, name) {\n if (!(arguments[2] || arguments[3] || arguments[4] || arguments[5])) {\n attrs[name] = '';\n } else if (arguments[5]) {\n attrs[arguments[5]] = '';\n booleanAttrs[arguments[5]] = true;\n } else {\n attrs[name] = arguments[2] || arguments[3] || arguments[4] || REGEXES.fillAttr.test(name) && name || '';\n }\n rest = rest.replace(match, '');\n });\n return {\n v: new _tokens.StartTagToken(match[1], match[0].length, attrs, booleanAttrs, !!match[3], rest.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, ''))\n };\n }();\n if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === \"object\") return _ret.v;\n }\n }\n }\n\n /**\n * Reads atomic tag token.\n *\n * @param {string} stream The input stream\n * @returns {AtomicTagToken}\n */\n function atomicTag(stream) {\n var start = startTag(stream);\n if (start) {\n var rest = stream.slice(start.length);\n // for optimization, we check first just for the end tag\n if (rest.match(new RegExp('<\\/\\\\s*' + start.tagName + '\\\\s*>', 'i'))) {\n // capturing the content is inefficient, so we do it inside the if\n var match = rest.match(new RegExp('([\\\\s\\\\S]*?)<\\/\\\\s*' + start.tagName + '\\\\s*>', 'i'));\n if (match) {\n return new _tokens.AtomicTagToken(start.tagName, match[0].length + start.length, start.attrs, start.booleanAttrs, match[1]);\n }\n }\n }\n }\n\n /**\n * Reads an end tag token.\n *\n * @param {string} stream The input stream\n * @returns {EndTagToken}\n */\n function endTag(stream) {\n var match = stream.match(REGEXES.endTag);\n if (match) {\n return new _tokens.EndTagToken(match[1], match[0].length);\n }\n }\n\n /***/\n }, /* 4 */\n /***/function (module, exports, __nested_webpack_require_43509__) {\n 'use strict';\n\n exports.__esModule = true;\n exports.EndTagToken = exports.AtomicTagToken = exports.StartTagToken = exports.TagToken = exports.CharsToken = exports.CommentToken = exports.Token = undefined;\n var _utils = __nested_webpack_require_43509__(5);\n function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\
1n throw new TypeError(\"Cannot call a class as a function\");\n }\n }\n\n /**\n * Token is a base class for all token types parsed. Note we don't actually\n * use intheritance due to IE8's non-existent ES5 support.\n */\n\n var Token =\n /**\n * Constructor.\n *\n * @param {string} type The type of the Token.\n * @param {Number} length The length of the Token text.\n */\n exports.Token = function Token(type, length) {\n _classCallCheck(this, Token);\n this.type = type;\n this.length = length;\n this.text = '';\n };\n\n /**\n * CommentToken represents comment tags.\n */\n\n var CommentToken = exports.CommentToken = function () {\n /**\n * Constructor.\n *\n * @param {string} content The content of the comment\n * @param {Number} length The length of the Token text.\n */\n\n function CommentToken(content, length) {\n _classCallCheck(this, CommentToken);\n this.type = 'comment';\n this.length = length || (content ? content.length : 0);\n this.text = '';\n this.content = content;\n }\n CommentToken.prototype.toString = function toString() {\n return '\x3c!--' + this.content;\n };\n return CommentToken;\n }();\n\n /**\n * CharsToken represents non-tag characters.\n */\n\n var CharsToken = exports.CharsToken = function () {\n /**\n * Constructor.\n *\n * @param {Number} length The length of the Token text.\n */\n\n function CharsToken(length) {\n _classCallCheck(this, CharsToken);\n this.type = 'chars';\n this.length = length;\n this.text = '';\n }\n CharsToken.prototype.toString = function toString() {\n return this.text;\n };\n return CharsToken;\n }();\n\n /**\n * TagToken is a base class for all tag-based Tokens.\n */\n\n var TagToken = exports.TagToken = function () {\n /**\n * Constructor.\n *\n * @param {string} type The type of the token.\n * @param {string} tagName The tag name.\n * @param {Number} length The length of the Token text.\n * @param {Object} attrs The dictionary of attributes and values\n * @param {Object} booleanAttrs If an entry has 'true' then the attribute\n * is a boolean attribute\n */\n\n function TagToken(type, tagName, length, attrs, booleanAttrs) {\n _classCallCheck(this, TagToken);\n this.type = type;\n this.length = length;\n this.text = '';\n this.tagName = tagName;\n this.attrs = attrs;\n this.booleanAttrs = booleanAttrs;\n this.unary = false;\n this.html5Unary = false;\n }\n\n /**\n * Formats the given token tag.\n *\n * @param {TagToken} tok The TagToken to format.\n * @param {?string} [content=null] The content of the token.\n * @returns {string} The formatted tag.\n */\n\n TagToken.formatTag = function formatTag(tok) {\n var content = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];\n var str = '<' + tok.tagName;\n for (var key in tok.attrs) {\n if (tok.attrs.hasOwnProperty(key)) {\n str += ' ' + key;\n var val = tok.attrs[key];\n if (typeof tok.booleanAttrs === 'undefined' || typeof tok.booleanAttrs[key] === 'undefined') {\n str += '=\"' + (0, _utils.escapeQuotes)(val) + '\"';\n }\n }\n }\n if (tok.rest) {\n str += ' ' + tok.rest;\n }\n if (tok.unary && !tok.html5Unary) {\n str += '/>';\n } else {\n str += '>';\n }\n if (content !== undefined && content !== null) {\n str += content + '</' + tok.tagName + '>';\n }\n return str;\n };\n return TagToken;\n }();\n\n /**\n * StartTagToken represents a start token.\n */\n\n var StartTagToken = exports.StartTagToken = function () {\n /**\n * Constructor.\n *\n * @param {string} tagName The tag name.\n * @param {Number} length The length of the Token text\n * @param {Object} attrs The dictionary of attributes and values\n * @param {Object} booleanAttrs If an entry has 'true' then the attribute\n * is a boolean attribute\n * @param {boolean} unary True if the tag is a unary tag\n * @param {string} rest The rest of the content.\n */\n\n function StartTagToken(tagName, length, attrs, booleanAttrs, unary, rest) {\n _classCallCheck(this, StartTagToken);\n this.type = 'startTag';\n this.length = length;\n this.text = '';\n this.tagName = tagName;\n this.attrs = attrs;\n this.booleanAttrs = booleanAttrs;\n this.html5Unary = false;\n this.unary = unary;\n this.rest = rest;\n }\n StartTagToken.prototype.toString = function toString() {\n return TagToken.formatTag(this);\n };\n return StartTagToken;\n }();\n\n /**\n * AtomicTagToken represents an atomic tag.\n */\n\n var AtomicTagToken = exports.AtomicTagToken = function () {\n /**\n * Constructor.\n *\n * @param {string} tagName The name of the tag.\n * @param {Number} length The length of the tag text.\n * @param {Object} attrs The attributes.\n * @param {Object} booleanAttrs If an entry has 'true' then the attribute\n * is a boolean attribute\n * @param {string} content The content of the tag.\n */\n\n function AtomicTagToken(tagName, length, attrs, booleanAttrs, content) {\n _classCallCheck(this, AtomicTagToken);\n this.type = 'atomicTag';\n this.length = length;\n this.text = '';\n this.tagName = tagName;\n this.attrs = attrs;\n this.booleanAttrs = booleanAttrs;\n this.unary = false;\n this.html5Unary = false;\n this.content = content;\n }\n AtomicTagToken.prototype.toString = function toString() {\n return TagToken.formatTag(this, this.content);\n };\n return AtomicTagToken;\n }();\n\n /**\n * EndTagToken represents an end tag.\n */\n\n var EndTagToken = exports.EndTagToken = function () {\n /**\n * Constructor.\n *\n * @param {string} tagName The name of the tag.\n * @param {Number} length The length of the tag text.\n */\n\n function EndTagToken(tagName, length) {\n _classCallCheck(this, EndTagToken);\n this.type = 'endTag';\n this.length = length;\n this.text = '';\n this.tagName = tagName;\n }\n EndTagToken.prototype.toString = function toString() {\n return '</' + this.tagName + '>';\n };\n return EndTagToken;\n }();\n\n /***/\n }
1, /* 5 */\n /***/function (module, exports) {\n 'use strict';\n\n exports.__esModule = true;\n exports.escapeQuotes = escapeQuotes;\n\n /**\n * Escape quotes in the given value.\n *\n * @param {string} value The value to escape.\n * @param {string} [defaultValue=''] The default value to return if value is falsy.\n * @returns {string}\n */\n function escapeQuotes(value) {\n var defaultValue = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];\n\n // There's no lookback in JS, so /(^|[^\\\\])\"/ only matches the first of two `\"`s.\n // Instead, just match anything before a double-quote and escape if it's not already escaped.\n return !value ? defaultValue : value.replace(/([^\"]*)\"/g, function (_, prefix) {\n return /\\\\/.test(prefix) ? prefix + '\"' : prefix + '\\\\\"';\n });\n }\n\n /***/\n }, /* 6 */\n /***/function (module, exports) {\n 'use strict';\n\n exports.__esModule = true;\n exports['default'] = fixedReadTokenFactory;\n /**\n * Empty Elements - HTML 4.01\n *\n * @type {RegExp}\n */\n var EMPTY = /^(AREA|BASE|BASEFONT|BR|COL|FRAME|HR|IMG|INPUT|ISINDEX|LINK|META|PARAM|EMBED)$/i;\n\n /**\n * Elements that you can intentionally leave open (and which close themselves)\n *\n * @type {RegExp}\n */\n var CLOSESELF = /^(COLGROUP|DD|DT|LI|OPTIONS|P|TD|TFOOT|TH|THEAD|TR)$/i;\n\n /**\n * Corrects a token.\n *\n * @param {Token} tok The token to correct\n * @returns {Token} The corrected token\n */\n function correct(tok) {\n if (tok && tok.type === 'startTag') {\n tok.unary = EMPTY.test(tok.tagName) || tok.unary;\n tok.html5Unary = !/\\/>$/.test(tok.text);\n }\n return tok;\n }\n\n /**\n * Peeks at the next token in the parser.\n *\n * @param {HtmlParser} parser The parser\n * @param {Function} readTokenImpl The underlying readToken implementation\n * @returns {Token} The next token\n */\n function peekToken(parser, readTokenImpl) {\n var tmp = parser.stream;\n var tok = correct(readTokenImpl());\n parser.stream = tmp;\n return tok;\n }\n\n /**\n * Closes the last token.\n *\n * @param {HtmlParser} parser The parser\n * @param {Array<Token>} stack The stack\n */\n function closeLast(parser, stack) {\n var tok = stack.pop();\n\n // prepend close tag to stream.\n parser.prepend('</' + tok.tagName + '>');\n }\n\n /**\n * Create a new token stack.\n *\n * @returns {Array<Token>}\n */\n function newStack() {\n var stack = [];\n stack.last = function () {\n return this[this.length - 1];\n };\n stack.lastTagNameEq = function (tagName) {\n var last = this.last();\n return last && last.tagName && last.tagName.toUpperCase() === tagName.toUpperCase();\n };\n stack.containsTagName = function (tagName) {\n for (var i = 0, tok; tok = this[i]; i++) {\n if (tok.tagName === tagName) {\n return true;\n }\n }\n return false;\n };\n return stack;\n }\n\n /**\n * Return a readToken implementation that fixes input.\n *\n * @param {HtmlParser} parser The parser\n * @param {Object} options Options for fixing\n * @param {boolean} options.tagSoupFix True to fix tag soup scenarios\n * @param {boolean} options.selfCloseFix True to fix self-closing tags\n * @param {Function} readTokenImpl The underlying readToken implementation\n * @returns {Function}\n */\n function fixedReadTokenFactory(parser, options, readTokenImpl) {\n var stack = newStack();\n var handlers = {\n startTag: function startTag(tok) {\n var tagName = tok.tagName;\n if (tagName.toUpperCase() === 'TR' && stack.lastTagNameEq('TABLE')) {\n parser.prepend('<TBODY>');\n prepareNextToken();\n } else if (options.selfCloseFix && CLOSESELF.test(tagName) && stack.containsTagName(tagName)) {\
1n if (stack.lastTagNameEq(tagName)) {\n closeLast(parser, stack);\n } else {\n parser.prepend('</' + tok.tagName + '>');\n prepareNextToken();\n }\n } else if (!tok.unary) {\n stack.push(tok);\n }\n },\n endTag: function endTag(tok) {\n var last = stack.last();\n if (last) {\n if (options.tagSoupFix && !stack.lastTagNameEq(tok.tagName)) {\n // cleanup tag soup\n closeLast(parser, stack);\n } else {\n stack.pop();\n }\n } else if (options.tagSoupFix) {\n // cleanup tag soup part 2: skip this token\n readTokenImpl();\n prepareNextToken();\n }\n }\n };\n function prepareNextToken() {\n var tok = peekToken(parser, readTokenImpl);\n if (tok && handlers[tok.type]) {\n handlers[tok.type](tok);\n }\n }\n return function fixedReadToken() {\n prepareNextToken();\n return correct(readTokenImpl());\n };\n }\n\n /***/\n }\n /******/]);\n });\n ;\n\n /***/\n }, /* 4 */\n /***/function (module, exports) {\n 'use strict';\n\n exports.__esModule = true;\n var _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol ? \"symbol\" : typeof obj;\n };\n exports.existy = existy;\n exports.isFunction = isFunction;\n exports.each = each;\n exports.eachKey = eachKey;\n exports.defaults = defaults;\n exports.toArray = toArray;\n exports.last = last;\n exports.isTag = isTag;\n exports.isScript = isScript;\n exports.isStyle = isStyle;\n /**\n * Determine if the thing is not undefined and not null.\n *\n * @param {*} thing The thing to test\n * @returns {boolean} True if the thing is not undefined and not null.\n */\n function existy(thing) {\n return thing !== void 0 && thing !== null;\n }\n\n /**\n * Is this a function?\n *\n * @param {*} x The variable to test\n * @returns {boolean} True if the variable is a function\n */\n function isFunction(x) {\n return 'function' === typeof x;\n }\n\n /**\n * Loop over each item in an array-like value.\n *\n * @param {Array<*>} arr The array to loop over\n * @param {Function} fn The function to call\n * @param {?Object} target The object to bind to the function\n */\n function each(arr, fn, target) {\n var i = void 0;\n var len = arr && arr.length || 0;\n for (i = 0; i < len; i++) {\n fn.call(target, arr[i], i);\n }\n }\n\n /**\n * Loop over each key/value pair in a hash.\n *\n * @param {Object} obj The object\n * @param {Function} fn The function to call\n * @param {?Object} target The object to bind to the function\n */\n function eachKey(obj, fn, target) {\n for (var key in obj) {\n if (obj.hasOwnProperty(key)) {\n fn.call(target, key, obj[key]);\n }\n }\n }\n\n /**\n * Set default options where some option was not specified.\n *\n * @param {Object} options The destination\n * @param {Object} _defaults The defaults\n * @returns {Object}\n */\n function defaults(options, _defaults) {\n options = options || {};\n eachKey(_defaults, function (key, val) {\n if (!existy(options[key])) {\n options[key] = val;\n }\n });\n return options;\n }\n\n /**\n * Convert value (e.g., a NodeList) to an array.\n *\n * @param {*} obj The object\n * @returns {Array<*>}\n */\n function toArray(obj) {\n try {\n return Array.prototype.slice.call(obj);\n } catch (e) {\n var _ret = function () {\n var ret = [];
1\n each(obj, function (val) {\n ret.push(val);\n });\n return {\n v: ret\n };\n }();\n if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === \"object\") return _ret.v;\n }\n }\n\n /**\n * Get the last item in an array\n *\n * @param {Array<*>} array The array\n * @returns {*} The last item in the array\n */\n function last(array) {\n return array[array.length - 1];\n }\n\n /**\n * Test if token is a script tag.\n *\n * @param {Object} tok The token\n * @param {String} tag The tag name\n * @returns {boolean} True if the token is a script tag\n */\n function isTag(tok, tag) {\n return !tok || !(tok.type === 'startTag' || tok.type === 'atomicTag') || !('tagName' in tok) ? !1 : !!~tok.tagName.toLowerCase().indexOf(tag);\n }\n\n /**\n * Test if token is a script tag.\n *\n * @param {Object} tok The token\n * @returns {boolean} True if the token is a script tag\n */\n function isScript(tok) {\n return isTag(tok, 'script');\n }\n\n /**\n * Test if token is a style tag.\n *\n * @param {Object} tok The token\n * @returns {boolean} True if the token is a style tag\n */\n function isStyle(tok) {\n return isTag(tok, 'style');\n }\n\n /***/\n }\n /******/]);\n});\n;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTU2LmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vdmVuZG9yL3Bvc3RzY3JpYmUuanM/MThlYSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBmaWxlIHBvc3RzY3JpYmVcbiAqIEBkZXNjcmlwdGlvbiBBc3luY2hyb25vdXNseSB3cml0ZSBqYXZhc2NyaXB0LCBldmVuIHdpdGggZG9jdW1lbnQud3JpdGUuXG4gKiBAdmVyc2lvbiB2Mi4wLjZcbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8va3J1eC5naXRodWIuaW8vcG9zdHNjcmliZX1cbiAqIEBsaWNlbnNlIE1JVFxuICogQGF1dGhvciBEZXJlayBCcmFuc1xuICogQGNvcHlyaWdodCAyMDE2IEtydXggRGlnaXRhbCwgSW5jXG4gKi9cbihmdW5jdGlvbiB3ZWJwYWNrVW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbihyb290LCBmYWN0b3J5KSB7XG5cdGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0Jylcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0ZGVmaW5lKFtdLCBmYWN0b3J5KTtcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXG5cdFx0ZXhwb3J0c1tcInBvc3RzY3JpYmVcIl0gPSBmYWN0b3J5KCk7XG5cdGVsc2Vcblx0XHRyb290W1wicG9zdHNjcmliZVwiXSA9IGZhY3RvcnkoKTtcbn0pKHRoaXMsIGZ1bmN0aW9uKCkge1xucmV0dXJuIC8qKioqKiovIChmdW5jdGlvbihtb2R1bGVzKSB7IC8vIHdlYnBhY2tCb290c3RyYXBcbi8qKioqKiovIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuLyoqKioqKi8gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbi8qKioqKiovIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuLyoqKioqKi9cbi8qKioqKiovIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbi8qKioqKiovIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSlcbi8qKioqKiovIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuLyoqKioqKi9cbi8qKioqKiovIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuLyoqKioqKi8gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbi8qKioqKiovIFx0XHRcdGV4cG9ydHM6IHt9LFxuLyoqKioqKi8gXHRcdFx0aWQ6IG1vZHVsZUlkLFxuLyoqKioqKi8gXHRcdFx0bG9hZGVkOiBmYWxzZVxuLyoqKioqKi8gXHRcdH07XG4vKioqKioqL1xuLyoqKioqKi8gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuLyoqKioqKi8gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuLyoqKioqKi9cbi8qKioqKiovIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4vKioqKioqLyBcdFx0bW9kdWxlLmxvYWRlZCA9IHRydWU7XG4vKioqKioqL1xuLyoqKioqKi8gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4vKioqKioqLyBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuLyoqKioqKi8gXHR9XG4vKioqKioqL1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO
11xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4vKioqKioqLyBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xuLyoqKioqKi8gfSlcbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKioqKioqLyAoW1xuLyogMCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0J3VzZSBzdHJpY3QnO1xuXHRcblx0dmFyIF9wb3N0c2NyaWJlID0gX193ZWJwYWNrX3JlcXVpcmVfXygxKTtcblx0XG5cdHZhciBfcG9zdHNjcmliZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9wb3N0c2NyaWJlKTtcblx0XG5cdGZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblx0XG5cdG1vZHVsZS5leHBvcnRzID0gX3Bvc3RzY3JpYmUyWydkZWZhdWx0J107XG5cbi8qKiovIH0sXG4vKiAxICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdFxuXHRleHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXHRcblx0dmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblx0XG5cdGV4cG9ydHNbJ2RlZmF1bHQnXSA9IHBvc3RzY3JpYmU7XG5cdFxuXHR2YXIgX3dyaXRlU3RyZWFtID0gX193ZWJwYWNrX3JlcXVpcmVfXygyKTtcblx0XG5cdHZhciBfd3JpdGVTdHJlYW0yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfd3JpdGVTdHJlYW0pO1xuXHRcblx0dmFyIF91dGlscyA9IF9fd2VicGFja19yZXF1aXJlX18oNCk7XG5cdFxuXHR2YXIgdXRpbHMgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfdXRpbHMpO1xuXHRcblx0ZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQob2JqKSB7IGlmIChvYmogJiYgb2JqLl9fZXNNb2R1bGUpIHsgcmV0dXJuIG9iajsgfSBlbHNlIHsgdmFyIG5ld09iaiA9IHt9OyBpZiAob2JqICE9IG51bGwpIHsgZm9yICh2YXIga2V5IGluIG9iaikgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkgbmV3T2JqW2tleV0gPSBvYmpba2V5XTsgfSB9IG5ld09ialsnZGVmYXVsdCddID0gb2JqOyByZXR1cm4gbmV3T2JqOyB9IH1cblx0XG5cdGZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblx0XG5cdC8qKlxuXHQgKiBBIGZ1bmN0aW9uIHRoYXQgaW50ZW50aW9uYWxseSBkb2VzIG5vdGhpbmcuXG5cdCAqL1xuXHRmdW5jdGlvbiBkb05vdGhpbmcoKSB7fVxuXHRcblx0LyoqXG5cdCAqIEF2YWlsYWJsZSBvcHRpb25zIGFuZCBkZWZhdWx0cy5cblx0ICpcblx0ICogQHR5cGUge09iamVjdH1cblx0ICovXG5cdHZhciBPUFRJT05TID0ge1xuXHQgIC8qKlxuXHQgICAqIENhbGxlZCB3aGVuIGFuIGFzeW5jIHNjcmlwdCBoYXMgbG9hZGVkLlxuXHQgICAqL1xuXHQgIGFmdGVyQXN5bmM6IGRvTm90aGluZyxcblx0XG5cdCAgLyoqXG5cdCAgICogQ2FsbGVkIGltbWVkaWF0ZWx5IGJlZm9yZSByZW1vdmluZyBmcm9tIHRoZSB3cml0ZSBxdWV1ZS5cblx0ICAgKi9cblx0ICBhZnRlckRlcXVldWU6IGRvTm90aGluZyxcblx0XG5cdCAgLyoqXG5cdCAgICogQ2FsbGVkIHN5bmMgYWZ0ZXIgYSBzdHJlYW0ncyBmaXJzdCB0aHJlYWQgcmVsZWFzZS5cblx0ICAgKi9cblx0ICBhZnRlclN0cmVhbVN0YXJ0OiBkb05vdGhpbmcsXG5cdFxuXHQgIC8qKlxuXHQgICAqIENhbGxlZCBhZnRlciB3cml0aW5nIGJ1ZmZlcmVkIGRvY3VtZW50LndyaXRlIGNhbGxzLlxuXHQgICAqL1xuXHQgIGFmdGVyV3JpdGU6IGRvTm90aGluZyxcblx0XG5cdCAgLyoqXG5cdCAgICogQWxsb3dzIGRpc2FibGluZyB0aGUgYXV0b0ZpeCBmZWF0dXJlIG9mIHByZXNjcmliZVxuXHQgICAqL1xuXHQgIGF1dG9GaXg6IHRydWUsXG5cdFxuXHQgIC8qKlxuXHQgICAqIENhbGxlZCBpbW1lZGlhdGVseSBiZWZvcmUgYWRkaW5nIHRvIHRoZSB3cml0ZSBxdWV1ZS5cblx0ICAgKi9cblx0ICBiZWZvcmVFbnF1ZXVlOiBkb05vdGhpbmcsXG5cdFxuXHQgIC8qKlxuXHQgICAqIENhbGxlZCBiZWZvcmUgd3JpdGluZyBhIHRva2VuLlxuXHQgICAqXG5cdCAgICogQHBhcmFtIHtPYmplY3R9IHRvayBUaGUgdG9rZW5cblx0ICAgKi9cblx0ICBiZWZvcmVXcml0ZVRva2VuOiBmdW5jdGlvbiBiZWZvcmVXcml0ZVRva2VuKHRvaykge1xuXHQgICAgcmV0dXJuIHRvaztcblx0ICB9LFxuXHRcblx0ICAvKipcblx0ICAgKiBDYWxsZWQgYmVmb3JlIHdyaXRpbmcgYnVmZmVyZWQgZG9jdW1lbnQud3JpdGUgY2FsbHMuXG5cdCAgICpcblx0ICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFRoZSBzdHJpbmdcblx0ICAgKi9cblx0ICBiZWZvcmVXcml0ZTogZnVuY3Rpb24gYmVmb3JlV3JpdGUoc3RyKSB7XG5cdCAgICByZXR1cm4gc3RyO1xuXHQgIH0sXG5cdFxuXHQgIC8qKlxuXHQgICAqIENhbGxlZCB3aGVuIGV2YWx1YXRpb24gaXMgZmluaXNoZWQuXG5cdCAgICovXG5cdCAgZG9uZTogZG9Ob3RoaW5nLFxuXHRcblx0ICAvKipcblx0ICAgKiBDYWxsZWQgd2hlbiBhIHdyaXRlIHJlc3VsdHMgaW4gYW4gZXJyb3IuXG5cdCAgICpcblx0ICAgKiBAcGFyYW0ge0Vycm9yfSBlIFRoZSBlcnJvclxuXHQgICAqL1xuXHQgIGVycm9yOiBmdW5jdGlvbiBlcnJvcihlKSB7XG5cdCAgICB0aHJvdyBlO1xuXHQgIH0sXG5cdFxuXHRcblx0ICAvKipcblx0ICAgKiBXaGV0aGVyIHRvIGxldCBzY3JpcHRzIHcvIGFzeW5jIGF0dHJpYnV0ZSBzZXQgZmFsbCBvdXQgb2YgdGhlIHF1ZXVlLlxuXHQgICAqL1xuXHQgIHJlbGVhc2VBc3luYzogZmFsc2Vcblx0fTtcblx0XG5cdHZhciBuZXh0SWQgPSAwO1xuXHR2YXIgcXVldWUgPSBbXTtcblx0dmFyIGFjdGl2ZSA9IG51bGw7XG5cdFxuXHRmdW5jdGlvbiBuZXh0U3RyZWFtKCkge1xuXHQgIHZhciBhcmdzID0gcXVldWUuc2hpZnQoKTtcblx0ICBpZiAoYXJncykge1xuXHQgICAgdmFyIG9wdGlvbnMgPSB1dGlscy5sYXN0KGFyZ3MpO1xuXHRcblx0ICAgIG9wdGlvbnMuYWZ0ZXJEZXF1ZXVlKCk7XG5cdCAgICBhcmdzLnN0cmVhbSA9IHJ1blN0cmVhbS5hcHBseSh1bmRlZmluZWQsIGFyZ3MpO1xuXHQgICAgb3B0aW9ucy5hZnRlclN0cmVhbVN0YXJ0KCk7XG5cdCAgfVxuXHR9XG5cdFxuXHRmdW5jdGlvbiBydW5TdHJlYW0oZWwsIGh0bWwsIG9wdGlvbnMpIHtcblx0ICBhY3RpdmUgPSBuZXdcblx0ICAvLyBFeHBvc2UgaW50ZXJuYWwgY2xhc3Nlcy5cblx0ICBfd3JpdG
1VTdHJlYW0yWydkZWZhdWx0J10oZWwsIG9wdGlvbnMpO1xuXHRcblx0ICAvLyBJZGVudGlmeSB0aGlzIHN0cmVhbS5cblx0ICBhY3RpdmUuaWQgPSBuZXh0SWQrKztcblx0ICBhY3RpdmUubmFtZSA9IG9wdGlvbnMubmFtZSB8fCBhY3RpdmUuaWQ7XG5cdCAgcG9zdHNjcmliZS5zdHJlYW1zW2FjdGl2ZS5uYW1lXSA9IGFjdGl2ZTtcblx0XG5cdCAgLy8gT3ZlcnJpZGUgZG9jdW1lbnQud3JpdGUuXG5cdCAgdmFyIGRvYyA9IGVsLm93bmVyRG9jdW1lbnQ7XG5cdFxuXHQgIHZhciBzdGFzaCA9IHtcblx0ICAgIGNsb3NlOiBkb2MuY2xvc2UsXG5cdCAgICBvcGVuOiBkb2Mub3Blbixcblx0ICAgIHdyaXRlOiBkb2Mud3JpdGUsXG5cdCAgICB3cml0ZWxuOiBkb2Mud3JpdGVsblxuXHQgIH07XG5cdFxuXHQgIGZ1bmN0aW9uIF93cml0ZShzdHIpIHtcblx0ICAgIHN0ciA9IG9wdGlvbnMuYmVmb3JlV3JpdGUoc3RyKTtcblx0ICAgIGFjdGl2ZS53cml0ZShzdHIpO1xuXHQgICAgb3B0aW9ucy5hZnRlcldyaXRlKHN0cik7XG5cdCAgfVxuXHRcblx0ICBfZXh0ZW5kcyhkb2MsIHtcblx0ICAgIGNsb3NlOiBkb05vdGhpbmcsXG5cdCAgICBvcGVuOiBkb05vdGhpbmcsXG5cdCAgICB3cml0ZTogZnVuY3Rpb24gd3JpdGUoKSB7XG5cdCAgICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBzdHIgPSBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcblx0ICAgICAgICBzdHJbX2tleV0gPSBhcmd1bWVudHNbX2tleV07XG5cdCAgICAgIH1cblx0XG5cdCAgICAgIHJldHVybiBfd3JpdGUoc3RyLmpvaW4oJycpKTtcblx0ICAgIH0sXG5cdCAgICB3cml0ZWxuOiBmdW5jdGlvbiB3cml0ZWxuKCkge1xuXHQgICAgICBmb3IgKHZhciBfbGVuMiA9IGFyZ3VtZW50cy5sZW5ndGgsIHN0ciA9IEFycmF5KF9sZW4yKSwgX2tleTIgPSAwOyBfa2V5MiA8IF9sZW4yOyBfa2V5MisrKSB7XG5cdCAgICAgICAgc3RyW19rZXkyXSA9IGFyZ3VtZW50c1tfa2V5Ml07XG5cdCAgICAgIH1cblx0XG5cdCAgICAgIHJldHVybiBfd3JpdGUoc3RyLmpvaW4oJycpICsgJ1xcbicpO1xuXHQgICAgfVxuXHQgIH0pO1xuXHRcblx0ICAvLyBPdmVycmlkZSB3aW5kb3cub25lcnJvclxuXHQgIHZhciBvbGRPbkVycm9yID0gYWN0aXZlLndpbi5vbmVycm9yIHx8IGRvTm90aGluZztcblx0XG5cdCAgLy8gVGhpcyB3b3JrcyB0b2dldGhlciB3aXRoIHRoZSB0cnkvY2F0Y2ggYXJvdW5kIFdyaXRlU3RyZWFtOjppbnNlcnRTY3JpcHRcblx0ICAvLyBJbiBtb2Rlcm4gYnJvd3NlcnMsIGV4Y2VwdGlvbnMgaW4gdGFnIHNjcmlwdHMgZ28gZGlyZWN0bHkgdG8gdG9wIGxldmVsXG5cdCAgYWN0aXZlLndpbi5vbmVycm9yID0gZnVuY3Rpb24gKG1zZywgdXJsLCBsaW5lKSB7XG5cdCAgICBvcHRpb25zLmVycm9yKHsgbXNnOiBtc2cgKyAnIC0gJyArIHVybCArICc6ICcgKyBsaW5lIH0pO1xuXHQgICAgb2xkT25FcnJvci5hcHBseShhY3RpdmUud2luLCBbbXNnLCB1cmwsIGxpbmVdKTtcblx0ICB9O1xuXHRcblx0ICAvLyBXcml0ZSB0byB0aGUgc3RyZWFtXG5cdCAgYWN0aXZlLndyaXRlKGh0bWwsIGZ1bmN0aW9uICgpIHtcblx0ICAgIC8vIHJlc3RvcmUgZG9jdW1lbnQud3JpdGVcblx0ICAgIF9leHRlbmRzKGRvYywgc3Rhc2gpO1xuXHRcblx0ICAgIC8vIHJlc3RvcmUgd2luZG93Lm9uZXJyb3Jcblx0ICAgIGFjdGl2ZS53aW4ub25lcnJvciA9IG9sZE9uRXJyb3I7XG5cdFxuXHQgICAgb3B0aW9ucy5kb25lKCk7XG5cdCAgICBhY3RpdmUgPSBudWxsO1xuXHQgICAgbmV4dFN0cmVhbSgpO1xuXHQgIH0pO1xuXHRcblx0ICByZXR1cm4gYWN0aXZlO1xuXHR9XG5cdFxuXHRmdW5jdGlvbiBwb3N0c2NyaWJlKGVsLCBodG1sLCBvcHRpb25zKSB7XG5cdCAgaWYgKHV0aWxzLmlzRnVuY3Rpb24ob3B0aW9ucykpIHtcblx0ICAgIG9wdGlvbnMgPSB7IGRvbmU6IG9wdGlvbnMgfTtcblx0ICB9IGVsc2UgaWYgKG9wdGlvbnMgPT09ICdjbGVhcicpIHtcblx0ICAgIHF1ZXVlID0gW107XG5cdCAgICBhY3RpdmUgPSBudWxsO1xuXHQgICAgbmV4dElkID0gMDtcblx0ICAgIHJldHVybjtcblx0ICB9XG5cdFxuXHQgIG9wdGlvbnMgPSB1dGlscy5kZWZhdWx0cyhvcHRpb25zLCBPUFRJT05TKTtcblx0XG5cdCAgLy8gaWQgc2VsZWN0b3Jcblx0ICBpZiAoL14jLy50ZXN0KGVsKSkge1xuXHQgICAgZWwgPSB3aW5kb3cuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWwuc3Vic3RyKDEpKTtcblx0ICB9IGVsc2Uge1xuXHQgICAgZWwgPSBlbC5qcXVlcnkgPyBlbFswXSA6IGVsO1xuXHQgIH1cblx0XG5cdCAgdmFyIGFyZ3MgPSBbZWwsIGh0bWwsIG9wdGlvbnNdO1xuXHRcblx0ICBlbC5wb3N0c2NyaWJlID0ge1xuXHQgICAgY2FuY2VsOiBmdW5jdGlvbiBjYW5jZWwoKSB7XG5cdCAgICAgIGlmIChhcmdzLnN0cmVhbSkge1xuXHQgICAgICAgIGFyZ3Muc3RyZWFtLmFib3J0KCk7XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgYXJnc1sxXSA9IGRvTm90aGluZztcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH07XG5cdFxuXHQgIG9wdGlvbnMuYmVmb3JlRW5xdWV1ZShhcmdzKTtcblx0ICBxdWV1ZS5wdXNoKGFyZ3MpO1xuXHRcblx0ICBpZiAoIWFjdGl2ZSkge1xuXHQgICAgbmV4dFN0cmVhbSgpO1xuXHQgIH1cblx0XG5cdCAgcmV0dXJuIGVsLnBvc3RzY3JpYmU7XG5cdH1cblx0XG5cdF9leHRlbmRzKHBvc3RzY3JpYmUsIHtcblx0ICAvLyBTdHJlYW1zIGJ5IG5hbWUuXG5cdCAgc3RyZWFtczoge30sXG5cdCAgLy8gUXVldWUgb2Ygc3RyZWFtcy5cblx0ICBxdWV1ZTogcXVldWUsIFdyaXRlU3RyZWFtOiBfd3JpdGVTdHJlYW0yWydkZWZhdWx0J11cblx0fSk7XG5cbi8qKiovIH0sXG4vKiAyICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cdFxuXHRleHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXHRcblx0dmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblx0XG5cdHZhciBfcHJlc2NyaWJlID0gX193ZWJwYWNrX3JlcXVpcmVfXygzKTtcblx0XG5cdHZhciBfcHJlc2NyaWJlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3ByZXNjcmliZSk7XG5cdFxuXHR2YXIgX3V0aWxzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0KTtcblx0XG5cdHZhciB1dGlscyA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKF91dGlscyk7XG5cdFxuXHRmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChvYmopIHsgaWYgKG9iaiAmJiBvYmouX19lc01vZHVsZSkgeyByZXR1cm4gb2JqOyB9IGVsc2UgeyB2YXIgbmV3T2JqID0ge307IGlmIChvYmogIT0gbnVsbCkgeyBmb3IgKHZhciBrZXkgaW4gb2JqKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSBuZXdPYmpba2V5XSA9IG9ialtrZXldOyB9IH0gbmV3T2JqWydkZWZhdWx0J10gPSBvYmo7IHJldHVybi
1BuZXdPYmo7IH0gfVxuXHRcblx0ZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXHRcblx0ZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblx0XG5cdC8qKlxuXHQgKiBUdXJuIG9uIHRvIGRlYnVnIGhvdyBlYWNoIGNodW5rIGFmZmVjdGVkIHRoZSBET00uXG5cdCAqIEB0eXBlIHtib29sZWFufVxuXHQgKi9cblx0dmFyIERFQlVHX0NIVU5LID0gZmFsc2U7XG5cdFxuXHQvKipcblx0ICogUHJlZml4IGZvciBkYXRhIGF0dHJpYnV0ZXMgb24gRE9NIGVsZW1lbnRzLlxuXHQgKiBAdHlwZSB7c3RyaW5nfVxuXHQgKi9cblx0dmFyIEJBU0VBVFRSID0gJ2RhdGEtcHMtJztcblx0XG5cdC8qKlxuXHQgKiBJRCBmb3IgdGhlIHN0eWxlIHByb3h5XG5cdCAqIEB0eXBlIHtzdHJpbmd9XG5cdCAqL1xuXHR2YXIgUFJPWFlfU1RZTEUgPSAncHMtc3R5bGUnO1xuXHRcblx0LyoqXG5cdCAqIElEIGZvciB0aGUgc2NyaXB0IHByb3h5XG5cdCAqIEB0eXBlIHtzdHJpbmd9XG5cdCAqL1xuXHR2YXIgUFJPWFlfU0NSSVBUID0gJ3BzLXNjcmlwdCc7XG5cdFxuXHQvKipcblx0ICogR2V0IGRhdGEgYXR0cmlidXRlc1xuXHQgKlxuXHQgKiBAcGFyYW0ge09iamVjdH0gZWwgVGhlIERPTSBlbGVtZW50LlxuXHQgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgYXR0cmlidXRlIG5hbWUuXG5cdCAqIEByZXR1cm5zIHtTdHJpbmd9XG5cdCAqL1xuXHRmdW5jdGlvbiBnZXREYXRhKGVsLCBuYW1lKSB7XG5cdCAgdmFyIGF0dHIgPSBCQVNFQVRUUiArIG5hbWU7XG5cdFxuXHQgIHZhciB2YWwgPSBlbC5nZXRBdHRyaWJ1dGUoYXR0cik7XG5cdFxuXHQgIC8vIElFIDggcmV0dXJucyBhIG51bWJlciBpZiBpdCdzIGEgbnVtYmVyXG5cdCAgcmV0dXJuICF1dGlscy5leGlzdHkodmFsKSA/IHZhbCA6IFN0cmluZyh2YWwpO1xuXHR9XG5cdFxuXHQvKipcblx0ICogU2V0IGRhdGEgYXR0cmlidXRlc1xuXHQgKlxuXHQgKiBAcGFyYW0ge09iamVjdH0gZWwgVGhlIERPTSBlbGVtZW50LlxuXHQgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgYXR0cmlidXRlIG5hbWUuXG5cdCAqIEBwYXJhbSB7bnVsbHwqfSB2YWx1ZSBUaGUgYXR0cmlidXRlIHZhbHVlLlxuXHQgKi9cblx0ZnVuY3Rpb24gc2V0RGF0YShlbCwgbmFtZSkge1xuXHQgIHZhciB2YWx1ZSA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMiB8fCBhcmd1bWVudHNbMl0gPT09IHVuZGVmaW5lZCA/IG51bGwgOiBhcmd1bWVudHNbMl07XG5cdFxuXHQgIHZhciBhdHRyID0gQkFTRUFUVFIgKyBuYW1lO1xuXHRcblx0ICBpZiAodXRpbHMuZXhpc3R5KHZhbHVlKSAmJiB2YWx1ZSAhPT0gJycpIHtcblx0ICAgIGVsLnNldEF0dHJpYnV0ZShhdHRyLCB2YWx1ZSk7XG5cdCAgfSBlbHNlIHtcblx0ICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShhdHRyKTtcblx0ICB9XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBTdHJlYW0gc3RhdGljIGh0bWwgdG8gYW4gZWxlbWVudCwgd2hlcmUgXCJzdGF0aWMgaHRtbFwiIGRlbm90ZXMgXCJodG1sXG5cdCAqIHdpdGhvdXQgc2NyaXB0c1wiLlxuXHQgKlxuXHQgKiBUaGlzIGNsYXNzIG1haW50YWlucyBhICpoaXN0b3J5IG9mIHdyaXRlcyBkZXZvaWQgb2YgYW55IGF0dHJpYnV0ZXMqIG9yXG5cdCAqIFwicHJveHkgaGlzdG9yeVwiLlxuXHQgKlxuXHQgKiBJbmplY3RpbmcgdGhlIHByb3h5IGhpc3RvcnkgaW50byBhIHRlbXBvcmFyeSBkaXYgaGFzIG5vIHNpZGUtZWZmZWN0cyxcblx0ICogb3RoZXIgdGhhbiB0byBjcmVhdGUgcHJveHkgZWxlbWVudHMgZm9yIHByZXZpb3VzbHkgd3JpdHRlbiBlbGVtZW50cy5cblx0ICpcblx0ICogR2l2ZW4gdGhlIGBzdGF0aWNIdG1sYCBvZiBhIG5ldyB3cml0ZSwgYSBgdGVtcERpdmAncyBpbm5lckhUTUwgaXMgc2V0IHRvXG5cdCAqIGBwcm94eV9oaXN0b3J5ICsgc3RhdGljSHRtbGAuXG5cdCAqIFRoZSAqc3RydWN0dXJlKiBvZiBgdGVtcERpdmAncyBjb250ZW50cywgKGkuZS4sIHRoZSBwbGFjZW1lbnQgb2YgbmV3IG5vZGVzXG5cdCAqIGJlc2lkZSBvciBpbnNpZGUgb2YgcHJveHkgZWxlbWVudHMpLCByZWZsZWN0cyB0aGUgRE9NIHN0cnVjdHVyZSB0aGF0IHdvdWxkXG5cdCAqIGhhdmUgcmVzdWx0ZWQgaWYgYWxsIHdyaXRlcyBoYWQgYmVlbiBzcXVhc2hlZCBpbnRvIGEgc2luZ2xlIHdyaXRlLlxuXHQgKlxuXHQgKiBGb3IgZWFjaCBkZXNjZW5kZW50IGBub2RlYCBvZiBgdGVtcERpdmAgd2hvc2UgcGFyZW50Tm9kZSBpcyBhICpwcm94eSosXG5cdCAqIGBub2RlYCBpcyBhcHBlbmRlZCB0byB0aGUgY29ycmVzcG9uZGluZyAqcmVhbCogZWxlbWVudCB3aXRoaW4gdGhlIERPTS5cblx0ICpcblx0ICogUHJveHkgZWxlbWVudHMgYXJlIG1hcHBlZCB0byAqYWN0dWFsKiBlbGVtZW50cyBpbiB0aGUgRE9NIGJ5IGluamVjdGluZyBhXG5cdCAqIGBkYXRhLWlkYCBhdHRyaWJ1dGUgaW50byBlYWNoIHN0YXJ0IHRhZyBpbiBgc3RhdGljSHRtbGAuXG5cdCAqXG5cdCAqL1xuXHRcblx0dmFyIFdyaXRlU3RyZWFtID0gZnVuY3Rpb24gKCkge1xuXHQgIC8qKlxuXHQgICAqIENvbnN0cnVjdG9yLlxuXHQgICAqXG5cdCAgICogQHBhcmFtIHtPYmplY3R9IHJvb3QgVGhlIHJvb3QgZWxlbWVudFxuXHQgICAqIEBwYXJhbSB7P09iamVjdH0gb3B0aW9ucyBUaGUgb3B0aW9uc1xuXHQgICAqL1xuXHRcblx0ICBmdW5jdGlvbiBXcml0ZVN0cmVhbShyb290KSB7XG5cdCAgICB2YXIgb3B0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMSB8fCBhcmd1bWVudHNbMV0gPT09IHVuZGVmaW5lZCA/IHt9IDogYXJndW1lbnRzWzFdO1xuXHRcblx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBXcml0ZVN0cmVhbSk7XG5cdFxuXHQgICAgdGhpcy5yb290ID0gcm9vdDtcblx0ICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG5cdCAgICB0aGlzLmRvYyA9IHJvb3Qub3duZXJEb2N1bWVudDtcblx0ICAgIHRoaXMud2luID0gdGhpcy5kb2MuZGVmYXVsdFZpZXcgfHwgdGhpcy5kb2MucGFyZW50V2luZG93O1xuXHQgICAgdGhpcy5wYXJzZXIgPSBuZXcgX3ByZXNjcmliZTJbJ2RlZmF1bHQnXSgnJywgeyBhdXRvRml4OiBvcHRpb25zLmF1dG9GaXggfSk7XG5cdFxuXHQgICAgLy8gQWN0dWFsIGVsZW1lbnRzIGJ5IGlkLlxuXHQgICAgdGhpcy5hY3R1YWxzID0gW3Jvb3RdO1xuXHRcblx0ICAgIC8vIEVtYm9kaWVzIHRoZSBcInN0cnVjdHVyZVwiIG9mIHdoYXQncyBiZWVuIHdyaXR0ZW4gc28gZmFyLFxuXHQgICAgLy8gZGV2b2lkIG9mIGF0dHJpYnV0ZXMuXG5cdCAgICB0aGlzLnByb3h5SGlzdG9yeSA9ICcnO1xuXHRcblx0ICAgIC8vIENyZWF0ZSBhIHByb3h5IG9mIHRoZSByb290IGVsZW1lbnQuXG5cdCAgICB0aGlzLnByb3h5Um9vdCA9IHRoaXMuZG9jLmNyZWF0ZUVsZW1lbnQocm9vdC5ub2RlTmFtZSk7XG5cdFxuXHQgICAgdGhpcy5zY3JpcHRTdGFjayA9IFtdO1xuXHQgICAgdGhpcy53cml0ZVF1ZXVlID0gW107XG5cdFxuXHQgICAgc2V0RGF0YSh0aGlzLnByb3h5Um9vdCwgJ3Byb3h5b2YnLCAwKTtcblx0ICB9XG5cdFxuXHQgIC8qKlxuXHQgICAqIFdyaXRlcyB0aGUgZ2l2ZW4gc3RyaW5ncy5cblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7Li4uU3RyaW5nfSBzdHIgVGhlIHN0cmluZ3MgdG8gd3JpdGVcblx0ICAgKi9cblx0XG5cdFxuXHQgIFdyaXRlU3RyZWFtLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIHdyaXRlKCkge1xuXHQgICAgdmFyIF93cml0ZVF1ZXVlO1xuXHRcblx0ICAgIChfd3JpdG
1VRdWV1ZSA9IHRoaXMud3JpdGVRdWV1ZSkucHVzaC5hcHBseShfd3JpdGVRdWV1ZSwgYXJndW1lbnRzKTtcblx0XG5cdCAgICAvLyBQcm9jZXNzIHdyaXRlc1xuXHQgICAgLy8gV2hlbiBuZXcgc2NyaXB0IGdldHMgcHVzaGVkIG9yIHBlbmRpbmcgdGhpcyB3aWxsIHN0b3Bcblx0ICAgIC8vIGJlY2F1c2UgbmV3IHdyaXRlUXVldWUgZ2V0cyBwdXNoZWRcblx0ICAgIHdoaWxlICghdGhpcy5kZWZlcnJlZFJlbW90ZSAmJiB0aGlzLndyaXRlUXVldWUubGVuZ3RoKSB7XG5cdCAgICAgIHZhciBhcmcgPSB0aGlzLndyaXRlUXVldWUuc2hpZnQoKTtcblx0XG5cdCAgICAgIGlmICh1dGlscy5pc0Z1bmN0aW9uKGFyZykpIHtcblx0ICAgICAgICB0aGlzLl9jYWxsRnVuY3Rpb24oYXJnKTtcblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICB0aGlzLl93cml0ZUltcGwoYXJnKTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH07XG5cdFxuXHQgIC8qKlxuXHQgICAqIENhbGxzIHRoZSBnaXZlbiBmdW5jdGlvbi5cblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBjYWxsXG5cdCAgICogQHByaXZhdGVcblx0ICAgKi9cblx0XG5cdFxuXHQgIFdyaXRlU3RyZWFtLnByb3RvdHlwZS5fY2FsbEZ1bmN0aW9uID0gZnVuY3Rpb24gX2NhbGxGdW5jdGlvbihmbikge1xuXHQgICAgdmFyIHRvayA9IHsgdHlwZTogJ2Z1bmN0aW9uJywgdmFsdWU6IGZuLm5hbWUgfHwgZm4udG9TdHJpbmcoKSB9O1xuXHQgICAgdGhpcy5fb25TY3JpcHRTdGFydCh0b2spO1xuXHQgICAgZm4uY2FsbCh0aGlzLndpbiwgdGhpcy5kb2MpO1xuXHQgICAgdGhpcy5fb25TY3JpcHREb25lKHRvayk7XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogVGhlIHdyaXRlIGltcGxlbWVudGF0aW9uXG5cdCAgICpcblx0ICAgKiBAcGFyYW0ge1N0cmluZ30gaHRtbCBUaGUgSFRNTCB0byB3cml0ZS5cblx0ICAgKiBAcHJpdmF0ZVxuXHQgICAqL1xuXHRcblx0XG5cdCAgV3JpdGVTdHJlYW0ucHJvdG90eXBlLl93cml0ZUltcGwgPSBmdW5jdGlvbiBfd3JpdGVJbXBsKGh0bWwpIHtcblx0ICAgIHRoaXMucGFyc2VyLmFwcGVuZChodG1sKTtcblx0XG5cdCAgICB2YXIgdG9rID0gdm9pZCAwO1xuXHQgICAgdmFyIHNjcmlwdCA9IHZvaWQgMDtcblx0ICAgIHZhciBzdHlsZSA9IHZvaWQgMDtcblx0ICAgIHZhciB0b2tlbnMgPSBbXTtcblx0XG5cdCAgICAvLyBzdG9wIGlmIHdlIHNlZSBhIHNjcmlwdCB0b2tlblxuXHQgICAgd2hpbGUgKCh0b2sgPSB0aGlzLnBhcnNlci5yZWFkVG9rZW4oKSkgJiYgIShzY3JpcHQgPSB1dGlscy5pc1NjcmlwdCh0b2spKSAmJiAhKHN0eWxlID0gdXRpbHMuaXNTdHlsZSh0b2spKSkge1xuXHQgICAgICB0b2sgPSB0aGlzLm9wdGlvbnMuYmVmb3JlV3JpdGVUb2tlbih0b2spO1xuXHRcblx0ICAgICAgaWYgKHRvaykge1xuXHQgICAgICAgIHRva2Vucy5wdXNoKHRvayk7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0XG5cdCAgICBpZiAodG9rZW5zLmxlbmd0aCA+IDApIHtcblx0ICAgICAgdGhpcy5fd3JpdGVTdGF0aWNUb2tlbnModG9rZW5zKTtcblx0ICAgIH1cblx0XG5cdCAgICBpZiAoc2NyaXB0KSB7XG5cdCAgICAgIHRoaXMuX2hhbmRsZVNjcmlwdFRva2VuKHRvayk7XG5cdCAgICB9XG5cdFxuXHQgICAgaWYgKHN0eWxlKSB7XG5cdCAgICAgIHRoaXMuX2hhbmRsZVN0eWxlVG9rZW4odG9rKTtcblx0ICAgIH1cblx0ICB9O1xuXHRcblx0ICAvKipcblx0ICAgKiBXcml0ZSBjb250aWd1b3VzIG5vbi1zY3JpcHQgdG9rZW5zIChhIGNodW5rKVxuXHQgICAqXG5cdCAgICogQHBhcmFtIHtBcnJheTxPYmplY3Q+fSB0b2tlbnMgVGhlIHRva2Vuc1xuXHQgICAqIEByZXR1cm5zIHt7dG9rZW5zLCByYXcsIGFjdHVhbCwgcHJveHl9fG51bGx9XG5cdCAgICogQHByaXZhdGVcblx0ICAgKi9cblx0XG5cdFxuXHQgIFdyaXRlU3RyZWFtLnByb3RvdHlwZS5fd3JpdGVTdGF0aWNUb2tlbnMgPSBmdW5jdGlvbiBfd3JpdGVTdGF0aWNUb2tlbnModG9rZW5zKSB7XG5cdCAgICB2YXIgY2h1bmsgPSB0aGlzLl9idWlsZENodW5rKHRva2Vucyk7XG5cdFxuXHQgICAgaWYgKCFjaHVuay5hY3R1YWwpIHtcblx0ICAgICAgLy8gZS5nLiwgbm8gdG9rZW5zLCBvciBhIG5vc2NyaXB0IHRoYXQgZ290IGlnbm9yZWRcblx0ICAgICAgcmV0dXJuIG51bGw7XG5cdCAgICB9XG5cdFxuXHQgICAgY2h1bmsuaHRtbCA9IHRoaXMucHJveHlIaXN0b3J5ICsgY2h1bmsuYWN0dWFsO1xuXHQgICAgdGhpcy5wcm94eUhpc3RvcnkgKz0gY2h1bmsucHJveHk7XG5cdCAgICB0aGlzLnByb3h5Um9vdC5pbm5lckhUTUwgPSBjaHVuay5odG1sO1xuXHRcblx0ICAgIGlmIChERUJVR19DSFVOSykge1xuXHQgICAgICBjaHVuay5wcm94eUlubmVySFRNTCA9IHRoaXMucHJveHlSb290LmlubmVySFRNTDtcblx0ICAgIH1cblx0XG5cdCAgICB0aGlzLl93YWxrQ2h1bmsoKTtcblx0XG5cdCAgICBpZiAoREVCVUdfQ0hVTkspIHtcblx0ICAgICAgY2h1bmsuYWN0dWFsSW5uZXJIVE1MID0gdGhpcy5yb290LmlubmVySFRNTDtcblx0ICAgIH1cblx0XG5cdCAgICByZXR1cm4gY2h1bms7XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogQnVpbGQgYSBjaHVuay5cblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0Pn0gdG9rZW5zIFRoZSB0b2tlbnMgdG8gdXNlLlxuXHQgICAqIEByZXR1cm5zIHt7dG9rZW5zOiAqLCByYXc6IHN0cmluZywgYWN0dWFsOiBzdHJpbmcsIHByb3h5OiBzdHJpbmd9fVxuXHQgICAqIEBwcml2YXRlXG5cdCAgICovXG5cdFxuXHRcblx0ICBXcml0ZVN0cmVhbS5wcm90b3R5cGUuX2J1aWxkQ2h1bmsgPSBmdW5jdGlvbiBfYnVpbGRDaHVuayh0b2tlbnMpIHtcblx0ICAgIHZhciBuZXh0SWQgPSB0aGlzLmFjdHVhbHMubGVuZ3RoO1xuXHRcblx0ICAgIC8vIFRoZSByYXcgaHRtbCBvZiB0aGlzIGNodW5rLlxuXHQgICAgdmFyIHJhdyA9IFtdO1xuXHRcblx0ICAgIC8vIFRoZSBodG1sIHRvIGNyZWF0ZSB0aGUgbm9kZXMgaW4gdGhlIHRva2VucyAod2l0aCBpZCdzIGluamVjdGVkKS5cblx0ICAgIHZhciBhY3R1YWwgPSBbXTtcblx0XG5cdCAgICAvLyBIdG1sIHRoYXQgY2FuIGxhdGVyIGJlIHVzZWQgdG8gcHJveHkgdGhlIG5vZGVzIGluIHRoZSB0b2tlbnMuXG5cdCAgICB2Y
1XIgcHJveHkgPSBbXTtcblx0XG5cdCAgICB2YXIgbGVuID0gdG9rZW5zLmxlbmd0aDtcblx0ICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcblx0ICAgICAgdmFyIHRvayA9IHRva2Vuc1tpXTtcblx0ICAgICAgdmFyIHRva2VuUmF3ID0gdG9rLnRvU3RyaW5nKCk7XG5cdFxuXHQgICAgICByYXcucHVzaCh0b2tlblJhdyk7XG5cdFxuXHQgICAgICBpZiAodG9rLmF0dHJzKSB7XG5cdCAgICAgICAgLy8gdG9rLmF0dHJzIDw9PT4gc3RhcnRUYWcgb3IgYXRvbWljVGFnIG9yIGN1cnNvclxuXHQgICAgICAgIC8vIElnbm9yZSBub3NjcmlwdCB0YWdzLiBUaGV5IGFyZSBhdG9taWMsIHNvIHdlIGRvbid0IGhhdmUgdG8gd29ycnkgYWJvdXQgY2hpbGRyZW4uXG5cdCAgICAgICAgaWYgKCEvXm5vc2NyaXB0JC9pLnRlc3QodG9rLnRhZ05hbWUpKSB7XG5cdCAgICAgICAgICB2YXIgaWQgPSBuZXh0SWQrKztcblx0XG5cdCAgICAgICAgICAvLyBBY3R1YWw6IGluamVjdCBpZCBhdHRyaWJ1dGU6IHJlcGxhY2UgJz4nIGF0IGVuZCBvZiBzdGFydCB0YWcgd2l0aCBpZCBhdHRyaWJ1dGUgKyAnPidcblx0ICAgICAgICAgIGFjdHVhbC5wdXNoKHRva2VuUmF3LnJlcGxhY2UoLyhcXC8/PikvLCAnICcgKyBCQVNFQVRUUiArICdpZD0nICsgaWQgKyAnICQxJykpO1xuXHRcblx0ICAgICAgICAgIC8vIERvbid0IHByb3h5IHNjcmlwdHM6IHRoZXkgaGF2ZSBubyBiZWFyaW5nIG9uIERPTSBzdHJ1Y3R1cmUuXG5cdCAgICAgICAgICBpZiAodG9rLmF0dHJzLmlkICE9PSBQUk9YWV9TQ1JJUFQgJiYgdG9rLmF0dHJzLmlkICE9PSBQUk9YWV9TVFlMRSkge1xuXHQgICAgICAgICAgICAvLyBQcm94eTogc3RyaXAgYWxsIGF0dHJpYnV0ZXMgYW5kIGluamVjdCBwcm94eW9mIGF0dHJpYnV0ZVxuXHQgICAgICAgICAgICBwcm94eS5wdXNoKFxuXHQgICAgICAgICAgICAvLyBpZ25vcmUgYXRvbWljIHRhZ3MgKGUuZy4sIHN0eWxlKTogdGhleSBoYXZlIG5vIFwic3RydWN0dXJhbFwiIGVmZmVjdFxuXHQgICAgICAgICAgICB0b2sudHlwZSA9PT0gJ2F0b21pY1RhZycgPyAnJyA6ICc8JyArIHRvay50YWdOYW1lICsgJyAnICsgQkFTRUFUVFIgKyAncHJveHlvZj0nICsgaWQgKyAodG9rLnVuYXJ5ID8gJyAvPicgOiAnPicpKTtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgLy8gVmlzaXQgYW55IG90aGVyIHR5cGUgb2YgdG9rZW5cblx0ICAgICAgICAvLyBBY3R1YWw6IGFwcGVuZC5cblx0ICAgICAgICBhY3R1YWwucHVzaCh0b2tlblJhdyk7XG5cdFxuXHQgICAgICAgIC8vIFByb3h5OiBhcHBlbmQgZW5kVGFncy4gSWdub3JlIGV2ZXJ5dGhpbmcgZWxzZS5cblx0ICAgICAgICBwcm94eS5wdXNoKHRvay50eXBlID09PSAnZW5kVGFnJyA/IHRva2VuUmF3IDogJycpO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdFxuXHQgICAgcmV0dXJuIHtcblx0ICAgICAgdG9rZW5zOiB0b2tlbnMsXG5cdCAgICAgIHJhdzogcmF3LmpvaW4oJycpLFxuXHQgICAgICBhY3R1YWw6IGFjdHVhbC5qb2luKCcnKSxcblx0ICAgICAgcHJveHk6IHByb3h5LmpvaW4oJycpXG5cdCAgICB9O1xuXHQgIH07XG5cdFxuXHQgIC8qKlxuXHQgICAqIFdhbGsgdGhlIGNodW5rcy5cblx0ICAgKlxuXHQgICAqIEBwcml2YXRlXG5cdCAgICovXG5cdFxuXHRcblx0ICBXcml0ZVN0cmVhbS5wcm90b3R5cGUuX3dhbGtDaHVuayA9IGZ1bmN0aW9uIF93YWxrQ2h1bmsoKSB7XG5cdCAgICB2YXIgbm9kZSA9IHZvaWQgMDtcblx0ICAgIHZhciBzdGFjayA9IFt0aGlzLnByb3h5Um9vdF07XG5cdFxuXHQgICAgLy8gdXNlIHNoaWZ0L3Vuc2hpZnQgc28gdGhhdCBjaGlsZHJlbiBhcmUgd2Fsa2VkIGluIGRvY3VtZW50IG9yZGVyXG5cdCAgICB3aGlsZSAodXRpbHMuZXhpc3R5KG5vZGUgPSBzdGFjay5zaGlmdCgpKSkge1xuXHQgICAgICB2YXIgaXNFbGVtZW50ID0gbm9kZS5ub2RlVHlwZSA9PT0gMTtcblx0ICAgICAgdmFyIGlzUHJveHkgPSBpc0VsZW1lbnQgJiYgZ2V0RGF0YShub2RlLCAncHJveHlvZicpO1xuXHRcblx0ICAgICAgLy8gSWdub3JlIHByb3hpZXNcblx0ICAgICAgaWYgKCFpc1Byb3h5KSB7XG5cdCAgICAgICAgaWYgKGlzRWxlbWVudCkge1xuXHQgICAgICAgICAgLy8gTmV3IGFjdHVhbCBlbGVtZW50OiByZWdpc3RlciBpdCBhbmQgcmVtb3ZlIHRoZSB0aGUgaWQgYXR0ci5cblx0ICAgICAgICAgIHRoaXMuYWN0dWFsc1tnZXREYXRhKG5vZGUsICdpZCcpXSA9IG5vZGU7XG5cdCAgICAgICAgICBzZXREYXRhKG5vZGUsICdpZCcpO1xuXHQgICAgICAgIH1cblx0XG5cdCAgICAgICAgLy8gSXMgbm9kZSdzIHBhcmVudCBhIHByb3h5P1xuXHQgICAgICAgIHZhciBwYXJlbnRJc1Byb3h5T2YgPSBub2RlLnBhcmVudE5vZGUgJiYgZ2V0RGF0YShub2RlLnBhcmVudE5vZGUsICdwcm94eW9mJyk7XG5cdCAgICAgICAgaWYgKHBhcmVudElzUHJveHlPZikge1xuXHQgICAgICAgICAgLy8gTW92ZSBub2RlIHVuZGVyIGFjdHVhbCBwYXJlbnQuXG5cdCAgICAgICAgICB0aGlzLmFjdHVhbHNbcGFyZW50SXNQcm94eU9mXS5hcHBlbmRDaGlsZChub2RlKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0XG5cdCAgICAgIC8vIHByZXBlbmQgY2hpbGROb2RlcyB0byBzdGFja1xuXHQgICAgICBzdGFjay51bnNoaWZ0LmFwcGx5KHN0YWNrLCB1dGlscy50b0FycmF5KG5vZGUuY2hpbGROb2RlcykpO1xuXHQgICAgfVxuXHQgIH07XG5cdFxuXHQgIC8qKlxuXHQgICAqIEhhbmRsZXMgU2NyaXB0IHRva2Vuc1xuXHQgICAqXG5cdCAgICogQHBhcmFtIHtPYmplY3R9IHRvayBUaGUgdG9rZW5cblx0ICAgKi9cblx0XG5cdFxuXHQgIFdyaXRlU3RyZWFtLnByb3RvdHlwZS5faGFuZGxlU2NyaXB0VG9rZW4gPSBmdW5jdGlvbiBfaGFuZGxlU2NyaXB0VG9rZW4odG9rKSB7XG5cdCAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXHRcblx0ICAgIHZhciByZW1haW5kZXIgPSB0aGlzLnBhcnNlci5jbGVhcigpO1xuXHRcblx0ICAgIGlmIChyZW1haW5kZXIpIHtcblx0ICAgICAgLy8gV3JpdGUgcmVtYWluZGVyIGltbWVkaWF0ZWx5IGJlaGluZCB0aGlzIHNjcmlwdC5cblx0ICAgICAgdGhpcy53cml0ZVF1ZXVlLnVuc2hpZnQocmVtYWluZGVyKTtcblx0ICAgIH1cblx0XG5cdCAgICB0b2suc3JjID0gdG9rLmF0dHJzLnNyYyB8fCB0b2suYXR0cnMuU1JDO1xuXHRcblx0ICAgIHRvayA9IHRoaXMub3B0aW9ucy5iZWZvcmVXcml0ZVRva2VuKHRvayk7XG5cdCAgICBpZiAoIXRvaykge1xuXHQgICAgICAvLyBVc2VyIGhhcyByZW1vdmVkIHRoaXMgdG9rZW5cblx0ICAgICAgcmV0dXJuO1xuXHQgICAgfVxuXHRcblx0ICAgIGlmICh0b2suc3JjICYmIHRoaXMuc2NyaXB0U3RhY2subGVuZ3RoKSB7XG5cdCAgICAgIC8vIERlZmVyIHRoaXMgc2NyaXB0IHVudGlsIHNjcmlwdFN0YWNrIGlzIGVtcHR5LlxuXHQgICAgICAvLyBBc3N1bXB0aW9uIDE6IFRoaXMgc2NyaXB0IHdpbGwgbm90IHN0YXJ0IGV4ZWN1dGluZyB1bnRpbFxuXHQgICAgICAvLyBzY3JpcHRTdGFjayBpcyBlbXB0eS5cblx0ICAgICAgdGhpcy5kZWZlcnJlZFJlbW90ZSA9IHRvaztcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgI
1HRoaXMuX29uU2NyaXB0U3RhcnQodG9rKTtcblx0ICAgIH1cblx0XG5cdCAgICAvLyBQdXQgdGhlIHNjcmlwdCBub2RlIGluIHRoZSBET00uXG5cdCAgICB0aGlzLl93cml0ZVNjcmlwdFRva2VuKHRvaywgZnVuY3Rpb24gKCkge1xuXHQgICAgICBfdGhpcy5fb25TY3JpcHREb25lKHRvayk7XG5cdCAgICB9KTtcblx0ICB9O1xuXHRcblx0ICAvKipcblx0ICAgKiBIYW5kbGVzIHN0eWxlIHRva2Vuc1xuXHQgICAqXG5cdCAgICogQHBhcmFtIHtPYmplY3R9IHRvayBUaGUgdG9rZW5cblx0ICAgKi9cblx0XG5cdFxuXHQgIFdyaXRlU3RyZWFtLnByb3RvdHlwZS5faGFuZGxlU3R5bGVUb2tlbiA9IGZ1bmN0aW9uIF9oYW5kbGVTdHlsZVRva2VuKHRvaykge1xuXHQgICAgdmFyIHJlbWFpbmRlciA9IHRoaXMucGFyc2VyLmNsZWFyKCk7XG5cdFxuXHQgICAgaWYgKHJlbWFpbmRlcikge1xuXHQgICAgICAvLyBXcml0ZSByZW1haW5kZXIgaW1tZWRpYXRlbHkgYmVoaW5kIHRoaXMgc3R5bGUuXG5cdCAgICAgIHRoaXMud3JpdGVRdWV1ZS51bnNoaWZ0KHJlbWFpbmRlcik7XG5cdCAgICB9XG5cdFxuXHQgICAgdG9rLnR5cGUgPSB0b2suYXR0cnMudHlwZSB8fCB0b2suYXR0cnMuVFlQRSB8fCAndGV4dC9jc3MnO1xuXHRcblx0ICAgIHRvayA9IHRoaXMub3B0aW9ucy5iZWZvcmVXcml0ZVRva2VuKHRvayk7XG5cdFxuXHQgICAgaWYgKHRvaykge1xuXHQgICAgICAvLyBQdXQgdGhlIHN0eWxlIG5vZGUgaW4gdGhlIERPTS5cblx0ICAgICAgdGhpcy5fd3JpdGVTdHlsZVRva2VuKHRvayk7XG5cdCAgICB9XG5cdFxuXHQgICAgaWYgKHJlbWFpbmRlcikge1xuXHQgICAgICB0aGlzLndyaXRlKCk7XG5cdCAgICB9XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogQnVpbGQgYSBzdHlsZSBhbmQgaW5zZXJ0IGl0IGludG8gdGhlIERPTS5cblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7T2JqZWN0fSB0b2sgVGhlIHRva2VuXG5cdCAgICovXG5cdFxuXHRcblx0ICBXcml0ZVN0cmVhbS5wcm90b3R5cGUuX3dyaXRlU3R5bGVUb2tlbiA9IGZ1bmN0aW9uIF93cml0ZVN0eWxlVG9rZW4odG9rKSB7XG5cdCAgICB2YXIgZWwgPSB0aGlzLl9idWlsZFN0eWxlKHRvayk7XG5cdFxuXHQgICAgdGhpcy5faW5zZXJ0Q3Vyc29yKGVsLCBQUk9YWV9TVFlMRSk7XG5cdFxuXHQgICAgLy8gU2V0IGNvbnRlbnRcblx0ICAgIGlmICh0b2suY29udGVudCkge1xuXHQgICAgICBpZiAoZWwuc3R5bGVTaGVldCAmJiAhZWwuc2hlZXQpIHtcblx0ICAgICAgICBlbC5zdHlsZVNoZWV0LmNzc1RleHQgPSB0b2suY29udGVudDtcblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICBlbC5hcHBlbmRDaGlsZCh0aGlzLmRvYy5jcmVhdGVUZXh0Tm9kZSh0b2suY29udGVudCkpO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogQnVpbGQgYSBzdHlsZSBlbGVtZW50IGZyb20gYW4gYXRvbWljIHN0eWxlIHRva2VuLlxuXHQgICAqXG5cdCAgICogQHBhcmFtIHtPYmplY3R9IHRvayBUaGUgdG9rZW5cblx0ICAgKiBAcmV0dXJucyB7RWxlbWVudH1cblx0ICAgKi9cblx0XG5cdFxuXHQgIFdyaXRlU3RyZWFtLnByb3RvdHlwZS5fYnVpbGRTdHlsZSA9IGZ1bmN0aW9uIF9idWlsZFN0eWxlKHRvaykge1xuXHQgICAgdmFyIGVsID0gdGhpcy5kb2MuY3JlYXRlRWxlbWVudCh0b2sudGFnTmFtZSk7XG5cdFxuXHQgICAgZWwuc2V0QXR0cmlidXRlKCd0eXBlJywgdG9rLnR5cGUpO1xuXHRcblx0ICAgIC8vIFNldCBhdHRyaWJ1dGVzXG5cdCAgICB1dGlscy5lYWNoS2V5KHRvay5hdHRycywgZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG5cdCAgICAgIGVsLnNldEF0dHJpYnV0ZShuYW1lLCB2YWx1ZSk7XG5cdCAgICB9KTtcblx0XG5cdCAgICByZXR1cm4gZWw7XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogQXBwZW5kIGEgc3BhbiB0byB0aGUgc3RyZWFtLiBUaGF0IHNwYW4gd2lsbCBhY3QgYXMgYSBjdXJzb3Jcblx0ICAgKiAoaS5lLiBpbnNlcnRpb24gcG9pbnQpIGZvciB0aGUgZWxlbWVudC5cblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7T2JqZWN0fSBlbCBUaGUgZWxlbWVudFxuXHQgICAqIEBwYXJhbSB7c3RyaW5nfSB3aGljaCBUaGUgdHlwZSBvZiBwcm94eSBlbGVtZW50XG5cdCAgICovXG5cdFxuXHRcblx0ICBXcml0ZVN0cmVhbS5wcm90b3R5cGUuX2luc2VydEN1cnNvciA9IGZ1bmN0aW9uIF9pbnNlcnRDdXJzb3IoZWwsIHdoaWNoKSB7XG5cdCAgICB0aGlzLl93cml0ZUltcGwoJzxzcGFuIGlkPVwiJyArIHdoaWNoICsgJ1wiLz4nKTtcblx0XG5cdCAgICB2YXIgY3Vyc29yID0gdGhpcy5kb2MuZ2V0RWxlbWVudEJ5SWQod2hpY2gpO1xuXHRcblx0ICAgIGlmIChjdXJzb3IpIHtcblx0ICAgICAgY3Vyc29yLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGVsLCBjdXJzb3IpO1xuXHQgICAgfVxuXHQgIH07XG5cdFxuXHQgIC8qKlxuXHQgICAqIENhbGxlZCB3aGVuIGEgc2NyaXB0IGlzIHN0YXJ0ZWQuXG5cdCAgICpcblx0ICAgKiBAcGFyYW0ge09iamVjdH0gdG9rIFRoZSB0b2tlblxuXHQgICAqIEBwcml2YXRlXG5cdCAgICovXG5cdFxuXHRcblx0ICBXcml0ZVN0cmVhbS5wcm90b3R5cGUuX29uU2NyaXB0U3RhcnQgPSBmdW5jdGlvbiBfb25TY3JpcHRTdGFydCh0b2spIHtcblx0ICAgIHRvay5vdXRlcldyaXRlcyA9IHRoaXMud3JpdGVRdWV1ZTtcblx0ICAgIHRoaXMud3JpdGVRdWV1ZSA9IFtdO1xuXHQgICAgdGhpcy5zY3JpcHRTdGFjay51bnNoaWZ0KHRvayk7XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogQ2FsbGVkIHdoZW4gYSBzY3JpcHQgaXMgZG9uZS5cblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7T2JqZWN0fSB0b2sgVGhlIHRva2VuXG5cdCAgICogQHByaXZhdGVcblx0ICAgKi9cblx0XG5cdFxuXHQgIFdyaXRlU3RyZWFtLnByb3RvdHlwZS5fb25TY3JpcHREb25lID0gZnVuY3Rpb24gX29uU2NyaXB0RG9uZSh0b2spIHtcblx0ICAgIC8vIFBvcCBzY3JpcHQgYW5kIGNoZWNrIG5lc3RpbmcuXG5cdCAgICBpZiAodG9rICE9PSB0aGlzLnNjcmlwdFN0YWNrWzBdKSB7XG5cdCAgICAgIHRoaXMub3B0aW9ucy5lcnJvcih7IG1lc3NhZ2U6ICdCYWQgc2NyaXB0IG5lc3Rpbmcgb3Igc2NyaXB0IGZpbmlzaGVkIHR3aWNlJyB9KTtcblx0ICAgICAgcmV0dXJuO1xuXHQgICAgfVxuXHRcblx0ICAgIHRoaXMuc2NyaXB0U3RhY2suc2hpZnQoKTtcblx0XG5cdCAgICAvLyBBcHBlbmQgb3V0ZXIgd3JpdG
1VzIHRvIHF1ZXVlIGFuZCBwcm9jZXNzIHRoZW0uXG5cdCAgICB0aGlzLndyaXRlLmFwcGx5KHRoaXMsIHRvay5vdXRlcldyaXRlcyk7XG5cdFxuXHQgICAgLy8gQ2hlY2sgZm9yIHBlbmRpbmcgcmVtb3RlXG5cdFxuXHQgICAgLy8gQXNzdW1wdGlvbiAyOiBpZiByZW1vdGVfc2NyaXB0MSB3cml0ZXMgcmVtb3RlX3NjcmlwdDIgdGhlblxuXHQgICAgLy8gdGhlIHdlIG5vdGljZSByZW1vdGVfc2NyaXB0MSBmaW5pc2hlcyBiZWZvcmUgcmVtb3RlX3NjcmlwdDIgc3RhcnRzLlxuXHQgICAgLy8gSSB0aGluayB0aGlzIGlzIGVxdWl2YWxlbnQgdG8gYXNzdW1wdGlvbiAxXG5cdCAgICBpZiAoIXRoaXMuc2NyaXB0U3RhY2subGVuZ3RoICYmIHRoaXMuZGVmZXJyZWRSZW1vdGUpIHtcblx0ICAgICAgdGhpcy5fb25TY3JpcHRTdGFydCh0aGlzLmRlZmVycmVkUmVtb3RlKTtcblx0ICAgICAgdGhpcy5kZWZlcnJlZFJlbW90ZSA9IG51bGw7XG5cdCAgICB9XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogQnVpbGQgYSBzY3JpcHQgYW5kIGluc2VydCBpdCBpbnRvIHRoZSBET00uXG5cdCAgICogRG9uZSBpcyBjYWxsZWQgb25jZSBzY3JpcHQgaGFzIGV4ZWN1dGVkLlxuXHQgICAqXG5cdCAgICogQHBhcmFtIHtPYmplY3R9IHRvayBUaGUgdG9rZW5cblx0ICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lIFRoZSBjYWxsYmFjayB3aGVuIGNvbXBsZXRlXG5cdCAgICovXG5cdFxuXHRcblx0ICBXcml0ZVN0cmVhbS5wcm90b3R5cGUuX3dyaXRlU2NyaXB0VG9rZW4gPSBmdW5jdGlvbiBfd3JpdGVTY3JpcHRUb2tlbih0b2ssIGRvbmUpIHtcblx0ICAgIHZhciBlbCA9IHRoaXMuX2J1aWxkU2NyaXB0KHRvayk7XG5cdCAgICB2YXIgYXN5bmNSZWxlYXNlID0gdGhpcy5fc2hvdWxkUmVsZWFzZShlbCk7XG5cdCAgICB2YXIgYWZ0ZXJBc3luYyA9IHRoaXMub3B0aW9ucy5hZnRlckFzeW5jO1xuXHRcblx0ICAgIGlmICh0b2suc3JjKSB7XG5cdCAgICAgIC8vIEZpeCBmb3IgYXR0cmlidXRlIFwiU1JDXCIgKGNhcGl0YWxpemVkKS4gSUUgZG9lcyBub3QgcmVjb2duaXplIGl0LlxuXHQgICAgICBlbC5zcmMgPSB0b2suc3JjO1xuXHQgICAgICB0aGlzLl9zY3JpcHRMb2FkSGFuZGxlcihlbCwgIWFzeW5jUmVsZWFzZSA/IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBkb25lKCk7XG5cdCAgICAgICAgYWZ0ZXJBc3luYygpO1xuXHQgICAgICB9IDogYWZ0ZXJBc3luYyk7XG5cdCAgICB9XG5cdFxuXHQgICAgdHJ5IHtcblx0ICAgICAgdGhpcy5faW5zZXJ0Q3Vyc29yKGVsLCBQUk9YWV9TQ1JJUFQpO1xuXHQgICAgICBpZiAoIWVsLnNyYyB8fCBhc3luY1JlbGVhc2UpIHtcblx0ICAgICAgICBkb25lKCk7XG5cdCAgICAgIH1cblx0ICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgdGhpcy5vcHRpb25zLmVycm9yKGUpO1xuXHQgICAgICBkb25lKCk7XG5cdCAgICB9XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogQnVpbGQgYSBzY3JpcHQgZWxlbWVudCBmcm9tIGFuIGF0b21pYyBzY3JpcHQgdG9rZW4uXG5cdCAgICpcblx0ICAgKiBAcGFyYW0ge09iamVjdH0gdG9rIFRoZSB0b2tlblxuXHQgICAqIEByZXR1cm5zIHtFbGVtZW50fVxuXHQgICAqL1xuXHRcblx0XG5cdCAgV3JpdGVTdHJlYW0ucHJvdG90eXBlLl9idWlsZFNjcmlwdCA9IGZ1bmN0aW9uIF9idWlsZFNjcmlwdCh0b2spIHtcblx0ICAgIHZhciBlbCA9IHRoaXMuZG9jLmNyZWF0ZUVsZW1lbnQodG9rLnRhZ05hbWUpO1xuXHRcblx0ICAgIC8vIFNldCBhdHRyaWJ1dGVzXG5cdCAgICB1dGlscy5lYWNoS2V5KHRvay5hdHRycywgZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG5cdCAgICAgIGVsLnNldEF0dHJpYnV0ZShuYW1lLCB2YWx1ZSk7XG5cdCAgICB9KTtcblx0XG5cdCAgICAvLyBTZXQgY29udGVudFxuXHQgICAgaWYgKHRvay5jb250ZW50KSB7XG5cdCAgICAgIGVsLnRleHQgPSB0b2suY29udGVudDtcblx0ICAgIH1cblx0XG5cdCAgICByZXR1cm4gZWw7XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogU2V0dXAgdGhlIHNjcmlwdCBsb2FkIGhhbmRsZXIgb24gYW4gZWxlbWVudC5cblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7T2JqZWN0fSBlbCBUaGUgZWxlbWVudFxuXHQgICAqIEBwYXJhbSB7RnVuY3Rpb259IGRvbmUgVGhlIGNhbGxiYWNrXG5cdCAgICogQHByaXZhdGVcblx0ICAgKi9cblx0XG5cdFxuXHQgIFdyaXRlU3RyZWFtLnByb3RvdHlwZS5fc2NyaXB0TG9hZEhhbmRsZXIgPSBmdW5jdGlvbiBfc2NyaXB0TG9hZEhhbmRsZXIoZWwsIGRvbmUpIHtcblx0ICAgIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG5cdCAgICAgIGVsID0gZWwub25sb2FkID0gZWwub25yZWFkeXN0YXRlY2hhbmdlID0gZWwub25lcnJvciA9IG51bGw7XG5cdCAgICB9XG5cdFxuXHQgICAgdmFyIGVycm9yID0gdGhpcy5vcHRpb25zLmVycm9yO1xuXHRcblx0ICAgIGZ1bmN0aW9uIHN1Y2Nlc3MoKSB7XG5cdCAgICAgIGNsZWFudXAoKTtcblx0ICAgICAgZG9uZSgpO1xuXHQgICAgfVxuXHRcblx0ICAgIGZ1bmN0aW9uIGZ
1haWx1cmUoZXJyKSB7XG5cdCAgICAgIGNsZWFudXAoKTtcblx0ICAgICAgZXJyb3IoZXJyKTtcblx0ICAgICAgZG9uZSgpO1xuXHQgICAgfVxuXHRcblx0ICAgIC8vIFNldCBoYW5kbGVyc1xuXHQgICAgX2V4dGVuZHMoZWwsIHtcblx0ICAgICAgb25sb2FkOiBmdW5jdGlvbiBvbmxvYWQoKSB7XG5cdCAgICAgICAgcmV0dXJuIHN1Y2Nlc3MoKTtcblx0ICAgICAgfSxcblx0XG5cdCAgICAgIG9ucmVhZHlzdGF0ZWNoYW5nZTogZnVuY3Rpb24gb25yZWFkeXN0YXRlY2hhbmdlKCkge1xuXHQgICAgICAgIGlmICgvXihsb2FkZWR8Y29tcGxldGUpJC8udGVzdChlbC5yZWFkeVN0YXRlKSkge1xuXHQgICAgICAgICAgc3VjY2VzcygpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfSxcblx0XG5cdCAgICAgIG9uZXJyb3I6IGZ1bmN0aW9uIG9uZXJyb3IoKSB7XG5cdCAgICAgICAgcmV0dXJuIGZhaWx1cmUoeyBtZXNzYWdlOiAncmVtb3RlIHNjcmlwdCBmYWlsZWQgJyArIGVsLnNyYyB9KTtcblx0ICAgICAgfVxuXHQgICAgfSk7XG5cdCAgfTtcblx0XG5cdCAgLyoqXG5cdCAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRvIHJlbGVhc2UuXG5cdCAgICpcblx0ICAgKiBAcGFyYW0ge09iamVjdH0gZWwgVGhlIGVsZW1lbnRcblx0ICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cblx0ICAgKiBAcHJpdmF0ZVxuXHQgICAqL1xuXHRcblx0XG5cdCAgV3JpdGVTdHJlYW0ucHJvdG90eXBlLl9zaG91bGRSZWxlYXNlID0gZnVuY3Rpb24gX3Nob3VsZFJlbGVhc2UoZWwpIHtcblx0ICAgIHZhciBpc1NjcmlwdCA9IC9ec2NyaXB0JC9pLnRlc3QoZWwubm9kZU5hbWUpO1xuXHQgICAgcmV0dXJuICFpc1NjcmlwdCB8fCAhISh0aGlzLm9wdGlvbnMucmVsZWFzZUFzeW5jICYmIGVsLnNyYyAmJiBlbC5oYXNBdHRyaWJ1dGUoJ2FzeW5jJykpO1xuXHQgIH07XG5cdFxuXHQgIHJldHVybiBXcml0ZVN0cmVhbTtcblx0fSgpO1xuXHRcblx0ZXhwb3J0c1snZGVmYXVsdCddID0gV3JpdGVTdHJlYW07XG5cbi8qKiovIH0sXG4vKiAzICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQvKipcblx0ICogQGZpbGUgcHJl
1c2NyaWJlXG5cdCAqIEBkZXNjcmlwdGlvbiBUaW55LCBmb3JnaXZpbmcgSFRNTCBwYXJzZXJcblx0ICogQHZlcnNpb24gdjEuMS4xXG5cdCAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9rcnV4L3ByZXNjcmliZS99XG5cdCAqIEBsaWNlbnNlIE1JVFxuXHQgKiBAYXV0aG9yIERlcmVrIEJyYW5zXG5cdCAqIEBjb3B5cmlnaHQgMjAxNiBLcnV4IERpZ2l0YWwsIEluY1xuXHQgKi9cblx0KGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0XHRpZih0cnVlKVxuXHRcdFx0bW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCk7XG5cdFx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0XHRkZWZpbmUoW10sIGZhY3RvcnkpO1xuXHRcdGVsc2UgaWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnKVxuXHRcdFx0ZXhwb3J0c1tcIlByZXNjcmliZVwiXSA9IGZhY3RvcnkoKTtcblx0XHRlbHNlXG5cdFx0XHRyb290W1wiUHJlc2NyaWJlXCJdID0gZmFjdG9yeSgpO1xuXHR9KSh0aGlzLCBmdW5jdGlvbigpIHtcblx0cmV0dXJuIC8qKioqKiovIChmdW5jdGlvbihtb2R1bGVzKSB7IC8vIHdlYnBhY2tCb290c3RyYXBcblx0LyoqKioqKi8gXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG5cdC8qKioqKiovIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblx0XG5cdC8qKioqKiovIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cblx0LyoqKioqKi8gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cdFxuXHQvKioqKioqLyBcdFx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG5cdC8qKioqKiovIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSlcblx0LyoqKioqKi8gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG5cdFxuXHQvKioqKioqLyBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcblx0LyoqKioqKi8gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcblx0LyoqKioqKi8gXHRcdFx0ZXhwb3J0czoge30sXG5cdC8qKioqKiovIFx0XHRcdGlkOiBtb2R1bGVJZCxcblx0LyoqKioqKi8gXHRcdFx0bG9hZGVkOiBmYWxzZVxuXHQvKioqKioqLyBcdFx0fTtcblx0XG5cdC8qKioqKiovIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cblx0LyoqKioqKi8gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXHRcblx0LyoqKioqKi8gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcblx0LyoqKioqKi8gXHRcdG1vZHVsZS5sb2FkZWQgPSB0cnVlO1xuXHRcblx0LyoqKioqKi8gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG5cdC8qKioqKiovIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG5cdC8qKioqKiovIFx0fVxuXHRcblx0XG5cdC8qKioqKiovIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcblx0LyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXHRcblx0LyoqKioqKi8gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuXHQvKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG5cdFxuXHQvKioqKioqLyBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG5cdC8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblx0XG5cdC8qKioqKiovIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG5cdC8qKioqKiovIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oMCk7XG5cdC8qKioqKiovIH0pXG5cdC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cdC8qKioqKiovIChbXG5cdC8qIDAgKi9cblx0LyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cdFxuXHRcdCd1c2Ugc3RyaWN0Jztcblx0XG5cdFx0dmFyIF9IdG1sUGFyc2VyID0gX193ZWJwYWNrX3JlcXVpcmVfXygxKTtcblx0XG5cdFx0dmFyIF9IdG1sUGFyc2VyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0h0bWxQYXJzZXIpO1xuXHRcblx0XHRmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cdFxuXHRcdG1vZHVsZS5leHBvcnRzID0gX0h0bWxQYXJzZXIyWydkZWZhdWx0J107XG5cdFxuXHQvKioqLyB9LFxuXHQvKiAxICovXG5cdC8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXHRcblx0XHQndXNlIHN0cmljdCc7XG5cdFxuXHRcdGV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cdFxuXHRcdHZhciBfc3VwcG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDIpO1xuXHRcblx0XHR2YXIgc3VwcG9ydHMgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfc3VwcG9ydHMpO1xuXHRcblx0XHR2YXIgX3N0cmVhbVJlYWRlcnMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDMpO1xuXHRcblx0XHR2YXIgc3RyZWFtUmVhZGVycyA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKF9zdHJlYW1SZWFkZXJzKTtcblx0XG5cdFx0dmFyIF9maXhlZFJlYWRUb2tlbkZhY3RvcnkgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDYpO1xuXHRcblx0XHR2YXIgX2ZpeGVkUmVhZFRva2VuRmFjdG9yeTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9maXhlZFJlYWRUb2tlbkZhY3RvcnkpO1xuXHRcblx0XHR2YXIgX3V0aWxzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg1KTtcblx0XG5cdFx0ZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXHRcblx0XHRmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChvYmopIHsgaWYgKG9iaiAmJiBvYmouX19lc01vZHVsZSkgeyByZXR1cm4gb2JqOyB9IGVsc2UgeyB2YXIgbmV3T2JqID0ge307IGlmIChvYmogIT0gbnVsbCkgeyBmb3IgKHZhciBrZXkgaW4gb2JqKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSBuZXdPYmpba2V5XSA9IG9ialtrZXldOyB9IH0gbmV3T2JqWydkZWZhdWx0J10gPSBvYmo7IHJldHVybi
1BuZXdPYmo7IH0gfVxuXHRcblx0XHRmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXHRcblx0XHQvKipcblx0XHQgKiBEZXRlY3Rpb24gcmVndWxhciBleHByZXNzaW9ucy5cblx0XHQgKlxuXHRcdCAqIE9yZGVyIG9mIGRldGVjdGlvbiBtYXR0ZXJzOiBkZXRlY3Rpb24gb2Ygb25lIGNhbiBvbmx5XG5cdFx0ICogc3VjY2VlZCBpZiBkZXRlY3Rpb24gb2YgcHJldmlvdXMgZGlkbid0XG5cdFxuXHRcdCAqIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdFx0dmFyIGRldGVjdCA9IHtcblx0XHQgIGNvbW1lbnQ6IC9ePCEtLS8sXG5cdFx0ICBlbmRUYWc6IC9ePFxcLy8sXG5cdFx0ICBhdG9taWNUYWc6IC9ePFxccyooc2NyaXB0fHN0eWxlfG5vc2NyaXB0fGlmcmFtZXx0ZXh0YXJlYSlbXFxzXFwvPl0vaSxcblx0XHQgIHN0YXJ0VGFnOiAvXjwvLFxuXHRcdCAgY2hhcnM6IC9eW148XS9cblx0XHR9O1xuXHRcblx0XHQvKipcblx0XHQgKiBIdG1sUGFyc2VyIHByb3ZpZGVzIHRoZSBjYXBhYmlsaXR5IHRvIHBhcnNlIEhUTUwgYW5kIHJldHVybiB0b2tlbnNcblx0XHQgKiByZXByZXNlbnRpbmcgdGhlIHRhZ3MgYW5kIGNvbnRlbnQuXG5cdFx0ICovXG5cdFxuXHRcdHZhciBIdG1sUGFyc2VyID0gZnVuY3Rpb24gKCkge1xuXHRcdCAgLyoqXG5cdFx0ICAgKiBDb25zdHJ1Y3Rvci5cblx0XHQgICAqXG5cdFx0ICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyZWFtIFRoZSBpbml0aWFsIHBhcnNlIHN0cmVhbSBjb250ZW50cy5cblx0XHQgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIFRoZSBvcHRpb25zXG5cdFx0ICAgKiBAcGFyYW0ge2Jvb2xlYW59IG9wdGlvbnMuYXV0b0ZpeCBTZXQgdG8gdHJ1ZSB0byBhdXRvbWF0aWNhbGx5IGZpeCBlcnJvcnNcblx0XHQgICAqL1xuXHRcblx0XHQgIGZ1bmN0aW9uIEh0bWxQYXJzZXIoKSB7XG5cdFx0ICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cdFxuXHRcdCAgICB2YXIgc3RyZWFtID0gYXJndW1lbnRzLmxlbmd0aCA8PSAwIHx8IGFyZ3VtZW50c1swXSA9PT0gdW5kZWZpbmVkID8gJycgOiBhcmd1bWVudHNbMF07XG5cdFx0ICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA8PSAxIHx8IGFyZ3VtZW50c1sxXSA9PT0gdW5kZWZpbmVkID8ge30gOiBhcmd1bWVudHNbMV07XG5cdFxuXHRcdCAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgSHRtbFBhcnNlcik7XG5cdFxuXHRcdCAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcblx0XG5cdFx0ICAgIHZhciBmaXggPSBmYWxzZTtcblx0XHQgICAgdmFyIGZpeGVkVG9rZW5PcHRpb25zID0ge307XG5cdFxuXHRcdCAgICBmb3IgKHZhciBrZXkgaW4gc3VwcG9ydHMpIHtcblx0XHQgICAgICBpZiAoc3VwcG9ydHMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuXHRcdCAgICAgICAgaWYgKG9wdGlvbnMuYXV0b0ZpeCkge1xuXHRcdCAgICAgICAgICBmaXhlZFRva2VuT3B0aW9uc1trZXkgKyAnRml4J10gPSB0cnVlOyAvLyAhc3VwcG9ydHNba2V5XTtcblx0XHQgICAgICAgIH1cblx0XHQgICAgICAgIGZpeCA9IGZpeCB8fCBmaXhlZFRva2VuT3B0aW9uc1trZXkgKyAnRml4J107XG5cdFx0ICAgICAgfVxuXHRcdCAgICB9XG5cdFxuXHRcdCAgICBpZiAoZml4KSB7XG5cdFx0ICAgICAgdGhpcy5fcmVhZFRva2VuID0gKDAsIF9maXhlZFJlYWRUb2tlbkZhY3RvcnkyWydkZWZhdWx0J10pKHRoaXMsIGZpeGVkVG9rZW5PcHRpb25zLCBmdW5jdGlvbiAoKSB7XG5cdFx0ICAgICAgICByZXR1cm4gX3RoaXMuX3JlYWRUb2tlbkltcGwoKTtcblx0XHQgICAgICB9KTtcblx0XHQgICAgICB0aGlzLl9wZWVrVG9rZW4gPSAoMCwgX2ZpeGVkUmVhZFRva2VuRmFjdG9yeTJbJ2RlZmF1bHQnXSkodGhpcywgZml4ZWRUb2tlbk9wdGlvbnMsIGZ1bmN0aW9uICgpIHtcblx0XHQgICAgICAgIHJldHVybiBfdGhpcy5fcGVla1Rva2VuSW1wbCgpO1xuXHRcdCAgICAgIH0pO1xuXHRcdCAgICB9IGVsc2Uge1xuXHRcdCAgICAgIHRoaXMuX3JlYWRUb2tlbiA9IHRoaXMuX3JlYWRUb2tlbkltcGw7XG5cdFx0ICAgICAgdGhpcy5fcGVla1Rva2VuID0gdGhpcy5fcGVla1Rva2VuSW1wbDtcblx0XHQgICAgfVxuXHRcdCAgfVxuXHRcblx0XHQgIC8qKlxuXHRcdCAgICogQXBwZW5kcyB0aGUgZ2l2ZW4gc3RyaW5nIHRvIHRoZSBwYXJzZSBzdHJlYW0uXG5cdFx0ICAgKlxuXHRcdCAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBUaGUgc3RyaW5nIHRvIGFwcGVuZFxuXHRcdCAgICovXG5cdFxuXHRcblx0XHQgIEh0bWxQYXJzZXIucHJvdG90eXBlLmFwcGVuZCA9IGZ1bmN0aW9uIGFwcGVuZChzdHIpIHtcblx0XHQgICAgdGhpcy5zdHJlYW0gKz0gc3RyO1xuXHRcdCAgfTtcblx0XG5cdFx0ICAvKipcblx0XHQgICAqIFByZXBlbmRzIHRoZSBnaXZlbiBzdHJpbmcgdG8gdGhlIHBhcnNlIHN0cmVhbS5cblx0XHQgICAqXG5cdFx0ICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFRoZSBzdHJpbmcgdG8gcHJlcGVuZFxuXHRcdCAgICovXG5cdFxuXHRcblx0XHQgIEh0bWxQYXJzZXIucHJvdG90eXBlLnByZXBlbmQgPSBmdW5jdGlvbiBwcmVwZW5kKHN0cikge1xuXHRcdCAgICB0aGlzLnN0cmVhbSA9IHN0ciArIHRoaXMuc3RyZWFtO1xuXHRcdCAgfTtcblx0XG5cdFx0ICAvKipcblx0XHQgICAqIFRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgdG9rZW4gcmVhZGluZy5cblx0XHQgICAqXG5cdFx0ICAgKiBAcHJpdmF0ZVxuXHRcdCAgICogQHJldHVybnMgez9Ub2tlbn1cblx0XHQgICAqL1xuXHRcblx0XG5cdFx0ICBIdG1sUGFyc2VyLnByb3RvdHlwZS5fcmVhZFRva2VuSW1wbCA9IGZ1bmN0aW9uIF9yZWFkVG9rZW5JbXBsKCkge1xuXHRcdCAgICB2YXIgdG9rZW4gPSB0aGlzLl9wZWVrVG9rZW5JbXBsKCk7XG5cdFx0ICAgIGlmICh0b2tlbikge1xuXHRcdCAgICAgIHRoaXMuc3RyZWFtID0gdGhpcy5zdHJlYW0uc2xpY2UodG9rZW4ubGVuZ3RoKTtcblx0XHQgICAgICByZXR1cm4gdG9rZW47XG5cdFx0ICAgIH1cblx0XHQgIH07XG5cdFxuXHRcdCAgLyoqXG5cdFx0ICAgKiBUaGUgaW1wbGVtZW50YXRpb24gb2YgdG9rZW4gcG
1Vla2luZy5cblx0XHQgICAqXG5cdFx0ICAgKiBAcmV0dXJucyB7P1Rva2VufVxuXHRcdCAgICovXG5cdFxuXHRcblx0XHQgIEh0bWxQYXJzZXIucHJvdG90eXBlLl9wZWVrVG9rZW5JbXBsID0gZnVuY3Rpb24gX3BlZWtUb2tlbkltcGwoKSB7XG5cdFx0ICAgIGZvciAodmFyIHR5cGUgaW4gZGV0ZWN0KSB7XG5cdFx0ICAgICAgaWYgKGRldGVjdC5oYXNPd25Qcm9wZXJ0eSh0eXBlKSkge1xuXHRcdCAgICAgICAgaWYgKGRldGVjdFt0eXBlXS50ZXN0KHRoaXMuc3RyZWFtKSkge1xuXHRcdCAgICAgICAgICB2YXIgdG9rZW4gPSBzdHJlYW1SZWFkZXJzW3R5cGVdKHRoaXMuc3RyZWFtKTtcblx0XG5cdFx0ICAgICAgICAgIGlmICh0b2tlbikge1xuXHRcdCAgICAgICAgICAgIGlmICh0b2tlbi50eXBlID09PSAnc3RhcnRUYWcnICYmIC9zY3JpcHR8c3R5bGUvaS50ZXN0KHRva2VuLnRhZ05hbWUpKSB7XG5cdFx0ICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcblx0XHQgICAgICAgICAgICB9IGVsc2Uge1xuXHRcdCAgICAgICAgICAgICAgdG9rZW4udGV4dCA9IHRoaXMuc3RyZWFtLnN1YnN0cigwLCB0b2tlbi5sZW5ndGgpO1xuXHRcdCAgICAgICAgICAgICAgcmV0dXJuIHRva2VuO1xuXHRcdCAgICAgICAgICAgIH1cblx0XHQgICAgICAgICAgfVxuXHRcdCAgICAgICAgfVxuXHRcdCAgICAgIH1cblx0XHQgICAgfVxuXHRcdCAgfTtcblx0XG5cdFx0ICAvKipcblx0XHQgICAqIFRoZSBwdWJsaWMgdG9rZW4gcGVla2luZyBpbnRlcmZhY2UuICBEZWxlZ2F0ZXMgdG8gdGhlIGJhc2ljIHRva2VuIHBlZWtpbmdcblx0XHQgICAqIG9yIGEgdmVyc2lvbiB0aGF0IHBlcmZvcm1zIGZpeHVwcyBkZXBlbmRpbmcgb24gdGhlIGBhdXRvRml4YCBzZXR0aW5nIGluXG5cdFx0ICAgKiBvcHRpb25zLlxuXHRcdCAgICpcblx0XHQgICAqIEByZXR1cm5zIHtvYmplY3R9XG5cdFx0ICAgKi9cblx0XG5cdFxuXHRcdCAgSHRtbFBhcnNlci5wcm90b3R5cGUucGVla1Rva2VuID0gZnVuY3Rpb24gcGVla1Rva2VuKCkge1xuXHRcdCAgICByZXR1cm4gdGhpcy5fcGVla1Rva2VuKCk7XG5cdFx0ICB9O1xuXHRcblx0XHQgIC8qKlxuXHRcdCAgICogVGhlIHB1YmxpYyB0b2tlbiByZWFkaW5nIGludGVyZmFjZS4gIERlbGVnYXRlcyB0byB0aGUgYmFzaWMgdG9rZW4gcmVhZGluZ1xuXHRcdCAgICogb3IgYSB2ZXJzaW9uIHRoYXQgcGVyZm9ybXMgZml4dXBzIGRlcGVuZGluZyBvbiB0aGUgYGF1dG9GaXhgIHNldHRpbmcgaW5cblx0XHQgICAqIG9wdGlvbnMuXG5cdFx0ICAgKlxuXHRcdCAgICogQHJldHVybnMge29iamVjdH1cblx0XHQgICAqL1xuXHRcblx0XG5cdFx0ICBIdG1sUGFyc2VyLnByb3RvdHlwZS5yZWFkVG9rZW4gPSBmdW5jdGlvbiByZWFkVG9rZW4oKSB7XG5cdFx0ICAgIHJldHVybiB0aGlzLl9yZWFkVG9rZW4oKTtcblx0XHQgIH07XG5cdFxuXHRcdCAgLyoqXG5cdFx0ICAgKiBSZWFkIHRva2VucyBhbmQgaGFuZCB0byB0aGUgZ2l2ZW4gaGFuZGxlcnMuXG5cdFx0ICAgKlxuXHRcdCAgICogQHBhcmFtIHtPYmplY3R9IGhhbmRsZXJzIFRoZSBoYW5kbGVycyB0byB1c2UgZm9yIHRoZSBkaWZmZXJlbnQgdG9rZW5zLlxuXHRcdCAgICovXG5cdFxuXHRcblx0XHQgIEh0bWxQYXJzZXIucHJvdG90eXBlLnJlYWRUb2tlbnMgPSBmdW5jdGlvbiByZWFkVG9rZW5zKGhhbmRsZXJzKSB7XG5cdFx0ICAgIHZhciB0b2sgPSB2b2lkIDA7XG5cdFx0ICAgIHdoaWxlICh0b2sgPSB0aGlzLnJlYWRUb2tlbigpKSB7XG5cdFx0ICAgICAgLy8gY29udGludWUgdW50aWwgd2UgZ2V0IGFuIGV4cGxpY2l0IFwiZmFsc2VcIiByZXR1cm5cblx0XHQgICAgICBpZiAoaGFuZGxlcnNbdG9rLnR5cGVdICYmIGhhbmRsZXJzW3Rvay50eXBlXSh0b2spID09PSBmYWxzZSkge1xuXHRcdCAgICAgICAgcmV0dXJuO1xuXHRcdCAgICAgIH1cblx0XHQgICAgfVxuXHRcdCAgfTtcblx0XG5cdFx0ICAvKipcblx0XHQgICAqIENsZWFycyB0aGUgcGFyc2Ugc3RyZWFtLlxuXHRcdCAgICpcblx0XHQgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjb250ZW50cyBvZiB0aGUgcGFyc2Ugc3RyZWFtIGJlZm9yZSBjbGVhcmluZy5cblx0XHQgICAqL1xuXHRcblx0XG5cdFx0ICBIdG1sUGFyc2VyLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uIGNsZWFyKCkge1xuXHRcdCAgICB2YXIgcmVzdCA9IHRoaXMuc3RyZWFtO1xuXHRcdCAgICB0aGlzLnN0cmVhbSA9ICcnO1xuXHRcdCAgICByZXR1cm4gcmVzdDtcblx0XHQgIH07XG5cdFxuXHRcdCAgLyoqXG5cdFx0ICAgKiBSZXR1cm5zIHRoZSByZXN0IG9mIHRoZSBwYXJzZSBzdHJlYW0uXG5cdFx0ICAgKlxuXHRcdCAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGNvbnRlbnRzIG9mIHRoZSBwYXJzZSBzdHJlYW0uXG5cdFx0ICAgKi9cblx0XG5cdFxuXHRcdCAgSHRtbFBhcnNlci5wcm90b3R5cGUucmVzdCA9IGZ1bmN0aW9uIHJlc3QoKSB7XG5cdFx0ICAgIHJldHVybiB0aGlzLnN0cmVhbTtcblx0XHQgIH07XG5cdFxuXHRcdCAgcmV0dXJuIEh0bWxQYXJzZXI7XG5cdFx0fSgpO1xuXHRcblx0XHRleHBvcnRzWydkZWZhdWx0J10gPSBIdG1sUGFyc2VyO1xuXHRcblx0XG5cdFx0SHRtbFBhcnNlci50b2tlblRvU3RyaW5nID0gZnVuY3Rpb24gKHRvaykge1xuXHRcdCAgcmV0dXJuIHRvay50b1N0cmluZygpO1xuXHRcdH07XG5cdFxuXHRcdEh0bWxQYXJzZXIuZXNjYXBlQXR0cmlidXRlcyA9IGZ1bmN0aW9uIChhdHRycykge1xuXHRcdCAgdmFyIGVzY2FwZWRBdHRycyA9IHt9O1xuXHRcblx0XHQgIGZvciAodmFyIG5hbWUgaW4gYXR0cnMpIHtcblx0XHQgICAgaWYgKGF0dHJzLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG5cdFx0ICAgICAgZXNjYXBlZEF0dHJzW25hbWVdID0gKDAsIF91dGlscy5lc2NhcGVRdW90ZXMpKGF0dHJzW25hbWVdLCBudWxsKTtcblx0XHQgICAgfVxuXHRcdCAgfVxuXHRcblx0XHQgIHJldHVybiBlc2NhcGVkQXR0cnM7XG5cdFx0fTtcblx0XG5cdFx0SHRtbFBhcnNlci5zdXBwb3J0cyA9IHN1cHBvcnRzO1xuXHRcblx0XHRmb3IgKHZhciBrZXkgaW4gc3VwcG9ydHMpIHtcblx0XHQgIGlmIChzdXBwb3J0cy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG5cdFx0ICAgIEh0bWxQYXJzZXIuYnJvd3Nlckhhc0ZsYXcgPSBIdG1sUGFyc2VyLmJyb3dzZXJIYXNGbGF3IHx8ICFzdXBwb3J0c1trZXldICYmIGtleTtcblx0XHQgIH1cblx0XHR9XG5cdFxuXHQvKioqLyB9LFxuXHQvKiAyICovXG5cdC8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXHRcblx0XHQndXNlIHN0cmljdCc7XG5cdFxuXHRcdGV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cdFx0dmFyIHRhZ1NvdXAgPSBmYWxzZTtcblx0XHR2YXIgc2VsZkNsb3NlID0gZmFsc2U7XG5cdFxuXHRcdHZhciB3b3JrID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHRcblx0XHR0cnkge1xuXHRcdCAgdmFyIGh0bWwgPSAnPFA+PEk+PC9QPjwvST4nO1xuXHRcdCAgd29yay5pbm5lckhUTUwgPSBodG1sO1xuXHRcdCAgZXhwb3J0cy50YWdTb3VwID0gdGFnU291cCA9IHdvcmsuaW5uZXJIVE1MICE9PSBodG1sO1xuXHRcdH0gY2F0Y2ggKGUpIHtcblx0XHQgIGV4cG9ydHMudGFnU291cCA9IHRhZ1NvdXAgPSBmYWxzZTtcblx0XHR9XG5cdFxuXHRcdHRyeSB7XG5cdFx0ICB3b3JrLmlubmVySFRNTCA9ICc8UD48aT48UD48L1A+PC9pPjwvUD4nO1xuXHRcdCAgZXhwb3J0cy5zZWxmQ2xvc2UgPSBzZWxmQ2xvc2UgPSB3b3JrLmNoaWxkTm9kZXMubGVuZ3RoID09PSAyO1xuXHRcdH0gY2F0Y2ggKGUpIHtcblx0XHQgIGV4cG9ydHMuc2VsZkNsb3NlID0gc2VsZkNsb3NlID0gZmFsc2U7XG5cdFx0fVxuXHRcblx0XHR3b3JrID0gbnVsbDtcblx0XG5cdFx0ZXhwb3J0cy50YWdTb3VwID0gdGFnU291cDtcblx0XHRleHBvcnRzLnNlbGZDbG9zZSA9IHNlbGZDbG9zZTtcblx0XG5cdC8qKiovIH0sXG5cdC8qIDMgKi9cblx0LyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cdFxuXHRcdCd1c2Ugc3RyaWN0Jztcblx0XG5cdFx0ZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblx0XG5cdFx0dmFyIF90eXBlb2YgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIiA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH0gOiBmdW5jdGlvbiAob2JqKSB7IHJldHVybi
1BvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7IH07XG5cdFxuXHRcdGV4cG9ydHMuY29tbWVudCA9IGNvbW1lbnQ7XG5cdFx0ZXhwb3J0cy5jaGFycyA9IGNoYXJzO1xuXHRcdGV4cG9ydHMuc3RhcnRUYWcgPSBzdGFydFRhZztcblx0XHRleHBvcnRzLmF0b21pY1RhZyA9IGF0b21pY1RhZztcblx0XHRleHBvcnRzLmVuZFRhZyA9IGVuZFRhZztcblx0XG5cdFx0dmFyIF90b2tlbnMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpO1xuXHRcblx0XHQvKipcblx0XHQgKiBSZWd1bGFyIEV4cHJlc3Npb25zIGZvciBwYXJzaW5nIHRhZ3MgYW5kIGF0dHJpYnV0ZXNcblx0XHQgKlxuXHRcdCAqIEB0eXBlIHtPYmplY3R9XG5cdFx0ICovXG5cdFx0dmFyIFJFR0VYRVMgPSB7XG5cdFx0ICBzdGFydFRhZzogL148KFtcXC1BLVphLXowLTlfXSspKCg/OlxccytbXFx3XFwtXSsoPzpcXHMqPT9cXHMqKD86KD86XCJbXlwiXSpcIil8KD86J1teJ10qJyl8W14+XFxzXSspKT8pKilcXHMqKFxcLz8pPi8sXG5cdFx0ICBlbmRUYWc6IC9ePFxcLyhbXFwtQS1aYS16MC05X10rKVtePl0qPi8sXG5cdFx0ICBhdHRyOiAvKD86KFtcXC1BLVphLXowLTlfXSspXFxzKj1cXHMqKD86KD86XCIoKD86XFxcXC58W15cIl0pKilcIil8KD86JygoPzpcXFxcLnxbXiddKSopJyl8KFtePlxcc10rKSkpfCg/OihbXFwtQS1aYS16MC05X10rKShcXHN8JCkrKS9nLFxuXHRcdCAgZmlsbEF0dHI6IC9eKGNoZWNrZWR8Y29tcGFjdHxkZWNsYXJlfGRlZmVyfGRpc2FibGVkfGlzbWFwfG11bHRpcGxlfG5vaHJlZnxub3Jlc2l6ZXxub3NoYWRlfG5vd3JhcHxyZWFkb25seXxzZWxlY3RlZCkkL2lcblx0XHR9O1xuXHRcblx0XHQvKipcblx0XHQgKiBSZWFkcyBhIGNvbW1lbnQgdG9rZW5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSBzdHJlYW0gVGhlIGlucHV0IHN0cmVhbVxuXHRcdCAqIEByZXR1cm5zIHtDb21tZW50VG9rZW59XG5cdFx0ICovXG5cdFx0ZnVuY3Rpb24gY29tbWVudChzdHJlYW0pIHtcblx0XHQgIHZhciBpbmRleCA9IHN0cmVhbS5pbmRleE9mKCctLT4nKTtcblx0XHQgIGlmIChpbmRleCA+PSAwKSB7XG5cdFx0ICAgIHJldHVybiBuZXcgX3Rva2Vucy5Db21tZW50VG9rZW4oc3RyZWFtLnN1YnN0cig0LCBpbmRleCAtIDEpLCBpbmRleCArIDMpO1xuXHRcdCAgfVxuXHRcdH1cblx0XG5cdFx0LyoqXG5cdFx0ICogUmVhZHMgbm9uLXRhZyBjaGFyYWN0ZXJzLlxuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IHN0cmVhbSBUaGUgaW5wdXQgc3RyZWFtXG5cdFx0ICogQHJldHVybnMge0NoYXJzVG9rZW59XG5cdFx0ICovXG5cdFx0ZnVuY3Rpb24gY2hhcnMoc3RyZWFtKSB7XG5cdFx0ICB2YXIgaW5kZXggPSBzdHJlYW0uaW5kZXhPZignPCcpO1xuXHRcdCAgcmV0dXJuIG5ldyBfdG9rZW5zLkNoYXJzVG9rZW4oaW5kZXggPj0gMCA/IGluZGV4IDogc3RyZWFtLmxlbmd0aCk7XG5cdFx0fVxuXHRcblx0XHQvKipcblx0XHQgKiBSZWFkcyBzdGFydCB0YWcgdG9rZW4uXG5cdFx0ICpcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gc3RyZWFtIFRoZSBpbnB1dCBzdHJlYW1cblx0XHQgKiBAcmV0dXJucyB7U3RhcnRUYWdUb2tlbn1cblx0XHQgKi9cblx0XHRmdW5jdGlvbiBzdGFydFRhZyhzdHJlYW0pIHtcblx0XHQgIHZhciBlbmRUYWdJbmRleCA9IHN0cmVhbS5pbmRleE9mKCc+Jyk7XG5cdFx0ICBpZiAoZW5kVGFnSW5kZXggIT09IC0xKSB7XG5cdFx0ICAgIHZhciBtYXRjaCA9IHN0cmVhbS5tYXRjaChSRUdFWEVTLnN0YXJ0VGFnKTtcblx0XHQgICAgaWYgKG1hdGNoKSB7XG5cdFx0ICAgICAgdmFyIF9yZXQgPSBmdW5jdGlvbiAoKSB7XG5cdFx0ICAgICAgICB2Y
1XIgYXR0cnMgPSB7fTtcblx0XHQgICAgICAgIHZhciBib29sZWFuQXR0cnMgPSB7fTtcblx0XHQgICAgICAgIHZhciByZXN0ID0gbWF0Y2hbMl07XG5cdFxuXHRcdCAgICAgICAgbWF0Y2hbMl0ucmVwbGFjZShSRUdFWEVTLmF0dHIsIGZ1bmN0aW9uIChtYXRjaCwgbmFtZSkge1xuXHRcdCAgICAgICAgICBpZiAoIShhcmd1bWVudHNbMl0gfHwgYXJndW1lbnRzWzNdIHx8IGFyZ3VtZW50c1s0XSB8fCBhcmd1bWVudHNbNV0pKSB7XG5cdFx0ICAgICAgICAgICAgYXR0cnNbbmFtZV0gPSAnJztcblx0XHQgICAgICAgICAgfSBlbHNlIGlmIChhcmd1bWVudHNbNV0pIHtcblx0XHQgICAgICAgICAgICBhdHRyc1thcmd1bWVudHNbNV1dID0gJyc7XG5cdFx0ICAgICAgICAgICAgYm9vbGVhbkF0dHJzW2FyZ3VtZW50c1s1XV0gPSB0cnVlO1xuXHRcdCAgICAgICAgICB9IGVsc2Uge1xuXHRcdCAgICAgICAgICAgIGF0dHJzW25hbWVdID0gYXJndW1lbnRzWzJdIHx8IGFyZ3VtZW50c1szXSB8fCBhcmd1bWVudHNbNF0gfHwgUkVHRVhFUy5maWxsQXR0ci50ZXN0KG5hbWUpICYmIG5hbWUgfHwgJyc7XG5cdFx0ICAgICAgICAgIH1cblx0XG5cdFx0ICAgICAgICAgIHJlc3QgPSByZXN0LnJlcGxhY2UobWF0Y2gsICcnKTtcblx0XHQgICAgICAgIH0pO1xuXHRcblx0XHQgICAgICAgIHJldHVybiB7XG5cdFx0ICAgICAgICAgIHY6IG5ldyBfdG9rZW5zLlN0YXJ0VGFnVG9rZW4obWF0Y2hbMV0sIG1hdGNoWzBdLmxlbmd0aCwgYXR0cnMsIGJvb2xlYW5BdHRycywgISFtYXRjaFszXSwgcmVzdC5yZXBsYWNlKC9eW1xcc1xcdUZFRkZcXHhBMF0rfFtcXHNcXHVGRUZGXFx4QTBdKyQvZywgJycpKVxuXHRcdCAgICAgICAgfTtcblx0XHQgICAgICB9KCk7XG5cdFxuXHRcdCAgICAgIGlmICgodHlwZW9mIF9yZXQgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKF9yZXQpKSA9PT0gXCJvYmplY3RcIikgcmV0dXJuIF9yZXQudjtcblx0XHQgICAgfVxuXHRcdCAgfVxuXHRcdH1cblx0XG5cdFx0LyoqXG5cdFx0ICogUmVhZHMgYXRvbWljIHRhZyB0b2tlbi5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSBzdHJlYW0gVGhlIGlucHV0IHN0cmVhbVxuXHRcdCAqIEByZXR1cm5zIHtBdG9taWNUYWdUb2tlbn1cblx0XHQgKi9cblx0XHRmdW5jdGlvbiBhdG9taWNUYWcoc3RyZWFtKSB7XG5cdFx0ICB2YXIgc3RhcnQgPSBzdGFydFRhZyhzdHJlYW0pO1xuXHRcdCAgaWYgKHN0YXJ0KSB7XG5cdFx0ICAgIHZhciByZXN0ID0gc3RyZWFtLnNsaWNlKHN0YXJ0Lmxlbmd0aCk7XG5cdFx0ICAgIC8vIGZvciBvcHRpbWl6YXRpb24sIHdlIGNoZWNrIGZpcnN0IGp1c3QgZm9yIHRoZSBlbmQgdGFnXG5cdFx0ICAgIGlmIChyZXN0Lm1hdGNoKG5ldyBSZWdFeHAoJzxcXC9cXFxccyonICsgc3RhcnQudGFnTmFtZSArICdcXFxccyo+JywgJ2knKSkpIHtcblx0XHQgICAgICAvLyBjYXB0dXJpbmcgdGhlIGNvbnRlbnQgaXMgaW5lZmZpY2llbnQsIHNvIHdlIGRvIGl0IGluc2lkZSB0aGUgaWZcblx0XHQgICAgICB2YXIgbWF0Y2ggPSByZXN0Lm1hdGNoKG5ldyBSZWdFeHAoJyhbXFxcXHNcXFxcU10qPyk8XFwvXFxcXHMqJyArIHN0YXJ0LnRhZ05hbWUgKyAnXFxcXHMqPicsICdpJykpO1xuXHRcdCAgICAgIGlmIChtYXRjaCkge1xuXHRcdCAgICAgICAgcmV0dXJuIG5ldyBfdG9rZW5zLkF0b21pY1RhZ1Rva2VuKHN0YXJ0LnRhZ05hbWUsIG1hdGNoWzBdLmxlbmd0aCArIHN0YXJ0Lmxlbmd0aCwgc3RhcnQuYXR0cnMsIHN0YXJ0LmJvb2xlYW5BdHRycywgbWF0Y2hbMV0pO1xuXHRcdCAgICAgIH1cblx0XHQgICAgfVxuXHRcdCAgfVxuXHRcdH1cblx0XG5cdFx0LyoqXG5cdFx0ICogUmVhZHMgYW4gZW5kIHRhZyB0b2tlbi5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSBzdHJlYW0gVGhlIGlucHV0IHN0cmVhbVxuXHRcdCAqIEByZXR1cm5zIHtFbmRUYWdUb2tlbn1cblx0XHQgKi9cblx0XHRmdW5jdGlvbiBlbmRUYWcoc3RyZWFtKSB7XG5cdFx0ICB2YXIgbWF0Y2ggPSBzdHJlYW0ubWF0Y2goUkVHRVhFUy5lbmRUYWcpO1xuXHRcdCAgaWYgKG1hdGNoKSB7XG5cdFx0ICAgIHJldHVybiBuZXcgX3Rva2Vucy5FbmRUYWdUb2tlbihtYXRjaFsxXSwgbWF0Y2hbMF0ubGVuZ3RoKTtcblx0XHQgIH1cblx0XHR9XG5cdFxuXHQvKioqLyB9LFxuXHQvKiA0ICovXG5cdC8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXHRcblx0XHQndXNlIHN0cmljdCc7XG5cdFxuXHRcdGV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cdFx0ZXhwb3J0cy5FbmRUYWdUb2tlbiA9IGV4cG9ydHMuQXRvbWljVGFnVG9rZW4gPSBleHBvcnRzLlN0YXJ0VGFnVG9rZW4gPSBleHBvcnRzLlRhZ1Rva2VuID0gZXhwb3J0cy5DaGFyc1Rva2VuID0gZXhwb3J0cy5Db21tZW50VG9rZW4gPSBleHBvcnRzLlRva2VuID0gdW5kZWZpbmVkO1xuXHRcblx0XHR2YXIgX3V0aWxzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg1KTtcblx0XG5cdFx0ZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblx0XG5cdFx0LyoqXG5cdFx0ICogVG9rZW4gaXMgYSBiYXNlIGNsYXNzIGZvciBhbGwgdG9rZW4gdHlwZXMgcGFyc2VkLiAgTm90ZSB3ZSBkb24ndCBhY3R1YWxseVxuXHRcdCAqIHVzZSBpbnRoZXJpdGFuY2UgZHVlIHRvIElFOCdzIG5vbi1leGlzdGVudCBFUzUgc3VwcG9ydC5cblx0XHQgKi9cblx0XG5cdFx0dmFyIFRva2VuID1cblx0XHQvKipcblx0XHQgKiBDb25zdHJ1Y3Rvci5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFRoZSB0eXBlIG9mIHRoZSBUb2tlbi5cblx0XHQgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoIFRoZSBsZW5ndGggb2YgdGhlIFRva2VuIHRleHQuXG5cdFx0ICovXG5cdFx0ZXhwb3J0cy5Ub2tlbiA9IGZ1bmN0aW9uIFRva2VuKHR5cGUsIGxlbmd0aCkge1xuXHRcdCAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFRva2VuKTtcblx0XG5cdFx0ICB0aGlzLnR5cGUgPSB0eXBlO1xuXHRcdCAgdGhpcy5sZW5ndGggPSBsZW5ndGg7XG5cdFx0ICB0aGlzLnRleHQgPSAnJztcblx0XHR9O1xuXHRcblx0XHQvKipcblx0XHQgKiBDb21tZW50VG9rZW4gcmVwcmVzZW50cyBjb21tZW50IHRhZ3MuXG5cdFx0ICovXG5cdFxuXHRcblx0XHR2YXIgQ29tbWVudFRva2VuID0gZXhwb3J0cy5Db21tZW50VG9rZW4gPSBmdW5jdGlvbiAoKSB7XG5cdFx0ICAvKipcblx0XHQgICAqIENvbnN0cnVjdG9yLlxuXHRcdCAgICpcblx0XHQgICAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZW50IFRoZSBjb250ZW50IG9mIHRoZSBjb21tZW50XG5cdFx0ICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoIFRoZSBsZW5ndGggb2YgdGhlIFRva2VuIHRleHQuXG5cdFx0ICAgKi9cblx0XG5cdFx0ICBmdW5jdGlvbiBDb21tZW50VG9rZW4oY29udGVudCwgbGVuZ3RoKSB7XG5cdFx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDb21tZW50VG9rZW4pO1xuXHRcblx0XHQgICAgdGhpcy50eXBlID0gJ2NvbW1lbnQnO1xuXHRcdCAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aCB8fCAoY29udGVudCA/IGNvbnRlbnQubGVuZ3RoIDogMCk7XG5cdFx0ICAgIHRoaXMudGV4dCA9ICcnO1xuXHRcdCAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50O1xuXHRcdCAgfVxuXHRcblx0XHQgIENvbW1lbnRUb2tlbi5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcblx0XHQgICAgcmV0dXJuICc8IS0tJyArIHRoaXMuY29udGVudDtcblx0XHQgIH07XG5cdFxuXHRcdCAgcmV0dXJuIENvbW1lbnRUb2tlbjtcblx0XHR9KCk7XG5cdFxuXHRcdC8qKlxuXHRcdCAqIENoYXJzVG9rZW4gcmVwcmVzZW50cyBub24tdGFnIGNoYXJhY3RlcnMuXG5cdFx0ICovXG5cdFxuXHRcblx0XHR2YXIgQ2hhcnNUb2tlbiA9IGV4cG9ydHMuQ2hhcnNUb2tlbiA9IGZ1bmN0aW9uICgpIHtcblx0XHQgIC8qKlxuXHRcdCAgICogQ29uc3RydWN0b3IuXG5cdFx0ICAgKlxuXHRcdCAgICogQHBhcmFtIHtOdW1iZXJ9IGxlbmd0aCBUaGUgbGVuZ3RoIG9mIHRoZSBUb2tlbiB0ZXh0LlxuXHRcdCAgICovXG5cdFxuXHRcdCAgZnVuY3Rpb24gQ2hhcnNUb2tlbihsZW5ndGgpIHtcblx0XHQgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIENoYXJzVG9rZW4pO1xuXHRcblx0XHQgICAgdGhpcy50eXBlID0gJ2NoYXJzJztcblx0XHQgICAgdGhpcy5sZW5ndGggPSBsZW5ndGg7XG5cdFx0ICAgIHRoaXMudGV4dCA9ICcnO1xuXHRcdCAgfVxuXHRcblx0XHQgIENoYXJzVG9rZW4ucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmc
1oKSB7XG5cdFx0ICAgIHJldHVybiB0aGlzLnRleHQ7XG5cdFx0ICB9O1xuXHRcblx0XHQgIHJldHVybiBDaGFyc1Rva2VuO1xuXHRcdH0oKTtcblx0XG5cdFx0LyoqXG5cdFx0ICogVGFnVG9rZW4gaXMgYSBiYXNlIGNsYXNzIGZvciBhbGwgdGFnLWJhc2VkIFRva2Vucy5cblx0XHQgKi9cblx0XG5cdFxuXHRcdHZhciBUYWdUb2tlbiA9IGV4cG9ydHMuVGFnVG9rZW4gPSBmdW5jdGlvbiAoKSB7XG5cdFx0ICAvKipcblx0XHQgICAqIENvbnN0cnVjdG9yLlxuXHRcdCAgICpcblx0XHQgICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFRoZSB0eXBlIG9mIHRoZSB0b2tlbi5cblx0XHQgICAqIEBwYXJhbSB7c3RyaW5nfSB0YWdOYW1lIFRoZSB0YWcgbmFtZS5cblx0XHQgICAqIEBwYXJhbSB7TnVtYmVyfSBsZW5ndGggVGhlIGxlbmd0aCBvZiB0aGUgVG9rZW4gdGV4dC5cblx0XHQgICAqIEBwYXJhbSB7T2JqZWN0fSBhdHRycyBUaGUgZGljdGlvbmFyeSBvZiBhdHRyaWJ1dGVzIGFuZCB2YWx1ZXNcblx0XHQgICAqIEBwYXJhbSB7T2JqZWN0fSBib29sZWFuQXR0cnMgSWYgYW4gZW50cnkgaGFzICd0cnVlJyB0aGVuIHRoZSBhdHRyaWJ1dGVcblx0XHQgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgYSBib29sZWFuIGF0dHJpYnV0ZVxuXHRcdCAgICovXG5cdFxuXHRcdCAgZnVuY3Rpb24gVGFnVG9rZW4odHlwZSwgdGFnTmFtZSwgbGVuZ3RoLCBhdHRycywgYm9vbGVhbkF0dHJzKSB7XG5cdFx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBUYWdUb2tlbik7XG5cdFxuXHRcdCAgICB0aGlzLnR5cGUgPSB0eXBlO1xuXHRcdCAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDtcblx0XHQgICAgdGhpcy50ZXh0ID0gJyc7XG5cdFx0ICAgIHRoaXMudGFnTmFtZSA9IHRhZ05hbWU7XG5cdFx0ICAgIHRoaXMuYXR0cnMgPSBhdHRycztcblx0XHQgICAgdGhpcy5ib29sZWFuQXR0cnMgPSBib29sZWFuQXR0cnM7XG5cdFx0ICAgIHRoaXMudW5hcnkgPSBmYWxzZTtcblx0XHQgICAgdGhpcy5odG1sNVVuYXJ5ID0gZmFsc2U7XG5cdFx0ICB9XG5cdFxuXHRcdCAgLyoqXG5cdFx0ICAgKiBGb3JtYXRzIHRoZSBnaXZlbiB0b2tlbiB0YWcuXG5cdFx0ICAgKlxuXHRcdCAgICogQHBhcmFtIHtUYWdUb2tlbn0gdG9rIFRoZSBUYWdUb2tlbiB0byBmb3JtYXQuXG5cdFx0ICAgKiBAcGFyYW0gez9zdHJpbmd9IFtjb250ZW50PW51bGxdIFRoZSBjb250ZW50IG9mIHRoZSB0b2tlbi5cblx0XHQgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBmb3JtYXR0ZWQgdGFnLlxuXHRcdCAgICovXG5cdFxuXHRcblx0XHQgIFRhZ1Rva2VuLmZvcm1hdFRhZyA9IGZ1bmN0aW9uIGZvcm1hdFRhZyh0b2spIHtcblx0XHQgICAgdmFyIGNvbnRlbnQgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDEgfHwgYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyBudWxsIDogYXJndW1lbnRzWzFdO1xuXHRcblx0XHQgICAgdmFyIHN0ciA9ICc8JyArIHRvay50YWdOYW1lO1xuXHRcdCAgICBmb3IgKHZhciBrZXkgaW4gdG9rLmF0dHJzKSB7XG5cdFx0ICAgICAgaWYgKHRvay5hdHRycy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG5cdFx0ICAgICAgICBzdHIgKz0gJyAnICsga2V5O1xuXHRcblx0XHQgICAgICAgIHZhciB2YWwgPSB0b2suYXR0cnNba2V5XTtcblx0XHQgICAgICAgIGlmICh0eXBlb2YgdG9rLmJvb2xlYW5BdHRycyA9PT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIHRvay5ib29sZWFuQXR0cnNba2V5XSA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHQgICAgICAgICAgc3RyICs9ICc9XCInICsgKDAsIF91dGlscy5lc2NhcGVRdW90ZXMpKHZhbCkgKyAnXCInO1xuXHRcdCAgICAgICAgfVxuXHRcdCAgICAgIH1cblx0XHQgICAgfVxuXHRcblx0XHQgICAgaWYgKHRvay5yZXN0KSB7XG5cdFx0ICAgICAgc3RyICs9ICcgJyArIHRvay5yZXN0O1xuXHRcdCAgICB9XG5cdFxuXHRcdCAgICBpZiAodG9rLnVuYXJ5ICYmICF0b2suaHRtbDVVbmFyeSkge1xuXHRcdCAgICAgIHN0ciArPSAnLz4nO1xuXHRcdCAgICB9IGVsc2Uge1xuXHRcdCAgICAgIHN0ciArPSAnPic7XG5cdFx0ICAgIH1cblx0XG5cdFx0ICAgIGlmIChjb250ZW50ICE9PSB1bmRlZmluZWQgJiYgY29udGVudCAhPT0gbnVsbCkge1xuXHRcdCAgICAgIHN0ciArPSBjb250ZW50ICsgJzwvJyArIHRvay50YWdOYW1lICsgJz4nO1xuXHRcdCAgICB9XG5cdFxuXHRcdCAgICByZXR1cm4gc3RyO1xuXHRcdCAgfTtcblx0XG5cdFx0ICByZXR1cm4gVGFnVG9rZW47XG5cdFx0fSgpO1xuXHRcblx0XHQvKipcblx0XHQgKiBTdGFydFRhZ1Rva2VuIHJlcHJlc2VudHMgYSBzdGFydCB0b2tlbi5cblx0XHQgKi9cblx0XG5cdFxuXHRcdHZhciBTdGFydFRhZ1Rva2VuID0gZXhwb3J0cy5TdGFydFRhZ1Rva2VuID0gZnVuY3Rpb24gKCkge1xuXHRcdCAgLyoqXG5cdFx0ICAgKiBDb25zdHJ1Y3Rvci5cblx0XHQgICAqXG5cdFx0ICAgKiBAcGFyYW0ge3N0cmluZ30gdGFnTmFtZSBUaGUgdGFnIG5hbWUuXG5cdFx0ICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoIFRoZSBsZW5ndGggb2YgdGhlIFRva2VuIHRleHRcblx0XHQgICAqIEBwYXJhbSB7T2JqZWN0fSBhdHRycyBUaGUgZGljdGlvbmFyeSBvZiBhdHRyaWJ1dGVzIGFuZCB2YWx1ZXNcblx0XHQgICAqIEBwYXJhbSB7T2JqZWN0fSBib29sZWFuQXR0cnMgSWYgYW4gZW50cnkgaGFzICd0cnVlJyB0aGVuIHRoZSBhdHRyaWJ1dGVcblx0XHQgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgYSBib29sZWFuIGF0dHJpYnV0ZVxuXHRcdCAgICogQHBhcmFtIHtib29sZWFufSB1bmFyeSBUcnVlIGlmIHRoZSB0YWcgaXMgYSB1bmFyeSB0YWdcblx0XHQgICAqIEBwYXJhbSB7c3RyaW5nfSByZXN0IFRoZSByZXN0IG9mIHRoZSBjb250ZW50LlxuXHRcdCAgICovXG5cdFxuXHRcdCAgZnVuY3Rpb24gU3RhcnRUYWdUb2tlbih0YWdOYW1lLCBsZW5ndGgsIGF0dHJzLCBib29sZWFuQXR0cnMsIHVuYXJ5LCByZXN0KSB7XG5cdFx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBTdGFydFRhZ1Rva2VuKTtcblx0XG5cdFx0ICAgIHRoaXMudHlwZSA9ICdzdGFydFRhZyc7XG5cdFx0ICAgIHRoaXMubGVuZ3RoID0gbGVuZ3RoO1xuXHRcdCAgICB0aGlzLnRleHQgPSAnJztcblx0XHQgICAgdGhpcy50YWdOYW1lID0gdGFnTmFtZTtcblx0XHQgICAgdGhpcy5hdHRycyA9IGF0dHJzO1xuXHRcdCAgICB0aGlzLmJvb2xlYW5BdHRycyA9IGJvb2xlYW5BdHRycztcblx0XHQgICAgdGhpcy5odG1sNVVuYXJ5ID0gZmFsc2U7XG5cdFx0ICAgIHRoaXMudW5hcnkgPSB1bmFyeTtcblx0XHQgICAgdGhpcy5yZXN0ID0gcmVzdDtcblx0XHQgIH1cblx0XG5cdFx0ICBTdGFydFRhZ1Rva2VuLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuXHRcdCAgICByZXR1cm4gVGFnVG9rZW4uZm9ybWF0VGFnKHRoaXMpO1xuXHRcdCAgfTtcblx0XG5cdFx0ICByZXR1cm4gU3RhcnRUYWdUb2tlbjtcblx0XHR9KCk7XG5cdFxuXHRcdC8qKlxuXHRcdCAqIEF0b21pY1RhZ1Rva2VuIHJlcHJlc2VudHMgYW4gYXRvbWljIHRhZy5cblx0XHQgKi9cblx0XG5cdFxuXHRcdHZhciBBdG9taWNUYWdUb2tlbiA9IGV4cG9ydHMuQXRvbWljVGFnVG9rZW4gPSBmdW5jdGlvbiAoKSB7XG5cdFx0ICAvKipcblx0XHQgICAqIENvbnN0cnVjdG9yLlxuXHRcdCAgICpcblx0XHQgICAqIEBwYXJhbSB7c3RyaW5nfSB0YWdOYW1lIFRoZSBuYW1lIG9mIHRoZSB0YWcuXG5cdFx0ICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoIFRoZSBsZW5ndGggb2YgdGhlIHRhZyB0ZXh0LlxuXHRcdCAgICogQHBhcmFtIHtPYmplY3R9IGF0dHJzIFRoZSBhdHRyaWJ1dGVzLlxuXHRcdCAgICogQHBhcmFtIHtPYmplY3R9IGJvb2xlYW5BdHRycyBJZiBhbiBlbnRyeSBoYXMgJ3RydWUnIHRoZW4gdGhlIGF0dHJpYnV0ZVxuXHRcdCAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcyBhIGJvb2xlYW4gYXR0cmlidXRlXG5cdFx0ICAgKiBAcGFyYW0ge3N0cmluZ30gY29udGVudCBUaGUgY29udGVudCBvZiB0aGUgdGFnLlxuXHRcdCAgICovXG5cdFxuXHRcdCAgZnVuY3Rpb24gQXRvbWljVGFnVG9rZW4odGFnTmFtZSwgbGVuZ3RoLCBhdHRycywgYm9vbGVhbkF0dHJzLCBjb250ZW50KSB7XG5cdFx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBBdG9taWNUYWdUb2tlbik7XG5cdFxuXHRcdCAgICB0aGlzLnR5cGUgPSAnYXRvbWljVGFnJztcblx0XHQgICAgdGhpcy5sZW5ndGggPSBsZW5ndGg7XG5cdFx0ICAgIHRoaXMudGV4dCA9ICcnO1xuXHRcdCAgICB0aGlzLnRhZ05hbWUgPSB0YWdOYW1lO1xuXHRcdCAgICB0aGlzLmF0dHJzID0gYXR0cnM7XG5cdFx0ICAgIHRoaXMuYm9vbGVhbkF0dHJzID0gYm9vbGVhbkF0dHJzO1xuXHRcdCAgICB0aGlzLnVuYXJ5ID0gZmFsc2U7XG5cdFx0ICAgIHRoaXMuaHRtbDVVbmFyeSA9IGZhbHNlO1xuXHRcdCAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50O1xuXHRcdCAgfVxuXHRcblx0XHQgIEF0b21pY1RhZ1Rva2VuLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuXHRcdCAgICByZXR1cm4gVGFnVG9rZW4uZm9ybWF0VGFnKHRoaXMsIHR
1oaXMuY29udGVudCk7XG5cdFx0ICB9O1xuXHRcblx0XHQgIHJldHVybiBBdG9taWNUYWdUb2tlbjtcblx0XHR9KCk7XG5cdFxuXHRcdC8qKlxuXHRcdCAqIEVuZFRhZ1Rva2VuIHJlcHJlc2VudHMgYW4gZW5kIHRhZy5cblx0XHQgKi9cblx0XG5cdFxuXHRcdHZhciBFbmRUYWdUb2tlbiA9IGV4cG9ydHMuRW5kVGFnVG9rZW4gPSBmdW5jdGlvbiAoKSB7XG5cdFx0ICAvKipcblx0XHQgICAqIENvbnN0cnVjdG9yLlxuXHRcdCAgICpcblx0XHQgICAqIEBwYXJhbSB7c3RyaW5nfSB0YWdOYW1lIFRoZSBuYW1lIG9mIHRoZSB0YWcuXG5cdFx0ICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoIFRoZSBsZW5ndGggb2YgdGhlIHRhZyB0ZXh0LlxuXHRcdCAgICovXG5cdFxuXHRcdCAgZnVuY3Rpb24gRW5kVGFnVG9rZW4odGFnTmFtZSwgbGVuZ3RoKSB7XG5cdFx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBFbmRUYWdUb2tlbik7XG5cdFxuXHRcdCAgICB0aGlzLnR5cGUgPSAnZW5kVGFnJztcblx0XHQgICAgdGhpcy5sZW5ndGggPSBsZW5ndGg7XG5cdFx0ICAgIHRoaXMudGV4dCA9ICcnO1xuXHRcdCAgICB0aGlzLnRhZ05hbWUgPSB0YWdOYW1lO1xuXHRcdCAgfVxuXHRcblx0XHQgIEVuZFRhZ1Rva2VuLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuXHRcdCAgICByZXR1cm4gJzwvJyArIHRoaXMudGFnTmFtZSArICc+Jztcblx0XHQgIH07XG5cdFxuXHRcdCAgcmV0dXJuIEVuZFRhZ1Rva2VuO1xuXHRcdH0oKTtcblx0XG5cdC8qKiovIH0sXG5cdC8qIDUgKi9cblx0LyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cdFxuXHRcdCd1c2Ugc3RyaWN0Jztcblx0XG5cdFx0ZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblx0XHRleHBvcnRzLmVzY2FwZVF1b3RlcyA9IGVzY2FwZVF1b3Rlcztcblx0XG5cdFx0LyoqXG5cdFx0ICogRXNjYXBlIHF1b3RlcyBpbiB0aGUgZ2l2ZW4gdmFsdWUuXG5cdFx0ICpcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgVGhlIHZhbHVlIHRvIGVzY2FwZS5cblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gW2RlZmF1bHRWYWx1ZT0nJ10gVGhlIGRlZmF1bHQgdmFsdWUgdG8gcmV0dXJuIGlmIHZhbHVlIGlzIGZhbHN5LlxuXHRcdCAqIEByZXR1cm5zIHtzdHJpbmd9XG5cdFx0ICovXG5cdFx0ZnVuY3Rpb24gZXNjYXBlUXVvdGVzKHZhbHVlKSB7XG5cdFx0ICB2YXIgZGVmYXVsdFZhbHVlID0gYXJndW1lbnRzLmxlbmd0aCA8PSAxIHx8IGFyZ3VtZW50c1sxXSA9PT0gdW5kZWZpbmVkID8gJycgOiBhcmd1bWVudHNbMV07XG5cdFxuXHRcdCAgLy8gVGhlcmUncyBubyBsb29rYmFjayBpbiBKUywgc28gLyhefFteXFxcXF0pXCIvIG9ubHkgbWF0Y2hlcyB0aGUgZmlyc3Qgb2YgdHdvIGBcImBzLlxuXHRcdCAgLy8gSW5zdGVhZCwganVzdCBtYXRjaCBhbnl0aGluZyBiZWZvcmUgYSBkb3VibGUtcXVvdGUgYW5kIGVzY2FwZSBpZiBpdCdzIG5vdCBhbHJlYWR5IGVzY2FwZWQuXG5cdFx0ICByZXR1cm4gIXZhbHVlID8gZGVmYXVsdFZhbHVlIDogdmFsdWUucmVwbGFjZSgvKFteXCJdKilcIi9nLCBmdW5jdGlvbiAoXywgcHJlZml4KSB7XG5cdFx0ICAgIHJldHVybiAoL1xcXFwvLnRlc3QocHJlZml4KSA/IHByZWZpeCArICdcIicgOiBwcmVmaXggKyAnXFxcXFwiJ1xuXHRcdCAgICApO1xuXHRcdCAgfSk7XG5cdFx0fVxuXHRcblx0LyoqKi8gfSxcblx0LyogNiAqL1xuXHQvKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblx0XG5cdFx0J3VzZSBzdHJpY3QnO1xuXHRcblx0XHRleHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXHRcdGV4cG9ydHNbJ2RlZmF1bHQnXSA9IGZpeGVkUmVhZFRva2VuRmFjdG9yeTtcblx0XHQvKipcblx0XHQgKiBFbXB0eSBFbGVtZW50cyAtIEhUTUwgNC4wMVxuXHRcdCAqXG5cdFx0ICogQHR5cGUge1JlZ0V4cH1cblx0XHQgKi9cblx0XHR2YXIgRU1QVFkgPSAvXihBUkVBfEJBU0V8QkFTRUZPTlR8QlJ8Q09MfEZSQU1FfEhSfElNR3xJTlBVVHxJU0lOREVYfExJTkt8TUVUQXxQQVJBTXxFTUJFRCkkL2k7XG5cdFxuXHRcdC8qKlxuXHRcdCAqIEVsZW1lbnRzIHRoYXQgeW91IGNhbiBpbnRlbnRpb25hbGx5IGxlYXZlIG9wZW4gKGFuZCB3aGljaCBjbG9zZSB0aGVtc2VsdmVzKVxuXHRcdCAqXG5cdFx0ICogQHR5cGUge1JlZ0V4cH1cblx0XHQgKi9cblx0XHR2YXIgQ0xPU0VTRUxGID0gL14oQ09MR1JPVVB8RER8RFR8TEl8T1BUSU9OU3xQfFREfFRGT09UfFRIfFRIRUFEfFRSKSQvaTtcblx0XG5cdFx0LyoqXG5cdFx0ICogQ29ycmVjdHMgYSB0b2tlbi5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7VG9rZW59IHRvayBUaGUgdG9rZW4gdG8gY29ycmVjdFxuXHRcdCAqIEByZXR1cm5zIHtUb2tlbn0gVGhlIGNvcnJlY3RlZCB0b2tlblxuXHRcdCAqL1xuXHRcdGZ1bmN0aW9uIGNvcnJlY3QodG9rKSB7XG5cdFx0ICBpZiAodG9rICYmIHRvay50eXBlID09PSAnc3RhcnRUYWcnKSB7XG5cdFx0ICAgIHRvay51bmFyeSA9IEVNUFRZLnRlc3QodG9rLnRhZ05hbWUpIHx8IHRvay51bmFyeTtcblx0XHQgICAgdG9rLmh0bWw1VW5hcnkgPSAhL1xcLz4kLy50ZXN0KHRvay50ZXh0KTtcblx0XHQgIH1cblx0XHQgIHJldHVybiB0b2s7XG5cdFx0fVxuXHRcblx0XHQvKipcblx0XHQgKiBQZWVrcyBhdCB0aGUgbmV4dCB0b2tlbiBpbiB0aGUgcGFyc2VyLlxuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtIdG1sUGFyc2VyfSBwYXJzZXIgVGhlIHBhcnNlclxuXHRcdCAqIEBwYXJhbSB7RnVuY3Rpb259IHJlYWRUb2tlbkltcGwgVGhlIHVuZGVybHlpbmcgcmVhZFRva2VuIGltcGxlbWVudGF0aW9uXG5cdFx0ICogQHJldHVybnMge1Rva2VufSBUaGUgbmV4dCB0b2tlblxuXHRcdCAqL1xuXHRcdGZ1bmN0aW9uIHBlZWtUb2tlbihwYXJzZXIsIHJlYWRUb2tlbkltcGwpIHtcblx0XHQgIHZhciB0bXAgPSBwYXJzZXIuc3RyZWFtO1xuXHRcdCAgdmFyIHRvayA9IGNvcnJlY3QocmVhZFRva2VuSW1wbCgpKTtcblx0XHQgIHBhcnNlci5zdHJlYW0gPSB0bXA7XG5cdFx0ICByZXR1cm4gdG9rO1xuXHRcdH1cblx0XG5cdFx0LyoqXG5cdFx0ICogQ2xvc2VzIHRoZSBsYXN0IHRva2VuLlxuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtIdG1sUGFyc2VyfSBwYXJzZXIgVGhlIHBhcnNlclxuXHRcdCAqIEBwYXJhbSB7QXJyYXk8VG9rZW4+fSBzdGFjayBUaGUgc3RhY2tcblx0XHQgKi9cblx0XHRmdW5jdGlvbiBjbG9zZUxhc3QocGFyc2VyLCBzdGFjaykge1xuXHRcdCAgdmFyIHRvayA9IHN0YWNrLnBvcCgpO1xuXHRcblx0XHQgIC8vIHByZXBlbmQgY2xvc2UgdGFnIHRvIHN0cmVhbS5cblx0XHQgIHBhcnNlci5wcmVwZW5kKCc8LycgKyB0b2sudGFnTmFtZSArICc+Jyk7XG5cdFx0fVxuXHRcblx0XHQvKipcblx0XHQgKiBDcmVhdGUgYSBuZXcgdG9rZW4gc3RhY2suXG5cdFx0ICpcblx0XHQgKiBAcmV0dXJucyB7QXJyYXk8VG9rZW4+fVxuXHRcdCAqL1xuXHRcdGZ1bmN0aW9uIG5ld1N0YWNrKCkge1xuXHRcdCAgdmFyIHN0YWNrID0gW107XG5cdFxuXHRcdCAgc3RhY2subGFzdCA9IGZ1bmN0aW9uICgpIHtcblx0XHQgICAgcmV0dXJuIHRoaXNbdGhpcy5sZW5ndGggLSAxXTtcblx0XHQgIH07XG5cdFxuXHRcdCAgc3RhY2subGFzdFRhZ05hbWVFcSA9IGZ1bmN0aW9uICh0YWdOYW1lKSB7XG5cdFx0ICAgIHZhciBsYXN0ID0gdGhpcy5sYXN0KCk7XG5cdFx0ICAgIHJldHVybi
1BsYXN0ICYmIGxhc3QudGFnTmFtZSAmJiBsYXN0LnRhZ05hbWUudG9VcHBlckNhc2UoKSA9PT0gdGFnTmFtZS50b1VwcGVyQ2FzZSgpO1xuXHRcdCAgfTtcblx0XG5cdFx0ICBzdGFjay5jb250YWluc1RhZ05hbWUgPSBmdW5jdGlvbiAodGFnTmFtZSkge1xuXHRcdCAgICBmb3IgKHZhciBpID0gMCwgdG9rOyB0b2sgPSB0aGlzW2ldOyBpKyspIHtcblx0XHQgICAgICBpZiAodG9rLnRhZ05hbWUgPT09IHRhZ05hbWUpIHtcblx0XHQgICAgICAgIHJldHVybiB0cnVlO1xuXHRcdCAgICAgIH1cblx0XHQgICAgfVxuXHRcdCAgICByZXR1cm4gZmFsc2U7XG5cdFx0ICB9O1xuXHRcblx0XHQgIHJldHVybiBzdGFjaztcblx0XHR9XG5cdFxuXHRcdC8qKlxuXHRcdCAqIFJldHVybiBhIHJlYWRUb2tlbiBpbXBsZW1lbnRhdGlvbiB0aGF0IGZpeGVzIGlucHV0LlxuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtIdG1sUGFyc2VyfSBwYXJzZXIgVGhlIHBhcnNlclxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIE9wdGlvbnMgZm9yIGZpeGluZ1xuXHRcdCAqIEBwYXJhbSB7Ym9vbGVhbn0gb3B0aW9ucy50YWdTb3VwRml4IFRydWUgdG8gZml4IHRhZyBzb3VwIHNjZW5hcmlvc1xuXHRcdCAqIEBwYXJhbSB7Ym9vbGVhbn0gb3B0aW9ucy5zZWxmQ2xvc2VGaXggVHJ1ZSB0byBmaXggc2VsZi1jbG9zaW5nIHRhZ3Ncblx0XHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWFkVG9rZW5JbXBsIFRoZSB1bmRlcmx5aW5nIHJlYWRUb2tlbiBpbXBsZW1lbnRhdGlvblxuXHRcdCAqIEByZXR1cm5zIHtGdW5jdGlvbn1cblx0XHQgKi9cblx0XHRmdW5jdGlvbiBmaXhlZFJlYWRUb2tlbkZhY3RvcnkocGFyc2VyLCBvcHRpb25zLCByZWFkVG9rZW5JbXBsKSB7XG5cdFx0ICB2YXIgc3RhY2sgPSBuZXdTdGFjaygpO1xuXHRcblx0XHQgIHZhciBoYW5kbGVycyA9IHtcblx0XHQgICAgc3RhcnRUYWc6IGZ1bmN0aW9uIHN0YXJ0VGFnKHRvaykge1xuXHRcdCAgICAgIHZhciB0YWdOYW1lID0gdG9rLnRhZ05hbWU7XG5cdFxuXHRcdCAgICAgIGlmICh0YWdOYW1lLnRvVXBwZXJDYXNlKCkgPT09ICdUUicgJiYgc3RhY2subGFzdFRhZ05hbWVFcSgnVEFCTEUnKSkge1xuXHRcdCAgICAgICAgcGFyc2VyLnByZXBlbmQoJzxUQk9EWT4nKTtcblx0XHQgICAgICAgIHByZXBhcmVOZXh0VG9rZW4oKTtcblx0XHQgICAgICB9IGVsc2UgaWYgKG9wdGlvbnMuc2VsZkNsb3NlRml4ICYmIENMT1NFU0VMRi50ZXN0KHRhZ05hbWUpICYmIHN0YWNrLmNvbnRhaW5zVGFnTmFtZSh0YWdOYW1lKSkge1xuXHRcdCAgICAgICAgaWYgKHN0YWNrLmxhc3RUYWdOYW1lRXEodGFnTmFtZSkpIHtcblx0XHQgICAgICAgICAgY2xvc2VMYXN0KHBhcnNlciwgc3RhY2spO1xuXHRcdCAgICAgICAgfSBlbHNlIHtcblx0XHQgICAgICAgICAgcGFyc2VyLnByZXBlbmQoJzwvJyArIHRvay50YWdOYW1lICsgJz4nKTtcblx0XHQgICAgICAgICAgcHJlcGFyZU5leHRUb2tlbigpO1xuXHRcdCAgICAgICAgfVxuXHRcdCAgICAgIH0gZWxzZSBpZiAoIXRvay51bmFyeSkge1xuXHRcdCAgICAgICAgc3RhY2sucHVzaCh0b2spO1xuXHRcdCAgICAgIH1cblx0XHQgICAgfSxcblx0XHQgICAgZW5kVGFnOiBmdW5jdGlvbiBlbmRUYWcodG9rKSB7XG5cdFx0ICAgICAgdmFyIGxhc3QgPSBzdGFjay5sYXN0KCk7XG5cdFx0ICAgICAgaWYgKGxhc3QpIHtcblx0XHQgICAgICAgIGlmIChvcHRpb25zLnRhZ1NvdXBGaXggJiYgIXN0YWNrLmxhc3RUYWdOYW1lRXEodG9rLnRhZ05hbWUpKSB7XG5cdFx0ICAgICAgICAgIC8vIGNsZWFudXAgdGFnIHNvdXBcblx0XHQgICAgICAgICAgY2xvc2VMYXN0KHBhcnNlciwgc3RhY2spO1xuXHRcdCAgICAgICAgfSBlbHNlIHtcblx0XHQgICAgICAgICAgc3RhY2sucG9wKCk7XG5cdFx0ICAgICAgICB9XG5cdFx0ICAgICAgfSBlbHNlIGlmIChvcHRpb25zLnRhZ1NvdXBGaXgpIHtcblx0XHQgICAgICAgIC8vIGNsZWFudXAgdGFnIHNvdXAgcGFydCAyOiBza2lwIHRoaXMgdG9rZW5cblx0XHQgICAgICAgIHJlYWRUb2tlbkltcGwoKTtcblx0XHQgICAgICAgIHByZXBhcmVOZXh0VG9rZW4oKTtcblx0XHQgICAgICB9XG5cdFx0ICAgIH1cblx0XHQgIH07XG5cdFxuXHRcdCAgZnVuY3Rpb24gcHJlcGFyZU5leHRUb2tlbigpIHtcblx0XHQgICAgdmFyIHRvayA9IHBlZWtUb2tlbihwYXJzZXIsIHJlYWRUb2tlbkltcGwpO1xuXHRcdCAgICBpZiAodG9rICYmIGhhbmRsZXJzW3Rvay50eXBlXSkge1xuXHRcdCAgICAgIGhhbmRsZXJzW3Rvay50eXBlXSh0b2spO1xuXHRcdCAgICB9XG5cdFx0ICB9XG5cdFxuXHRcdCAgcmV0dXJuIGZ1bmN0aW9uIGZpeGVkUmVhZFRva2VuKCkge1xuXHRcdCAgICBwcmVwYXJlTmV4dFRva2VuKCk7XG5cdFx0ICAgIHJldHVybiBjb3JyZWN0KHJlYWRUb2tlbkltcGwoKSk7XG5cdFx0ICB9O1xuXHRcdH1cblx0XG5cdC8qKiovIH1cblx0LyoqKioqKi8gXSlcblx0fSk7XG5cdDtcblxuLyoqKi8gfSxcbi8qIDQgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5cdCd1c2Ugc3RyaWN0Jztcblx0XG5cdGV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cdFxuXHR2YXIgX3R5cGVvZiA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcInN5bWJvbFwiID8gZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gdHlwZW9mIG9iajsgfSA6IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTtcblx0XG5cdGV4cG9ydHMuZXhpc3R5ID0gZXhpc3R5O1xuXHRleHBvcnRzLmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uO1xuXHRleHBvcnRzLmVhY2ggPSBlYWNoO1xuXHRleHBvcnRzLmVhY2hLZXkgPSBlYWNoS2V5O1xuXHRleHBvcnRzLmRlZmF1bHRzID0gZGVmYXVsdHM7XG5cdGV4cG9ydHMudG9BcnJheSA9IHRvQXJyYXk7XG5cdGV4cG9ydHMubGFzdCA9IGxhc3Q7XG5cdGV4cG9ydHMuaXNUYWcgPSBpc1RhZztcblx0ZXhwb3J0cy5pc1NjcmlwdCA9IGlzU2NyaXB0O1xuXHRleHBvcnRzLmlzU3R5bGUgPSBpc1N0eWxlO1xuXHQvKipcblx0ICogRGV0ZXJtaW5lIGlmIHRoZSB0aGluZyBpcyBub3QgdW5kZWZpbmVkIGFuZCBub3QgbnVsbC5cblx0ICpcblx0ICogQHBhcmFtIHsqfSB0aGluZyBUaGUgdGhpbmcgdG8gdGVzdFxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgdGhpbmcgaXMgbm90IHVuZGVmaW5lZCBhbmQgbm90IG51bGwuXG5cdCAqL1xuXHRmdW5jdGlvbiBleGlzdHkodGhpbmcpIHtcblx0ICByZXR1cm4gdGhpbmcgIT09IHZvaWQgMCAmJiB0aGluZyAhPT0gbnVsbDtcblx0fVxuXHRcblx0LyoqXG5cdCAqIElzIHRoaXMgYSBmdW5jdGlvbj9cblx0ICpcblx0ICogQHBhcmFtIHsqfSB4IFRoZSB2YXJpYWJsZSB0byB0ZXN0XG5cdCAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB2YXJpYWJsZSBpcyBhIGZ1bmN0aW9uXG5cdCAqL1xuXHRmdW5jdGlvbiBpc0Z1bmN0aW9uKHgpIHtcblx0ICByZXR1cm4gJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIHg7XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBMb29wIG92ZXIgZWFjaCBpdGVtIGluIGFuIGFycmF5LWxpa2UgdmFsdWUuXG5cdCAqXG5cdCAqIEBwYXJhbSB7QXJyYXk8Kj59IGFyciBUaGUgYXJyYXkgdG8gbG9vcCBvdmVyXG5cdCAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBjYWxsXG5cdCAqIEBwYXJhbSB7P09iamVjdH0gdGFyZ2V0IFRoZSBvYmplY3QgdG8gYmluZCB0byB0aGUgZnVuY3Rpb25cblx0ICovXG5cdGZ1bmN0aW9uIGVhY2goYXJyLCBmbiwgdGFyZ2V0KSB7XG5cdCAgdmFyIGkgPSB2b2lkIDA7XG5cdCAgdmFyIGxlbiA9IGFyciAmJiBhcnIubGVuZ3RoIHx8IDA7XG5cdCAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG5cdCAgICBmbi5jYWxsKHRhcmdldCwgYXJyW2ldLCBpKTtcblx0ICB9XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBMb29wIG92ZXIgZWFjaCBrZXkvdmFsdWUgcGFpciBpbiBhIGhhc2guXG5cdCAqXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBvYmogVGhlIG9iamVjdFxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gY2FsbFxuXHQgKiBAcGFyYW0gez9PYmplY3R9IHRhcmdldCBUaGUgb2JqZWN0IHRvIGJpbmQgdG8gdGhlIGZ1bmN0aW9uXG5cdCAqL1xuXHRmdW5jdGlvbiBlYWNoS2V5KG9iaiwgZm4sIHRhcmdldCkge1xuXHQgIGZvciAodmFyIGtleSBpbiBvYmopIHtcblx0ICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoa2V5KSkge1xuXHQgICAgICBmbi5jYWxsKHRhcmdldCwga2V5LCBvYmpba2V5XSk7XG5cdCAgICB9XG5cdCAgfVxuXHR9XG5cdFxuXHQvKipcblx0ICogU2V0IGRlZmF1bHQgb3B0aW9ucyB3aGVyZSBzb21lIG9wdGlvbiB3YXMgbm90IHNwZWNpZmllZC5cblx0ICpcblx0ICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgVGhlIGRlc3RpbmF0aW9uXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBfZGVmYXVsdHMgVGhlIGRlZmF1bHRzXG5cdCAqIEByZXR1cm5zIHtPYmplY3R9XG5cdCAqL1xuXHRmdW5jdGlvbiBkZWZh
1dWx0cyhvcHRpb25zLCBfZGVmYXVsdHMpIHtcblx0ICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblx0ICBlYWNoS2V5KF9kZWZhdWx0cywgZnVuY3Rpb24gKGtleSwgdmFsKSB7XG5cdCAgICBpZiAoIWV4aXN0eShvcHRpb25zW2tleV0pKSB7XG5cdCAgICAgIG9wdGlvbnNba2V5XSA9IHZhbDtcblx0ICAgIH1cblx0ICB9KTtcblx0ICByZXR1cm4gb3B0aW9ucztcblx0fVxuXHRcblx0LyoqXG5cdCAqIENvbnZlcnQgdmFsdWUgKGUuZy4sIGEgTm9kZUxpc3QpIHRvIGFuIGFycmF5LlxuXHQgKlxuXHQgKiBAcGFyYW0geyp9IG9iaiBUaGUgb2JqZWN0XG5cdCAqIEByZXR1cm5zIHtBcnJheTwqPn1cblx0ICovXG5cdGZ1bmN0aW9uIHRvQXJyYXkob2JqKSB7XG5cdCAgdHJ5IHtcblx0ICAgIHJldHVybiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChvYmopO1xuXHQgIH0gY2F0Y2ggKGUpIHtcblx0ICAgIHZhciBfcmV0ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICB2YXIgcmV0ID0gW107XG5cdCAgICAgIGVhY2gob2JqLCBmdW5jdGlvbiAodmFsKSB7XG5cdCAgICAgICAgcmV0LnB1c2godmFsKTtcblx0ICAgICAgfSk7XG5cdCAgICAgIHJldHVybiB7XG5cdCAgICAgICAgdjogcmV0XG5cdCAgICAgIH07XG5cdCAgICB9KCk7XG5cdFxuXHQgICAgaWYgKCh0eXBlb2YgX3JldCA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2YoX3JldCkpID09PSBcIm9iamVjdFwiKSByZXR1cm4gX3JldC52O1xuXHQgIH1cblx0fVxuXHRcblx0LyoqXG5cdCAqIEdldCB0aGUgbGFzdCBpdGVtIGluIGFuIGFycmF5XG5cdCAqXG5cdCAqIEBwYXJhbSB7QXJyYXk8Kj59IGFycmF5IFRoZSBhcnJheVxuXHQgKiBAcmV0dXJucyB7Kn0gVGhlIGxhc3QgaXRlbSBpbiB0aGUgYXJyYXlcblx0ICovXG5cdGZ1bmN0aW9uIGxhc3QoYXJyYXkpIHtcblx0ICByZXR1cm4gYXJyYXlbYXJyYXkubGVuZ3RoIC0gMV07XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBUZXN0IGlmIHRva2VuIGlzIGEgc2NyaXB0IHRhZy5cblx0ICpcblx0ICogQHBhcmFtIHtPYmplY3R9IHRvayBUaGUgdG9rZW5cblx0ICogQHBhcmFtIHtTdHJpbmd9IHRhZyBUaGUgdGFnIG5hbWVcblx0ICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHRva2VuIGlzIGEgc2NyaXB0IHRhZ1xuXHQgKi9cblx0ZnVuY3Rpb24gaXNUYWcodG9rLCB0YWcpIHtcblx0ICByZXR1cm4gIXRvayB8fCAhKHRvay50eXBlID09PSAnc3RhcnRUYWcnIHx8IHRvay50eXBlID09PSAnYXRvbWljVGFnJykgfHwgISgndGFnTmFtZScgaW4gdG9rKSA/ICExIDogISEgfnRvay50YWdOYW1lLnRvTG93ZXJDYXNlKCkuaW5kZXhPZih0YWcpO1xuXHR9XG5cdFxuXHQvKipcblx0ICogVGVzdCBpZiB0b2tlbiBpcyBhIHNjcmlwdCB0YWcuXG5cdCAqXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSB0b2sgVGhlIHRva2VuXG5cdCAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB0b2tlbiBpcyBhIHNjcmlwdCB0YWdcblx0ICovXG5cdGZ1bmN0aW9uIGlzU2NyaXB0KHRvaykge1xuXHQgIHJldHVybiBpc1RhZyh0b2ssICdzY3JpcHQnKTtcblx0fVxuXHRcblx0LyoqXG5cdCAqIFRlc3QgaWYgdG9rZW4gaXMgYSBzdHlsZSB0YWcuXG5cdCAqXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSB0b2sgVGhlIHRva2VuXG5cdCAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB0b2tlbiBpcyBhIHN0eWxlIHRhZ1xuXHQgKi9cblx0ZnVuY3Rpb24gaXNTdHlsZSh0b2spIHtcblx0ICByZXR1cm4gaXNUYWcodG9rLCAnc3R5bGUnKTtcblx0fVxuXG4vKioqLyB9XG4vKioqKioqLyBdKVxufSk7XG47XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wb3N0c2NyaWJlLmpzLm1hcCJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUVBO0FBRUE7QUFFQTtBQUVBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUVBO0FBRUE7QUFFQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBUUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFFQTtBQUVBO0FBRUE7QUFFQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFHQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///156\n")},782:function(module){eval('/**\n * @file postscribe\n * @description Asynchronously write javascript, even with document.write.\n * @version v2.0.8\n * @see {@link https://krux.github.io/postscribe}\n * @license MIT\n * @author Derek Brans\n * @copyright 2016 Krux Digital, Inc\n */\n!function (t, e) {\n true ? module.exports = e() : 0;\n}(this, function () {\n return function (t) {\n function e(n) {\
1n if (r[n]) return r[n].exports;\n var o = r[n] = {\n "exports": {},\n "id": n,\n "loaded": !1\n };\n return t[n].call(o.exports, o, o.exports, e), o.loaded = !0, o.exports;\n }\n var r = {};\n return e.m = t, e.c = r, e.p = "", e(0);\n }([function (t, e, r) {\n "use strict";\n\n function n(t) {\n return t && t.__esModule ? t : {\n "default": t\n };\n }\n var o = r(1),\n i = n(o);\n t.exports = i["default"];\n }, function (t, e, r) {\n "use strict";\n\n function n(t) {\n if (t && t.__esModule) return t;\n var e = {};\n if (null != t) for (var r in t) Object.prototype.hasOwnProperty.call(t, r) && (e[r] = t[r]);\n return e["default"] = t, e;\n }\n function o(t) {\n return t && t.__esModule ? t : {\n "default": t\n };\n }\n function i() {}\n function a() {\n var t = m.shift();\n if (t) {\n var e = h.last(t);\n e.afterDequeue(), t.stream = s.apply(void 0, t), e.afterStreamStart();\n }\n }\n function s(t, e, r) {\n function n(t) {\n t = r.beforeWrite(t), g.write(t), r.afterWrite(t);\n }\n g = new p["default"](t, r), g.id = y++, g.name = r.name || g.id, u.streams[g.name] = g;\n var o = t.ownerDocument,\n s = {\n "close": o.close,\n "open": o.open,\n "write": o.write,\n "writeln": o.writeln\n };\n c(o, {\n "close": i,\n "open": i,\n "write": function () {\n for (var t = arguments.length, e = Array(t), r = 0; r < t; r++) e[r] = arguments[r];\n return n(e.join(""));\n },\n "writeln": function () {\n for (var t = arguments.length, e = Array(t), r = 0; r < t; r++) e[r] = arguments[r];\n return n(e.join("") + "\\n");\n }\n });\n var l = g.win.onerror || i;\n return g.win.onerror = function (t, e, n) {\n r.error({\n "msg": t + " - " + e + ": " + n\n }), l.apply(g.win, [t, e, n]);\n }, g.write(e, function () {\n c(o, s), g.win.onerror = l, r.done(), g = null, a();\n }), g;\n }\n function u(t, e, r) {\n if (h.isFunction(r)) r = {\n "done": r\n };else if ("clear" === r) return m = [], g = null, void (y = 0);\n r = h.defaults(r, d), t = /^#/.test(t) ? window.document.getElementById(t.substr(1)) : t.jquery ? t[0] : t;\n var n = [t, e, r];\n return t.postscribe = {\n "cancel": function () {\n n.stream ? n.stream.abort() : n[1] = i;\n }\n }, r.beforeEnqueue(n), m.push(n), g || a(), t.postscribe;\n }\n e.__esModule = !0;\n var c = Object.assign || function (t) {\n for (var e = 1; e < arguments.length; e++) {\n var r = arguments[e];\n for (var n in r) Object.prototype.hasOwnProperty.call(r, n) && (t[n] = r[n]);\n }\n return t;\n };\n e["default"] = u;\n var l = r(2),\n p = o(l),\n f = r(4),\n h = n(f),\n d = {\n "afterAsync": i,\n "afterDequeue": i,\n "afterStreamStart": i,\n "afterWrite": i,\n "autoFix": !0,\n "beforeEnqueue": i,\n "beforeWriteToken": function (t) {\n return t;\n },\n "beforeWrite": function (t) {\n return t;\n },\n "done": i,\n "error": function (t) {\n throw new Error(t.msg);\n },\n "releaseAsync": !1\n },\n y = 0,\n m = [],\n g = null;\n c(u, {\n "streams": {},\n "queue": m,\n "WriteStream": p["default"]\n });\n }, function (t, e, r) {\n "use strict";\n\n function n(t) {\n if (t && t.__esModule) return t;\n var e = {};\n if (null != t) for (var r in t) Object.prototype.hasOwnProperty.call(t, r) && (e[r] = t[r]);\n return e["default"] = t, e;\n }\n function o(t) {\n return t && t.__esModule ? t : {\n "default": t\n };\n }\n function i(t, e) {\n if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function");\n }\n function a(t, e) {\n var r = d + e,\n n = t.getAttribute(r);\n return f.existy(n) ? String(n) : n;\n }\n function s(t, e) {\n var r = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : null,\n n = d + e;\n f.existy(r) && "" !== r ? t.setAttribute(n, r) : t.removeAttribute(n);\n }
1\n e.__esModule = !0;\n var u = Object.assign || function (t) {\n for (var e = 1; e < arguments.length; e++) {\n var r = arguments[e];\n for (var n in r) Object.prototype.hasOwnProperty.call(r, n) && (t[n] = r[n]);\n }\n return t;\n },\n c = r(3),\n l = o(c),\n p = r(4),\n f = n(p),\n h = !1,\n d = "data-ps-",\n y = "ps-style",\n m = "ps-script",\n g = function () {\n function t(e) {\n var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {};\n i(this, t), this.root = e, this.options = r, this.doc = e.ownerDocument, this.win = this.doc.defaultView || this.doc.parentWindow, this.parser = new l["default"]("", {\n "autoFix": r.autoFix\n }), this.actuals = [e], this.proxyHistory = "", this.proxyRoot = this.doc.createElement(e.nodeName), this.scriptStack = [], this.writeQueue = [], s(this.proxyRoot, "proxyof", 0);\n }\n return t.prototype.write = function () {\n var t;\n for ((t = this.writeQueue).push.apply(t, arguments); !this.deferredRemote && this.writeQueue.length;) {\n var e = this.writeQueue.shift();\n f.isFunction(e) ? this._callFunction(e) : this._writeImpl(e);\n }\n }, t.prototype._callFunction = function (t) {\n var e = {\n "type": "function",\n "value": t.name || t.toString()\n };\n this._onScriptStart(e), t.call(this.win, this.doc), this._onScriptDone(e);\n }, t.prototype._writeImpl = function (t) {\n this.parser.append(t);\n for (var e = void 0, r = void 0, n = void 0, o = []; (e = this.parser.readToken()) && !(r = f.isScript(e)) && !(n = f.isStyle(e));) e = this.options.beforeWriteToken(e), e && o.push(e);\n o.length > 0 && this._writeStaticTokens(o), r && this._handleScriptToken(e), n && this._handleStyleToken(e);\n }, t.prototype._writeStaticTokens = function (t) {\n var e = this._buildChunk(t);\n return e.actual ? (e.html = this.proxyHistory + e.actual, this.proxyHistory += e.proxy, this.proxyRoot.innerHTML = e.html, h && (e.proxyInnerHTML = this.proxyRoot.innerHTML), this._walkChunk(), h && (e.actualInnerHTML = this.root.innerHTML), e) : null;\n }, t.prototype._buildChunk = function (t) {\n for (var e = this.actuals.length, r = [], n = [], o = [], i = t.length, a = 0; a < i; a++) {\n var s = t[a],\n u = s.toString();\n if (r.push(u), s.attrs) {\n if (!/^noscript$/i.test(s.tagName)) {\n var c = e++;\n n.push(u.replace(/(\\/?>)/, " " + d + "id=" + c + " $1")), s.attrs.id !== m && s.attrs.id !== y && o.push("atomicTag" === s.type ? "" : "<" + s.tagName + " " + d + "proxyof=" + c + (s.unary ? " />" : ">"));\n }\n } else n.push(u), o.push("endTag" === s.type ? u : "");\n }\n return {\n "tokens": t,\n "raw": r.join(""),\n "actual": n.join(""),\n "proxy": o.join("")\n };\n }, t.prototype._walkChunk = function () {\n for (var t = void 0, e = [this.proxyRoot]; f.existy(t = e.shift());) {\n var r = 1 === t.nodeType,\n n = r && a(t, "proxyof");\n if (!n) {\n r && (this.actuals[a(t, "id")] = t, s(t, "id"));\n var o = t.parentNode && a(t.parentNode, "proxyof");\n o && this.actuals[o].appendChild(t);\n }\n e.unshift.apply(e, f.toArray(t.childNodes));\n }\n }, t.prototype._handleScriptToken = function (t) {\n var e = this,\n r = this.parser.clear();\n r && this.writeQueue.unshift(r), t.src = t.attrs.src || t.attrs.SRC, t = this.options.beforeWriteToken(t), t && (t.src && this.scriptStack.length ? this.deferredRemote = t : this._onScriptStart(t), this._writeScriptToken(t, function () {\n e._onScriptDone(t);\n }));\n }, t.prototype._handleStyleToken = function (t) {\n var e = this.parser.clear();\n e && this.writeQueue.unshift(e), t.type = t.attrs.type || t.attrs.TYPE || "text/css", t = this.options.beforeWriteToken(t), t && this._writeStyleToken(t), e && this.write();\n }, t.prototype._writeStyleToken = function (t) {\n var e = this._buildStyle(t);\n this._insertCursor(e, y), t.content && (e.styleSheet && !e.sheet ? e.styleSheet.cssText = t.content : e.appendChild(this.doc.createTextNode(t.content)));\n }, t.prototype._buildStyle = function (t) {\n var e = this.doc.createElement(t.tagName);\n return e.setAttribute("type", t.type), f.eachKey(t.attrs, function (t, r) {\n e.setAttribute(t, r);\n }), e;\n }, t.prototype._insertCursor = function (t, e) {\n this._writeImpl(\'<span id="\' + e + \'"/>\');\n var r = this.doc.getElementById(e);\n r && r.parentNode.replaceChild(t, r);\n }, t.prototype._onScriptStart = function (t) {\n t.outerWrites = this.writeQueue, this.writeQueue = [], this.scriptStack.unshift(t);\n }, t.prototype._onScriptDone = function (t) {\n return t !== this.scriptStack[0] ? void this.options.error({\n "msg": "Bad script nesting or script finished twice"\n }) : (this.scriptStack.shift(), this.write.apply(this, t.outerWrites), void (!this.scriptStack.length && this.deferredRemote && (this._onScriptStart(this.deferredRemote), this.deferredRemote = null)));\n }, t.prototype._writeScriptToken = function (t, e) {\n var r = this._buildScript(t),\n n = this._shouldRelease(r),\n o = this.options.afterAsync;\n t.src && (r.src = t.src, this._scriptLoadHandler(r, n ? o : function () {\n e(), o();\n }));\n try {\n this._insertCursor(r, m), r.src && !n || e();\n } catch (t) {\n this.options.error(t), e();\n }\n }, t.prototype._buildScript = function (t) {\n var e = this.doc.createElement(t.tagName);\n return f.eachKey(t.attrs, function (t, r) {\n e.setAttribute(t, r);\n }), t.content && (e.text = t.content), e;\n }, t.prototype._scriptLoadHandler = function (t, e) {\n function r() {\n t = t.onload = t.onreadystatechange = t.onerror = null;\n }\n function n() {\n r(), null != e && e(), e = null;\n }\n function o(t) {\n r(), a(t), null != e && e(), e = null;\n }\n function i(t, e) {\n var r = t["on" + e];\n null != r && (t["_on" + e] = r);\n }\n var a = this.options.error;\n i(t, "load"), i(t, "error"), u(t, {\n "onload": function () {\n if (t._onload) try {\n t._onload.apply(this, Array.prototype.slice.call(arguments, 0));\n } catch (e) {\n o({\n "msg": "onload handler failed " + e + " @ " + t.src\n });\n }\n n();\n },\n "onerror": function () {\n if (t._onerror) try {\n t._onerror.apply(this, Array.prototype.slice.call(arguments, 0));\n } catch (e) {\n return void o({\n "msg": "onerror handler failed " + e + " @ " + t.src\n });\n }\n o({\n "msg": "remote script failed " + t.src\n });\n },\n "onreadystatechange": function () {\n /^(loaded|complete)$/.test(t.readyState) && n();\n }\n });\n }, t.prototype._shouldRelease = function (t) {\n var e = /^script$/i.test(t.no
1deName);\n return !e || !!(this.options.releaseAsync && t.src && t.hasAttribute("async"));\n }, t;\n }();\n e["default"] = g;\n }, function (t, e, r) {\n !function (e, r) {\n t.exports = r();\n }(this, function () {\n return function (t) {\n function e(n) {\n if (r[n]) return r[n].exports;\n var o = r[n] = {\n "exports": {},\n "id": n,\n "loaded": !1\n };\n return t[n].call(o.exports, o, o.exports, e), o.loaded = !0, o.exports;\n }\n var r = {};\n return e.m = t, e.c = r, e.p = "", e(0);\n }([function (t, e, r) {\n "use strict";\n\n function n(t) {\n return t && t.__esModule ? t : {\n "default": t\n };\n }\n var o = r(1),\n i = n(o);\n t.exports = i["default"];\n }, function (t, e, r) {\n "use strict";\n\n function n(t) {\n return t && t.__esModule ? t : {\n "default": t\n };\n }\n function o(t) {\n if (t && t.__esModule) return t;\n var e = {};\n if (null != t) for (var r in t) Object.prototype.hasOwnProperty.call(t, r) && (e[r] = t[r]);\n return e["default"] = t, e;\n }\n function i(t, e) {\n if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function");\n }\n e.__esModule = !0;\n var a = r(2),\n s = o(a),\n u = r(3),\n c = o(u),\n l = r(6),\n p = n(l),\n f = r(5),\n h = {\n "comment": /^\x3c!--/,\n "endTag": /^<\\//,\n "atomicTag": /^<\\s*(script|style|noscript|iframe|textarea)[\\s\\/>]/i,\n "startTag": /^</,\n "chars": /^[^<]/\n },\n d = function () {\n function t() {\n var e = this,\n r = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "",\n n = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {};\n i(this, t), this.stream = r;\n var o = !1,\n a = {};\n for (var u in s) s.hasOwnProperty(u) && (n.autoFix && (a[u + "Fix"] = !0), o = o || a[u + "Fix"]);\n o ? (this._readToken = (0, p["default"])(this, a, function () {\n return e._readTokenImpl();\n }), this._peekToken = (0, p["default"])(this, a, function () {\n return e._peekTokenImpl();\n })) : (this._readToken = this._readTokenImpl, this._peekToken = this._peekTokenImpl);\n }\n return t.prototype.append = function (t) {\n this.stream += t;\n }, t.prototype.prepend = function (t) {\n this.stream = t + this.stream;\n }, t.prototype._readTokenImpl = function () {\n var t = this._peekTokenImpl();\n if (t) return this.stream = this.stream.slice(t.length), t;\n }, t.prototype._peekTokenImpl = function () {\n for (var t in h) if (h.hasOwnProperty(t) && h[t].test(this.stream)) {\n var e = c[t](this.stream);\n if (e) return "startTag" === e.type && /script|style/i.test(e.tagName) ? null : (e.text = this.stream.substr(0, e.length), e);\n }\n }, t.prototype.peekToken = function () {\n return this._peekToken();\n }, t.prototype.readToken = function () {\n return this._readToken();\n }, t.prototype.readTokens = function (t) {\n for (var e = void 0; e = this.readToken();) if (t[e.type] && t[e.type](e) === !1) return;\n }, t.prototype.clear = function () {\n var t = this.stream;\n return this.stream = "", t;\n }, t.prototype.rest = function () {\n return this.stream;\n }, t;\n }();\n e["default"] = d, d.tokenToString = function (t) {\n return t.toString();\n }, d.escapeAttributes = function (t) {\n var e = {};\n for (var r in t) t.hasOwnProperty(r) && (e[r] = (0, f.escapeQuotes)(t[r], null));\n return e;\n }, d.supports = s;\n for (var y in s) s.hasOwnProperty(y) && (d.browserHasFlaw = d.browserHasFlaw || !s[y] && y);\n }, function (t, e) {\n "use strict";
1\n\n e.__esModule = !0;\n var r = !1,\n n = !1,\n o = window.document.createElement("div");\n try {\n var i = "<P><I></P></I>";\n o.innerHTML = i, e.tagSoup = r = o.innerHTML !== i;\n } catch (t) {\n e.tagSoup = r = !1;\n }\n try {\n o.innerHTML = "<P><i><P></P></i></P>", e.selfClose = n = 2 === o.childNodes.length;\n } catch (t) {\n e.selfClose = n = !1;\n }\n o = null, e.tagSoup = r, e.selfClose = n;\n }, function (t, e, r) {\n "use strict";\n\n function n(t) {\n var e = t.indexOf("--\x3e");\n if (e >= 0) return new c.CommentToken(t.substr(4, e - 1), e + 3);\n }\n function o(t) {\n var e = t.indexOf("<");\n return new c.CharsToken(e >= 0 ? e : t.length);\n }\n function i(t) {\n var e = t.indexOf(">");\n if (e !== -1) {\n var r = t.match(l.startTag);\n if (r) {\n var n = function () {\n var t = {},\n e = {},\n n = r[2];\n return r[2].replace(l.attr, function (r, o) {\n arguments[2] || arguments[3] || arguments[4] || arguments[5] ? arguments[5] ? (t[arguments[5]] = "", e[arguments[5]] = !0) : t[o] = arguments[2] || arguments[3] || arguments[4] || l.fillAttr.test(o) && o || "" : t[o] = "", n = n.replace(r, "");\n }), {\n "v": new c.StartTagToken(r[1], r[0].length, t, e, !!r[3], n.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, ""))\n };\n }();\n if ("object" === ("undefined" == typeof n ? "undefined" : u(n))) return n.v;\n }\n }\n }\n function a(t) {\n var e = i(t);\n if (e) {\n var r = t.slice(e.length);\n if (r.match(new RegExp("</\\\\s*" + e.tagName + "\\\\s*>", "i"))) {\n var n = r.match(new RegExp("([\\\\s\\\\S]*?)</\\\\s*" + e.tagName + "\\\\s*>", "i"));\n if (n) return new c.AtomicTagToken(e.tagName, n[0].length + e.length, e.attrs, e.booleanAttrs, n[1]);\n }\n }\n }\n function s(t) {\n var e = t.match(l.endTag);\n if (e) return new c.EndTagToken(e[1], e[0].length);\n }\n e.__esModule = !0;\n var u = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (t) {\n return typeof t;\n } : function (t) {\n return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t;\n };\n e.comment = n, e.chars = o, e.startTag = i, e.atomicTag = a, e.endTag = s;\n var c = r(4),\n l = {\n "startTag": /^<([\\-A-Za-z0-9_]+)((?:\\s+[\\w\\-]+(?:\\s*=?\\s*(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>\\s]+))?)*)\\s*(\\/?)>/,\n "endTag": /^<\\/([\\-A-Za-z0-9_]+)[^>]*>/,\n "attr": /(?:([\\-A-Za-z0-9_]+)\\s*=\\s*(?:(?:"((?:\\\\.|[^"])*)")|(?:\'((?:\\\\.|[^\'])*)\')|([^>\\s]+)))|(?:([\\-A-Za-z0-9_]+)(\\s|$)+)/g,\n "fillAttr": /^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noresize|noshade|nowrap|readonly|selected)$/i\n };\n }, function (t, e, r) {\n "use strict";\n\n function n(t, e) {\n if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function");\n }\n e.__esModule = !0, e.EndTagToken = e.AtomicTagToken = e.StartTagToken = e.TagToken = e.CharsToken = e.CommentToken = e.Token = void 0;\n var o = r(5),\n i = (e.Token = function t(e, r) {\n n(this, t), this.type = e, this.length = r, this.text = "";\n }, e.CommentToken = function () {\n function t(e, r) {\n n(this, t), this.type = "comment", this.length = r || (e ? e.length : 0), this.text = "", this.content = e;\n }\n return t.prototype.toString = function () {\n return "\x3c!--" + this.content;\n }, t;\n }(), e.CharsToken = function () {\n function t(e) {\n n(this, t), this.type = "chars", this.length = e, this.text = "";\n }\n return t.prototype.toString = function () {\n return this.text;\n }, t;\n }(), e.TagToken = function () {\n function t(e, r, o, i, a) {\n n(this, t), this.type = e, this.length = o, this.text = "", this.tagName = r, this.attrs = i, this.booleanAttrs = a, this.unary = !1, this.html5Unary = !1;\n }\n return t.formatTag = function (t) {\n var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : null,\n r = "<" + t.tagName;\n for (var n in t.attrs) if (t.attrs.hasOwnProperty(n)) {\n r += " " + n;\n var i = t.attrs[n];\n "undefined" != typeof t.booleanAttrs && "undefined" != typeof t.booleanAttrs[n] || (r += \'="\' + (0, o.escapeQuotes)(i) + \'"\');\n }\n return t.rest && (r += " " + t.rest), r += t.unary && !t.html5Unary ? "/>" : ">", void 0 !== e && null !== e && (r += e + "</" + t.tagName + ">"), r;\n }, t;\n }());\n e.StartTagToken = function () {\n function t(e, r, o, i, a, s) {\n n(this, t), this.type = "startTag", this.length = r, this.text = "", this.tagName = e, this.attrs = o, this.booleanAttrs = i, this.html5Unary = !1, this.unary = a, this.rest = s;\n }\n return t.prototype.toString = function () {\n return i.formatTag(this);\n }, t;\n }(), e.AtomicTagToken = function () {\n function t(e, r, o, i, a) {\n n(this, t), this.type = "atomicTag", this.length = r, this.text = "", this.tagName = e, this.attrs = o, this.booleanAttrs = i, this.unary = !1, this.html5Unary = !1, this.content = a;\n }\n return t.prototype.toString = function () {\n return i.formatTag(this, this.content);\n }, t;\n }(), e.EndTagToken = function () {\n function t(e, r) {\n n(this, t), this.type = "endTag", this.length = r, this.text = "", this.tagName = e;\n }\n return t.prototype.toString = function () {\n return "</" + this.tagName + ">";\n }, t;\n }();\n }, function (t, e) {\n "use strict";\n\n function r(t) {\n var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : "";\n return t ? t.replace(/([^"]*)"/g, function (t, e) {\n return /\\\\/.test(e) ? e + \'"\' : e + \'\\\\"\';\n }) : e;
1\n }\n e.__esModule = !0, e.escapeQuotes = r;\n }, function (t, e) {\n "use strict";\n\n function r(t) {\n return t && "startTag" === t.type && (t.unary = s.test(t.tagName) || t.unary, t.html5Unary = !/\\/>$/.test(t.text)), t;\n }\n function n(t, e) {\n var n = t.stream,\n o = r(e());\n return t.stream = n, o;\n }\n function o(t, e) {\n var r = e.pop();\n t.prepend("</" + r.tagName + ">");\n }\n function i() {\n var t = [];\n return t.last = function () {\n return this[this.length - 1];\n }, t.lastTagNameEq = function (t) {\n var e = this.last();\n return e && e.tagName && e.tagName.toUpperCase() === t.toUpperCase();\n }, t.containsTagName = function (t) {\n for (var e, r = 0; e = this[r]; r++) if (e.tagName === t) return !0;\n return !1;\n }, t;\n }\n function a(t, e, a) {\n function s() {\n var e = n(t, a);\n e && l[e.type] && l[e.type](e);\n }\n var c = i(),\n l = {\n "startTag": function (r) {\n var n = r.tagName;\n "TR" === n.toUpperCase() && c.lastTagNameEq("TABLE") ? (t.prepend("<TBODY>"), s()) : e.selfCloseFix && u.test(n) && c.containsTagName(n) ? c.lastTagNameEq(n) ? o(t, c) : (t.prepend("</" + r.tagName + ">"), s()) : r.unary || c.push(r);\n },\n "endTag": function (r) {\n var n = c.last();\n n ? e.tagSoupFix && !c.lastTagNameEq(r.tagName) ? o(t, c) : c.pop() : e.tagSoupFix && (a(), s());\n }\n };\n return function () {\n return s(), r(a());\n };\n }\n e.__esModule = !0, e["default"] = a;\n var s = /^(AREA|BASE|BASEFONT|BR|COL|FRAME|HR|IMG|INPUT|ISINDEX|LINK|META|PARAM|EMBED)$/i,\n u = /^(COLGROUP|DD|DT|LI|OPTIONS|P|TD|TFOOT|TH|THEAD|TR)$/i;\n }]);\n });\n }, function (t, e) {\n "use strict";\n\n function r(t) {\n return void 0 !== t && null !== t;\n }\n function n(t) {\n return "function" == typeof t;\n }\n function o(t, e, r) {\n var n = void 0,\n o = t && t.length || 0;\n for (n = 0; n < o; n++) e.call(r, t[n], n);\n }\n function i(t, e, r) {\n for (var n in t) t.hasOwnProperty(n) && e.call(r, n, t[n]);\n }\n function a(t, e) {\n return t = t || {}, i(e, function (e, n) {\n r(t[e]) || (t[e] = n);\n }), t;\n }\n function s(t) {\n try {\n return Array.prototype.slice.call(t);\n } catch (r) {\n var e = function () {\n var e = [];\n return o(t, function (t) {\n e.push(t);\n }), {\n "v": e\n };\n }();\n if ("object" === ("undefined" == typeof e ? "undefined" : f(e))) return e.v;\n }\n }\n function u(t) {\n return t[t.length - 1];\n }\n function c(t, e) {\n return !(!t || "startTag" !== t.type && "atomicTag" !== t.type || !("tagName" in t)) && !!~t.tagName.toLowerCase().indexOf(e);\n }\n function l(t) {\n return c(t, "script");\n }\n function p(t) {\n return c(t, "style");\n }\n e.__esModule = !0;\n var f = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (t) {\n return typeof t;\n } : function (t) {\n return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t;\n };\n e.existy = r, e.isFunction = n, e.each = o, e.eachKey = i, e.defaults = a, e.toArray = s, e.last = u, e.isTag = c, e.isScript = l, e.isStyle = p;\n }]);\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzgyLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vdmVuZG9yL3Bvc3RzY3JpYmUubWluLmpzPzdlMTIiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAZmlsZSBwb3N0c2NyaWJlXG4gKiBAZGVzY3JpcHRpb24gQXN5bmNocm9ub3VzbHkgd3JpdGUgamF2YXNjcmlwdCwgZXZlbiB3aXRoIGRvY3VtZW50LndyaXRlLlxuICogQHZlcnNpb24gdjIuMC44XG4gKiBAc2VlIHtAbGluayBodHRwczovL2tydXguZ2l0aHViLmlvL3Bvc3RzY3JpYmV9XG4gKiBAbGljZW5zZSBNSVRcbiAqIEBhdXRob3IgRGVyZWsgQnJhbnNcbiAqIEBjb3B5cmlnaHQgMjAxNiBLcnV4IERpZ2l0YWwsIEluY1xuICovXG4hZnVuY3Rpb24odCxlKXtcIm9iamVjdFwiPT10eXBlb2YgZXhwb3J0cyYmXCJvYmplY3RcIj09dHlwZW9mIG1vZHVsZT9tb2R1bGUuZXhwb3J0cz1lKCk6XCJmdW5jdGlvblwiPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kP2RlZmluZShbXSxlKTpcIm9iamVjdFwiPT10eXBlb2YgZXhwb3J0cz9leHBvcnRzW1wicG9zdHNjcmliZVwiXT1lKCk6dFtcInBvc3RzY3JpYmVcIl09ZSgpfSh0aGlzLGZ1bmN0aW9uKCl7cmV0dXJuIGZ1bmN0aW9uKHQpe2Z1bmN0aW9uIGUobil7aWYocltuXSlyZXR1cm4gcltuXS5leHBvcnRzO3ZhciBvPXJbbl09e1wiZXhwb3J0c1wiOnt9LFwiaWRcIjpuLFwibG9h
1ZGVkXCI6ITF9O3JldHVybiB0W25dLmNhbGwoby5leHBvcnRzLG8sby5leHBvcnRzLGUpLG8ubG9hZGVkPSEwLG8uZXhwb3J0c312YXIgcj17fTtyZXR1cm4gZS5tPXQsZS5jPXIsZS5wPVwiXCIsZSgwKX0oW2Z1bmN0aW9uKHQsZSxyKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBuKHQpe3JldHVybiB0JiZ0Ll9fZXNNb2R1bGU/dDp7XCJkZWZhdWx0XCI6dH19dmFyIG89cigxKSxpPW4obyk7dC5leHBvcnRzPWlbXCJkZWZhdWx0XCJdfSxmdW5jdGlvbih0LGUscil7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbih0KXtpZih0JiZ0Ll9fZXNNb2R1bGUpcmV0dXJuIHQ7dmFyIGU9e307aWYobnVsbCE9dClmb3IodmFyIHIgaW4gdClPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodCxyKSYmKGVbcl09dFtyXSk7cmV0dXJuIGVbXCJkZWZhdWx0XCJdPXQsZX1mdW5jdGlvbiBvKHQpe3JldHVybiB0JiZ0Ll9fZXNNb2R1bGU/dDp7XCJkZWZhdWx0XCI6dH19ZnVuY3Rpb24gaSgpe31mdW5jdGlvbiBhKCl7dmFyIHQ9bS5zaGlmdCgpO2lmKHQpe3ZhciBlPWgubGFzdCh0KTtlLmFmdGVyRGVxdWV1ZSgpLHQuc3RyZWFtPXMuYXBwbHkodm9pZCAwLHQpLGUuYWZ0ZXJTdHJlYW1TdGFydCgpfX1mdW5jdGlvbiBzKHQsZSxyKXtmdW5jdGlvbiBuKHQpe3Q9ci5iZWZvcmVXcml0ZSh0KSxnLndyaXRlKHQpLHIuYWZ0ZXJXcml0ZSh0KX1nPW5ldyBwW1wiZGVmYXVsdFwiXSh0LHIpLGcuaWQ9eSsrLGcubmFtZT1yLm5hbWV8fGcuaWQsdS5zdHJlYW1zW2cubmFtZV09Zzt2YXIgbz10Lm93bmVyRG9jdW1lbnQscz17XCJjbG9zZVwiOm8uY2xvc2UsXCJvcGVuXCI6by5vcGVuLFwid3JpdGVcIjpvLndyaXRlLFwid3JpdGVsblwiOm8ud3JpdGVsbn07YyhvLHtcImNsb3NlXCI6aSxcIm9wZW5cIjppLFwid3JpdGVcIjpmdW5jdGlvbigpe2Zvcih2YXIgdD1hcmd1bWVudHMubGVuZ3RoLGU9QXJyYXkodCkscj0wO3I8dDtyKyspZVtyXT1hcmd1bWVudHNbcl07cmV0dXJuIG4oZS5qb2luKFwiXCIpKX0sXCJ3cml0ZWxuXCI6ZnVuY3Rpb24oKXtmb3IodmFyIHQ9YXJndW1lbnRzLmxlbmd0aCxlPUFycmF5KHQpLHI9MDtyPHQ7cisrKWVbcl09YXJndW1lbnRzW3JdO3JldHVybiBuKGUuam9pbihcIlwiKStcIlxcblwiKX19KTt2YXIgbD1nLndpbi5vbmVycm9yfHxpO3JldHVybiBnLndpbi5vbmVycm9yPWZ1bmN0aW9uKHQsZSxuKXtyLmVycm9yKHtcIm1zZ1wiOnQrXCIgLSBcIitlK1wiOiBcIitufSksbC5hcHBseShnLndpbixbdCxlLG5dKX0sZy53cml0ZShlLGZ1bmN0aW9uKCl7YyhvLHMpLGcud2luLm9uZXJyb3I9bCxyLmRvbmUoKSxnPW51bGwsYSgpfSksZ31mdW5jdGlvbiB1KHQsZSxyKXtpZihoLmlzRnVuY3Rpb24ocikpcj17XCJkb25lXCI6cn07ZWxzZSBpZihcImNsZWFyXCI9PT1yKXJldHVybiBtPVtdLGc9bnVsbCx2b2lkKHk9MCk7cj1oLmRlZmF1bHRzKHIsZCksdD0vXiMvLnRlc3QodCk/d2luZG93LmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHQuc3Vic3RyKDEpKTp0LmpxdWVyeT90WzBdOnQ7dmFyIG49W3QsZSxyXTtyZXR1cm4gdC5wb3N0c2NyaWJlPXtcImNhbmNlbFwiOmZ1bmN0aW9uKCl7bi5zdHJlYW0/bi5zdHJlYW0uYWJvcnQoKTpuWzFdPWl9fSxyLmJlZm9yZUVucXVldWUobiksbS5wdXNoKG4pLGd8fGEoKSx0LnBvc3RzY3JpYmV9ZS5fX2VzTW9kdWxlPSEwO3ZhciBjPU9iamVjdC5hc3NpZ258fGZ1bmN0aW9uKHQpe2Zvcih2YXIgZT0xO2U8YXJndW1lbnRzLmxlbmd0aDtlKyspe3ZhciByPWFyZ3VtZW50c1tlXTtmb3IodmFyIG4gaW4gcilPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocixuKSYmKHRbbl09cltuXSl9cmV0dXJuIHR9O2VbXCJkZWZhdWx0XCJdPXU7dmFyIGw9cigyKSxwPW8obCksZj1yKDQpLGg9bihmKSxkPXtcImFmdGVyQXN5bmNcIjppLFwiYWZ0ZXJEZXF1ZXVlXCI6aSxcImFmdGVyU3RyZWFtU3RhcnRcIjppLFwiYWZ0ZXJXcml0ZVwiOmksXCJhdXRvRml4XCI6ITAsXCJiZWZvcmVFbnF1ZXVlXCI6aSxcImJlZm9yZVdyaXRlVG9rZW5cIjpmdW5jdGlvbih0KXtyZXR1cm4gdH0sXCJiZWZvcmVXcml0ZVwiOmZ1bmN0aW9uKHQpe3JldHVybiB0fSxcImRvbmVcIjppLFwiZXJyb3JcIjpmdW5jdGlvbih0KXt0aHJvdyBuZXcgRXJyb3IodC5tc2cpfSxcInJlbGVhc2VBc3luY1wiOiExfSx5PTAsbT1bXSxnPW51bGw7Yyh1LHtcInN0cmVhbXNcIjp7fSxcInF1ZXVlXCI6bSxcIldyaXRlU3RyZWFtXCI6cFtcImRlZmF1bHRcIl19KX0sZnVuY3Rpb24odCxlLHIpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG4odCl7aWYodCYmdC5fX2VzTW9kdWxlKXJldHVybiB0O3ZhciBlPXt9O2lmKG51bGwhPXQpZm9yKHZhciByIGluIHQpT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHQscikmJihlW3JdPXRbcl0pO3JldHVybiBlW1wiZGVmYXVsdFwiXT10LGV9ZnVuY3Rpb24gbyh0KXtyZXR1cm4gdCYmdC5fX2VzTW9kdWxlP3Q6e1wiZGVmYXVsdFwiOnR9fWZ1bmN0aW9uIGkodCxlKXtpZighKHQgaW5zdGFuY2VvZiBlKSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpfWZ1bmN0aW9uIGEodCxlKXt2YXIgcj1kK2Usbj10LmdldEF0dHJpYnV0ZShyKTtyZXR1cm4gZi5leGlzdHkobik/U3RyaW5nKG4pOm59ZnVuY3Rpb24gcyh0LGUpe3ZhciByPWFyZ3VtZW50cy5sZW5ndGg+MiYmdm9pZCAwIT09YXJndW1lbnRzWzJdP2FyZ3VtZW50c1syXTpudWxsLG49ZCtlO2YuZXhpc3R5KHIpJiZcIlwiIT09cj90LnNldEF0dHJpYnV0ZShuLHIpOnQucmVtb3ZlQXR0cmlidXRlKG4pfWUuX19lc01vZHVsZT0hMDt2YXIgdT1PYmplY3QuYXNzaWdufHxmdW5jdGlvbih0KXtmb3IodmFyIGU9MTtlPGFyZ3VtZW50cy5sZW5ndGg7ZSsrKXt2YXIgcj1hcmd1bWVudHNbZV07Zm9yKHZhciBuIGluIHIpT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHIsbikmJih0W25dPXJbbl0pfXJldHVybiB0fSxjPXIoMyksbD1vKGMpLHA9cig0KSxmPW4ocCksaD0hMSxkPVwiZGF0YS1wcy1cIix5PVwicHMtc3R5bGVcIixtPVwicHMtc2NyaXB0XCIsZz1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoZSl7dmFyIHI9YXJndW1lbnRzLmxlbmd0aD4xJiZ2b2lkIDAhPT1hcmd1bWVudHNbMV0/YXJndW1lbnRzWzFdOnt9O2kodGhpcyx0KSx0aGlzLnJvb3Q9ZSx0aGlzLm9wdGlvbnM9cix0aGlzLmRvYz1lLm93bmVyRG9jdW1lbnQsdGhpcy53aW49dGhpcy5kb2MuZGVmYXVsdFZpZXd8fHRoaXMuZG9jLnBhcmVudFdpbmRvdyx0aGlzLnBhcnNlcj1uZXcgbFtcImRlZmF1bHRcIl0oXCJcIix7XCJhdXRvRml4XCI6ci5hdXRvRml4fSksdGhpcy5hY3R1YWxzPVtlXSx0aGlzLnByb3h5SGlzdG9yeT1cIlwiLHRoaXMucHJveHlSb290PXRoaXMuZG9jLmNyZWF0ZUVsZW1lbnQoZS5ub2RlTmFtZSksdGhpcy5zY3JpcHRTdGFjaz1bXSx0aGlzLndyaXRlUXVldWU9W10scyh0aGlzLnByb3h5Um9vdCxcInByb3h5b2ZcIiwwKX1yZXR1cm4gdC5wcm90b3R5cGUud3JpdGU9ZnVuY3Rpb24oKXt2YXIgdDtmb3IoKHQ9dGhpcy53cml0ZVF1ZXVlKS5wdXNoLmFwcGx5KHQsYXJndW1lbnRzKTshdGhpcy5kZWZlcnJlZFJlbW90ZSYmdGhpcy53cml0ZVF1ZXVlLmxlbmd0aDspe3ZhciBlPXR
1oaXMud3JpdGVRdWV1ZS5zaGlmdCgpO2YuaXNGdW5jdGlvbihlKT90aGlzLl9jYWxsRnVuY3Rpb24oZSk6dGhpcy5fd3JpdGVJbXBsKGUpfX0sdC5wcm90b3R5cGUuX2NhbGxGdW5jdGlvbj1mdW5jdGlvbih0KXt2YXIgZT17XCJ0eXBlXCI6XCJmdW5jdGlvblwiLFwidmFsdWVcIjp0Lm5hbWV8fHQudG9TdHJpbmcoKX07dGhpcy5fb25TY3JpcHRTdGFydChlKSx0LmNhbGwodGhpcy53aW4sdGhpcy5kb2MpLHRoaXMuX29uU2NyaXB0RG9uZShlKX0sdC5wcm90b3R5cGUuX3dyaXRlSW1wbD1mdW5jdGlvbih0KXt0aGlzLnBhcnNlci5hcHBlbmQodCk7Zm9yKHZhciBlPXZvaWQgMCxyPXZvaWQgMCxuPXZvaWQgMCxvPVtdOyhlPXRoaXMucGFyc2VyLnJlYWRUb2tlbigpKSYmIShyPWYuaXNTY3JpcHQoZSkpJiYhKG49Zi5pc1N0eWxlKGUpKTspZT10aGlzLm9wdGlvbnMuYmVmb3JlV3JpdGVUb2tlbihlKSxlJiZvLnB1c2goZSk7by5sZW5ndGg+MCYmdGhpcy5fd3JpdGVTdGF0aWNUb2tlbnMobyksciYmdGhpcy5faGFuZGxlU2NyaXB0VG9rZW4oZSksbiYmdGhpcy5faGFuZGxlU3R5bGVUb2tlbihlKX0sdC5wcm90b3R5cGUuX3dyaXRlU3RhdGljVG9rZW5zPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuX2J1aWxkQ2h1bmsodCk7cmV0dXJuIGUuYWN0dWFsPyhlLmh0bWw9dGhpcy5wcm94eUhpc3RvcnkrZS5hY3R1YWwsdGhpcy5wcm94eUhpc3RvcnkrPWUucHJveHksdGhpcy5wcm94eVJvb3QuaW5uZXJIVE1MPWUuaHRtbCxoJiYoZS5wcm94eUlubmVySFRNTD10aGlzLnByb3h5Um9vdC5pbm5lckhUTUwpLHRoaXMuX3dhbGtDaHVuaygpLGgmJihlLmFjdHVhbElubmVySFRNTD10aGlzLnJvb3QuaW5uZXJIVE1MKSxlKTpudWxsfSx0LnByb3RvdHlwZS5fYnVpbGRDaHVuaz1mdW5jdGlvbih0KXtmb3IodmFyIGU9dGhpcy5hY3R1YWxzLmxlbmd0aCxyPVtdLG49W10sbz1bXSxpPXQubGVuZ3RoLGE9MDthPGk7YSsrKXt2YXIgcz10W2FdLHU9cy50b1N0cmluZygpO2lmKHIucHVzaCh1KSxzLmF0dHJzKXtpZighL15ub3NjcmlwdCQvaS50ZXN0KHMudGFnTmFtZSkpe3ZhciBjPWUrKztuLnB1c2godS5yZXBsYWNlKC8oXFwvPz4pLyxcIiBcIitkK1wiaWQ9XCIrYytcIiAkMVwiKSkscy5hdHRycy5pZCE9PW0mJnMuYXR0cnMuaWQhPT15JiZvLnB1c2goXCJhdG9taWNUYWdcIj09PXMudHlwZT9cIlwiOlwiPFwiK3MudGFnTmFtZStcIiBcIitkK1wicHJveHlvZj1cIitjKyhzLnVuYXJ5P1wiIC8+XCI6XCI+XCIpKX19ZWxzZSBuLnB1c2godSksby5wdXNoKFwiZW5kVGFnXCI9PT1zLnR5cGU/dTpcIlwiKX1yZXR1cm57XCJ0b2tlbnNcIjp0LFwicmF3XCI6ci5qb2luKFwiXCIpLFwiYWN0dWFsXCI6bi5qb2luKFwiXCIpLFwicHJveHlcIjpvLmpvaW4oXCJcIil9fSx0LnByb3RvdHlwZS5fd2Fsa0NodW5rPWZ1bmN0aW9uKCl7Zm9yKHZhciB0PXZvaWQgMCxlPVt0aGlzLnByb3h5Um9vdF07Zi5leGlzdHkodD1lLnNoaWZ0KCkpOyl7dmFyIHI9MT09PXQubm9kZVR5cGUsbj1yJiZhKHQsXCJwcm94eW9mXCIpO2lmKCFuKXtyJiYodGhpcy5hY3R1YWxzW2EodCxcImlkXCIpXT10LHModCxcImlkXCIpKTt2YXIgbz10LnBhcmVudE5vZGUmJmEodC5wYXJlbnROb2RlLFwicHJveHlvZlwiKTtvJiZ0aGlzLmFjdHVhbHNbb10uYXBwZW5kQ2hpbGQodCl9ZS51bnNoaWZ0LmFwcGx5KGUsZi50b0FycmF5KHQuY2hpbGROb2RlcykpfX0sdC5wcm90b3R5cGUuX2hhbmRsZVNjcmlwdFRva2VuPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMscj10aGlzLnBhcnNlci5jbGVhcigpO3ImJnRoaXMud3JpdGVRdWV1ZS51bnNoaWZ0KHIpLHQuc3JjPXQuYXR0cnMuc3JjfHx0LmF0dHJzLlNSQyx0PXRoaXMub3B0aW9ucy5iZWZvcmVXcml0ZVRva2VuKHQpLHQmJih0LnNyYyYmdGhpcy5zY3JpcHRTdGFjay5sZW5ndGg/dGhpcy5kZWZlcnJlZFJlbW90ZT10OnRoaXMuX29uU2NyaXB0U3RhcnQodCksdGhpcy5fd3JpdGVTY3JpcHRUb2tlbih0LGZ1bmN0aW9uKCl7ZS5fb25TY3JpcHREb25lKHQpfSkpfSx0LnByb3RvdHlwZS5faGFuZGxlU3R5bGVUb2tlbj1mdW5jdGlvbih0KXt2YXIgZT10aGlzLnBhcnNlci5jbGVhcigpO2UmJnRoaXMud3JpdGVRdWV1ZS51bnNoaWZ0KGUpLHQudHlwZT10LmF0dHJzLnR5cGV8fHQuYXR0cnMuVFlQRXx8XCJ0ZXh0L2Nzc1wiLHQ9dGhpcy5vcHRpb25zLmJlZm9yZVdyaXRlVG9rZW4odCksdCYmdGhpcy5fd3JpdGVTdHlsZVRva2VuKHQpLGUmJnRoaXMud3JpdGUoKX0sdC5wcm90b3R5cGUuX3dyaXRlU3R5bGVUb2tlbj1mdW5jdGlvbih0KXt2YXIgZT10aGlzLl9idWlsZFN0eWxlKHQpO3RoaXMuX2luc2VydEN1cnNvcihlLHkpLHQuY29udGVudCYmKGUuc3R5bGVTaGVldCYmIWUuc2hlZXQ/ZS5zdHlsZVNoZWV0LmNzc1RleHQ9dC5jb250ZW50OmUuYXBwZW5kQ2hpbGQodGhpcy5kb2MuY3JlYXRlVGV4dE5vZGUodC5jb250ZW50KSkpfSx0LnByb3RvdHlwZS5fYnVpbGRTdHlsZT1mdW5jdGlvbih0KXt2YXIgZT10aGlzLmRvYy5jcmVhdGVFbGVtZW50KHQudGFnTmFtZSk7cmV0dXJuIGUuc2V0QXR0cmlidXRlKFwidHlwZVwiLHQudHlwZSksZi5lYWNoS2V5KHQuYXR0cnMsZnVuY3Rpb24odCxyKXtlLnNldEF0dHJpYnV0ZSh0LHIpfSksZX0sdC5wcm90b3R5cGUuX2luc2VydEN1cnNvcj1mdW5jdGlvbih0LGUpe3RoaXMuX3dyaXRlSW1wbCgnPHNwYW4gaWQ9XCInK2UrJ1wiLz4nKTt2YXIgcj10aGlzLmRvYy5nZXRFbGVtZW50QnlJZChlKTtyJiZyLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKHQscil9LHQucHJvdG90eXBlLl9vblNjcmlwdFN0YXJ0PWZ1bmN0aW9uKHQpe3Qub3V0ZXJXcml0ZXM9dGhpcy53cml0ZVF1ZXVlLHRoaXMud3JpdGVRdWV1ZT1bXSx0aGlzLnNjcmlwdFN0YWNrLnVuc2hpZnQodCl9LHQucHJvdG90eXBlLl9vblNjcmlwdERvbmU9ZnVuY3Rpb24odCl7cmV0dXJuIHQhPT10aGlzLnNjcmlwdFN0YWNrWzBdP3ZvaWQgdGhpcy5vcHRpb25zLmVycm9yKHtcIm1zZ1wiOlwiQmFkIHNjcmlwdCBuZXN0aW5nIG9yIHNjcmlwdCBmaW5pc2hlZCB0d2ljZVwifSk6KHRoaXMuc2NyaXB0U3RhY2suc2hpZnQoKSx0aGlzLndyaXRlLmFwcGx5KHRoaXMsdC5vdXRlcldyaXRlcyksdm9pZCghdGhpcy5zY3JpcHRTdGFjay5sZW5ndGgmJnRoaXMuZGVmZXJyZWRSZW1vdGUmJih0aGlzLl9vblNjcmlwdFN0YXJ0KHRoaXMuZGVmZXJyZWRSZW1vdGUpLHRoaXMuZGVmZXJyZWRSZW1vdGU9bnVsbCkpKX0sdC5wcm90b3R5cGUuX3dyaXRlU2NyaXB0VG9rZW49ZnVuY3Rpb24odCxlKXt2YXIgcj10aGlzLl9idWlsZFNjcmlwdCh0KSxuPXRoaXMuX3Nob3VsZFJlbGVhc2Uociksbz10aGlzLm9wdGlvbnMuYWZ0ZXJBc3luYzt0LnNyYyYmKHIuc3JjPXQuc3JjLHRoaXMuX3NjcmlwdExvYWRIYW5kbGVyKHIsbj9vOmZ1bmN0aW9uKCl7ZSgpLG8oKX0pKTt0cnl7dGhpcy5faW5zZXJ0Q3Vyc29yKHIsbSksci5zcmMmJiFufHxlKCl9Y2F0Y2godCl7dGhpcy5vcHRpb25zLmVycm9yKHQpLGUoKX19LHQucHJvdG90eXBlLl9idWlsZFNjcmlwdD1mdW5jdGlvbih0KXt2YXIgZT10aGlzLmRvYy5jcmVhdGVFbGVtZW50KHQudGFnTmFtZSk7cmV0dXJuIGYuZWFjaEtleSh0LmF0dHJzLGZ1bmN0aW9uKHQscil7ZS5zZXRBdHRyaWJ1dGUodCxyKX0pLHQuY29udGVudCYmKGUudGV4dD10LmNvbnRlbnQpLGV9LHQucHJvdG90eXBlLl9zY3JpcHRMb2FkSGFuZGxlcj1mdW5jdGlvbih0LGUpe2Z1bmN0aW9uIHIoKXt0PXQub25sb2FkPXQub25yZWFkeXN0YXRlY2hhbmdlPXQub25lcnJvcj1udWxsfWZ1bmN0aW9uIG4oKXtyKCksbnVsbCE9ZSYmZSgpLGU9bnVsbH1mdW5jdGlvbiBvKHQpe3IoKSxhKHQpLG51bGwhPWUmJmUoKSxlPW51bGx9ZnVuY3Rpb24gaSh0LGUpe3ZhciByPXRbXCJvblwiK2VdO251bGwhPXImJih0W1wiX29uXCIrZV09cil9dmFyIGE9dGhpcy5vcHRpb25zLmVycm9yO2kodCxcImxvYWRcIiksaSh0LFwiZXJyb3JcIiksdSh0LHtcIm9ubG9hZFwiOmZ1bmN0aW9uKCl7aWYodC5fb25sb2FkKXRyeXt0Ll9vbmxvYWQuYXBwbHkodGhpcyxBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsMCkpfWNhdGNoKGUpe28oe1wibXNnXCI6XCJvbmxvYWQgaGFuZGxlciBmYWlsZWQgXCIrZStcIiBAIFwiK3Quc3JjfSl9bigpfSxcIm9uZXJyb3JcIjpmdW5jdGlvbigpe2lmKHQuX29uZXJyb3IpdHJ5e3QuX29uZXJyb3IuYXBwbHkodGhpcyxBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsMCkpfWNhdGNoKGUpe3JldHVybiB2b2lkIG8oe1wibXNnXCI6XCJvbmVycm9yIGhhbmRsZXIgZmFpbGVkIFwiK2UrXCIgQCBcIit0LnNyY30pfW8oe1wibXNnXCI6XCJyZW1vdGUgc2NyaXB0IGZhaWxlZCBcIit0LnNyY30pfSxcIm9ucmVhZHlzdGF0ZWNoYW5nZVwiOmZ1bmN0aW9uKCl7L14obG9hZGVkfGNvbXBsZXRlKSQvLnRlc3QodC5yZWFkeVN0YXRl
1KSYmbigpfX0pfSx0LnByb3RvdHlwZS5fc2hvdWxkUmVsZWFzZT1mdW5jdGlvbih0KXt2YXIgZT0vXnNjcmlwdCQvaS50ZXN0KHQubm9kZU5hbWUpO3JldHVybiFlfHwhISh0aGlzLm9wdGlvbnMucmVsZWFzZUFzeW5jJiZ0LnNyYyYmdC5oYXNBdHRyaWJ1dGUoXCJhc3luY1wiKSl9LHR9KCk7ZVtcImRlZmF1bHRcIl09Z30sZnVuY3Rpb24odCxlLHIpeyFmdW5jdGlvbihlLHIpe3QuZXhwb3J0cz1yKCl9KHRoaXMsZnVuY3Rpb24oKXtyZXR1cm4gZnVuY3Rpb24odCl7ZnVuY3Rpb24gZShuKXtpZihyW25dKXJldHVybiByW25dLmV4cG9ydHM7dmFyIG89cltuXT17XCJleHBvcnRzXCI6e30sXCJpZFwiOm4sXCJsb2FkZWRcIjohMX07cmV0dXJuIHRbbl0uY2FsbChvLmV4cG9ydHMsbyxvLmV4cG9ydHMsZSksby5sb2FkZWQ9ITAsby5leHBvcnRzfXZhciByPXt9O3JldHVybiBlLm09dCxlLmM9cixlLnA9XCJcIixlKDApfShbZnVuY3Rpb24odCxlLHIpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG4odCl7cmV0dXJuIHQmJnQuX19lc01vZHVsZT90OntcImRlZmF1bHRcIjp0fX12YXIgbz1yKDEpLGk9bihvKTt0LmV4cG9ydHM9aVtcImRlZmF1bHRcIl19LGZ1bmN0aW9uKHQsZSxyKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBuKHQpe3JldHVybiB0JiZ0Ll9fZXNNb2R1bGU/dDp7XCJkZWZhdWx0XCI6dH19ZnVuY3Rpb24gbyh0KXtpZih0JiZ0Ll9fZXNNb2R1bGUpcmV0dXJuIHQ7dmFyIGU9e307aWYobnVsbCE9dClmb3IodmFyIHIgaW4gdClPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodCxyKSYmKGVbcl09dFtyXSk7cmV0dXJuIGVbXCJkZWZhdWx0XCJdPXQsZX1mdW5jdGlvbiBpKHQsZSl7aWYoISh0IGluc3RhbmNlb2YgZSkpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKX1lLl9fZXNNb2R1bGU9ITA7dmFyIGE9cigyKSxzPW8oYSksdT1yKDMpLGM9byh1KSxsPXIoNikscD1uKGwpLGY9cig1KSxoPXtcImNvbW1lbnRcIjovXjwhLS0vLFwiZW5kVGFnXCI6L148XFwvLyxcImF0b21pY1RhZ1wiOi9ePFxccyooc2NyaXB0fHN0eWxlfG5vc2NyaXB0fGlmcmFtZXx0ZXh0YXJlYSlbXFxzXFwvPl0vaSxcInN0YXJ0VGFnXCI6L148LyxcImNoYXJzXCI6L15bXjxdL30sZD1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt2YXIgZT10aGlzLHI9YXJndW1lbnRzLmxlbmd0aD4wJiZ2b2lkIDAhPT1hcmd1bWVudHNbMF0/YXJndW1lbnRzWzBdOlwiXCIsbj1hcmd1bWVudHMubGVuZ3RoPjEmJnZvaWQgMCE9PWFyZ3VtZW50c1sxXT9hcmd1bWVudHNbMV06e307aSh0aGlzLHQpLHRoaXMuc3RyZWFtPXI7dmFyIG89ITEsYT17fTtmb3IodmFyIHUgaW4gcylzLmhhc093blByb3BlcnR5KHUpJiYobi5hdXRvRml4JiYoYVt1K1wiRml4XCJdPSEwKSxvPW98fGFbdStcIkZpeFwiXSk7bz8odGhpcy5fcmVhZFRva2VuPSgwLHBbXCJkZWZhdWx0XCJdKSh0aGlzLGEsZnVuY3Rpb24oKXtyZXR1cm4gZS5fcmVhZFRva2VuSW1wbCgpfSksdGhpcy5fcGVla1Rva2VuPSgwLHBbXCJkZWZhdWx0XCJdKSh0aGlzLGEsZnVuY3Rpb24oKXtyZXR1cm4gZS5fcGVla1Rva2VuSW1wbCgpfSkpOih0aGlzLl9yZWFkVG9rZW49dGhpcy5fcmVhZFRva2VuSW1wbCx0aGlzLl9wZWVrVG9rZW49dGhpcy5fcGVla1Rva2VuSW1wbCl9cmV0dXJuIHQucHJvdG90eXBlLmFwcGVuZD1mdW5jdGlvbih0KXt0aGlzLnN0cmVhbSs9dH0sdC5wcm90b3R5cGUucHJlcGVuZD1mdW5jdGlvbih0KXt0aGlzLnN0cmVhbT10K3RoaXMuc3RyZWFtfSx0LnByb3RvdHlwZS5fcmVhZFRva2VuSW1wbD1mdW5jdGlvbigpe3ZhciB0PXRoaXMuX3BlZWtUb2tlbkltcGwoKTtpZih0KXJldHVybiB0aGlzLnN0cmVhbT10aGlzLnN0cmVhbS5zbGljZSh0Lmxlbmd0aCksdH0sdC5wcm90b3R5cGUuX3BlZWtUb2tlbkltcGw9ZnVuY3Rpb24oKXtmb3IodmFyIHQgaW4gaClpZihoLmhhc093blByb3BlcnR5KHQpJiZoW3RdLnRlc3QodGhpcy5zdHJlYW0pKXt2YXIgZT1jW3RdKHRoaXMuc3RyZWFtKTtpZihlKXJldHVyblwic3RhcnRUYWdcIj09PWUudHlwZSYmL3NjcmlwdHxzdHlsZS9pLnRlc3QoZS50YWdOYW1lKT9udWxsOihlLnRleHQ9dGhpcy5zdHJlYW0uc3Vic3RyKDAsZS5sZW5ndGgpLGUpfX0sdC5wcm90b3R5cGUucGVla1Rva2VuPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX3BlZWtUb2tlbigpfSx0LnByb3RvdHlwZS5yZWFkVG9rZW49ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5fcmVhZFRva2VuKCl9LHQucHJvdG90eXBlLnJlYWRUb2tlbnM9ZnVuY3Rpb24odCl7Zm9yKHZhciBlPXZvaWQgMDtlPXRoaXMucmVhZFRva2VuKCk7KWlmKHRbZS50eXBlXSYmdFtlLnR5cGVdKGUpPT09ITEpcmV0dXJufSx0LnByb3RvdHlwZS5jbGVhcj1mdW5jdGlvbigpe3ZhciB0PXRoaXMuc3RyZWFtO3JldHVybiB0aGlzLnN0cmVhbT1cIlwiLHR9LHQucHJvdG90eXBlLnJlc3Q9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5zdHJlYW19LHR9KCk7ZVtcImRlZmF1bHRcIl09ZCxkLnRva2VuVG9TdHJpbmc9ZnVuY3Rpb24odCl7cmV0dXJuIHQudG9TdHJpbmcoKX0sZC5lc2NhcGVBdHRyaWJ1dGVzPWZ1bmN0aW9uKHQpe3ZhciBlPXt9O2Zvcih2YXIgciBpbiB0KXQuaGFzT3duUHJvcGVydHkocikmJihlW3JdPSgwLGYuZXNjYXBlUXVvdGVzKSh0W3JdLG51bGwpKTtyZXR1cm4gZX0sZC5zdXBwb3J0cz1zO2Zvcih2YXIgeSBpbiBzKXMuaGFzT3duUHJvcGVydHkoeSkmJihkLmJyb3dzZXJIYXNGbGF3PWQuYnJvd3Nlckhhc0ZsYXd8fCFzW3ldJiZ5KX0sZnVuY3Rpb24odCxlKXtcInVzZSBzdHJpY3RcIjtlLl9fZXNNb2R1bGU9ITA7dmFyIHI9ITEsbj0hMSxvPXdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO3RyeXt2YXIgaT1cIjxQPjxJPjwvUD48L0k+XCI7by5pbm5lckhUTUw9aSxlLnRhZ1NvdXA9cj1vLmlubmVySFRNTCE9PWl9Y2F0Y2godCl7ZS50YWdTb3VwPXI9ITF9dHJ5e28uaW5uZXJIVE1MPVwiPFA+PGk+PFA+PC9QPjwvaT48L1A+XCIsZS5zZWxmQ2xvc2U9bj0yPT09by5jaGlsZE5vZGVzLmxlbmd0aH1jYXRjaCh0KXtlLnNlbGZDbG9zZT1uPSExfW89bnVsbCxlLnRhZ1NvdXA9cixlLnNlbGZDbG9zZT1ufSxmdW5jdGlvbih0LGUscil7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbih0KXt2YXIgZT10LmluZGV4T2YoXCItLT5cIik7aWYoZT49MClyZXR1cm4gbmV3IGMuQ29tbWVudFRva2VuKHQuc3Vic3RyKDQsZS0xKSxlKzMpfWZ1bmN0aW9uIG8odCl7dmFyIGU9dC5pbmRleE9mKFwiPFwiKTtyZXR1cm4gbmV3IGMuQ2h
1hcnNUb2tlbihlPj0wP2U6dC5sZW5ndGgpfWZ1bmN0aW9uIGkodCl7dmFyIGU9dC5pbmRleE9mKFwiPlwiKTtpZihlIT09LTEpe3ZhciByPXQubWF0Y2gobC5zdGFydFRhZyk7aWYocil7dmFyIG49ZnVuY3Rpb24oKXt2YXIgdD17fSxlPXt9LG49clsyXTtyZXR1cm4gclsyXS5yZXBsYWNlKGwuYXR0cixmdW5jdGlvbihyLG8pe2FyZ3VtZW50c1syXXx8YXJndW1lbnRzWzNdfHxhcmd1bWVudHNbNF18fGFyZ3VtZW50c1s1XT9hcmd1bWVudHNbNV0/KHRbYXJndW1lbnRzWzVdXT1cIlwiLGVbYXJndW1lbnRzWzVdXT0hMCk6dFtvXT1hcmd1bWVudHNbMl18fGFyZ3VtZW50c1szXXx8YXJndW1lbnRzWzRdfHxsLmZpbGxBdHRyLnRlc3QobykmJm98fFwiXCI6dFtvXT1cIlwiLG49bi5yZXBsYWNlKHIsXCJcIil9KSx7XCJ2XCI6bmV3IGMuU3RhcnRUYWdUb2tlbihyWzFdLHJbMF0ubGVuZ3RoLHQsZSwoISFyWzNdKSxuLnJlcGxhY2UoL15bXFxzXFx1RkVGRlxceEEwXSt8W1xcc1xcdUZFRkZcXHhBMF0rJC9nLFwiXCIpKX19KCk7aWYoXCJvYmplY3RcIj09PShcInVuZGVmaW5lZFwiPT10eXBlb2Ygbj9cInVuZGVmaW5lZFwiOnUobikpKXJldHVybiBuLnZ9fX1mdW5jdGlvbiBhKHQpe3ZhciBlPWkodCk7aWYoZSl7dmFyIHI9dC5zbGljZShlLmxlbmd0aCk7aWYoci5tYXRjaChuZXcgUmVnRXhwKFwiPC9cXFxccypcIitlLnRhZ05hbWUrXCJcXFxccyo+XCIsXCJpXCIpKSl7dmFyIG49ci5tYXRjaChuZXcgUmVnRXhwKFwiKFtcXFxcc1xcXFxTXSo/KTwvXFxcXHMqXCIrZS50YWdOYW1lK1wiXFxcXHMqPlwiLFwiaVwiKSk7aWYobilyZXR1cm4gbmV3IGMuQXRvbWljVGFnVG9rZW4oZS50YWdOYW1lLG5bMF0ubGVuZ3RoK2UubGVuZ3RoLGUuYXR0cnMsZS5ib29sZWFuQXR0cnMsblsxXSl9fX1mdW5jdGlvbiBzKHQpe3ZhciBlPXQubWF0Y2gobC5lbmRUYWcpO2lmKGUpcmV0dXJuIG5ldyBjLkVuZFRhZ1Rva2VuKGVbMV0sZVswXS5sZW5ndGgpfWUuX19lc01vZHVsZT0hMDt2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiBTeW1ib2wmJlwic3ltYm9sXCI9PXR5cGVvZiBTeW1ib2wuaXRlcmF0b3I/ZnVuY3Rpb24odCl7cmV0dXJuIHR5cGVvZiB0fTpmdW5jdGlvbih0KXtyZXR1cm4gdCYmXCJmdW5jdGlvblwiPT10eXBlb2YgU3ltYm9sJiZ0LmNvbnN0cnVjdG9yPT09U3ltYm9sJiZ0IT09U3ltYm9sLnByb3RvdHlwZT9cInN5bWJvbFwiOnR5cGVvZiB0fTtlLmNvbW1lbnQ9bixlLmNoYXJzPW8sZS5zdGFydFRhZz1pLGUuYXRvbWljVGFnPWEsZS5lbmRUYWc9czt2YXIgYz1yKDQpLGw9e1wic3RhcnRUYWdcIjovXjwoW1xcLUEtWmEtejAtOV9dKykoKD86XFxzK1tcXHdcXC1dKyg/Olxccyo9P1xccyooPzooPzpcIlteXCJdKlwiKXwoPzonW14nXSonKXxbXj5cXHNdKykpPykqKVxccyooXFwvPyk+LyxcImVuZFRhZ1wiOi9ePFxcLyhbXFwtQS1aYS16MC05X10rKVtePl0qPi8sXCJhdHRyXCI6Lyg/OihbXFwtQS1aYS16MC05X10rKVxccyo9XFxzKig/Oig/OlwiKCg/OlxcXFwufFteXCJdKSopXCIpfCg/OicoKD86XFxcXC58W14nXSkqKScpfChbXj5cXHNdKykpKXwoPzooW1xcLUEtWmEtejAtOV9dKykoXFxzfCQpKykvZyxcImZpbGxBdHRyXCI6L14oY2hlY2tlZHxjb21wYWN0fGRlY2xhcmV8ZGVmZXJ8ZGlzYWJsZWR8aXNtYXB8bXVsdGlwbGV8bm9ocmVmfG5vcmVzaXplfG5vc2hhZGV8bm93cmFwfHJlYWRvbmx5fHNlbGVjdGVkKSQvaX19LGZ1bmN0aW9uKHQsZSxyKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBuKHQsZSl7aWYoISh0IGluc3RhbmNlb2YgZSkpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKX1lLl9fZXNNb2R1bGU9ITAsZS5FbmRUYWdUb2tlbj1lLkF0b21pY1RhZ1Rva2VuPWUuU3RhcnRUYWdUb2tlbj1lLlRhZ1Rva2VuPWUuQ2hhcnNUb2tlbj1lLkNvbW1lbnRUb2tlbj1lLlRva2VuPXZvaWQgMDt2YXIgbz1yKDUpLGk9KGUuVG9rZW49ZnVuY3Rpb24gdChlLHIpe24odGhpcyx0KSx0aGlzLnR5cGU9ZSx0aGlzLmxlbmd0aD1yLHRoaXMudGV4dD1cIlwifSxlLkNvbW1lbnRUb2tlbj1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoZSxyKXtuKHRoaXMsdCksdGhpcy50eXBlPVwiY29tbWVudFwiLHRoaXMubGVuZ3RoPXJ8fChlP2UubGVuZ3RoOjApLHRoaXMudGV4dD1cIlwiLHRoaXMuY29udGVudD1lfXJldHVybiB0LnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVyblwiPCEtLVwiK3RoaXMuY29udGVudH0sdH0oKSxlLkNoYXJzVG9rZW49ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KGUpe24odGhpcyx0KSx0aGlzLnR5cGU9XCJjaGFyc1wiLHRoaXMubGVuZ3RoPWUsdGhpcy50ZXh0PVwiXCJ9cmV0dXJuIHQucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGV4dH0sdH0oKSxlLlRhZ1Rva2VuPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdChlLHIsbyxpLGEpe24odGhpcyx0KSx0aGlzLnR5cGU9ZSx0aGlzLmxlbmd0aD1vLHRoaXMudGV4dD1cIlwiLHRoaXMudGFnTmFtZT1yLHRoaXMuYXR0cnM9aSx0aGlzLmJvb2xlYW5BdHRycz1hLHRoaXMudW5hcnk9ITEsdGhpcy5odG1sNVVuYXJ5PSExfXJldHVybiB0LmZvcm1hdFRhZz1mdW5jdGlvbih0KXt2YXIgZT1hcmd1bWVudHMubGVuZ3RoPjEmJnZvaWQgMCE9PWFyZ3VtZW50c1sxXT9hcmd1bWVudHNbMV06bnVsbCxyPVwiPFwiK3QudGFnTmFtZTtmb3IodmFyIG4gaW4gdC5hdHRycylpZih0LmF0dHJzLmhhc093blByb3BlcnR5KG4pKXtyKz1cIiBcIituO3ZhciBpPXQuYXR0cnNbbl07XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQuYm9vbGVhbkF0dHJzJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgdC5ib29sZWFuQXR0cnNbbl18fChyKz0nPVwiJysoMCxvLmVzY2FwZVF1b3RlcykoaSkrJ1wiJyl9cmV0dXJuIHQucmVzdCYmKHIrPVwiIFwiK3QucmVzdCkscis9dC51bmFyeSYmIXQuaHRtbDVVbmFyeT9cIi8+XCI6XCI+XCIsdm9pZCAwIT09ZSYmbnVsbCE9PWUmJihyKz1lK1wiPC9cIit0LnRhZ05hbWUrXCI+XCIpLHJ9LHR9KCkpO2UuU3RhcnRUYWdUb2tlbj1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoZSxyLG8saSxhLHMpe24odGhpcyx0KSx0aGlzLnR5cGU9XCJzdGFydFRhZ1wiLHRoaXMubGVuZ3RoPXIsdGhpcy50ZXh0PVwiXCIsdGhpcy50YWdOYW1lPWUsdGhpcy5hdHRycz1vLHRoaXMuYm9vbGVhbkF0dHJzPWksdGhpcy5odG1sNVVuYXJ5PSExLHRoaXMudW5hcnk9YSx0aGlzLnJlc3Q9c31yZXR1cm4gdC5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gaS5mb3JtYXRUYWcodGhpcyl9LHR9KCksZS5BdG9taWNUYWdUb2tlbj1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoZSxyLG8saSxhKXtuKHRoaXMsdCksdGhpcy50eXBlPVwiYXRvbWljVGFnXCIsdGhpcy5sZW5ndGg9cix0aGlzLnRleHQ9XCJcIix0aGlzLnRhZ05hbWU9ZSx0aGlzLmF0dHJzPW8sdGhpcy5ib29sZWFuQXR0cnM9aSx0aGlzLnVuYXJ5PSExLHRoaXMuaHRtbDVVbmFyeT0hMSx0aGlzLmNvbnRlbnQ9YX1yZXR1cm4gdC5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gaS5mb3JtYXRUYWcodGhpcyx0aGlzLmNvbnRlbnQpfSx0fSgpLGUuRW5kVGFnVG9rZW49ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KGUscil7bih0aGlzLHQpLHRoaXMudHlwZT1cImVuZFRhZ1wiLHRoaXMubGVuZ3RoPXIsdGhpcy50ZXh0PVwiXCIsdGhpcy50YWdOYW1lPWV9cmV0dXJuIHQucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuXCI8L1wiK3RoaXMudGFnTmFtZStcIj5cIn0sdH0oKX0sZnVuY3Rpb24odCxlKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiByKHQpe3ZhciBlPWFyZ3VtZW50cy5sZW5ndGg+MSYmdm9pZCAwIT09YXJndW1lbnRzWzFdP2FyZ3VtZW50c1sxXTpcIlwiO3JldHVybiB0P3QucmVwbGFjZSgvKFteXCJdKilc
1Ii9nLGZ1bmN0aW9uKHQsZSl7cmV0dXJuL1xcXFwvLnRlc3QoZSk/ZSsnXCInOmUrJ1xcXFxcIid9KTplfWUuX19lc01vZHVsZT0hMCxlLmVzY2FwZVF1b3Rlcz1yfSxmdW5jdGlvbih0LGUpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIHIodCl7cmV0dXJuIHQmJlwic3RhcnRUYWdcIj09PXQudHlwZSYmKHQudW5hcnk9cy50ZXN0KHQudGFnTmFtZSl8fHQudW5hcnksdC5odG1sNVVuYXJ5PSEvXFwvPiQvLnRlc3QodC50ZXh0KSksdH1mdW5jdGlvbiBuKHQsZSl7dmFyIG49dC5zdHJlYW0sbz1yKGUoKSk7cmV0dXJuIHQuc3RyZWFtPW4sb31mdW5jdGlvbiBvKHQsZSl7dmFyIHI9ZS5wb3AoKTt0LnByZXBlbmQoXCI8L1wiK3IudGFnTmFtZStcIj5cIil9ZnVuY3Rpb24gaSgpe3ZhciB0PVtdO3JldHVybiB0Lmxhc3Q9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpc1t0aGlzLmxlbmd0aC0xXX0sdC5sYXN0VGFnTmFtZUVxPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMubGFzdCgpO3JldHVybiBlJiZlLnRhZ05hbWUmJmUudGFnTmFtZS50b1VwcGVyQ2FzZSgpPT09dC50b1VwcGVyQ2FzZSgpfSx0LmNvbnRhaW5zVGFnTmFtZT1mdW5jdGlvbih0KXtmb3IodmFyIGUscj0wO2U9dGhpc1tyXTtyKyspaWYoZS50YWdOYW1lPT09dClyZXR1cm4hMDtyZXR1cm4hMX0sdH1mdW5jdGlvbiBhKHQsZSxhKXtmdW5jdGlvbiBzKCl7dmFyIGU9bih0LGEpO2UmJmxbZS50eXBlXSYmbFtlLnR5cGVdKGUpfXZhciBjPWkoKSxsPXtcInN0YXJ0VGFnXCI6ZnVuY3Rpb24ocil7dmFyIG49ci50YWdOYW1lO1wiVFJcIj09PW4udG9VcHBlckNhc2UoKSYmYy5sYXN0VGFnTmFtZUVxKFwiVEFCTEVcIik/KHQucHJlcGVuZChcIjxUQk9EWT5cIikscygpKTplLnNlbGZDbG9zZUZpeCYmdS50ZXN0KG4pJiZjLmNvbnRhaW5zVGFnTmFtZShuKT9jLmxhc3RUYWdOYW1lRXEobik/byh0LGMpOih0LnByZXBlbmQoXCI8L1wiK3IudGFnTmFtZStcIj5cIikscygpKTpyLnVuYXJ5fHxjLnB1c2gocil9LFwiZW5kVGFnXCI6ZnVuY3Rpb24ocil7dmFyIG49Yy5sYXN0KCk7bj9lLnRhZ1NvdXBGaXgmJiFjLmxhc3RUYWdOYW1lRXEoci50YWdOYW1lKT9vKHQsYyk6Yy5wb3AoKTplLnRhZ1NvdXBGaXgmJihhKCkscygpKX19O3JldHVybiBmdW5jdGlvbigpe3JldHVybiBzKCkscihhKCkpfX1lLl9fZXNNb2R1bGU9ITAsZVtcImRlZmF1bHRcIl09YTt2YXIgcz0vXihBUkVBfEJBU0V8QkFTRUZPTlR8QlJ8Q09MfEZSQU1FfEhSfElNR3xJTlBVVHxJU0lOREVYfExJTkt8TUVUQXxQQVJBTXxFTUJFRCkkL2ksdT0vXihDT0xHUk9VUHxERHxEVHxMSXxPUFRJT05TfFB8VER8VEZPT1R8VEh8VEhFQUR8VFIpJC9pfV0pfSl9LGZ1bmN0aW9uKHQsZSl7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gcih0KXtyZXR1cm4gdm9pZCAwIT09dCYmbnVsbCE9PXR9ZnVuY3Rpb24gbih0KXtyZXR1cm5cImZ1bmN0aW9uXCI9PXR5cGVvZiB0fWZ1bmN0aW9uIG8odCxlLHIpe3ZhciBuPXZvaWQgMCxvPXQmJnQubGVuZ3RofHwwO2ZvcihuPTA7bj
1xvO24rKyllLmNhbGwocix0W25dLG4pfWZ1bmN0aW9uIGkodCxlLHIpe2Zvcih2YXIgbiBpbiB0KXQuaGFzT3duUHJvcGVydHkobikmJmUuY2FsbChyLG4sdFtuXSl9ZnVuY3Rpb24gYSh0LGUpe3JldHVybiB0PXR8fHt9LGkoZSxmdW5jdGlvbihlLG4pe3IodFtlXSl8fCh0W2VdPW4pfSksdH1mdW5jdGlvbiBzKHQpe3RyeXtyZXR1cm4gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodCl9Y2F0Y2gocil7dmFyIGU9ZnVuY3Rpb24oKXt2YXIgZT1bXTtyZXR1cm4gbyh0LGZ1bmN0aW9uKHQpe2UucHVzaCh0KX0pLHtcInZcIjplfX0oKTtpZihcIm9iamVjdFwiPT09KFwidW5kZWZpbmVkXCI9PXR5cGVvZiBlP1widW5kZWZpbmVkXCI6ZihlKSkpcmV0dXJuIGUudn19ZnVuY3Rpb24gdSh0KXtyZXR1cm4gdFt0Lmxlbmd0aC0xXX1mdW5jdGlvbiBjKHQsZSl7cmV0dXJuISghdHx8XCJzdGFydFRhZ1wiIT09dC50eXBlJiZcImF0b21pY1RhZ1wiIT09dC50eXBlfHwhKFwidGFnTmFtZVwiaW4gdCkpJiYhIX50LnRhZ05hbWUudG9Mb3dlckNhc2UoKS5pbmRleE9mKGUpfWZ1bmN0aW9uIGwodCl7cmV0dXJuIGModCxcInNjcmlwdFwiKX1mdW5jdGlvbiBwKHQpe3JldHVybiBjKHQsXCJzdHlsZVwiKX1lLl9fZXNNb2R1bGU9ITA7dmFyIGY9XCJmdW5jdGlvblwiPT10eXBlb2YgU3ltYm9sJiZcInN5bWJvbFwiPT10eXBlb2YgU3ltYm9sLml0ZXJhdG9yP2Z1bmN0aW9uKHQpe3JldHVybiB0eXBlb2YgdH06ZnVuY3Rpb24odCl7cmV0dXJuIHQmJlwiZnVuY3Rpb25cIj09dHlwZW9mIFN5bWJvbCYmdC5jb25zdHJ1Y3Rvcj09PVN5bWJvbCYmdCE9PVN5bWJvbC5wcm90b3R5cGU/XCJzeW1ib2xcIjp0eXBlb2YgdH07ZS5leGlzdHk9cixlLmlzRnVuY3Rpb249bixlLmVhY2g9byxlLmVhY2hLZXk9aSxlLmRlZmF1bHRzPWEsZS50b0FycmF5PXMsZS5sYXN0PXUsZS5pc1RhZz1jLGUuaXNTY3JpcHQ9bCxlLmlzU3R5bGU9cH1dKX0pOyJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///782\n')},458:()=>{"use strict";eval('\n\n(function () {\n var PolyfillEvent = eventConstructor();\n function eventConstructor() {\n if (typeof window.CustomEvent === "function") return window.CustomEvent;\n // IE<=9 Support\n function CustomEvent(event, params) {\n params = params || {\n bubbles: false,\n cancelable: false,\n detail: undefined\n };\n var evt = document.createEvent(\'CustomEvent\');\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n return evt;\n }\n CustomEvent.prototype = window.Event.prototype;\n return CustomEvent;\n }\n function buildHiddenInput(name, value) {\n var input = document.createElement("input");\n input.type = "hidden";\n input.name = name;\n input.value = value;\n return input;\n }\n function handleClick(element, targetModifierKey) {\n var to = element.getAttribute("data-to"),\n method = buildHiddenInput("_method", element.getAttribute("data-method")),\n csrf = buildHiddenInput("_csrf_token", element.getAttribute("data-csrf")),\n form = document.createElement("form"),\n submit = document.createElement("input"),\n target = element.getAttribute("target");\n form.method = element.getAttribute("data-method") === "get" ? "get" : "post";\n form.action = to;\n form.style.display = "none";\n if (target) form.target = target;else if (targetModifierKey) form.target = "_blank";\n form.appendChild(csrf);\n form.appendChild(method);\n document.body.appendChild(form);\n\n // Insert a button and click it instead of using `form.submit`\n // because the `submit` function does not emit a `submit` event.\n submit.type = "submit";\n form.appendChild(submit);\n submit.click();\n }\n window.addEventListener("click", function (e) {\n var element = e.target;\n if (e.defaultPrevented) return;\n while (element && element.getAttribute) {\n var phoenixLinkEvent = new PolyfillEvent(\'phoenix.link.click\', {\n "bubbles": true,\n "cancelable": true\n });\n if (!element.dispatchEvent(phoenixLinkEvent)) {\n e.preventDefault();\n e.stopImmediatePropagation();\n return false;\n }\n if (element.getAttribute("data-method") && element.getAttribute("data-to")) {\n handleClick(element, e.metaKey || e.shiftKey);\n e.preventDefault();\n return false;\n } else {\n element = element.parentNode;\n }\n }\n }, false);\n window.addEventListener(\'phoenix.link.click\', function (e) {\n var message = e.target.getAttribute("data-confirm");\n if (message && !window.confirm(message)) {\n e.preventDefault();\n }\n }, false);\n})();//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDU4LmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4uL2RlcHMvcGhvZW5peF9odG1sL3ByaXYvc3RhdGljL3Bob2VuaXhfaHRtbC5qcz80N2Q4Il0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBQb2x5ZmlsbEV2ZW50ID0gZXZlbnRDb25zdHJ1Y3RvcigpO1xuXG4gIGZ1bmN0aW9uIGV2ZW50Q29uc3RydWN0b3IoKSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cuQ3VzdG9tRXZlbnQgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHdpbmRvdy5DdXN0b21FdmVudDtcbiAgICAvLyBJRTw9OSBTdXBwb3J0XG4gICAgZnVuY3Rpb24gQ3VzdG9tRXZlbnQoZXZlbnQsIHBhcmFtcykge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHtidWJibGVzOiBmYWxzZSwgY2FuY2VsYWJsZTogZmFsc2UsIGRldGFpbDogdW5kZWZpbmVkfTtcbiAgICAgIHZhciBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnQ3VzdG9tRXZlbnQnKTtcbiAgICAgIGV2dC5pbml0Q3VzdG9tRXZlbnQoZXZlbnQsIHBhcmFtcy5idWJibGVzLCBwYXJhbXMuY2FuY2VsYWJsZSwgcGFyYW1zLmRldGFpbCk7XG4gICAgICByZXR1cm4gZXZ0O1xuICAgIH1cbiAgICBDdXN0b21FdmVudC5wcm90b3R5cGUgPSB3aW5kb3cuRXZlbnQucHJvdG90eXBlO1xuICAgIHJldHVybi
1BDdXN0b21FdmVudDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGJ1aWxkSGlkZGVuSW5wdXQobmFtZSwgdmFsdWUpIHtcbiAgICB2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7XG4gICAgaW5wdXQudHlwZSA9IFwiaGlkZGVuXCI7XG4gICAgaW5wdXQubmFtZSA9IG5hbWU7XG4gICAgaW5wdXQudmFsdWUgPSB2YWx1ZTtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVDbGljayhlbGVtZW50LCB0YXJnZXRNb2RpZmllcktleSkge1xuICAgIHZhciB0byA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS10b1wiKSxcbiAgICAgICAgbWV0aG9kID0gYnVpbGRIaWRkZW5JbnB1dChcIl9tZXRob2RcIiwgZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJkYXRhLW1ldGhvZFwiKSksXG4gICAgICAgIGNzcmYgPSBidWlsZEhpZGRlbklucHV0KFwiX2NzcmZfdG9rZW5cIiwgZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJkYXRhLWNzcmZcIikpLFxuICAgICAgICBmb3JtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImZvcm1cIiksXG4gICAgICAgIHN1Ym1pdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbnB1dFwiKSxcbiAgICAgICAgdGFyZ2V0ID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJ0YXJnZXRcIik7XG5cbiAgICBmb3JtLm1ldGhvZCA9IChlbGVtZW50LmdldEF0dHJpYnV0ZShcImRhdGEtbWV0aG9kXCIpID09PSBcImdldFwiKSA/IFwiZ2V0XCIgOiBcInBvc3RcIjtcbiAgICBmb3JtLmFjdGlvbiA9IHRvO1xuICAgIGZvcm0uc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuXG4gICAgaWYgKHRhcmdldCkgZm9ybS50YXJnZXQgPSB0YXJnZXQ7XG4gICAgZWxzZSBpZiAodGFyZ2V0TW9kaWZpZXJLZXkpIGZvcm0udGFyZ2V0ID0gXCJfYmxhbmtcIjtcblxuICAgIGZvcm0uYXBwZW5kQ2hpbGQoY3NyZik7XG4gICAgZm9ybS5hcHBlbmRDaGlsZChtZXRob2QpO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZm9ybSk7XG5cbiAgICAvLyBJbnNlcnQgYSBidXR0b24gYW5kIGNsaWNrIGl0IGluc3RlYWQgb2YgdXNpbmcgYGZvcm0uc3VibWl0YFxuICAgIC8vIGJlY2F1c2UgdGhlIGBzdWJtaXRgIGZ1bmN0aW9uIGRvZXMgbm90IGVtaXQgYSBgc3VibWl0YCBldmVudC5cbiAgICBzdWJtaXQudHlwZSA9IFwic3VibWl0XCI7XG4gICAgZm9ybS5hcHBlbmRDaGlsZChzdWJtaXQpO1xuICAgIHN1Ym1pdC5jbGljaygpO1xuICB9XG5cbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBmdW5jdGlvbihlKSB7XG4gICAgdmFyIGVsZW1lbnQgPSBlLnRhcmdldDtcbiAgICBpZiAoZS5kZWZhdWx0UHJldmVudGVkKSByZXR1cm47XG5cbiAgICB3aGlsZSAoZWxlbWVudCAmJiBlbGVtZW50LmdldEF0dHJpYnV0ZSkge1xuICAgICAgdmFyIHBob2VuaXhMaW5rRXZlbnQgPSBuZXcgUG9seWZpbGxFdmVudCgncGhvZW5peC5saW5rLmNsaWNrJywge1xuICAgICAgICBcImJ1YmJsZXNcIjogdHJ1ZSwgXCJjYW5jZWxhYmxlXCI6IHRydWVcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoIWVsZW1lbnQuZGlzcGF0Y2hFdmVudChwaG9lbml4TGlua0V2ZW50KSkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS1tZXRob2RcIikgJiYgZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJkYXRhLXRvXCIpKSB7XG4gICAgICAgIGhhbmRsZUNsaWNrKGVsZW1lbnQsIGUubWV0YUtleSB8fCBlLnNoaWZ0S2V5KTtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbGVtZW50ID0gZWxlbWVudC5wYXJlbnROb2RlO1xuICAgICAgfVxuICAgIH1cbiAgfSwgZmFsc2UpO1xuXG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdwaG9lbml4LmxpbmsuY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgIHZhciBtZXNzYWdlID0gZS50YXJnZXQuZ2V0QXR0cmlidXRlKFwiZGF0YS1jb25maXJtXCIpO1xuICAgIGlmKG1lc3NhZ2UgJiYgIXdpbmRvdy5jb25maXJtKG1lc3NhZ2UpKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9LCBmYWxzZSk7XG59KSgpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///458\n')},865:function(module,exports,__webpack_require__){eval("var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress\n * @license MIT */\n\n;(function(root, factory) {\n\n if (true) {\n !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) :\n\t\t__WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else {}\n\n}
1)(this, function() {\n var NProgress = {};\n\n NProgress.version = '0.2.0';\n\n var Settings = NProgress.settings = {\n minimum: 0.08,\n easing: 'ease',\n positionUsing: '',\n speed: 200,\n trickle: true,\n trickleRate: 0.02,\n trickleSpeed: 800,\n showSpinner: true,\n barSelector: '[role=\"bar\"]',\n spinnerSelector: '[role=\"spinner\"]',\n parent: 'body',\n template: '<div class=\"bar\" role=\"bar\"><div class=\"peg\"></div></div><div class=\"spinner\" role=\"spinner\"><div class=\"spinner-icon\"></div></div>'\n };\n\n /**\n * Updates configuration.\n *\n * NProgress.configure({\n * minimum: 0.1\n * });\n */\n NProgress.configure = function(options) {\n var key, value;\n for (key in options) {\n value = options[key];\n if (value !== undefined && options.hasOwnProperty(key)) Settings[key] = value;\n }\n\n return this;\n };\n\n /**\n * Last number.\n */\n\n NProgress.status = null;\n\n /**\n * Sets the progress bar status, where `n` is a number from `0.0` to `1.0`.\n *\n * NProgress.set(0.4);\n * NProgress.set(1.0);\n */\n\n NProgress.set = function(n) {\n var started = NProgress.isStarted();\n\n n = clamp(n, Settings.minimum, 1);\n NProgress.status = (n === 1 ? null : n);\n\n var progress = NProgress.render(!started),\n bar = progress.querySelector(Settings.barSelector),\n speed = Settings.speed,\n ease = Settings.easing;\n\n progress.offsetWidth; /* Repaint */\n\n queue(function(next) {\n // Set positionUsing if it hasn't already been set\n if (Settings.positionUsing === '') Settings.positionUsing = NProgress.getPositioningCSS();\n\n // Add transition\n css(bar, barPositionCSS(n, speed, ease));\n\n if (n === 1) {\n // Fade out\n css(progress, { \n transition: 'none', \n opacity: 1 \n });\n progress.offsetWidth; /* Repaint */\n\n setTimeout(function() {\n css(progress, { \n transition: 'all ' + speed + 'ms linear', \n opacity: 0 \n });\n setTimeout(function() {\n NProgress.remove();\n next();\n }, speed);\n }, speed);\n } else {\n setTimeout(next, speed);\n }\n });\n\n return this;\n };\n\n NProgress.isStarted = function() {\n return typeof NProgress.status === 'number';\n };\n\n /**\n * Shows the progress bar.\n * This is the same as setting the status to 0%, except that it doesn't go backwards.\n *\n * NProgress.start();\n *\n */\n NProgress.start = function() {\n if (!NProgress.status) NProgress.set(0);\n\n var work = function() {\n setTimeout(function() {\n if (!NProgress.status) return;\n NProgress.trickle();\n work();\n }, Settings.trickleSpeed);\n };\n\n if (Settings.trickle) work();\n\n return this;\n };\n\n /**\n * Hides the progress bar.\n * This is the *sort of* the same as setting the status to 100%, with the\n * difference being `done()` makes some placebo effect of some realistic motion.\n *\n * NProgress.done();\n *\n * If `true` is passed, it will show the progress bar even if its hidden.\n *\n * NProgress.done(true);\n */\n\n NProgress.done = function(force) {\n if (!force && !NProgress.status) return this;\n\n return NProgress.inc(0.3 + 0.5 * Math.random()).set(1);\n };\n\n /**\n * Increments by a random amount.\n */\n\n NProgress.inc = function(amount) {\n var n = NProgress.status;\n\n if (!n) {\n return NProgress.start();\n } else {\n if (typeof amount !== 'number') {\n amount = (1 - n) * clamp(Math.random() * n, 0.1, 0.95);\n }\n\n n = clamp(n + amount, 0, 0.994);\n return NProgress.set(n);\n }\n };\n\n NProgress.trickle = function() {\n return NProgress.inc(Math.random() * Settings.trickleRate);\n };\n\n /**\n * Waits for all supplied jQuery promises and\n * increases the progress as the promises resolve.\n *\n * @param $promise jQUery Promise\n */\n (function() {\
1n var initial = 0, current = 0;\n\n NProgress.promise = function($promise) {\n if (!$promise || $promise.state() === \"resolved\") {\n return this;\n }\n\n if (current === 0) {\n NProgress.start();\n }\n\n initial++;\n current++;\n\n $promise.always(function() {\n current--;\n if (current === 0) {\n initial = 0;\n NProgress.done();\n } else {\n NProgress.set((initial - current) / initial);\n }\n });\n\n return this;\n };\n\n })();\n\n /**\n * (Internal) renders the progress bar markup based on the `template`\n * setting.\n */\n\n NProgress.render = function(fromStart) {\n if (NProgress.isRendered()) return document.getElementById('nprogress');\n\n addClass(document.documentElement, 'nprogress-busy');\n \n var progress = document.createElement('div');\n progress.id = 'nprogress';\n progress.innerHTML = Settings.template;\n\n var bar = progress.querySelector(Settings.barSelector),\n perc = fromStart ? '-100' : toBarPerc(NProgress.status || 0),\n parent = document.querySelector(Settings.parent),\n spinner;\n \n css(bar, {\n transition: 'all 0 linear',\n transform: 'translate3d(' + perc + '%,0,0)'\n });\n\n if (!Settings.showSpinner) {\n spinner = progress.querySelector(Settings.spinnerSelector);\n spinner && removeElement(spinner);\n }\n\n if (parent != document.body) {\n addClass(parent, 'nprogress-custom-parent');\n }\n\n parent.appendChild(progress);\n return progress;\n };\n\n /**\n * Removes the element. Opposite of render().\n */\n\n NProgress.remove = function() {\n removeClass(document.documentElement, 'nprogress-busy');\n removeClass(document.querySelector(Settings.parent), 'nprogress-custom-parent');\n var progress = document.getElementById('nprogress');\n progress && removeElement(progress);\n };\n\n /**\n * Checks if the progress bar is rendered.\n */\n\n NProgress.isRendered = function() {\n return !!document.getElementById('nprogress');\n };\n\n /**\n * Determine which positioning CSS rule to use.\n */\n\n NProgress.getPositioningCSS = function() {\n // Sniff on document.body.style\n var bodyStyle = document.body.style;\n\n // Sniff prefixes\n var vendorPrefix = ('WebkitTransform' in bodyStyle) ? 'Webkit' :\n ('MozTransform' in bodyStyle) ? 'Moz' :\n ('msTransform' in bodyStyle) ? 'ms' :\n ('OTransform' in bodyStyle) ? 'O' : '';\n\n if (vendorPrefix + 'Perspective' in bodyStyle) {\n // Modern browsers with 3D support, e.g. Webkit, IE10\n return 'translate3d';\n } else if (vendorPrefix + 'Transform' in bodyStyle) {\n // Browsers without 3D support, e.g. IE9\n return 'translate';\n } else {\n // Browsers without translate() support, e.g. IE7-8\n return 'margin';\n }\n };\n\n /**\n * Helpers\n */\n\n function clamp(n, min, max) {\n if (n < min) return min;\n if (n > max) return max;\n return n;\n }\n\n /**\n * (Internal) converts a percentage (`0..1`) to a bar translateX\n * percentage (`-100%..0%`).\n */\n\n function toBarPerc(n) {\n return (-1 + n) * 100;\n }\n\n\n /**\n * (Internal) returns the correct CSS for changing the bar's\n * position given an n percentage, and speed and ease from Settings\n */\n\n function barPositionCSS(n, speed, ease) {\n var barCSS;\n\n if (Settings.positionUsing === 'translate3d') {\n barCSS = { transform: 'translate3d('+toBarPerc(n)+'%,0,0)' };\n } else if (Settings.positionUsing === 'translate') {\n barCSS = { transform: 'translate('+toBarPerc(n)+'%,0)' };\n } else {\n barCSS = { 'margin-left': toBarPerc(n)+'%' };\n }\n\n barCSS.transition = 'all '+speed+'ms '+ease;\n\n return barCSS;\n }\n\n /**\n * (Internal) Queues a function to be executed.\n */\n\n var queue = (function() {\n var pending = [];\n \n function next() {\n var fn = pending.shift();\n if (fn) {\n fn(next);\n }\n }\n\n return function(fn) {\n pending.push(fn);\n if (pending.length == 1) next();\n };\n })();\n\n /**\n * (Internal) Applies css properties to an element, similar to the jQuery \n * css method.\n *\n * While this helper does assist with vendor prefixed property names, it \n * does not perform any manipulation of values prior to setting styles.\n */\n\n var css = (function() {\
1n var cssPrefixes = [ 'Webkit', 'O', 'Moz', 'ms' ],\n cssProps = {};\n\n function camelCase(string) {\n return string.replace(/^-ms-/, 'ms-').replace(/-([\\da-z])/gi, function(match, letter) {\n return letter.toUpperCase();\n });\n }\n\n function getVendorProp(name) {\n var style = document.body.style;\n if (name in style) return name;\n\n var i = cssPrefixes.length,\n capName = name.charAt(0).toUpperCase() + name.slice(1),\n vendorName;\n while (i--) {\n vendorName = cssPrefixes[i] + capName;\n if (vendorName in style) return vendorName;\n }\n\n return name;\n }\n\n function getStyleProp(name) {\n name = camelCase(name);\n return cssProps[name] || (cssProps[name] = getVendorProp(name));\n }\n\n function applyCss(element, prop, value) {\n prop = getStyleProp(prop);\n element.style[prop] = value;\n }\n\n return function(element, properties) {\n var args = arguments,\n prop, \n value;\n\n if (args.length == 2) {\n for (prop in properties) {\n value = properties[prop];\n if (value !== undefined && properties.hasOwnProperty(prop)) applyCss(element, prop, value);\n }\n } else {\n applyCss(element, args[1], args[2]);\n }\n }\n })();\n\n /**\n * (Internal) Determines if an element or space separated list of class names contains a class name.\n */\n\n function hasClass(element, name) {\n var list = typeof element == 'string' ? element : classList(element);\n return list.indexOf(' ' + name + ' ') >= 0;\n }\n\n /**\n * (Internal) Adds a class to an element.\n */\n\n function addClass(element, name) {\n var oldList = classList(element),\n newList = oldList + name;\n\n if (hasClass(oldList, name)) return; \n\n // Trim the opening space.\n element.className = newList.substring(1);\n }\n\n /**\n * (Internal) Removes a class from an element.\n */\n\n function removeClass(element, name) {\n var oldList = classList(element),\n newList;\n\n if (!hasClass(element, name)) return;\n\n // Replace the class name.\n newList = oldList.replace(' ' + name + ' ', ' ');
1\n\n // Trim the opening and closing spaces.\n element.className = newList.substring(1, newList.length - 1);\n }\n\n /**\n * (Internal) Gets a space separated list of the class names on the element. \n * The list is wrapped with a single space on each end to facilitate finding \n * matches within the list.\n */\n\n function classList(element) {\n return (' ' + (element.className || '') + ' ').replace(/\\s+/gi, ' ');\n }\n\n /**\n * (Internal) Removes an element from the DOM.\n */\n\n function removeElement(element) {\n element && element.parentNode && element.parentNode.removeChild(element);\n }\n\n return NProgress;\n});\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODY1LmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL25wcm9ncmVzcy9ucHJvZ3Jlc3MuanM/MzIzZSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiBOUHJvZ3Jlc3MsIChjKSAyMDEzLCAyMDE0IFJpY28gU3RhLiBDcnV6IC0gaHR0cDovL3JpY29zdGFjcnV6LmNvbS9ucHJvZ3Jlc3NcbiAqIEBsaWNlbnNlIE1JVCAqL1xuXG47KGZ1bmN0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblxuICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgZGVmaW5lKGZhY3RvcnkpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuICB9IGVsc2Uge1xuICAgIHJvb3QuTlByb2dyZXNzID0gZmFjdG9yeSgpO1xuICB9XG5cbn0pKHRoaXMsIGZ1bmN0aW9uKCkge1xuICB2YXIgTlByb2dyZXNzID0ge307XG5cbiAgTlByb2dyZXNzLnZlcnNpb24gPSAnMC4yLjAnO1xuXG4gIHZhciBTZXR0aW5ncyA9IE5Qcm9ncmVzcy5zZXR0aW5ncyA9IHtcbiAgICBtaW5pbXVtOiAwLjA4LFxuICAgIGVhc2luZzogJ2Vhc2UnLFxuICAgIHBvc2l0aW9uVXNpbmc6ICcnLFxuICAgIHNwZWVkOiAyMDAsXG4gICAgdHJpY2tsZTogdHJ1ZSxcbiAgICB0cmlja2xlUmF0ZTogMC4wMixcbiAgICB0cmlja2xlU3BlZWQ6IDgwMCxcbiAgICBzaG93U3Bpbm5lcjogdHJ1ZSxcbiAgICBiYXJTZWxlY3RvcjogJ1tyb2xlPVwiYmFyXCJdJyxcbiAgICBzcGlubmVyU2VsZWN0b3I6ICdbcm9sZT1cInNwaW5uZXJcIl0nLFxuICAgIHBhcmVudDogJ2JvZHknLFxuICAgIHRlbXBsYXRlOiAnPGRpdiBjbGFzcz1cImJhclwiIHJvbGU9XCJiYXJcIj48ZGl2IGNsYXNzPVwicGVnXCI+PC9kaXY+PC9kaXY+PGRpdiBjbGFzcz1cInNwaW5uZXJcIiByb2xlPVwic3Bpbm5lclwiPjxkaXYgY2xhc3M9XCJzcGlubmVyLWljb25cIj48L2Rpdj48L2Rpdj4nXG4gIH07XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgY29uZmlndXJhdGlvbi5cbiAgICpcbiAgICogICAgIE5Qcm9ncmVzcy5jb25maWd1cmUoe1xuICAgKiAgICAgICBtaW5pbXVtOiAwLjFcbiAgICogICAgIH0pO1xuICAgKi9cbiAgTlByb2dyZXNzLmNvbmZpZ3VyZSA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICB2YXIga2V5LCB2YWx1ZTtcbiAgICBmb3IgKGtleSBpbiBvcHRpb25zKSB7XG4gICAgICB2YWx1ZSA9IG9wdGlvbnNba2V5XTtcbiAgICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMuaGFzT3duUHJvcGVydHkoa2V5KSkgU2V0dGluZ3Nba2V5XSA9IHZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8qKlxuICAgKiBMYXN0IG51bWJlci5cbiAgICovXG5cbiAgTlByb2dyZXNzLnN0YXR1cyA9IG51bGw7XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIHByb2dyZXNzIGJhciBzdGF0dXMsIHdoZXJlIGBuYCBpcyBhIG51bWJlciBmcm9tIGAwLjBgIHRvIGAxLjBgLlxuICAgKlxuICAgKiAgICAgTlByb2dyZXNzLnNldCgwLjQpO1xuICAgKiAgICAgTlByb2dyZXNzLnNldCgxLjApO1xuICAgKi9cblxuICBOUHJvZ3Jlc3Muc2V0ID0gZnVuY3Rpb24obikge1xuICAgIHZhciBzdGFydGVkID0gTlByb2dyZXNzLmlzU3RhcnRlZCgpO1xuXG4gICAgbiA9IGNsYW1wKG4sIFNldHRpbmdzLm1pbmltdW0sIDEpO1xuICAgIE5Qcm9ncmVzcy5zdGF0dXMgPSAobiA9PT0gMSA/IG51bGwgOiBuKTtcblxuICAgIHZhciBwcm9ncmVzcyA9IE5Qcm9ncmVzcy5yZW5kZXIoIXN0YXJ0ZWQpLFxuICAgICAgICBiYXIgICAgICA9IHByb2dyZXNzLnF1ZXJ5U2VsZWN0b3IoU2V0dGluZ3MuYmFyU2VsZWN0b3IpLFxuICAgICAgICBzcGVlZCAgICA9IFNldHRpbmdzLnNwZWVkLFxuICAgICAgICBlYXNlICAgICA9IFNldHRpbmdzLmVhc2luZztcblxuICAgIHByb2dyZXNzLm9mZnNldFdpZHRoOyAvKiBSZXBhaW50ICovXG5cbiAgICBxdWV1ZShmdW5jdGlvbihuZXh0KSB7XG4gICAgICAvLyBTZXQgcG9zaXRpb25Vc2luZyBpZiBpdCBoYXNuJ3QgYWxyZWFkeSBiZWVuIHNldFxuICAgICAgaWYgKFNldHRpbmdzLnBvc2l0aW9uVXNpbmcgPT09ICcnKSBTZXR0aW5ncy5wb3NpdGlvblVzaW5nID0gTlByb2dyZXNzLmdldFBvc2l0aW9uaW5nQ1NTKCk7XG5cbiAgICAgIC8vIEFkZCB0cmFuc2l0aW9uXG4gICAgICBjc3MoYmFyLCBiYXJQb3NpdGlvbkNTUyhuLCBzcGVlZCwgZWFzZSkpO1xuXG4gICAgICBpZiAobiA9PT0gMSkge1xuICAgICAgICAvLyBGYWRlIG91dFxuICAgICAgICBjc3MocHJvZ3Jlc3MsIHsgXG4gICAgICAgICAgdHJhbnNpdGlvbjogJ25vbmUnLCBcbiAgICAgICAgICBvcGFjaXR5OiAxIFxuICAgICAgICB9KTtcbiAgICAgICAgcHJvZ3Jlc3Mub2Zmc2V0V2lkdGg7IC8qIFJlcGFpbnQgKi9cblxuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGNzcyhwcm9ncmVzcywgeyBcbiAgICAgICAgICAgI
1HRyYW5zaXRpb246ICdhbGwgJyArIHNwZWVkICsgJ21zIGxpbmVhcicsIFxuICAgICAgICAgICAgb3BhY2l0eTogMCBcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgTlByb2dyZXNzLnJlbW92ZSgpO1xuICAgICAgICAgICAgbmV4dCgpO1xuICAgICAgICAgIH0sIHNwZWVkKTtcbiAgICAgICAgfSwgc3BlZWQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0VGltZW91dChuZXh0LCBzcGVlZCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBOUHJvZ3Jlc3MuaXNTdGFydGVkID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBOUHJvZ3Jlc3Muc3RhdHVzID09PSAnbnVtYmVyJztcbiAgfTtcblxuICAvKipcbiAgICogU2hvd3MgdGhlIHByb2dyZXNzIGJhci5cbiAgICogVGhpcyBpcyB0aGUgc2FtZSBhcyBzZXR0aW5nIHRoZSBzdGF0dXMgdG8gMCUsIGV4Y2VwdCB0aGF0IGl0IGRvZXNuJ3QgZ28gYmFja3dhcmRzLlxuICAgKlxuICAgKiAgICAgTlByb2dyZXNzLnN0YXJ0KCk7XG4gICAqXG4gICAqL1xuICBOUHJvZ3Jlc3Muc3RhcnQgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAoIU5Qcm9ncmVzcy5zdGF0dXMpIE5Qcm9ncmVzcy5zZXQoMCk7XG5cbiAgICB2YXIgd29yayA9IGZ1bmN0aW9uKCkge1xuICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKCFOUHJvZ3Jlc3Muc3RhdHVzKSByZXR1cm47XG4gICAgICAgIE5Qcm9ncmVzcy50cmlja2xlKCk7XG4gICAgICAgIHdvcmsoKTtcbiAgICAgIH0sIFNldHRpbmdzLnRyaWNrbGVTcGVlZCk7XG4gICAgfTtcblxuICAgIGlmIChTZXR0aW5ncy50cmlja2xlKSB3b3JrKCk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvKipcbiAgICogSGlkZXMgdGhlIHByb2dyZXNzIGJhci5cbiAgICogVGhpcyBpcyB0aGUgKnNvcnQgb2YqIHRoZSBzYW1lIGFzIHNldHRpbmcgdGhlIHN0YXR1cyB0byAxMDAlLCB3aXRoIHRoZVxuICAgKiBkaWZmZXJlbmNlIGJlaW5nIGBkb25lKClgIG1ha2VzIHNvbWUgcGxhY2VibyBlZmZlY3Qgb2Ygc29tZSByZWFsaXN0aWMgbW90aW9uLlxuICAgKlxuICAgKiAgICAgTlByb2dyZXNzLmRvbmUoKTtcbiAgICpcbiAgICogSWYgYHRydWVgIGlzIHBhc3NlZCwgaXQgd2lsbCBzaG93IHRoZSBwcm9ncmVzcyBiYXIgZXZlbiBpZiBpdHMgaGlkZGVuLlxuICAgKlxuICAgKiAgICAgTlByb2dyZXNzLmRvbmUodHJ1ZSk7XG4gICAqL1xuXG4gIE5Qcm9ncmVzcy5kb25lID0gZnVuY3Rpb24oZm9yY2UpIHtcbiAgICBpZiAoIWZvcmNlICYmICFOUHJvZ3Jlc3Muc3RhdHVzKSByZXR1cm4gdGhpcztcblxuICAgIHJldHVybiBOUHJvZ3Jlc3MuaW5jKDAuMyArIDAuNSAqIE1hdGgucmFuZG9tKCkpLnNldCgxKTtcbiAgfTtcblxuICAvKipcbiAgICogSW5jcmVtZW50cyBieSBhIHJhbmRvbSBhbW91bnQuXG4gICAqL1xuXG4gIE5Qcm9ncmVzcy5pbmMgPSBmdW5jdGlvbihhbW91bnQpIHtcbiAgICB2YXIgbiA9IE5Qcm9ncmVzcy5zdGF0dXM7XG5cbiAgICBpZiAoIW4pIHtcbiAgICAgIHJldHVybiBOUHJvZ3Jlc3Muc3RhcnQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHR5cGVvZiBhbW91bnQgIT09ICdudW1iZXInKSB7XG4gICAgICAgIGFtb3VudCA9ICgxIC0gbikgKiBjbGFtcChNYXRoLnJhbmRvbSgpICogbiwgMC4xLCAwLjk1KTtcbiAgICAgIH1cblxuICAgICAgbiA9IGNsYW1wKG4gKyBhbW91bnQsIDAsIDAuOTk0KTtcbiAgICAgIHJldHVybiBOUHJvZ3Jlc3Muc2V0KG4pO1xuICAgIH1cbiAgfTtcblxuICBOUHJvZ3Jlc3MudHJpY2tsZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBOUHJvZ3Jlc3MuaW5jKE1hdGgucmFuZG9tKCkgKiBTZXR0aW5ncy50cmlja2xlUmF0ZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFdhaXRzIGZvciBhbGwgc3VwcGxpZWQgalF1ZXJ5IHByb21pc2VzIGFuZFxuICAgKiBpbmNyZWFzZXMgdGhlIHByb2dyZXNzIGFzIHRoZSBwcm9taXNlcyByZXNvbHZlLlxuICAgKlxuICAgKiBAcGFyYW0gJHByb21pc2UgalFVZXJ5IFByb21pc2VcbiAgICovXG4gIChmdW5jdGlvbigpIHtcbiAgICB2YXIgaW5pdGlhbCA9IDAsIGN1cnJlbnQgPSAwO1xuXG4gICAgTlByb2dyZXNzLnByb21pc2UgPSBmdW5jdGlvbigkcHJvbWlzZSkge1xuICAgICAgaWYgKCEkcHJvbWlzZSB8fCAkcHJvbWlzZS5zdGF0ZSgpID09PSBcInJlc29sdmVkXCIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIGlmIChjdXJyZW50ID09PSAwKSB7XG4gICAgICAgIE5Qcm9ncmVzcy5zdGFydCgpO1xuICAgICAgfVxuXG4gICAgICBpbml0aWFsKys7XG4gICAgICBjdXJyZW50Kys7XG5cbiAgICAgICRwcm9taXNlLmFsd2F5cyhmdW5jdGlvbigpIHtcbiAgICAgICAgY3VycmVudC0tO1xuICAgICAgICBpZiAoY3VycmVudCA9PT0gMCkge1xuICAgICAgICAgICAgaW5pdGlhbCA9IDA7XG4gICAgICAgICAgICBOUHJvZ3Jlc3MuZG9uZSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgTlByb2dyZXNzLnNldCgoaW5pdGlhbCAtIGN1cnJlbnQpIC8gaW5pdGlhbCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gIH0pKCk7XG5cbiAgLyoqXG4gICAqIChJbnRlcm5hbCkgcmVuZGVycyB0aGUgcHJvZ3Jlc3MgYmFyIG1hcmt1cCBiYXNlZCBvbiB0aGUgYHRlbXBsYXRlYFxuICAgKiBzZXR0aW5nLlxuICAgKi9cblxuICBOUHJvZ3Jlc3MucmVuZGVyID0gZnVuY3Rpb24oZnJvbVN0YXJ0KSB7XG4gICAgaWYgKE5Qcm9ncmVzcy5pc1JlbmRlcmVkKCkpIHJldHVybiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbnByb2dyZXNzJyk7XG5cbiAgICBhZGRDbGFzcyhkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICducHJvZ3Jlc3MtYnVzeScpO1xuICAgIFxuICAgIHZhciBwcm9ncmVzcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHByb2dyZXNzLmlkID0gJ25wcm9ncmVzcyc7XG4gICAgcHJvZ3Jlc3MuaW5uZXJIVE1MID0gU2V0dGluZ3MudGVtcGxhdGU7XG5cbiAgICB2YXIgYmFyICAgICAgPSBwcm9ncmVzcy5xdWVyeVNlbGVjdG9yKFNldHRpbmdzLmJhclNlbGVjdG9yKSxcbiAgICAgICAgcGVyYyAgICAgPSBmcm9tU3RhcnQgPyAnLTEwMCcgOiB0b0JhclBlcmMoTlByb2dyZXNzLnN0YXR1cyB8fCAwKSxcbiAgICAgICAgcGFyZW50ICAgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFNldHRpbmdzLnBhcmVudCksXG4gICAgICAgI
1HNwaW5uZXI7XG4gICAgXG4gICAgY3NzKGJhciwge1xuICAgICAgdHJhbnNpdGlvbjogJ2FsbCAwIGxpbmVhcicsXG4gICAgICB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgnICsgcGVyYyArICclLDAsMCknXG4gICAgfSk7XG5cbiAgICBpZiAoIVNldHRpbmdzLnNob3dTcGlubmVyKSB7XG4gICAgICBzcGlubmVyID0gcHJvZ3Jlc3MucXVlcnlTZWxlY3RvcihTZXR0aW5ncy5zcGlubmVyU2VsZWN0b3IpO1xuICAgICAgc3Bpbm5lciAmJiByZW1vdmVFbGVtZW50KHNwaW5uZXIpO1xuICAgIH1cblxuICAgIGlmIChwYXJlbnQgIT0gZG9jdW1lbnQuYm9keSkge1xuICAgICAgYWRkQ2xhc3MocGFyZW50LCAnbnByb2dyZXNzLWN1c3RvbS1wYXJlbnQnKTtcbiAgICB9XG5cbiAgICBwYXJlbnQuYXBwZW5kQ2hpbGQocHJvZ3Jlc3MpO1xuICAgIHJldHVybiBwcm9ncmVzcztcbiAgfTtcblxuICAvKipcbiAgICogUmVtb3ZlcyB0aGUgZWxlbWVudC4gT3Bwb3NpdGUgb2YgcmVuZGVyKCkuXG4gICAqL1xuXG4gIE5Qcm9ncmVzcy5yZW1vdmUgPSBmdW5jdGlvbigpIHtcbiAgICByZW1vdmVDbGFzcyhkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICducHJvZ3Jlc3MtYnVzeScpO1xuICAgIHJlbW92ZUNsYXNzKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoU2V0dGluZ3MucGFyZW50KSwgJ25wcm9ncmVzcy1jdXN0b20tcGFyZW50Jyk7XG4gICAgdmFyIHByb2dyZXNzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25wcm9ncmVzcycpO1xuICAgIHByb2dyZXNzICYmIHJlbW92ZUVsZW1lbnQocHJvZ3Jlc3MpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIHByb2dyZXNzIGJhciBpcyByZW5kZXJlZC5cbiAgICovXG5cbiAgTlByb2dyZXNzLmlzUmVuZGVyZWQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gISFkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbnByb2dyZXNzJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqIERldGVybWluZSB3aGljaCBwb3NpdGlvbmluZyBDU1MgcnVsZSB0byB1c2UuXG4gICAqL1xuXG4gIE5Qcm9ncmVzcy5nZXRQb3NpdGlvbmluZ0NTUyA9IGZ1bmN0aW9uKCkge1xuICAgIC8vIFNuaWZmIG9uIGRvY3VtZW50LmJvZHkuc3R5bGVcbiAgICB2YXIgYm9keVN0eWxlID0gZG9jdW1lbnQuYm9keS5zdHlsZTtcblxuICAgIC8vIFNuaWZmIHByZWZpeGVzXG4gICAgdmFyIHZlbmRvclByZWZpeCA9ICgnV2Via2l0VHJhbnNmb3JtJyBpbiBib2R5U3R5bGUpID8gJ1dlYmtpdCcgOlxuICAgICAgICAgICAgICAgICAgICAgICAoJ01velRyYW5zZm9ybScgaW4gYm9keVN0eWxlKSA/ICdNb3onIDpcbiAgICAgICAgICAgICAgICAgICAgICAgKCdtc1RyYW5zZm9ybScgaW4gYm9keVN0eWxlKSA/ICdtcycgOlxuICAgICAgICAgICAgICAgICAgICAgICAoJ09UcmFuc2Zvcm0nIGluIGJvZHlTdHlsZSkgPyAnTycgOiAnJztcblxuICAgIGlmICh2ZW5kb3JQcmVmaXggKyAnUGVyc3BlY3RpdmUnIGluIGJvZHlTdHlsZSkge1xuICAgICAgLy8gTW9kZXJuIGJyb3dzZXJzIHdpdGggM0Qgc3VwcG9ydCwgZS5nLiBXZWJraXQsIElFMTBcbiAgICAgIHJldHVybiAndHJhbnNsYXRlM2QnO1xuICAgIH0gZWxzZSBpZiAodmVuZG9yUHJlZml4ICsgJ1RyYW5zZm9ybScgaW4gYm9keVN0eWxlKSB7XG4gICAgICAvLyBCcm93c2VycyB3aXRob3V0IDNEIHN1cHBvcnQsIGUuZy4gSUU5XG4gICAgICByZXR1cm4gJ3RyYW5zbGF0ZSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEJyb3dzZXJzIHdpdGhvdXQgdHJhbnNsYXRlKCkgc3VwcG9ydCwgZS5nLiBJRTctOFxuICAgICAgcmV0dXJuICdtYXJnaW4nO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogSGVscGVyc1xuICAgKi9cblxuICBmdW5jdGlvbiBjbGFtcChuLCBtaW4sIG1heCkge1xuICAgIGlmIChuIDwgbWluKSByZXR1cm4gbWluO1xuICAgIGlmIChuID4gbWF4KSByZXR1cm4gbWF4O1xuICAgIHJldHVybiBuO1xuICB9XG5cbiAgLyoqXG4gICAqIChJbnRlcm5hbCkgY29udmVydHMgYSBwZXJjZW50YWdlIChgMC4uMWApIHRvIGEgYmFyIHRyYW5zbGF0ZVhcbiAgICogcGVyY2VudGFnZSAoYC0xMDAlLi4wJWApLlxuICAgKi9cblxuICBmdW5jdGlvbiB0b0JhclBlcmMobikge1xuICAgIHJldHVybiAoLTEgKyBuKSAqIDEwMDtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIChJbnRlcm5hbCkgcmV0dXJucyB0aGUgY29ycmVjdCBDU1MgZm9yIGNoYW5naW5nIHRoZSBiYXInc1xuICAgKiBwb3NpdGlvbiBnaXZlbiBhbiBuIHBlcmNlbnRhZ2UsIGFuZCBzcGVlZCBhbmQgZWFzZSBmcm9tIFNldHRpbmdzXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGJhclBvc2l0aW9uQ1NTKG4sIHNwZWVkLCBlYXNlKSB7XG4gICAgdmFyIGJhckNTUztcblxuICAgIGlmIChTZXR0aW5ncy5wb3NpdGlvblVzaW5nID09PSAndHJhbnNsYXRlM2QnKSB7XG4gICAgICBiYXJDU1MgPSB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKCcrdG9CYXJQZXJjKG4pKyclLDAsMCknIH07XG4gICAgfSBlbHNlIGlmIChTZXR0aW5ncy5wb3NpdGlvblVzaW5nID09PSAndHJhbnNsYXRlJykge1xuICAgICAgYmFyQ1NTID0geyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUoJyt0b0JhclBlcmMobikrJyUsMCknIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGJhckNTUyA9IHsgJ21hcmdpbi1sZWZ0JzogdG9CYXJQZXJjKG4pKyclJyB9O1xuICAgIH1cblxuICAgIGJhckNTUy50cmFuc2l0aW9uID0gJ2FsbCAnK3NwZWVkKydtcyAnK2Vhc2U7XG5cbiAgICByZXR1cm4gYmFyQ1NTO1xuICB9XG5cbiAgLyoqXG4gICAqIChJbnRlcm5hbCkgUXVldWVzIGEgZnVuY3Rpb24gdG8gYmUgZXhlY3V0ZWQuXG4gICAqL1xuXG4gIHZhciBxdWV1ZSA9IChmdW5jdGlvbigpIHtcbiAgICB2YXIgcGVuZGluZyA9IFtdO1xuICAgIFxuICAgIGZ1bmN0aW9uIG5leHQoKSB7XG4gICAgICB2Y
1XIgZm4gPSBwZW5kaW5nLnNoaWZ0KCk7XG4gICAgICBpZiAoZm4pIHtcbiAgICAgICAgZm4obmV4dCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGZuKSB7XG4gICAgICBwZW5kaW5nLnB1c2goZm4pO1xuICAgICAgaWYgKHBlbmRpbmcubGVuZ3RoID09IDEpIG5leHQoKTtcbiAgICB9O1xuICB9KSgpO1xuXG4gIC8qKlxuICAgKiAoSW50ZXJuYWwpIEFwcGxpZXMgY3NzIHByb3BlcnRpZXMgdG8gYW4gZWxlbWVudCwgc2ltaWxhciB0byB0aGUgalF1ZXJ5IFxuICAgKiBjc3MgbWV0aG9kLlxuICAgKlxuICAgKiBXaGlsZSB0aGlzIGhlbHBlciBkb2VzIGFzc2lzdCB3aXRoIHZlbmRvciBwcmVmaXhlZCBwcm9wZXJ0eSBuYW1lcywgaXQgXG4gICAqIGRvZXMgbm90IHBlcmZvcm0gYW55IG1hbmlwdWxhdGlvbiBvZiB2YWx1ZXMgcHJpb3IgdG8gc2V0dGluZyBzdHlsZXMuXG4gICAqL1xuXG4gIHZhciBjc3MgPSAoZnVuY3Rpb24oKSB7XG4gICAgdmFyIGNzc1ByZWZpeGVzID0gWyAnV2Via2l0JywgJ08nLCAnTW96JywgJ21zJyBdLFxuICAgICAgICBjc3NQcm9wcyAgICA9IHt9O1xuXG4gICAgZnVuY3Rpb24gY2FtZWxDYXNlKHN0cmluZykge1xuICAgICAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKC9eLW1zLS8sICdtcy0nKS5yZXBsYWNlKC8tKFtcXGRhLXpdKS9naSwgZnVuY3Rpb24obWF0Y2gsIGxldHRlcikge1xuICAgICAgICByZXR1cm4gbGV0dGVyLnRvVXBwZXJDYXNlKCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRWZW5kb3JQcm9wKG5hbWUpIHtcbiAgICAgIHZhciBzdHlsZSA9IGRvY3VtZW50LmJvZHkuc3R5bGU7XG4gICAgICBpZiAobmFtZSBpbiBzdHlsZSkgcmV0dXJuIG5hbWU7XG5cbiAgICAgIHZhciBpID0gY3NzUHJlZml4ZXMubGVuZ3RoLFxuICAgICAgICAgIGNhcE5hbWUgPSBuYW1lLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgbmFtZS5zbGljZSgxKSxcbiAgICAgICAgICB2ZW5kb3JOYW1lO1xuICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICB2ZW5kb3JOYW1lID0gY3NzUHJlZml4ZXNbaV0gKyBjYXBOYW1lO1xuICAgICAgICBpZiAodmVuZG9yTmFtZSBpbiBzdHlsZSkgcmV0dXJuIHZlbmRvck5hbWU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuYW1lO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFN0eWxlUHJvcChuYW1lKSB7XG4gICAgICBuYW1lID0gY2FtZWxDYXNlKG5hbWUpO1xuICAgICAgcmV0dXJuIGNzc1Byb3BzW25hbWVdIHx8IChjc3NQcm9wc1tuYW1lXSA9IGdldFZlbmRvclByb3AobmFtZSkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFwcGx5Q3NzKGVsZW1lbnQsIHByb3AsIHZhbHVlKSB7XG4gICAgICBwcm9wID0gZ2V0U3R5bGVQcm9wKHByb3ApO1xuICAgICAgZWxlbWVudC5zdHlsZVtwcm9wXSA9IHZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiBmdW5jdGlvbihlbGVtZW50LCBwcm9wZXJ0aWVzKSB7XG4gICAgICB2Y
1XIgYXJncyA9IGFyZ3VtZW50cyxcbiAgICAgICAgICBwcm9wLCBcbiAgICAgICAgICB2YWx1ZTtcblxuICAgICAgaWYgKGFyZ3MubGVuZ3RoID09IDIpIHtcbiAgICAgICAgZm9yIChwcm9wIGluIHByb3BlcnRpZXMpIHtcbiAgICAgICAgICB2YWx1ZSA9IHByb3BlcnRpZXNbcHJvcF07XG4gICAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgcHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShwcm9wKSkgYXBwbHlDc3MoZWxlbWVudCwgcHJvcCwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhcHBseUNzcyhlbGVtZW50LCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pKCk7XG5cbiAgLyoqXG4gICAqIChJbnRlcm5hbCkgRGV0ZXJtaW5lcyBpZiBhbiBlbGVtZW50IG9yIHNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mIGNsYXNzIG5hbWVzIGNvbnRhaW5zIGEgY2xhc3MgbmFtZS5cbiAgICovXG5cbiAgZnVuY3Rpb24gaGFzQ2xhc3MoZWxlbWVudCwgbmFtZSkge1xuICAgIHZhciBsaXN0ID0gdHlwZW9mIGVsZW1lbnQgPT0gJ3N0cmluZycgPyBlbGVtZW50IDogY2xhc3NMaXN0KGVsZW1lbnQpO1xuICAgIHJldHVybiBsaXN0LmluZGV4T2YoJyAnICsgbmFtZSArICcgJykgPj0gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiAoSW50ZXJuYWwpIEFkZHMgYSBjbGFzcyB0byBhbiBlbGVtZW50LlxuICAgKi9cblxuICBmdW5jdGlvbiBhZGRDbGFzcyhlbGVtZW50LCBuYW1lKSB7XG4gICAgdmFyIG9sZExpc3QgPSBjbGFzc0xpc3QoZWxlbWVudCksXG4gICAgICAgIG5ld0xpc3QgPSBvbGRMaXN0ICsgbmFtZTtcblxuICAgIGlmIChoYXNDbGFzcyhvbGRMaXN0LCBuYW1lKSkgcmV0dXJuOyBcblxuICAgIC8vIFRyaW0gdGhlIG9wZW5pbmcgc3BhY2UuXG4gICAgZWxlbWVudC5jbGFzc05hbWUgPSBuZXdMaXN0LnN1YnN0cmluZygxKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAoSW50ZXJuYWwpIFJlbW92ZXMgYSBjbGFzcyBmcm9tIGFuIGVsZW1lbnQuXG4gICAqL1xuXG4gIGZ1bmN0aW9uIHJlbW92ZUNsYXNzKGVsZW1lbnQsIG5hbWUpIHtcbiAgICB2YXIgb2xkTGlzdCA9IGNsYXNzTGlzdChlbGVtZW50KSxcbiAgICAgICAgbmV3TGlzdDtcblxuICAgIGlmICghaGFzQ2xhc3MoZWxlbWVudCwgbmFtZSkpIHJldHVybjtcblxuICAgIC8vIFJlcGxhY2UgdGhlIGNsYXNzIG5hbWUuXG4gICAgbmV3TGlzdCA9IG9sZExpc3QucmVwbGFjZSgnICcgKyBuYW1lICsgJyAnLCAnICcpO1xuXG4gICAgLy8gVHJpbSB0aGUgb3BlbmluZyBhbmQgY2xvc2luZyBzcGFjZXMuXG4gICAgZWxlbWVudC5jbGFzc05hbWUgPSBuZXdMaXN0LnN1YnN0cmluZygxLCBuZXdMaXN0Lmxlbmd0aCAtIDEpO1xuICB9XG5cbiAgLyoqXG4gICAqIChJbnRlcm5hbCkgR2V0cyBhIHNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mIHRoZSBjbGFzcyBuYW1lcyBvbiB0aGUgZWxlbWVudC4gXG4gICAqIFRoZSBsaXN0IGlzIHdyYXBwZWQgd2l0aCBhIHNpbmdsZSBzcGFjZSBvbiBlYWNoIGVuZCB0byBmYWNpbGl0YXRlIGZpbmRpbmcgXG4gICAqIG1hdGNoZXMgd2l0aGluIHRoZSBsaXN0LlxuICAgKi9cblxuICBmdW5jdGlvbiBjbGFzc0xpc3QoZWxlbWVudCkge1xuICAgIHJldHVybiAoJyAnICsgKGVsZW1lbnQuY2xhc3NOYW1lIHx8ICcnKSArICcgJykucmVwbGFjZSgvXFxzKy9naSwgJyAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAoSW50ZXJuYWwpIFJlbW92ZXMgYW4gZWxlbWVudCBmcm9tIHRoZSBET00uXG4gICAqL1xuXG4gIGZ1bmN0aW9uIHJlbW92ZUVsZW1lbnQoZWxlbWVudCkge1xuICAgIGVsZW1lbnQgJiYgZWxlbWVudC5wYXJlbnROb2RlICYmIGVsZW1lbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbGVtZW50KTtcbiAgfVxuXG4gIHJldHVybiBOUHJvZ3Jlc3M7XG59KTtcblxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0EsV0FJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///865\n")},304:function(module){eval('\n;(function (name, root, factory) {\n if (true) {\n module.exports = factory()\n module.exports.default = factory()\n }\n /* istanbul ignore next */\n else {}\n}(\'slugify\', this, function () {\n var charMap = JSON.parse(\'{"$":"dollar","%":"percent","&":"and","<":"less",">":"greater","|":"or","¢":"cent","£":"pound","¤":"currency","Â¥":"yen","©":"(c)","ª":"a","®":"(r)","º":"o","Ã":"A","Ã":"A","Ã":"A","Ã":"A","Ã":"A","Ã
":"A","Ã":"AE","Ã":"C","Ã":"E","Ã":"E","Ã":"E","Ã":"E","Ã":"I","Ã":"I","Ã":"I","Ã":"I","Ã":"D","Ã":"N","Ã":"O","Ã":"O","Ã":"O","Ã":"O","Ã":"O","Ã":"O","Ã":"U","Ã":"U","Ã":"U","Ã":"U","Ã":"Y","Ã":"TH","Ã":"ss","à ":"a","á":"a","â":"a","ã":"a","ä":"a","Ã¥":"a","æ":"ae","ç":"c","è":"e","é":"e","ê":"e","ë":"e","ì":"i","Ã":"i","î":"i","ï":"i","ð":"d","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","ù":"u","ú":"u","û":"u","ü":"u","ý":"y","þ":"th","ÿ":"y","Ä":"A","Ä":"a","Ä":"A","Ä":"a","Ä":"A","Ä
":"a","Ä":"C","Ä":"
1c","Ä":"C","Ä":"c","Ä":"D","Ä":"d","Ä":"DJ","Ä":"dj","Ä":"E","Ä":"e","Ä":"E","Ä":"e","Ä":"e","Ä":"e","Ä":"E","Ä":"e","Ä":"G","Ä":"g","Ä¢":"G","Ä£":"g","Ĩ":"I","Ä©":"i","Ī":"i","Ä«":"i","Ä®":"I","į":"i","İ":"I","ı":"i","Ķ":"k","Ä·":"k","Ä»":"L","ļ":"l","Ľ":"L","ľ":"l","Å":"L","Å":"l","Å":"N","Å":"n","Å
":"N","Å":"n","Å":"N","Å":"n","Å":"O","Å":"o","Å":"O","Å":"o","Å":"OE","Å":"oe","Å":"R","Å":"r","Å":"R","Å":"r","Å":"S","Å":"s","Å":"S","Å":"s","Å ":"S","Å¡":"s","Å¢":"T","Å£":"t","Ť":"T","Å¥":"t","Ũ":"U","Å©":"u","Ū":"u","Å«":"u","Å®":"U","ů":"u","Ű":"U","ű":"u","Ų":"U","ų":"u","Å´":"W","ŵ":"w","Ŷ":"Y","Å·":"y","Ÿ":"Y","Ź":"Z","ź":"z","Å»":"Z","ż":"z","Ž":"Z","ž":"z","Æ":"E","Æ":"f","Æ ":"O","Æ¡":"o","Ư":"U","ư":"u","Ç":"LJ","Ç":"lj","Ç":"NJ","Ç":"nj","È":"S","È":"s","È":"T","È":"t","É":"e","Ë":"o","Î":"A","Î":"E","Î":"H","Î":"I","Î":"O","Î":"Y","Î":"W","Î":"i","Î":"A","Î":"B","Î":"G","Î":"D","Î":"E","Î":"Z","Î":"H","Î":"8","Î":"I","Î":"K","Î":"L","Î":"M","Î":"N","Î":"3","Î":"O","Î ":"P","Ρ":"R","Σ":"S","Τ":"T","Î¥":"Y","Φ":"F","Χ":"X","Ψ":"PS","Ω":"W","Ϊ":"I","Ϋ":"Y","ά":"a","Î":"e","ή":"h","ί":"i","ΰ":"y","α":"a","β":"b","γ":"g","δ":"d","ε":"e","ζ":"z","η":"h","θ":"8","ι":"i","κ":"k","λ":"l","μ":"m","ν":"n","ξ":"3","ο":"o","Ï":"p","Ï":"r","Ï":"s","Ï":"s","Ï":"t","Ï
":"y","Ï":"f","Ï":"x","Ï":"ps","Ï":"w","Ï":"i","Ï":"y","Ï":"o","Ï":"y","Ï":"w","Ð":"Yo","Ð":"DJ","Ð":"Ye","Ð":"I","Ð":"Yi","Ð":"J","Ð":"LJ","Ð":"NJ","Ð":"C","Ð":"DZ","Ð":"A","Ð":"B","Ð":"V","Ð":"G","Ð":"D","Ð":"E","Ð":"Zh","Ð":"Z","Ð":"I","Ð":"J","Ð":"K","Ð":"L","Ð":"M","Ð":"N","Ð":"O","Ð":"P","Ð ":"R","С":"S","Т":"T","У":"U","Ф":"F","Ð¥":"H","Ц":"C","Ч":"Ch","Ш":"Sh","Щ":"Sh","Ъ":"U","Ы":"Y","Ь":"","Ð":"E","Ю":"Yu","Я":"Ya","а":"a","б":"b","в":"v","г":"g","д":"d","е":"e","ж":"zh","з":"z","и":"i","й":"j","к":"k","л":"l","м":"m","н":"n","о":"o","п":"p","Ñ":"r","Ñ":"s","Ñ":"t","Ñ":"u","Ñ":"f","Ñ
":"h","Ñ":"c","Ñ":"ch","Ñ":"sh","Ñ":"sh","Ñ":"u","Ñ":"y","Ñ":"","Ñ":"e","Ñ":"yu","Ñ":"ya","Ñ":"yo","Ñ":"dj","Ñ":"ye","Ñ":"i","Ñ":"yi","Ñ":"j","Ñ":"lj","Ñ":"nj","Ñ":"c","Ñ":"u","Ñ":"dz","Ò":"G","Ò":"g","Ò":"GH","Ò":"gh","Ò":"KH","Ò":"kh","Ò¢":"NG","Ò£":"ng","Ò®":"UE","Ò¯":"ue","Ò°":"U","Ò±":"u","Òº":"H","Ò»":"h","Ó":"AE","Ó":"ae","Ó¨":"OE","Ó©":"oe","Ô±":"A","Ô²":"B","Ô³":"G","Ô´":"D","Ôµ":"E","Ô¶":"Z","Ô·":"E\\\'","Ô¸":"Y\\\'","Ô¹":"T\\\'","Ôº":"JH","Ô»":"I","Ô¼":"L","Ô½":"X","Ô¾":"C\\\'","Ô¿":"K","Õ":"H","Õ":"D\\\'","Õ":"GH","Õ":"TW","Õ":"M","Õ
":"Y","Õ":"N","Õ":"SH","Õ":"CH","Õ":"P","Õ":"J","Õ":"R\\\'","Õ":"S","Õ":"V","Õ":"T","Õ":"R","Õ":"C","Õ":"P\\\'","Õ":"Q\\\'","Õ":"O\\\'\\\'","Õ":"F","Ö":"EV","Ø¡":"a","Ø¢":"aa","Ø£":"a","ؤ":"u","Ø¥":"i","ئ":"e","ا":"a","ب":"b","Ø©":"h","ت":"t","Ø«":"th","ج":"j","Ø":"h","Ø®":"kh","د":"d","ذ":"th","ر":"r","ز":"z","س":"s","Ø´":"sh","ص":"s","ض":"dh","Ø·":"t","ظ":"z","ع":"a","غ":"gh","Ù":"f","Ù":"q","Ù":"k","Ù":"l","Ù
":"m","Ù":"n","Ù":"h","Ù":"w","Ù":"a","Ù":"y","Ù":"an","Ù":"on","Ù":"en","Ù":"a","Ù":"u","Ù":"e","Ù":"","Ù ":"0","Ù¡":"1","Ù¢":"2","Ù£":"3","Ù¤":"4","Ù¥":"5","Ù¦":"6","Ù§":"7","Ù¨":"8","Ù©":"9","Ù¾":"p","Ú":"ch","Ú":"zh","Ú©":"k","Ú¯":"g","Û":"y","Û°":"0","Û±":"1","Û²":"2","Û³":"3","Û´":"4","Ûµ":"5","Û¶":"6","Û·":"7","Û¸":"8","Û¹":"9","฿":"baht","á":"a","á":"b","á":"g","á":"d","á":"e","á":"v","á":"z","á":"t","á":"i","á":"k","á":"l","á":"m","á":"n","á":"o","á":"p","á":"zh","á ":"r","á¡":"s","á¢":"t","á£":"u","á¤":"f","á¥":"k","á¦":"gh","á§":"q","á¨":"sh","á©":"ch","áª":"ts","á«":"dz","á¬":"ts","á":"ch","á®":"kh","á¯":"j","á°":"h","á¹¢":"S","á¹£":"s","áº":"W","áº":"w","áº":"W","áº":"w","áº":"W","áº
":"w","áº":"SS","Ạ":"A","ạ":"a","Ả":"A","ả":"a","Ấ":"A","ấ":"a","Ầ":"A","ầ":"a","Ẩ":"A","ẩ":"a","Ẫ":"A","ẫ":"a","Ậ":"A","áº":"a","Ắ":"A","ắ":"a","Ằ":"A","ằ":"a","Ẳ":"A","ẳ":"a","Ẵ":"A","ẵ":"a","Ặ":"A","ặ":"a","Ẹ":"E","ẹ":"e","Ẻ":"E","ẻ":"e","Ẽ":"E","ẽ":"e","Ế":"E","ế":"e","á»":"E","á»":"e","á»":"E","á»":"e","á»":"E","á»
":"e","á»":"E","á»":"e","á»":"I","á»":"i","á»":"I","á»":"i","á»":"O","á»":"o","á»":"O","á»":"o","á»":"O","á»":"o","á»":"O","á»":"o","á»":"O","á»":"o","á»":"O","á»":"o","á»":"O","á»":"o","á»":"O","á»":"o","á»":"O","á»":"o","á»":"O","á»":"o","á» ":"O","ỡ":"o","Ợ":"O","ợ":"o","Ụ":"U","ụ":"u","Ủ":"U","á»§":"u","Ứ":"U","ứ":"u","Ừ":"U","ừ":"u","Ử":"U","á»":"u","á»®":"U","ữ":"u","á»°":"U","á»±":"u","Ỳ":"Y","ỳ":"y","á»´":"Y","ỵ":"y","á»¶":"Y","á»·":"y","Ỹ":"Y","ỹ":"y","â":"-","â":"\\\'","â":"\\\'","â":"\\\\\\"","â":"\\\\\\"","â":"\\\\\\"","â ":"+","â¢":"*","â¦":"...","â ":"ecu","â¢":"cruzeiro","â£":"french franc","â¤":"lira","â¥":"mill","â¦":"naira","â
1§":"peseta","â¨":"rupee","â©":"won","âª":"new shequel","â«":"dong","â¬":"euro","â":"kip","â®":"tugrik","â¯":"drachma","â°":"penny","â±":"peso","â²":"guarani","â³":"austral","â´":"hryvnia","âµ":"cedi","â¸":"kazakhstani tenge","â¹":"indian rupee","âº":"turkish lira","â½":"russian ruble","â¿":"bitcoin","â ":"sm","â¢":"tm","â":"d","â":"delta","â":"sum","â":"infinity","â¥":"love","å
":"yuan","å":"yen","ï·¼":"rial","ﻵ":"laa","ï»·":"laa","ﻹ":"lai","ï»»":"la"}\')\n var locales = JSON.parse(\'{"bg":{"Ð":"Y","Ц":"Ts","Щ":"Sht","Ъ":"A","Ь":"Y","й":"y","Ñ":"ts","Ñ":"sht","Ñ":"a","Ñ":"y"},"de":{"Ã":"AE","ä":"ae","Ã":"OE","ö":"oe","Ã":"UE","ü":"ue","Ã":"ss","%":"prozent","&":"und","|":"oder","â":"summe","â":"unendlich","â¥":"liebe"},"es":{"%":"por ciento","&":"y","<":"menor que",">":"mayor que","|":"o","¢":"centavos","£":"libras","¤":"moneda","â£":"francos","â":"suma","â":"infinito","â¥":"amor"},"fr":{"%":"pourcent","&":"et","<":"plus petit",">":"plus grand","|":"ou","¢":"centime","£":"livre","¤":"devise","â£":"franc","â":"somme","â":"infini","â¥":"amour"},"pt":{"%":"porcento","&":"e","<":"menor",">":"maior","|":"ou","¢":"centavo","â":"soma","£":"libra","â":"infinito","â¥":"amor"},"uk":{"Ð":"Y","и":"y","Ð":"Y","й":"y","Ц":"Ts","Ñ":"ts","Ð¥":"Kh","Ñ
":"kh","Щ":"Shch","Ñ":"shch","Ð":"H","г":"h"},"vi":{"Ä":"D","Ä":"d"},"da":{"Ã":"OE","ø":"oe","Ã
":"AA","Ã¥":"aa","%":"procent","&":"og","|":"eller","$":"dollar","<":"mindre end",">":"større end"},"nb":{"&":"og","Ã
":"AA","Ã":"AE","Ã":"OE","Ã¥":"aa","æ":"ae","ø":"oe"},"it":{"&":"e"},"nl":{"&":"en"},"sv":{"&":"och","Ã
":"AA","Ã":"AE","Ã":"OE","Ã¥":"aa","ä":"ae","ö":"oe"}}\')\n\n function replace (string, options) {\n if (typeof string !== \'string\') {\n throw new Error(\'slugify: string argument expected\')\n }\n\n options = (typeof options === \'string\')\n ? {replacement: options}\n : options || {}\n\n var locale = locales[options.locale] || {}\n\n var replacement = options.replacement === undefined ? \'-\' : options.replacement\n\n var trim = options.trim === undefined ? true : options.trim\n\n var slug = string.normalize().split(\'\')\n // replace characters based on charMap\n .reduce(function (result, ch) {\n var appendChar = locale[ch];\n if (appendChar === undefined) appendChar = charMap[ch];\n if (appendChar === undefined) appendChar = ch;\n if (appendChar === replacement) appendChar = \' \';\n return result + appendChar\n // remove not allowed characters\n .replace(options.remove || /[^\\w\\s$*_+~.()\'"!\\-:@]+/g, \'\')\n }, \'\');\n\n if (options.strict) {\n slug = slug.replace(/[^A-Za-z0-9\\s]/g, \'\');\n }\n\n if (trim) {\n slug = slug.trim()\n }\n\n // Replace spaces with replacement character, treating multiple consecutive\n // spaces as a single space.\n slug = slug.replace(/\\s+/g, replacement);\n\n if (options.lower) {\n slug = slug.toLowerCase()\n }\n\n return slug\n }\n\n replace.extend = function (customMap) {\n Object.assign(charMap, customMap)\n }\n\n return replace\n}))\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzA0LmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL3NsdWdpZnkvc2x1Z2lmeS5qcz8zNjY2Il0sInNvdXJjZXNDb250ZW50IjpbIlxuOyhmdW5jdGlvbiAobmFtZSwgcm9vdCwgZmFjdG9yeSkge1xuICBpZiAodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KClcbiAgICBtb2R1bGUuZXhwb3J0c1snZGVmYXVsdCddID0gZmFjdG9yeSgpXG4gIH1cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgZGVmaW5lKGZhY3RvcnkpXG4gIH1cbiAgZWxzZSB7XG4gICAgcm9vdFtuYW1lXSA9IGZhY3RvcnkoKVxuICB9XG59KCdzbHVnaWZ5JywgdGhpcywgZnVuY3Rpb24gKCkge1xuICB2YXIgY2hhck1hcCA9IEpTT04ucGFyc2UoJ3tcIiRcIjpcImRvbGxhclwiLFwiJVwiOlwicGVyY2VudFwiLFwiJlwiOlwiYW5kXCIsXCI8XCI6XCJsZXNzXCIsXCI+XCI6XCJncmVhdGVyXCIsXCJ8XCI6XCJvclwiLFwiwqJcIjpcImNlbnRcIixcIsKjXCI6XCJwb3VuZFwiLFwiwqRcIjpcImN1cnJlbmN5XCIsXCLCpVwiOlwieWVuXCIsXCLCqVwiOlwiKGMpXCIsXCLCqlwiOlwiYVwiLFwiwq5cIjpcIihyKVwiLFwiwrpcIjpcIm9cIixcIsOAXCI6XCJBXCIsXCLDgVwiOlwiQVwiLFwiw4JcIjpcIkFcIixcIsODXCI6XCJBXCIsXCLDhFwiOlwiQVwiLFwiw4VcIjpcIkFcIixcIsOGXCI6XCJBRVwiLFwiw4dcIjpcIkNcIixcIsOIXCI6XCJFXCIsXCLDiVwiOlwiRVwiLFwiw4pcIjpcIkVcIixcIsOLXCI6XCJFXCIsXCLDjFwiOlwiSVwiLFwiw41cIjpcIklcIixcIsOOXCI6XCJJXCIsXCLDj1wiOlwiSVwiLFwiw5BcIjpcIkRcIixcIsORXCI6XCJOXCIsXCLDklwiOlwiT1wiLFwiw5NcIjpcIk9cIixcIsOUXCI6XCJPXCIsXCLDlVwiOlwiT1wiLFwiw5ZcIjpcIk9cIixcIsOYXCI6XCJPXCIsXCLDmVwiOlwiVVwiLFwiw5pcIjpcIlVcIixcIsObXCI6XCJVXCIsXCLDnFwiOlwiVVwiLFwiw51cIjpcIllcIixcIsOeXCI6XCJUSFwiLFwiw59cIjpcInNzXCIsXCLDoFwiOlwiYVwiLFwiw6FcIjpcImFcIixcIsOiXCI6XCJhXCIsXCLDo1wiOlwiYVwiLFwiw6RcIjpcImFcIixcIsOlXCI6XCJhXCIsXCLDplwiOlwiYWVcIixcIsOnXCI6XCJjXCIsXCLDqFwiOlwiZVwiLFwiw6lcIjpcImVcIixcIsOqXCI6XCJlXCIsXCLDq1wiOlwiZVwiLFwiw6xcIjpcImlcIixcIsOtXCI6XCJpXCIsXCLDrlwiOlwiaVwiLFwiw69cIjpcImlcIixcIsOwXCI6XCJkXCIsXCLDsVwiOlwiblwiLFwiw7JcIjpcIm9cIixcIsOzXCI6XCJvXCIsXCLDtFwiOlwib1wiLFwiw7VcIjpcIm9cIixcIsO2XCI6XCJvXCIsXCLDuFwiOlwib1wiLFwiw7lcIjpcInVcIixcIsO6XCI6XCJ1XCIsXCLDu1wiOlwidVwiLFwiw7xcIjpcInVcIixcIsO9XCI6XCJ5XCIsXCLDvlwiOlwidGhcIixcIsO/XCI6XCJ5XCIsXCLEgFwiOlwiQVwiLFwixIFcIjpcImFcIixcIsSCXCI6XCJBXCIsXCLEg1wiOlwiYVwiLFwixIRcIjpcIkFcIixcIsSFXCI6XCJhXCIsXCLEhlwiOlwiQ1wiLFwixIdcIjpcImNcIixcIsSMXCI6XCJDXCIsXCLEjVwiOlwiY1wiLFwixI5cIjpcIkRcIixcIsSPXCI6XCJkXCIsXCLEkFwiOlwiREpcIixcIsSRXCI6XCJkalwiLFwixJJcIjpcIkVcIixcIsSTXCI6XCJlXCIsXCLEllwiOlwiRVwiLFwixJdcIjpcImVcIixcIsSYXCI6XCJlXCIsXCLEmVwiOlwiZVwiLFwixJpcIjpcIkVcIixcIsSbXCI6XCJlXCIsXCLEnlwiOlwiR1wiLFwixJ9cIjpcImdcIixcIsSiXCI6XCJHXCIsXCLEo1wiOlwiZ1wiLFwixKhcIjpcIklcIixcIsSpXCI6XCJpXCIsXCLEqlwiOlwiaVwiLFwixKtcIjpcImlcIixcIsSuXCI6XCJJXCIsXCLEr1wiOlwiaVwiLFwixLBcIjpcIklcIixcIsSxXCI6XCJpXCIsXCLEtlwiOlwia1wiLFwixLdcIjpcImtcIixcIsS7XCI6XCJMXCIsXCLEvFwiOlwibFwiLFwixL1cIjpcIkxcIixcIsS+XCI6XCJsXCIsXCLFgVwiOlwiTFwiLFwixYJcIjpcImxcIixcIsWDXCI6XCJOXCIsXCLFhFwiOlwiblwiLFwixYVcIjpcIk5cIixcIsWGXCI6XCJuXCIsXCLFh1wiOlwiTlwiLFwixYhcIjpcIm5cIixcIsWMXCI6XCJPXCIsXCLFjVwiOlwib1wiLFwixZBcIjpcIk9cIixcIsWRXCI6XCJvXCIsXCLFklwiOlwiT0VcIixcIsWTXCI6XCJvZVwiLFwixZRcIjpcIlJcIixcIsWVXCI6XCJyXCIsXCLFmFwiOlwiUlwiLFwixZlcIjpcInJcIixcIsWaXCI6XCJTXCIsXCLFm1wiOlwic1wiLFwixZ5cIjpcIlNcIixcIsWfXCI6XCJzXCIsXCLFoFwiOlwiU1wiLFwixaFcIjpcInNcIixcIsWiXCI6XCJUXCIsXCLFo1wiOlwidFwiLFwixaRcIjpcIlRcIixcIsWlXCI6XCJ0XCIsXCLFqFwiOlwiVVwiLFwixalcIjpcInVcIixcIsWqXCI6XCJ1XCIsXCLFq1wiOlwidVwiLFwixa5cIjpcIlVcIixcIsWvXCI6XCJ1XCIsXCLFsFwiOlwiVVwiLFwixbFcIjpcInVcIixcIsWyXCI6XCJVXCIsXCLFs1wiOlwidVwiLFwixbRcIjpcIldcIixcIsW1XCI6XCJ3XCIsXCLFtlwiOlwiWVwiLFwixbdcIjpcInlcIixcIsW4XCI6XCJZXCIsXCLFuVwiOlwiWlwiLFwixbpcIjpcInpcIixcIsW7XCI6XCJaXCIsXCLFvFwiOlwielwiLFwixb
11cIjpcIlpcIixcIsW+XCI6XCJ6XCIsXCLGj1wiOlwiRVwiLFwixpJcIjpcImZcIixcIsagXCI6XCJPXCIsXCLGoVwiOlwib1wiLFwixq9cIjpcIlVcIixcIsawXCI6XCJ1XCIsXCLHiFwiOlwiTEpcIixcIseJXCI6XCJsalwiLFwix4tcIjpcIk5KXCIsXCLHjFwiOlwibmpcIixcIsiYXCI6XCJTXCIsXCLImVwiOlwic1wiLFwiyJpcIjpcIlRcIixcIsibXCI6XCJ0XCIsXCLJmVwiOlwiZVwiLFwiy5pcIjpcIm9cIixcIs6GXCI6XCJBXCIsXCLOiFwiOlwiRVwiLFwizolcIjpcIkhcIixcIs6KXCI6XCJJXCIsXCLOjFwiOlwiT1wiLFwizo5cIjpcIllcIixcIs6PXCI6XCJXXCIsXCLOkFwiOlwiaVwiLFwizpFcIjpcIkFcIixcIs6SXCI6XCJCXCIsXCLOk1wiOlwiR1wiLFwizpRcIjpcIkRcIixcIs6VXCI6XCJFXCIsXCLOllwiOlwiWlwiLFwizpdcIjpcIkhcIixcIs6YXCI6XCI4XCIsXCLOmVwiOlwiSVwiLFwizppcIjpcIktcIixcIs6bXCI6XCJMXCIsXCLOnFwiOlwiTVwiLFwizp1cIjpcIk5cIixcIs6eXCI6XCIzXCIsXCLOn1wiOlwiT1wiLFwizqBcIjpcIlBcIixcIs6hXCI6XCJSXCIsXCLOo1wiOlwiU1wiLFwizqRcIjpcIlRcIixcIs6lXCI6XCJZXCIsXCLOplwiOlwiRlwiLFwizqdcIjpcIlhcIixcIs6oXCI6XCJQU1wiLFwizqlcIjpcIldcIixcIs6qXCI6XCJJXCIsXCLOq1wiOlwiWVwiLFwizqxcIjpcImFcIixcIs6tXCI6XCJlXCIsXCLOrlwiOlwiaFwiLFwizq9cIjpcImlcIixcIs6wXCI6XCJ5XCIsXCLOsVwiOlwiYVwiLFwizrJcIjpcImJcIixcIs6zXCI6XCJnXCIsXCLOtFwiOlwiZFwiLFwizrVcIjpcImVcIixcIs62XCI6XCJ6XCIsXCLOt1wiOlwiaFwiLFwizrhcIjpcIjhcIixcIs65XCI6XCJpXCIsXCLOulwiOlwia1wiLFwizrtcIjpcImxcIixcIs68XCI6XCJtXCIsXCLOvVwiOlwiblwiLFwizr5cIjpcIjNcIixcIs6/XCI6XCJvXCIsXCLPgFwiOlwicFwiLFwiz4FcIjpcInJcIixcIs+CXCI6XCJzXCIsXCLPg1wiOlwic1wiLFwiz4RcIjpcInRcIixcIs+FXCI6XCJ5XCIsXCLPhlwiOlwiZlwiLFwiz4dcIjpcInhcIixcIs+IXCI6XCJwc1wiLFwiz4lcIjpcIndcIixcIs+KXCI6XCJpXCIsXCLPi1wiOlwieVwiLFwiz4xcIjpcIm9cIixcIs+NXCI6XCJ5XCIsXCLPjlwiOlwid1wiLFwi0IFcIjpcIllvXCIsXCLQglwiOlwiREpcIixcItCEXCI6XCJZZVwiLFwi0IZcIjpcIklcIixcItCHXCI6XCJZaVwiLFwi0IhcIjpcIkpcIixcItCJXCI6XCJMSlwiLFwi0IpcIjpcIk5KXCIsXCLQi1wiOlwiQ1wiLFwi0I9cIjpcIkRaXCIsXCLQkFwiOlwiQVwiLFwi0JFcIjpcIkJcIixcItCSXCI6XCJWXCIsXCLQk1wiOlwiR1wiLFwi0JRcIjpcIkRcIixcItCVXCI6XCJFXCIsXCLQllwiOlwiWmhcIixcItCXXCI6XCJaXCIsXCLQmFwiOlwiSVwiLFwi0JlcIjpcIkpcIixcItCaXCI6XCJLXCIsXCLQm1wiOlwiTFwiLFwi0JxcIjpcIk1cIixcItCdXCI6XCJOXCIsXCLQnlwiOlwiT1wiLFwi0J9cIjpcIlBcIixcItCgXCI6XCJSXCIsXCLQoVwiOlwiU1wiLFwi0KJcIjpcIlRcIixcItCjXCI6XCJVXCIsXCLQpFwiOlwiRlwiLFwi0KVcIjpcIkhcIixcItCmXCI6XCJDXCIsXCLQp1wiOlwiQ2hcIixcItCoXCI6XCJTaFwiLFwi0KlcIjpcIlNoXCIsXCLQqlwiOlwiVVwiLFwi0KtcIjpcIllcIixcItCsXCI6XCJcIixcItCtXCI6XCJFXCIsXCLQrlwiOlwiWXVcIixcItCvXCI6XCJZYVwiLFwi0LBcIjpcImFcIixcItCxXCI6XCJiXCIsXCLQslwiOlwidlwiLFwi0LNcIjpcImdcIixcItC0XCI6XCJkXCIsXCLQtVwiOlwiZVwiLFwi0LZcIjpcInpoXCIsXCLQt1wiOlwielwiLFwi0LhcIjpcImlcIixcItC5XCI6XCJqXCIsXCLQulwiOlwia1wiLFwi0LtcIjpcImxcIixcItC8XCI6XCJtXCIsXCLQvVwiOlwiblwiLFwi0L5cIjpcIm9cIixcItC/XCI6XCJwXCIsXCLRgFwiOlwiclwiLFwi0YFcIjpcInNcIixcItGCXCI6XCJ0XCIsXCLRg1wiOlwidVwiLFwi0YRcIjpcImZcIixcItGFXCI6XCJoXCIsXCLRhlwiOlwiY1wiLFwi0YdcIjpcImNoXCIsXCLRiFwiOlwic2hcIixcItGJXCI6XCJzaFwiLFwi0YpcIjpcInVcIixcItGLXCI6XCJ5XCIsXCLRjFwiOlwiXCIsXCLRjVwiOlwiZVwiLFwi0Y5cIjpcInl1XCIsXCLRj1wiOlwieWFcIixcItGRXCI6XCJ5b1wiLFwi0ZJcIjpcImRqXCIsXCLRlFwiOlwieWVcIixcItGWXCI6XCJpXCIsXCLRl1wiOlwieWlcIixcItGYXCI6XCJqXCIsXCLRmVwiOlwibGpcIixcItGaXCI6XCJualwiLFwi0ZtcIjpcImNcIixcItGdXCI6XCJ1XCIsXCLRn1wiOlwiZHpcIixcItKQXCI6XCJHXCIsXCLSkVwiOlwiZ1wiLFwi0pJcIjpcIkdIXCIsXCLSk1wiOlwiZ2hcIixcItKaXCI6XCJLSFwiLFwi0ptcIjpcImtoXCIsXCLSolwiOlwiTkdcIixcItKjXCI6XCJuZ1wiLFwi0q5cIjpcIlVFXCIsXCLSr1wiOlwidWVcIixcItKwXCI6XCJVXCIsXCLSsVwiOlwidVwiLFwi0rpcIjpcIkhcIixcItK7XCI6XCJoXCIsXCLTmFwiOlwiQUVcIixcItOZXCI6XCJhZVwiLFwi06hcIjpcIk9FXCIsXCLTqVwiOlwib2VcIixcItSxXCI6XCJBXCIsXCLUslwiOlwiQlwiLFwi1LNcIjpcIkdcIixcItS0XCI6XCJEXCIsXCLUtVwiOlwiRVwiLFwi1LZcIjpcIlpcIixcItS3XCI6XCJFXFwnXCIsXCLUuFwiOlwiWVxcJ1wiLFwi1LlcIjpcIlRcXCdcIixcItS6XCI6XCJKSFwiLFwi1LtcIjpcIklcIixcItS8XCI6XCJMXCIsXCLUvVwiOlwiWFwiLFwi1L5cIjpcIkNcXCdcIixcItS/XCI6XCJLXCIsXCLVgFwiOlwiSFwiLFwi1YFcIjpcIkRcXCdcIixcItWCXCI6XCJHSFwiLFwi1YNcIjpcIlRXXCIsXCLVhFwiOlwiTVwiLFwi1YVcIjpcIllcIixcItWGXCI6XCJOXCIsXCLVh1wiOlwiU0hcIixcItWJXCI6XCJDSFwiLFwi1YpcIjpcIlBcIixcItWLXCI6XCJKXCIsXCLVjFwiOlwiUlxcJ1wiLFwi1Y1cIjpcIlNcIixcItWOXCI6XCJWXCIsXCLVj1wiOlwiVFwiLFwi1ZBcIjpcIlJcIixcItWRXCI6XCJDXCIsXCLVk1wiOlwiUFxcJ1wiLFwi1ZRcIjpcIlFcXCdcIixcItWVXCI6XCJPXFwnXFwnXCIsXCLVllwiOlwiRlwiLFwi1odcIjpcIkVWXCIsXCLYoVwiOlwiYVwiLFwi2KJcIjpcImFhXCIsXCLYo1wiOlwiYVwiLFwi2KRcIjpcInVcIixcItilXCI6XCJpXCIsXCLYplwiOlwiZVwiLFwi2KdcIjpcImFcIixcItioXCI6XCJiXCIsXCLYqVwiOlwiaFwiLFwi2KpcIjpcInRcIixcItirXCI6XCJ0aFwiLFwi2KxcIjpcImpcIixcItitXCI6XCJoXCIsXCLYrlwiOlwia2hcIixcItivXCI6XCJkXCIsXCLYsFwiOlwidGhcIixcItixXCI6XCJyXCIsXCLYslwiOlwielwiLFwi2LNcIjpcInNcIixcIti0XCI6XCJzaFwiLFwi2LVcIjpcInNcIixcIti2XCI6XCJkaFwiLFwi2LdcIjpcInRcIixcIti4XCI6XCJ6XCIsXCLYuVwiOlwiYVwiLFwi2LpcIjpcImdoXCIsXCLZgVwiOlwiZlwiLFwi2YJcIjpcInFcIixcItmDXCI6XCJrXCIsXCLZhFwiOlwibFwiLFwi2YVcIjpcIm1cIixcItmGXCI6XCJuXCIsXCLZh1wiOlwiaFwiLFwi2YhcIjpcIndcIixcItmJXCI6XCJhXCIsXCLZilwiOlwieVwiLFwi2YtcIjpcImFuXCIsXCLZj
1FwiOlwib25cIixcItmNXCI6XCJlblwiLFwi2Y5cIjpcImFcIixcItmPXCI6XCJ1XCIsXCLZkFwiOlwiZVwiLFwi2ZJcIjpcIlwiLFwi2aBcIjpcIjBcIixcItmhXCI6XCIxXCIsXCLZolwiOlwiMlwiLFwi2aNcIjpcIjNcIixcItmkXCI6XCI0XCIsXCLZpVwiOlwiNVwiLFwi2aZcIjpcIjZcIixcItmnXCI6XCI3XCIsXCLZqFwiOlwiOFwiLFwi2alcIjpcIjlcIixcItm+XCI6XCJwXCIsXCLahlwiOlwiY2hcIixcItqYXCI6XCJ6aFwiLFwi2qlcIjpcImtcIixcItqvXCI6XCJnXCIsXCLbjFwiOlwieVwiLFwi27BcIjpcIjBcIixcItuxXCI6XCIxXCIsXCLbslwiOlwiMlwiLFwi27NcIjpcIjNcIixcItu0XCI6XCI0XCIsXCLbtVwiOlwiNVwiLFwi27ZcIjpcIjZcIixcItu3XCI6XCI3XCIsXCLbuFwiOlwiOFwiLFwi27lcIjpcIjlcIixcIuC4v1wiOlwiYmFodFwiLFwi4YOQXCI6XCJhXCIsXCLhg5FcIjpcImJcIixcIuGDklwiOlwiZ1wiLFwi4YOTXCI6XCJkXCIsXCLhg5RcIjpcImVcIixcIuGDlVwiOlwidlwiLFwi4YOWXCI6XCJ6XCIsXCLhg5dcIjpcInRcIixcIuGDmFwiOlwiaVwiLFwi4YOZXCI6XCJrXCIsXCLhg5pcIjpcImxcIixcIuGDm1wiOlwibVwiLFwi4YOcXCI6XCJuXCIsXCLhg51cIjpcIm9cIixcIuGDnlwiOlwicFwiLFwi4YOfXCI6XCJ6aFwiLFwi4YOgXCI6XCJyXCIsXCLhg6FcIjpcInNcIixcIuGDolwiOlwidFwiLFwi4YOjXCI6XCJ1XCIsXCLhg6RcIjpcImZcIixcIuGDpVwiOlwia1wiLFwi4YOmXCI6XCJnaFwiLFwi4YOnXCI6XCJxXCIsXCLhg6hcIjpcInNoXCIsXCLhg6lcIjpcImNoXCIsXCLhg6pcIjpcInRzXCIsXCLhg6tcIjpcImR6XCIsXCLhg6xcIjpcInRzXCIsXCLhg61cIjpcImNoXCIsXCLhg65cIjpcImtoXCIsXCLhg69cIjpcImpcIixcIuGDsFwiOlwiaFwiLFwi4bmiXCI6XCJTXCIsXCLhuaNcIjpcInNcIixcIuG6gFwiOlwiV1wiLFwi4bqBXCI6XCJ3XCIsXCLhuoJcIjpcIldcIixcIuG6g1wiOlwid1wiLFwi4bqEXCI6XCJXXCIsXCLhuoVcIjpcIndcIixcIuG6nlwiOlwiU1NcIixcIuG6oFwiOlwiQVwiLFwi4bqhXCI6XCJhXCIsXCLhuqJcIjpcIkFcIixcIuG6o1wiOlwiYVwiLFwi4bqkXCI6XCJBXCIsXCLhuqVcIjpcImFcIixcIuG6plwiOlwiQVwiLFwi4bqnXCI6XCJhXCIsXCLhuqhcIjpcIkFcIixcIuG6qVwiOlwiYVwiLFwi4bqqXCI6XCJBXCIsXCLhuqtcIjpcImFcIixcIuG6rFwiOlwiQVwiLFwi4bqtXCI6XCJhXCIsXCLhuq5cIjpcIkFcIixcIuG6r1wiOlwiYVwiLFwi4bqwXCI6XCJBXCIsXCLhurFcIjpcImFcIixcIuG6slwiOlwiQVwiLFwi4bqzXCI6XCJhXCIsXCLhurRcIjpcIkFcIixcIuG6tVwiOlwiYVwiLFwi4bq2XCI6XCJBXCIsXCLhurdcIjpcImFcIixcIuG6uFwiOlwiRVwiLFwi4bq5XCI6XCJlXCIsXCLhurpcIjpcIkVcIixcIuG6u1wiOlwiZVwiLFwi4bq8XCI6XCJFXCIsXCLhur1cIjpcImVcIixcIuG6vlwiOlwiRVwiLFwi4bq/XCI6XCJlXCIsXCLhu4BcIjpcIkVcIixcIuG7gVwiOlwiZVwiLFwi4buCXCI6XCJFXCIsXCLhu4NcIjpcImVcIixcIuG7hFwiOlwiRVwiLFwi4buFXCI6XCJlXCIsXCLhu4ZcIjpcIkVcIixcIuG7h1wiOlwiZVwiLFwi4buIXCI6XCJJXCIsXCLhu4lcIjpcImlcIixcIuG7ilwiOlwiSVwiLFwi4buLXCI6XCJpXCIsXCLhu4xcIjpcIk9cIixcIuG7jVwiOlwib1wiLFwi4buOXCI6XCJPXCIsXCLhu49cIjpcIm9cIixcIuG7kFwiOlwiT1wiLFwi4buRXCI6XCJvXCIsXCLhu5JcIjpcIk9cIixcIuG7k1wiOlwib1wiLFwi4buUXCI6XCJPXCIsXCLhu5VcIjpcIm9cIixcIuG7llwiOlwiT1wiLFwi4buXXCI6XCJvXCIsXCLhu5hcIjpcIk9cIixcIuG7mVwiOlwib1wiLFwi4buaXCI6XCJPXCIsXCLhu5tcIjpcIm9cIixcIuG7nFwiOlwiT1wiLFwi4budXCI6XCJvXCIsXCLhu55cIjpcIk9cIixcIuG7n1wiOlwib1wiLFwi4bugXCI6XCJPXCIsXCLhu6FcIjpcIm9cIixcIuG7olwiOlwiT1wiLFwi4bujXCI6XCJvXCIsXCLhu6RcIjpcIlVcIixcIuG7pVwiOlwidVwiLFwi4bumXCI6XCJVXCIsXCLhu6dcIjpcInVcIixcIuG7qFwiOlwiVVwiLFwi4bupXCI6XCJ1XCIsXCLhu6pcIjpcIlVcIixcIuG7q1wiOlwidVwiLFwi4busXCI6XCJVXCIsXCLhu61cIjpcInVcIixcIuG7rlwiOlwiVVwiLFwi4buvXCI6XCJ1XCIsXCLhu7BcIjpcIlVcIixcIuG7sVwiOlwidVwiLFwi4buyXCI6XCJZXCIsXCLhu7NcIjpcInlcIixcIuG7tFwiOlwiWVwiLFwi4bu1XCI6XCJ5XCIsXCLhu7ZcIjpcIllcIixcIuG7t1wiOlwieVwiLFwi4bu4XCI6XCJZXCIsXCLhu7lcIjpcInlcIixcIuKAk1wiOlwiLVwiLFwi4oCYXCI6XCJcXCdcIixcIuKAmVwiOlwiXFwnXCIsXCLigJxcIjpcIlxcXFxcXFwiXCIsXCLigJ1cIjpcIlxcXFxcXFwiXCIsXCLigJ5cIjpcIlxcXFxcXFwiXCIsXCLigKBcIjpcIitcIixcIuKAolwiOlwiKlwiLFwi4oCmXCI6XCIuLi5cIixcIuKCoFwiOlwiZWN1XCIsXCLigqJcIjpcImNydXplaXJvXCIsXCLigqNcIjpcImZyZW5jaCBmcmFuY1wiLFwi4oKkXCI6XCJsaXJhXCIsXCLigqVcIjpcIm1pbGxcIixcIuKCplwiOlwibmFpcmFcIixcIuKCp1wiOlwicGVzZXRhXCIsXCLigqhcIjpcInJ1cGVlXCIsXCLigqlcIjpcIndvblwiLFwi4oKqXCI6XCJuZXcgc2hlcXVlbFwiLFwi4oKrXCI6XCJkb25nXCIsXCLigqxcIjpcImV1cm9cIixcIuKCrVwiOlwia2lwXCIsXCLigq5cIjpcInR1Z3Jpa1wiLFwi4oKvXCI6XCJkcmFjaG1hXCIsXCLigrBcIjpcInBlbm55XCIsXCLigrFcIjpcInBlc29cIixcIuKCslwiOlwiZ3VhcmFuaVwiLFwi4oKzXCI6XCJhdXN0cmFsXCIsXCLigrRcIjpcImhyeXZuaWFcIixcIuKCtVwiOlwiY2VkaVwiLFwi4oK4XCI6XCJrYXpha2hzdGFuaSB0ZW5nZVwiLFwi4oK5XCI6XCJpbmRpYW4gcnVwZWVcIixcIuKCulwiOlwidHVya2lzaCBsaXJhXCIsXCLigr1cIjpcInJ1c3NpYW4gcnVibGVcIixcIuKCv1wiOlwiYml0Y29pblwiLFwi4oSgXCI6XCJzbVwiLFwi4oSiXCI6XCJ0bVwiLFwi4oiCXCI6XCJkXCIsXCLiiIZcIjpcImRlbHRhXCIsXCLiiJFcIjpcInN1bVwiLFwi4oieXCI6XCJpbmZpbml0eVwiLFwi4pmlXCI6XCJsb3ZlXCIsXCLlhYNcIjpcInl1YW5cIixcIuWGhlwiOlwieWVuXCIsXCLvt7xcIjpcInJpYWxcIixcIu+7tVwiOlwibGFhXCIsXCLvu7dcIjpcImxhYVwiLFwi77u5XCI6XCJsYWlcIixcIu+7u1wiOlwibGFcIn0nKVxuICB2YXIgbG9jYWxlcyA9IEpTT04ucGFyc2UoJ3tcImJnXCI6e1wi0JlcIjpcIllcIixcItCmXCI6XCJUc1wiLFwi0KlcIjpcIlNodFwiLFwi0KpcIjpcIkFcIixcItCsXCI6XCJZXCIsXCLQuVwiOlwieVwiLFwi0YZcIjpcInRzXCIsXCLRiVwiOlwic2h0XCIsXCLRilwiOlwiYVwiLFwi0YxcIjpcInlcIn0sXCJkZVwiOntcIsOEXCI6XCJBRVwiLFwiw6RcIjpcImFlXCIsXCLDllwiOlwiT0VcIixcIsO2XCI6XCJvZVwiLFwiw5xcIjpcIlVFXCIsXCLDvFwiOlwidWVcIixcIsOfXCI6XCJzc1wiLFwiJVwiOlwicHJvemVudFwiLFwiJlwiOlwidW5kXCIsXCJ8XCI6XCJvZGVyXCIsXCLiiJFcIjpcInN1bW1lXCIsXCLiiJ5cIjpcInVuZW5kbGljaFwiLFwi4pmlXCI6XCJsaWViZVwifSxcImVzXCI6e1wiJVwiOlwicG9yIGNpZW50b1wiLFwiJlwiOlwieVwiLFwiPFwiOlwibWVub3IgcXVlXCIsXCI+XCI6XCJtYXlvciBxdWVcIixcInxcIjpcIm9cIixcIsKiXCI6XCJjZW50YXZvc1wiLFwiwqNcIjpcImxpYnJhc1wiLFwiwqRcIjpcIm1vbmVkYVwiLFwi4oKjXCI6XCJmcmFuY29zXCIsXCLiiJFcIjpcInN1bWFcIixcIuKInlwiOlwiaW5maW5pdG9cIixcIuKZpVwiOlwiYW1vclwifSxcImZyXCI6e1wiJVwiOlwicG91cmNlbnRcIixcIiZcIjpcImV0XCIsXCI8XCI6XCJwbHVzIHBldGl0XCIsXCI+XCI6XCJwbHVzIGdyYW5kXCIsXCJ8XCI6XCJvdVwiLFwiwqJcIjpcImNlbnRpbWVcIixcIsKjXCI6XCJsaXZyZVwiLFwiwqRcIjpcImRldmlzZVwiLFwi4oKjXCI6XCJmcmFuY1wiLFwi4oiRXCI6XCJzb21tZVwiLFwi4oieXCI6XCJpbmZpbmlcIixcIuKZpVwiOlwiYW1vdXJcIn0sXCJwdFwiOntcIiVcIjpcInBvcmNlbnRvXCIsXCImXCI6XCJlXCIsXCI8XCI6XCJtZW5vclwiLFwiPlwiOlwibWFpb3JcIixcInxcIjpcIm91XCIsXCLColwiOlwiY2VudGF2b1wiLFwi4oiRXCI6XCJzb21hXCIsXCLCo1wiOlwibGlicmFcIixcIuKInlwiOlwiaW5maW5pdG9cIixcIuKZpVwiOlwiYW1vclwifSxcInVrXCI6e1wi0JhcIjpcIllcIixcItC4XCI6XCJ5XCIsXCLQmVwiOlwiWVwiLFwi0LlcIjpcInlcIixcItCmXCI6XCJUc1wiLFwi0YZcIjpcInRzXCIsXCLQpVwiOlwiS2hcIixcItGFXCI6XCJraFwiLFwi0KlcIjpcIlNoY2hcIixcItGJXCI6XCJzaGNoXCIsXCLQk1wiOlwiSFwiLFwi0LNcIjpcImhcIn0sXCJ2aVwiOntcIsSQXCI6XCJEXCIsXCLEkVwiOlwiZFwifSxcImRhXCI6e1wiw5hcIjpcIk9FXCIsXCLDuFwiOlwib2VcIixcIsOFXCI6XCJBQVwiLFwiw6VcIjpcImFhXCIsXCIlXCI6XCJwcm9jZW50XCIsXCImXCI6XCJvZ1wiLFwifFwiOlwiZWxsZXJcIixcIiRcIjpcImRvbGxhclwiLFwiPFwiOlwibWluZHJlIGVuZFwiLFwiPlwiOlwic3TDuHJyZSBlbmRcIn0sXCJuYlwiOntcIiZcIjpcIm9nXCIsXCLDhVwiOlwiQUFcIixcIsOGXCI6XCJBRVwiLFwiw5hcIjpcIk9FXCIsXCLDpVwiOlwiYWFcIixcIsOmXCI6XCJhZVwiLFwiw7hcIjpcIm9lXCJ9LFwiaXRcIjp7XCImXCI6XCJlXCJ9LFwibmxcIjp7XCImXCI6XCJlblwifSxcInN2XCI6e1wiJlwiOlwib2NoXCIsXCLDhVwiOlwiQUFcIixcIsOEXCI6XCJBRVwiLFwiw5ZcIjpcIk9FXCIsXCLDpVwiOlwiYWFcIixcIsOkXCI6XCJhZVwiLFwiw7ZcIjpcIm9lXCJ9fScpXG5cbiAgZnVuY3Rpb24gcmVwbGFjZSAoc3RyaW5nLCBvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NsdWdpZnk6IHN0cmluZyBhcmd1bWVudCBleHBlY3RlZCcpXG4gICAgfVxuXG4gICAgb3B0aW9ucyA9ICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycpXG4gICAgICA/IHtyZXBsYWNlbWVudDogb3B0aW9uc31cbiAgICAgIDogb3B0aW9ucyB8fCB7fVxuXG4gICAgdmFyIGxvY2FsZSA9IGxvY2FsZXNbb3B0aW9ucy5sb2NhbGVdIHx8IHt9XG5cbiAgICB2YXIgcmVwbGFjZW1lbnQgPSBvcHRpb25zLnJlcGxhY2VtZW50ID09PSB1bmRlZmluZWQgPyAnLScgOiBvcHRpb25zLnJlcGxhY2VtZW50XG5cbiAgICB2YXIgdHJpbSA9IG9wdGlvbnMudHJpbSA9PT0gdW5kZWZpbmVkID8gdHJ1ZSA6IG9wdGlvbnMudHJpbVxuXG4gICAgdmFyIHNsdWcgPSBzdHJpbmcubm9ybWFsaXplKCkuc3BsaXQoJycpXG4gICAgICAvLyByZXBsYWNlIGNoYXJhY3RlcnMgYmFzZWQgb24gY2hhck1hcFxuICAgICAgLnJlZHVjZShmdW5jdGlvbiAocmVzdWx0LCBjaCkge1xuICAgICAgICB2Y
1XIgYXBwZW5kQ2hhciA9IGxvY2FsZVtjaF07XG4gICAgICAgIGlmIChhcHBlbmRDaGFyID09PSB1bmRlZmluZWQpIGFwcGVuZENoYXIgPSBjaGFyTWFwW2NoXTtcbiAgICAgICAgaWYgKGFwcGVuZENoYXIgPT09IHVuZGVmaW5lZCkgYXBwZW5kQ2hhciA9IGNoO1xuICAgICAgICBpZiAoYXBwZW5kQ2hhciA9PT0gcmVwbGFjZW1lbnQpIGFwcGVuZENoYXIgPSAnICc7XG4gICAgICAgIHJldHVybiByZXN1bHQgKyBhcHBlbmRDaGFyXG4gICAgICAgICAgLy8gcmVtb3ZlIG5vdCBhbGxvd2VkIGNoYXJhY3RlcnNcbiAgICAgICAgICAucmVwbGFjZShvcHRpb25zLnJlbW92ZSB8fCAvW15cXHdcXHMkKl8rfi4oKSdcIiFcXC06QF0rL2csICcnKVxuICAgICAgfSwgJycpO1xuXG4gICAgaWYgKG9wdGlvbnMuc3RyaWN0KSB7XG4gICAgICBzbHVnID0gc2x1Zy5yZXBsYWNlKC9bXkEtWmEtejAtOVxcc10vZywgJycpO1xuICAgIH1cblxuICAgIGlmICh0cmltKSB7XG4gICAgICBzbHVnID0gc2x1Zy50cmltKClcbiAgICB9XG5cbiAgICAvLyBSZXBsYWNlIHNwYWNlcyB3aXRoIHJlcGxhY2VtZW50IGNoYXJhY3RlciwgdHJlYXRpbmcgbXVsdGlwbGUgY29uc2VjdXRpdmVcbiAgICAvLyBzcGFjZXMgYXMgYSBzaW5nbGUgc3BhY2UuXG4gICAgc2x1ZyA9IHNsdWcucmVwbGFjZSgvXFxzKy9nLCByZXBsYWNlbWVudCk7XG5cbiAgICBpZiAob3B0aW9ucy5sb3dlcikge1xuICAgICAgc2x1ZyA9IHNsdWcudG9Mb3dlckNhc2UoKVxuICAgIH1cblxuICAgIHJldHVybiBzbHVnXG4gIH1cblxuICByZXBsYWNlLmV4dGVuZCA9IGZ1bmN0aW9uIChjdXN0b21NYXApIHtcbiAgICBPYmplY3QuYXNzaWduKGNoYXJNYXAsIGN1c3RvbU1hcClcbiAgfVxuXG4gIHJldHVybiByZXBsYWNlXG59KSlcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///304\n')}},__webpack_module_cache__={};function __webpack_require__(n){var t=__webpack_module_cache__[n];if(void 0!==t)return t.exports;var I=__webpack_module_cache__[n]={exports:{}};return __webpack_modules__[n].call(I.exports,I,I.exports,__webpack_require__),I.exports}__webpack_require__.n=n=>{var t=n&&n.__esModule?()=>n.default:()=>n;return __webpack_require__.d(t,{a:t}),t},__webpack_require__.d=(n,t)=>{for(var I in t)__webpack_require__.o(t,I)&&!__webpack_require__.o(n,I)&&Object.defineProperty(n,I,{enumerable:!0,get:t[I]})},__webpack_require__.o=(n,t)=>Object.prototype.hasOwnProperty.call(n,t),__webpack_require__(70),__webpack_require__(156),__webpack_require__(782);var __webpack_exports__=__webpack_require__(17)})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.